View previous topic :: View next topic |
Author |
Message |
JamesW
Joined: 23 Apr 2007 Posts: 91 Location: Rochester, England
|
Interrupt on Change on DSPIC33CK64MP105 [FIXED BUG V5.096] |
Posted: Thu Nov 12, 2020 11:09 am |
|
|
Hi Folks,
Sometimes the simplest things seem to be the hardest.
I am trying to generate an interrupt on change from PIN_D13 on the DSPIC33CK64MP105. (Using Compiler V5.096)
To enable it I am doing this
Code: |
output_float(PIN_D13);
clear_interrupt(INTR_CN_PIN | PIN_D13);
int8 Test = input(PIN_D13);
enable_interrupts(INTR_CN_PIN | PIN_D13);
enable_interrupts(INT_CNID);
enable_interrupts(INT_TIMER1);
enable_interrupts(INTR_GLOBAL);
|
I've stripped out everything else intelligent out of the ISR, and am just trying to turn an LED on when it fires now.
Code: |
#INT_CNID
void HandlePortDIOC()
{
output_high(TERMINATION_LED);
//fprintf(DEBUG_PORT, "D:%04lu", input_change_d( ));
}
|
I've checked I can read the pin, and it does change state and I can monitor it normally in the main code - and the LED works fine too.
I have also tried exactly the same for PIN_C0 as well (using the CNIC version).
I even tried coding the setup, by direct register addressing and that didn't work either
Code: |
CNEN0D = 0xFFFF;
CNEN1D = 0xFFFF;
CNCOND = 0x8800;
CNDIF = 0;
enable_interrupts(INT_CNID);
|
If however I set CNDIF to a 1, the interrupt does fire and the LED comes on
Any ideas?
Many Thanks
James
Last edited by JamesW on Fri Nov 13, 2020 6:08 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Fri Nov 13, 2020 3:13 am |
|
|
OK. The reason it is not working, is that there seems to be a major fault
with the device database for this chip and these functions. It does seem to
set the correct bits for PORTA, but for the rest is accessing the wrong
registers....
If you look at the assembler generated:
Code: |
.............................. enable_interrupts(INTR_CN_PIN | PIN_D13);
04A4: BSET.B E9D.5 : E9D.5 = 1
04A6: BSET.B E9B.7 : E9B.7 = 1
04A8: BSET.B 81E.7 : [81E.7] = 1
|
It is setting bits in register E9D and E9B, which are undefined registers.
Should be accessing E64 and E68, Then is sets the bit 7 in 81E, when it
should be accessing bit 3 in 0x829 to enable the interrupt....
On your 'manual test', I'd be setting :
Code: |
#bit CNIDE=getenv("BIT:CNDIE")
CNEN0D = 0x2000; //enable bit 13
CNEN1D = 0x2000; //and again
CNCOND = 0x8800; //now enable the CN operation and style
CNIDE = TRUE; //and enable the interrupt
|
Report it to CCS. |
|
|
JamesW
Joined: 23 Apr 2007 Posts: 91 Location: Rochester, England
|
|
Posted: Fri Nov 13, 2020 4:26 am |
|
|
You are right. (as always!)
Spoke to Richard @ CCS last night, and had this reply.
Quote: |
So I determined that the problem is an error in the enable_interrupts() function when INTR_CN_PIN or'd with the pin is passed to it. There's an error in the internal math that the compiler uses to determine which registers it needs to write to enable the CNI interrupt for the pin. Unfortunately the error only showed up for pins on ports C and above which is why I didn't see it when I originally tested the feature for these chips, I was using a dsPIC33CK64MC102 which only has pins on ports A and B. I have corrected the issue and the fix will be in the next compiler release we do, or if you want I can send you an updated pcd.dll that has the fix in it now. Let me know if you would like the updated pcd.dll.
|
He's just sent me a new pcd.dll and it now works fine. Its' nice to know it's not you at times !!!
Thanks for your help (again) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Fri Nov 13, 2020 4:55 am |
|
|
Fun!...
At least it was quickly fixed.
It does also though illustrate how useful the assembler is for diagnosis.
Here you could see instantly that it is talking to the wrong registers.
Ugh. |
|
|
|