• AVR Freaks

Hot!18F97J60 Interrupt Issue

Author
Antimatter
Starting Member
  • Total Posts : 64
  • Reward points : 0
  • Joined: 2012/10/18 21:39:12
  • Location: Salt Lake City
  • Status: offline
2020/03/13 11:00:26 (permalink)
0

18F97J60 Interrupt Issue

I have a curious interrupt problem on a 18F97J60 that I have yet to resolve:
  • I am using interrupt priority.
  • The high priority ISR exclusively services the Ethernet (only blinks LED) and PKT Pending Ints.
  • The low priority ISR services TMR1 and TMR2. TMR1 is clocked from an external source and is used as a RTC. TMR2 is clocked from Fosc/4.
  • If I use  RETFIE 1 (Fast Return) on both Low and High ISRs problems with register corruption occurs. This is expected because the High priority interrupt will interrupt the Low priority interrupt at any given moment and corrupt the WREG, BSR, and STATUS. This is documented in the forum.
  • If I use the Fast Return (RETFIE 1) to end the High ISR and a RETFIE 0 to end the Low ISR saving and restoring WREG, STATUS and BSR registers per datasheet an endless loop occurs in the main program several call levels deep. Exact cause unknown at this time. Something to do with a time delay loop using TMR0???. TMR0 does not have IE set at any time. This was the recommended way described elsewhere in the forum.
  • If I use the Fast Return (RETFIE 1) to end the Low ISR and end the High ISR with RETFIE 0 saving and restoring WREG, STATUS and BSR registers per the datasheet it appears to work fine but I can foresee some issues with this.
How can this behavior be explained and what will fix it?
 
post edited by Antimatter - 2020/03/13 11:01:40
#1

17 Replies Related Threads

    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11982
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/03/13 13:18:14 (permalink)
    +2 (2)
    Does your PIC have the interrupt priority errata?  Does your code work when you don't use interrupt priorities?
    #2
    ric
    Super Member
    • Total Posts : 28324
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F97J60 Interrupt Issue 2020/03/14 02:42:46 (permalink)
    +4 (4)
    Antimatter
    If I use the Fast Return (RETFIE 1) to end the Low ISR and end the High ISR with RETFIE 0 saving and restoring WREG, STATUS and BSR registers per the datasheet it appears to work fine but I can foresee some issues with this.

    That is not how it should be used, and willl certainly corrupt the non interrupt registers if you get a HP interrupt inside a LP interrupt
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    Antimatter
    Starting Member
    • Total Posts : 64
    • Reward points : 0
    • Joined: 2012/10/18 21:39:12
    • Location: Salt Lake City
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/17 10:29:32 (permalink)
    0
    OK so for some reason in the Low priority ISR I had some code between the stack restoring and the RETFIE. Must have happened when I was pasting code. That was the cause of the hang. After correcting the code there was no hang up in the ISR.

    I believe originally I wasn't using interrupt priority and yes the problem was there in the original code. 
     
    I have checked the device errata. I have revision A3 and it appears in this situation I am OK. 

    Now I am using the fast return on the High ISR and saving and restoring manually in the Low ISR:


    ;=================================
    ISR_LOW
    ;=================================
    ;CONTEXT SAVE
    BANKSEL W_LO
    MOVWF W_LO
    MOVFF STATUS, STATUS_LO
    MOVFF BSR, BSR_LO

    ...


    ;CONTEXT RESTORE
    MOVFF BSR_LO, BSR
    MOVFF STATUS_LO, STATUS
    BANKSEL W_LO
    MOVF W_LO, W
    RETFIE
     
    Interestingly, though to get passed the main problem, I disable the Low Priority Interrupts (IPEN = 0) before calling any Ethernet, Display, or RTC subroutines and enable them immediately after the subroutine returns. Things work perfectly that way. Perhaps this is a clue to the source of the problem?
     
    If I don't disable the Low Priority Interrupts before calling the display routines I get corrupted information on the display. The driver routines consist of writes to PORTJ (display data bus) and PORTB (display control bus). Could be an impedance issue with the port pins perhaps? The errata does mention PORTJ although I don't think it is applicable here. Here is some typical driver code for the display:


    ;----------------------------------------
    ;WRITE COMMAND - CASET (COLUMN SET) (2AH)
    ;----------------------------------------
    CASET
    GLOBAL CASET
    BANKSEL PORTB
    ;RS
    BCF PORTB, 1
    ;WR
    BCF PORTB, 2
    ;DATA
    MOVLW 2AH
    MOVWF PORTJ
    ;WR
    BSF PORTB, 2
    ;RS
    BSF PORTB, 1
    ;WRITE COLUMN START ADDRESS HIGH
    ;WR
    BCF PORTB, 2
    ;DATA
    MOVFF CASET_START_HI, PORTJ
    ;WR
    BSF PORTB, 2
    ;WRITE COLUMN START ADDRESS LOW
    ;WR
    BCF PORTB, 2
    ;DATA
    MOVFF CASET_START_LO, PORTJ
    ;WR
    BSF PORTB, 2
    ;WRITE COLUMN END ADDRESS HIGH
    ;WR
    BCF PORTB, 2
    ;DATA
    MOVFF CASET_END_HI, PORTJ
    ;WR
    BSF PORTB, 2
    ;WRITE COLUMN END ADDRESS LOW
    ;WR
    BCF PORTB, 2
    ;DATA
    MOVFF CASET_START_LO, PORTJ
    ;WR
    BSF PORTB, 2
    RETURN


    ;-------------------------
    ;WRITE COMMAND - RAMWR (2CH)
    ;-------------------------
    RAMWR
    GLOBAL RAMWR

    BANKSEL PORTB
    ;RS
    BCF PORTB, 1
    ;WR
    BCF PORTB, 2
    ;DATA
    MOVLW 2CH
    MOVWF PORTJ
    ;WR
    BSF PORTB, 2
    ;RS
    BSF PORTB, 1
    ;WRITE DATA
    ;WR
    BCF PORTB, 2
    ;COLOR DATA
    MOVFF COLOR_DATA_UP, PORTJ
    ;WR
    BANKSEL PORTB
    BSF PORTB, 2

    ;WRITE DATA
    ;WR
    BCF PORTB, 2
    ;COLOR DATA
    MOVFF COLOR_DATA_HI, PORTJ
    ;WR
    BANKSEL PORTB
    BSF PORTB, 2
    ;WRITE DATA
    ;WR
    BCF PORTB, 2
    ;COLOR DATA
    MOVFF COLOR_DATA_LO, PORTJ
    ;WR
    BANKSEL PORTB
    BSF PORTB, 2
    RETURN
    #4
    Jerry Messina
    Super Member
    • Total Posts : 549
    • Reward points : 0
    • Joined: 2003/11/07 12:35:12
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/17 15:06:44 (permalink)
    +3 (3)

    ;=================================
    ISR_LOW
    ;=================================
    ;CONTEXT SAVE
    BANKSEL W_LO
    MOVWF W_LO

    In that code, the BANKSEL is going to destroy the BSR register before you get a chance to save it.
     
    Likewise, your RESTORE CONTEXT routine restores BSR and then overwrites it with a BANKSEL before it returns.
     
    Change the order of saving/restoring those registers and it might work a bit better.
    #5
    ric
    Super Member
    • Total Posts : 28324
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F97J60 Interrupt Issue 2020/05/17 15:13:00 (permalink)
    +2 (2)
    +1
    Doesn't the recommended code use MOVFF instead?
    As mentioned, you can't use BANKSEL there.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    Jerry Messina
    Super Member
    • Total Posts : 549
    • Reward points : 0
    • Joined: 2003/11/07 12:35:12
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/17 16:39:48 (permalink)
    +1 (1)
    Doesn't the recommended code use MOVFF instead?

    Might depend where you look. I see this in a number of places...

    MOVWF W_TEMP ; W_TEMP is in virtual bank

     
    I'm with ric. I'd just use MOVFF (or MOVFFL if req'd by the device) and skip worrying about where W_TEMP is.
    MOVFF  W, W_TEMP
     
    #7
    ric
    Super Member
    • Total Posts : 28324
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F97J60 Interrupt Issue 2020/05/17 16:54:29 (permalink)
    +2 (2)
    Jerry Messina
    Doesn't the recommended code use MOVFF instead?

    Might depend where you look. I see this in a number of places...

     
    MOVWF W_TEMP ; W_TEMP is in virtual bank
     

    Presumably that means the scratch is in the ACCESS bank, so doesn't need BANKSEL.
    I was referring to "EXAMPLE 10-1: SAVING STATUS, WREG AND BSR REGISTERS IN RAM" in the datasheet for that PIC.
     
    I guess MOVFF is one clock cycle slower than using the ACCESS bank, which could be a consideration if you're trying to shave the low priority ISR down to the minimum number of cycles.
    (Assuming the HP ISR is already taken by something that's even tighter...)
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #8
    Jerry Messina
    Super Member
    • Total Posts : 549
    • Reward points : 0
    • Joined: 2003/11/07 12:35:12
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/18 03:18:45 (permalink)
    +2 (2)
    I was referring to "EXAMPLE 10-1: SAVING STATUS, WREG AND BSR REGISTERS IN RAM" in the datasheet for that PIC

    Me too. That's where I pulled that line of code from.
     
    It might not be obvious to someone doing this for the first time that you need to ensure that W_TEMP gets put into the ACCESS bank. At least that version has a comment to that effect... others don't.
    #9
    Antimatter
    Starting Member
    • Total Posts : 64
    • Reward points : 0
    • Joined: 2012/10/18 21:39:12
    • Location: Salt Lake City
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/24 08:15:17 (permalink)
    0
    OK so I used MOVFF to save the WREG and it seems to work! I removed all the code disabling the Low Priority ISR before calling subroutines and I have yet to see any problem.


    ;CONTEXT SAVE
    MOVFF WREG, W_LO
    MOVFF STATUS, STATUS_LO
    MOVFF BSR, BSR_LO

    ...


    ;CONTEXT RESTORE
    MOVFF BSR_LO, BSR
    MOVFF STATUS_LO, STATUS
    MOVFF W_LO, WREG

    Fabulous!
    #10
    ric
    Super Member
    • Total Posts : 28324
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F97J60 Interrupt Issue 2020/05/24 13:08:57 (permalink)
    0
    +1.
    Have you worked out WHY it is necessary?
    That might give you a better understanding of how interrupts work.
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #11
    Antimatter
    Starting Member
    • Total Posts : 64
    • Reward points : 0
    • Joined: 2012/10/18 21:39:12
    • Location: Salt Lake City
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/24 19:18:59 (permalink)
    0
    Yes, I understand why it is necessary. It got passed me. It didn't occur to me that the BANKSEL prior to the BSR push changed the BSR register that I was trying to push in the first place. I also could have done this instead of the MOVFF:


    ;CONTEXT SAVE
    MOVFF STATUS, STATUS_LO
    MOVFF BSR, BSR_LO
    BANKSEL W_LO
    MOVWF W_LO

    ...


    ;CONTEXT RESTORE
    MOVFF STATUS_LO , STATUS
    MOVFF BSR_LO, BSR
    BANKSEL W_LO
    MOVF W_LO, WREG
     
     





    #12
    1and0
    Access is Denied
    • Total Posts : 11125
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/24 21:05:06 (permalink)
    +2 (2)
    Antimatter
    Yes, I understand why it is necessary. It got passed me. It didn't occur to me that the BANKSEL prior to the BSR push changed the BSR register that I was trying to push in the first place. I also could have done this instead of the MOVFF:
     
    ;CONTEXT RESTORE
    MOVFF STATUS_LO , STATUS
    MOVFF BSR_LO, BSR
    BANKSEL W_LO
    MOVF W_LO, WREG

     
    Try again. ;)
     
     
    Edit: Just noticed your code in Post #4, do use LATx for output.
     
    post edited by 1and0 - 2020/05/24 21:10:45
    #13
    Antimatter
    Starting Member
    • Total Posts : 64
    • Reward points : 0
    • Joined: 2012/10/18 21:39:12
    • Location: Salt Lake City
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/25 08:22:31 (permalink)
    -1 (1)
    I use PORTx for output. When TRISx is cleared to zero a write to LATx and PORTx are the same. A write to the PORTx register writes the data value to the port latch. 



    #14
    1and0
    Access is Denied
    • Total Posts : 11125
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/25 08:26:59 (permalink)
    +2 (2)
    Antimatter
    I use PORTx for output. When TRISx is cleared to zero a write to LATx and PORTx are the same. A write to the PORTx register writes the data value to the port latch. 

     
    I don't have the time to explain now. If you want to know, search and read about Read-Modify-Write (RMW) in this forum or google.
     
    LISTEN -- READ FROM PORTx and WRITE TO LATx !!!
     
     
    #15
    upand_at_them
    Super Member
    • Total Posts : 637
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: online
    Re: 18F97J60 Interrupt Issue 2020/05/25 08:50:23 (permalink)
    +2 (2)
    AntimatterI use PORTx for output. When TRISx is cleared to zero a write to LATx and PORTx are the same.

     
    They're only the same if you write the ENTIRE port.  Just go through LATx as mentioned.
    #16
    1and0
    Access is Denied
    • Total Posts : 11125
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: 18F97J60 Interrupt Issue 2020/05/25 09:06:29 (permalink)
    0
    One more thing, there is NO need to BANKSEL PORTx as most SFRs are located in the Access RAM.
    #17
    ric
    Super Member
    • Total Posts : 28324
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F97J60 Interrupt Issue 2020/05/25 13:18:09 (permalink)
    +1 (1)
    Antimatter
    I use PORTx for output. When TRISx is cleared to zero a write to LATx and PORTx are the same. A write to the PORTx register writes the data value to the port latch.

    I have seen the same WRONG argument hundreds of times.
    As 1and0 mentioned that is only valid when you write the entire port.
    When you use a BSF or BCF instruction, the other 7 bits in the same port get overwritten by the value read from the PORTx register. That is WHY the LATx registers exist.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #18
    Jump to:
    © 2020 APG vNext Commercial Version 4.5