#include "cgc.h"
#include "common.h"
#include "BAT32A239.h"
#include "gpio.h"
#include "RTE_RTC.h"
#include"isr.h"
#define USED_FSUB_RTC_FCLK
/**
* @brief Convert from 2 digit BCD to Binary.
* @param Value: BCD value to be converted.
* @retval Converted word
*/
uint8_t RTC_Bcd2ToByte(uint8_t Value)
{
uint8_t tmp = 0;
tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;
return (tmp + (Value & (uint8_t)0x0F));
}
/**
* @brief Converts a 2 digit decimal to BCD format.
* @param Value: Byte to be converted.
* @retval Converted byte
*/
uint8_t RTC_ByteToBcd2_Format(uint8_t Value)
{
uint8_t bcdhigh = 0;
while (Value >= 10)
{
bcdhigh++;
Value -= 10;
}
return ((uint8_t)(bcdhigh << 4) | Value);
}
/**************************************************************************/ /**
* \brief Determine if a year is leap year
* \param Year: the year to be determined
* \retval \arg 0: Not leap year
* \arg 1: Leap year
******************************************************************************/
// static uint8_t RTE_RTC_Determine_Leap_Year(uint16_t Year)
// {
// if(Year%4==0) //�����ܱ�4����
// {
// if(Year%100==0)
// {
// if(Year%400==0)
// {return 1;}//�����???00��β,��Ҫ�ܱ�400����
// else
// {return 0;}
// }
// else
// {return 1;}
// }
// else
// {return 0;}
// }
// static void RTE_RTC_Stop(void)
// {
// RTC_Stop();
// }
static void RTE_RTC_Start(void)
{
RTC_Start();
}
void RTE_RTC_Pre_Init(void)
{
RTC_Stop(); /* Stop RTCA*/
#ifdef USED_FSUB_RTC_FCLK
CGC_LSEConfig(OSC_OSCILLATOR,OSC_NORMAL_POWER);//�ⲿ����ʱ��
#else
CGC_HSEConfig(OSC_OSCILLATOR,OSC_UNDER_10M);
CGC_PLL_Setting(PLL_SR_fMX,PLL_DIV_2,PLL_MUL_16);
CGC_PLL_CFG_AS_FCLK();
#endif
}
void RTE_RTC_Set_Time(RTC_TimeTypeDef* RTC_TimeStruct, RTC_DateTypeDef* RTC_DateStruct)
{
CGC_PER0PeriphClockCmd(CGC_PER0Periph_RTC,DISABLE); /*Stop all clock counters*/
/*Write start values*/
RTC_SetTime(RTC_TimeStruct);
RTC_SetDate(RTC_DateStruct);
/*Start all clock counters*/
CGC_PER0PeriphClockCmd(CGC_PER0Periph_RTC,ENABLE);
}
void RTE_RTC_Get_CounterValue(RTC_CounterTypeDef *counter_val)
{
RTC->RTCC1 |= RTC_RTCC1_RWAIT_Msk; // stops SEC to YEAR counters. Mode to read or write counter value
while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) == 0); // wait RWST = 1
counter_val->time.RTC_Seconds = RTC->SEC;
counter_val->time.RTC_Minutes = RTC->MIN;
counter_val->time.RTC_Hours = RTC->HOUR;
counter_val->date.RTC_Day = RTC->DAY;
counter_val->date.RTC_WeekDay = RTC->WEEK;
counter_val->date.RTC_Month = RTC->MONTH;
counter_val->date.RTC_Year = RTC->YEAR;
RTC->RTCC1 &= ~RTC_RTCC1_RWAIT_Msk; // sets counter operation
while((RTC->RTCC1 & RTC_RTCC1_RWST_Msk) != 0); // wait RWST = 0
}
void rtc_interrupt(void *msg)
{
if (RTC->RTCC1 & RTC_RTCC1_WAFG_Msk) //if generate alarm interrupt
{
RTC->RTCC1 &= (uint8_t)~0x10; // clear WAFG
INTC_ClearPendingIRQ(RTC_IRQn); //clear INTRTC flag
}
if (RTC->RTCC1 & RTC_RTCC1_RIFG_Msk) //if generate consant period interrupt
{
RTC->RTCC1 &= (uint8_t)~0x08; // clear RIFG
INTC_ClearPendingIRQ(RTC_IRQn); // clear INTRTC flag
}
}
void RTE_RTC_Init(RTC_Information_st_t g_stRTCInformation)
{
RTC_InitTypeDef RTC_InitStructure = {0};
// GPIO_InitTypeDef GPIO_InitStruct = {0};
#ifdef USED_FSUB_RTC_FCLK
RTC_InitStructure.RTC_Clk = RTC_FSUB;
#else
RTC_InitStructure.RTC_Clk = RTC_8MHZ;
#endif
// RTC_InitStructure.RTC_Clk = RTC_FSUB; //?????��?????��??
RTC_InitStructure.RTC_Time.RTC_Seconds = g_stRTCInformation.u8RTCSecond;
RTC_InitStructure.RTC_Time.RTC_Minutes = g_stRTCInformation.u8RTCMinute;
RTC_InitStructure.RTC_Time.RTC_Hours = g_stRTCInformation.u8RTCHour; //????8??30��?20??
RTC_InitStructure.RTC_Time.RTC_H12 = RTC_H12_AM;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;//RTC_HourFormat_24
RTC_InitStructure.RTC_Date.RTC_Day = g_stRTCInformation.u8RTCDayOfMonth;// 22
RTC_InitStructure.RTC_Date.RTC_WeekDay = g_stRTCInformation.u8RTCDayOfWeek;//????
RTC_InitStructure.RTC_Date.RTC_Month = g_stRTCInformation.u8RTCMonth; //5??
RTC_InitStructure.RTC_Date.RTC_Year = g_stRTCInformation.u8RTCYear; //2022?��
RTC_InitStructure.RTC_Period = Period_None; //RTC ????????1s?��?��???��????????
RTC_InitStructure.RTC_Alarm_Onoff = RTC_Alarm_Off;
RTC_InitStructure.RTC_Alarm.Alarm_Minute = 0;
RTC_InitStructure.RTC_Alarm.Alarm_Hour = 12;
RTC_InitStructure.RTC_Alarm.Alarm_Week = ALARM_WEEK(SUNDAY) | ALARM_WEEK(SATURDAY);
RTC_InitStructure.RTC_1HZ_Output = DISABLE; //RTC1HZ diable output
RTC_Init(&RTC_InitStructure);
RTC->SUBCUD = 0x1D;
ISR_Register(RTC_IRQn, rtc_interrupt); //RTC????��????��??��??��
RTE_RTC_Start();
// ISR_DisRegister(RTC_IRQn, rtc_interrupt);
}