Monday, June 23, 2014

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


  1. The PIC32MX1xx/2xx have only one register set (ie. no shadow registers).

    1. I seemed to have missed that in the datasheet while concentrating on the reference manual. So, I guess it's best to force the compiler to use software context save/restore when using ipl7 instead of the default AUTO mode. At least that's what my little 'experiment' just taught.

      I'll edit the article to reflect this.

      Thanks for your input!

  2. I posted asking for some help and you have deleted my post. Why?

    1. The question you posted was in no way relevant to the PIC32. If you post in the relevant section, I will gladly answer it.

  3. I see. I apologize, but you could have answered as you just said now, instead of you have deleted my comment. It would be more polite on your part.
    Anyway, now I commented on the post IR2110.


  4. Hey Tahmid, the Smart Sine software links thay you gave is not available any more, if I ask you can you share it again. Thanks a lot.

  5. Hi, I have been working on pic32mx250f128b and not getting command on the basics. By basics i mean i am not able to interface LCD and having problem in serial communication :(. Can u help me or suggest me anyone of ur blog.? plzzzzzzzz

  6. Are you working on bipolar or unipolar spwm?

  7. It's a Nice post! Thank you for sharing your knowledge to others, it was very informative and in depth one.
    R Training in Electronic City