2020-08-31 06:59 AM
Hello,
I've followed all the steps required to generate and handle a RTC wakeup in the manual, but it still doesn't work. I can't figure out why that doesn't work.
The goal of the following code is that, when I click the reset button of my nucleo L152-RE board, it goes to sleep mode for 3 seconds and then wake up and turn on a led.
In the "set_countdown_duration" routine, I set up the duration to a hard coded value of 3 seconds.
If you want to read more about RTC wakeup events and my struggle with them, you can read the following 30 posts thread I wrote about this during the last two weeks.
I believe I have scrupulously followed all the steps required but it still doesn't work and I can't figure out why.
Here's my "rtc_timer.S" file. This is the code I wrote that deals with enabling RTC/RTC wakeup events:
.syntax unified
.include "bits.i"
.include "stm32_registers.i"
.macro setbit register:req, bit:req
PUSH {R0,R1}
LDR R0, =\register
LDR R1, [R0]
ORR.W R1, R1, \bit
STR R1, [R0]
POP {R0,R1}
.endm
.macro clearbit register:req, bit:req
PUSH {R0,R1}
LDR R0, =\register
LDR R1, [R0]
BIC.W R1, R1, \bit
STR R1, [R0]
POP {R0,R1}
.endm
enable_power_interface_clock:
setbit RCC_APB1ENR, RCC_APB1ENR_BIT_PWREN
BX LR
enable_rtc_interrupt_mode:
setbit EXTI_EMR, BIT20
setbit EXTI_RTSR, BIT20
clearbit EXTI_FTSR, BIT20
BX LR
unlock_rtc_registers:
setbit PWR_CR, PWR_CR_BIT_DBP
PUSH {R0,R1}
LDR R0, =RTC_WPR
LDR R1, =0xCA
STR R1, [R0]
LDR R1, =0x53
STR R1, [R0]
POP {R0,R1}
BX LR
disable_wakeup_timer:
clearbit RTC_CR, RTC_CR_BIT_WUTE
BX LR
wait_timer_programmable:
PUSH {R0,R1,R2}
LDR R0, =RTC_ISR
LDR R1, =RTC_ISR_BIT_WUTF
loop:
LDR R2, [R0]
ANDS R2, R2, R1
BNE loop
POP {R0,R1,R2}
BX LR
select_hse_rtc_clock_source:
PUSH {R0,R1,R2}
LDR R0, =RCC_CSR
LDR R1, [R0]
LDR R2, =0b11
BFI.W R1, R2, #16, #2
STR R1, [R0]
POP {R0, R1, R2}
BX LR
enable_rtc_clock:
setbit RCC_CSR, RCC_CSR_BIT_RTCEN
BX LR
set_ck_spre_to_1_hz:
PUSH {R0,R1,R2}
LDR R0, =RTC_PRER
LDR R1, [R0]
LDR R2, =255
BFI.W R1, R2, #0, #15
LDR R2, =127
BFI.W R1, R2, #16, #7
STR R1, [R0]
POP {R0,R1,R2}
BX LR
select_ck_spre_as_timer_freq:
PUSH {R0,R1,R2}
LDR R0, =RTC_CR
LDR R1, [R0]
LDR R2, =0b10
BFI.W R1, R2, #0, #3
STR R1, [R0]
POP {R0,R1,R2}
BX LR
set_countdown_duration:
PUSH {R0,R1}
LDR R0, =RTC_WUTR
LDR R1, [R0]
LDR R2, =3
BFI.W R1, R2, #0, #16
STR R1, [R0]
POP {R0,R1}
BX LR
start_countdown:
setbit RTC_CR, RTC_CR_BIT_WUTE
BX LR
lock_back_registers:
PUSH {R0,R1}
LDR R0, =RTC_WPR
LDR R1, =0x00
STR R1, [R0]
POP {R0,R1}
clearbit PWR_CR, PWR_CR_BIT_DBP
BX LR
sleep_for_3_sec:
BL enable_power_interface_clock
BL enable_rtc_interrupt_mode
BL unlock_rtc_registers
BL disable_wakeup_timer
BL wait_timer_programmable
BL select_hse_rtc_clock_source
BL enable_rtc_clock
BL set_ck_spre_to_1_hz
BL select_ck_spre_as_timer_freq
BL set_countdown_duration
BL start_countdown
BX LR
.global sleep_for_3_sec
my main.S file is the following:
.syntax unified
.align 2
_start:
.word 0x20008000
.word start
.type start, function
.rept 18
.long 0
.endr
.word wakeup_handler
.type wakeup_handler, function
start:
BL enable_led
BL sleep_for_3_sec
wfe
wakeup_handler:
BL turn_led_on
.global _start
The functions about leds I have tested multiple times, I have absolutely no doubt they work properly so I'm not including them here.
My "bits.i" and "stm32_registers.i" include files are the following, in case you were wondering.
bits.i:
.equ BIT0, 1 << 0
.equ BIT1, 1 << 1
.equ BIT2, 1 << 2
.equ BIT3, 1 << 3
.equ BIT4, 1 << 4
.equ BIT5, 1 << 5
.equ BIT6, 1 << 6
.equ BIT7, 1 << 7
.equ BIT8, 1 << 8
.equ BIT9, 1 << 9
.equ BIT10, 1 << 10
.equ BIT11, 1 << 11
.equ BIT12, 1 << 12
.equ BIT13, 1 << 13
.equ BIT14, 1 << 14
.equ BIT15, 1 << 15
.equ BIT16, 1 << 16
.equ BIT17, 1 << 17
.equ BIT18, 1 << 18
.equ BIT19, 1 << 19
.equ BIT20, 1 << 20
.equ BIT21, 1 << 21
.equ BIT22, 1 << 22
.equ BIT23, 1 << 23
.equ BIT24, 1 << 24
.equ BIT25, 1 << 25
.equ BIT26, 1 << 26
.equ BIT27, 1 << 27
.equ BIT28, 1 << 28
.equ BIT29, 1 << 29
.equ BIT30, 1 << 30
.equ BIT31, 1 << 31
stm32_registers.i:
.include "bits.i"
.equ EXTI, (0x40010400)
.equ EXTI_EMR, (EXTI + 0x04)
.equ EXTI_RTSR, (EXTI + 0x08)
.equ EXTI_FTSR, (EXTI + 0x0C)
.equ PWR, (0x40007000)
.equ PWR_CR, (PWR + 0x00)
.equ PWR_CR_BIT_DBP, (BIT8)
.equ RTC, (0x40002800)
.equ RTC_CR, (RTC + 0x08)
.equ RTC_CR_BIT_WUTE, BIT10
.equ RTC_ISR, (RTC + 0x0C)
.equ RTC_ISR_BIT_WUTF, BIT10
.equ RTC_PRER, (RTC + 0x10)
.equ RTC_WUTR, (RTC + 0x14)
.equ RTC_WPR, (RTC + 0x24)
.equ RCC, (0x40023800)
.equ RCC_APB1ENR, (RCC + 0x24)
.equ RCC_APB1ENR_BIT_PWREN, (BIT28)
.equ RCC_CSR, (RCC + 0x34)
.equ RCC_CSR_BIT_RTCEN, (BIT22)
Any help would be greatly, greatly, appreciated.
2020-08-31 09:35 AM
By the way, I followed the execution of the program step by step in gdb.
The only thing that appeared weird is that, in my "unlock_rtc_registers" routine, I set RTC_WPR to 0xCA but, when inspecting the content of the RTC_WPR in gdb, this register doesn't seem to be modified. Then I set it to 0x53 and still, the register is not modified. I don't know if that is normal. Maybe writing 0xCA and then 0x53 to this register is just a command to unlock the RTC registers but that doesn't actually modify RTC_WPR ? This or something is wrong at this step.
2020-08-31 12:39 PM
RTC_WPR always reads zero per the reference manual.
2020-09-01 07:35 AM
Thank you. So the problem must come from somewhere else.
2020-09-01 09:59 AM
What do you expect to be in the RTC registers, and how is the reality different from your expectations?
JW
2020-09-04 03:07 AM
I don't expect anything to be different than it is in the RTC registers I'm using here. What I expect is the the user led to turn on after the 3 secs.
Are there registers (RTC registers or other registers) that I could read to check:
Or can you think of any other thing that I could check?