/*******************************************************************************
* @Copyright (c)    :(C)2020, Qingdao ieslab Co., Ltd
* @FileName         :hc32_rtcc_driver.c
* @Author           :Kv-L
* @Version          :V1.0
* @Date             :2020-07-01 15:30:52
* @Description      :the function of the entity of GP22Gas_rtcc_driver.c
*******************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif

/* Includes ------------------------------------------------------------------*/
#include "UWater_timer1uS_driver.h"
#include "UWater_rtcc_driver.h"
#include "UWater_DataTools_App.h"
#include "UWater_frame_app.h"
#include "soe.h"

/* Private variables ---------------------------------------------------------*/
//static u8 s_Rtcc_AlarmA_Count = 0;
//static u16 s_Rtcc_AlarmA_Cycle = 0;
//static u16 s_Rtcc_AlarmA_Bits = 0;
//static u8 s_Rtcc_AlarmA_MASK = 0;
//static u8 s_Rtcc_AlarmA_Reload = FALSE;
//static u16 s_Rtcc_AlarmA_Set = 0;
//static u8 s_Rtcc_AlarmA_Limit_Flg = FALSE;

static u8 s_Rtcc_Alarm_Msg_cnt =0;
static u8 s_Rtcc_Alarm_Minite =0;
static Time PT;
static u8 s_Rtcc_Alarm_Msg = 0;   //Alarm msg :bit0: s msg    bit1: min msg   bit2:period msg   bit0:rtc timer msg
//static u32 s_Rtcc_Alarm_Tr = 0;   //Alarm TR
//static u32 s_Rtcc_Alarm_Dr = 0;   //Alarm DR
//static u8 s_Rtcc_WUT_Msg = FALSE; //WUT msg

static u16 s_Rtcc_Timer_Array[RTC_TIM_MAX_NUM]; //RTCC Timer
static u16 s_Rtcc_Timer_Period = 0;             //

//static u32 s_Rtcc_TickStart = 0; //timeout start time

/* Private function prototypes -----------------------------------------------*/
static u8 Rtcc_Get_Weekday(u8 year, u8 month, u8 day);
u8 Rtcc_Check_DateTime(DateTime *pDT);
//static u16 Rtcc_Get_Mask(u16 data);

static DateTime init_time_driver;
//用于定时,基本定时器使用基时2个32.768CLK
//static u32 s_rtcc_init_limit_time=0;
static u8 rtcc_clk_source=0;//0:外部低速时钟,1:内部高速时钟

/**
 *******************************************************************************
 ** \brief 系统时钟源使能
 ** \param [in]  enSource   目标时钟源
 ** \param [in]  bFlag      使能1-开/0-关
 ** \retval      Ok         设定成功
 **             其他        设定失败
 ******************************************************************************/
en_result_t RTC_ClkSourceEnable(en_sysctrl_clk_source_t enSource, boolean_t bFlag)
{
    en_result_t enRet = Ok;
    uint32_t u32Temp;

    bFlag = !!bFlag;
    M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
    M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
	M0P_SYSCTRL->SYSCTRL1_f.XTL_ALWAYS_ON = FALSE;
    M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
    M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
	M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = FALSE;
    M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
    M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
    u32Temp = M0P_SYSCTRL->PERI_CLKEN0;
	Set100msTimer(TIMER_100MS_METER_RTCCLK_MONITOR,10);//
    switch (enSource)
    {
        case SysctrlClkRCL:
            
            M0P_SYSCTRL->SYSCTRL0_f.RCL_EN = bFlag;
            while(bFlag && (1 != M0P_SYSCTRL->RCL_CR_f.STABLE))
            {
                if(0 == Check100msTimer(TIMER_100MS_METER_RTCCLK_MONITOR))
				{
					enRet = ErrorInvalidParameter;
					break;
				}
            }
            break;

        case SysctrlClkXTL:
		#if GP30_XTL//GP30提供时钟的情况
		#else
            M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
            M0P_GPIO->PCADS |= 0xC000;
		#endif
            M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = bFlag;
            while(bFlag && (1 != M0P_SYSCTRL->XTL_CR_f.STABLE))
            {
                if(0 == Check100msTimer(TIMER_100MS_METER_RTCCLK_MONITOR))
				{
					enRet = ErrorInvalidParameter;
					break;
				}
            }
            break;
        default:
            enRet = ErrorInvalidParameter;
            break;
    }
    M0P_SYSCTRL->PERI_CLKEN0 = u32Temp;
    
    return enRet;
}
/*******************************************************************************
* @fun_name     RtccInit
* @brief        RTCC初始化接口
* @param[in]    None
* @param[out]   None
* @retval       u8:0:使用外部低速时钟,1:使用内部高速时钟
* @other        None
*******************************************************************************/
u8 RtccInit(void)
{
	stc_rtc_initstruct_t RtcInitStruct;
	stc_rtc_cyccfg_t stRtcCycel;
#if GP30_XTL//GP30 提供时钟
	stc_gpio_cfg_t stcGpioCfg;
    DDL_ZERO_STRUCT(stcGpioCfg);

    stcGpioCfg.enDir = GpioDirIn;    ///< 端口方向配置->输入
    stcGpioCfg.enDrv = GpioDrvL;     ///< 端口驱动能力配置->驱动能力
    stcGpioCfg.enPu = GpioPuDisable; ///< 端口上下拉配置->无
    stcGpioCfg.enPd = GpioPdDisable;
    stcGpioCfg.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭
    stcGpioCfg.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    Gpio_Init(GpioPortC, GpioPin14, &stcGpioCfg);
//    
    /*stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置->输出
    Gpio_Init(GpioPortC, GpioPin15, &stcGpioCfg);
    Gpio_WriteOutputIO(GpioPortC,GpioPin15,FALSE); */
	/*stcGpioCfg.enPu = GpioPuEnable; ///使用时钟校准功能,需要配置为上拉输入,大13uA
    Gpio_Init(GpioPortC, GpioPin15, &stcGpioCfg);
	Gpio_WriteOutputIO(GpioPortC,GpioPin15,TRUE);*/
	Gpio_SetAnalogMode(GpioPortC, GpioPin15);//使用时钟校准功能,需要配置为上拉输入,功耗不变

    M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
    M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
    M0P_SYSCTRL->SYSCTRL1_f.EXTL_EN = TRUE;
#else
    M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = TRUE;
    M0P_GPIO->PCADS |= 0xC000;
#endif

	DDL_ZERO_STRUCT(RtcInitStruct);                     //初始值清零
	DDL_ZERO_STRUCT(stRtcCycel);
	Sysctrl_XTLDriverCfg(SysctrlXtlAmp3, SysctrlXtalDriver3);//外部低速晶振驱动配置,最大振幅，一般驱动能力
	Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384);//稳定周期设置
/*外部低速时钟失效后不切换内部低速时钟
	Sysctrl_ClkSourceEnable(SysctrlClkXTL, TRUE); //使能外部XTL时钟作为RTC时钟
	s_rtcc_init_limit_time = Timer1usGetTick();
	while(TRUE && (1 != M0P_SYSCTRL->XTL_CR_f.STABLE))
	{
	    if(Timer1usGetTick() - s_rtcc_init_limit_time > 500000)//500ms
		{
		    break;
		}
	}
	RtcInitStruct.rtcClksrc = RtcClkXtl;   //外部低速时钟RtcInitStruct.rtcCompen = RtcCompenEnable; // 使能时钟误差补偿
	Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc,TRUE);           //打开RTC时钟
*/
//外部低速时钟失效后，切换为内部低速时钟
	if(ErrorInvalidParameter == RTC_ClkSourceEnable(SysctrlClkXTL, TRUE))//使能外部XTL时钟作为RTC时钟
	{
		RTC_ClkSourceEnable(SysctrlClkRCL, TRUE);
		RtcInitStruct.rtcClksrc = RtcClkRcl;   //内部低速时钟
		rtcc_clk_source =1;
		SaveNewSoe(SOE_SWITCH_INTER_OSCI,SOE_REMARK_NOR);		//存SOE
	}
	else
	{
		RtcInitStruct.rtcClksrc = RtcClkXtl;   //外部低速时钟
		rtcc_clk_source =0;
	}
    Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc,TRUE);           //打开RTC时钟
	
	/*初始化*/
	//    NVIC_SetPriority(RTC_Alarm_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 2));    //Set the priority of an interrupt.
    RtcInitStruct.rtcAmpm = RtcPm;         //24小时制
    RtcInitStruct.rtcCompValue = 0;         //补偿值  根据实际情况进行补偿
    if (SUCCESS == RtccGetDateTime(&init_time_driver))
    {
        
        RtcInitStruct.rtcTime.u8Second = init_time_driver.s.second; //配置RTC时间
        RtcInitStruct.rtcTime.u8Minute = init_time_driver.s.minute;
        RtcInitStruct.rtcTime.u8Hour = init_time_driver.s.hour;
        RtcInitStruct.rtcTime.u8Day = init_time_driver.s.day;
        RtcInitStruct.rtcTime.u8DayOfWeek = init_time_driver.s.weekday;
        RtcInitStruct.rtcTime.u8Month = init_time_driver.s.month;
        RtcInitStruct.rtcTime.u8Year = init_time_driver.s.year;  
    }
    else
    {
        RtcInitStruct.rtcTime.u8Second = 0x55; //配置RTC时间
        RtcInitStruct.rtcTime.u8Minute = 0x01;
        RtcInitStruct.rtcTime.u8Hour = 0x10;
        RtcInitStruct.rtcTime.u8Day = 0x01;
        RtcInitStruct.rtcTime.u8DayOfWeek = 0x03;
        RtcInitStruct.rtcTime.u8Month = 0x05;
        RtcInitStruct.rtcTime.u8Year = 0x23; 
    }
    Rtc_Init(&RtcInitStruct);
#if RTC_TIMER_EN
	Rtc_AlmIeCmd(TRUE); //使能闹钟中断
	Rtc_AlmEnCmd(TRUE);
#else
	Rtc_AlmIeCmd(FALSE); /* Disable interrupt */
	Rtc_AlmEnCmd(FALSE);
#endif

/*RTC 中断设置*/
#if RTC_TIMER_RPT_SEC
    stRtcCycel.rtcPrdsel = RtcPrds;
    stRtcCycel.rtcPrds = Rtc1S;
	s_Rtcc_Timer_Period = 1;
#elif RTC_TIMER_RPT_MIN
	stRtcCycel.rtcPrdsel = RtcPrds;
    stRtcCycel.rtcPrds = Rtc1Min;
	s_Rtcc_Timer_Period = 60;
#elif RTC_TIMER_RPT_HOUR
	stRtcCycel.rtcPrdsel = RtcPrds;
    stRtcCycel.rtcPrds = Rtc1H;
	s_Rtcc_Timer_Period = 3600;
#elif RTC_TIMER_RPT_DAY
	stRtcCycel.rtcPrdsel = RtcPrds;
    stRtcCycel.rtcPrds = Rtc1Day;
	s_Rtcc_Timer_Period = 65535;
#elif RTC_TIMER_RPT_WEEK //不支持周中断
//    MODIFY_REG(RTC->ALRMBR, 0x80808080, 0x40000000);
//	  s_Rtcc_Timer_Period = 65535;
#else //RTC_TIMER_RPT_MON
	stRtcCycel.rtcPrdsel = RtcPrds;
    stRtcCycel.rtcPrds = Rtc1Mon;
	s_Rtcc_Timer_Period = 65535;
#endif
    Rtc_SetCyc(&stRtcCycel);

#if RTC_TIMER_EN
		/* Configure the Alarm state: Enable Alarm */
		Rtc_Cmd(TRUE);
		/* Configure the Alarm interrupt */
		EnableNvic(RTC_IRQn, IrqLevel3, TRUE); //使能RTC中断向量
#endif
	return rtcc_clk_source;
}

/*******************************************************************************
* @fun_name     RtccSetDateTime
* @brief        设置日期时间接口
* @param[in]    DateTime
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccSetDateTime(DateTime *pDT)
{
	stc_rtc_time_t wrtietime;

	wrtietime.u8Day = pDT->s.day;
	wrtietime.u8Hour = pDT->s.hour;
	wrtietime.u8Minute = pDT->s.minute;
	wrtietime.u8Month = pDT->s.month;
	wrtietime.u8Second = pDT->s.second;
	wrtietime.u8Year = pDT->s.year;
	wrtietime.u8DayOfWeek=Rtcc_Get_Weekday(wrtietime.u8Year,wrtietime.u8Month,wrtietime.u8Day);
	Rtc_SetTime(&wrtietime);

}

/*******************************************************************************
* @fun_name     RtccGetDateTime
* @brief        获取当前日期时间接口
* @param[in]    DateTime*
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
u8 RtccGetDateTime(DateTime *pDT)
{
	stc_rtc_time_t readtime;

	Rtc_ReadDateTime(&readtime);

	pDT->s.second = readtime.u8Second;
	pDT->s.minute = readtime.u8Minute;
	pDT->s.hour = readtime.u8Hour;
	pDT->s.day = readtime.u8Day;
	pDT->s.month = readtime.u8Month;
	pDT->s.year = readtime.u8Year;
	pDT->s.weekday = readtime.u8DayOfWeek;

	return Rtcc_Check_DateTime(pDT);
}

/*******************************************************************************
* @fun_name     RtccGetDate
* @brief        获取日期接口
* @param[in]    Date*
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccGetDate(Date *pD)
{
	stc_rtc_time_t readtime;

	Rtc_ReadDateTime(&readtime);

	pD->s.day = readtime.u8Day;
	pD->s.month = readtime.u8Month;
	pD->s.year = readtime.u8Year;
	pD->s.weekday = readtime.u8DayOfWeek;
}

/*******************************************************************************
* @fun_name     RtccGetTime
* @brief        获取时间接口
* @param[in]    Time*
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccGetTime(Time *pT)
{
	stc_rtc_time_t readtime;

	Rtc_ReadDateTime(&readtime);

	pT->s.second = readtime.u8Second;
	pT->s.minute = readtime.u8Minute;
	pT->s.hour = readtime.u8Hour;
}

/*******************************************************************************
* @fun_name     RtccAdjustDateTime
* @brief        调整日期时间接口
* @param[in]    u8 adjust：0减；非0加       u32 sec :调整秒数
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccAdjustDateTime(u8 adjust, u32 sec)
{
	DateTime cdt;
	struct tm tmdt;
	struct tm *ldt;
	time_t ctt;

	RtccGetDateTime(&cdt);
	tmdt.tm_year = (cdt.s.year >> 4) * 10 + (cdt.s.year & 0x0F) + 100;
	tmdt.tm_mon = (cdt.s.month >> 4) * 10 + (cdt.s.month & 0x0F) - 1;
	tmdt.tm_mday = (cdt.s.day >> 4) * 10 + (cdt.s.day & 0x0F);
	tmdt.tm_hour = (cdt.s.hour >> 4) * 10 + (cdt.s.hour & 0x0F);
	tmdt.tm_min = (cdt.s.minute >> 4) * 10 + (cdt.s.minute & 0x0F);
	tmdt.tm_sec = (cdt.s.second >> 4) * 10 + (cdt.s.second & 0x0F);
	tmdt.tm_isdst = 0;
	ctt = mktime(&tmdt);

	if (0 == adjust) //0: 减
	{
			ctt -= sec;
	}
	else //非0：加
	{
			ctt += sec;
	}

	ldt = localtime(&ctt);

	cdt.s.year = ((*ldt).tm_year - 100) / 10 * 16 + ((*ldt).tm_year - 100) % 10;
	cdt.s.month = ((*ldt).tm_mon + 1) / 10 * 16 + ((*ldt).tm_mon + 1) % 10;
	cdt.s.day = ((*ldt).tm_mday) / 10 * 16 + ((*ldt).tm_mday) % 10;
	cdt.s.weekday = ((*ldt).tm_wday) / 10 * 16 + ((*ldt).tm_wday) % 10;
	cdt.s.hour = ((*ldt).tm_hour) / 10 * 16 + ((*ldt).tm_hour) % 10;
	cdt.s.minute = ((*ldt).tm_min) / 10 * 16 + ((*ldt).tm_min) % 10;
	cdt.s.second = ((*ldt).tm_sec) / 10 * 16 + ((*ldt).tm_sec) % 10;
	RtccSetDateTime(&cdt);
}

/*******************************************************************************
* @fun_name     RtccSetTimer
* @brief        RTCC TIM 设置定时接口
* @param[in]    u8 rtcc_timenum：申请的定时器； u16 rtcc_timespan：定时长短(s)
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccSetTimer(u8 rtcc_timenum, u16 rtcc_timespan)
{
	if (rtcc_timenum < RTC_TIM_MAX_NUM)
	{
		s_Rtcc_Timer_Array[rtcc_timenum] = rtcc_timespan;
	}
}

/*******************************************************************************
* @fun_name     RtccCheckTimer
* @brief        查询定时器接口
* @param[in]    u8 rtcc_timenum：申请的定时器
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
u16 RtccCheckTimer(u8 rtcc_timenum)
{
	if (rtcc_timenum < RTC_TIM_MAX_NUM)
	{
		return s_Rtcc_Timer_Array[rtcc_timenum];
	}
	else
	{
		return 0;
	}
}

/*******************************************************************************
* @fun_name     RtccSetAlrm
* @brief        设置闹钟接口
* @param[in]    u8 count:闹钟次数，0表示无限次；    u32 cycle：闹钟间隔(us)
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccSetAlrm(DateTime *pDT)
{
	//  u8 WeekTempValue=0;//保存是周几
	stc_rtc_alarmtime_t   rtc_alarmtime;

	rtc_alarmtime.RtcAlarmHour = pDT->s.hour;
	rtc_alarmtime.RtcAlarmMinute = pDT->s.minute;
	rtc_alarmtime.RtcAlarmSec = pDT->s.second;
	//rtc_alarmtime.RtcAlarmWeek = pDT->s.weekday;
	rtc_alarmtime.RtcAlarmWeek=0x7F; //Bit0代表周一，Bit6代表周日。0x7F代表每天的这个时候都产生中断。

	Rtc_SetAlarmTime(&rtc_alarmtime);
}

/*******************************************************************************
* @fun_name     RtccGetAlrm
* @brief        获取闹钟接口
* @param[in]    u8 count:闹钟次数，0表示无限次；    u32 cycle：闹钟间隔(us)
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccGetAlrm(DateTime *pDT)
{
	stc_rtc_alarmtime_t   rtc_alarmtime;

	Rtc_GetAlarmTime(&rtc_alarmtime);
	pDT->s.hour = rtc_alarmtime.RtcAlarmHour;
	pDT->s.minute = rtc_alarmtime.RtcAlarmMinute;
	pDT->s.second = rtc_alarmtime.RtcAlarmSec;
	pDT->s.weekday = rtc_alarmtime.RtcAlarmWeek;
}

/*******************************************************************************
* @fun_name     RtccCheckMsg
* @brief        查询闹钟msg接口
* @param[in]    None
* @param[out]   Msg：
* @retval       None
* @other        
*******************************************************************************/
u8 RtccCheckMsg(void)
{
	return s_Rtcc_Alarm_Msg;
}

/*******************************************************************************
* @fun_name     RtccClearMsg
* @brief        清msg接口
* @param[in]    u8 bit：0：清bit0；  N：清bitN  (N<8)
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccClearMsg(u8 bit)
{
    if(bit > 7)
    {
        return;
    }
    s_Rtcc_Alarm_Msg &= ~(1 << bit);
}

/*******************************************************************************
* @fun_name     RtccGetAlrmTimeAfter
* @brief        获取最近整分时间接口
* @param[in]    DateTime*
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
//void RtccGetAlrmTimeAfter(DateTime *pDT)
//{
//	pDT->s.second = (u8)((s_Rtcc_Alarm_Tr >> 0) & (u32)0x7F);
//	pDT->s.minute = (u8)((s_Rtcc_Alarm_Tr >> 8) & (u32)0x7F);
//	pDT->s.hour = (u8)((s_Rtcc_Alarm_Tr >> 16) & (u32)0x3F);

//	pDT->s.day = (u8)((s_Rtcc_Alarm_Dr >> 0) & (u32)0x3F);
//	pDT->s.month = (u8)((s_Rtcc_Alarm_Dr >> 8) & (u32)0x1F);
//	pDT->s.year = (u8)((s_Rtcc_Alarm_Dr >> 16) & (u32)0xFF);

//	pDT->s.weekday = Rtcc_Get_Weekday(pDT->s.year, pDT->s.month, pDT->s.day);
//}
/*************************************************
Function：s32 RtcccalculateDiffTime(const DateTime *newpD, const DateTime *oldpD)
Description：计算时间差
Input:newData oldData带计算的时间
Output：void
Return：newData-oldData=差值时间(单位second)
Others:
 *************************************************/
s32 RtcccalculateDiffTime(const DateTime *newpD, const DateTime *oldpD)
{
    struct tm oldTime;
    struct tm newTime;
    //将十六进制数字转换成十进制数字
    oldTime.tm_year = (oldpD->s.year >> 4)*10 + (oldpD->s.year & 0x0F) + 100; //年份基数为1900年
    oldTime.tm_mon = (oldpD->s.month >> 4)*10 + (oldpD->s.month & 0x0F) - 1; //0-11代表1-12月
    oldTime.tm_mday = (oldpD->s.day >> 4)*10 + (oldpD->s.day & 0x0F);
    oldTime.tm_hour = (oldpD->s.hour >> 4)*10 + (oldpD->s.hour & 0x0F);
    oldTime.tm_min = (oldpD->s.minute >> 4)*10 + (oldpD->s.minute & 0x0F);
    oldTime.tm_sec = (oldpD->s.second >> 4)*10 + (oldpD->s.second & 0x0F);
    newTime.tm_year = (newpD->s.year >> 4)*10 + (newpD->s.year & 0x0F) + 100; //年份基数为1900年
    newTime.tm_mon = (newpD->s.month >> 4)*10 + (newpD->s.month & 0x0F) - 1; //0-11代表1-12月
    newTime.tm_mday = (newpD->s.day >> 4)*10 + (newpD->s.day & 0x0F);
    newTime.tm_hour = (newpD->s.hour >> 4)*10 + (newpD->s.hour & 0x0F);
    newTime.tm_min = (newpD->s.minute >> 4)*10 + (newpD->s.minute & 0x0F);
    newTime.tm_sec = (newpD->s.second >> 4)*10 + (newpD->s.second & 0x0F);
    //将当前时间转换成从1970开始的秒数
    long t1 = mktime(&newTime);
    long t2 = mktime(&oldTime);
    return difftime(t1, t2);
}




/*******************************************************************************
* @fun_name     RtccIfSleep
* @brief        查询RTCC是否允许休眠
* @param[in]    None
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
u8 RtccIfSleep(void)
{
	return TRUE;
}

/*******************************************************************************
* @fun_name     RtccPreSleep
* @brief        休眠前处理
* @param[in]    None
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccPreSleep(void)
{
	
}
//掉电后关闭RTC闹钟
void RtccPrePowerDown(void)
{
	Rtc_AlmEnCmd(FALSE);      //闹钟禁止
}
/*******************************************************************************
* @fun_name     RtccWakeSleep
* @brief        唤醒后处理
* @param[in]    None
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void RtccWakeSleep(void)
{
	;
}

/*******************************************************************************
* @fun_name     Rtcc_Get_Weekday
* @brief        计算周几函数
* @param[in]    None
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
static u8 Rtcc_Get_Weekday(u8 year, u8 month, u8 day)
{
	struct tm tm_datetime;
	tm_datetime.tm_year = (year >> 4) * 10 + (year & 0x0F) + 100;
	tm_datetime.tm_mon = (month >> 4) * 10 + (month & 0x0F) - 1;
	tm_datetime.tm_mday = (day >> 4) * 10 + (day & 0x0F);
	tm_datetime.tm_hour = 0;
	tm_datetime.tm_min = 0;
	tm_datetime.tm_sec = 0;
	tm_datetime.tm_isdst = 0;
	mktime(&tm_datetime);
	return tm_datetime.tm_wday;
}

/*******************************************************************************
* @fun_name     Rtcc_Check_DateTime
* @brief        检查日期合法性
* @param[in]    None
* @param[out]   SUCCESS：合法； ERROR：非法
* @retval       None
* @other        None
*******************************************************************************/
u8 Rtcc_Check_DateTime(DateTime *pDT)
{
	int i = 0;
	for (i = 0; i < 7; i++)
	{
		if ((pDT->b[i] >> 4) > 9 || (pDT->b[i] & 0x0F) > 9)
		{
			if(i != 3)//不判断week
			{
				return ERROR;
			}
		}
	}
	if ((0 == pDT->s.month) || (pDT->s.month > 0x12))
	{
		return ERROR;
	}
	if ((0 == pDT->s.day) || (pDT->s.day > 0x31))
	{
		return ERROR;
	}
	if (pDT->s.hour > 0x23)
	{
		return ERROR;
	}
	if (pDT->s.minute > 0x59)
	{
		return ERROR;
	}
	if (pDT->s.second > 0x59)
	{
		return ERROR;
	}

	if (pDT->s.month == 0x4 || pDT->s.month == 0x6 || pDT->s.month == 0x9 || pDT->s.month == 0x11)
	{
		if (pDT->s.day > 0x30)
		{
			return ERROR;
		}
	}

	if (pDT->s.month == 0x2)
	{
		if (((0 == (pDT->s.year) % 4) && (0 != (pDT->s.year) % 100)) || (0 == (pDT->s.year) % 400))
		{
			if (pDT->s.day > 0x29)
			{
				return ERROR;
			}
		}
		else
		{
			if (pDT->s.day > 0x28)
			{
				return ERROR;
			}
		}
	}
	return SUCCESS;
}

/*******************************************************************************
* @fun_name     Rtcc_Get_Mask
* @brief        计算sub sec mask bit 函数
* @param[in]    None
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
/*static u16 Rtcc_Get_Mask(u16 data)
{
	u8 i = 0;
	for (i = 0; i < 15; i++)
	{
		if (data <= (1 << i))
		{
			if (data == (1 << i))
			{
				s_Rtcc_AlarmA_Reload = FALSE;
			}
			else
			{
				s_Rtcc_AlarmA_Reload = TRUE;
			}
			return ((i > 0) ? i : 1);
		}
	}
	return 14;
}*/

/*************************************************
Function：long RTCC_CalculateDiffTime(DataTime data_time)
Description：计算时间差
Input:newData oldData带计算的时间
Output：void
Return：newData-oldData=差值时间(单位second)
Others:
 *************************************************/
long RtccCalculateDiffTime(const DateTime *newpD, const DateTime *oldpD)
{
    struct tm oldTime;
    struct tm newTime;
    //将十六进制数字转换成十进制数字
    oldTime.tm_year = (oldpD->s.year >> 4)*10 + (oldpD->s.year & 0x0F) + 100; //年份基数为1900年
    oldTime.tm_mon = (oldpD->s.month >> 4)*10 + (oldpD->s.month & 0x0F) - 1; //0-11代表1-12月
    oldTime.tm_mday = (oldpD->s.day >> 4)*10 + (oldpD->s.day & 0x0F);
    oldTime.tm_hour = (oldpD->s.hour >> 4)*10 + (oldpD->s.hour & 0x0F);
    oldTime.tm_min = (oldpD->s.minute >> 4)*10 + (oldpD->s.minute & 0x0F);
    oldTime.tm_sec = (oldpD->s.second >> 4)*10 + (oldpD->s.second & 0x0F);
    newTime.tm_year = (newpD->s.year >> 4)*10 + (newpD->s.year & 0x0F) + 100; //年份基数为1900年
    newTime.tm_mon = (newpD->s.month >> 4)*10 + (newpD->s.month & 0x0F) - 1; //0-11代表1-12月
    newTime.tm_mday = (newpD->s.day >> 4)*10 + (newpD->s.day & 0x0F);
    newTime.tm_hour = (newpD->s.hour >> 4)*10 + (newpD->s.hour & 0x0F);
    newTime.tm_min = (newpD->s.minute >> 4)*10 + (newpD->s.minute & 0x0F);
    newTime.tm_sec = (newpD->s.second >> 4)*10 + (newpD->s.second & 0x0F);
    //将当前时间转换成从1970开始的秒数
    long t1 = mktime(&newTime);
    long t2 = mktime(&oldTime);
    return difftime(t1, t2);
}
time_t get_mktime (DateTime *time_GMT)//标准时间准换为绝对秒数
{
    struct tm time_GTM_temp;
    time_GTM_temp.tm_year = BCD2HEX(time_GMT->s.year) + 100;//年份基数为1900年
    time_GTM_temp.tm_mon  = BCD2HEX(time_GMT->s.month) - 1; //0-11代表1-12月
    time_GTM_temp.tm_mday = BCD2HEX(time_GMT->s.day);//
    time_GTM_temp.tm_hour = BCD2HEX(time_GMT->s.hour);//
    time_GTM_temp.tm_min  = BCD2HEX(time_GMT->s.minute);//
    time_GTM_temp.tm_sec  = BCD2HEX(time_GMT->s.second);// 
    return(mktime(&time_GTM_temp));
}

time_t get_mktime_noweek (DateTime_noweek *time_GMT)//标准时间准换为绝对秒数
{
    struct tm time_GTM_temp;
    time_GTM_temp.tm_year = BCD2HEX(time_GMT->s.year) + 100;//年份基数为1900年
    time_GTM_temp.tm_mon  = BCD2HEX(time_GMT->s.month) - 1; //0-11代表1-12月
    time_GTM_temp.tm_mday = BCD2HEX(time_GMT->s.day);//
    time_GTM_temp.tm_hour = BCD2HEX(time_GMT->s.hour);//
    time_GTM_temp.tm_min  = BCD2HEX(time_GMT->s.minute);//
    time_GTM_temp.tm_sec  = BCD2HEX(time_GMT->s.second);//
    return(mktime(&time_GTM_temp));
}
/*******************************************************************************
* @fun_name     RTC_Alarm_IRQHandler
* @brief        Alarm中断入口
* @param[in]    None
* @param[out]   None
* @retval       None
* @other        None
*******************************************************************************/
void Rtc_IRQHandler(void)
{

	if ((M0P_RTC->CR1_f.ALMF == 1) && (M0P_RTC->CR1_f.ALMEN == 1)) //RTC  闹铃
	{
		/* Clear the EXTI's line Flag for RTC Alarm */
//		s_Rtcc_Alarm_Msg = TRUE;
		M0P_RTC->CR1_f.ALMF = 0;
	}

	if (M0P_RTC->CR1_f.PRDF == 1)// && (M0P_RTC->CR0_f.PRDS != 0)) //RTC  定时
	{
		/* Clear the EXTI's line Flag for RTC Alarm */
		M0P_RTC->CR1_f.PRDF = 0;
        s_Rtcc_Alarm_Msg |= 0x04;//抛周期唤醒msg
        FrameClearMsgApp(MsgRtccAdjustTime);//清校时消息,该消息是防止检定0.5s超时复位用的
        s_Rtcc_Alarm_Msg |= 0x01;       //整秒
		s_Rtcc_Alarm_Msg |= 0x10;       //整秒,统计功耗用
        s_Rtcc_Alarm_Msg_cnt++;
        s_Rtcc_Alarm_Minite++;
        if(0 == s_Rtcc_Alarm_Msg_cnt%2)
        {
            s_Rtcc_Alarm_Msg |= 0x08;//整2秒
        }
//        RtccGetTime(&PT);
        PT.s.second = M0P_RTC->SEC;
        if((u32)0x00 ==PT.s.second)
        {
            s_Rtcc_Alarm_Minite =0;
        }
        if(0 == s_Rtcc_Alarm_Minite%60)
        {
            s_Rtcc_Alarm_Msg |= 0x02;//整分
			s_Rtcc_Alarm_Msg |= 0x20;//整分,用于待机功耗计算
        }

        for (u8 i = 0; i < RTC_TIM_MAX_NUM; i++)
        {
            if(s_Rtcc_Timer_Array[i] >= s_Rtcc_Timer_Period)
            {
                s_Rtcc_Timer_Array[i] -= s_Rtcc_Timer_Period;
            }
            else
            {
                s_Rtcc_Timer_Array[i] = 0;
            }
        }	    	
	}
}
/*******************************************************************************
* @fun_name     RTC_ClkSource
* @brief        返回rtcc时钟源:0:使用外部低速时钟,1:使用内部低速时钟
*******************************************************************************/
u8 RTC_ClkSource(void)
{
	return rtcc_clk_source;
}


#ifdef __cplusplus
}
#endif

/***************************************************************END OF FILE****/
