2023-05-03 10:09 AM - edited 2023-11-20 06: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 03: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 03: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 08: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 3FF
Yes, the program is written on assembler. Here is the code.
2023-05-05 08: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
end
2023-05-05 08:36 AM
and the ISR code
2023-05-06 09: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 02:01 PM
Alright, the real reason after all was an extra IRET which made stack pointer wrap around and counting down from the top.