This took me ages to find and might be the reason why there are so many questions on this forum about interrupts not working properly...
I incorporated the Freescale USB Stack v4.0.2 into my project. It works just fine as a USB Device but causes problems with the GPIO interrupts I also need. Following my start-up code in my debugger I could see that my GPIO interrupts were being configured correctly but, as soon as I ran the USB_init() function, all my existing interrupts were being disabled and only the USB interrupt was enabled. And here's why...
USBinit contains two coding errors in this line :-
NVICICER2 |= (1 << 9); /* Clear any pending interrupts on USB */
1) It calls NVICICERx instead of NVICICPRx to clear pending interrupts.
While ICER (Interrupt Clear Enabled Register) disables interrupts, this would not be harmful on its own, but it was the way it was coded which caused the problem.
2) NVICICERx was being used with |= so it was reading the state of all existing interrupts, ORing those with the USB interrupt, then writing those bits back to ICER. So all existing interrupts were being disabled. The following line was just enabling the USB interrupt.
NVICICERx is a write-to-clear register so all we need to do to clear a single interrupt is to write a one in that particular bit position. All zeros are ignored. Other NVIC registers work in a similar way with both SET and CLEAR variants. Using OR is wrong.
I did a search of my project and found this error scattered throughout the Freescale examples. I also found the same code being used to reset the Interrupt Status Flags (PORTx_ISFR), ie, using |= when we should just use =
To be honest this is not something I wouldn't have expected from Freescale, but having read other reports of demos not working, I can now see the error in that assumption. So please Freescale, get this fixed because wasting programmers time is a frustrating and costly exercise...