Skip to main content
BCora.1
Associate III
August 31, 2020
Question

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

  • August 31, 2020
  • 5 replies
  • 1300 views

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.

This topic has been closed for replies.

5 replies

BCora.1
BCora.1Author
Associate III
August 31, 2020

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
August 31, 2020

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
BCora.1Author
Associate III
September 1, 2020

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

waclawek.jan
Super User
September 1, 2020

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

JW

BCora.1
BCora.1Author
Associate III
September 4, 2020

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?