dspic33f different interrupt priority levels for freertos api calling ISR

dragonflight1 wrote on Thursday, November 07, 2013:

swissEmbeded

As in my response to Richard (not Richard Damon), my stuff did not change the semantics of the port, so it wouldn’t work differently.

Having said that I’m not sure why your changing the SR register caused things to fail (at least the way you described), the correct IPL would have been restored when you exited the interrupt.

You did say that the interrupt was not FreeRTOS API free, and that would cause bad things to happen it you went to (configKERNEL_INTERRUPT_PRIORITY+1) for the reasons in previous posts.

Richard Damon has brought up a point (nesting FreeRTOS calls) that I assumed worked because the PIC port instructions included instructions for changing configKERNEL_INTERRUPT_PRIORITY. I even … (more excuses)
He is at least half correct, there is a problem. I think I haven’t seen the problem because my interrupts don’t share queues, but …

Regardless, I wanted you to be very wary of using multiple interrupt levels (for now). I’m onto another project, but I need (well want) nested interrupts and I will figure it out - though it might not be tomorrow!.
I have started another thread about this and hopefully Richard Damon will be kind enough to lead me through the problems (and hopefully solutions)

mike

swissembedded wrote on Friday, November 08, 2013:

Mike, I’m using some libs from microchip. Those libs heavily modify registers for DSP instructions, those registers needs to be reset/restored in the ISR (sr, corcon, modcon is enough).

BTW I added the following traps in my main. AddressError might be helpfull.

//Error traps

//Oscillator Fail Error trap routine
void attribute((interrupt, auto_psv)) _OscillatorFail(void)
{
INTCON1bits.OSCFAIL=0;
for(;;);
}

//Address Error trap routine
void attribute((interrupt, auto_psv)) _AddressError(void)
{
INTCON1bits.ADDRERR=0;
for(;;);

}

//Stack Error trap routine
void attribute((interrupt, auto_psv)) _StackError(void)
{
INTCON1bits.STKERR=0;
for(;;);
}

//maths (Arithmetic) Error trap routine
void attribute((interrupt, auto_psv)) _MathError(void)
{
INTCON1bits.MATHERR=0;
for(;;);
}

Dave, Richard ^2, Mike, thank you yery much for your help.

dragonflight1 wrote on Friday, November 08, 2013:

I thank you for your thank you, but all I’ve done so far is lead you astray!

The current port doesn’t handle modcon. I wondered about that, but left it till I got to the point where I can play with the math stuff. I kinda felt that if interrupts worked then all would be ok, and if they didn’t then the math routines would disable interrupts to protect, but I checked and they don’t
in fact I found a post that included this warning (from Microchip)

“When integrating with the DSP Library, you must examine the Function Profile of each function description to determine which resources are used. If a library function will be interrupted, it is your responsibility to save and restore the contents of all registers used by the function, including the state of the DO, REPEAT and special addressing hardware. Naturally this also includes saving and restoring the contents of the CORCON and Status registers.”

So, as far as I have read the problem with modcon is that it affects how a register is used, say W3. If the interrupt routine (or anything it calls) uses W3 as a pointer bad things will happen. If this is true then you need to modify the timer routine in port.c to save and reset it (and anytime you call taskYield()).

I did a quick google of
modcon interrupt
and got some interesting results (but old) including a post in FreeRTOS

https://sourceforge.net/p/freertos/discussion/382005/thread/cc40786a

a couple (related) suggested they needed to initialize CORCON to 0x24 or they got an address error (I’m guessing what they really needed to do was CORCON |=0x04, though why PSV access would be disabled???

I seem to be taking an unhealthy interest in the PIC24 port, so I would appreciate your feedback on what it takes to get your stuff working. (plus I want to play with the math stuff sometime this winter)

As all task switches in the port are done either through interrupts or in idle
all that may be necessary is to make sure DSP users replace the timer1 interrupt.

saving stuff is one thing, but more ominous is having to reset corcon and modcom and ???

mike

richard_damon wrote on Saturday, November 09, 2013:

First, my comment on using DMA was just a suggestion on a way to reduce processor load. It still might be possible to use the DMA, even if you need to send the data to two places, as you can setup, I believe, 2 DMA channels, for for each output device and start them up together.

The key to the ring buffer idea was to make the ISR FreeRTOS free, so it would be allowed to be at a higher interrupt level, and thus not influenced by the other interrupts and be able to nest with them. If you have a requirement to absolutely minimize latency to the interrupt, this might be important.

Another option would be to work to rewrite the port layer to allow nested ISRs as has been discussed. This isn’t an impossible task, but does have some interesting design issues.

It also sounds like something needs to be done to fix the CORCON / modcon problem. I haven’t looked enough at the issues on that to give advice. My dsPic work didn’t need to use them so I didn’t study them enough.

dragonflight1 wrote on Monday, November 11, 2013:

I don’t think you need it, but if you want to try it, I have a solution for fully nested interrupts.

mike