GPS Device
Loading...
Searching...
No Matches
RTC Public API

Public functions to interact with the RTC peripheral. More...

Collaboration diagram for RTC Public API:

Functions

ERR_te rtc_init (void)
 Initializes the RTC peripheral.
void rtc_set_calendar (CALENDAR_ts const *date)
 Sets the RTC calendar (date and weekday).
void rtc_set_time (TIME_ts const *time)
 Sets the RTC time (hours, minutes, seconds).
void rtc_get_time (TIME_ts *time)
 Reads the current time from the RTC.

Detailed Description

Public functions to interact with the RTC peripheral.

Function Documentation

◆ rtc_init()

ERR_te rtc_init ( void )

Initializes the RTC peripheral.

Enables the PWR and backup domain access, starts the LSE oscillator, selects LSE as the RTC clock source, enables the RTC, and configures the prescalers for a 1 Hz tick (PREDIV_A = 127, PREDIV_S = 255) with 24-hour format.

If the backup register sentinel pattern is already present, the RTC is assumed to be running with a valid configuration and the function returns immediately without modifying the time or calendar.

Returns
  • ERR_OK on success
  • ERR_MODULE_ALREADY_INITIALIZED if the RTC was already initialized (either by a prior call in this boot or because the backup domain was preserved across a reset)
Note
To force re-initialization and clear the current time, call rcc_reset_bkpd before calling this function.
Typically called indirectly via init_rtc.
See also
rtc_init

Definition at line 49 of file stm32f401re_rtc.c.

49 {
50 if(initialized) {
52 }
53
54 // Enable PWR clock to allow access to the backup domain
56
57 // Enable backup domain write access
58 PWR->PWR_CR |= (1 << PWR_CR_DBP);
59
60 // Check sentinel: if present, the RTC was already configured before this reset
64 {
66 }
67
69
70 // Start LSE oscillator and wait for it to stabilize
71 RCC->RCC_BDCR |= (1 << RCC_BDCR_LSEON);
72 while(!(RCC->RCC_BDCR & (1 << RCC_BDCR_LSERDY)));
73
74 // Select LSE as the RTC clock source
75 RCC->RCC_BDCR &= ~(0x3 << RCC_BDCR_RTCSEL);
76 RCC->RCC_BDCR |= (0x1 << RCC_BDCR_RTCSEL);
77
78 // Enable RTC
79 RCC->RCC_BDCR |= (1 << RCC_BDCR_RTCEN);
80
81 // Enter INIT mode and wait for INITF confirmation
82 RTC->RTC_ISR |= (1 << RTC_ISR_INIT);
83 while(!(RTC->RTC_ISR & (1 << RTC_ISR_INITF)));
84
85 // 24-hour format, prescalers for 1 Hz tick from 32.768 kHz LSE:
86 // f_ck_apre = LSE / (PREDIV_A + 1) = 32768 / 128 = 256 Hz
87 // f_ck_spre = f_ck_apre / (PREDIV_S + 1) = 256 / 256 = 1 Hz
88 RTC->RTC_CR &= ~(1 << RTC_CR_FMT);
89 RTC->RTC_PRER =
90 (127 << RTC_PRER_PREDIV_A) |
91 (255 << RTC_PRER_PREDIV_S);
92
93 // Exit INIT mode
94 RTC->RTC_ISR &= ~(1 << RTC_ISR_INIT);
95 while(RTC->RTC_ISR & (1 << RTC_ISR_INITF));
96
97 // Write sentinel to backup register to mark initialization complete
100
102
103 initialized = true;
104
105 return ERR_OK;
106}
@ ENABLE
Definition common.h:100
@ DISABLE
Definition common.h:97
@ ERR_OK
Definition err.h:36
@ ERR_MODULE_ALREADY_INITIALIZED
Definition err.h:54
void rcc_set_pclk_apb1(RCC_APB1ENR_te periph_position, EN_STATUS_te en_status)
Enables or disables the peripheral clock for an APB1 peripheral.
static void rtc_set_write_protection(EN_STATUS_te en_status)
Enables or disables write protection of the RTC registers.
#define PWR
#define RTC
#define RCC
@ RTC_PRER_PREDIV_S
@ RTC_PRER_PREDIV_A
@ RTC_CR_FMT
@ RCC_BDCR_LSEON
@ RCC_BDCR_LSERDY
@ RCC_BDCR_RTCSEL
@ RCC_BDCR_RTCEN
@ PWR_CR_DBP
@ RTC_ISR_INIT
@ RTC_ISR_INITF
@ RCC_APB1ENR_PWREN
#define RTC_BKP_DOMAIN_RST_INDICATOR_PATTERN
Sentinel value written to BKP0R after successful RTC initialization.
#define RTC_BKP_DOMAIN_RST_INDICATOR_BKPxR
Backup register index used to store the initialization sentinel pattern.
bool initialized
True after rtc_init has completed successfully in this boot session.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rtc_set_calendar()

void rtc_set_calendar ( CALENDAR_ts const * date)

Sets the RTC calendar (date and weekday).

Enters RTC INIT mode, writes the date, month, weekday, and year to RTC_DR in BCD format, then exits INIT mode. Write protection is disabled and re-enabled around the operation.

Parameters
[in]datePointer to the calendar structure to write.
Note
Years must be in the range 2000–2099.
See also
rtc_set_calendar

Definition at line 109 of file stm32f401re_rtc.c.

109 {
111
112 RTC->RTC_ISR |= (1 << RTC_ISR_INIT);
113 while(!(RTC->RTC_ISR & (1 << RTC_ISR_INITF)));
114
115 RTC->RTC_DR =
116 ((date->date % 10) << RTC_DR_DU) |
117 ((date->date / 10) << RTC_DR_DT) |
118 ((date->months % 10) << RTC_DR_MU) |
119 ((date->months / 10) << RTC_DR_MT) |
120 ((date->week_days) << RTC_DR_WDU) |
121 (((date->year - 2000) % 10) << RTC_DR_YU) |
122 (((date->year - 2000) / 10) << RTC_DR_YT);
123
124 RTC->RTC_ISR &= ~(1 << RTC_ISR_INIT);
125 while(RTC->RTC_ISR & (1 << RTC_ISR_INITF));
126
128}
@ RTC_DR_MT
@ RTC_DR_MU
@ RTC_DR_WDU
@ RTC_DR_YU
@ RTC_DR_DT
@ RTC_DR_DU
@ RTC_DR_YT
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rtc_set_time()

void rtc_set_time ( TIME_ts const * time)

Sets the RTC time (hours, minutes, seconds).

Enters RTC INIT mode, writes hours, minutes, and seconds to RTC_TR in BCD format using DEC_TO_BCD, then exits INIT mode. Write protection is disabled and re-enabled around the operation.

Parameters
[in]timePointer to the time structure to write.
See also
rtc_set_time

Definition at line 131 of file stm32f401re_rtc.c.

131 {
133
134 RTC->RTC_ISR |= (1 << RTC_ISR_INIT);
135 while(!(RTC->RTC_ISR & (1 << RTC_ISR_INITF)));
136
137 RTC->RTC_TR =
138 (DEC_TO_BCD(time->hours) << RTC_TR_HU) |
139 (DEC_TO_BCD(time->minutes) << RTC_TR_MNU) |
140 (DEC_TO_BCD(time->seconds) << RTC_TR_SU);
141
142 RTC->RTC_ISR &= ~(1 << RTC_ISR_INIT);
143 while(RTC->RTC_ISR & (1 << RTC_ISR_INITF));
144
146}
#define DEC_TO_BCD(DEC)
Converts a decimal value to its BCD-encoded byte equivalent.
Definition common.h:54
@ RTC_TR_SU
@ RTC_TR_MNU
@ RTC_TR_HU
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rtc_get_time()

void rtc_get_time ( TIME_ts * time)

Reads the current time from the RTC.

Reads RTC_TR atomically using the shadow register double-read technique: reads TR, reads DR (to unlock the shadow registers), reads TR again, and repeats if the two TR reads differ. Converts BCD values to decimal using BCD_TO_DEC before storing in time.

Parameters
[out]timePointer to the time structure that will receive the current hours, minutes, and seconds.
See also
rtc_get_time

Definition at line 149 of file stm32f401re_rtc.c.

149 {
150 uint32_t tr1, tr2;
151
152 // Double-read to ensure consistency: reading DR after TR unlocks the shadow
153 // registers and allows TR to be read again safely
154 do {
155 tr1 = RTC->RTC_TR;
156 (void)RTC->RTC_DR;
157 tr2 = RTC->RTC_TR;
158 } while(tr1 != tr2);
159
160 time->seconds = BCD_TO_DEC(tr1 & 0x7F);
161 time->minutes = BCD_TO_DEC((tr1 >> RTC_TR_MNU) & 0x7F);
162 time->hours = BCD_TO_DEC((tr1 >> RTC_TR_HU) & 0x7F);
163}
#define BCD_TO_DEC(BCD)
Converts a BCD-encoded byte to its decimal equivalent.
Definition common.h:47
uint8_t seconds
uint8_t hours
uint8_t minutes
Here is the caller graph for this function: