Skip to main content
Explorer II
March 27, 2024
Solved

How to enable and disable a maskable interrupt from inside an ISR in stm8A

  • March 27, 2024
  • 2 replies
  • 1671 views

Hello all. 

 

I have an ISR inside which I want to disable and enable interrupts.

 

Reference manual says : 

 

https://www.st.com/resource/en/reference_manual/rm0016-stm8s-series-and-stm8af-series-8bit-microcontrollers-stmicroelectronics.pdf

 

Disabling the interrupts

#asm
PUSH CC
POP ISR_CC(1)
SIM
#endasm

Enabling the interrupts

#asm
PUSH ISR_CC(1)
POP CC
#endasm

I want to achieve mutual exclusion. I have tried using sim and rim and it works for now.

However the above method got me confused. 

What do I do for POP ISR_CC ? 

Please suggest me exact ways. 

I have found this inside a blog. Is it correct?

uint8_t atomic_begin(void) __naked {
__asm
; Copy CC value, put in A reg for return value, and disable all interrupts.
push cc
pop a
sim
ret
__endasm;
}

void atomic_end(const uint8_t istate) {
(void)istate;

__asm
; Restore CC from arg value in A reg.
push a
pop cc
__endasm;
}
    This topic has been closed for replies.
    Best answer by raja1

    I was using cosmic c compiler.

     

    I did the following modifications for cosmic C and stvd.

     

    uint8_t atomic_begin(void) 
    {
    #asm
    ; Copy CC value, put in A reg for return value, and disable all interrupts.
    push cc
    pop a
    sim
    #endasm;
    }
    
    void atomic_end(const uint8_t istate) {
    (void)istate;
    
    #asm
    ; Restore CC from arg value in A reg.
    push a
    pop cc
    #endasm;
    }
    
    //Usage is as follows
    ISR()
    {
    uint8_t ISR_CC_ret = atomic_begin();
    //execute your ISR
    atomic_end(ISR_CC_ret);
    }

    2 replies

    raja1Author
    Explorer II
    March 27, 2024

     

     

    uint8_t atomic_begin(void) __naked {
    	__asm
    		; Copy CC value, put in A reg for return value, and disable all interrupts.
    		ld a,cc
     push cc
    		pop a
    		sim
    		ret
    	__endasm;
    }
    
    void atomic_end(const uint8_t istate) {
    	(void)istate;
    
    	__asm
    		; Restore CC from arg value in A reg.
     ld cc,a
    		push a
    		pop cc
    	__endasm;
    }

     


    @raja1 wrote:

    Hello all. 

     

    I have an ISR inside which I want to disable and enable interrupts.

     

    Reference manual says : 

     

    https://www.st.com/resource/en/reference_manual/rm0016-stm8s-series-and-stm8af-series-8bit-microcontrollers-stmicroelectronics.pdf

     

    Disabling the interrupts

     

    #asm
    PUSH CC
    POP ISR_CC(1)
    SIM
    #endasm

     

    Enabling the interrupts

     

    #asm
    PUSH ISR_CC(1)
    POP CC
    #endasm

     

    I want to achieve mutual exclusion. I have tried using sim and rim and it works for now.

    However the above method got me confused. 

    What do I do for POP ISR_CC ? 

    Please suggest me exact ways. 

    I have found this inside a blog. Is it correct?

     

    uint8_t atomic_begin(void) __naked {
    __asm
    ; Copy CC value, put in A reg for return value, and disable all interrupts.
    push cc
    pop a
    sim
    ret
    __endasm;
    }
    
    void atomic_end(const uint8_t istate) {
    (void)istate;
    
    __asm
    ; Restore CC from arg value in A reg.
    push a
    pop cc
    __endasm;
    }

     


    Does this make sense?

     

    raja1AuthorAnswer
    Explorer II
    March 30, 2024

    I was using cosmic c compiler.

     

    I did the following modifications for cosmic C and stvd.

     

    uint8_t atomic_begin(void) 
    {
    #asm
    ; Copy CC value, put in A reg for return value, and disable all interrupts.
    push cc
    pop a
    sim
    #endasm;
    }
    
    void atomic_end(const uint8_t istate) {
    (void)istate;
    
    #asm
    ; Restore CC from arg value in A reg.
    push a
    pop cc
    #endasm;
    }
    
    //Usage is as follows
    ISR()
    {
    uint8_t ISR_CC_ret = atomic_begin();
    //execute your ISR
    atomic_end(ISR_CC_ret);
    }