Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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. ***/
Generated on Tue Jul 12 2022 15:37:20 by
1.7.2