/** @addtogroup rtc_file @author @htmlonly © @endhtmlonly 2012 Karl Palsson */ /* * This file is part of the libopencm3 project. * * Copyright (C) 2012 Karl Palsson * * 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 . */ /**@{*/ #include /*---------------------------------------------------------------------------*/ /** @brief Set RTC prescalars. This sets the RTC synchronous and asynchronous prescalars. */ void rtc_set_prescaler(u32 sync, u32 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(u16 wkup_time, u8 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; } /**@}*/