2023-05-03 10:09 AM - edited 2023-11-20 6:34 AM
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).
Next is the screen of the result of IRET instruction
And a screen with programmable alarm disabled where MCU exits correctly from the ISR
 
What is it?  Any clues?
Solved! Go to Solution.
2023-05-04 3:15 AM
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.
2023-05-04 3:15 AM
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.
2023-05-05 8:25 AM
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 3FFYes, the program is written on assembler. Here is the code.
2023-05-05 8:28 AM
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
 	
 	end2023-05-05 8:36 AM
and the ISR code
2023-05-06 9:17 AM
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!
2023-05-06 2:01 PM
Alright, the real reason after all was an extra IRET which made stack pointer wrap around and counting down from the top.
