#include "BAT32A279.h"
#include "cgc.h"
#include "isr.h"
#include "gpio.h"
#include "RTE_RTC.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(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);

    ISR_Register(RTC_IRQn, rtc_interrupt);     //RTC????��????��??��??��

    RTE_RTC_Start();

//    ISR_DisRegister(RTC_IRQn, rtc_interrupt); 

}