
/******************************************************************************
*@file  : app.c
*@brief : application
*@ver   : 1.0.0
*@date  : 2022.10.20
******************************************************************************/

#include "app.h"   


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



/******************************************************************************
* @brief : RTC function test.
* @param : mode: Different function test options
* @return: None
******************************************************************************/
void APP_RTC_Test(RTC_TestMode_TypeDef mode)
{
    uint32_t fu32_Seconds;
    uint32_t write_data, read_data;
    RTC_ConfigTypeDef RTC_Handle;
    RTC_WUTimerTypeDef  WuTimer_Handler;
    RTC_TimeTypeDef  temp_Time_Set;
    RTC_TimeTypeDef  temp_Time_Get;
    RTC_TimeTypeDef  temp_Time_Get_Again;
    RTC_DateTypeDef  temp_Date_Set;
    RTC_DateTypeDef  temp_Date_Get;
    RTC_AlarmTypeDef temp_Alarm;
    RTC_TemperTypeDef temp_Temper;
    GPIO_InitTypeDef GPIOA_PIN0_Handle;
    GPIO_InitTypeDef GPIOC_PIN13_Handle;
    
    switch (mode)
    {
        /* RTC日期时间功能 */
        case RTC_TIME_DATE_TEST: 
        {
            printfS("RTC Date&Time Test.....\r\n");
            RTC_Handle.ClockSource       = RTC_CLOCK_XTL;
            RTC_Handle.Compensation      = COMPENSATION_INCREASE;    // 开启时钟误差补偿
            RTC_Handle.CompensationValue = 0x05;                     // 开启时钟误差补偿，该参数只针对ACM32G103 LQFP64 Core板XTL电路

            HAL_RTC_Config(&RTC_Handle);

            /* Set RTC Time、Date */
            temp_Time_Set.Hour   = 0x12;
            temp_Time_Set.Minute = 0x30;
            temp_Time_Set.Second = 0x00;
            HAL_RTC_SetTime(&temp_Time_Set);

            temp_Date_Set.Year    = 0x22;    // 2022
            temp_Date_Set.Month   = RTC_MONTH_OCTOBER;
            temp_Date_Set.Date    = 0x21;
            temp_Date_Set.WeekDay = RTC_WEEKDAY_FRIDAY;
            HAL_RTC_SetDate(&temp_Date_Set);
            
            NVIC_ClearPendingIRQ(RTC_IRQn);
            NVIC_EnableIRQ(RTC_IRQn);
            __HAL_RTC_ENABLE_MIN_IT;

            while (1) 
            {
                HAL_RTC_GetTime(&temp_Time_Get);
                HAL_RTC_GetDate(&temp_Date_Get);
                HAL_RTC_GetTime(&temp_Time_Get_Again);
                if (temp_Time_Get.Second != temp_Time_Get_Again.Second) 
                {
                    continue;   
                }
                if (fu32_Seconds != temp_Time_Get.Second) 
                {
                    fu32_Seconds = temp_Time_Get.Second;
                    
                    printf("Date: 20%x-%x-%x week:%x \n", temp_Date_Get.Year, temp_Date_Get.Month, temp_Date_Get.Date, temp_Date_Get.WeekDay);
                    printf("Time: %x:%x:%x \n", temp_Time_Get.Hour, temp_Time_Get.Minute, temp_Time_Get.Second);
                }
            }
        }

        /* RTC闹钟功能 */
        case RTC_ALARM_TEST:
        {
			printfS("RTC ALARM Test.....\r\n");
            /********************************************/
            /**************** RTC Config ****************/
            /********************************************/
            RTC_Handle.ClockSource       = RTC_CLOCK_XTL;
            RTC_Handle.Compensation      = COMPENSATION_INCREASE;    // 开启时钟误差补偿
            RTC_Handle.CompensationValue = 0x05;                     // 开启时钟误差补偿，该参数只针对ACM32G103 LQFP64 Core板XTL电路

            HAL_RTC_Config(&RTC_Handle);

            /* Set RTC Time、Date */
            temp_Time_Set.Hour   = 0x12;
            temp_Time_Set.Minute = 0x30;
            temp_Time_Set.Second = 0x00;
            HAL_RTC_SetTime(&temp_Time_Set);

            temp_Date_Set.Year    = 0x22;    // 2022
            temp_Date_Set.Month   = RTC_MONTH_OCTOBER;
            temp_Date_Set.Date    = 0x21;
            temp_Date_Set.WeekDay = RTC_WEEKDAY_FRIDAY;
            HAL_RTC_SetDate(&temp_Date_Set);
			
			

            /********************************************/
            /**************** Alarm Config ****************/
            /********************************************/
            temp_Alarm.u32_AlarmMode      = RTC_ALM_ALM_WDS_WEEK;            // 使用星期模式
            temp_Alarm.u32_AlarmInterrupt = RTC_ALARM_INT_ENABLE;           // 开启闹钟中断
            temp_Alarm.u32_DayMask        = RTC_ALARM_DAY_MASK_DISABLE;     // 天  屏蔽关闭
            temp_Alarm.u32_HourMask       = RTC_ALARM_HOUR_MASK_DISABLE;    // 小时屏蔽关闭
            temp_Alarm.u32_MinMask        = RTC_ALARM_MIN_MASK_DISABLE;     // 分钟屏蔽关闭
            temp_Alarm.u32_AlarmWeek      = RTC_ALARM_WEEK_FRIDAY | RTC_ALARM_WEEK_SATURDAY;    // 周五、周六
            temp_Alarm.u32_Hours          = 0x12;    // 时间 12：30：30
            temp_Alarm.u32_Minutes        = 0x30;
            temp_Alarm.u32_Seconds        = 0x30;
            HAL_RTC_AlarmConfig(&temp_Alarm);

            NVIC_ClearPendingIRQ(RTC_IRQn);
            NVIC_EnableIRQ(RTC_IRQn);
            /* RTC domain write enable */
            SET_BIT(PMU->CTRL0,PMU_CTL0_RTC_WE);
            HAL_RTC_AlarmEnable();
            
            while (1) 
            {
                HAL_RTC_GetTime(&temp_Time_Get);
                HAL_RTC_GetDate(&temp_Date_Get);
                HAL_RTC_GetTime(&temp_Time_Get_Again);
                if (temp_Time_Get.Second != temp_Time_Get_Again.Second) 
                {
                    continue;   
                }
                if (fu32_Seconds != temp_Time_Get.Second) 
                {
                    fu32_Seconds = temp_Time_Get.Second;
                    
                    printf("Date: 20%x-%x-%x week:%x \n", temp_Date_Get.Year, temp_Date_Get.Month, temp_Date_Get.Date, temp_Date_Get.WeekDay);
                    printf("Time: %x:%x:%x \n", temp_Time_Get.Hour, temp_Time_Get.Minute, temp_Time_Get.Second);
                }
                
                while (galarmFlag) 
                {
                    printf("This is RTC Alarm!!! \r\n");
                    HAL_Delay(500);
                    galarmFlag= 0;
                }
            }
        }

        case RTC_TAMPER_TEST:
        {
            printfS("RTC Tamper Test.....\r\n");
            /********************************************/
            /**************** RTC Config ****************/
            /********************************************/
            RTC_Handle.ClockSource       = RTC_CLOCK_XTL;
            RTC_Handle.Compensation      = COMPENSATION_INCREASE;    // 开启时钟误差补偿
            RTC_Handle.CompensationValue = 0x05;                     // 开启时钟误差补偿，该参数只针对ACM32G103 LQFP64 Core板XTL电路

            HAL_RTC_Config(&RTC_Handle);
			
            /* Set RTC Time、Date */
            temp_Time_Set.Hour   = 0x12;
            temp_Time_Set.Minute = 0x30;
            temp_Time_Set.Second = 0x00;
            HAL_RTC_SetTime(&temp_Time_Set);

            temp_Date_Set.Year    = 0x22;    // 2022
            temp_Date_Set.Month   = RTC_MONTH_OCTOBER;
            temp_Date_Set.Date    = 0x21;
            temp_Date_Set.WeekDay = RTC_WEEKDAY_FRIDAY;
            HAL_RTC_SetDate(&temp_Date_Set);
            

    

            __HAL_RCC_GPIOA_CLK_ENABLE();
            __HAL_RCC_GPIOC_CLK_ENABLE();
            
            //PA0--RTC_TAMP2, PC13--RTC_TAMP1
            
            /* Initialization GPIOA0 */
            GPIOA_PIN0_Handle.Pin       = GPIO_PIN_0;   
            GPIOA_PIN0_Handle.Mode      = GPIO_MODE_INPUT;
            GPIOA_PIN0_Handle.Pull      = GPIO_PULLUP;
            GPIOA_PIN0_Handle.Drive     = GPIO_DRIVE_LEVEL3;
            HAL_GPIO_Init(GPIOA, &GPIOA_PIN0_Handle);
            
            /* Initialization GPIOC13 */
            GPIOC_PIN13_Handle.Pin       = GPIO_PIN_13;
            GPIOC_PIN13_Handle.Mode      = GPIO_MODE_INPUT;
            GPIOC_PIN13_Handle.Pull      = GPIO_PULLUP;
            GPIOC_PIN13_Handle.Drive     = GPIO_DRIVE_LEVEL3;
            HAL_GPIO_Init(GPIOC, &GPIOC_PIN13_Handle);
					
            temp_Temper.u32_TemperEdge  = RTC_TEMP_EDGE_FALLING;
            temp_Temper.u32_InterruptEN = RTC_TEMP_INT_ENABLE;
            temp_Temper.u32_ClearBackup = RTC_TEMP_CLEAR_ENABLE;
            temp_Temper.u32_FilterClk   = RTC_CR_TAMPFLTCLK_512_RTCCLK;
            temp_Temper.u32_Filter      = RTC_TEMP_FILTER_4_RTCCLK;
            HAL_RTC_Tamper(RTC_TEMPER_1, &temp_Temper);
            HAL_RTC_Tamper(RTC_TEMPER_2, &temp_Temper);
			
            //RTC备份寄存器
            PMU->CTRL0 |= PMU_CTL0_RTC_WE;//RTC模块写使能

			*((__IO uint32_t *)0x40002870) = 0;
			*((__IO uint32_t *)0x400028AC) = 0;
            
            write_data = 0x3CC35AA5;
			*((__IO uint32_t *)0x40002870) = write_data;
			*((__IO uint32_t *)0x400028AC) = write_data + 1;
			

            NVIC_ClearPendingIRQ(RTC_IRQn);
            NVIC_EnableIRQ(RTC_IRQn);

            while (1) 
            {

                HAL_RTC_GetTime(&temp_Time_Get);
                HAL_RTC_GetDate(&temp_Date_Get);
                HAL_RTC_GetTime(&temp_Time_Get_Again);
                if (temp_Time_Get.Second != temp_Time_Get_Again.Second) 
                {
                    continue;   
                }
                if (fu32_Seconds != temp_Time_Get.Second) 
                {
                    fu32_Seconds = temp_Time_Get.Second;
                    
                    printf("20%x-%x-%x week:%x  ", temp_Date_Get.Year, temp_Date_Get.Month, temp_Date_Get.Date, temp_Date_Get.WeekDay);
                    printf("%x:%x:%x\n", temp_Time_Get.Hour, temp_Time_Get.Minute, temp_Time_Get.Second);
                }
                if (gtemperFlag1) 
                {
                    gtemperFlag1 = false;
                    PMU->CTRL0 |= PMU_CTL0_RTC_WE;//RTC模块写使能
                    read_data = 0;
                    read_data = *((__IO uint32_t *)0x40002870);
                    printf("RTC_CLKSTEMP1_Date: %08x, backup = %08x\r\n", RTC->CAL_STAMP1, read_data);
                    read_data = 0;
                    read_data = *((__IO uint32_t *)0x400028AC);
					printf("RTC_CLKSTEMP1_Time: %08x, backup = %08x\r\n", RTC->CLK_STAMP1, read_data);
                    write_data = 0x3C3CC3C3;
                    *((__IO uint32_t *)0x40002870) = write_data;
                    *((__IO uint32_t *)0x400028AC) = write_data + 1;
                }
                
                if (gtemperFlag2) 
                {
                    gtemperFlag2 = false;
                    PMU->CTRL0 |= PMU_CTL0_RTC_WE;//RTC模块写使能
                    read_data = 0;
                    read_data = *((__IO uint32_t *)0x40002870);
					printf("RTC_CLKSTEMP2_Date: %08x, backup = %08x\r\n", RTC->CAL_STAMP2, read_data);
                    read_data = 0;
                    read_data = *((__IO uint32_t *)0x400028AC);
                    printf("RTC_CLKSTEMP2_Time: %08x, backup = %08x\r\n", RTC->CLK_STAMP2, read_data);
                    write_data = 0xA5A55A5A;
                    *((__IO uint32_t *)0x40002870) = write_data;
                    *((__IO uint32_t *)0x400028AC) = write_data + 1;
                    
                }
            }
        }
        
        case RTC_STANDBY_WAKEUP_TEST:
        {
            printf("MCU Standby WUTimer Test \r\n");
            
            printfS("PMU->SR=0x%08x \n",PMU->SR);
	        PMU->STCLR |= 0xFFFF;
                 
            /********************************************/
            /**************** RTC Config ****************/
            /********************************************/
            RTC_Handle.ClockSource       = RTC_CLOCK_XTL;
            RTC_Handle.Compensation      = COMPENSATION_INCREASE;    // 开启时钟误差补偿
            RTC_Handle.CompensationValue = 0x05;                     // 开启时钟误差补偿，该参数只针对ACM32G103 LQFP64 Core板XTL电路
            HAL_RTC_Config(&RTC_Handle);

            //Wakeup Timer config 
            WuTimer_Handler.u32_WuckSel      = RTC_CR_WUCKSEL_2;//1HZ  
            WuTimer_Handler.u32_InterruptEN  = ENABLE;
            WuTimer_Handler.WakeUpCounter    = 5;
            HAL_RTC_SetWakeUpTimer(&WuTimer_Handler);
            
            NVIC_ClearPendingIRQ(RTC_IRQn);
            NVIC_EnableIRQ(RTC_IRQn);
            

            printf("RTC->SR =0x%08x\n",RTC->SR);
            printf("RTC->IE =0x%08x\n",RTC->IE);
            
            HAL_Delay(5000);
            printf("MCU enter standby mode \r\n");
            __HAL_RTC_ENABLE_WUTIE_IT;
            HAL_PMU_StandbyWakeupRTCConfig(STANDBY_WAKEUP_WUTIE); 
            HAL_PMU_EnterStandbyMode();

            while(1)
            {
                printf("MCU never run here \r\n");
            }
        }
        default: break; 
    }
    
}






