libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
rtc.c
Go to the documentation of this file.
1/** @defgroup rtc_file RTC peripheral API
2 *
3 * @ingroup peripheral_apis
4 *
5 * @brief <b>libopencm3 STM32F1xx RTC</b>
6 *
7 * @author @htmlonly &copy; @endhtmlonly 2010 Uwe Hermann <uwe@hermann-uwe.de>
8 * @author @htmlonly &copy; @endhtmlonly 2010 Lord James <lordjames@y7mail.com>
9 *
10 * @version 1.0.0
11 *
12 * @date 4 March 2013
13 *
14 * The Real Time Clock peripheral consists of a set of 16 bit control, status,
15 * prescaler, counter and alarm registers. Before the latter three can be
16 * written the RTC must be placed in configuration mode by a call to
17 * @ref rtc_enter_config_mode(). The functions below handle this implictly.
18 *
19 * The RTC is completely reset by performing a Backup Domain reset. Note
20 * that this can affect unrelated user data contained in the Backup Domain
21 * registers. Other forms of reset will not affect the RTC registers as they
22 * are contained within the backup domain.
23 *
24 * The RTC clock source to be used is selected by calling
25 * @ref rcc_set_rtc_clock_source().
26 *
27 * The LSE clock source normally comes from a 32.768kHz external crystal
28 * This clock is in the backup domain and so continues to run when only the
29 * V_BAT supply is present. A prescaler value of 7FFF will give a 1 second
30 * count quantum.
31 *
32 * The LSI clock source is a low accuracy internal clock of about 40kHz
33 * frequency, and the HSE clock source is the external high speed clock
34 * divided by 128.
35 *
36 * Initial configuration of the RTC consists of:
37 *
38 * @li perform a Backup Domain reset if appropriate;
39 * @li select the clock to be used;
40 * @li set the prescaler, counter and configuration values;
41 * @li enable the RTC.
42 *
43 * @note reading the RTC registers may result in a corrupted value being
44 * returned in certain cases. Refer to the STM32F1xx Reference Manual.
45 *
46 * LGPL License Terms @ref lgpl_license
47 */
48
49/*
50 * This file is part of the libopencm3 project.
51 *
52 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
53 * Copyright (C) 2010 Lord James <lordjames@y7mail.com>
54 *
55 * This library is free software: you can redistribute it and/or modify
56 * it under the terms of the GNU Lesser General Public License as published by
57 * the Free Software Foundation, either version 3 of the License, or
58 * (at your option) any later version.
59 *
60 * This library is distributed in the hope that it will be useful,
61 * but WITHOUT ANY WARRANTY; without even the implied warranty of
62 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 * GNU Lesser General Public License for more details.
64 *
65 * You should have received a copy of the GNU Lesser General Public License
66 * along with this library. If not, see <http://www.gnu.org/licenses/>.
67 */
68/**@{*/
69
70
74
75/*---------------------------------------------------------------------------*/
76/** @brief RTC Set Operational from the Off state.
77
78Power up the backup domain clocks, enable write access to the backup domain,
79select the clock source, clear the RTC registers and enable the RTC.
80
81@param[in] clock_source ::rcc_osc. RTC clock source. Only the values HSE, LSE
82 and LSI are permitted.
83*/
84
85void rtc_awake_from_off(enum rcc_osc clock_source)
86{
87 uint32_t reg32;
88
89 /* Enable power and backup interface clocks. */
92
93 /* Enable access to the backup registers and the RTC. */
95
96 /* Set the clock source */
97 rcc_set_rtc_clock_source(clock_source);
98
99 /* Clear the RTC Control Register */
100 RTC_CRH = 0;
101 RTC_CRL = 0;
102
103 /* Enable the RTC. */
105
106 /* Clear the Registers */
108 RTC_PRLH = 0;
109 RTC_PRLL = 0;
110 RTC_CNTH = 0;
111 RTC_CNTL = 0;
112 RTC_ALRH = 0xFFFF;
113 RTC_ALRL = 0xFFFF;
115
116 /* Wait for the RSF bit in RTC_CRL to be set by hardware. */
117 RTC_CRL &= ~RTC_CRL_RSF;
118 while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0);
119}
120
121/*---------------------------------------------------------------------------*/
122/** @brief RTC Enter Configuration Mode.
123
124Prime the RTC for configuration changes by giving access to the prescaler,
125and counter and alarm registers.
126*/
127
129{
130 uint32_t reg32;
131
132 /* Wait until the RTOFF bit is 1 (no RTC register writes ongoing). */
133 while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0);
134
135 /* Enter configuration mode. */
137}
138
139/*---------------------------------------------------------------------------*/
140/** @brief RTC Leave Configuration Mode.
141
142Revert the RTC to operational state.
143*/
144
146{
147 uint32_t reg32;
148
149 /* Exit configuration mode. */
150 RTC_CRL &= ~RTC_CRL_CNF;
151
152 /* Wait until the RTOFF bit is 1 (our RTC register write finished). */
153 while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0);
154}
155
156/*---------------------------------------------------------------------------*/
157/** @brief RTC Set the Alarm Time.
158
159@param[in] alarm_time uint32_t. time at which the alarm event is triggered.
160*/
161
162void rtc_set_alarm_time(uint32_t alarm_time)
163{
165 RTC_ALRL = (alarm_time & 0x0000ffff);
166 RTC_ALRH = (alarm_time & 0xffff0000) >> 16;
168}
169
170/*---------------------------------------------------------------------------*/
171/** @brief RTC Enable the Alarm.
172
173*/
174
176{
180}
181
182/*---------------------------------------------------------------------------*/
183/** @brief RTC Disable the Alarm.
184
185*/
186
188{
190 RTC_CRH &= ~RTC_CRH_ALRIE;
192}
193
194/*---------------------------------------------------------------------------*/
195/** @brief RTC Set the prescaler Value
196
197@param[in] prescale_val uint32_t. 20 bit prescale divider.
198*/
199
200void rtc_set_prescale_val(uint32_t prescale_val)
201{
203 RTC_PRLL = prescale_val & 0x0000ffff; /* PRL[15:0] */
204 RTC_PRLH = (prescale_val & 0x000f0000) >> 16; /* PRL[19:16] */
206}
207
208/*---------------------------------------------------------------------------*/
209/** @brief RTC return the Counter Value
210
211@returns uint32_t: the 32 bit counter value.
212*/
213
215{
216 return (RTC_CNTH << 16) | RTC_CNTL;
217}
218
219/*---------------------------------------------------------------------------*/
220/** @brief RTC return the prescaler Value
221
222@returns uint32_t: the 20 bit prescale divider.
223*/
224
226{
227 return (RTC_DIVH << 16) | RTC_DIVL;
228}
229
230/*---------------------------------------------------------------------------*/
231/** @brief RTC return the Alarm Value
232
233@returns uint32_t: the 32 bit alarm value.
234*/
235
236uint32_t rtc_get_alarm_val(void)
237{
238 return (RTC_ALRH << 16) | RTC_ALRL;
239}
240
241/*---------------------------------------------------------------------------*/
242/** @brief RTC set the Counter
243
244@param[in] counter_val 32 bit time setting for the counter.
245*/
246
247void rtc_set_counter_val(uint32_t counter_val)
248{
250 RTC_CNTH = (counter_val & 0xffff0000) >> 16; /* CNT[31:16] */
251 RTC_CNTL = counter_val & 0x0000ffff; /* CNT[15:0] */
253}
254
255/*---------------------------------------------------------------------------*/
256/** @brief RTC Enable Interrupt
257
258@param[in] flag_val ::rtcflag_t: The flag to enable.
259*/
260
262{
264
265 /* Set the correct interrupt enable. */
266 switch (flag_val) {
267 case RTC_SEC:
269 break;
270 case RTC_ALR:
272 break;
273 case RTC_OW:
275 break;
276 }
277
279}
280
281/*---------------------------------------------------------------------------*/
282/** @brief RTC Disable Interrupt
283
284@param[in] flag_val ::rtcflag_t: The flag to disable.
285*/
286
288{
290
291 /* Disable the correct interrupt enable. */
292 switch (flag_val) {
293 case RTC_SEC:
294 RTC_CRH &= ~RTC_CRH_SECIE;
295 break;
296 case RTC_ALR:
297 RTC_CRH &= ~RTC_CRH_ALRIE;
298 break;
299 case RTC_OW:
300 RTC_CRH &= ~RTC_CRH_OWIE;
301 break;
302 }
303
305}
306
307/*---------------------------------------------------------------------------*/
308/** @brief RTC Clear an Interrupt Flag
309
310@param[in] flag_val ::rtcflag_t: The flag to clear.
311*/
312
314{
315 /* Configuration mode not needed. */
316
317 /* Clear the correct flag. */
318 switch (flag_val) {
319 case RTC_SEC:
320 RTC_CRL &= ~RTC_CRL_SECF;
321 break;
322 case RTC_ALR:
323 RTC_CRL &= ~RTC_CRL_ALRF;
324 break;
325 case RTC_OW:
326 RTC_CRL &= ~RTC_CRL_OWF;
327 break;
328 }
329}
330
331/*---------------------------------------------------------------------------*/
332/** @brief RTC Return a Flag Setting
333
334@param[in] flag_val ::rtcflag_t: The flag to check.
335@returns uint32_t: a nonzero value if the flag is set, zero otherwise.
336*/
337
338uint32_t rtc_check_flag(rtcflag_t flag_val)
339{
340 uint32_t reg32;
341
342 /* Read correct flag. */
343 switch (flag_val) {
344 case RTC_SEC:
345 reg32 = RTC_CRL & RTC_CRL_SECF;
346 break;
347 case RTC_ALR:
348 reg32 = RTC_CRL & RTC_CRL_ALRF;
349 break;
350 case RTC_OW:
351 reg32 = RTC_CRL & RTC_CRL_OWF;
352 break;
353 default:
354 reg32 = 0;
355 break;
356 }
357
358 return reg32;
359}
360
361/*---------------------------------------------------------------------------*/
362/** @brief RTC Start RTC after Standby Mode.
363
364Enable the backup domain clocks, enable write access to the backup
365domain and the RTC, and synchronise the RTC register access.
366*/
367
369{
370 uint32_t reg32;
371
372 /* Enable power and backup interface clocks. */
375
376 /* Enable access to the backup registers and the RTC. */
378
379 /* Wait for the RSF bit in RTC_CRL to be set by hardware. */
380 RTC_CRL &= ~RTC_CRL_RSF;
381 while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0);
382
383 /* Wait for the last write operation to finish. */
384 /* TODO: Necessary? */
385 while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0);
386}
387
388/*---------------------------------------------------------------------------*/
389/** @brief RTC Configuration on Wakeup
390
391Enable the backup domain clocks and write access to the backup domain.
392If the RTC has not been enabled, set the clock source and prescaler value.
393The parameters are not used if the RTC has already been enabled.
394
395@param[in] clock_source ::rcc_osc. RTC clock source. Only HSE, LSE
396 and LSI are permitted.
397@param[in] prescale_val uint32_t. 20 bit prescale divider.
398*/
399
400void rtc_auto_awake(enum rcc_osc clock_source, uint32_t prescale_val)
401{
402 uint32_t reg32;
403
404 /* Enable power and backup interface clocks. */
407
409
410 if (reg32 != 0) {
412 } else {
413 rtc_awake_from_off(clock_source);
414 rtc_set_prescale_val(prescale_val);
415 }
416}
417/**@}*/
418
void pwr_disable_backup_domain_write_protect(void)
Disable Backup Domain Write Protection.
Definition: pwr_common_v1.c:38
void rcc_set_rtc_clock_source(enum rcc_osc clock_source)
RCC Set the Source for the RTC clock.
Definition: rcc.c:581
rcc_osc
Definition: f1/rcc.h:567
void rcc_periph_clock_enable(enum rcc_periph_clken clken)
Enable Peripheral Clock in running mode.
void rcc_enable_rtc_clock(void)
RCC Enable the RTC clock.
Definition: rcc.c:570
uint32_t rcc_rtc_clock_enabled_flag(void)
RCC RTC Clock Enabled Flag.
Definition: rcc.c:560
@ RCC_PWR
Definition: f1/rcc.h:639
@ RCC_BKP
Definition: f1/rcc.h:638
#define RTC_CRH
Definition: f1/rtc.h:49
#define RTC_CRH_OWIE
Definition: f1/rtc.h:75
#define RTC_ALRH
Definition: f1/rtc.h:67
#define RTC_DIVH
Definition: f1/rtc.h:59
#define RTC_CRL_SECF
Definition: f1/rtc.h:103
#define RTC_PRLH
Definition: f1/rtc.h:55
#define RTC_CNTL
Definition: f1/rtc.h:64
#define RTC_CRL_CNF
Definition: f1/rtc.h:91
#define RTC_CRL
Definition: f1/rtc.h:52
#define RTC_CRL_RTOFF
Definition: f1/rtc.h:88
rtcflag_t
RTC Interrupt Flags.
Definition: f1/rtc.h:142
#define RTC_PRLL
Definition: f1/rtc.h:56
#define RTC_CRH_SECIE
Definition: f1/rtc.h:81
#define RTC_CRH_ALRIE
Definition: f1/rtc.h:78
#define RTC_ALRL
Definition: f1/rtc.h:68
#define RTC_CRL_ALRF
Definition: f1/rtc.h:100
#define RTC_CRL_OWF
Definition: f1/rtc.h:97
#define RTC_CNTH
Definition: f1/rtc.h:63
#define RTC_CRL_RSF
Definition: f1/rtc.h:94
#define RTC_DIVL
Definition: f1/rtc.h:60
@ RTC_ALR
Alarm Event Flag.
Definition: f1/rtc.h:146
@ RTC_SEC
Counter Second Flag.
Definition: f1/rtc.h:144
@ RTC_OW
Counter Overflow Flag.
Definition: f1/rtc.h:148
uint32_t rtc_get_counter_val(void)
RTC return the Counter Value.
Definition: rtc.c:214
void rtc_awake_from_standby(void)
RTC Start RTC after Standby Mode.
Definition: rtc.c:368
void rtc_set_prescale_val(uint32_t prescale_val)
RTC Set the prescaler Value.
Definition: rtc.c:200
void rtc_clear_flag(rtcflag_t flag_val)
RTC Clear an Interrupt Flag.
Definition: rtc.c:313
void rtc_set_alarm_time(uint32_t alarm_time)
RTC Set the Alarm Time.
Definition: rtc.c:162
void rtc_interrupt_disable(rtcflag_t flag_val)
RTC Disable Interrupt.
Definition: rtc.c:287
void rtc_disable_alarm(void)
RTC Disable the Alarm.
Definition: rtc.c:187
void rtc_auto_awake(enum rcc_osc clock_source, uint32_t prescale_val)
RTC Configuration on Wakeup.
Definition: rtc.c:400
uint32_t rtc_get_alarm_val(void)
RTC return the Alarm Value.
Definition: rtc.c:236
uint32_t rtc_check_flag(rtcflag_t flag_val)
RTC Return a Flag Setting.
Definition: rtc.c:338
void rtc_exit_config_mode(void)
RTC Leave Configuration Mode.
Definition: rtc.c:145
void rtc_awake_from_off(enum rcc_osc clock_source)
RTC Set Operational from the Off state.
Definition: rtc.c:85
void rtc_interrupt_enable(rtcflag_t flag_val)
RTC Enable Interrupt.
Definition: rtc.c:261
void rtc_enable_alarm(void)
RTC Enable the Alarm.
Definition: rtc.c:175
uint32_t rtc_get_prescale_div_val(void)
RTC return the prescaler Value.
Definition: rtc.c:225
void rtc_set_counter_val(uint32_t counter_val)
RTC set the Counter.
Definition: rtc.c:247
void rtc_enter_config_mode(void)
RTC Enter Configuration Mode.
Definition: rtc.c:128