Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m480_clk.c Source File

m480_clk.c

00001 /**************************************************************************//**
00002  * @file     clk.c
00003  * @version  V3.00
00004  * @brief    M480 series CLK driver source file
00005  *
00006  * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without modification,
00009  * are permitted provided that the following conditions are met:
00010  *   1. Redistributions of source code must retain the above copyright notice,
00011  *      this list of conditions and the following disclaimer.
00012  *   2. Redistributions in binary form must reproduce the above copyright notice,
00013  *      this list of conditions and the following disclaimer in the documentation
00014  *      and/or other materials provided with the distribution.
00015  *   3. Neither the name of Nuvoton Technology Corp. nor the names of its contributors
00016  *      may be used to endorse or promote products derived from this software
00017  *      without specific prior written permission.
00018  * 
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00023  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00024  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00025  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00026  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *****************************************************************************/
00030 
00031 #include "NuMicro.h"
00032 
00033 /** @addtogroup Standard_Driver Standard Driver
00034   @{
00035 */
00036 
00037 /** @addtogroup CLK_Driver CLK Driver
00038   @{
00039 */
00040 
00041 /** @addtogroup CLK_EXPORTED_FUNCTIONS CLK Exported Functions
00042   @{
00043 */
00044 
00045 /**
00046   * @brief      Disable clock divider output function
00047   * @param      None
00048   * @return     None
00049   * @details    This function disable clock divider output function.
00050   */
00051 void CLK_DisableCKO(void)
00052 {
00053     /* Disable CKO clock source */
00054     CLK_DisableModuleClock(CLKO_MODULE);
00055 }
00056 
00057 /**
00058   * @brief      This function enable clock divider output module clock,
00059   *             enable clock divider output function and set frequency selection.
00060   * @param[in]  u32ClkSrc is frequency divider function clock source. Including :
00061   *             - \ref CLK_CLKSEL1_CLKOSEL_HXT
00062   *             - \ref CLK_CLKSEL1_CLKOSEL_LXT
00063   *             - \ref CLK_CLKSEL1_CLKOSEL_HCLK
00064   *             - \ref CLK_CLKSEL1_CLKOSEL_HIRC
00065   * @param[in]  u32ClkDiv is divider output frequency selection. It could be 0~15.
00066   * @param[in]  u32ClkDivBy1En is clock divided by one enabled.
00067   * @return     None
00068   * @details    Output selected clock to CKO. The output clock frequency is divided by u32ClkDiv. \n
00069   *             The formula is: \n
00070   *                 CKO frequency = (Clock source frequency) / 2^(u32ClkDiv + 1) \n
00071   *             This function is just used to set CKO clock.
00072   *             User must enable I/O for CKO clock output pin by themselves. \n
00073   */
00074 void CLK_EnableCKO(uint32_t u32ClkSrc, uint32_t u32ClkDiv, uint32_t u32ClkDivBy1En)
00075 {
00076     /* CKO = clock source / 2^(u32ClkDiv + 1) */
00077     CLK->CLKOCTL = CLK_CLKOCTL_CLKOEN_Msk | (u32ClkDiv) | (u32ClkDivBy1En << CLK_CLKOCTL_DIV1EN_Pos);
00078     /* Enable CKO clock source */
00079     CLK_EnableModuleClock(CLKO_MODULE);
00080     /* Select CKO clock source */
00081     CLK_SetModuleClock(CLKO_MODULE, u32ClkSrc, 0UL);
00082 }
00083 
00084 /**
00085   * @brief      Enter to Power-down mode
00086   * @param      None
00087   * @return     None
00088   * @details    This function is used to let system enter to Power-down mode. \n
00089   *             The register write-protection function should be disabled before using this function.
00090   */
00091 void CLK_PowerDown(void)
00092 {
00093     uint32_t u32HIRCTRIMCTL;
00094     /* Set the processor uses deep sleep as its low power mode */
00095     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
00096     /* Set system Power-down enabled */
00097     CLK->PWRCTL |= (CLK_PWRCTL_PDEN_Msk);
00098     /* Store HIRC control register */
00099     u32HIRCTRIMCTL = SYS->IRCTCTL;
00100     /* Disable HIRC auto trim */
00101     SYS->IRCTCTL &= (~SYS_IRCTCTL_FREQSEL_Msk);
00102     /* Chip enter Power-down mode after CPU run WFI instruction */
00103     __WFI();
00104     /* Restore HIRC control register */
00105     SYS->IRCTCTL = u32HIRCTRIMCTL;
00106 }
00107 
00108 /**
00109   * @brief      Enter to Idle mode
00110   * @param      None
00111   * @return     None
00112   * @details    This function let system enter to Idle mode. \n
00113   *             The register write-protection function should be disabled before using this function.
00114   */
00115 void CLK_Idle(void)
00116 {
00117     /* Set the processor uses sleep as its low power mode */
00118     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
00119     /* Set chip in idle mode because of WFI command */
00120     CLK->PWRCTL &= ~CLK_PWRCTL_PDEN_Msk;
00121     /* Chip enter idle mode after CPU run WFI instruction */
00122     __WFI();
00123 }
00124 
00125 /**
00126   * @brief      Get external high speed crystal clock frequency
00127   * @param      None
00128   * @return     External high frequency crystal frequency
00129   * @details    This function get external high frequency crystal frequency. The frequency unit is Hz.
00130   */
00131 uint32_t CLK_GetHXTFreq(void)
00132 {
00133     uint32_t u32Freq;
00134 
00135     if ((CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk) == CLK_PWRCTL_HXTEN_Msk) {
00136         u32Freq = __HXT;
00137     } else {
00138         u32Freq = 0UL;
00139     }
00140 
00141     return u32Freq;
00142 }
00143 
00144 
00145 /**
00146   * @brief      Get external low speed crystal clock frequency
00147   * @param      None
00148   * @return     External low speed crystal clock frequency
00149   * @details    This function get external low frequency crystal frequency. The frequency unit is Hz.
00150   */
00151 uint32_t CLK_GetLXTFreq(void)
00152 {
00153     uint32_t u32Freq;
00154 
00155     if ((CLK->PWRCTL & CLK_PWRCTL_LXTEN_Msk) == CLK_PWRCTL_LXTEN_Msk) {
00156         u32Freq = __LXT;
00157     } else {
00158         u32Freq = 0UL;
00159     }
00160 
00161     return u32Freq;
00162 }
00163 
00164 /**
00165   * @brief      Get PCLK0 frequency
00166   * @param      None
00167   * @return     PCLK0 frequency
00168   * @details    This function get PCLK0 frequency. The frequency unit is Hz.
00169   */
00170 uint32_t CLK_GetPCLK0Freq(void)
00171 {
00172     uint32_t u32Freq;
00173     SystemCoreClockUpdate();
00174 
00175     if ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_PCLK0DIV1) {
00176         u32Freq = SystemCoreClock;
00177     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_PCLK0DIV2) {
00178         u32Freq = SystemCoreClock / 2UL;
00179     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_PCLK0DIV4) {
00180         u32Freq = SystemCoreClock / 4UL;
00181     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_PCLK0DIV8) {
00182         u32Freq = SystemCoreClock / 8UL;
00183     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB0DIV_Msk) == CLK_PCLKDIV_PCLK0DIV16) {
00184         u32Freq = SystemCoreClock / 16UL;
00185     } else {
00186         u32Freq = SystemCoreClock;
00187     }
00188 
00189     return u32Freq;
00190 }
00191 
00192 
00193 /**
00194   * @brief      Get PCLK1 frequency
00195   * @param      None
00196   * @return     PCLK1 frequency
00197   * @details    This function get PCLK1 frequency. The frequency unit is Hz.
00198   */
00199 uint32_t CLK_GetPCLK1Freq(void)
00200 {
00201     uint32_t u32Freq;
00202     SystemCoreClockUpdate();
00203 
00204     if ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_PCLK1DIV1) {
00205         u32Freq = SystemCoreClock;
00206     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_PCLK1DIV2) {
00207         u32Freq = SystemCoreClock / 2UL;
00208     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_PCLK1DIV4) {
00209         u32Freq = SystemCoreClock / 4UL;
00210     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_PCLK1DIV8) {
00211         u32Freq = SystemCoreClock / 8UL;
00212     } else if ((CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) == CLK_PCLKDIV_PCLK1DIV16) {
00213         u32Freq = SystemCoreClock / 16UL;
00214     } else {
00215         u32Freq = SystemCoreClock;
00216     }
00217 
00218     return u32Freq;
00219 }
00220 
00221 
00222 /**
00223   * @brief      Get HCLK frequency
00224   * @param      None
00225   * @return     HCLK frequency
00226   * @details    This function get HCLK frequency. The frequency unit is Hz.
00227   */
00228 uint32_t CLK_GetHCLKFreq(void)
00229 {
00230     SystemCoreClockUpdate();
00231     return SystemCoreClock;
00232 }
00233 
00234 
00235 /**
00236   * @brief      Get CPU frequency
00237   * @param      None
00238   * @return     CPU frequency
00239   * @details    This function get CPU frequency. The frequency unit is Hz.
00240   */
00241 uint32_t CLK_GetCPUFreq(void)
00242 {
00243     SystemCoreClockUpdate();
00244     return SystemCoreClock;
00245 }
00246 
00247 
00248 /**
00249   * @brief      Set HCLK frequency
00250   * @param[in]  u32Hclk is HCLK frequency. The range of u32Hclk is running up to 192MHz.
00251   * @return     HCLK frequency
00252   * @details    This function is used to set HCLK frequency. The frequency unit is Hz. \n
00253   *             The register write-protection function should be disabled before using this function.
00254   */
00255 uint32_t CLK_SetCoreClock(uint32_t u32Hclk)
00256 {
00257     uint32_t u32HIRCSTB;
00258     /* Read HIRC clock source stable flag */
00259     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
00260 
00261     /* The range of u32Hclk is running up to 192 MHz */
00262     if (u32Hclk > FREQ_192MHZ) {
00263         u32Hclk = FREQ_192MHZ;
00264     }
00265 
00266     /* Switch HCLK clock source to HIRC clock for safe */
00267     CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
00268     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
00269     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLKSEL_Msk;
00270     CLK->CLKDIV0 &= (~CLK_CLKDIV0_HCLKDIV_Msk);
00271 
00272     /* Configure PLL setting if HXT clock is enabled */
00273     if ((CLK->PWRCTL & CLK_PWRCTL_HXTEN_Msk) == CLK_PWRCTL_HXTEN_Msk) {
00274         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HXT, u32Hclk);
00275     }
00276     /* Configure PLL setting if HXT clock is not enabled */
00277     else {
00278         u32Hclk = CLK_EnablePLL(CLK_PLLCTL_PLLSRC_HIRC, u32Hclk);
00279         /* Read HIRC clock source stable flag */
00280         u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
00281     }
00282 
00283     /* Select HCLK clock source to PLL,
00284        and update system core clock
00285     */
00286     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(1UL));
00287 
00288     /* Disable HIRC if HIRC is disabled before setting core clock */
00289     if (u32HIRCSTB == 0UL) {
00290         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
00291     }
00292 
00293     /* Return actually HCLK frequency is PLL frequency divide 1 */
00294     return u32Hclk;
00295 }
00296 
00297 /**
00298   * @brief      This function set HCLK clock source and HCLK clock divider
00299   * @param[in]  u32ClkSrc is HCLK clock source. Including :
00300   *             - \ref CLK_CLKSEL0_HCLKSEL_HXT
00301   *             - \ref CLK_CLKSEL0_HCLKSEL_LXT
00302   *             - \ref CLK_CLKSEL0_HCLKSEL_PLL
00303   *             - \ref CLK_CLKSEL0_HCLKSEL_LIRC
00304   *             - \ref CLK_CLKSEL0_HCLKSEL_HIRC
00305   * @param[in]  u32ClkDiv is HCLK clock divider. Including :
00306   *             - \ref CLK_CLKDIV0_HCLK(x)
00307   * @return     None
00308   * @details    This function set HCLK clock source and HCLK clock divider. \n
00309   *             The register write-protection function should be disabled before using this function.
00310   */
00311 void CLK_SetHCLK(uint32_t u32ClkSrc, uint32_t u32ClkDiv)
00312 {
00313     uint32_t u32HIRCSTB;
00314     /* Read HIRC clock source stable flag */
00315     u32HIRCSTB = CLK->STATUS & CLK_STATUS_HIRCSTB_Msk;
00316     /* Switch to HIRC for Safe. Avoid HCLK too high when applying new divider. */
00317     CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
00318     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
00319     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC;
00320     /* Apply new Divider */
00321     CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | u32ClkDiv;
00322     /* Switch HCLK to new HCLK source */
00323     CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | u32ClkSrc;
00324     /* Update System Core Clock */
00325     SystemCoreClockUpdate();
00326 
00327     /* Disable HIRC if HIRC is disabled before switching HCLK source */
00328     if (u32HIRCSTB == 0UL) {
00329         CLK->PWRCTL &= ~CLK_PWRCTL_HIRCEN_Msk;
00330     }
00331 }
00332 
00333 /**
00334   * @brief      This function set selected module clock source and module clock divider
00335   * @param[in]  u32ModuleIdx is module index.
00336   * @param[in]  u32ClkSrc is module clock source.
00337   * @param[in]  u32ClkDiv is module clock divider.
00338   * @return     None
00339   * @details    Valid parameter combinations listed in following table:
00340   *
00341   * |Module index        |Clock source                           |Divider                        |
00342   * | :----------------  | :-----------------------------------  | :--------------------------   |
00343   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_HXT           |\ref CLK_CLKDIV0_SDH0(x)       |
00344   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_PLL           |\ref CLK_CLKDIV0_SDH0(x)       |
00345   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_HIRC          |\ref CLK_CLKDIV0_SDH0(x)       |
00346   * |\ref SDH0_MODULE    |\ref CLK_CLKSEL0_SDH0SEL_HCLK          |\ref CLK_CLKDIV0_SDH0(x)       |
00347   * |\ref SDH1_MODULE    |\ref CLK_CLKSEL0_SDH1SEL_HXT           |\ref CLK_CLKDIV3_SDH1(x)       |
00348   * |\ref SDH1_MODULE    |\ref CLK_CLKSEL0_SDH1SEL_PLL           |\ref CLK_CLKDIV3_SDH1(x)       |
00349   * |\ref SDH1_MODULE    |\ref CLK_CLKSEL0_SDH1SEL_HIRC          |\ref CLK_CLKDIV3_SDH1(x)       |
00350   * |\ref SDH1_MODULE    |\ref CLK_CLKSEL0_SDH1SEL_HCLK          |\ref CLK_CLKDIV3_SDH1(x)       |
00351   * |\ref WDT_MODULE     |\ref CLK_CLKSEL1_WDTSEL_LXT            | x                             |
00352   * |\ref WDT_MODULE     |\ref CLK_CLKSEL1_WDTSEL_LIRC           | x                             |
00353   * |\ref WDT_MODULE     |\ref CLK_CLKSEL1_WDTSEL_HCLK_DIV2048   | x                             |
00354   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_HXT           | x                             |
00355   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_LXT           | x                             |
00356   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_LIRC          | x                             |
00357   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_HIRC          | x                             |
00358   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_PCLK0         | x                             |
00359   * |\ref TMR0_MODULE    |\ref CLK_CLKSEL1_TMR0SEL_EXT           | x                             |
00360   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_HXT           | x                             |
00361   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_LXT           | x                             |
00362   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_LIRC          | x                             |
00363   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_HIRC          | x                             |
00364   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_PCLK0         | x                             |
00365   * |\ref TMR1_MODULE    |\ref CLK_CLKSEL1_TMR1SEL_EXT           | x                             |
00366   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_HXT           | x                             |
00367   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_LXT           | x                             |
00368   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_LIRC          | x                             |
00369   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_HIRC          | x                             |
00370   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_PCLK1         | x                             |
00371   * |\ref TMR2_MODULE    |\ref CLK_CLKSEL1_TMR2SEL_EXT           | x                             |
00372   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_HXT           | x                             |
00373   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_LXT           | x                             |
00374   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_LIRC          | x                             |
00375   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_HIRC          | x                             |
00376   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_PCLK1         | x                             |
00377   * |\ref TMR3_MODULE    |\ref CLK_CLKSEL1_TMR3SEL_EXT           | x                             |
00378   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_HXT          |\ref CLK_CLKDIV0_UART0(x)      |
00379   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_LXT          |\ref CLK_CLKDIV0_UART0(x)      |
00380   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_PLL          |\ref CLK_CLKDIV0_UART0(x)      |
00381   * |\ref UART0_MODULE   |\ref CLK_CLKSEL1_UART0SEL_HIRC         |\ref CLK_CLKDIV0_UART0(x)      |
00382   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_HXT          |\ref CLK_CLKDIV0_UART1(x)      |
00383   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_LXT          |\ref CLK_CLKDIV0_UART1(x)      |
00384   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_PLL          |\ref CLK_CLKDIV0_UART1(x)      |
00385   * |\ref UART1_MODULE   |\ref CLK_CLKSEL1_UART1SEL_HIRC         |\ref CLK_CLKDIV0_UART1(x)      |
00386   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_HXT           | x                             |
00387   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_LXT           | x                             |
00388   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_HIRC          | x                             |
00389   * |\ref CLKO_MODULE    |\ref CLK_CLKSEL1_CLKOSEL_HCLK          | x                             |
00390   * |\ref WWDT_MODULE    |\ref CLK_CLKSEL1_WWDTSEL_LIRC          | x                             |
00391   * |\ref WWDT_MODULE    |\ref CLK_CLKSEL1_WWDTSEL_HCLK_DIV2048  | x                             |
00392   * |\ref EPWM0_MODULE   |\ref CLK_CLKSEL2_EPWM0SEL_PLL          | x                             |
00393   * |\ref EPWM0_MODULE   |\ref CLK_CLKSEL2_EPWM0SEL_PCLK0        | x                             |
00394   * |\ref EPWM1_MODULE   |\ref CLK_CLKSEL2_EPWM1SEL_PLL          | x                             |
00395   * |\ref EPWM1_MODULE   |\ref CLK_CLKSEL2_EPWM1SEL_PCLK1        | x                             |
00396   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_HXT          | x                             |
00397   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_PLL          | x                             |
00398   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_HIRC         | x                             |
00399   * |\ref QSPI0_MODULE   |\ref CLK_CLKSEL2_QSPI0SEL_PCLK0        | x                             |
00400   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_HXT           | x                             |
00401   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_PLL           | x                             |
00402   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_HIRC          | x                             |
00403   * |\ref SPI0_MODULE    |\ref CLK_CLKSEL2_SPI0SEL_PCLK1         | x                             |
00404   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_HXT           | x                             |
00405   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_PLL           | x                             |
00406   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_HIRC          | x                             |
00407   * |\ref SPI1_MODULE    |\ref CLK_CLKSEL2_SPI1SEL_PCLK0         | x                             |
00408   * |\ref BPWM0_MODULE   |\ref CLK_CLKSEL2_BPWM0SEL_PLL          | x                             |
00409   * |\ref BPWM0_MODULE   |\ref CLK_CLKSEL2_BPWM0SEL_PCLK0        | x                             |
00410   * |\ref BPWM1_MODULE   |\ref CLK_CLKSEL2_BPWM1SEL_PLL          | x                             |
00411   * |\ref BPWM1_MODULE   |\ref CLK_CLKSEL2_BPWM1SEL_PCLK1        | x                             |
00412   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_HXT           | x                             |
00413   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_PLL           | x                             |
00414   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_HIRC          | x                             |
00415   * |\ref SPI2_MODULE    |\ref CLK_CLKSEL2_SPI2SEL_PCLK1         | x                             |
00416   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_HXT           | x                             |
00417   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_PLL           | x                             |
00418   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_HIRC          | x                             |
00419   * |\ref SPI3_MODULE    |\ref CLK_CLKSEL2_SPI3SEL_PCLK0         | x                             |
00420   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_HXT            |\ref CLK_CLKDIV1_SC0(x)        |
00421   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_PLL            |\ref CLK_CLKDIV1_SC0(x)        |
00422   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_HIRC           |\ref CLK_CLKDIV1_SC0(x)        |
00423   * |\ref SC0_MODULE     |\ref CLK_CLKSEL3_SC0SEL_PCLK0          |\ref CLK_CLKDIV1_SC0(x)        |
00424   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_HXT            |\ref CLK_CLKDIV1_SC1(x)        |
00425   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_PLL            |\ref CLK_CLKDIV1_SC1(x)        |
00426   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_HIRC           |\ref CLK_CLKDIV1_SC1(x)        |
00427   * |\ref SC1_MODULE     |\ref CLK_CLKSEL3_SC1SEL_PCLK1          |\ref CLK_CLKDIV1_SC1(x)        |
00428   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_HXT            |\ref CLK_CLKDIV1_SC2(x)        |
00429   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_PLL            |\ref CLK_CLKDIV1_SC2(x)        |
00430   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_HIRC           |\ref CLK_CLKDIV1_SC2(x)        |
00431   * |\ref SC2_MODULE     |\ref CLK_CLKSEL3_SC2SEL_PCLK0          |\ref CLK_CLKDIV1_SC2(x)        |
00432   * |\ref RTC_MODULE     |\ref CLK_CLKSEL3_RTCSEL_LXT            | x                             |
00433   * |\ref RTC_MODULE     |\ref CLK_CLKSEL3_RTCSEL_LIRC           | x                             |
00434   * |\ref I2S0_MODULE    |\ref CLK_CLKSEL3_I2S0SEL_HXT           | x                             |
00435   * |\ref I2S0_MODULE    |\ref CLK_CLKSEL3_I2S0SEL_PLL           | x                             |
00436   * |\ref I2S0_MODULE    |\ref CLK_CLKSEL3_I2S0SEL_HIRC          | x                             |
00437   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_HXT          |\ref CLK_CLKDIV4_UART2(x)      |
00438   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_LXT          |\ref CLK_CLKDIV4_UART2(x)      |
00439   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_PLL          |\ref CLK_CLKDIV4_UART2(x)      |
00440   * |\ref UART2_MODULE   |\ref CLK_CLKSEL3_UART2SEL_HIRC         |\ref CLK_CLKDIV4_UART2(x)      |
00441   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_HXT          |\ref CLK_CLKDIV4_UART3(x)      |
00442   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_LXT          |\ref CLK_CLKDIV4_UART3(x)      |
00443   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_PLL          |\ref CLK_CLKDIV4_UART3(x)      |
00444   * |\ref UART3_MODULE   |\ref CLK_CLKSEL3_UART3SEL_HIRC         |\ref CLK_CLKDIV4_UART3(x)      |
00445   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_HXT          |\ref CLK_CLKDIV4_UART4(x)      |
00446   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_LXT          |\ref CLK_CLKDIV4_UART4(x)      |
00447   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_PLL          |\ref CLK_CLKDIV4_UART4(x)      |
00448   * |\ref UART4_MODULE   |\ref CLK_CLKSEL3_UART4SEL_HIRC         |\ref CLK_CLKDIV4_UART4(x)      |
00449   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_HXT          |\ref CLK_CLKDIV4_UART5(x)      |
00450   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_LXT          |\ref CLK_CLKDIV4_UART5(x)      |
00451   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_PLL          |\ref CLK_CLKDIV4_UART5(x)      |
00452   * |\ref UART5_MODULE   |\ref CLK_CLKSEL3_UART5SEL_HIRC         |\ref CLK_CLKDIV4_UART5(x)      |
00453   * |\ref EADC_MODULE    | x                                     |\ref CLK_CLKDIV0_EADC(x)       |
00454   * |\ref EMAC_MODULE    | x                                     |\ref CLK_CLKDIV3_EMAC(x)       |
00455   *
00456   */
00457 void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
00458 {
00459     uint32_t u32sel = 0U, u32div = 0U;
00460 
00461     if (MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk) {
00462         /* Get clock divider control register address */
00463         if (MODULE_CLKDIV(u32ModuleIdx) == 2U) {
00464             u32div = (uint32_t)&CLK->CLKDIV3;
00465         } else if (MODULE_CLKDIV(u32ModuleIdx) == 3U) {
00466             u32div = (uint32_t)&CLK->CLKDIV4;
00467         } else {
00468             u32div = (uint32_t)&CLK->CLKDIV0 + ((MODULE_CLKDIV(u32ModuleIdx)) * 4U);
00469         }
00470 
00471         /* Apply new divider */
00472         M32(u32div) = (M32(u32div) & (~(MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx)))) | u32ClkDiv;
00473     }
00474 
00475     if (MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk) {
00476         /* Get clock select control register address */
00477         u32sel = (uint32_t)&CLK->CLKSEL0 + ((MODULE_CLKSEL(u32ModuleIdx)) * 4U);
00478         /* Set new clock selection setting */
00479         M32(u32sel) = (M32(u32sel) & (~(MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx)))) | u32ClkSrc;
00480     }
00481 }
00482 
00483 /**
00484   * @brief      Set SysTick clock source
00485   * @param[in]  u32ClkSrc is module clock source. Including:
00486   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT
00487   *             - \ref CLK_CLKSEL0_STCLKSEL_LXT
00488   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
00489   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
00490   *             - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
00491   * @return     None
00492   * @details    This function set SysTick clock source. \n
00493   *             The register write-protection function should be disabled before using this function.
00494   */
00495 void CLK_SetSysTickClockSrc(uint32_t u32ClkSrc)
00496 {
00497     CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
00498 }
00499 
00500 /**
00501   * @brief      Enable clock source
00502   * @param[in]  u32ClkMask is clock source mask. Including :
00503   *             - \ref CLK_PWRCTL_HXTEN_Msk
00504   *             - \ref CLK_PWRCTL_LXTEN_Msk
00505   *             - \ref CLK_PWRCTL_HIRCEN_Msk
00506   *             - \ref CLK_PWRCTL_LIRCEN_Msk
00507   * @return     None
00508   * @details    This function enable clock source. \n
00509   *             The register write-protection function should be disabled before using this function.
00510   */
00511 void CLK_EnableXtalRC(uint32_t u32ClkMask)
00512 {
00513     CLK->PWRCTL |= u32ClkMask;
00514 }
00515 
00516 /**
00517   * @brief      Disable clock source
00518   * @param[in]  u32ClkMask is clock source mask. Including :
00519   *             - \ref CLK_PWRCTL_HXTEN_Msk
00520   *             - \ref CLK_PWRCTL_LXTEN_Msk
00521   *             - \ref CLK_PWRCTL_HIRCEN_Msk
00522   *             - \ref CLK_PWRCTL_LIRCEN_Msk
00523   * @return     None
00524   * @details    This function disable clock source. \n
00525   *             The register write-protection function should be disabled before using this function.
00526   */
00527 void CLK_DisableXtalRC(uint32_t u32ClkMask)
00528 {
00529     CLK->PWRCTL &= ~u32ClkMask;
00530 }
00531 
00532 /**
00533   * @brief      Enable module clock
00534   * @param[in]  u32ModuleIdx is module index. Including :
00535   *             - \ref PDMA_MODULE
00536   *             - \ref ISP_MODULE
00537   *             - \ref EBI_MODULE
00538   *             - \ref EMAC_MODULE
00539   *             - \ref SDH0_MODULE
00540   *             - \ref CRC_MODULE
00541   *             - \ref HSUSBD_MODULE
00542   *             - \ref CRPT_MODULE
00543   *             - \ref SPIM_MODULE
00544   *             - \ref FMCIDLE_MODULE
00545   *             - \ref USBH_MODULE
00546   *             - \ref SDH1_MODULE
00547   *             - \ref WDT_MODULE
00548   *             - \ref RTC_MODULE
00549   *             - \ref TMR0_MODULE
00550   *             - \ref TMR1_MODULE
00551   *             - \ref TMR2_MODULE
00552   *             - \ref TMR3_MODULE
00553   *             - \ref CLKO_MODULE
00554   *             - \ref WWDT_MODULE
00555   *             - \ref ACMP01_MODULE
00556   *             - \ref I2C0_MODULE
00557   *             - \ref I2C1_MODULE
00558   *             - \ref I2C2_MODULE
00559   *             - \ref QSPI0_MODULE
00560   *             - \ref SPI0_MODULE
00561   *             - \ref SPI1_MODULE
00562   *             - \ref SPI2_MODULE
00563   *             - \ref UART0_MODULE
00564   *             - \ref UART1_MODULE
00565   *             - \ref UART2_MODULE
00566   *             - \ref UART3_MODULE
00567   *             - \ref UART4_MODULE
00568   *             - \ref UART5_MODULE
00569   *             - \ref CAN0_MODULE
00570   *             - \ref CAN1_MODULE
00571   *             - \ref OTG_MODULE
00572   *             - \ref USBD_MODULE
00573   *             - \ref EADC_MODULE
00574   *             - \ref I2S0_MODULE
00575   *             - \ref HSOTG_MODULE
00576   *             - \ref SC0_MODULE
00577   *             - \ref SC1_MODULE
00578   *             - \ref SC2_MODULE
00579   *             - \ref SPI3_MODULE
00580   *             - \ref USCI0_MODULE
00581   *             - \ref USCI1_MODULE
00582   *             - \ref DAC_MODULE
00583   *             - \ref EPWM0_MODULE
00584   *             - \ref EPWM1_MODULE
00585   *             - \ref BPWM0_MODULE
00586   *             - \ref BPWM1_MODULE
00587   *             - \ref QEI0_MODULE
00588   *             - \ref QEI1_MODULE
00589   *             - \ref ECAP0_MODULE
00590   *             - \ref ECAP1_MODULE
00591   *             - \ref OPA_MODULE
00592   * @return     None
00593   * @details    This function is used to enable module clock.
00594   */
00595 void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
00596 {
00597     uint32_t u32tmpVal = 0UL, u32tmpAddr = 0UL;
00598     u32tmpVal = (1UL << MODULE_IP_EN_Pos(u32ModuleIdx));
00599     u32tmpAddr = (uint32_t)&CLK->AHBCLK;
00600     u32tmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));
00601     *(volatile uint32_t *)u32tmpAddr |= u32tmpVal;
00602 }
00603 
00604 /**
00605   * @brief      Disable module clock
00606   * @param[in]  u32ModuleIdx is module index. Including :
00607   *             - \ref PDMA_MODULE
00608   *             - \ref ISP_MODULE
00609   *             - \ref EBI_MODULE
00610   *             - \ref EMAC_MODULE
00611   *             - \ref SDH0_MODULE
00612   *             - \ref CRC_MODULE
00613   *             - \ref HSUSBD_MODULE
00614   *             - \ref CRPT_MODULE
00615   *             - \ref SPIM_MODULE
00616   *             - \ref FMCIDLE_MODULE
00617   *             - \ref USBH_MODULE
00618   *             - \ref SDH1_MODULE
00619   *             - \ref WDT_MODULE
00620   *             - \ref RTC_MODULE
00621   *             - \ref TMR0_MODULE
00622   *             - \ref TMR1_MODULE
00623   *             - \ref TMR2_MODULE
00624   *             - \ref TMR3_MODULE
00625   *             - \ref CLKO_MODULE
00626   *             - \ref WWDT_MODULE
00627   *             - \ref ACMP01_MODULE
00628   *             - \ref I2C0_MODULE
00629   *             - \ref I2C1_MODULE
00630   *             - \ref I2C2_MODULE
00631   *             - \ref QSPI0_MODULE
00632   *             - \ref SPI0_MODULE
00633   *             - \ref SPI1_MODULE
00634   *             - \ref SPI2_MODULE
00635   *             - \ref UART0_MODULE
00636   *             - \ref UART1_MODULE
00637   *             - \ref UART2_MODULE
00638   *             - \ref UART3_MODULE
00639   *             - \ref UART4_MODULE
00640   *             - \ref UART5_MODULE
00641   *             - \ref CAN0_MODULE
00642   *             - \ref CAN1_MODULE
00643   *             - \ref OTG_MODULE
00644   *             - \ref USBD_MODULE
00645   *             - \ref EADC_MODULE
00646   *             - \ref I2S0_MODULE
00647   *             - \ref HSOTG_MODULE
00648   *             - \ref SC0_MODULE
00649   *             - \ref SC1_MODULE
00650   *             - \ref SC2_MODULE
00651   *             - \ref SPI3_MODULE
00652   *             - \ref USCI0_MODULE
00653   *             - \ref USCI1_MODULE
00654   *             - \ref DAC_MODULE
00655   *             - \ref EPWM0_MODULE
00656   *             - \ref EPWM1_MODULE
00657   *             - \ref BPWM0_MODULE
00658   *             - \ref BPWM1_MODULE
00659   *             - \ref QEI0_MODULE
00660   *             - \ref QEI1_MODULE
00661   *             - \ref ECAP0_MODULE
00662   *             - \ref ECAP1_MODULE
00663   *             - \ref OPA_MODULE
00664   * @return     None
00665   * @details    This function is used to disable module clock.
00666   */
00667 void CLK_DisableModuleClock(uint32_t u32ModuleIdx)
00668 {
00669     uint32_t u32tmpVal = 0UL, u32tmpAddr = 0UL;
00670     u32tmpVal = ~(1UL << MODULE_IP_EN_Pos(u32ModuleIdx));
00671     u32tmpAddr = (uint32_t)&CLK->AHBCLK;
00672     u32tmpAddr += ((MODULE_APBCLK(u32ModuleIdx) * 4UL));
00673     *(uint32_t *)u32tmpAddr &= u32tmpVal;
00674 }
00675 
00676 
00677 /**
00678   * @brief      Set PLL frequency
00679   * @param[in]  u32PllClkSrc is PLL clock source. Including :
00680   *             - \ref CLK_PLLCTL_PLLSRC_HXT
00681   *             - \ref CLK_PLLCTL_PLLSRC_HIRC
00682   * @param[in]  u32PllFreq is PLL frequency.
00683   * @return     PLL frequency
00684   * @details    This function is used to configure PLLCTL register to set specified PLL frequency. \n
00685   *             The register write-protection function should be disabled before using this function.
00686   */
00687 uint32_t CLK_EnablePLL(uint32_t u32PllClkSrc, uint32_t u32PllFreq)
00688 {
00689     uint32_t u32PllSrcClk, u32NR, u32NF, u32NO, u32CLK_SRC, u32PllClk;
00690     uint32_t u32Tmp, u32Tmp2, u32Tmp3, u32Min, u32MinNF, u32MinNR, u32MinNO, u32basFreq;
00691     /* Disable PLL first to avoid unstable when setting PLL */
00692     CLK_DisablePLL();
00693 
00694     /* PLL source clock is from HXT */
00695     if (u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT) {
00696         /* Enable HXT clock */
00697         CLK->PWRCTL |= CLK_PWRCTL_HXTEN_Msk;
00698         /* Wait for HXT clock ready */
00699         CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
00700         /* Select PLL source clock from HXT */
00701         u32CLK_SRC = CLK_PLLCTL_PLLSRC_HXT;
00702         u32PllSrcClk = __HXT;
00703         /* u32NR start from 2 */
00704         u32NR = 2UL;
00705     }
00706     /* PLL source clock is from HIRC */
00707     else {
00708         /* Enable HIRC clock */
00709         CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
00710         /* Wait for HIRC clock ready */
00711         CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
00712         /* Select PLL source clock from HIRC */
00713         u32CLK_SRC = CLK_PLLCTL_PLLSRC_HIRC;
00714         u32PllSrcClk = __HIRC;
00715         /* u32NR start from 4 when FIN = 22.1184MHz to avoid calculation overflow */
00716         u32NR = 4UL;
00717     }
00718 
00719     if ((u32PllFreq <= FREQ_500MHZ) && (u32PllFreq >= FREQ_50MHZ)) {
00720         /* Find best solution */
00721         u32Min = (uint32_t) - 1;
00722         u32MinNR = 0UL;
00723         u32MinNF = 0UL;
00724         u32MinNO = 0UL;
00725         u32basFreq = u32PllFreq;
00726 
00727         for (u32NO = 1UL; u32NO <= 4UL; u32NO++) {
00728             /* Break when get good results */
00729             if (u32Min == 0UL) {
00730                 break;
00731             }
00732 
00733             if (u32NO != 3UL) {
00734                 if (u32NO == 4UL) {
00735                     u32PllFreq = u32basFreq << 2;
00736                 } else if (u32NO == 2UL) {
00737                     u32PllFreq = u32basFreq << 1;
00738                 } else {
00739                 }
00740 
00741                 for (u32NR = 2UL; u32NR <= 32UL; u32NR++) {
00742                     /* Break when get good results */
00743                     if (u32Min == 0UL) {
00744                         break;
00745                     }
00746 
00747                     u32Tmp = u32PllSrcClk / u32NR;
00748 
00749                     if ((u32Tmp >= 4000000UL) && (u32Tmp <= 8000000UL)) {
00750                         for (u32NF = 2UL; u32NF <= 513UL; u32NF++) {
00751                             /* u32Tmp2 is shifted 2 bits to avoid overflow */
00752                             u32Tmp2 = (((u32Tmp * 2UL) >> 2) * u32NF);
00753 
00754                             if ((u32Tmp2 >= FREQ_50MHZ) && (u32Tmp2 <= FREQ_125MHZ)) {
00755                                 u32Tmp3 = (u32Tmp2 > (u32PllFreq >> 2)) ? u32Tmp2 - (u32PllFreq >> 2) : (u32PllFreq >> 2) - u32Tmp2;
00756 
00757                                 if (u32Tmp3 < u32Min) {
00758                                     u32Min = u32Tmp3;
00759                                     u32MinNR = u32NR;
00760                                     u32MinNF = u32NF;
00761                                     u32MinNO = u32NO;
00762 
00763                                     /* Break when get good results */
00764                                     if (u32Min == 0UL) {
00765                                         break;
00766                                     }
00767                                 }
00768                             }
00769                         }
00770                     }
00771                 }
00772             }
00773         }
00774 
00775         /* Enable and apply new PLL setting. */
00776         CLK->PLLCTL = u32CLK_SRC | ((u32MinNO - 1UL) << 14) | ((u32MinNR - 1UL) << 9) | (u32MinNF - 2UL);
00777         /* Wait for PLL clock stable */
00778         CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
00779         /* Actual PLL output clock frequency */
00780         u32PllClk = u32PllSrcClk / (u32MinNO * (u32MinNR)) * (u32MinNF) * 2UL;
00781     } else {
00782         /* Wrong frequency request. Just return default setting. */
00783         /* Apply default PLL setting and return */
00784         if (u32PllClkSrc == CLK_PLLCTL_PLLSRC_HXT) {
00785             CLK->PLLCTL = CLK_PLLCTL_192MHz_HXT;
00786         } else {
00787             CLK->PLLCTL = CLK_PLLCTL_192MHz_HIRC;
00788         }
00789 
00790         /* Wait for PLL clock stable */
00791         CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
00792         /* Actual PLL output clock frequency */
00793         u32PllClk = CLK_GetPLLClockFreq();
00794     }
00795 
00796     return u32PllClk;
00797 }
00798 
00799 /**
00800   * @brief      Disable PLL
00801   * @param      None
00802   * @return     None
00803   * @details    This function set PLL in Power-down mode. \n
00804   *             The register write-protection function should be disabled before using this function.
00805   */
00806 void CLK_DisablePLL(void)
00807 {
00808     CLK->PLLCTL |= CLK_PLLCTL_PD_Msk;
00809 }
00810 
00811 
00812 /**
00813   * @brief      This function check selected clock source status
00814   * @param[in]  u32ClkMask is selected clock source. Including :
00815   *             - \ref CLK_STATUS_HXTSTB_Msk
00816   *             - \ref CLK_STATUS_LXTSTB_Msk
00817   *             - \ref CLK_STATUS_HIRCSTB_Msk
00818   *             - \ref CLK_STATUS_LIRCSTB_Msk
00819   *             - \ref CLK_STATUS_PLLSTB_Msk
00820   * @retval     0  clock is not stable
00821   * @retval     1  clock is stable
00822   * @details    To wait for clock ready by specified clock source stable flag or timeout (~300ms)
00823   */
00824 uint32_t CLK_WaitClockReady(uint32_t u32ClkMask)
00825 {
00826     int32_t i32TimeOutCnt = 2160000;
00827     uint32_t u32Ret = 1U;
00828 
00829     while ((CLK->STATUS & u32ClkMask) != u32ClkMask) {
00830         if (i32TimeOutCnt-- <= 0) {
00831             u32Ret = 0U;
00832             break;
00833         }
00834     }
00835 
00836     return u32Ret;
00837 }
00838 
00839 /**
00840   * @brief      Enable System Tick counter
00841   * @param[in]  u32ClkSrc is System Tick clock source. Including:
00842   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT
00843   *             - \ref CLK_CLKSEL0_STCLKSEL_LXT
00844   *             - \ref CLK_CLKSEL0_STCLKSEL_HXT_DIV2
00845   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK_DIV2
00846   *             - \ref CLK_CLKSEL0_STCLKSEL_HIRC_DIV2
00847   *             - \ref CLK_CLKSEL0_STCLKSEL_HCLK
00848   * @param[in]  u32Count is System Tick reload value. It could be 0~0xFFFFFF.
00849   * @return     None
00850   * @details    This function set System Tick clock source, reload value, enable System Tick counter and interrupt. \n
00851   *             The register write-protection function should be disabled before using this function.
00852   */
00853 void CLK_EnableSysTick(uint32_t u32ClkSrc, uint32_t u32Count)
00854 {
00855     /* Set System Tick counter disabled */
00856     SysTick->CTRL = 0UL;
00857 
00858     /* Set System Tick clock source */
00859     if (u32ClkSrc == CLK_CLKSEL0_STCLKSEL_HCLK) {
00860         SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
00861     } else {
00862         CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_STCLKSEL_Msk) | u32ClkSrc;
00863     }
00864 
00865     /* Set System Tick reload value */
00866     SysTick->LOAD = u32Count;
00867     /* Clear System Tick current value and counter flag */
00868     SysTick->VAL = 0UL;
00869     /* Set System Tick interrupt enabled and counter enabled */
00870     SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
00871 }
00872 
00873 /**
00874   * @brief      Disable System Tick counter
00875   * @param      None
00876   * @return     None
00877   * @details    This function disable System Tick counter.
00878   */
00879 void CLK_DisableSysTick(void)
00880 {
00881     /* Set System Tick counter disabled */
00882     SysTick->CTRL = 0UL;
00883 }
00884 
00885 
00886 /**
00887   * @brief      Power-down mode selected
00888   * @param[in]  u32PDMode is power down mode index. Including :
00889   *             - \ref CLK_PMUCTL_PDMSEL_PD
00890   *             - \ref CLK_PMUCTL_PDMSEL_LLPD
00891   *             - \ref CLK_PMUCTL_PDMSEL_FWPD
00892   *             - \ref CLK_PMUCTL_PDMSEL_SPD0
00893   *             - \ref CLK_PMUCTL_PDMSEL_SPD1
00894   *             - \ref CLK_PMUCTL_PDMSEL_DPD
00895   * @return     None
00896   * @details    This function is used to set power-down mode.
00897   * @note       Must enable LIRC clock before entering to Standby Power-down Mode
00898   */
00899 
00900 void CLK_SetPowerDownMode(uint32_t u32PDMode)
00901 {
00902     /* Enable LIRC clock before entering to Standby Power-down Mode */
00903     if ((u32PDMode == CLK_PMUCTL_PDMSEL_SPD0) || (u32PDMode == CLK_PMUCTL_PDMSEL_SPD1)) {
00904         /* Enable LIRC clock */
00905         CLK->PWRCTL |= CLK_PWRCTL_LIRCEN_Msk;
00906         /* Wait for LIRC clock stable */
00907         CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);
00908     }
00909 
00910     CLK->PMUCTL = (CLK->PMUCTL & ~(CLK_PMUCTL_PDMSEL_Msk)) | u32PDMode;
00911 }
00912 
00913 /**
00914  * @brief       Set Wake-up pin trigger type at Deep Power down mode
00915  *
00916  * @param[in]   u32TriggerType
00917  *              - \ref CLK_DPDWKPIN_RISING
00918  *              - \ref CLK_DPDWKPIN_FALLING
00919  *              - \ref CLK_DPDWKPIN_BOTHEDGE
00920  * @return      None
00921  *
00922  * @details     This function is used to enable Wake-up pin trigger type.
00923  */
00924 
00925 void CLK_EnableDPDWKPin(uint32_t u32TriggerType)
00926 {
00927     CLK->PMUCTL = (CLK->PMUCTL & ~(CLK_PMUCTL_WKPINEN_Msk)) | u32TriggerType;
00928 }
00929 
00930 /**
00931  * @brief      Get power manager wake up source
00932  *
00933  * @param[in]   None
00934  * @return      None
00935  *
00936  * @details     This function get power manager wake up source.
00937  */
00938 
00939 uint32_t CLK_GetPMUWKSrc(void)
00940 {
00941     return (CLK->PMUSTS);
00942 }
00943 
00944 /**
00945  * @brief       Set specified GPIO as wake up source at Stand-by Power down mode
00946  *
00947  * @param[in]   u32Port GPIO port. It could be 0~3.
00948  * @param[in]   u32Pin  The pin of specified GPIO port. It could be 0 ~ 15.
00949  * @param[in]   u32TriggerType
00950  *              - \ref CLK_SPDWKPIN_RISING
00951  *              - \ref CLK_SPDWKPIN_FALLING
00952  * @param[in]   u32DebounceEn
00953  *              - \ref CLK_SPDWKPIN_DEBOUNCEEN
00954  *              - \ref CLK_SPDWKPIN_DEBOUNCEDIS
00955  * @return      None
00956  *
00957  * @details     This function is used to set specified GPIO as wake up source
00958  *              at Stand-by Power down mode.
00959  */
00960 void CLK_EnableSPDWKPin(uint32_t u32Port, uint32_t u32Pin, uint32_t u32TriggerType, uint32_t u32DebounceEn)
00961 {
00962     uint32_t u32tmpAddr = 0UL;
00963     uint32_t u32tmpVal = 0UL;
00964     /* GPx Stand-by Power-down Wake-up Pin Select */
00965     u32tmpAddr = (uint32_t)&CLK->PASWKCTL;
00966     u32tmpAddr += (0x4UL * u32Port);
00967     u32tmpVal = inpw((uint32_t *)u32tmpAddr);
00968     u32tmpVal = (u32tmpVal & ~(CLK_PASWKCTL_WKPSEL_Msk | CLK_PASWKCTL_PRWKEN_Msk | CLK_PASWKCTL_PFWKEN_Msk | CLK_PASWKCTL_DBEN_Msk | CLK_PASWKCTL_WKEN_Msk)) |
00969                 (u32Pin << CLK_PASWKCTL_WKPSEL_Pos) | u32TriggerType | u32DebounceEn | CLK_SPDWKPIN_ENABLE;
00970     outpw((uint32_t *)u32tmpAddr, u32tmpVal);
00971 }
00972 
00973 /**
00974   * @brief      Get PLL clock frequency
00975   * @param      None
00976   * @return     PLL frequency
00977   * @details    This function get PLL frequency. The frequency unit is Hz.
00978   */
00979 uint32_t CLK_GetPLLClockFreq(void)
00980 {
00981     uint32_t u32PllFreq = 0UL, u32PllReg;
00982     uint32_t u32FIN, u32NF, u32NR, u32NO;
00983     uint8_t au8NoTbl[4] = {1U, 2U, 2U, 4U};
00984     u32PllReg = CLK->PLLCTL;
00985 
00986     if (u32PllReg & (CLK_PLLCTL_PD_Msk | CLK_PLLCTL_OE_Msk)) {
00987         u32PllFreq = 0UL;           /* PLL is in power down mode or fix low */
00988     } else if ((u32PllReg & CLK_PLLCTL_BP_Msk) == CLK_PLLCTL_BP_Msk) {
00989         if ((u32PllReg & CLK_PLLCTL_PLLSRC_HIRC) == CLK_PLLCTL_PLLSRC_HIRC) {
00990             u32FIN = __HIRC;    /* PLL source clock from HIRC */
00991         } else {
00992             u32FIN = __HXT;     /* PLL source clock from HXT */
00993         }
00994 
00995         u32PllFreq = u32FIN;
00996     } else {
00997         if ((u32PllReg & CLK_PLLCTL_PLLSRC_HIRC) == CLK_PLLCTL_PLLSRC_HIRC) {
00998             u32FIN = __HIRC;    /* PLL source clock from HIRC */
00999         } else {
01000             u32FIN = __HXT;     /* PLL source clock from HXT */
01001         }
01002 
01003         /* PLL is output enabled in normal work mode */
01004         u32NO = au8NoTbl[((u32PllReg & CLK_PLLCTL_OUTDIV_Msk) >> CLK_PLLCTL_OUTDIV_Pos)];
01005         u32NF = ((u32PllReg & CLK_PLLCTL_FBDIV_Msk) >> CLK_PLLCTL_FBDIV_Pos) + 2UL;
01006         u32NR = ((u32PllReg & CLK_PLLCTL_INDIV_Msk) >> CLK_PLLCTL_INDIV_Pos) + 1UL;
01007         /* u32FIN is shifted 2 bits to avoid overflow */
01008         u32PllFreq = (((u32FIN >> 2) * u32NF) / (u32NR * u32NO) << 2) * 2UL;
01009     }
01010 
01011     return u32PllFreq;
01012 }
01013 
01014 /**
01015   * @brief      Get selected module clock source
01016   * @param[in]  u32ModuleIdx is module index.
01017   *             - \ref SDH0_MODULE
01018   *             - \ref SDH1_MODULE
01019   *             - \ref WDT_MODULE
01020   *             - \ref UART0_MODULE
01021   *             - \ref UART1_MODULE
01022   *             - \ref CLKO_MODULE
01023   *             - \ref WWDT_MODULE
01024   *             - \ref TMR0_MODULE
01025   *             - \ref TMR1_MODULE
01026   *             - \ref TMR2_MODULE
01027   *             - \ref TMR3_MODULE
01028   *             - \ref EPWM0_MODULE
01029   *             - \ref EPWM1_MODULE
01030   *             - \ref BPWM0_MODULE
01031   *             - \ref BPWM1_MODULE
01032   *             - \ref QSPI0_MODULE
01033   *             - \ref SPI0_MODULE
01034   *             - \ref SPI1_MODULE
01035   *             - \ref SPI2_MODULE
01036   *             - \ref SPI3_MODULE
01037   *             - \ref SC0_MODULE
01038   *             - \ref SC1_MODULE
01039   *             - \ref SC2_MODULE
01040   *             - \ref RTC_MODULE
01041   *             - \ref I2S0_MODULE
01042   *             - \ref UART2_MODULE
01043   *             - \ref UART3_MODULE
01044   *             - \ref UART4_MODULE
01045   *             - \ref UART5_MODULE
01046   * @return     Selected module clock source setting
01047   * @details    This function get selected module clock source.
01048   */
01049 uint32_t CLK_GetModuleClockSource(uint32_t u32ModuleIdx)
01050 {
01051     uint32_t u32sel = 0;
01052     uint32_t u32SelTbl[4] = {0x0, 0x4, 0x8, 0xC};
01053 
01054     /* Get clock source selection setting */
01055     if (u32ModuleIdx == EPWM0_MODULE) {
01056         return ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM0SEL_Msk) >> CLK_CLKSEL2_EPWM0SEL_Pos);
01057     } else if (u32ModuleIdx == EPWM1_MODULE) {
01058         return ((CLK->CLKSEL2 & CLK_CLKSEL2_EPWM1SEL_Msk) >> CLK_CLKSEL2_EPWM1SEL_Pos);
01059     } else if (u32ModuleIdx == BPWM0_MODULE) {
01060         return ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM0SEL_Msk) >> CLK_CLKSEL2_BPWM0SEL_Pos);
01061     } else if (u32ModuleIdx == BPWM1_MODULE) {
01062         return ((CLK->CLKSEL2 & CLK_CLKSEL2_BPWM1SEL_Msk) >> CLK_CLKSEL2_BPWM1SEL_Pos);
01063     } else if (MODULE_CLKSEL_Msk(u32ModuleIdx) != MODULE_NoMsk) {
01064         /* Get clock select control register address */
01065         u32sel = (uint32_t)&CLK->CLKSEL0 + (u32SelTbl[MODULE_CLKSEL(u32ModuleIdx)]);
01066         /* Get clock source selection setting */
01067         return ((M32(u32sel) & (MODULE_CLKSEL_Msk(u32ModuleIdx) << MODULE_CLKSEL_Pos(u32ModuleIdx))) >> MODULE_CLKSEL_Pos(u32ModuleIdx));
01068     } else {
01069         return 0;
01070     }
01071 }
01072 
01073 /**
01074   * @brief      Get selected module clock divider number
01075   * @param[in]  u32ModuleIdx is module index.
01076   *             - \ref UART0_MODULE
01077   *             - \ref UART1_MODULE
01078   *             - \ref EADC_MODULE
01079   *             - \ref SDH0_MODULE
01080   *             - \ref SC0_MODULE
01081   *             - \ref SC1_MODULE
01082   *             - \ref SC2_MODULE
01083   *             - \ref EMAC_MODULE
01084   *             - \ref SDH1_MODULE
01085   *             - \ref UART2_MODULE
01086   *             - \ref UART3_MODULE
01087   *             - \ref UART4_MODULE
01088   *             - \ref UART5_MODULE
01089   * @return     Selected module clock divider number setting
01090   * @details    This function get selected module clock divider number.
01091   */
01092 uint32_t CLK_GetModuleClockDivider(uint32_t u32ModuleIdx)
01093 {
01094     uint32_t u32div = 0;
01095     uint32_t u32DivTbl[4] = {0x0, 0x4, 0x8, 0x10};
01096 
01097     if (MODULE_CLKDIV_Msk(u32ModuleIdx) != MODULE_NoMsk) {
01098         /* Get clock divider control register address */
01099         u32div = (uint32_t)&CLK->CLKDIV0 + (u32DivTbl[MODULE_CLKDIV(u32ModuleIdx)]);
01100         /* Get clock divider number setting */
01101         return ((M32(u32div) & (MODULE_CLKDIV_Msk(u32ModuleIdx) << MODULE_CLKDIV_Pos(u32ModuleIdx))) >> MODULE_CLKDIV_Pos(u32ModuleIdx));
01102     } else {
01103         return 0;
01104     }
01105 }
01106 
01107 
01108 /*@}*/ /* end of group CLK_EXPORTED_FUNCTIONS */
01109 
01110 /*@}*/ /* end of group CLK_Driver */
01111 
01112 /*@}*/ /* end of group Standard_Driver */
01113 
01114 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/