libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
rtc_common_l1f024.c
Go to the documentation of this file.
1/** @addtogroup rtc_file RTC peripheral API
2@ingroup peripheral_apis
3
4@author @htmlonly &copy; @endhtmlonly 2012 Karl Palsson <karlp@tweak.net.au>
5
6*/
7
8/*
9 * This file is part of the libopencm3 project.
10 *
11 * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
12 *
13 * This library is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this library. If not, see <http://www.gnu.org/licenses/>.
25 */
26
27/**@{*/
28
30
31static uint8_t _rtc_dec_to_bcd(uint8_t dec)
32{
33 return ((dec / 10) << 4) | (dec % 10);
34}
35
36/*---------------------------------------------------------------------------*/
37/** @brief Set RTC prescalars.
38
39This sets the RTC synchronous and asynchronous prescalars.
40*/
41
42void rtc_set_prescaler(uint32_t sync, uint32_t async)
43{
44 /*
45 * Even if only one of the two fields needs to be changed,
46 * 2 separate write accesses must be performed to the RTC_PRER register.
47 */
50}
51
52/*---------------------------------------------------------------------------*/
53/** @brief Wait for RTC registers to be synchronised with the APB1 bus
54
55 Time and Date are accessed through shadow registers which must be synchronized
56*/
57
59{
60 /* Unlock RTC registers */
61 RTC_WPR = 0xca;
62 RTC_WPR = 0x53;
63
64 RTC_ISR &= ~(RTC_ISR_RSF);
65
66 while (!(RTC_ISR & RTC_ISR_RSF));
67
68 /* disable write protection again */
69 RTC_WPR = 0xff;
70}
71
72/*---------------------------------------------------------------------------*/
73/** @brief Unlock write access to the RTC registers
74
75*/
76void rtc_unlock(void)
77{
78 RTC_WPR = 0xca;
79 RTC_WPR = 0x53;
80}
81
82/*---------------------------------------------------------------------------*/
83/** @brief Lock write access to the RTC registers
84
85*/
86void rtc_lock(void)
87{
88 RTC_WPR = 0xff;
89}
90
91/*---------------------------------------------------------------------------*/
92/** @brief Sets the wakeup time auto-reload value
93
94*/
95void rtc_set_wakeup_time(uint16_t wkup_time, uint8_t rtc_cr_wucksel)
96{
97 /* FTFM:
98 * The following sequence is required to configure or change the wakeup
99 * timer auto-reload value (WUT[15:0] in RTC_WUTR):
100 * 1. Clear WUTE in RTC_CR to disable the wakeup timer.
101 */
102 RTC_CR &= ~RTC_CR_WUTE;
103 /* 2. Poll WUTWF until it is set in RTC_ISR to make sure the access to
104 * wakeup auto-reload counter and to WUCKSEL[2:0] bits is allowed.
105 * It takes around 2 RTCCLK clock cycles (due to clock
106 * synchronization).
107 */
108 while (!((RTC_ISR) & (RTC_ISR_WUTWF)));
109 /* 3. Program the wakeup auto-reload value WUT[15:0], and the wakeup
110 * clock selection (WUCKSEL[2:0] bits in RTC_CR).Set WUTE in RTC_CR
111 * to enable the timer again. The wakeup timer restarts
112 * down-counting.
113 */
114 RTC_WUTR = wkup_time;
116 RTC_CR |= (rtc_cr_wucksel << RTC_CR_WUCLKSEL_SHIFT);
118}
119
120/*---------------------------------------------------------------------------*/
121/** @brief Clears the wakeup flag
122
123@details This function should be called first in the rtc_wkup_isr()
124*/
126{
127 RTC_ISR &= ~RTC_ISR_WUTF;
128}
129
130/*---------------------------------------------------------------------------*/
131/** @brief Sets the initialization flag
132
133@details Requires unlocking backup domain write protection (PWR_CR_DBP)
134*/
136{
138}
139
140/*---------------------------------------------------------------------------*/
141/** @brief Clears (resets) the initialization flag
142
143@details Requires unlocking backup domain write protection (PWR_CR_DBP)
144*/
146{
147 RTC_ISR &= ~RTC_ISR_INIT;
148}
149
150/*---------------------------------------------------------------------------*/
151/** @brief Returns if the RTC_ISR init flag RTC_ISR_INITF is set
152
153@details Requires unlocking backup domain write protection (PWR_CR_DBP)
154*/
156{
157 return (RTC_ISR & RTC_ISR_INITF);
158}
159
160/*---------------------------------------------------------------------------*/
161/** @brief Waits infinitely for initialization flag to be set in RTC_ISR
162
163@details Requires unlocking backup domain write protection (PWR_CR_DBP)
164*/
166{
167 while (!rtc_init_flag_is_ready());
168}
169
170/*---------------------------------------------------------------------------*/
171/** @brief Sets the bypass shadow bit in RTC_CR
172
173@details Requires unlocking backup domain write protection (PWR_CR_DBP)
174*/
176{
178}
179
180/*---------------------------------------------------------------------------*/
181/** @brief Clears the bypass shadow bit in RTC_CR
182
183@details Requires unlocking backup domain write protection (PWR_CR_DBP)
184*/
186{
187 RTC_CR &= ~RTC_CR_BYPSHAD;
188}
189
190/*---------------------------------------------------------------------------*/
191/** @brief Sets the RTC control register hour format to AM (24h)
192
193@details Requires unlocking backup domain write protection (PWR_CR_DBP)
194*/
196{
197 RTC_CR &= ~RTC_CR_FMT;
198}
199
200/*---------------------------------------------------------------------------*/
201/** @brief Sets the RTC control register hour format to PM (12h)
202
203@details Requires unlocking backup domain write protection (PWR_CR_DBP)
204*/
206{
208}
209
210/*---------------------------------------------------------------------------*/
211/** @brief Sets the RTC BCD calendar year value
212
213@details Requires unlocking the RTC write-protection (RTC_WPR)
214
215The year value should only be the abbreviated year tens, meaning if 2021 is
216desired pass in only 21.
217*/
218void rtc_calendar_set_year(uint8_t year)
219{
220 uint8_t bcd_year = _rtc_dec_to_bcd(year);
222 RTC_DR |= (((bcd_year >> 4) & RTC_DR_YT_MASK) << RTC_DR_YT_SHIFT) |
223 ((bcd_year & RTC_DR_YU_MASK) << RTC_DR_YU_SHIFT);
224}
225
226/*---------------------------------------------------------------------------*/
227/** @brief Sets the RTC BCD calendar weekday
228
229@details Requires unlocking the RTC write-protection (RTC_WPR)
230*/
232{
234 RTC_DR |= (rtc_dr_wdu << RTC_DR_WDU_SHIFT);
235}
236
237/*---------------------------------------------------------------------------*/
238/** @brief Sets the RTC BCD calendar month value
239
240@details Requires unlocking the RTC write-protection (RTC_WPR)
241*/
242void rtc_calendar_set_month(uint8_t month)
243{
244 uint8_t bcd_month = _rtc_dec_to_bcd(month);
246 RTC_DR |= (((bcd_month >> 4) & RTC_DR_MT_MASK) << RTC_DR_MT_SHIFT) |
247 ((bcd_month & RTC_DR_MU_MASK) << RTC_DR_MU_SHIFT);
248}
249
250/*---------------------------------------------------------------------------*/
251/** @brief Sets the RTC BCD calendar day value
252
253@details Requires unlocking the RTC write-protection (RTC_WPR)
254*/
255void rtc_calendar_set_day(uint8_t day)
256{
257 uint8_t bcd_day = _rtc_dec_to_bcd(day);
259 RTC_DR |= (((bcd_day >> 4) & RTC_DR_DT_MASK) << RTC_DR_DT_SHIFT) |
260 ((bcd_day & RTC_DR_DU_MASK) << RTC_DR_DU_SHIFT);
261}
262
263/*---------------------------------------------------------------------------*/
264/** @brief Sets the RTC BCD calendar value
265
266@details Requires unlocking the RTC write-protection (RTC_WPR)
267
268The year value should only be the abbreviated year tens, meaning if 2021 is
269desired pass in only 21.
270*/
271void rtc_calendar_set_date(uint8_t year, uint8_t month, uint8_t day, enum rtc_weekday rtc_dr_wdu)
272{
275 rtc_calendar_set_weekday(rtc_dr_wdu);
277}
278
279/*---------------------------------------------------------------------------*/
280/** @brief Sets the RTC BCD time hour value
281
282@details Requires unlocking the RTC write-protection (RTC_WPR)
283
284Pass true to use_am_notation to use 24-hour input time; pass false to
285use_am_notation to use 12-hour (AM/PM) input time
286*/
287void rtc_time_set_hour(uint8_t hour, bool use_am_notation)
288{
289 if (use_am_notation) {
290 RTC_TR &= ~(RTC_TR_PM);
291 } else {
292 RTC_TR |= RTC_TR_PM;
293 }
294
295 uint8_t bcd_hour = _rtc_dec_to_bcd(hour);
297 RTC_TR |= (((bcd_hour >> 4) & RTC_TR_HT_MASK) << RTC_TR_HT_SHIFT) |
298 ((bcd_hour & RTC_TR_HU_MASK) << RTC_TR_HU_SHIFT);
299}
300
301/*---------------------------------------------------------------------------*/
302/** @brief Sets the RTC BCD time minute value
303
304@details Requires unlocking the RTC write-protection (RTC_WPR)
305*/
306void rtc_time_set_minute(uint8_t minute)
307{
308 uint8_t bcd_minute = _rtc_dec_to_bcd(minute);
310 RTC_TR |= (((bcd_minute >> 4) & RTC_TR_MNT_MASK) << RTC_TR_MNT_SHIFT) |
311 ((bcd_minute & RTC_TR_MNU_MASK) << RTC_TR_MNU_SHIFT);
312}
313
314/*---------------------------------------------------------------------------*/
315/** @brief Sets the RTC BCD time second value
316
317@details Requires unlocking the RTC write-protection (RTC_WPR)
318*/
319void rtc_time_set_second(uint8_t second)
320{
321 uint8_t bcd_second = _rtc_dec_to_bcd(second);
323 RTC_TR |= (((bcd_second >> 4) & RTC_TR_ST_MASK) << RTC_TR_ST_SHIFT) |
324 ((bcd_second & RTC_TR_SU_MASK) << RTC_TR_SU_SHIFT);
325}
326
327/*---------------------------------------------------------------------------*/
328/** @brief Sets the RTC BCD time
329
330@details Requires unlocking the RTC write-protection (RTC_WPR)
331*/
332void rtc_time_set_time(uint8_t hour, uint8_t minute, uint8_t second, bool use_am_notation)
333{
334 rtc_time_set_hour(hour, use_am_notation);
335 rtc_time_set_minute(minute);
336 rtc_time_set_second(second);
337}
338/**@}*/
#define RTC_CR_WUTE
Wakeup timer enable.
#define RTC_CR_WUCLKSEL_MASK
#define RTC_CR_BYPSHAD
Bypass the shadow registers.
#define RTC_CR_WUCLKSEL_SHIFT
#define RTC_CR_FMT
Hour format.
rtc_weekday
#define RTC_DR_WDU_MASK
Weekday units mask.
#define RTC_DR_MT_SHIFT
Month tens in BCD format shift.
#define RTC_DR_YT_SHIFT
Year tens in BCD format shift.
#define RTC_DR_MU_SHIFT
Month units in BCD format shift.
#define RTC_DR_MU_MASK
Month units in BCD format mask.
#define RTC_DR_YT_MASK
Year tens in BCD format mask.
#define RTC_DR_DT_SHIFT
Date tens in BCD format shift.
#define RTC_DR_DU_MASK
Date units in BCD format mask.
#define RTC_DR_MT_MASK
Month tens in BCD format mask.
#define RTC_DR_DT_MASK
Date tens in BCD format mask.
#define RTC_DR_DU_SHIFT
Date units in BCD format shift.
#define RTC_DR_WDU_SHIFT
Weekday units shift.
#define RTC_DR_YU_MASK
Year units in BCD format mask.
#define RTC_DR_YU_SHIFT
Year units in BCD format shift.
void rtc_calendar_set_weekday(enum rtc_weekday rtc_dr_wdu)
Sets the RTC BCD calendar weekday.
void rtc_disable_bypass_shadow_register(void)
Clears the bypass shadow bit in RTC_CR.
void rtc_unlock(void)
Unlock write access to the RTC registers.
void rtc_wait_for_synchro(void)
Wait for RTC registers to be synchronised with the APB1 bus.
void rtc_time_set_hour(uint8_t hour, bool use_am_notation)
Sets the RTC BCD time hour value.
void rtc_set_init_flag(void)
Sets the initialization flag.
void rtc_lock(void)
Lock write access to the RTC registers.
void rtc_time_set_minute(uint8_t minute)
Sets the RTC BCD time minute value.
void rtc_calendar_set_date(uint8_t year, uint8_t month, uint8_t day, enum rtc_weekday rtc_dr_wdu)
Sets the RTC BCD calendar value.
void rtc_calendar_set_month(uint8_t month)
Sets the RTC BCD calendar month value.
void rtc_clear_init_flag(void)
Clears (resets) the initialization flag.
void rtc_set_am_format(void)
Sets the RTC control register hour format to AM (24h)
bool rtc_init_flag_is_ready(void)
Returns if the RTC_ISR init flag RTC_ISR_INITF is set.
void rtc_time_set_time(uint8_t hour, uint8_t minute, uint8_t second, bool use_am_notation)
Sets the RTC BCD time.
void rtc_set_prescaler(uint32_t sync, uint32_t async)
Set RTC prescalars.
void rtc_wait_for_init_ready(void)
Waits infinitely for initialization flag to be set in RTC_ISR.
void rtc_calendar_set_year(uint8_t year)
Sets the RTC BCD calendar year value.
void rtc_enable_bypass_shadow_register(void)
Sets the bypass shadow bit in RTC_CR.
void rtc_time_set_second(uint8_t second)
Sets the RTC BCD time second value.
void rtc_set_wakeup_time(uint16_t wkup_time, uint8_t rtc_cr_wucksel)
Sets the wakeup time auto-reload value.
static uint8_t _rtc_dec_to_bcd(uint8_t dec)
void rtc_set_pm_format(void)
Sets the RTC control register hour format to PM (12h)
void rtc_clear_wakeup_flag(void)
Clears the wakeup flag.
void rtc_calendar_set_day(uint8_t day)
Sets the RTC BCD calendar day value.
#define RTC_ISR_WUTWF
WUTWF: Wakeup timer write flag.
#define RTC_ISR_RSF
RSF: Registers sync flag.
#define RTC_ISR_INITF
INITF: Initialization flag.
#define RTC_ISR_INIT
INIT: Initialization mode.
#define RTC_PRER_PREDIV_S_MASK
Sync prescaler factor mask.
#define RTC_PRER_PREDIV_A_SHIFT
Async prescaler factor shift.
#define RTC_WUTR
RTC wakeup timer register (RTC_WUTR)
#define RTC_PRER
RTC prescaler register (RTC_PRER)
#define RTC_DR
RTC date register (RTC_DR)
#define RTC_CR
RTC control register (RTC_CR)
#define RTC_WPR
RTC write protection register (RTC_WPR)
#define RTC_TR
RTC time register (RTC_TR)
#define RTC_ISR
RTC initialization and status register (RTC_ISR)
#define RTC_TR_ST_SHIFT
Second tens in BCD format shift.
#define RTC_TR_HU_MASK
Hour units in BCD format mask.
#define RTC_TR_MNU_SHIFT
Minute units in BCD format shift.
#define RTC_TR_MNU_MASK
Minute units in BCD format mask.
#define RTC_TR_PM
AM/PM notation.
#define RTC_TR_HU_SHIFT
Hour units in BCD format shift.
#define RTC_TR_SU_MASK
Second units in BCD format mask.
#define RTC_TR_ST_MASK
Second tens in BCD format mask.
#define RTC_TR_SU_SHIFT
Second units in BCD format shift.
#define RTC_TR_MNT_MASK
Minute tens in BCD format mask.
#define RTC_TR_HT_SHIFT
Hour tens in BCD format shift.
#define RTC_TR_MNT_SHIFT
Minute tens in BCD format shift.
#define RTC_TR_HT_MASK
Hour tens in BCD format mask.