diff options
Diffstat (limited to 'libopencm3/lib/stm32/common/rtc_common_l1f024.c')
-rw-r--r-- | libopencm3/lib/stm32/common/rtc_common_l1f024.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/libopencm3/lib/stm32/common/rtc_common_l1f024.c b/libopencm3/lib/stm32/common/rtc_common_l1f024.c new file mode 100644 index 0000000..7579dfd --- /dev/null +++ b/libopencm3/lib/stm32/common/rtc_common_l1f024.c @@ -0,0 +1,123 @@ +/** @addtogroup rtc_file + +@author @htmlonly © @endhtmlonly 2012 Karl Palsson <karlp@tweak.net.au> + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/**@{*/ + +#include <libopencm3/stm32/rtc.h> + +/*---------------------------------------------------------------------------*/ +/** @brief Set RTC prescalars. + +This sets the RTC synchronous and asynchronous prescalars. +*/ + +void rtc_set_prescaler(uint32_t sync, uint32_t async) +{ + /* + * Even if only one of the two fields needs to be changed, + * 2 separate write accesses must be performed to the RTC_PRER register. + */ + RTC_PRER = (sync & RTC_PRER_PREDIV_S_MASK); + RTC_PRER |= (async << RTC_PRER_PREDIV_A_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Wait for RTC registers to be synchronised with the APB1 bus + + Time and Date are accessed through shadow registers which must be synchronized +*/ + +void rtc_wait_for_synchro(void) +{ + /* Unlock RTC registers */ + RTC_WPR = 0xca; + RTC_WPR = 0x53; + + RTC_ISR &= ~(RTC_ISR_RSF); + + while (!(RTC_ISR & RTC_ISR_RSF)); + + /* disable write protection again */ + RTC_WPR = 0xff; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock write access to the RTC registers + +*/ +void rtc_unlock(void) +{ + RTC_WPR = 0xca; + RTC_WPR = 0x53; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock write access to the RTC registers + +*/ +void rtc_lock(void) +{ + RTC_WPR = 0xff; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Sets the wakeup time auto-reload value + +*/ +void rtc_set_wakeup_time(uint16_t wkup_time, uint8_t rtc_cr_wucksel) +{ + /* FTFM: + * The following sequence is required to configure or change the wakeup + * timer auto-reload value (WUT[15:0] in RTC_WUTR): + * 1. Clear WUTE in RTC_CR to disable the wakeup timer. + */ + RTC_CR &= ~RTC_CR_WUTE; + /* 2. Poll WUTWF until it is set in RTC_ISR to make sure the access to + * wakeup auto-reload counter and to WUCKSEL[2:0] bits is allowed. + * It takes around 2 RTCCLK clock cycles (due to clock + * synchronization). + */ + while (!((RTC_ISR) & (RTC_ISR_WUTWF))); + /* 3. Program the wakeup auto-reload value WUT[15:0], and the wakeup + * clock selection (WUCKSEL[2:0] bits in RTC_CR).Set WUTE in RTC_CR + * to enable the timer again. The wakeup timer restarts + * down-counting. + */ + RTC_WUTR = wkup_time; + RTC_CR |= (rtc_cr_wucksel << RTC_CR_WUCLKSEL_SHIFT); + RTC_CR |= RTC_CR_WUTE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clears the wakeup flag + +@details This function should be called first in the rtc_wkup_isr() +*/ +void rtc_clear_wakeup_flag(void) +{ + RTC_ISR &= ~RTC_ISR_WUTF; +} + +/**@}*/ |