Problem with interrupts on the PIC

All,

If you are attempting interrupts, please exercise extreme care if you are using any platform more powerful than the Edubot.

My issue is the lack of context saving. Please read section 9.9 of the “PIC18FXX20 Data Sheet” and section 10.3.1.7 of the “PICmicro® 18C MCU Family Reference Manual”.

To quote the latter: “If both low and high priority interrupts are enabled, the shadow registers cannot be used reliably for low priority interrupts, as a high priority interrupt event will overwrite the shadow registers.

If you implement the low priority interrupt as per the IFI white paper “Using Polled or Interrupt-driven Timers”, you are in for some problems as the WREG, BSR and STATUS registers will likely be trashed when a LPI is interrupted by an HPI.

I have a call in with IFI about this and have been promised that they will look at the issue.

I’ll keep everyone informed.

There are two ways to handle this.

If you are writing code in C use the #pragma interrupt InterruptHandlerLow according top the Microchip C compiler ref’ doc:
http://www.microchip.com/download/tools/picmicro/code/mplab18/51288b.pdf
the basic context should be saved for you.

In assembler the code to do this is:
MOVWF W_TEMP ; W_TEMP is in virtual bank
MOVFF STATUS, STATUS_TEMP ; STATUS_TEMP located anywhere
MOVFF BSR, BSR_TEMP ; BSR located anywhere
;
; USER ISR CODE
;
MOVFF BSR_TEMP, BSR ; Restore BSR
MOVF W_TEMP, W ; Restore WREG
MOVFF STATUS_TEMP,STATUS ; Restore STATUS

Which is found at the end of section 9 of the Pic18F8520 data sheet.

-Jim

I wrote a quadrature decoder for the PORTB change state interrupt pins (RB4-7, or IFI 3-6). It is simple and works great. Just enable the RB interrupt, assign it to low priority and enable global interrups and it works. I call my routine from the user_function_fast.c module in the low interrupt handler.

However. The system doesn’t work. As my shaft turns and the counts are accumulated the servo output pulses glitch and the serial I/O over the program port glitches. If I run my encoder fast enough the entire system crashes.

Attached is the code.

I have done a lot of embedded small system programming and I know what I am doing, however, this is my first time with a PIC, so there could be something I don’t understand. But looking at the dissasembly code it all looks ok. Interrupts off upon entry, re-enabled upon exit, call a single routine.

Any ideas? It sure looks like a classic race condition where something is crapping on something else. Maybe this is a C compiler thing?

Quadrature.zip (1.36 KB)


Quadrature.zip (1.36 KB)

Jim,

Thank you. Your input is basically the same as IFI gave me… My bad for not reading the C compiler manual more closely.

One of the issues is that your pragma fragment, the default code and the Timers White Paper is that all use:

*#pragma interrupt InterruptHandlerLow *

However, section 2.9.2 of “MPLAB® C18 C COMPILER USER’S GUIDE” indicates that

*#pragma interruptlow InterruptHandlerLow *

is the correct pragma to use. Otherwise, both high and low will use the same shadow registers and a high priority interrupt will eventually interrupt the low priority and trash your context.

Once again, thanks for your help.

Mike

Larry,

In addition to my comment above, please be sure that you read section 2.9.2 in it’s entirety. Specifically, I quote:

“If an interrupt service routine calls another function, the normal functions’ temporary data section (which is named .tmpdata) should be saved using a save=section(”.tmpdata") qualifier on the interrupt pragma command."

In your case, the pragma in User_Routines_Fast.c needs to be:

#pragma interruptlow InterruptHandlerLow save=section(".tmpdata")

I hope this fixes your glitching problem. It did for me…

I knew it was some sort of problem of crapping on another context. I missed the fact that any routine that is called by a handler needs to save additional information. IFI should have a sample of something called by a handler so folks know what is needed.

Thanks!

I updated the user_routines_fast.c with the correct #pragma and it now works much better. However, it still hangs the EDU controller if the interrupts come in too fast. I think that is simply the user processor saturating and not servicing the communications processor fast enough (i.e. not making it’s 17ms loop) and being shut down.

Again, thanks!

Innovation First has released a new set of Default Code for the EDU RC (12-15-2003). The only change is to the old line 54 of the user_routines_fast.c file. The change fixes a bug in which “interrupt” should have read “interruptlow”. It also shows an example of how to save some extra context if you are using interrupts.

This is only an example, and depending on your interrupt code and practices, you may need to save additional context on this line, in accordance with section 2.9.2 of the “MPLAB® IDE C18 C Compiler User’s Guide” (page 28).

Documentation and Files are located at http://www.innovationfirst.com/FIRSTRobotics/documentation.htm

I noticed we’re not supposed to use any of the high priority interrupts… I looked around a little bit and I notice there’s a handler already located in the IFI library file… but anyone know what they’re using it for?

Also… technically, couldn’t we just hook the interrupt similar to a TSR in DOS? Unfortunately I’m not going to have access to the controller until the beginning of the year so I’m just throwing code together and hopefully it works out.