• AVR Freaks

Hot!I get interrupts after disabling them. Why?

Author
user2x
Super Member
  • Total Posts : 317
  • Reward points : 0
  • Joined: 2011/02/10 20:43:36
  • Location: 0
  • Status: offline
2019/10/29 15:08:13 (permalink)
0

I get interrupts after disabling them. Why?

I have the following simplified code:
It frequently  hits the breakpoint as set in the IRQ handler, indicating tha tI got an interrupt AFTER turning them off.
 
There are other indications substantiating the claim in that changes get made to LATB from irq handlers (to other pins) while the interrupt is disabled in the function below. The result is a unexpected output on LATB = corrupt.
 
Why would that be happening and is there a workaround?
 

volatile uint16_t int_detect = 0;
 
void Test1(void)
{
   __builtin_disable_interrupts(); 
   int_detect = 1;
   temp_lat = LATB & off_mask;
   LATB = temp_lat | on_mask;
 
   int_detect = 0;
   __builtin_enable_interrupts();
}
 
 
void __attribute__((interrupt, no_auto_psv))_T1Interrupt(void)
{
   if (int_detect)
       int_detect++;    //BREAKPOINT HERE
   IFS0bits.T1IF = 0; // Clear irq Flag
   Comms_T1_Handler();
}

#1

12 Replies Related Threads

    ric
    Super Member
    • Total Posts : 24202
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: I get interrupts after disabling them. Why? 2019/10/29 15:20:15 (permalink)
    +1 (1)
    Which PIC are you using?
     
    What happens if you insert a NOP between these two lines?
       __builtin_disable_interrupts(); 
       int_detect = 1;


    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!
    #2
    du00000001
    Just Some Member
    • Total Posts : 3156
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 15:29:27 (permalink)
    +1 (1)
    Could it be you're not servicing the interrupt properly - resulting in the IRQ persisting?
    I could imagine that in this case the interrupt disable won't have the desired effect - - - until the interrupt has been serviced as required.
    (IIRC, the disable prevents the setting of  the IRQ  during the rising edge of some IF. Once the IRQ is set, you may be requested to do whatever is required to clear it prior the interrupt disable effecting the disable. Just an educated guess ...)

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #3
    user2x
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 15:40:15 (permalink)
    0
    Sorry, of course,
     
    It is PIC24FJ32GA002
     
    I just checked the registers as follows when I hit the breakpoint in the IRQ:
    INTCON1 = 0x8000
    INTCON2 = 0x0000
    CORCON = 0x0004
    IFS0 = 0x0109
    IFS1 = 0xC010
    #4
    user2x
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 15:45:06 (permalink)
    0
    And here is the disassembly of the c code part.
     

    ! __builtin_disable_interrupts();
    0x1B58: DISI #0x6
    0x1B5A: MOV SR, W2
    0x1B5C: IOR #0xE0, W2
    0x1B5E: MOV W2, SR
    !
    ! int_detect = 1;
    0x1B60: MOV #0x1, W0
    0x1B62: MOV W0, int_detect
    ! uint16_t temp1;
    ! temp1 = LATB;
    0x1B64: MOV LATB, W1
    0x1B66: MOV W1, [W14+8]
    ! temp_lat = temp1;
    0x1B68: MOV [W14+8], W2
    0x1B6A: MOV W2, [W14+6]
    ! temp_lat &= off_mask;
    0x1B6C: MOV [W14+6], W0
    0x1B6E: AND W0, [W14], W0
    0x1B70: MOV W0, [W14+6]
    ! if (LATB != temp1)
    0x1B72: MOV LATB, W1
    0x1B74: MOV [W14+8], W0
    0x1B76: SUB W1, W0, [W15]
    0x1B78: BRA Z, .L26
    ! off_mask = 0;
    0x1B7A: CLR W0
    0x1B7C: MOV W0, [W14]
    ! LATB = temp_lat; // | on_mask;
    0x1B7E: MOV [W14+6], W1
    0x1B80: MOV W1, LATB
    !
    ! int_detect = 0;
    0x1B82: CLR int_detect
    ! __builtin_enable_interrupts();
    0x1B84: DISI #0x6
    0x1B86: MOV SR, W2
    0x1B88: AND.B #0x1F, W2
    0x1B8A: MOV W2, SR

     
    #5
    user2x
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 15:53:53 (permalink)
    0
    Have added ric's Nop() suggestion and it seems to have shifted the problem to the
    UART2 IRQ breakpoint happening instead of the TIMER1.
     
    That may just be a timing issue. Not sure.
     
    BTW: I use TIMER1, TIMER2 , INT1, ADC and UART2 interrupts in this system.
    #6
    user2x
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 16:22:17 (permalink)
    0
    What I found:
     
    The DISI bit in INTCON2 is NOT set when I get the interrupts occurring.
     
     
    How interrupts are disabled in that assembly listing I posted?
    DISI is activated for only 6 instructions.
    How is it expected that interrupts remain off after that?
     
     
     
     
    #7
    andersm
    Super Member
    • Total Posts : 2666
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: online
    Re: I get interrupts after disabling them. Why? 2019/10/29 16:27:59 (permalink)
    0
    The code in your disassembly doesn't seem to match the code in your first post. (Also dear lord do yourself a favour and turn optimizations on. All that extra moving data back and forth makes it much more difficult to follow the disassembly.)
    #8
    user2x
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 16:37:26 (permalink)
    0
    You re right, it does not follow it exactly since that C code was a simplified summary to illustrate the problem.
    So here:

       __builtin_disable_interrupts();
       Nop();
       int_detect = 1;
       temp_lat = LATB & off_mask;
       LATB = temp_lat | on_mask;
       int_detect = 0;
    __builtin_enable_interrupts();

     
    Disassembly

    ! __builtin_disable_interrupts();
    0x1B64: DISI #0x6
    0x1B66: MOV SR, W2
    0x1B68: IOR #0xE0, W2
    0x1B6A: MOV W2, SR
    ! Nop();
    0x1B6C: NOP
    ! int_detect = 1;
    0x1B6E: MOV #0x1, W0
    0x1B70: MOV W0, int_detect
    ! temp_lat = LATB & off_mask;
    0x1B72: MOV LATB, W0
    0x1B74: AND W0, [W14], W0
    0x1B76: MOV W0, [W14+6]
    ! LATB = temp_lat | on_mask;
    0x1B78: MOV [W14+6], W1
    0x1B7A: MOV [W14+4], W0
    0x1B7C: IOR W0, W1, W0
    0x1B7E: MOV W0, LATB
    !
    ! int_detect = 0;
    0x1B80: CLR int_detect
    ! __builtin_enable_interrupts();
    0x1B82: DISI #0x6
    0x1B84: MOV SR, W1
    0x1B86: AND.B #0x1F, W1
    0x1B88: MOV W1, SR
    !

     
     
     
     
     
    #9
    user2x
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 17:12:51 (permalink)
    0
    Observation:
     
    The IPL2:IPL0   in the SR register should be set to b111  = 7 = User interrupts disabled.
     
    That code 
    0x1B66: MOV SR, W2
     
     
     
    0x1B68: IOR #0xE0, W2
    0x1B6A: MOV W2, SR



    Should do that but in stepping over it, I see the bits in the SR register remaining at 000.
     
    Perhaps that is the problem?
    But why?
    EDIT:  It is the

    MOV W2, SR

    that seems to not work. The SR register remains at 0x0102 after that instruction although it should change to 0x01E2.


    post edited by user2x - 2019/10/29 17:33:34
    #10
    user2x
    Super Member
    • Total Posts : 317
    • Reward points : 0
    • Joined: 2011/02/10 20:43:36
    • Location: 0
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/10/29 17:48:10 (permalink)
    +1 (1)
    BOOOOOOOOAAAAAAAAAA, I found it!!!!!!!!!!!!!!!!!!!!
    Cunning, very cunning....
     
    I found this in the Manual:

     
    2: The IPL<2:0> status bits are read-only when NSTDIS = 1 (INTCON1<15>).
     

     
    That means that the IPL bits in the SR register are not writable as I have NSTDIS set.
    That means that the provided

     
    __builtin_disable_interrupts()
     

    does not work in that case. I think that they should have allowed for that and taken care of it.
     
     
    post edited by user2x - 2019/10/29 17:49:34
    #11
    cawilkie
    Administrator
    • Total Posts : 1983
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/11/06 07:42:35 (permalink)
    +1 (1)
    Something is fishy here.   DISI n followed by writing to the IPL has always been the required practice.
     
    I am seeking guidance from chip design.
     
    Regards
    Calum
    #12
    cawilkie
    Administrator
    • Total Posts : 1983
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    Re: I get interrupts after disabling them. Why? 2019/11/12 07:24:39 (permalink)
    +2 (2)
    Writing to the IPL is blocked by the device when nested interrupts is disabled.  Some devices have a GIE bit, which __builtin_disable_interrupts() will use.  Devices that do not have GIE bit have no (good) way of disabling interrupts when nesting is disabled.
     
    If disabling interrupts is required on one of these devices; one could set the CPU IPL to level n at startup and nominate all interrupts to be level n+1.   This would prevent nesting from occurring, as all interrupts will have the same priority.
     
    We cannot identify this situation at compile time, the best we can do is provide some extra guidance in the documentation for the builtins.   This will be done.
     
    Regards
    Calum
    #13
    Jump to:
    © 2019 APG vNext Commercial Version 4.5