cancel
Showing results for 
Search instead for 
Did you mean: 

Can't figure out why RTC wakeup event doesn't work

BCora.1
Associate III

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.

https://community.st.com/s/question/0D53W00000FzByJSAV/how-to-create-a-rtc-wakeup-event-to-wake-up-the-mcu-from-sleep-mode

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.

5 REPLIES 5
BCora.1
Associate III

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.

TDK
Guru

RTC_WPR always reads zero per the reference manual.

If you feel a post has answered your question, please click "Accept as Solution".
BCora.1
Associate III

Thank you. So the problem must come from somewhere else.

What do you expect to be in the RTC registers, and how is the reality different from your expectations?

JW

BCora.1
Associate III

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:

  • that a wakeup event has successfully been planned
  • that a wakeup event occured ?

Or can you think of any other thing that I could check?