 |
 |
| View previous topic :: View next topic |
| Author |
Message |
allenhuffman
Joined: 17 Jun 2019 Posts: 657 Location: Des Moines, Iowa, USA
|
| PIC24 interrupts - clear_interrupt() from inside an ISR? |
Posted: Sat Feb 28, 2026 10:56 pm |
|
|
To paraphrase... "When everything is the highest priority, nothing is the highest priority."
We use I2C for messages between our PIC24-based boards and a PC host program. We use the I2C interrupt to process a write or read from the PC master. This works well.
Recently, I updated firmware on a board which added new hardware to trigger a pin during a PWM pulse on an RF detector. The pins (two detectors) get mapped to the Change Notification Interrupt (INT_CNI). The interrupt fires on the rising edge and falling edge. Since both detectors normally see the same RF signal, this means four interrupts fire each PWM pulse.
At the 10,000 Hz pulse rate, that could be 40,000 interrupts a second. Since they all go to the same routine, which checks for the high status of the CNI pins... Pseudo code:
| Code: | if input_state (FWD_DET_PIN) || input_state (REF_DET_PIN)
{
...read the detector via SPI...
} |
If both pins trigger, I believe the CNI is only called once since it is already pending when the second pin goes high. This works well.
But, it does introduce issues if the I2C interrupt is handling an incoming byte, potentially delaying a PWM pulse. As far as I can see, we have enough wiggle room in our pulse that an i2c_read/i2c_write likely is not an issues. (We delay about 20 us to let the signal stabilize, then read, and have almost 20 us left after the SPI read).
But, it seems the PWM delay can sometimes/often throw off the I2C timing so the one byte RBF is full and misses something or -- worse -- at the end of a message we miss capturing the I2C stop bit condition. Without the deadlock check I added years ago, it would hang and the watchdog would reset.
I am experimenting with solutions.
Q1) For example, could I simply do a "clear_interrupt (INT_CNI)" at the end of my I2C handling ISR? We can throw away a pulse and catch the next one.
Side note: my personal solution was to never have the PWM interrupts enabled until we need a reading (we do not need 10,000 readings a second, even if our PIC could keep up with that many). This delays the reading by one pulse which is still more than fast enough. BUT, even doing this, that pulse seems to mess up an I2C thing.
Q2) I am also considering just using the first I2C interrupt, then staying in that loop polling the message bytes, rather than letting other things run in between I2C read/writes. This will slow things down, but a reliable message system is more important (and the PIC is handling the main loop way faster than the PC can hope to poll it over I2C).
I assume many have dealt with multiple "highest priority" interrupts, and wonder what other solutions there might be.
Thanks for any tips. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202, 24FJ64GA002 and 24FJ1024GA606. |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20040
|
|
Posted: Sun Mar 01, 2026 7:12 am |
|
|
Could you reset a timer whenever you enter the CNI interrupt?.
Then have the I2C routine test this timer, and only clear age CNI
interrupt if the time is greater than you would expect since the last PWM
handling event.
If the I2C is higher priority than the PWM, can''t you just lower the
PWM priority one step?. Given there are 8 priority levels you should
still be OK. The PIC24, doesn't just have high/low priority interrupts,
it has multiple priority levels. If both interrupts have the same priority
level, then neither can interrupt the other. If you give them different
levels, you can choose which can interrupt the other. |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|