316 lines
8.1 KiB
C
316 lines
8.1 KiB
C
/********************************** (C) COPYRIGHT *******************************
|
|
* File Name : ch32v30x_rtc.c
|
|
* Author : WCH
|
|
* Version : V1.0.0
|
|
* Date : 2021/06/06
|
|
* 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 "ch32v30x_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 high1a = 0, high1b = 0, high2a = 0, high2b = 0;
|
|
uint16_t low1 = 0, low2 = 0;
|
|
|
|
do{
|
|
high1a = RTC->CNTH;
|
|
high1b = RTC->CNTH;
|
|
}while( high1a != high1b );
|
|
|
|
do{
|
|
low1 = RTC->CNTL;
|
|
low2 = RTC->CNTL;
|
|
}while( low1 != low2 );
|
|
|
|
do{
|
|
high2a = RTC->CNTH;
|
|
high2b = RTC->CNTH;
|
|
}while( high2a != high2b );
|
|
|
|
if(high1b != high2b)
|
|
{
|
|
do{
|
|
low1 = RTC->CNTL;
|
|
low2 = RTC->CNTL;
|
|
}while( low1 != low2 );
|
|
}
|
|
|
|
return (((uint32_t)high2b << 16) | low2);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @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)
|
|
{
|
|
uint16_t high1a = 0, high1b = 0, high2a = 0, high2b = 0;
|
|
uint16_t low1 = 0, low2 = 0;
|
|
|
|
do{
|
|
high1a = RTC->DIVH;
|
|
high1b = RTC->DIVH;
|
|
}while( high1a != high1b );
|
|
|
|
do{
|
|
low1 = RTC->DIVL;
|
|
low2 = RTC->DIVL;
|
|
}while( low1 != low2 );
|
|
|
|
do{
|
|
high2a = RTC->DIVH;
|
|
high2b = RTC->DIVH;
|
|
}while( high2a != high2b );
|
|
|
|
if(high1b != high2b)
|
|
{
|
|
do{
|
|
low1 = RTC->DIVL;
|
|
low2 = RTC->DIVL;
|
|
}while( low1 != low2 );
|
|
}
|
|
|
|
return ((((uint32_t)high2b & (uint32_t)0x000F) << 16) | low2);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @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;
|
|
}
|