Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:04

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsARMLPC32XX
0007  *
0008  * @brief System clocks.
0009  */
0010 
0011 /*
0012  * Copyright (c) 2011 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #include <bsp.h>
0037 #include <bsp/lpc32xx.h>
0038 
0039 uint32_t lpc32xx_sysclk(void)
0040 {
0041   uint32_t sysclk_ctrl = LPC32XX_SYSCLK_CTRL;
0042 
0043   return (sysclk_ctrl & 0x1) == 0 ?
0044     LPC32XX_OSCILLATOR_MAIN
0045       : (397 * LPC32XX_OSCILLATOR_RTC);
0046 }
0047 
0048 uint32_t lpc32xx_hclkpll_clk(void)
0049 {
0050   uint32_t sysclk = lpc32xx_sysclk();
0051   uint32_t hclkpll_ctrl = LPC32XX_HCLKPLL_CTRL;
0052   uint32_t m = HCLK_PLL_M_GET(hclkpll_ctrl) + 1;
0053   uint32_t n = HCLK_PLL_N_GET(hclkpll_ctrl) + 1;
0054   uint32_t p = 1U << HCLK_PLL_P_GET(hclkpll_ctrl);
0055   uint32_t hclkpll_clk = 0;
0056 
0057   if ((hclkpll_ctrl & HCLK_PLL_BYPASS) != 0) {
0058     if ((hclkpll_ctrl & HCLK_PLL_DIRECT) != 0) {
0059       hclkpll_clk = sysclk;
0060     } else {
0061       hclkpll_clk = sysclk / (2 * p);
0062     }
0063   } else {
0064     if ((hclkpll_ctrl & HCLK_PLL_DIRECT) != 0) {
0065       hclkpll_clk = (m * sysclk) / n;
0066     } else {
0067       if ((hclkpll_ctrl & HCLK_PLL_FBD_FCLKOUT) != 0) {
0068         hclkpll_clk = m * (sysclk / n);
0069       } else {
0070         hclkpll_clk = (m / (2 * p)) * (sysclk / n);
0071       }
0072     }
0073   }
0074 
0075   return hclkpll_clk;
0076 }
0077 
0078 uint32_t lpc32xx_periph_clk(void)
0079 {
0080   uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
0081   uint32_t periph_clk = 0;
0082 
0083   if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) {
0084     uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL;
0085     uint32_t div = HCLK_DIV_PERIPH_CLK_GET(hclkdiv_ctrl) + 1;
0086 
0087     periph_clk = lpc32xx_hclkpll_clk() / div;
0088   } else {
0089     periph_clk = lpc32xx_sysclk();
0090   }
0091 
0092   return periph_clk;
0093 }
0094 
0095 uint32_t lpc32xx_hclk(void)
0096 {
0097   uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
0098   uint32_t hclk = 0;
0099 
0100   if ((pwr_ctrl & PWR_HCLK_USES_PERIPH_CLK) != 0) {
0101     hclk = lpc32xx_periph_clk();
0102   } else {
0103     if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) {
0104       uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL;
0105       uint32_t div = 1U << HCLK_DIV_HCLK_GET(hclkdiv_ctrl);
0106 
0107       hclk = lpc32xx_hclkpll_clk() / div;
0108     } else {
0109       hclk = lpc32xx_sysclk();
0110     }
0111   }
0112 
0113   return hclk;
0114 }
0115 
0116 uint32_t lpc32xx_arm_clk(void)
0117 {
0118   uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
0119   uint32_t arm_clk = 0;
0120 
0121   if ((pwr_ctrl & PWR_HCLK_USES_PERIPH_CLK) != 0) {
0122     arm_clk = lpc32xx_periph_clk();
0123   } else {
0124     if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) {
0125       arm_clk = lpc32xx_hclkpll_clk();
0126     } else {
0127       arm_clk = lpc32xx_sysclk();
0128     }
0129   }
0130 
0131   return arm_clk;
0132 }
0133 
0134 uint32_t lpc32xx_ddram_clk(void)
0135 {
0136   uint32_t hclkdiv_ctrl = LPC32XX_HCLKDIV_CTRL;
0137   uint32_t div = HCLK_DIV_DDRAM_CLK_GET(hclkdiv_ctrl);
0138   uint32_t ddram_clk = 0;
0139 
0140   if (div != 0) {
0141     uint32_t pwr_ctrl = LPC32XX_PWR_CTRL;
0142 
0143     if ((pwr_ctrl & PWR_NORMAL_RUN_MODE) != 0) {
0144       ddram_clk = lpc32xx_hclkpll_clk();
0145     } else {
0146       ddram_clk = lpc32xx_sysclk();
0147     }
0148 
0149     ddram_clk /= div;
0150   }
0151 
0152   return ddram_clk;
0153 }