We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
To anyone with intimate knowledge of the C167 interrupt system: The system I am working with uses a C167 processor to control an external device that communicates with the microcontroller over the SPI bus (MOSI/MISO/SCLK) on an interrupt basis. The problem I am experiencing is that the C167 appears to drop interrupts from this external device; that is, some interrupts from the device appear to be caught and handled by the C167 while others do not. The external device interrupts on P2.8 - a Fast Interrupt on port 2. This pin is set up as an input and the EXICON register is set to catch negative-edge transitions. Scope traces show that the levels are stable for the required 8 CPU cycles (at 20MHz = 400ns) in order for the edge to be recognized. I believe this is a software issue or system misunderstanding. Because the MOSI/MISO lines are used by multiple devices, including the one in question, I must disable and enable interrupts around code snipets that access the MOSI/MISO interface. I do so using: {_atomic_(0); IEN = 0; _nop_(); _endatomic_();}. I am wondering how the 167 handles interrupt requests. I assume that if an interrupt request from my external device comes in when interrupts are disabled that the corresponding CC8IR flag will be set and the interrupt will be serviced once interrupts are re-enabled. Is that correct? Furthermore, are interrupts from the same source also "queued" in this fashion? That is, when the ISR that handles the interrupt from my external device is executing and that device interrupts again, will the second interrupt be addressed after my ISR exits, or is that request lost for good?
Hello Nicholas, I assume that if an interrupt request from my external device comes in when interrupts are disabled that the corresponding CC8IR flag will be set and the interrupt will be serviced once interrupts are re-enabled. Is that correct? Yes. Furthermore, are interrupts from the same source also "queued" in this fashion? No. From your description I understand, that you use multiple SPI devices. One or more of them have an additional signal output, that you use as an interrupt source. If you avoid to do the SPI communication within the interrupt routine (ISR), you don't have to disable the interrupts. In your ISR just set a flag (or increment a counter, if you have to keep track of the number of interrupt events). In your main program periodically check for this flag (or counter) and do the required communication. Tim
Tim, Thanks for your insights. I ended up finding the problem in my code. It had to do with reentrancy. To anyone out there needing a reentrant subroutine for the C167, I recommend the following. If you are going to disable interrupts to resolve the reentrancy issue and you want to use IEN=0 to do so, enclose it in the following code sequence: _atomic_(0); IEN=0; _nop_(); _nop_(); _endatomic_(); This sequence borrows concepts from the #DISABLE pragma and enhances it with atomicity. Note: I have only seen recommendations for using a single _nop_() after the IEN=0 call. However, I still experienced interrupts with this solution. Keil's #DISABLE pragma uses 2 NOPs and that seems to do the trick!