- /**************************************************************************//**
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=895143]@version[/url] V3.00
- * @brief
- * Show how to enter to different Power-down mode and wake-up by RTC.
- *
- * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2019 Nuvoton Technology Corp. All rights reserved.
- *
- ******************************************************************************/
- #include <stdio.h>
- #include "NuMicro.h"
- #define PDMD_FLAG_ADDR 0x20000FFC
- extern int IsDebugFifoEmpty(void);
- uint32_t g_u32PowerDownMode;
- volatile uint32_t g_u32RTCTickINT;
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] IRQ Handler for RTC Interrupt
- *
- * @param None
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] None
- *
- * [url=home.php?mod=space&uid=1543424]@Details[/url] The RTC_IRQHandler is default IRQ of RTC, declared in startup_M261.s.
- */
- void RTC_IRQHandler(void)
- {
- /* To check if RTC tick interrupt occurred */
- if(RTC_GET_TICK_INT_FLAG(RTC) == 1)
- {
- /* Clear RTC tick interrupt flag */
- RTC_CLEAR_TICK_INT_FLAG(RTC);
- }
- g_u32RTCTickINT++;
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Function for RTC wake-up source setting */
- /*---------------------------------------------------------------------------------------------------------*/
- void RTC_Init(void)
- {
- S_RTC_TIME_DATA_T sWriteRTC;
- /* Init RTC in the start of sample code */
- if(RTC->INIT != RTC_INIT_ACTIVE_Msk)
- {
- printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);
- printf("+------------------------------------------+\n");
- printf("| Power-down and Wake-up Sample Code |\n");
- printf("+------------------------------------------+\n\n");
- /* Open RTC */
- sWriteRTC.u32Year = 2017;
- sWriteRTC.u32Month = 3;
- sWriteRTC.u32Day = 16;
- sWriteRTC.u32DayOfWeek = RTC_MONDAY;
- sWriteRTC.u32Hour = 0;
- sWriteRTC.u32Minute = 0;
- sWriteRTC.u32Second = 0;
- sWriteRTC.u32TimeScale = RTC_CLOCK_24;
- RTC_Open(&sWriteRTC);
- printf("# Set RTC current date/time: 2017/03/16 00:00:00.\n");
- /* It is the start of sample code */
- M32(PDMD_FLAG_ADDR) = 0;
- }
- /* Clear RTC tick interrupt flag */
- RTC_CLEAR_TICK_INT_FLAG(RTC);
- /* Enable RTC NVIC */
- NVIC_EnableIRQ(RTC_IRQn);
- /* Enable RTC tick interrupt and wake-up function will be enabled also */
- RTC_EnableInt(RTC_INTEN_TICKIEN_Msk);
- RTC_SetTickPeriod(RTC_TICK_1_SEC);
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Enable RTC wake-up from SPD and DPD */
- CLK_ENABLE_RTCWK();
- /* Lock protected registers */
- SYS_LockReg();
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Function for System Entry to Power Down Mode */
- /*---------------------------------------------------------------------------------------------------------*/
- void PowerDownFunction(void)
- {
- /* Select Power-down mode */
- CLK_SetPowerDownMode(g_u32PowerDownMode);
- /* To check if all the debug messages are finished */
- while(IsDebugFifoEmpty() == 0);
- /* Enter to Power-down mode */
- CLK_PowerDown();
- }
- /*-----------------------------------------------------------------------------------------------------------*/
- /* Function for Check Power Manager Status */
- /*-----------------------------------------------------------------------------------------------------------*/
- void CheckPowerSource(void)
- {
- S_RTC_TIME_DATA_T sReadRTC;
- /* Get Power Manager Status */
- uint32_t u32Status = CLK_GetPMUWKSrc();
- /* Clear wake-up status flag */
- CLK->PMUSTS = CLK_PMUSTS_CLRWK_Msk;
- /* Check Power Manager Status is wake-up by RTC */
- if(u32Status & CLK_PMUSTS_RTCWK_Msk)
- {
- g_u32PowerDownMode = M32(PDMD_FLAG_ADDR);
- switch(g_u32PowerDownMode)
- {
- case CLK_PMUCTL_PDMSEL_PD:
- /* It is the start of sample code by pressing reset button */
- printf("\n\nCPU @ %dHz\n", SystemCoreClock);
- printf("+------------------------------------------+\n");
- printf("| Power-down and Wake-up Sample Code |\n");
- printf("+------------------------------------------+\n");
- break;
- case CLK_PMUCTL_PDMSEL_SPD:
- /* Wake-up from Standby Power-down Mode */
- printf("Wake-up!\n");
- /* Read current RTC date/time */
- RTC_GetDateAndTime(&sReadRTC);
- printf("# Get RTC current date/time: %d/%02d/%02d %02d:%02d:%02d.\n",
- sReadRTC.u32Year, sReadRTC.u32Month, sReadRTC.u32Day, sReadRTC.u32Hour, sReadRTC.u32Minute, sReadRTC.u32Second);
- /* Next Power-down Mode is Deep Power-down Mode */
- M32(PDMD_FLAG_ADDR) = CLK_PMUCTL_PDMSEL_DPD;
- break;
- default:
- /* Wake-up from Deep Power-down Mode */
- printf("Wake-up!\n");
- /* Read current RTC date/time */
- RTC_GetDateAndTime(&sReadRTC);
- printf("# Get RTC current date/time: %d/%02d/%02d %02d:%02d:%02d.\n",
- sReadRTC.u32Year, sReadRTC.u32Month, sReadRTC.u32Day, sReadRTC.u32Hour, sReadRTC.u32Minute, sReadRTC.u32Second);
- /* End of sample code and clear Power-down Mode flag */
- printf("\nSample code end. Press Reset Button and continue.\n");
- M32(PDMD_FLAG_ADDR) = 0;
- while(1);
- }
- }
- }
- void SYS_Init(void)
- {
- /* Set PF multi-function pins for XT1_OUT(PF.2) and XT1_IN(PF.3) */
- SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF2MFP_Msk)) | SYS_GPF_MFPL_PF2MFP_XT1_OUT;
- SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF3MFP_Msk)) | SYS_GPF_MFPL_PF3MFP_XT1_IN;
- /* Set PF multi-function pins for X32_OUT(PF.4) and X32_IN(PF.5) */
- SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF4MFP_Msk)) | SYS_GPF_MFPL_PF4MFP_X32_OUT;
- SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF5MFP_Msk)) | SYS_GPF_MFPL_PF5MFP_X32_IN;
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init System Clock */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Enable HIRC, HXT and LXT clock */
- CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk | CLK_PWRCTL_HXTEN_Msk | CLK_PWRCTL_LXTEN_Msk);
- /* Wait for HIRC, HXT and LXT clock ready */
- CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk | CLK_STATUS_LXTSTB_Msk | CLK_STATUS_HXTSTB_Msk);
- /* Enable PLL */
- CLK->PLLCTL = CLK_PLLCTL_128MHz_HIRC;
- /* Wait for PLL stable */
- CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
- /* Select HCLK clock source as PLL and HCLK source divider as 2 */
- CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(2));
- /* Enable UART module clock */
- CLK_EnableModuleClock(UART0_MODULE);
- /* Select UART module clock source as HXT and UART module clock divider as 1 */
- CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
- /* Enable peripheral clock */
- CLK_EnableModuleClock(RTC_MODULE);
- /* Update System Core Clock */
- /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
- SystemCoreClockUpdate();
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Set multi-function pins for UART0 RXD and TXD */
- SYS->GPB_MFPH = (SYS->GPB_MFPH & (~(UART0_RXD_PB12_Msk | UART0_TXD_PB13_Msk))) | UART0_RXD_PB12 | UART0_TXD_PB13;
- /* Set PC multi-function pins for CLKO(PC.13) */
- SYS->GPC_MFPH = (SYS->GPC_MFPH & (~SYS_GPC_MFPH_PC13MFP_Msk)) | SYS_GPC_MFPH_PC13MFP_CLKO;
- }
- void UART0_Init()
- {
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init UART */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Reset UART0 */
- SYS_ResetModule(UART0_RST);
- /* Configure UART0 and set UART0 baud rate */
- UART_Open(UART0, 115200);
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Main Function */
- /*---------------------------------------------------------------------------------------------------------*/
- int32_t main(void)
- {
- S_RTC_TIME_DATA_T sReadRTC;
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Init System, peripheral clock and multi-function I/O */
- SYS_Init();
-
- /* Release I/O hold status */
- CLK->IOPDCTL = 1;
- /* Lock protected registers */
- SYS_LockReg();
- /* Init UART0 for printf */
- UART0_Init();
- /* Enable Clock Output function, output clock is stopped in Power-down mode */
- CLK_EnableCKO(CLK_CLKSEL1_CLKOSEL_HCLK, 3, 0);
- /* Get power manager wake up source */
- CheckPowerSource();
- /* RTC wake-up source setting */
- RTC_Init();
- /*
- This sample code will enter to different Power-down mode and wake-up by RTC:
- 1. Normal Power-down mode (PD).
- 2. Low Leakage Power-down mode (LLPD).
- 3. Fast Wake-up Power-down mode (FWPD).
- 4. Ultra Low Leakage Power-down mode (ULLPD).
- 5. Standby Power-down mode (SPD).
- 6. Deep Power-down mode (DPD).
- */
- while(1)
- {
- /* Select Power-down mode */
- g_u32PowerDownMode = M32(PDMD_FLAG_ADDR);
- switch(g_u32PowerDownMode)
- {
- case CLK_PMUCTL_PDMSEL_PD:
- printf("\nSystem enter to PD power-down mode ... ");
- break;
- case CLK_PMUCTL_PDMSEL_LLPD:
- printf("\nSystem enter to LLPD power-down mode ... ");
- break;
- case CLK_PMUCTL_PDMSEL_FWPD:
- printf("\nSystem enter to FWPD power-down mode ... ");
- break;
- case CLK_PMUCTL_PDMSEL_ULLPD:
- printf("\nSystem enter to ULLPD power-down mode ... ");
- break;
- case CLK_PMUCTL_PDMSEL_SPD:
- printf("\nSystem enter to SPD power-down mode ... ");
- break;
- case CLK_PMUCTL_PDMSEL_DPD:
- printf("\nSystem enter to DPD power-down mode ... ");
- break;
- default:
- printf("\nInit sample code. Press Reset Button and continue.\n");
- M32(PDMD_FLAG_ADDR) = 0;
- while(1);
- break;
- }
- /* Unlock protected registers before setting Power-down mode */
- SYS_UnlockReg();
- /* Enter to Power-down mode */
- PowerDownFunction();
- while(g_u32RTCTickINT == 0);
- printf("Wake-up!\n");
- /* Read current RTC date/time after wake-up */
- RTC_GetDateAndTime(&sReadRTC);
- printf("# Get RTC current date/time: %d/%02d/%02d %02d:%02d:%02d.\n",
- sReadRTC.u32Year, sReadRTC.u32Month, sReadRTC.u32Day, sReadRTC.u32Hour, sReadRTC.u32Minute, sReadRTC.u32Second);
- /* Select next Power-down mode */
- switch(g_u32PowerDownMode)
- {
- case CLK_PMUCTL_PDMSEL_PD:
- M32(PDMD_FLAG_ADDR) = CLK_PMUCTL_PDMSEL_LLPD;
- break;
- case CLK_PMUCTL_PDMSEL_LLPD:
- M32(PDMD_FLAG_ADDR) = CLK_PMUCTL_PDMSEL_FWPD;
- break;
- case CLK_PMUCTL_PDMSEL_FWPD:
- M32(PDMD_FLAG_ADDR) = CLK_PMUCTL_PDMSEL_ULLPD;
- break;
- case CLK_PMUCTL_PDMSEL_ULLPD:
- M32(PDMD_FLAG_ADDR) = CLK_PMUCTL_PDMSEL_SPD;
- break;
- default:
- printf("\nPress Reset Button and continue.\n");
- M32(PDMD_FLAG_ADDR) = 0;
- while(1);
- break;
- }
- }
- }
- /*** (C) COPYRIGHT 2019 Nuvoton Technology Corp. ***/
|