- /**************************************************************************//**
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=895143]@version[/url] V3.00
- * [url=home.php?mod=space&uid=247401]@brief[/url] Demonstrate the usage of clock fail detector and
- * clock frequency range detector function.
- *
- * SPDX-License-Identifier: Apache-2.0
- * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2018 Nuvoton Technology Corp. All rights reserved.
- ******************************************************************************/
- #include "stdio.h"
- #include "NuMicro.h"
- /*---------------------------------------------------------------------------------------------------------*/
- /* Clock Fail Detector IRQ Handler */
- /*---------------------------------------------------------------------------------------------------------*/
- void CKFAIL_IRQHandler(void)
- {
- uint32_t u32Reg;
- /* Unlock protected registers */
- SYS_UnlockReg();
- u32Reg = CLK->CLKDSTS;
- if(u32Reg & CLK_CLKDSTS_HXTFIF_Msk)
- {
- /* HCLK is switched to HIRC automatically if HXT clock fail interrupt is happened */
- printf("HXT Clock is stopped! HCLK is switched to HIRC.\n");
- /* Disable HXT clock fail interrupt */
- CLK->CLKDCTL &= ~(CLK_CLKDCTL_HXTFDEN_Msk | CLK_CLKDCTL_HXTFIEN_Msk);
- /* Write 1 to clear HXT Clock fail interrupt flag */
- CLK->CLKDSTS = CLK_CLKDSTS_HXTFIF_Msk;
- }
- if(u32Reg & CLK_CLKDSTS_LXTFIF_Msk)
- {
- /* LXT clock fail interrupt is happened */
- printf("LXT Clock is stopped!\n");
- /* Disable HXT clock fail interrupt */
- CLK->CLKDCTL &= ~(CLK_CLKDCTL_LXTFIEN_Msk | CLK_CLKDCTL_LXTFDEN_Msk);
- /* Write 1 to clear LXT Clock fail interrupt flag */
- CLK->CLKDSTS = CLK_CLKDSTS_LXTFIF_Msk;
- }
- if(u32Reg & CLK_CLKDSTS_HXTFQIF_Msk)
- {
- /* HCLK should be switched to HIRC if HXT clock frequency monitor interrupt is happened */
- CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
- printf("HXT Frequency is abnormal! HCLK is switched to HIRC.\n");
- /* Disable HXT clock frequency monitor interrupt */
- CLK->CLKDCTL &= ~(CLK_CLKDCTL_HXTFQDEN_Msk | CLK_CLKDCTL_HXTFQIEN_Msk);
- /* Write 1 to clear HXT Clock frequency monitor interrupt */
- CLK->CLKDSTS = CLK_CLKDSTS_HXTFQIF_Msk;
- }
- /* Lock protected registers */
- SYS_LockReg();
- }
- void SYS_Init(void)
- {
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
- GPIO_SetMode(PF, BIT2|BIT3, GPIO_MODE_INPUT);
- /* Set X32_OUT(PF.4) and X32_IN(PF.5) to input mode */
- GPIO_SetMode(PF, BIT4|BIT5, GPIO_MODE_INPUT);
- /* Enable HXT */
- CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
- /* Waiting for HXT clock ready */
- CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
- /* Enable HIRC */
- CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
- /* Waiting for HIRC clock ready */
- CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
- /* Enable LXT */
- CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk);
- /* Waiting for LXT clock ready */
- CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk);
- /* Switch HCLK clock source to HXT */
- CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT, CLK_CLKDIV0_HCLK(1));
- /* Enable UART module clock */
- CLK_EnableModuleClock(UART0_MODULE);
- /* Switch UART0 clock source to HIRC */
- CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));
- /* Update System Core Clock */
- /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
- SystemCoreClockUpdate();
- /*----------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*----------------------------------------------------------------------*/
- /* Set PB multi-function pins for UART0 RXD and TXD */
- /* Set PB multi-function pins for CLKO(PB.14) */
- SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk | SYS_GPB_MFPH_PB14MFP_Msk)) |
- (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD | SYS_GPB_MFPH_PB14MFP_CLKO);
- /* 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_PF5MFP_Msk)) |
- (SYS_GPF_MFPL_PF4MFP_X32_OUT | SYS_GPF_MFPL_PF5MFP_X32_IN);
- /* Lock protected registers */
- SYS_LockReg();
- }
- /*----------------------------------------------------------------------*/
- /* Init UART0 */
- /*----------------------------------------------------------------------*/
- void UART0_Init(void)
- {
- /* Reset UART0 */
- SYS_ResetModule(UART0_RST);
- /* Configure UART0 and set UART0 baud rate */
- UART_Open(UART0, 115200);
- }
- int32_t main(void)
- {
- /* Init System, IP clock and multi-function I/O. */
- SYS_Init();
- /* Init UART0 for printf */
- UART0_Init();
- printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
- printf("+-------------------------------------------------------------+\n");
- printf("| Clock Detector Sample Code |\n");
- printf("+-------------------------------------------------------------+\n");
- printf("| 1. HXT clock fail interrupt will happen if HXT is stopped. |\n");
- printf("| HCLK clock source will be switched from HXT to HIRC. |\n");
- printf("| 2. LXT clock fail interrupt will happen if LXT is stopped. |\n");
- printf("+-------------------------------------------------------------+\n");
- printf("\nStop HXT or LXT to test.\n\n");
- /* Enable clock output, select CLKO clock source as HCLK and set clock output frequency is HCLK/4.
- HCLK clock source will be switched to HIRC if HXT stop and HCLK clock source is from HXT.
- You can check if HCLK clock source is switched to HIRC by clock output pin output frequency.
- */
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Output selected clock to CKO, CKO Clock = HCLK / 2^(1 + 1) */
- CLK_EnableCKO(CLK_CLKSEL1_CLKOSEL_HCLK, 1, 0);
- /* Set the HXT clock frequency monitor upper and lower boundary value.
- The upper boundary value should be more than 1024*(HXT/HIRC).
- The low boundary value should be less than 1024*(HXT/HIRC).
- */
- /* For HXT=32MHz, HIRC=48MHz, 1024*(HXT/HIRC) = 682.6 */
- CLK->CDUPB = 687;
- CLK->CDLOWB = 677;
- /* Set clock fail detector function enabled and interrupt enabled */
- CLK->CLKDCTL = CLK_CLKDCTL_HXTFDEN_Msk |
- CLK_CLKDCTL_HXTFIEN_Msk |
- CLK_CLKDCTL_LXTFDEN_Msk |
- CLK_CLKDCTL_LXTFIEN_Msk |
- CLK_CLKDCTL_HXTFQDEN_Msk |
- CLK_CLKDCTL_HXTFQIEN_Msk;
- /* Enable clock fail detector interrupt */
- NVIC_EnableIRQ(CKFAIL_IRQn);
- /* Wait for clock fail detector interrupt happened */
- while(1);
- }
|