/********************************** (C) COPYRIGHT ******************************* * File Name : ch32f10x_rtc.c * Author : WCH * Version : V1.0.0 * Date : 2019/10/15 * Description : This file provides all the RTC firmware functions. ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #include "ch32f10x_rtc.h" /* RTC_Private_Defines */ #define RTC_LSB_MASK ((uint32_t)0x0000FFFF) /* RTC LSB Mask */ #define PRLH_MSB_MASK ((uint32_t)0x000F0000) /* RTC Prescaler MSB Mask */ /********************************************************************* * @fn RTC_ITConfig * * @brief Enables or disables the specified RTC interrupts. * * @param RTC_IT - specifies the RTC interrupts sources to be enabled or disabled. * RTC_IT_OW - Overflow interrupt * RTC_IT_ALR - Alarm interrupt * RTC_IT_SEC - Second interrupt * * @return NewState - new state of the specified RTC interrupts(ENABLE or DISABLE). */ void RTC_ITConfig( uint16_t RTC_IT, FunctionalState NewState ) { if( NewState != DISABLE ) { RTC->CTLRH |= RTC_IT; } else { RTC->CTLRH &= ( uint16_t )~RTC_IT; } } /********************************************************************* * @fn RTC_EnterConfigMode * * @brief Enters the RTC configuration mode. * * @return none */ void RTC_EnterConfigMode( void ) { RTC->CTLRL |= RTC_CTLRL_CNF; } /********************************************************************* * @fn RTC_ExitConfigMode * * @brief Exits from the RTC configuration mode. * * @return none */ void RTC_ExitConfigMode( void ) { RTC->CTLRL &= ( uint16_t )~( ( uint16_t )RTC_CTLRL_CNF ); } /********************************************************************* * @fn RTC_GetCounter * * @brief Gets the RTC counter value * * @return RTC counter value */ uint32_t RTC_GetCounter( void ) { uint16_t high1 = 0, high2 = 0, low = 0; high1 = RTC->CNTH; low = RTC->CNTL; high2 = RTC->CNTH; if( high1 != high2 ) { return ( ( ( uint32_t ) high2 << 16 ) | RTC->CNTL ); } else { return ( ( ( uint32_t ) high1 << 16 ) | low ); } } /********************************************************************* * @fn RTC_SetCounter * * @brief Sets the RTC counter value. * * @param CounterValue - RTC counter new value. * * @return RTC counter value */ void RTC_SetCounter( uint32_t CounterValue ) { RTC_EnterConfigMode(); RTC->CNTH = CounterValue >> 16; RTC->CNTL = ( CounterValue & RTC_LSB_MASK ); RTC_ExitConfigMode(); } /********************************************************************* * @fn RTC_SetPrescaler * * @brief Sets the RTC prescaler value * * @param PrescalerValue - RTC prescaler new value * * @return none */ void RTC_SetPrescaler( uint32_t PrescalerValue ) { RTC_EnterConfigMode(); RTC->PSCRH = ( PrescalerValue & PRLH_MSB_MASK ) >> 16; RTC->PSCRL = ( PrescalerValue & RTC_LSB_MASK ); RTC_ExitConfigMode(); } /********************************************************************* * @fn RTC_SetAlarm * * @brief Sets the RTC alarm value * * @param AlarmValue - RTC alarm new value * * @return none */ void RTC_SetAlarm( uint32_t AlarmValue ) { RTC_EnterConfigMode(); RTC->ALRMH = AlarmValue >> 16; RTC->ALRML = ( AlarmValue & RTC_LSB_MASK ); RTC_ExitConfigMode(); } /********************************************************************* * @fn RTC_GetDivider * * @brief Gets the RTC divider value * * @return RTC Divider value */ uint32_t RTC_GetDivider( void ) { uint32_t tmp = 0x00; tmp = ( ( uint32_t )RTC->DIVH & ( uint32_t )0x000F ) << 16; tmp |= RTC->DIVL; return tmp; } /********************************************************************* * @fn RTC_WaitForLastTask * * @brief Waits until last write operation on RTC registers has finished * Note- * This function must be called before any write to RTC registers. * @return none */ void RTC_WaitForLastTask( void ) { while( ( RTC->CTLRL & RTC_FLAG_RTOFF ) == ( uint16_t )RESET ) { } } /********************************************************************* * @fn RTC_WaitForSynchro * * @brief Waits until the RTC registers are synchronized with RTC APB clock * Note- * This function must be called before any read operation after an APB reset * or an APB clock stop. * * @return none */ void RTC_WaitForSynchro( void ) { RTC->CTLRL &= ( uint16_t )~RTC_FLAG_RSF; while( ( RTC->CTLRL & RTC_FLAG_RSF ) == ( uint16_t )RESET ) { } } /********************************************************************* * @fn RTC_GetFlagStatus * * @brief Checks whether the specified RTC flag is set or not * * @param RTC_FLAG- specifies the flag to check * RTC_FLAG_RTOFF - RTC Operation OFF flag * RTC_FLAG_RSF - Registers Synchronized flag * RTC_FLAG_OW - Overflow flag * RTC_FLAG_ALR - Alarm flag * RTC_FLAG_SEC - Second flag * * @return The new state of RTC_FLAG (SET or RESET) */ FlagStatus RTC_GetFlagStatus( uint16_t RTC_FLAG ) { FlagStatus bitstatus = RESET; if( ( RTC->CTLRL & RTC_FLAG ) != ( uint16_t )RESET ) { bitstatus = SET; } else { bitstatus = RESET; } return bitstatus; } /********************************************************************* * @fn RTC_ClearFlag * * @brief Clears the RTC's pending flags * * @param RTC_FLAG - specifies the flag to clear * RTC_FLAG_RSF - Registers Synchronized flag * RTC_FLAG_OW - Overflow flag * RTC_FLAG_ALR - Alarm flag * RTC_FLAG_SEC - Second flag * * @return none */ void RTC_ClearFlag( uint16_t RTC_FLAG ) { RTC->CTLRL &= ( uint16_t )~RTC_FLAG; } /********************************************************************* * @fn RTC_GetITStatus * * @brief Checks whether the specified RTC interrupt has occurred or not * * @param RTC_IT - specifies the RTC interrupts sources to check * RTC_FLAG_OW - Overflow interrupt * RTC_FLAG_ALR - Alarm interrupt * RTC_FLAG_SEC - Second interrupt * * @return The new state of the RTC_IT (SET or RESET) */ ITStatus RTC_GetITStatus( uint16_t RTC_IT ) { ITStatus bitstatus = RESET; bitstatus = ( ITStatus )( RTC->CTLRL & RTC_IT ); if( ( ( RTC->CTLRH & RTC_IT ) != ( uint16_t )RESET ) && ( bitstatus != ( uint16_t )RESET ) ) { bitstatus = SET; } else { bitstatus = RESET; } return bitstatus; } /********************************************************************* * @fn RTC_ClearITPendingBit * * @brief Clears the RTC's interrupt pending bits * * @param RTC_IT - specifies the interrupt pending bit to clear * RTC_FLAG_OW - Overflow interrupt * RTC_FLAG_ALR - Alarm interrupt * RTC_FLAG_SEC - Second interrupt * * @return none */ void RTC_ClearITPendingBit( uint16_t RTC_IT ) { RTC->CTLRL &= ( uint16_t )~RTC_IT; }