I had a surprising (to me) problem with CodeWarrior on the 56F803. While running a slow, low-priority interrupt routine, CW masks all other peripheral interrupts by setting I1 in the status register high. This delays my SPI0 read interrupt sufficiently that I lose incoming serial data. I tried it with version 7.3 and 8.1.1a.
The slow interrupt handler uses #pragma interrupt saveall; the fast ones use #pragma interrupt.
I "fixed" it by putting asm(BFCLR #$0200,SR); at the start of the low-priority interrupt handler, but this seems like a bit of a hack, and I am concerned that there may be more involved.
Why did CW mask the interrupts, and what possible problems am I creating by un-masking them? Is there a compiler setting to change this behaviour?
Thank you for the example, it will be useful in the future. But unless I missed something, I don't think it addresses my immediate question.
The example uses Timer A0 at the lowest priority level. I am using Timer C0 for something similar, also at the lowest interrupt priority; it interrupts and runs sensor and control code once per millisecond. Its handler uses #pragma saveall.
I also have several other interrupt handlers running, including CAN, SPI, and SCI. The problem appeared when I tried to receive serial data from SCI0 into a buffer at 115.2 Kbaud. The interrupt handler for this is only about 10 lines of C code, and it uses #pragma interrupt. I gave this interrupt handler the highest priority level, because this MCU has only a one-byte hardware receive buffer. Arriving data must be moved to the software buffer within about 80 microseconds. The software buffer is a global array, which of course is also accessed by the parsing function which runs during the TMRC0 interrupt handler.
The interrupt enable bits in the Status Register (SR) are initially set to allow interrupts, during the DSP56F803_init.c function. However, at some point bit I1 is turned on, disabling peripheral interrupts. I think it happens during the TMRC0 handler, and it must be that I1 is turned off again later, because all of the higher level interrupts do run eventually. It just happens to be too late for SCI0 at 115.2 Kbaud.
If I set I1 to zero with asm(bfclr #$0200,SR); at the start of the TMRC0 handler, all seems well, and no incoming serial data is lost. This is not the case if I add a bfclr line to my startup and initialization code, not surprisingly.
Although the fix described above seems to work, it seemed to me that this interrupt masking was done by the compiler for some specific reason, or perhaps as a result of some specific setting, and I wondered what it was. I would like to have some confidence that my interrupts are running on time, even when the resulting problems are not as obvious. I have not been able to find any reference to this in the documentation yet.