
#include "r_typedefs.h"
#include "dr7f701441.dvf.h"
#include "RTC.h"
#include "Clock.h"
#include "RTE_TIME.h"
#include <string.h>

volatile uint8_t g_RTCLeapYear; /*1:LeapYear , 0:Not a leap year*/
RTC_Information_st_t g_stRTCInformation;
#define RTC_TIME_OUT_COUNT 500U
/* BCD Convert   decimalism*/
/*The valid range of parameters is not judged*/
static uint8_t RTC_BCD_To_Dec(uint8_t u8RTCBCD)
{
	uint8_t u8RTCData = ((u8RTCBCD >> 4U) * 10U) + (u8RTCBCD & 0X0FU);
	return u8RTCData;
}
/* decimalism Convert  BCD */
uint8_t RTC_Dec_To_BCD(uint8_t u8RTCDec)
{
	uint8_t u8RTCData = (((u8RTCDec / 10U) % 10U) << 4U) + (u8RTCDec % 10U);
	return u8RTCData;
}

/**************************************************************************/ /**
  * \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 RTC_Determine_Leap_Year(uint16_t Year)
{
	uint16_t u16RTCLeapYear = Year;

	/*u16RTCLeapYear = ((Year >> 4) & 0x0F) * 10 + (Year & 0x0F);*/

	if (u16RTCLeapYear & 0x0003U)
	{
		u16RTCLeapYear = 0U;
	}
	else
	{
		u16RTCLeapYear = 1U;
	}

	return (uint8_t)u16RTCLeapYear;
}

static void RTC_Stop(void)
{
	uint16_t u16RTCCount = 0U;
	/*Stop sub-counter */
	RTCA0CE = 0U;
	/*Wait  sub-counter  stop*/
	while ((RTCA0CEST != 0) && (u16RTCCount < RTC_TIME_OUT_COUNT))
	{
		u16RTCCount++;
	}
}
void RTC_Pre_Init(void)
{
	uint16_t u16RTCCount = 0U;
	RTC_Stop(); /* Stop RTCA*/

#if (RTC_MODE_SELECT == RTC_MODE_MAIN)
	RTCA0SLSB = 1U;			   /*Frequency selection mode*/
	RTCA0SCMP = 4000000UL + 92UL;//- 1U; /*4M*/
#else
	RTCA0SLSB = 0U; /*32.768 kHz mode*/
	RTCA0SUBU = 0U; /*Reserved Later modified,Error Correction*/
#endif

	RTCA0AMPM = 1U; /*fix 24Hour Format*/
    
	/*Write start values*/
	RTCA0YEAR = RTC_Dec_To_BCD(0);
	RTCA0MONTH = RTC_Dec_To_BCD(1);
	RTCA0DAY = RTC_Dec_To_BCD(1);
	RTCA0HOUR = RTC_Dec_To_BCD(0);
	RTCA0MIN = RTC_Dec_To_BCD(0);
	RTCA0SEC = RTC_Dec_To_BCD(0);

	/*Starts sub-counter*/
	RTCA0CE = 1U;
	u16RTCCount = 0U;
	/*Wait  sub-counter  enable*/
	while ((RTCA0CEST != 1U) && (u16RTCCount < RTC_TIME_OUT_COUNT))
	{
		u16RTCCount++;
	}
}

void RTC_Set_Time(uint16_t day, uint8_t hour, uint8_t minute, uint8_t second)
{
	uint16_t u16RTCCount = 0U;
	while ((RTCA0WST != 0U) && (u16RTCCount < RTC_TIME_OUT_COUNT)) /*Check that all clock counters are running.*/
	{
		u16RTCCount++;
	}
	RTCA0WAIT = 1U; /*Stop all clock counters*/
	u16RTCCount = 0U;
	while ((RTCA0WST != 1U) && (u16RTCCount < RTC_TIME_OUT_COUNT)) /*Wait  all clock counters  stop*/
	{
		u16RTCCount++;
	}
	/*Write start values*/
	RTCA0YEAR = RTC_Dec_To_BCD(0);
	RTCA0MONTH = RTC_Dec_To_BCD(1);
	RTCA0DAY = RTC_Dec_To_BCD(day);
	RTCA0HOUR = RTC_Dec_To_BCD(hour);
	RTCA0MIN = RTC_Dec_To_BCD(minute);
	RTCA0SEC = RTC_Dec_To_BCD(second);

	/*Start all clock counters*/
	RTCA0WAIT = 0U;
	u16RTCCount = 0U;
	while ((RTCA0WST != 0U) && (u16RTCCount < RTC_TIME_OUT_COUNT)) /*Check that all clock counters are running.*/
	{
		u16RTCCount++;
	}
}
void RTC_Timing_Service(void)
{
    while ( RTCA0WST != 0U ) /*Check that all clock counters are running.*/
    {
        ;
    }
    RTCA0WAIT = 1U;          /*Stop all clock counters*/
    while ( RTCA0WST != 1U ) /*Wait  all clock counters  stop*/
    {
        ;
    }
    /*Read  data*/
    g_stRTCInformation.u8RTCYear       = RTC_BCD_To_Dec(RTCA0YEAR);
    g_stRTCInformation.u8RTCMonth      = RTC_BCD_To_Dec(RTCA0MONTH);
    g_stRTCInformation.u8RTCDayOfMonth = RTC_BCD_To_Dec(RTCA0DAY);
    g_stRTCInformation.u8RTCHour       = RTC_BCD_To_Dec(RTCA0HOUR);
    g_stRTCInformation.u8RTCMinute     = RTC_BCD_To_Dec(RTCA0MIN);
    g_stRTCInformation.u8RTCSecond     = RTC_BCD_To_Dec(RTCA0SEC);
    g_RTCLeapYear                      = RTC_Determine_Leap_Year(g_stRTCInformation.u8RTCYear);
    /*Start all clock counters*/
    RTCA0WAIT = 0U;
    while ( RTCA0WST != 0U ) /*Check that all clock counters are running.*/
    {
        ;
    }
}
void RTC_Get_Time(void)
{
	uint16_t u16RTCCount = 0U;

	while ((RTCA0WST != 0U) && (u16RTCCount < RTC_TIME_OUT_COUNT)) /*Check that all clock counters are running.*/
	{
		u16RTCCount++;
	}
	RTCA0WAIT = 1U; /*Stop all clock counters*/
	u16RTCCount = 0U;
	while ((RTCA0WST != 1U) && (u16RTCCount < RTC_TIME_OUT_COUNT)) /*Wait  all clock counters  stop*/
	{
		u16RTCCount++;
	}
	/*Read  data*/
	g_stRTCInformation.u8RTCYear = RTC_BCD_To_Dec(RTCA0YEAR);
	g_stRTCInformation.u8RTCMonth = RTC_BCD_To_Dec(RTCA0MONTH);
	g_stRTCInformation.u8RTCDayOfMonth = RTC_BCD_To_Dec(RTCA0DAY);
	g_stRTCInformation.u8RTCHour = RTC_BCD_To_Dec(RTCA0HOUR);
	g_stRTCInformation.u8RTCMinute = RTC_BCD_To_Dec(RTCA0MIN);
	g_stRTCInformation.u8RTCSecond = RTC_BCD_To_Dec(RTCA0SEC);
	g_RTCLeapYear = RTC_Determine_Leap_Year(g_stRTCInformation.u8RTCYear);
	/*Start all clock counters*/
	RTCA0WAIT = 0U;
	u16RTCCount = 0U;
	while ((RTCA0WST != 0U) && (u16RTCCount < RTC_TIME_OUT_COUNT)) /*Check that all clock counters are running.*/
	{
		u16RTCCount++;
	}
}

#pragma ghs section bss=".NonInitArea"
RTC_Information_st_t RtcBackup;
#pragma ghs section bss=default
void RTC_Backup_Time(void)
{  
    RTC_Get_Time();
    memcpy((uint8_t*)&RtcBackup, (uint8_t*)&g_stRTCInformation, sizeof (RtcBackup));
}

void Rtc_Restore_Time(void)
{
    uint16_t u16RTCCount = 0U;
	RTC_Stop(); /* Stop RTCA*/

#if (RTC_MODE_SELECT == RTC_MODE_MAIN)
	RTCA0SLSB = 1U;			   /*Frequency selection mode*/
	RTCA0SCMP = 4000000UL + 92UL; //- 1U; /*4M*/
#else
	RTCA0SLSB = 0U; /*32.768 kHz mode*/
	RTCA0SUBU = 0U; /*Reserved Later modified,Error Correction*/
#endif

	RTCA0AMPM = 1U; /*fix 24Hour Format*/

	/*Write start values*/
	RTCA0YEAR = RTC_Dec_To_BCD(RtcBackup.u8RTCYear);
	RTCA0MONTH = RTC_Dec_To_BCD(RtcBackup.u8RTCMonth);
	RTCA0DAY = RTC_Dec_To_BCD(RtcBackup.u8RTCDayOfMonth);
	RTCA0HOUR = RTC_Dec_To_BCD(RtcBackup.u8RTCHour);
	RTCA0MIN = RTC_Dec_To_BCD(RtcBackup.u8RTCMinute);
	RTCA0SEC = RTC_Dec_To_BCD(RtcBackup.u8RTCSecond);

	/*Starts sub-counter*/
	RTCA0CE = 1U;
	u16RTCCount = 0U;
	/*Wait  sub-counter  enable*/
	while ((RTCA0CEST != 1U) && (u16RTCCount < RTC_TIME_OUT_COUNT))
	{
		u16RTCCount++;
	}
}
