2020/11/13 05:46:41
I'm using "interrupt on change" to detect motion of a low cost rotary encoder and have encountered a weird problem when servicing a resulting interrupt.  On entry to the ISR I push the shadow registers then (hopefully!!) clear the interrupt flag.
As far as I can tell when debugging, this never happens at the first pass through the ISR!!  A break just after the instruction to clear the flag shows it still set!!  This obviously results in a second interrupt - at which point the instruction appears to work as expected.
Several hours of head scratching and messing with the code I have what appears to be a workaround.  This is to disable the interrupt before clearing the flag, followed by re-enabling the interrupt afterwards.
Attached are a couple of screenshots of the associated registers at the same interrupt breakpoint with and without the workaround. Check the interrupt flags in the file register window to see the difference.
There doesn't appear to be anything in the documentation (that I read so far) on this subject.

Attached Image(s)

2020/11/13 06:34:52
Chris A
Could it simply be some ringing on the input so it is getting re-set as soon as you clear it.  Clear it as late as you can in the interrupt.
Note I see you use push.s / pop.s in more than one interrupt. I expect you know, but this does not use the stack and there is just one saved copy so be careful when used that the interrupt cannot be preempted by another interrupt that is also using push.s (i.e. higher priority).
2020/11/13 07:35:32
It is the way the Interrupt on Change works!
Try Reading the Port register  before attempting to clear the interrupt flag,
and you may get the behaviour that was expected.
There may be a Family Reference Manual document with more explaination.
Look for  'Mismatch' in explaination of interrupt on change.
2020/11/13 07:49:37
Chris, thanks for your comments - I've been very careful to eliminate bounce in some of the tests using a separate  routine to get clean inputs. A 100MHz storage 'scope monitored each single input pulse give me a view of the actual input.   Contact bounce - or lack of it made absolutely no difference to the problem - execution was halted at the first interrupt, long before any observed bounce occurred (10's of microseconds later).
All system interrupts are left at their default priority, but I take your point about the push/pop situation if this situation is changed - thanks for the reminder.
2020/11/13 07:56:09
Thanks for that information - so its a design "feature"!!  I'll do what you suggest if that is the case.  Whay a pity such  basic info isn't in the data sheet though.  Surely I can't be the first to fall into this trap!!
2020/11/13 08:05:41
From the family reference manual :-
12.6.2 CN Configuration and Operation
The CN pins are configured as follows:
1. Ensure that the CN pin is configured as a digital input by setting the associated bit in the
TRISx register.
2. Enable interrupts for the selected CN pins by setting the appropriate bits in the CNENx
3. Turn on the weak pull-up devices (if desired) for the selected CN pins by setting the
appropriate bits in the CNPUx registers.
4. Clear the CNxIF interrupt flag.
5. Select the desired interrupt priority for CN interrupts using the CNxIP<2:0> control bits.
6. Enable CN interrupts using the CNxIE control bit.
When a CN interrupt occurs, the user should read the PORT register associated with the CN
pin(s). This will clear the mismatch condition and set up the CN logic to detect the next pin
change. The current PORT value can be compared to the PORT read value obtained at the last
CN interrupt to determine the pin that changed.
The CN pins have a minimum input pulse-width specification. Refer to the “Electrical
Characteristics” section of the specific device data sheet for further details.
It's another case of "RTFM" !!
2020/11/13 14:03:13
Also, by the time you read PORT, it might be different from what it was when the transition occurred. Therefore, if you have multiple CN interrupts, it may not be possible to figure out which of them caused the interrupt. INT interrupts are more reliable.
© 2021 APG vNext Commercial Version 4.5

Use My Existing Forum Account