mbed-os/targets/TARGET_GigaDevice/TARGET_GD32F30X/rtc_api.c

113 lines
3.2 KiB
C

/* mbed Microcontroller Library
* Copyright (c) 2018 GigaDevice Semiconductor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if DEVICE_RTC
#include "rtc_api.h"
static uint8_t rtc_init_flag = 0;
/** Initialize the RTC peripheral
*
* Powerup the RTC in perpetration for access. This function must be called
* before any other RTC functions ares called. This does not change the state
* of the RTC. It just enables access to it.
*
* @note This function is safe to call repeatedly - Tested by ::rtc_init_test
*/
void rtc_init(void)
{
/* make sure RTC only init once */
if (rtc_init_flag) {
return;
}
rtc_init_flag = 1;
/* enable PMU and BKPI clocks */
rcu_periph_clock_enable(RCU_BKPI);
rcu_periph_clock_enable(RCU_PMU);
/* allow access to BKP domain */
pmu_backup_write_enable();
/* enable LXTAL */
rcu_osci_on(RCU_LXTAL);
/* wait till LXTAL is ready */
rcu_osci_stab_wait(RCU_LXTAL);
/* select RCU_LXTAL as RTC clock source */
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
/* enable RTC Clock */
rcu_periph_clock_enable(RCU_RTC);
/* wait for RTC registers synchronization */
rtc_register_sync_wait();
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
/* set RTC prescaler: set RTC period to 1s */
rtc_prescaler_set(32767);
/* wait until last write operation on RTC registers has finished */
rtc_lwoff_wait();
}
/** Deinitialize RTC
*
* Powerdown the RTC in preparation for sleep, powerdown or reset. That should only
* affect the CPU domain and not the time keeping logic.
* After this function is called no other RTC functions should be called
* except for ::rtc_init.
*/
void rtc_free(void)
{
}
/** Check if the RTC has the time set and is counting
*
* @retval 0 The time reported by the RTC is not valid
* @retval 1 The time has been set the RTC is counting
*/
int rtc_isenabled(void)
{
if (RESET == (RTC_CTL & RTC_CTL_RSYNF)) {
return 0;
} else {
return 1;
}
}
/** Get the current time from the RTC peripheral
*
* @return The current time in seconds
*
* @note Some RTCs are not synchronized with the main clock. If
* this is the case with your RTC then you must read the RTC time
* in a loop to prevent reading the wrong time due to a glitch.
* The test ::rtc_glitch_test is intended to catch this bug.
*/
time_t rtc_read(void)
{
return (rtc_counter_get());
}
/** Write the current time in seconds to the RTC peripheral
*
* @param t The current time to be set in seconds.
*/
void rtc_write(time_t t)
{
rtc_counter_set((uint32_t)t);
rtc_lwoff_wait();
}
#endif /* DEVICE_RTC */