| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751 |
- /**************************************************************************//**
- * @file clk.c
- * @version V3.00
- * $Revision: 35 $
- * $Date: 15/08/11 10:26a $
- * @brief M451 series CLK driver source file
- *
- * @note
- * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
- *****************************************************************************/
- #include "M451Series.h"
- /** @addtogroup Standard_Driver Standard Driver
- @{
- */
- /** @addtogroup CLK_Driver CLK Driver
- @{
- */
- /** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
- @{
- */
- /**
- * @brief Disable clock divider output function
- * @param None
- * @return None
- * @details This function disable clock divider output function.
- */
- void CLK_DisableCKO(void)
- {
- /* Disable CKO clock source */
- CLK_DisableModuleClock(CLKO_MODULE);
- }
- /**
- * @brief This function enable clock divider output module clock,
- * enable clock divider output function and set frequency selection.
- * @param[in] u32ClkSrc is frequency divider function clock source. Including :
- * - \ref CLK_CLKSEL1_CLKOSEL_HXT
- * - \ref CLK_CLKSEL1_CLKOSEL_LXT
- * - \ref CLK_CLKSEL1_CLKOSEL_HCLK
- * - \ref CLK_CLKSEL1_CLKOSEL_HIRC
- * @param[in] u32ClkDiv is divider output frequency selection. It could be 0~15.
- * @param[in] u32ClkDivBy1En is clock divided by one enabled.
- * @return None
- * @details Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv. \n
- * The formula is: \n
- * CKO frequency = (Clock source frequency) / 2^(u32ClkDiv + 1) \n
- * This function is just used to set CKO clock.
- * User must enable I/O for CKO clock output pin by themselves. \n
- */
- void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
- {
- /* CKO = clock source / 2^(u32ClkDiv + 1) */
- CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | u32ClkDiv | (u32ClkDivBy1En << CLK_CLKOCTL_DIV1EN_Pos);
- /* Enable CKO clock source */
- CLK_EnableModuleClock(CLKO_MODULE);
- /* Select CKO clock source */
- CLK_SetModuleClock(CLKO_MODULE, u32ClkSrc, 0);
- }
- /**
- * @brief Enter to Power-down mode
- * @param None
- * @return None
- * @details This function is used to let system enter to Power-down mode. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_PowerDown(void)
- {
- /* Set the processor uses deep sleep as its low power mode */
- SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
- /* Set system Power-down enabled and Power-down entry condition */
- CLK->PWRCTL |= (CLK_PWRCTL_PDEN_Msk | CLK_PWRCTL_PDWTCPU_Msk);
- /* Chip enter Power-down mode after CPU run WFI instruction */
- __WFI();
- }
- /**
- * @brief Enter to Idle mode
- * @param None
- * @return None
- * @details This function let system enter to Idle mode. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_Idle(void)
- {
- /* Set the processor uses sleep as its low power mode */
- SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
- /* Set chip in idle mode because of WFI command */
- CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk;
- /* Chip enter idle mode after CPU run WFI instruction */
- __WFI();
- }
- /**
- * @brief Get external high speed crystal clock frequency
- * @param None
- * @return External high frequency crystal frequency
- * @details This function get external high frequency crystal frequency. The frequency unit is Hz.
- */
- uint32_t CLK_GetHXTFreq(void)
- {
- if(CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk)
- return __HXT;
- else
- return 0;
- }
- /**
- * @brief Get external low speed crystal clock frequency
- * @param None
- * @return External low speed crystal clock frequency
- * @details This function get external low frequency crystal frequency. The frequency unit is Hz.
- */
- uint32_t CLK_GetLXTFreq(void)
- {
- if(CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk)
- return __LXT;
- else
- return 0;
- }
- /**
- * @brief Get PCLK0 frequency
- * @param None
- * @return PCLK0 frequency
- * @details This function get PCLK0 frequency. The frequency unit is Hz.
- */
- uint32_t CLK_GetPCLK0Freq(void)
- {
- SystemCoreClockUpdate();
- if(CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk)
- return SystemCoreClock / 2;
- else
- return SystemCoreClock;
- }
- /**
- * @brief Get PCLK1 frequency
- * @param None
- * @return PCLK1 frequency
- * @details This function get PCLK1 frequency. The frequency unit is Hz.
- */
- uint32_t CLK_GetPCLK1Freq(void)
- {
- SystemCoreClockUpdate();
- if(CLK->CLKSEL0 & CLK_CLKSEL0_PCLK1SEL_Msk)
- return SystemCoreClock / 2;
- else
- return SystemCoreClock;
- }
- /**
- * @brief Get HCLK frequency
- * @param None
- * @return HCLK frequency
- * @details This function get HCLK frequency. The frequency unit is Hz.
- */
- uint32_t CLK_GetHCLKFreq(void)
- {
- SystemCoreClockUpdate();
- return SystemCoreClock;
- }
- /**
- * @brief Get CPU frequency
- * @param None
- * @return CPU frequency
- * @details This function get CPU frequency. The frequency unit is Hz.
- */
- uint32_t CLK_GetCPUFreq(void)
- {
- SystemCoreClockUpdate();
- return SystemCoreClock;
- }
- /**
- * @brief Set HCLK frequency
- * @param[in] u32Hclk is HCLK frequency. The range of u32Hclk is 25 MHz ~ 72 MHz.
- * @return HCLK frequency
- * @details This function is used to set HCLK frequency. The frequency unit is Hz. \n
- * It would configure PLL frequency to 50MHz ~ 144MHz,
- * set HCLK clock divider as 2 and switch HCLK clock source to PLL. \n
- * The register write-protection function should be disabled before using this function.
- */
- uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
- {
- uint32_t u32HIRCSTB;
- /* Read HIRC clock source stable flag */
- u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
- /* The range of u32Hclk is 25 MHz ~ 72 MHz */
- if(u32Hclk > FREQ_72MHZ)
- u32Hclk = FREQ_72MHZ;
- if(u32Hclk < FREQ_25MHZ)
- u32Hclk = FREQ_25MHZ;
- /* Switch HCLK clock source to HIRC clock for safe */
- CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
- CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
- CLK->CLKSEL0 |= CLK_CLKSEL0_HCLKSEL_Msk;
- CLK->CLKDIV0 &= (~CLK_CLKDIV0_HCLKDIV_Msk);
- /* Configure PLL setting if HXT clock is enabled */
- if(CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk)
- u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, (u32Hclk << 1));
- /* Configure PLL setting if HXT clock is not enabled */
- else
- {
- u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HIRC, (u32Hclk << 1));
- /* Read HIRC clock source stable flag */
- u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
- }
- /* Select HCLK clock source to PLL,
- Select HCLK clock source divider as 2
- and update system core clock
- */
- CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(2));
- /* Disable HIRC if HIRC is disabled before setting core clock */
- if(u32HIRCSTB == 0)
- CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
- /* Return actually HCLK frequency is PLL frequency divide 2 */
- return u32Hclk >> 1;
- }
- /**
- * @brief This function set HCLK clock source and HCLK clock divider
- * @param[in] u32ClkSrc is HCLK clock source. Including :
- * - \ref CLK_CLKSEL0_HCLKSEL_HXT
- * - \ref CLK_CLKSEL0_HCLKSEL_LXT
- * - \ref CLK_CLKSEL0_HCLKSEL_PLL
- * - \ref CLK_CLKSEL0_HCLKSEL_LIRC
- * - \ref CLK_CLKSEL0_HCLKSEL_HIRC
- * @param[in] u32ClkDiv is HCLK clock divider. Including :
- * - \ref CLK_CLKDIV0_HCLK(x)
- * @return None
- * @details This function set HCLK clock source and HCLK clock divider. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
- {
- uint32_t u32HIRCSTB;
- /* Read HIRC clock source stable flag */
- u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
- /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
- CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
- CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
- CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC;
- /* Apply new Divider */
- CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | u32ClkDiv;
- /* Switch HCLK to new HCLK source */
- CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | u32ClkSrc;
- /* Update System Core Clock */
- SystemCoreClockUpdate();
- /* Disable HIRC if HIRC is disabled before switching HCLK source */
- if(u32HIRCSTB == 0)
- CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
- }
- /**
- * @brief This function set selected module clock source and module clock divider
- * @param[in] u32ModuleIdx is module index.
- * @param[in] u32ClkSrc is module clock source.
- * @param[in] u32ClkDiv is module clock divider.
- * @return None
- * @details Valid parameter combinations listed in following table:
- *
- * |Module index |Clock source |Divider |
- * | :---------------- | :----------------------------------- | :---------------------- |
- * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_LXT | x |
- * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_PCLK0_DIV2048 | x |
- * |\ref WDT_MODULE |\ref CLK_CLKSEL1_WDTSEL_LIRC | x |
- * |\ref RTC_MODULE |\ref CLK_CLKSEL3_RTCSEL_LXT | x |
- * |\ref RTC_MODULE |\ref CLK_CLKSEL3_RTCSEL_LIRC | x |
- * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_HXT | x |
- * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_LXT | x |
- * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_PCLK0 | x |
- * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_EXT_TRG | x |
- * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_LIRC | x |
- * |\ref TMR0_MODULE |\ref CLK_CLKSEL1_TMR0SEL_HIRC | x |
- * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_HXT | x |
- * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_LXT | x |
- * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_PCLK0 | x |
- * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_EXT_TRG | x |
- * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_LIRC | x |
- * |\ref TMR1_MODULE |\ref CLK_CLKSEL1_TMR1SEL_HIRC | x |
- * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_HXT | x |
- * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_LXT | x |
- * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_PCLK1 | x |
- * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_EXT_TRG | x |
- * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_LIRC | x |
- * |\ref TMR2_MODULE |\ref CLK_CLKSEL1_TMR2SEL_HIRC | x |
- * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_HXT | x |
- * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_LXT | x |
- * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_PCLK1 | x |
- * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_EXT_TRG | x |
- * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_LIRC | x |
- * |\ref TMR3_MODULE |\ref CLK_CLKSEL1_TMR3SEL_HIRC | x |
- * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HXT | x |
- * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_LXT | x |
- * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HCLK | x |
- * |\ref CLKO_MODULE |\ref CLK_CLKSEL1_CLKOSEL_HIRC | x |
- * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_HXT | x |
- * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_PLL | x |
- * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_PCLK0 | x |
- * |\ref SPI0_MODULE |\ref CLK_CLKSEL2_SPI0SEL_HIRC | x |
- * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_HXT | x |
- * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_PLL | x |
- * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_PCLK1 | x |
- * |\ref SPI1_MODULE |\ref CLK_CLKSEL2_SPI1SEL_HIRC | x |
- * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_HXT | x |
- * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_PLL | x |
- * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_PCLK0 | x |
- * |\ref SPI2_MODULE |\ref CLK_CLKSEL2_SPI2SEL_HIRC | x |
- * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART0_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART1_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART2_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_HXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_LXT |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_PLL |\ref CLK_CLKDIV0_UART(x) |
- * |\ref UART3_MODULE |\ref CLK_CLKSEL1_UARTSEL_HIRC |\ref CLK_CLKDIV0_UART(x) |
- * |\ref USBH_MODULE | x |\ref CLK_CLKDIV0_USB(x) |
- * |\ref USBD_MODULE | x |\ref CLK_CLKDIV0_USB(x) |
- * |\ref OTG_MODULE | x |\ref CLK_CLKDIV0_USB(x) |
- * |\ref EADC_MODULE | x |\ref CLK_CLKDIV0_EADC(x) |
- * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_HXT |\ref CLK_CLKDIV1_SC0(x) |
- * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PLL |\ref CLK_CLKDIV1_SC0(x) |
- * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_PCLK0 |\ref CLK_CLKDIV1_SC0(x) |
- * |\ref SC0_MODULE |\ref CLK_CLKSEL3_SC0SEL_HIRC |\ref CLK_CLKDIV1_SC0(x) |
- * |\ref PWM0_MODULE |\ref CLK_CLKSEL2_PWM0SEL_PLL | x |
- * |\ref PWM0_MODULE |\ref CLK_CLKSEL2_PWM0SEL_PCLK0 | x |
- * |\ref PWM1_MODULE |\ref CLK_CLKSEL2_PWM1SEL_PLL | x |
- * |\ref PWM1_MODULE |\ref CLK_CLKSEL2_PWM1SEL_PCLK1 | x |
- * |\ref WWDT_MODULE |\ref CLK_CLKSEL1_WWDTSEL_PCLK0_DIV2048 | x |
- * |\ref WWDT_MODULE |\ref CLK_CLKSEL1_WWDTSEL_LIRC | x |
- */
- void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
- {
- uint32_t u32sel = 0, u32div = 0;
- if(MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk)
- {
- /* Get clock divider control register address */
- u32div = (uint32_t)&CLK->CLKDIV0 + ((MODULE_CLKDIV(u32ModuleIdx)) * 4);
- /* Apply new divider */
- M32(u32div) = (M32(u32div) & (~(MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx)))) | u32ClkDiv;
- }
- if(MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk)
- {
- /* Get clock select control register address */
- u32sel = (uint32_t)&CLK->CLKSEL0 + ((MODULE_CLKSEL(u32ModuleIdx)) * 4);
- /* Set new clock selection setting */
- M32(u32sel) = (M32(u32sel) & (~(MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx)))) | u32ClkSrc;
- }
- }
- /**
- * @brief Set SysTick clock source
- * @param[in] u32ClkSrc is module clock source. Including:
- * - \ref CLK_CLKSEL0_STCLKSEL_HXT
- * - \ref CLK_CLKSEL0_STCLKSEL_LXT
- * - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
- * - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
- * - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
- * @return None
- * @details This function set SysTick clock source. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
- {
- CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
- }
- /**
- * @brief Enable clock source
- * @param[in] u32ClkMask is clock source mask. Including :
- * - \ref CLK_PWRCTL_HXTEN_Msk
- * - \ref CLK_PWRCTL_LXTEN_Msk
- * - \ref CLK_PWRCTL_HIRCEN_Msk
- * - \ref CLK_PWRCTL_LIRCEN_Msk
- * @return None
- * @details This function enable clock source. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_EnableXtalRC(uint32_t u32ClkMask)
- {
- CLK->PWRCTL |= u32ClkMask;
- }
- /**
- * @brief Disable clock source
- * @param[in] u32ClkMask is clock source mask. Including :
- * - \ref CLK_PWRCTL_HXTEN_Msk
- * - \ref CLK_PWRCTL_LXTEN_Msk
- * - \ref CLK_PWRCTL_HIRCEN_Msk
- * - \ref CLK_PWRCTL_LIRCEN_Msk
- * @return None
- * @details This function disable clock source. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_DisableXtalRC(uint32_t u32ClkMask)
- {
- CLK->PWRCTL &= ~u32ClkMask;
- }
- /**
- * @brief Enable module clock
- * @param[in] u32ModuleIdx is module index. Including :
- * - \ref PDMA_MODULE
- * - \ref ISP_MODULE
- * - \ref EBI_MODULE
- * - \ref USBH_MODULE
- * - \ref CRC_MODULE
- * - \ref WDT_MODULE
- * - \ref WWDT_MODULE
- * - \ref RTC_MODULE
- * - \ref TMR0_MODULE
- * - \ref TMR1_MODULE
- * - \ref TMR2_MODULE
- * - \ref TMR3_MODULE
- * - \ref CLKO_MODULE
- * - \ref ACMP01_MODULE
- * - \ref I2C0_MODULE
- * - \ref I2C1_MODULE
- * - \ref SPI0_MODULE
- * - \ref SPI1_MODULE
- * - \ref SPI2_MODULE
- * - \ref UART0_MODULE
- * - \ref UART1_MODULE
- * - \ref UART2_MODULE
- * - \ref UART3_MODULE
- * - \ref CAN0_MODULE
- * - \ref OTG_MODULE
- * - \ref USBD_MODULE
- * - \ref EADC_MODULE
- * - \ref SC0_MODULE
- * - \ref DAC_MODULE
- * - \ref PWM0_MODULE
- * - \ref PWM1_MODULE
- * - \ref TK_MODULE
- * @return None
- * @details This function is used to enable module clock.
- */
- void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
- {
- *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK + (MODULE_APBCLK(u32ModuleIdx) * 4)) |= 1 << MODULE_IP_EN_Pos(u32ModuleIdx);
- }
- /**
- * @brief Disable module clock
- * @param[in] u32ModuleIdx is module index. Including :
- * - \ref PDMA_MODULE
- * - \ref ISP_MODULE
- * - \ref EBI_MODULE
- * - \ref USBH_MODULE
- * - \ref CRC_MODULE
- * - \ref WDT_MODULE
- * - \ref WWDT_MODULE
- * - \ref RTC_MODULE
- * - \ref TMR0_MODULE
- * - \ref TMR1_MODULE
- * - \ref TMR2_MODULE
- * - \ref TMR3_MODULE
- * - \ref CLKO_MODULE
- * - \ref ACMP01_MODULE
- * - \ref I2C0_MODULE
- * - \ref I2C1_MODULE
- * - \ref SPI0_MODULE
- * - \ref SPI1_MODULE
- * - \ref SPI2_MODULE
- * - \ref UART0_MODULE
- * - \ref UART1_MODULE
- * - \ref UART2_MODULE
- * - \ref UART3_MODULE
- * - \ref CAN0_MODULE
- * - \ref OTG_MODULE
- * - \ref USBD_MODULE
- * - \ref EADC_MODULE
- * - \ref SC0_MODULE
- * - \ref DAC_MODULE
- * - \ref PWM0_MODULE
- * - \ref PWM1_MODULE
- * - \ref TK_MODULE
- * @return None
- * @details This function is used to disable module clock.
- */
- void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
- {
- *(volatile uint32_t *)((uint32_t)&CLK->AHBCLK + (MODULE_APBCLK(u32ModuleIdx) * 4)) &= ~(1 << MODULE_IP_EN_Pos(u32ModuleIdx));
- }
- /**
- * @brief Set PLL frequency
- * @param[in] u32PllClkSrc is PLL clock source. Including :
- * - \ref CLK_PLLCTL_PLLSRC_HXT
- * - \ref CLK_PLLCTL_PLLSRC_HIRC
- * @param[in] u32PllFreq is PLL frequency.
- * @return PLL frequency
- * @details This function is used to configure PLLCTL register to set specified PLL frequency. \n
- * The register write-protection function should be disabled before using this function.
- */
- uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
- {
- uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32CLK_SRC;
- uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR;
- /* Disable PLL first to avoid unstable when setting PLL */
- CLK_DisablePLL();
- /* PLL source clock is from HXT */
- if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
- {
- /* Enable HXT clock */
- CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;
- /* Wait for HXT clock ready */
- CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
- /* Select PLL source clock from HXT */
- u32CLK_SRC = CLK_PLLCTL_PLLSRC_HXT;
- u32PllSrcClk = __HXT;
- /* u32NR start from 2 */
- u32NR = 2;
- }
- /* PLL source clock is from HIRC */
- else
- {
- /* Enable HIRC clock */
- CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
- /* Wait for HIRC clock ready */
- CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
- /* Select PLL source clock from HIRC */
- u32CLK_SRC = CLK_PLLCTL_PLLSRC_HIRC;
- u32PllSrcClk = __HIRC;
- /* u32NR start from 4 when FIN = 22.1184MHz to avoid calculation overflow */
- u32NR = 4;
- }
- /* Select "NO" according to request frequency */
- if((u32PllFreq <= FREQ_500MHZ) && (u32PllFreq > FREQ_250MHZ))
- {
- u32NO = 0;
- }
- else if((u32PllFreq <= FREQ_250MHZ) && (u32PllFreq > FREQ_125MHZ))
- {
- u32NO = 1;
- u32PllFreq = u32PllFreq << 1;
- }
- else if((u32PllFreq <= FREQ_125MHZ) && (u32PllFreq >= FREQ_50MHZ))
- {
- u32NO = 3;
- u32PllFreq = u32PllFreq << 2;
- }
- else
- {
- /* Wrong frequency request. Just return default setting. */
- goto lexit;
- }
- /* Find best solution */
- u32Min = (uint32_t) - 1;
- u32MinNR = 0;
- u32MinNF = 0;
- for(; u32NR <= 33; u32NR++)
- {
- u32Tmp = u32PllSrcClk / u32NR;
- if((u32Tmp > 1600000) && (u32Tmp < 16000000))
- {
- for(u32NF = 2; u32NF <= 513; u32NF++)
- {
- u32Tmp2 = u32Tmp * u32NF;
- if((u32Tmp2 >= 200000000) && (u32Tmp2 <= 500000000))
- {
- u32Tmp3 = (u32Tmp2 > u32PllFreq) ? u32Tmp2 - u32PllFreq : u32PllFreq - u32Tmp2;
- if(u32Tmp3 < u32Min)
- {
- u32Min = u32Tmp3;
- u32MinNR = u32NR;
- u32MinNF = u32NF;
- /* Break when get good results */
- if(u32Min == 0)
- break;
- }
- }
- }
- }
- }
- /* Enable and apply new PLL setting. */
- CLK->PLLCTL = u32CLK_SRC | (u32NO << 14) | ((u32MinNR - 2) << 9) | (u32MinNF - 2);
- /* Wait for PLL clock stable */
- CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
- /* Return actual PLL output clock frequency */
- return u32PllSrcClk / ((u32NO + 1) * u32MinNR) * u32MinNF;
- lexit:
- /* Apply default PLL setting and return */
- if(u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT)
- CLK->PLLCTL = CLK_PLLCTL_72MHz_HXT; /* 72MHz */
- else
- CLK->PLLCTL = CLK_PLLCTL_72MHz_HIRC; /* 71.8848MHz */
- /* Wait for PLL clock stable */
- CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
- return CLK_GetPLLClockFreq();
- }
- /**
- * @brief Disable PLL
- * @param None
- * @return None
- * @details This function set PLL in Power-down mode. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_DisablePLL(void)
- {
- CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
- }
- /**
- * @brief This function check selected clock source status
- * @param[in] u32ClkMask is selected clock source. Including :
- * - \ref CLK_STATUS_HXTSTB_Msk
- * - \ref CLK_STATUS_LXTSTB_Msk
- * - \ref CLK_STATUS_HIRCSTB_Msk
- * - \ref CLK_STATUS_LIRCSTB_Msk
- * - \ref CLK_STATUS_PLLSTB_Msk
- * @retval 0 clock is not stable
- * @retval 1 clock is stable
- * @details To wait for clock ready by specified clock source stable flag or timeout (~300ms)
- */
- uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
- {
- int32_t i32TimeOutCnt = 2160000;
- while((CLK->STATUS & u32ClkMask) != u32ClkMask)
- {
- if(i32TimeOutCnt-- <= 0)
- return 0;
- }
- return 1;
- }
- /**
- * @brief Enable System Tick counter
- * @param[in] u32ClkSrc is System Tick clock source. Including:
- * - \ref CLK_CLKSEL0_STCLKSEL_HXT
- * - \ref CLK_CLKSEL0_STCLKSEL_LXT
- * - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
- * - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
- * - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
- * - \ref CLK_CLKSEL0_STCLKSEL_HCLK
- * @param[in] u32Count is System Tick reload value. It could be 0~0xFFFFFF.
- * @return None
- * @details This function set System Tick clock source, reload value, enable System Tick counter and interrupt. \n
- * The register write-protection function should be disabled before using this function.
- */
- void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
- {
- /* Set System Tick counter disabled */
- SysTick->CTRL = 0;
- /* Set System Tick clock source */
- if( u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK )
- SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
- else
- CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
- /* Set System Tick reload value */
- SysTick->LOAD = u32Count;
-
- /* Clear System Tick current value and counter flag */
- SysTick->VAL = 0;
-
- /* Set System Tick interrupt enabled and counter enabled */
- SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
- }
- /**
- * @brief Disable System Tick counter
- * @param None
- * @return None
- * @details This function disable System Tick counter.
- */
- void CLK_DisableSysTick(void)
- {
- /* Set System Tick counter disabled */
- SysTick->CTRL = 0;
- }
- /*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
- /*@}*/ /* end of group CLK_Driver */
- /*@}*/ /* end of group Standard_Driver */
- /*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/
|