
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "app.h" 


bool g32sFlag = false;
bool galarmFlag = false;
bool gtemperFlag1 = false;
bool gtemperFlag2 = false;

/******************************************************************************
* @brief : Set date and time.
* @param : None
* @return: None
******************************************************************************/
void Set_Date_Time(void)
{
    RTC_DateTypeDef  DateStruct;
    RTC_TimeTypeDef  TimeStruct;
    
    RTC_DateStructInit(&DateStruct);
    RTC_TimeStructInit(&TimeStruct);
    
    /* 日期：2024年6月28日，星期五 */
    DateStruct.Year = 24;
    DateStruct.Month = 6;
    DateStruct.Day = 28;
    DateStruct.Week = 5;
    
    /* 时间：18时9分40秒 */
    TimeStruct.Hour = 18;
    TimeStruct.Minute = 9;
    TimeStruct.Second = 00;
    
    /* 关闭RTC写保护 */
    RTC_WriteProtectionCmd(RTC_STATE_DISABLE);
    
    /* 设置日期 */
    RTC_SetDate(RTC_FORMAT_DECIMAL, &DateStruct);
    /* 设置时间 */
    RTC_SetTime(RTC_FORMAT_DECIMAL, &TimeStruct);
    
    /* 开启RTC写保护 */
    RTC_WriteProtectionCmd(RTC_STATE_ENABLE);
    
}

/******************************************************************************
* @brief : Get date and time.
* @param : None
* @return: None
******************************************************************************/
void Get_Date_Time(void)
{
    static uint32_t tmp_Seconds = 0;
    RTC_DateTypeDef  RTC_GetDateStruct;
    RTC_TimeTypeDef  RTC_GetTimeStruct;
    RTC_TimeTypeDef  RTC_GetTimeAgaginStruct;
    
    RTC_DateStructInit(&RTC_GetDateStruct);
    RTC_TimeStructInit(&RTC_GetTimeStruct);
    RTC_TimeStructInit(&RTC_GetTimeAgaginStruct);
    
    /* 获取日期与时间 */
    RTC_GetTime(RTC_FORMAT_DECIMAL, &RTC_GetTimeStruct);
    RTC_GetDate(RTC_FORMAT_DECIMAL, &RTC_GetDateStruct);
    RTC_GetTime(RTC_FORMAT_DECIMAL, &RTC_GetTimeAgaginStruct);
    
    if (RTC_GetTimeStruct.Second != RTC_GetTimeAgaginStruct.Second) 
    {
        return;   
    }
    if (tmp_Seconds != RTC_GetTimeStruct.Second) 
    {
        tmp_Seconds = RTC_GetTimeStruct.Second;
        
        printf("Date: 20%02d-%02d-%02d week:%d \n", RTC_GetDateStruct.Year, RTC_GetDateStruct.Month, \
                                                    RTC_GetDateStruct.Day, RTC_GetDateStruct.Week);
        printf("Time: %02d:%02d:%02d \n", RTC_GetTimeStruct.Hour, RTC_GetTimeStruct.Minute, \
                                            RTC_GetTimeStruct.Second);
    }
}

/******************************************************************************
* @brief : set alarm.
* @param : None
* @return: None
******************************************************************************/
void Set_Alarm(void)
{
    RTC_AlarmTypeDef AlarmStruct;
    
    RTC_AlarmStructInit(&AlarmStruct);
    
    /* 闹钟使用星期模式，星期五，18时10分10秒 */
    AlarmStruct.RTC_AlarmMode = RTC_ALARM_WEEK;
    AlarmStruct.RTC_AlarmMask = RTC_ALARM_MASK_NONE;
    AlarmStruct.RTC_AlarmDayOrWeek = 5;
    AlarmStruct.RTC_AlarmTime.Hour = 18;
    AlarmStruct.RTC_AlarmTime.Minute = 10;
    AlarmStruct.RTC_AlarmTime.Second = 10;
    
    RTC_SetAlarm(RTC_FORMAT_DECIMAL, &AlarmStruct);
    
    /* 使能闹钟 */
    RTC_AlarmCmd(RTC_STATE_ENABLE);
    
    /* 清除闹钟中断标志 */
    RTC_ClearFlag(RTC_IT_FLAG_ALM);
    /* 开启闹钟中断 */
    RTC_ITConfig(RTC_IT_FLAG_ALM, RTC_STATE_ENABLE);
}


/******************************************************************************
* @brief : set Tamper.
* @param : None
* @return: None
******************************************************************************/
void Set_Tamper(void)
{
    /* Tamper1上升沿清除备份寄存器 */
    RTC_TamperTriggerEdgeConfig(RTC_TAMPER_1, RTC_TAMPER_RISING);
    RTC_TamperFilterClockConfig(RTC_TAMPER_CLOCK_RTCCLK);
    RTC_TamperFilterPeriodConfig(RTC_TAMPER_1, RTC_TAMPER_FILTER_2);
    RTC_TamperRasingClearBackpConfig(RTC_TAMPER_1, RTC_TAMPER_CLEAR_ENABLE);
    /* 使能Tamper1 */
    RTC_TamperCmd(RTC_TAMPER_1, RTC_STATE_ENABLE);
    
    /* 清除Tamper1上升沿中断标志 */
    RTC_ClearFlag(RTC_IT_FLAG_STP1R);
    /* 开启Tamper1上升沿中断 */
    RTC_ITConfig(RTC_IT_FLAG_STP1R, RTC_STATE_ENABLE);

    
    /* Tamper2下降沿不清除备份寄存器 */
    RTC_TamperTriggerEdgeConfig(RTC_TAMPER_2, RTC_TAMPER_FALLING);
    RTC_TamperFilterClockConfig(RTC_TAMPER_CLOCK_RTCCLK);
    RTC_TamperFilterPeriodConfig(RTC_TAMPER_2, RTC_TAMPER_FILTER_4);
    RTC_TamperFallingClearBackpConfig(RTC_TAMPER_2, RTC_TAMPER_CLEAR_DISABLE);
    /* 使能Tamper2 */
    RTC_TamperCmd(RTC_TAMPER_2, RTC_STATE_ENABLE);
    
    /* 清除Tamper2下降沿中断标志 */
    RTC_ClearFlag(RTC_IT_FLAG_STP2F);
    /* 开启Tamper2下降沿中断 */
    RTC_ITConfig(RTC_IT_FLAG_STP2F, RTC_STATE_ENABLE);
}

/******************************************************************************
* @brief : set Wakep
* @param : None
* @return: None
******************************************************************************/
void Set_Wakeup(void)
{ 
    /* 清除唤醒定时器标志中断标志 */
    RTC_ClearFlag(RTC_IT_FLAG_32S);
    /* 开启唤醒定时器中断 */
    RTC_ITConfig(RTC_IT_FLAG_32S, RTC_STATE_ENABLE);
       
}

/******************************************************************************
* @brief : Enter Standby.
* @param : None
* @return: None
******************************************************************************/
void Enter_Standby(void)
{
    /* 设置Standby唤醒等待时间 */
    PMU_SetStandbyWakeWaitTime(PMU_STANDBYWAKEWAIT_4);
    
    printfS("MCU enter standby mode \r\n");  
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;   // disable systick        
    __set_PRIMASK(1);    // disable interrupt 
    SCB->ICSR = BIT25;   // clear systick pending bit
    
    PMU_EnterStandbyMode(PMU_LOWPOWRENTRY_WFI);
    
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; /* Enable SysTick IRQ */               
    __set_PRIMASK(0);    // enable interrupt 
    
    printfS("MCU never run here \r\n");
    
}

/******************************************************************************
* @brief : RTC function test.
* @param : mode: Different function test options
* @return: None
******************************************************************************/
void RTC_Test(RTC_TestMode_TypeDef mode)
{
    uint8_t i;
    RTC_DeInit();
    /* RTC初始化 */
    RTC_Init(RTC_CLOCK_XTL);
    /* 开启时钟误差补偿 */
    RTC_AdjustConfig(RTC_ADJUST_POSITIVE, 0x05);
    
    NVIC_ClearPendingIRQ(RTC_IRQn);
    NVIC_SetPriority(RTC_IRQn, 0x05);
    NVIC_EnableIRQ(RTC_IRQn);
    
    Set_Date_Time();
    
    switch (mode)
    {
        /* RTC日期时间功能 */
        case RTC_TIME_DATE_TEST: 
        {
            printfS("RTC Date&Time Test.....\r\n");
            
            /* 清除32S中断标志 */
            RTC_ClearFlag(RTC_IT_FLAG_32S);
            /* 开启32S中断 */
            RTC_ITConfig(RTC_IT_FLAG_32S, RTC_STATE_ENABLE);

            while (1) 
            {
                Get_Date_Time();
                if(g32sFlag) 
                {
                    printf("32S interrupt has been triggered!!! \r\n");
                    g32sFlag= false;
                }  
            }
        }

        /* RTC闹钟功能 */
        case RTC_ALARM_TEST:
        {
            printfS("RTC ALARM Test.....\r\n");         

            Set_Alarm();                  
 
            while (1) 
            {
                Get_Date_Time();
                
                if(galarmFlag) 
                {
                    printf("Alarm interrupt has been triggered!!! \r\n");
                    galarmFlag= false;
                }
            }
        }

        case RTC_TAMPER_TEST:
        {
            printfS("RTC Tamper Test.....\r\n");           
            
            Set_Tamper();
			
            /* RTC模块写使能 */
            RTC_WriteBackupRegister(RTC_BACKUP_0, 0x11111111);
            RTC_WriteBackupRegister(RTC_BACKUP_1, 0x22222222);
            RTC_WriteBackupRegister(RTC_BACKUP_2, 0x33333333);
            RTC_WriteBackupRegister(RTC_BACKUP_3, 0x44444444);
            RTC_WriteBackupRegister(RTC_BACKUP_4, 0x55555555);

            for(i = 0; i < 5; i++)
            {            
                printf("backup[%d] = %08x\r\n", i, RTC_ReadBackupRegister(i));
            }
            printfS("Wait for PC13 rasing, PA0 falling\r\n");
            while (1) 
            {

                Get_Date_Time();
                
                if (gtemperFlag1) 
                {
                    gtemperFlag1 = false;  
                    printf("Tamper1 interrupt has been triggered!!! \r\n");                    
                    printf("RTC CLKSTEMP1 Date: %08x, Time: %08x\r\n", RTC->CALSTAMP1_DATE, RTC->CLKSTAMP1_TIME);
                    printfS("Tamper clear backup\r\n");
                    for(i = 0; i < 5; i++)
                    {            
                        printf("backup[%d] = %08x\r\n", i, RTC_ReadBackupRegister(i));
                    }
                    System_Delay_MS(1000);
                    RTC_WriteBackupRegister(RTC_BACKUP_0, 0x11111111);
                    RTC_WriteBackupRegister(RTC_BACKUP_1, 0x22222222);
                    RTC_WriteBackupRegister(RTC_BACKUP_2, 0x33333333);
                    RTC_WriteBackupRegister(RTC_BACKUP_3, 0x44444444);
                    RTC_WriteBackupRegister(RTC_BACKUP_4, 0x55555555);
                    printfS("write backup\r\n");
                    for(i = 0; i < 5; i++)
                    {            
                        printf("backup[%d] = %08x\r\n", i, RTC_ReadBackupRegister(i));
                    }                   
                }
                
                if (gtemperFlag2) 
                {
                    gtemperFlag2 = false;
                    printf("Tamper2 interrupt has been triggered!!! \r\n"); 
                    printf("RTC CLKSTEMP2 Date: %08x, Time: %08x\r\n", RTC->CALSTAMP2_DATE, RTC->CLKSTAMP2_TIME);
                    for(i = 0; i < 5; i++)
                    {            
                        printf("backup[%d] = %08x\r\n", i, RTC_ReadBackupRegister(i));
                    }                  
                }
                
            }
        }
        
        case RTC_STANDBY_WAKEUP_TEST:
        {
            printf("RTC Wakeup Test.....\r\n");         
            
            if(SET == PMU_GetFlagStatus(PMU_FLAG_RTC))
            {
                printfS("WakeUp by RTC !!!\n");
                PMU_ClearFlag(PMU_FLAG_RTC);
            }
            
            PMU_ClearFlag(PMU_FLAG_ALL);
            
            System_Delay_MS(1500);
                      
            Set_Wakeup();
                    
            Enter_Standby(); 
 
        }
        default: 
            printfS("The application is not supported\r\n");
        break; 
    }
    
}


/******************************************************************************
* @brief : app test.
* @param : None
* @return: None
******************************************************************************/
void APP_Test(void)
{
    /*
    RTC_TIME_DATE_TEST,
    RTC_ALARM_TEST,
    RTC_TAMPER_TEST,
    RTC_STANDBY_WAKEUP_TEST,
    */
    RTC_Test(RTC_TIME_DATE_TEST);

}



