#include "rtc_drivers.h"
#if RTC_ENABLE
/**
 * @brief RTC初始化
 */
void RTC_Init(void)
{
	LL_RTC_InitTypeDef rtc_initstruct;
	/*	测试GPIO翻转		*/
#if (RTC_DEBUG_GPIO != NO_PIN && RTC_DEBUG)
    GPIO_Init(RTC_DEBUG_GPIO, OUTPUT | PUSHPULL);
    GPIO_ClearBit(RTC_DEBUG_GPIO);
#endif
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
    LL_PWR_EnableBkUpAccess();
	while(LL_PWR_IsEnabledBkUpAccess() == 0)
	{
		;
	}
#if RTC_CLK
    LL_RCC_LSE_Enable();
	while (LL_RCC_LSE_IsReady() != 1)
	{
		;
	}
	if (LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE)
    {
        LL_RCC_ForceBackupDomainReset();
        LL_RCC_ReleaseBackupDomainReset();
        LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
    }
	rtc_initstruct.AsynchPrescaler = LSE_VALUE * (RTC_SEC_TIME) / 1000 - 1;
#else
	MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_LSI_TRIM), (*(uint32_t *)(0x1FFF0144) & 0x1FF) << RCC_ICSCR_LSI_TRIM_Pos);
	LL_RCC_LSI_Enable();
    while (LL_RCC_LSI_IsReady() != 1)
    {
        ;
    }
    if (LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSI)
    {
        LL_RCC_ForceBackupDomainReset();
        LL_RCC_ReleaseBackupDomainReset();
        LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI);
    }
	rtc_initstruct.AsynchPrescaler = LSI_VALUE * (RTC_SEC_TIME) / 1000 - 1;
#endif
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTC);
    LL_RCC_EnableRTC();
    if (LL_RTC_DeInit(RTC) != SUCCESS)
    {
        ;
    }
    rtc_initstruct.OutPutSource = LL_RTC_CALIB_OUTPUT_NONE;
    if (LL_RTC_Init(RTC, &rtc_initstruct) != SUCCESS)
    {
        ;
    }
#if (RTC_IRQ_ENABLE)
#if RTC_SEC_IRQ_ENABLE
	/* Enable second interrupt */
    LL_RTC_EnableIT_SEC(RTC); 
#endif
#if RTC_ALR_IRQ_ENABLE
	/* Enter Initialization mode */
	LL_RTC_EnterInitMode(RTC);
	LL_RTC_ALARM_Set(RTC,RTC_ALR_TIME);
	/* Exit Initialization mode */
	LL_RTC_ExitInitMode(RTC);
	/* Enable alarm interrupt */
	LL_RTC_EnableIT_ALR(RTC);
#endif	
    /*##- Configure RTC NVIC */
    NVIC_SetPriority(RTC_IRQn, RTC_IRQ_PRIORITY);
    NVIC_EnableIRQ(RTC_IRQn);
	/* Enable RTC EXTI interrupt */
    LL_EXTI_EnableIT(LL_EXTI_LINE_19);
#endif
}
/********************************************************
**	函数名	void RTC_SecCallback(void)
**	描述	RTC秒中断中断回调函数
**	传入	：无
**	返回	：无
*********************************************************/
__weak void RTC_SecCallback(void)
{
	
}
/********************************************************
**	函数名	void RTC_AlmCallback(void)
**	描述	RTC闹钟中断中断回调函数
**	传入	：无
**	返回	：无
*********************************************************/
__weak void RTC_AlrCallback(void)
{
	
}
/**
 * @brief RTC中断
 */
void RTC_IRQHandler(void)
{
    if (LL_RTC_IsActiveFlag_SEC(RTC) != 0)
    {
        /* Clear sec flag */
        LL_RTC_ClearFlag_SEC(RTC);
#if RTC_SEC_IRQ_ENABLE
#if (RTC_DEBUG_GPIO != NO_PIN && RTC_DEBUG)
		GPIO_ToggleBit(RTC_DEBUG_GPIO);
#endif
		RTC_SecCallback();
#endif
    }
	if (LL_RTC_IsActiveFlag_ALR(RTC) != 0)
	{
		/* Clear alarm flag */
		LL_RTC_ClearFlag_ALR(RTC);
#if RTC_ALR_IRQ_ENABLE		
		volatile uint32_t RTC_CNT;
		RTC_CNT = LL_RTC_TIME_Get(RTC);
		RTC_CNT += RTC_ALR_TIME;
		/*	等待上一次RTC操作完成	*/
		while(LL_RTC_IsActiveFlag_RTOF(RTC) == 0);
		/* Disable the write protection for RTC registers */
		LL_RTC_DisableWriteProtection(RTC);
		LL_RTC_ALARM_Set(RTC,RTC_CNT);
		/* Disable initialization mode */
		LL_RTC_EnableWriteProtection(RTC);
		/*	等待上一次RTC操作完成	*/
		while(LL_RTC_IsActiveFlag_RTOF(RTC) == 0);
		RTC_AlrCallback();
#endif
	}

}
#endif
