Spi/interrupt infinite loop

Discussion in 'Programmer's Corner' started by KCHARROIS, Oct 22, 2013.

  1. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    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
     
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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...
     
  3. RG23

    Active Member

    Dec 6, 2010
    301
    2
    Try the following


    Also in place of retfie, use retfie FAST

    If the above doesn't work, post the relevant code
     
  4. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    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.
     
  5. RG23

    Active Member

    Dec 6, 2010
    301
    2
    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
     
  6. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    You didn't say which PIC you were using but many have problems when polling BF in the SPI mode - like this one:
    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:
    Code ( (Unknown Language)):
    1. Interrupt_Handler:
    2.  call _foo,FAST ; re-copy W,BSR,STATUS to the fast return stack before doing anything else
    3. _foo:
    4.  pop ; blow off the call
    5. ... continue with interrupt processing
    6.  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: Oct 23, 2013
  7. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    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
     
  8. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    I should also mention that this problem does not occur when interrupts are disabled.
     
  9. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    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).
     
  10. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    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.
     
  11. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    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!
     
  12. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    TMR2 was likely used for multiplexing and/or PWM brightness control of the digits. :)
     
  13. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Happy to hear you figured it out, and, the clock looks fantastic. Bravo!

    Cheerful regards, Mike
     
  14. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    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!
     
  15. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,395
    1,607
    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.
     
  16. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    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.
     
  17. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    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
     
  18. KCHARROIS

    Thread Starter Member

    Jun 29, 2012
    292
    1
    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
     
  19. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    Looks great! I scanned your code and saw the analog stuff. Nice way to do it! Very pretty package as well.
     
Loading...