Skip to main content
Visitor II
May 3, 2023
Solved

Not possible to use programmable alarm and periodic wakeup functions simultaneously on the STM8L051F3 MCU?

  • May 3, 2023
  • 5 replies
  • 2061 views

IRET returns to nowhere from wakeup timer ISR as soon as programmable alarm interrupt is active!

Here is the STVD screen where programmable alarm and wakeup timer interrupts are enabled and wakeup timer ISR is just about to end. In the memory window at the bottom centered you can see a nonsense address stored in stack (highlighted with yellow).


_legacyfs_online_stmicro_images_0693W00000bjJREQA2.pngNext is the screen of the result of IRET instruction


_legacyfs_online_stmicro_images_0693W00000bjJRiQAM.pngAnd a screen with programmable alarm disabled where MCU exits correctly from the ISR


_legacyfs_online_stmicro_images_0693W00000bjJSHQA2.png 

What is it?  Any clues?

    This topic has been closed for replies.
    Best answer by AA1

    You have a problem with stack and this is not related with alarm and wakeup timer being both enable.

    Do you use large buffers of local variables?

    And it seems that you develop code in assembly, not in C.

    How the program reaches ISR routine?

    Show the ISR code and vector table.

    5 replies

    AA1Answer
    Visitor II
    May 4, 2023

    You have a problem with stack and this is not related with alarm and wakeup timer being both enable.

    Do you use large buffers of local variables?

    And it seems that you develop code in assembly, not in C.

    How the program reaches ISR routine?

    Show the ISR code and vector table.

    RDienAuthor
    Visitor II
    May 6, 2023

    You were right! The problem was the stack overflow. I used to call a procedure from ISR and seems like next IRQ fired before previous ISR over, so stack was overflowed.

    Thanks a lot for giving a hint!

    RDienAuthor
    Visitor II
    May 5, 2023

    Hello!

    I use segments. The RAM is divided in two segments ram0 and ram1. All the variables are in ram0 segment which is in 00-FF address range. The total value of all my variables is 33 bytes, so there is enough space.

    #define RAM0 1
    #define ram0_segment_start 0
    #define ram0_segment_end FF
    #define RAM1 1
    #define ram1_segment_start 100
    #define ram1_segment_end 1FF
    #define stack_segment_start 200
    #define stack_segment_end 3FF

    Yes, the program is written on assembler. Here is the code.

    RDienAuthor
    Visitor II
    May 5, 2023

    stm8/
     
    	extern main
     	#include "mapping.inc"
     	extern tim2_handler.l
     	extern tim4_handler.l
     	extern RTC_handler.l
     	extern key1_handler.l
     	extern key2_handler.l
     	extern key3_handler.l
     	extern key4_handler.l
     	
     	segment 'rom'
     reset.l
     	; initialize SP
     	ldw X,#$03ff
     	ldw SP,X
     	jp main
     	jra reset
     	
     	interrupt NonHandledInterrupt
     NonHandledInterrupt.l
     	iret
     	
     	segment 'vectit'
     	dc.l {$82000000+reset}								; reset
     	dc.l {$82000000+NonHandledInterrupt}	; trap
     	dc.l {$82000000+NonHandledInterrupt}	; irq0
     	dc.l {$82000000+NonHandledInterrupt}	; irq1
     	dc.l {$82000000+NonHandledInterrupt}	; irq2
     	dc.l {$82000000+NonHandledInterrupt}	; irq3
     	dc.l {$82000000+RTC_handler}					; irq4
     	dc.l {$82000000+NonHandledInterrupt}	; irq5
     	dc.l {$82000000+NonHandledInterrupt}	; irq6
     	dc.l {$82000000+NonHandledInterrupt}	; irq7
     	dc.l {$82000000+key4_handler}					; irq8
     	dc.l {$82000000+key1_handler}					; irq9
     	dc.l {$82000000+NonHandledInterrupt}	; irq10
     	dc.l {$82000000+NonHandledInterrupt}	; irq11
     	dc.l {$82000000+key3_handler}					; irq12
     	dc.l {$82000000+NonHandledInterrupt}	; irq13
     	dc.l {$82000000+NonHandledInterrupt}	; irq14
     	dc.l {$82000000+key2_handler}					; irq15
     	dc.l {$82000000+NonHandledInterrupt}	; irq16
     	dc.l {$82000000+NonHandledInterrupt}	; irq17
     	dc.l {$82000000+NonHandledInterrupt}	; irq18
     	dc.l {$82000000+tim2_handler}					; irq19
     	dc.l {$82000000+NonHandledInterrupt}	; irq20
     	dc.l {$82000000+NonHandledInterrupt}	; irq21
     	dc.l {$82000000+NonHandledInterrupt}	; irq22
     	dc.l {$82000000+NonHandledInterrupt}	; irq23
     	dc.l {$82000000+NonHandledInterrupt}	; irq24
     	dc.l {$82000000+tim4_handler}					; irq25
     	dc.l {$82000000+NonHandledInterrupt}	; irq26
     	dc.l {$82000000+NonHandledInterrupt}	; irq27
     	dc.l {$82000000+NonHandledInterrupt}	; irq28
     	dc.l {$82000000+NonHandledInterrupt}	; irq29
     	
     	end

    RDienAuthor
    Visitor II
    May 5, 2023

    and the ISR code

    RDienAuthor
    Visitor II
    May 6, 2023

    Alright, the real reason after all was an extra IRET which made stack pointer wrap around and counting down from the top.