cancel
Showing results for 
Search instead for 
Did you mean: 

What is the proper external ISR procedure to resume normal operation after entering halt mode on the STM8S?

JEREMYB
Associate

First off, I would really like to thank everyone in the community for being so great. Second, I would really like to thank anyone who is willing to take a few minutes to read this post and answer my hopefully quick question.

I am having a difficult time finding any code resources that show what assembly instructions to run in an external interrupt service routine after the halt assembly instruction has been run in order to resume normal operation. Thus far I have using a NOP and RIM, but I do not think this is correct. I am making some modifications to existing code and I cannot program the actual board at the moment due to the lack of a programming interface board, However here are the details. I am using the COSMIC compiler for a STM8S103F3P. I have an external interrupt service routine defined in the stm8_interrupt_vecor implementation and I have that service routine assigned to IRQ3 (PA2 is connected to a switch that gets grounded when de-pressed, and otherwise is pulled up and also has a debounce cap). This interrupt should fire when the device is supposed to resume normal operation. Also, I am not sure whether I need to set a specific value for PAIS[1:0], or if it defaults to 0x00.

Here's what I have thus far:

Relevant piece of main.c

**in_halt_mode is a bool that is assigned true right before the halt instruction is issued. This is because the switch will get pressed at times when the device is not in halt mode to turn it on and off or depressed for a long period to change settings that are saved to the EEPROM.

@far @interrupt void extia_int(void) {
    if (in_halt_mode)  {
            _asm("nop");
            _asm("rim");
            in_halt_mode = false;
    }
}

stm8_interrupt_vector.c:

/*	BASIC INTERRUPT VECTOR TABLE FOR STM8 devices
 *	Copyright (c) 2007 STMicroelectronics
 */
 
typedef void @far (* interrupt_handler_t)(void);
 
struct interrupt_vector {
    unsigned char       interrupt_instruction;
    interrupt_handler_t interrupt_handler;
};
 
@far @interrupt void NonHandledInterrupt(void) {
    /* Set a breakpoint here  */
}
 
/* External Interrupt for Port A
 * Resumes normal operation after
 * the halt instruction has been issued 
 */
extern @far @interrupt void extia_int(void);
extern @far @interrupt void exitd_int(void);
extern @far @interrupt void TIM4_UPD_OVF_IRQHandler(void);
/* startup routine */
extern void _stext();
 
struct interrupt_vector const _vectab[] = {
    { 0x82, (interrupt_handler_t) _stext }, /* reset */
    { 0x82, NonHandledInterrupt}, /* trap  */
    { 0x82, NonHandledInterrupt}, /* irq0  */
    { 0x82, NonHandledInterrupt}, /* irq1  */
    { 0x82, NonHandledInterrupt}, /* irq2  */
    { 0x82, extia_int},           /* irq3  */
    { 0x82, NonHandledInterrupt}, /* irq4  */
    { 0x82, NonHandledInterrupt}, /* irq5  */
    { 0x82, exitd_int},           /* irq6  */
    { 0x82, NonHandledInterrupt}, /* irq7  */
    { 0x82, NonHandledInterrupt}, /* irq8  */
    { 0x82, NonHandledInterrupt}, /* irq9  */
    { 0x82, NonHandledInterrupt}, /* irq10 */
    { 0x82, NonHandledInterrupt}, /* irq11 */
    { 0x82, NonHandledInterrupt}, /* irq12 */
    { 0x82, NonHandledInterrupt}, /* irq13 */
    { 0x82, NonHandledInterrupt}, /* irq14 */
    { 0x82, NonHandledInterrupt}, /* irq15 */
    { 0x82, NonHandledInterrupt}, /* irq16 */
    { 0x82, NonHandledInterrupt}, /* irq17 */
    { 0x82, NonHandledInterrupt}, /* irq18 */
    { 0x82, NonHandledInterrupt}, /* irq19 */
    { 0x82, NonHandledInterrupt}, /* irq20 */
    { 0x82, NonHandledInterrupt}, /* irq21 */
    { 0x82, NonHandledInterrupt}, /* irq22 */
    { 0x82, TIM4_UPD_OVF_IRQHandler}, /* irq23 */
    { 0x82, NonHandledInterrupt}, /* irq24 */
    { 0x82, NonHandledInterrupt}, /* irq25 */
    { 0x82, NonHandledInterrupt}, /* irq26 */
    { 0x82, NonHandledInterrupt}, /* irq27 */
    { 0x82, NonHandledInterrupt}, /* irq28 */
    { 0x82, NonHandledInterrupt}, /* irq29 */
};

1 REPLY 1
Cristian Gyorgy
Senior III

Hi Jeremyb!

I don't really understand what you mean: "what assembly instructions to run in an external interrupt service routine after the halt assembly instruction has been run in order to resume normal operation." - the external interrupt will wake up your MCU from halt mode, and when it's all done waking up, it will execute your external interrupt routine. At the end of your ISR routine, depending on the value of the AL bit, the program will resume code execution following the halt instruction or will go back to halt mode. In halt mode interrupts are enabled.

I don't see any reason to use the nop instruction in the ISR. To execute the rim instruction form the ISR, where the interrupts are normally disabled, is not a good idea if you don't know what you are doing. If you exit the ISR with the normal iret instruction, interrupts will be enabled on return to main program.