Spi/interrupt infinite loop

Thread Starter

KCHARROIS

Joined Jun 29, 2012
311
Hello,

I'm currently programming a clock using an RTC there for I'm using SPI constantly. But I have this problem that when an interrupt occurs during an SPI transfer, when coming back from the ISR it stays stuck in a loop. Below is the code i use to send out data... Interrupt is high priority and I use RETFIE to return

MOVLW B'10101010'
MOVWF SSPBUF,A (AT SOME POINT INTERRUPT OCCURS)
LOOP
BTFSS SSPSTAT,BF
GOTO LOOP (THIS IS THE LOOP THAT IT STAYS STUCK IN)

Thanks
 

tshuck

Joined Oct 18, 2012
3,534
It sounds like something else. The interrupt allows the current instruction(opcode) to complete - move data to SSPBUF. After that point, it's under hardware control and an interrupt shouldn't be able to affect it.

Post your whole code...
 

RG23

Joined Dec 6, 2010
304
Try the following

MOVLW B'10101010'
MOVWF SSPBUF
LOOP
BTFSS SSPSTAT,BF
GOTO LOOP

movf SSPBUF,W ; empty the receive buffer
movwf data ; put received byte into data
retlw 0 ; return from subroutine

Also in place of retfie, use retfie FAST

If the above doesn't work, post the relevant code
 

Thread Starter

KCHARROIS

Joined Jun 29, 2012
311
Hello,

The code is massive... Its for a VFD tube clock that I designed and built but the problem is I send data through SPI but when the timer0 interrupt triggers, goes through its ISR subroutine, clear the interrupt flag, subroutine ends and i do use retfie and then it gets stuck in the loop when testing for SSPSTAT,BF.
 

RG23

Joined Dec 6, 2010
304
Is your timer0 interrupt high priority?

Did you try retfie FAST instruction?

Read about the fast register stack and context saving during interrupts in the datasheet.

Also make sure you have defined the priority setting correctly or else just remove the priority setting for now.

Check if the higher priority goes to org 8 and lower priority goes to org 18
 

JohnInTX

Joined Jun 26, 2012
4,787
You didn't say which PIC you were using but many have problems when polling BF in the SPI mode - like this one:
29. Module: MSSP (SPI Mode)
In SPI mode, the Buffer Full Status bit, BF
(SSPxSTAT<0>), should not be polled in software
to determine when the transfer is complete.
Work around
Copy the SSPxSTAT register into a variable and
perform the bit test on the variable. In Example 7,
SSPxSTAT is copied into the working register
where the bit test is performed (SSP1STAT is
shown, but this process is also applicable to
SSP2STAT).

A second option is to poll the appropriate Master
Synchronous Serial Port Interrupt Flag bit,
SSPxIF. This bit can be polled and will set when
the transfer is complete.
Date Codes that pertain to this issue:
All engineering and production devices.
Depending on the P/N, the MSSP errata (read: should work but doesn't) can have many issues. Note that the errata pertains to the silicon revision as well as the P/N. You can get the silicon rev. from your programmer usually. Its not necessarily discernible from the mfg/date codes on the chip without consulting Microchip.

Other than that, be sure you read SSPBUF (to get the received data) before writing it and make sure you only read it once per byte as it will clear BF when you do. Finally, be sure WCOL and SSPOV are monitored and handled in your code.

As for the fast return stack for 18F, if indeed you use it, be aware that many 18F devices have a problem there as well. If a 2 word instruction e.g. MOVFF is interrupted in the middle, the current values of W, BSR, and STATUS might not be properly copied to the fast return stack meaning that the interrupt context is corrupt. The solution is not to use it or use this code:
Rich (BB code):
Interrupt_Handler:
 call _foo,FAST ; re-copy W,BSR,STATUS to the fast return stack before doing anything else
_foo:
 pop ; blow off the call
... continue with interrupt processing
 retfie FAST
You should know that the errata is not always up to date. I know.. geezzze. I have learned, frequently the hard way, to always incorporate the workarounds even if not specifically called for (yet).

Good luck.
 
Last edited:

Thread Starter

KCHARROIS

Joined Jun 29, 2012
311
Ahhh, I see I will definitly try this method:

29. Module: MSSP (SPI Mode)
In SPI mode, the Buffer Full Status bit, BF
(SSPxSTAT<0>), should not be polled in software
to determine when the transfer is complete.
Work around
Copy the SSPxSTAT register into a variable and
perform the bit test on the variable. In Example 7,
SSPxSTAT is copied into the working register
where the bit test is performed (SSP1STAT is
shown, but this process is also applicable to
SSP2STAT).

A second option is to poll the appropriate Master
Synchronous Serial Port Interrupt Flag bit,
SSPxIF. This bit can be polled and will set when
the transfer is complete.
Date Codes that pertain to this issue:
All engineering and production devices.


I am using the pic18F26K80 so maybe that could be it.

Thanks
 

JohnInTX

Joined Jun 26, 2012
4,787
I should also mention that this problem does not occur when interrupts are disabled.
I didn't see anything in the errata but you never know. Be sure that you are not mixing interrupt-driven and polled SPI. Make sure that other interrupt handlers do not inadvertently poll BF or read SSPBUF.

With all the various problems the MSSP has had over the years, I always read the status and data registers into temp registers whether polled or interrupt driven then process on the temp regs. I like a snapshot that isn't affected by bus activity after I've read the regs.

If your SPI has a fast bit rate and you are not sending/receiving volumes of data, consider just doing it in the main (not interrupt) program. Its true that waiting for BF after writing SSPBUF takes some time, at a fast bit rate, its not much compared to the overhead of servicing interrupts. You can mitigate some of the lost time while its transmitting by doing housekeeping chores (fetching the next byte from the buffer etc).
 

JohnInTX

Joined Jun 26, 2012
4,787
Solved!!!

DO NOT TOUCH THE TMR2 REGISTER IT WILL SCREW EVERYTHING UP.

Thanks for the ideas though, definitely a good learning experience, here's a look at the clock if anybody is interested.
Its 41 O'clock?

There really isn't any reason that TMR2 should have anything to do with the MSSP, based on what you have reported so I would personally be a little reluctant to declare success..

But nothing beats seeing it working to this point. While enjoying it, think about why TMR2 affects the MSSP..

That said, the project looks very nice..
Good work!
 

Thread Starter

KCHARROIS

Joined Jun 29, 2012
311
Alright turns out TMR2 wasnt the problem so I ended up flopping the interrupt idea and to just check the flags every so often and it worked great. But heres the new problem, everytime I program the pic through pic kit 3 it works fine even when the pickit is removed. But when I turn it off and then back on the clock goes in a weird state, led's are blinking, etc. How do i set up the pic to start up correctly without the pickit3?

Thanks for the help!
 

ErnieM

Joined Apr 24, 2011
8,377
Are you compiling for a debug build? It should be release.

If it then seems to work until you remove the PICkit check you have a pull up on MCLR.
 

JohnInTX

Joined Jun 26, 2012
4,787
Are you compiling for a debug build? It should be release.

If it then seems to work until you remove the PICkit check you have a pull up on MCLR.
And don't forget to set all of the CONFIG bits for the processor as well. Debug builds to this to suit the PICkit but leave them to you for release builds.
 

Thread Starter

KCHARROIS

Joined Jun 29, 2012
311
Thats the thing I do have a pullup resistor on the mclr pin and it is in release. Heres my code if your interested in looking at it, its not verywell commented yet butthe config bits are at the top of the code.

Thanks

CONFIG RETEN = OFF, INTOSCSEL = LOW, FOSC = INTIO1, PLLCFG = OFF, FCMEN = OFF
CONFIG IESO = OFF, PWRTEN = OFF, BOREN = OFF, WDTEN = OFF, MCLRE = OFF, STVREN = OFF
CONFIG XINST = OFF, SOSCSEL = DIG, CANMX = PORTC, BBSIZ = BB2K, CP0 = ON,CP1 = ON
CONFIG CP2 = ON, CP3 = ON, CPB = ON, CPD = ON, WRT0 = ON, WRT1 = ON, WRT2 = ON
CONFIG WRT3 = ON, WRTC = ON, EBTR0 = ON, EBTR1 = ON, EBTR2 = ON
CONFIG EBTR3 = ON, EBTRB = ON
 

Attachments

Thread Starter

KCHARROIS

Joined Jun 29, 2012
311
Sratch that, forgot to remove a line in the code that shouldnt be have been there causing the eratic behavior and going into limbo. Anyways the clock is done, thanks for the help and advice it was well well appreciated.

I've added pictures of what the clock looks like in the casing and everything. I have a button in the back that is used to change the clock time with the three pots on theright side of the clock but when the button from the back is not pressed, the pots are used to change the color of the LED's. I used the tlc5940 for led color, ds1306 for time, max6921 for tube driver and pic18f26k80 as microcontroller.

Would AAC appreciate if I added my clock to the completed projects for other to build?

Thanks
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
I have a button in the back that is used to change the clock time with the three pots on theright side of the clock but when the button from the back is not pressed, the pots are used to change the color of the LED's.
Looks great! I scanned your code and saw the analog stuff. Nice way to do it! Very pretty package as well.
 
Top