Browse over 10,000 Electronics Projects using the Page Numbering provided at the bottom of each Page.

PIC32MX250F128B ipl7: odd shadow register set behavior and observations

PIC32MX250F128B ipl7: odd shadow register set behavior and observations
This issue has now been solved. Scroll to the bottom for the update.

I started working on a pure sine wave inverter based on the PIC32MX250F128B. The first stage was to just get the SPWM working and test that before proceeding to add the power stage, feedback and other control, etc.

This led me to some interesting observations regarding the PIC32MX250F128B interrupts, especially the use of the shadow register set and a related problem.
I set up Timer 2 to be the time base for sine wave generation (DDS/SPWM) using OC1. In the Timer 2 interrupt, the duty cycle update request is performed (OC1RS is updated). Timer 2 interrupt priority was set to 7.

This all worked fine. The initial ISR definition was:

void __ISR(_TIMER_2_VECTOR, ipl7) T2int(void) {

However, when I used the ADC (input from potentiometer for amplitude control – a start at implementing feedback), accessing any of the ADC registers in the while (1) loop in main stopped the PIC32 from working. 

I then added a line of code in main to continuously toggle RA0 (PORTA bit 0). This would stop when trying to access the ADC registers as well. (It worked fine if I removed the code that accessed the ADC.) This meant that the core was being stopped. So, I thought that it might be some kind of exception being thrown (?).

However, changing the timer 2 interrupt priority from 7 (which I had initially) to anything else fixes the problem. My guess was that something went wrong when the shadow register set was being used for interrupt priority level 7 (?).

So I did some more tests and came up with this:

The way I have the ISR defined initially selects the “AUTO” mode of selection where, I believe, the compiler decides whether to use the shadow register set or software for context save/restore.

Forcing the compiler to use the software context save/restore instead of the shadow register set seems to fix it:

void __ISR(_TIMER_2_VECTOR, ipl7SOFT) T2int(void) {

I forced the shadow register set just to confirm:

void __ISR(_TIMER_2_VECTOR, ipl7SRS) T2int(void) {

and sure enough it didn’t work.

So, since it worked with ipl6, my guess was that for ipl6 (and for any ipl except 7), the compiler chooses software for AUTO, whereas for ipl7, the compiler chooses SRS.

So, I forced the shadow register set on ipl6:

void __ISR(_TIMER_2_VECTOR, ipl6SRS) T2int(void) {

and sure enough, it didn’t work.
Forcing software for ipl6 fixes it (as does AUTO).
I looked through the errata of the chip and couldn’t find anything. (The errata is an interesting read.)  I am also a little surprised since I did have ipl7 running fine previously. Maybe something weird happens with a certain combination of peripherals (?) that I unfortunately happened to use. I’ll still see if I can find this documented, and I’ll have to check whether an exception is thrown and if so, what type. If nothing else, at least it was a nice, albeit frustrating, lesson. Hopefully, it’ll help someone else who might run into a similar problem.

UPDATE/SOLUTION: It turns out that the PIC32MX250F128B does not have a shadow register set, as mentioned in the datasheet. I seemed to have missed that while concentrating on the reference manual which talks about the shadow register set for the PIC32 series. Thus, from the point of view of my ‘experiments’, the lesson learnt could very well just be that when using ipl7, force the compiler to use software instead of the default AUTO mode (which may make the compiler try to use the shadow register set, which doesn’t exist – explaining the problem I faced earlier).

DDS = direct digital synthesis
ipl = interrupt priority level
ISR = interrupt service routine 
SPWM = sinusoidal pulse width modulation
SRS = shadow register set