From 2cbdf19f9cfa8accf876573415ca265666ad6b8a Mon Sep 17 00:00:00 2001 From: Adrian Negreanu Date: Thu, 6 Jan 2022 22:25:50 +0200 Subject: [PATCH] lpc43xx_cgu: remove Signed-off-by: Adrian Negreanu --- source/hic_hal/nxp/lpc4322/board_LPC43xx.c | 122 ++- source/hic_hal/nxp/lpc4322/lpc43xx_cgu.c | 1132 -------------------- source/hic_hal/nxp/lpc4322/lpc43xx_cgu.h | 265 ----- source/hic_hal/nxp/lpc4322/uart.c | 15 +- 4 files changed, 116 insertions(+), 1418 deletions(-) delete mode 100644 source/hic_hal/nxp/lpc4322/lpc43xx_cgu.c delete mode 100644 source/hic_hal/nxp/lpc4322/lpc43xx_cgu.h diff --git a/source/hic_hal/nxp/lpc4322/board_LPC43xx.c b/source/hic_hal/nxp/lpc4322/board_LPC43xx.c index 367366f584..2a67c760a6 100644 --- a/source/hic_hal/nxp/lpc4322/board_LPC43xx.c +++ b/source/hic_hal/nxp/lpc4322/board_LPC43xx.c @@ -20,24 +20,112 @@ */ #include "sdk.h" -#include "lpc43xx_cgu.h" +#include "LPC43xx.h" + +#define XTAL_OSC_HZ 12000000 + + +static void wait_usec(uint32_t clock_hz, volatile uint32_t us) +{ + us *= (clock_hz / 1000000) / 3; + + while (us--); +} + + +static void clock_setup_base_m4(uint32_t clock_hz) +{ + uint32_t msel; + uint32_t nsel; + uint32_t tmp; + + // 0. Select IRC as BASE_M4_CLK source + tmp = LPC_CGU->BASE_M4_CLK & ~(0x0F << 24); // clear clk_sel. + LPC_CGU->BASE_M4_CLK = tmp + | (0x01 << 11) // AUTOBLOCK En + | (0x01 << 24) // CLK_SEL = IRC + ; + + // 1. Enable the crystal oscillator @12 MHz. + LPC_CGU->XTAL_OSC_CTRL &= ~(1 << 2); // HF: 0=XTAL running at freq < 15 MHz. + LPC_CGU->XTAL_OSC_CTRL &= ~1; // Power up XTAL. + + // 2. Wait 250us + wait_usec(XTAL_OSC_HZ, 250); + + // 3. Reconfigure PLL1 as follows: + // - Select the M and N divider values + // to produce the final desired + // PLL1 output frequency. + // Ex: 120MHz => M=10,N=1 => msel=9,nsel=0. + msel = clock_hz / XTAL_OSC_HZ - 1; + nsel = 0; + tmp = LPC_CGU->PLL1_CTRL & ~((0xFF << 16) | (0x03 << 12)); + LPC_CGU->PLL1_CTRL = tmp | (msel << 16) | (nsel << 12); + + // - Select the crystal oscillator as + // clock source for PLL1. + tmp = LPC_CGU->PLL1_CTRL & ~(0x0F << 24); // clear CLK_SEL. + LPC_CGU->PLL1_CTRL = tmp + | (0x01 << 11) // AUTOBLOCK: 0=Disabled, 1=Enabled. + | (0x06 << 24) // CLK_SEL = XTAL. + ; + + // 4. Wait for the PLL1 to lock + while ((LPC_CGU->PLL1_STAT & 1) == 0x0) + {} + + // 5. Set PLL1 P-divider to divide by 2 (DIRECT=0 and PSEL=0) + LPC_CGU->PLL1_CTRL &= ~((0x03 << 8) | (1 << 7)); + + // 6. Select PLL1 as BASE_M4_CLK source. + // BASE_M4_CLK is now operating in the + // mid frequency range (90 MHz - 110 Mhz). + tmp = LPC_CGU->BASE_M4_CLK & ~(0x0F << 24); // clear CLK_SEL. + LPC_CGU->BASE_M4_CLK = tmp + | (0x01 << 11) // AUTOBLOCK: 0=Disabled, 1=Enabled. + | (0x09 << 24) // CLK_SEL = PLL1. + ; + // 7. Wait 20us + tmp = (XTAL_OSC_HZ * (msel + 1)) / ((nsel + 1) * 2); + wait_usec(tmp, 20); + + // 8. Set PLL P-divider to direct output mode (DIRECT=1) + LPC_CGU->PLL1_CTRL |= 1 << 7; + + // BASE_M4_CLK is now operating in the + // high frequency range. + SystemCoreClock = (XTAL_OSC_HZ * (msel + 1)) / (nsel + 1); +} + +static void clock_setup_pll0usb() +{ + LPC_CGU->PLL0USB_CTRL |= 1; // Power down PLL0USB. + + // The USB core require output clock to be running @480 MHz. + // Setup PLL0USB to generate 480MHz from 12 MHz XTAL. + LPC_CGU->PLL0USB_NP_DIV = (514 << 12) // N + | (98 << 0); // P + LPC_CGU->PLL0USB_MDIV = (0x7FFA << 0) // MDEC + | (0x0B << 17) // SELP + | (0x10 << 22) // SELI + | (0x00 << 28) // SELR + ; + LPC_CGU->PLL0USB_CTRL = (0 << 0) // PD: 0=Power Up. + | (0x01 << 2) // DIRECTI: 1=bypass pre-divider. + | (0x01 << 3) // DIRECTO: 1=bypass post-divider. + | (0x01 << 4) // CLKEN + | (0x01 << 11) // AUTOBLOCK: 0=Disabled, 1=Enabled. + | (0x06 << 24) // CLK_SEL = XTAL_OSC. + ; + + LPC_CREG->CREG0 &= ~(1 << 5); // Enable USB0 PHY power. +} + void sdk_init(void) { - /* Set core clock to 120MHz */ - CGU_Init(120000000); - /* Set up USB0 clock */ - /* Disable PLL first */ - CGU_EnableEntity(CGU_CLKSRC_PLL0, DISABLE); - - /* the usb core require output clock = 480MHz */ - if (CGU_SetPLL0() != CGU_ERROR_SUCCESS) { - while (1); - } - - CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_CLKSRC_PLL0); - /* Enable PLL after all setting is done */ - CGU_EnableEntity(CGU_CLKSRC_PLL0, ENABLE); - /* Turn on the USB0PHY */ - LPC_CREG->CREG0 &= ~(1 << 5); + clock_setup_base_m4(120000000); + + clock_setup_pll0usb(); } diff --git a/source/hic_hal/nxp/lpc4322/lpc43xx_cgu.c b/source/hic_hal/nxp/lpc4322/lpc43xx_cgu.c deleted file mode 100644 index 867cc2fb49..0000000000 --- a/source/hic_hal/nxp/lpc4322/lpc43xx_cgu.c +++ /dev/null @@ -1,1132 +0,0 @@ -/** - * @file lpc43xx_cgu.c - * @brief - * - * DAPLink Interface Firmware - * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lpc_types.h" -#include "lpc43xx_scu.h" -#include "lpc43xx_cgu.h" - -/** This define used to fix mistake when run with IAR compiler */ -#ifdef __ICCARM__ -#define CGU_BRANCH_STATUS_ENABLE_MASK 0x80000001 -#else -#define CGU_BRANCH_STATUS_ENABLE_MASK 0x01 -#endif - -/*TODO List: - * SET PLL0 - * UPDATE Clock from PLL0 - * SetDIV uncheck value - * GetBaseStatus BASE_SAFE - * */ -/* Local definition */ -#define CGU_ADDRESS32(x,y) (*(uint32_t*)((uint32_t)x+y)) - -/* Local Variable */ -const int16_t CGU_Entity_ControlReg_Offset[CGU_ENTITY_NUM] = { - -1, //CGU_CLKSRC_32KHZ_OSC, - -1, //CGU_CLKSRC_IRC, - -1, //CGU_CLKSRC_ENET_RX_CLK, - -1, //CGU_CLKSRC_ENET_TX_CLK, - -1, //CGU_CLKSRC_GP_CLKIN, - -1, //CGU_CLKSRC_TCK, - 0x18, //CGU_CLKSRC_XTAL_OSC, - 0x20, //CGU_CLKSRC_PLL0, - 0x30, //CGU_CLKSRC_PLL0_AUDIO **REV A** - 0x44, //CGU_CLKSRC_PLL1, - -1, //CGU_CLKSRC_RESERVE, - -1, //CGU_CLKSRC_RESERVE, - 0x48, //CGU_CLKSRC_IDIVA,, - 0x4C, //CGU_CLKSRC_IDIVB, - 0x50, //CGU_CLKSRC_IDIVC, - 0x54, //CGU_CLKSRC_IDIVD, - 0x58, //CGU_CLKSRC_IDIVE, - - 0x5C, //CGU_BASE_SAFE, - 0x60, //CGU_BASE_USB0, - 0x64, //CGU_BASE_PERIPH, // used for SPGPIO, peripheral control - 0x68, //CGU_BASE_USB1, - 0x6C, //CGU_BASE_M4, - 0x70, //CGU_BASE_SPIFI, - -1, //CGU_BASE_RESERVE, - 0x78, //CGU_BASE_PHY_RX, - 0x7C, //CGU_BASE_PHY_TX, - 0x80, //CGU_BASE_APB1, - 0x84, //CGU_BASE_APB3, - 0x88, //CGU_BASE_LCD, - 0X8C, //CGU_BASE_ENET_CSR, **REV A** - 0x90, //CGU_BASE_SDIO, - 0x94, //CGU_BASE_SSP0, - 0x98, //CGU_BASE_SSP1, - 0x9C, //CGU_BASE_UART0, - 0xA0, //CGU_BASE_UART1, - 0xA4, //CGU_BASE_UART2, - 0xA8, //CGU_BASE_UART3, - 0xAC, //CGU_BASE_CLKOUT - -1, - -1, - -1, - -1, - 0xC0, //CGU_BASE_APLL - 0xC4, //CGU_BASE_OUT0 - 0xC8 //CGU_BASE_OUT1 -}; - -const uint8_t CGU_ConnectAlloc_Tbl[CGU_CLKSRC_NUM][CGU_ENTITY_NUM] = { -// 3 I E E G T X P P P x x D D D D D S U P U M S x P P A A L E S S S U U U U C x x x x A O O -// 2 R R T P C T L L L I I I I I A S E S 3 P H H P P C N D S S R R R R O P U U -// C X X I K A 0 A 1 A B C D E F B R B F RxTx1 3 D T I 0 1 0 1 2 3 L T T - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_32KHZ_OSC = 0,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_IRC,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_ENET_RX_CLK,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_ENET_TX_CLK,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_GP_CLKIN,*/ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, /*CGU_CLKSRC_TCK,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_XTAL_OSC,*/ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1}, /*CGU_CLKSRC_PLL0,*/ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_PLL0_AUDIO,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_PLL1,*/ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_IDIVA = CGU_CLKSRC_PLL1 + 3,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_IDIVB,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_IDIVC,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}, /*CGU_CLKSRC_IDIVD,*/ - {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1} /*CGU_CLKSRC_IDIVE,*/ -}; - -const CGU_PERIPHERAL_S CGU_PERIPHERAL_Info[CGU_PERIPHERAL_NUM] = { - /* Register Clock | Peripheral Clock - | BASE | BRANCH | BASE | BRANCH */ - {CGU_BASE_APB3, 0x1118, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_ADC0, - {CGU_BASE_APB3, 0x1120, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_ADC1, - {CGU_BASE_M4, 0x1460, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_AES, - //// CGU_PERIPHERAL_ALARMTIMER_CGU_RGU_RTC_WIC, - {CGU_BASE_APB1, 0x1200, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_APB1_BUS, - {CGU_BASE_APB3, 0x1100, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_APB3_BUS, - {CGU_BASE_APB3, 0x1128, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_CAN0, - {CGU_BASE_M4, 0x1538, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_CREG, - {CGU_BASE_APB3, 0x1110, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_DAC, - {CGU_BASE_M4, 0x1440, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_DMA, - {CGU_BASE_M4, 0x1430, CGU_BASE_M4, 0x1478, 0},//CGU_PERIPHERAL_EMC, - {CGU_BASE_M4, 0x1420, CGU_BASE_PHY_RX, 0x0000, CGU_PERIPHERAL_ETHERNET_TX},//CGU_PERIPHERAL_ETHERNET, - {CGU_ENTITY_NONE, 0x0000, CGU_BASE_PHY_TX, 0x0000, 0}, //CGU_PERIPHERAL_ETHERNET_TX - {CGU_BASE_M4, 0x1410, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_GPIO, - {CGU_BASE_APB1, 0x1210, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2C0, - {CGU_BASE_APB3, 0x1108, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2C1, - {CGU_BASE_APB1, 0x1218, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2S, - {CGU_BASE_M4, 0x1418, CGU_BASE_LCD, 0x0000, 0},//CGU_PERIPHERAL_LCD, - {CGU_BASE_M4, 0x1448, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_M3CORE, - {CGU_BASE_M4, 0x1400, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_M3_BUS, - {CGU_BASE_APB1, 0x1208, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_MOTOCON, - {CGU_BASE_M4, 0x1630, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_QEI, - {CGU_BASE_M4, 0x1600, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_RITIMER, - {CGU_BASE_M4, 0x1468, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_SCT, - {CGU_BASE_M4, 0x1530, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_SCU, - {CGU_BASE_M4, 0x1438, CGU_BASE_SDIO, 0x2800, 0},//CGU_PERIPHERAL_SDIO, - {CGU_BASE_M4, 0x1408, CGU_BASE_SPIFI, 0x1300, 0},//CGU_PERIPHERAL_SPIFI, - {CGU_BASE_M4, 0x1518, CGU_BASE_SSP0, 0x2700, 0},//CGU_PERIPHERAL_SSP0, - {CGU_BASE_M4, 0x1628, CGU_BASE_SSP1, 0x2600, 0},//CGU_PERIPHERAL_SSP1, - {CGU_BASE_M4, 0x1520, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER0, - {CGU_BASE_M4, 0x1528, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER1, - {CGU_BASE_M4, 0x1618, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER2, - {CGU_BASE_M4, 0x1620, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER3, - {CGU_BASE_M4, 0x1508, CGU_BASE_UART0, 0x2500, 0},//CGU_PERIPHERAL_UART0, - {CGU_BASE_M4, 0x1510, CGU_BASE_UART1, 0x2400, 0},//CGU_PERIPHERAL_UART1, - {CGU_BASE_M4, 0x1608, CGU_BASE_UART2, 0x2300, 0},//CGU_PERIPHERAL_UART2, - {CGU_BASE_M4, 0x1610, CGU_BASE_UART3, 0x2200, 0},//CGU_PERIPHERAL_UART3, - {CGU_BASE_M4, 0x1428, CGU_BASE_USB0, 0x1800, 0},//CGU_PERIPHERAL_USB0, - {CGU_BASE_M4, 0x1470, CGU_BASE_USB1, 0x1900, 0},//CGU_PERIPHERAL_USB1, - {CGU_BASE_M4, 0x1500, CGU_BASE_SAFE, 0x0000, 0},//CGU_PERIPHERAL_WWDT, -}; - -uint32_t CGU_ClockSourceFrequency[CGU_CLKSRC_NUM] = {0, 12000000, 0, 0, 0, 0, 0, 480000000, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -#define CGU_CGU_ADDR ((uint32_t)LPC_CGU) -#define CGU_REG_BASE_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_Entity_ControlReg_Offset[CGU_PERIPHERAL_Info[x].RegBaseEntity])) -#define CGU_REG_BRANCH_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset)) -#define CGU_REG_BRANCH_STATUS(x) (*(volatile uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset+4)) - -#define CGU_PER_BASE_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_Entity_ControlReg_Offset[CGU_PERIPHERAL_Info[x].PerBaseEntity])) -#define CGU_PER_BRANCH_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].PerBranchOffset)) -#define CGU_PER_BRANCH_STATUS(x) (*(volatile uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].PerBranchOffset+4)) - -/**************************************************************************//** - * - * @brief Rough approximation of a delay function with microsecond resolution. - * - * Used during initial clock setup as the Timers are not configured yet. - * - * @param [in] us The number of microseconds to wait - * - *****************************************************************************/ -static void cgu_WaitUS(volatile uint32_t us) -{ - us *= (SystemCoreClock / 1000000) / 3; - - while (us--); -} - -/**************************************************************************//** - * - * @brief Simple lookup of best MSEL and NSEL values for wanted frequency - * - * Not optimized. - * - * @param [in] wantedFreq The wanted PLL1 frequency - * @param [out] pMsel The best MSEL value for the PLL1_CTRL register - * @param [out] pNsel The best NSEL value for the PLL1_CTRL register - * - *****************************************************************************/ -static void cgu_findMN(uint32_t wantedFreq, uint32_t *pMsel, uint32_t *pNsel) -{ - uint32_t besterr = wantedFreq; - uint32_t m, n, f, tmp, err; -#define ABSDIFF(__a, __b) ( ((__a) < (__b)) ? ((__b) - (__a)) : ((__a) - (__b)) ) - - for (n = 1; n <= 4; n++) { - f = 12000000 / n; - tmp = 0; - - for (m = 1; m <= 256; m++) { - tmp += f; - err = ABSDIFF(tmp, wantedFreq); - - if (err == 0) { - // found perfect match - *pMsel = m - 1; - *pNsel = n - 1; - return; - - } else if (err < besterr) { - *pMsel = m - 1; - *pNsel = n - 1; - besterr = err; - } - - if (tmp > wantedFreq) { - // no point in continuing to increase tmp as value is too high already - break; - } - } - } -} - -/*********************************************************************//** - * @brief Initialize default clock for LPC4300 Eval board - * @param[in] None - * @return Initialize status, could be: - * - CGU_ERROR_SUCCESS: successful - * - Other: error - **********************************************************************/ -uint32_t CGU_Init(uint32_t wantedFreq) -{ - uint32_t msel = 0; - uint32_t nsel = 0; - uint32_t tmp; - // Setup PLL1 to 204MHz - // 0. Select IRC as BASE_M4_CLK source - CGU_EntityConnect(CGU_CLKSRC_IRC, CGU_BASE_M4); - SystemCoreClock = 120000000; - // 1. Enable the crystal oscillator - CGU_SetXTALOSC(12000000); - CGU_EnableEntity(CGU_CLKSRC_XTAL_OSC, ENABLE); - // 2. Wait 250us - cgu_WaitUS(250); - // 3. Reconfigure PLL1 as follows: - // - Select the M and N divider values to produce the final desired - // PLL1 output frequency (204MHz => M=17,N=1 => msel=16,nsel=0) - // - Select the crystal oscillator as clock source for PLL1 - cgu_findMN(wantedFreq, &msel, &nsel); - tmp = LPC_CGU->PLL1_CTRL & ~((0xFF << 16) | (0x03 << 12)); - LPC_CGU->PLL1_CTRL = tmp | (msel << 16) | (nsel << 12); - CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_CLKSRC_PLL1); - - // 4. Wait for the PLL1 to lock - while ((LPC_CGU->PLL1_STAT & 1) == 0x0); - - // 5. Set PLL1 P-divider to divide by 2 (DIRECT=0 and PSEL=0) - LPC_CGU->PLL1_CTRL &= ~((0x03 << 8) | CGU_PLL1_DIRECT_MASK); - // 6. Select PLL1 as BASE_M4_CLK source. The BASE_M4_CLK now operates at - // the mid frequency range - CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_M4); - SystemCoreClock = (12000000 * (msel + 1)) / ((nsel + 1) * 2); - // 7. Wait 20us - cgu_WaitUS(20); - // 8. Set PLL P-divider to direct output mode (DIRECT=1) - LPC_CGU->PLL1_CTRL |= CGU_PLL1_DIRECT_MASK; - // The BASE_M4_CLK now operates in the high frequency range - CGU_UpdateClock(); - SystemCoreClock = (12000000 * (msel + 1)) / (nsel + 1); - return 0; -} - -/*********************************************************************//** - * @brief Configure power for individual peripheral - * @param[in] PPType peripheral type, should be: - * - CGU_PERIPHERAL_ADC0 :ADC0 - * - CGU_PERIPHERAL_ADC1 :ADC1 - * - CGU_PERIPHERAL_AES :AES - * - CGU_PERIPHERAL_APB1_BUS :APB1 bus - * - CGU_PERIPHERAL_APB3_BUS :APB3 bus - * - CGU_PERIPHERAL_CAN :CAN - * - CGU_PERIPHERAL_CREG :CREG - * - CGU_PERIPHERAL_DAC :DAC - * - CGU_PERIPHERAL_DMA :DMA - * - CGU_PERIPHERAL_EMC :EMC - * - CGU_PERIPHERAL_ETHERNET :ETHERNET - * - CGU_PERIPHERAL_GPIO :GPIO - * - CGU_PERIPHERAL_I2C0 :I2C0 - * - CGU_PERIPHERAL_I2C1 :I2C1 - * - CGU_PERIPHERAL_I2S :I2S - * - CGU_PERIPHERAL_LCD :LCD - * - CGU_PERIPHERAL_M3CORE :M3 core - * - CGU_PERIPHERAL_M3_BUS :M3 bus - * - CGU_PERIPHERAL_MOTOCON :Motor control - * - CGU_PERIPHERAL_QEI :QEI - * - CGU_PERIPHERAL_RITIMER :RIT timer - * - CGU_PERIPHERAL_SCT :SCT - * - CGU_PERIPHERAL_SCU :SCU - * - CGU_PERIPHERAL_SDIO :SDIO - * - CGU_PERIPHERAL_SPIFI :SPIFI - * - CGU_PERIPHERAL_SSP0 :SSP0 - * - CGU_PERIPHERAL_SSP1 :SSP1 - * - CGU_PERIPHERAL_TIMER0 :TIMER0 - * - CGU_PERIPHERAL_TIMER1 :TIMER1 - * - CGU_PERIPHERAL_TIMER2 :TIMER2 - * - CGU_PERIPHERAL_TIMER3 :TIMER3 - * - CGU_PERIPHERAL_UART0 :UART0 - * - CGU_PERIPHERAL_UART1 :UART1 - * - CGU_PERIPHERAL_UART2 :UART2 - * - CGU_PERIPHERAL_UART3 :UART3 - * - CGU_PERIPHERAL_USB0 :USB0 - * - CGU_PERIPHERAL_USB1 :USB1 - * - CGU_PERIPHERAL_WWDT :WWDT - * @param[in] en status, should be: - * - ENABLE: Enable power - * - DISABLE: Disable power - * @return Configure status, could be: - * - CGU_ERROR_SUCCESS: successful - * - Other: error - **********************************************************************/ -uint32_t CGU_ConfigPWR(CGU_PERIPHERAL_T PPType, FunctionalState en) -{ - if (PPType >= CGU_PERIPHERAL_WWDT && PPType <= CGU_PERIPHERAL_ADC0) { - return CGU_ERROR_INVALID_PARAM; - } - - if (en == DISABLE) { /* Going to disable clock */ - /*Get Reg branch status */ - if (CGU_PERIPHERAL_Info[PPType].RegBranchOffset != 0 && - CGU_REG_BRANCH_STATUS(PPType) & 1) { - CGU_REG_BRANCH_CTRL(PPType) &= ~1; /* Disable branch clock */ - - while (CGU_REG_BRANCH_STATUS(PPType) & 1); - } - - /* GetBase Status*/ - if ((CGU_PERIPHERAL_Info[PPType].RegBaseEntity != CGU_ENTITY_NONE) && - CGU_GetBaseStatus((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity) == 0) { - /* Disable Base */ - CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity, 0); - } - - /* Same for Peripheral */ - if ((CGU_PERIPHERAL_Info[PPType].PerBranchOffset != 0) && (CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)) { - CGU_PER_BRANCH_CTRL(PPType) &= ~1; /* Disable branch clock */ - - while (CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK); - } - - /* GetBase Status*/ - if ((CGU_PERIPHERAL_Info[PPType].PerBaseEntity != CGU_ENTITY_NONE) && - CGU_GetBaseStatus((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity) == 0) { - /* Disable Base */ - CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity, 0); - } - - } else { - /* enable */ - /* GetBase Status*/ - if ((CGU_PERIPHERAL_Info[PPType].RegBaseEntity != CGU_ENTITY_NONE) && CGU_REG_BASE_CTRL(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK) { - /* Enable Base */ - CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity, 1); - } - - /*Get Reg branch status */ - if ((CGU_PERIPHERAL_Info[PPType].RegBranchOffset != 0) && !(CGU_REG_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)) { - CGU_REG_BRANCH_CTRL(PPType) |= 1; /* Enable branch clock */ - - while (!(CGU_REG_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)); - } - - /* Same for Peripheral */ - /* GetBase Status*/ - if ((CGU_PERIPHERAL_Info[PPType].PerBaseEntity != CGU_ENTITY_NONE) && - (CGU_PER_BASE_CTRL(PPType) & 1)) { - /* Enable Base */ - CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity, 1); - } - - /*Get Reg branch status */ - if ((CGU_PERIPHERAL_Info[PPType].PerBranchOffset != 0) && !(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)) { - CGU_PER_BRANCH_CTRL(PPType) |= 1; /* Enable branch clock */ - - while (!(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)); - } - } - - if (CGU_PERIPHERAL_Info[PPType].next) { - return CGU_ConfigPWR((CGU_PERIPHERAL_T)CGU_PERIPHERAL_Info[PPType].next, en); - } - - return CGU_ERROR_SUCCESS; -} - - -/*********************************************************************//** - * @brief Get peripheral clock frequency - * @param[in] Clock Peripheral type, should be: - * - CGU_PERIPHERAL_ADC0 :ADC0 - * - CGU_PERIPHERAL_ADC1 :ADC1 - * - CGU_PERIPHERAL_AES :AES - * - CGU_PERIPHERAL_APB1_BUS :APB1 bus - * - CGU_PERIPHERAL_APB3_BUS :APB3 bus - * - CGU_PERIPHERAL_CAN :CAN - * - CGU_PERIPHERAL_CREG :CREG - * - CGU_PERIPHERAL_DAC :DAC - * - CGU_PERIPHERAL_DMA :DMA - * - CGU_PERIPHERAL_EMC :EMC - * - CGU_PERIPHERAL_ETHERNET :ETHERNET - * - CGU_PERIPHERAL_GPIO :GPIO - * - CGU_PERIPHERAL_I2C0 :I2C0 - * - CGU_PERIPHERAL_I2C1 :I2C1 - * - CGU_PERIPHERAL_I2S :I2S - * - CGU_PERIPHERAL_LCD :LCD - * - CGU_PERIPHERAL_M3CORE :M3 core - * - CGU_PERIPHERAL_M3_BUS :M3 bus - * - CGU_PERIPHERAL_MOTOCON :Motor control - * - CGU_PERIPHERAL_QEI :QEI - * - CGU_PERIPHERAL_RITIMER :RIT timer - * - CGU_PERIPHERAL_SCT :SCT - * - CGU_PERIPHERAL_SCU :SCU - * - CGU_PERIPHERAL_SDIO :SDIO - * - CGU_PERIPHERAL_SPIFI :SPIFI - * - CGU_PERIPHERAL_SSP0 :SSP0 - * - CGU_PERIPHERAL_SSP1 :SSP1 - * - CGU_PERIPHERAL_TIMER0 :TIMER0 - * - CGU_PERIPHERAL_TIMER1 :TIMER1 - * - CGU_PERIPHERAL_TIMER2 :TIMER2 - * - CGU_PERIPHERAL_TIMER3 :TIMER3 - * - CGU_PERIPHERAL_UART0 :UART0 - * - CGU_PERIPHERAL_UART1 :UART1 - * - CGU_PERIPHERAL_UART2 :UART2 - * - CGU_PERIPHERAL_UART3 :UART3 - * - CGU_PERIPHERAL_USB0 :USB0 - * - CGU_PERIPHERAL_USB1 :USB1 - * - CGU_PERIPHERAL_WWDT :WWDT - * @return Return frequently value - **********************************************************************/ -uint32_t CGU_GetPCLKFrequency(CGU_PERIPHERAL_T Clock) -{ - uint32_t ClkSrc; - - if (Clock >= CGU_PERIPHERAL_WWDT && Clock <= CGU_PERIPHERAL_ADC0) { - return CGU_ERROR_INVALID_PARAM; - } - - if (CGU_PERIPHERAL_Info[Clock].PerBaseEntity != CGU_ENTITY_NONE) { - /* Get Base Clock Source */ - ClkSrc = (CGU_PER_BASE_CTRL(Clock) & CGU_CTRL_SRC_MASK) >> 24; - - /* GetBase Status*/ - if (CGU_PER_BASE_CTRL(Clock) & 1) { - return 0; - } - - /* check Branch if it is enabled */ - if ((CGU_PERIPHERAL_Info[Clock].PerBranchOffset != 0) && !(CGU_PER_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) { - return 0; - } - - } else { - if (CGU_REG_BASE_CTRL(Clock) & 1) { - return 0; - } - - ClkSrc = (CGU_REG_BASE_CTRL(Clock) & CGU_CTRL_SRC_MASK) >> 24; - - /* check Branch if it is enabled */ - if ((CGU_PERIPHERAL_Info[Clock].RegBranchOffset != 0) && !(CGU_REG_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) { - return 0; - } - } - - return CGU_ClockSourceFrequency[ClkSrc]; -} - - -/*********************************************************************//** - * @brief Update clock - * @param[in] None - * @return None - **********************************************************************/ -void CGU_UpdateClock(void) -{ - uint32_t ClkSrc; - uint32_t div; - uint32_t divisor; - int32_t RegOffset; - - /* 32OSC */ - if (ISBITSET(LPC_CREG->CREG0, 1) && ISBITCLR(LPC_CREG->CREG0, 3)) { - CGU_ClockSourceFrequency[CGU_CLKSRC_32KHZ_OSC] = 32768; - - } else { - CGU_ClockSourceFrequency[CGU_CLKSRC_32KHZ_OSC] = 0; - } - - /*PLL0*/ - /* PLL1 */ - if (ISBITCLR(LPC_CGU->PLL1_CTRL, 0) /* Enabled */ /* EA ANDLI: Original code tested bit 1 which is BYPASS, not PD */ - && (LPC_CGU->PLL1_STAT & 1)) { /* Locked? */ - ClkSrc = (LPC_CGU->PLL1_CTRL & CGU_CTRL_SRC_MASK) >> 24; - CGU_ClockSourceFrequency[CGU_CLKSRC_PLL1] = CGU_ClockSourceFrequency[ClkSrc] * - (((LPC_CGU->PLL1_CTRL >> 16) & 0xFF) + 1); - - } else { - CGU_ClockSourceFrequency[CGU_CLKSRC_PLL1] = 0; - } - - /* DIV */ - for (div = CGU_CLKSRC_IDIVA; div <= CGU_CLKSRC_IDIVE; div++) { - RegOffset = CGU_Entity_ControlReg_Offset[div]; - - if (ISBITCLR(CGU_ADDRESS32(LPC_CGU, RegOffset), 1)) { - ClkSrc = (CGU_ADDRESS32(LPC_CGU, RegOffset) & CGU_CTRL_SRC_MASK) >> 24; - divisor = (CGU_ADDRESS32(LPC_CGU, RegOffset) >> 2) & 0xFF; - divisor ++; - CGU_ClockSourceFrequency[div] = CGU_ClockSourceFrequency[ClkSrc] / divisor; - - } else { - CGU_ClockSourceFrequency[div] = 0; - } - } -} - -/*********************************************************************//** - * @brief Set XTAL oscillator value - * @param[in] ClockFrequency XTAL Frequency value - * @return Setting status, could be: - * - CGU_ERROR_SUCCESS: successful - * - CGU_ERROR_FREQ_OUTOF_RANGE: XTAL value set is out of range - **********************************************************************/ -uint32_t CGU_SetXTALOSC(uint32_t ClockFrequency) -{ - if (ClockFrequency < 15000000) { - LPC_CGU->XTAL_OSC_CTRL &= ~(1 << 2); - - } else if (ClockFrequency < 25000000) { - LPC_CGU->XTAL_OSC_CTRL |= (1 << 2); - - } else { - return CGU_ERROR_FREQ_OUTOF_RANGE; - } - - CGU_ClockSourceFrequency[CGU_CLKSRC_XTAL_OSC] = ClockFrequency; - return CGU_ERROR_SUCCESS; -} - - -/*********************************************************************//** - * @brief Set clock divider - * @param[in] SelectDivider Clock source, should be: - * - CGU_CLKSRC_IDIVA :Integer divider register A - * - CGU_CLKSRC_IDIVB :Integer divider register B - * - CGU_CLKSRC_IDIVC :Integer divider register C - * - CGU_CLKSRC_IDIVD :Integer divider register D - * - CGU_CLKSRC_IDIVE :Integer divider register E - * @param[in] divisor Divisor value, should be: 0..255 - * @return Setting status, could be: - * - CGU_ERROR_SUCCESS: successful - * - CGU_ERROR_INVALID_ENTITY: Invalid entity - **********************************************************************/ -/* divisor number must >=1*/ -uint32_t CGU_SetDIV(CGU_ENTITY_T SelectDivider, uint32_t divisor) -{ - int32_t RegOffset; - uint32_t tempReg; - - if (SelectDivider >= CGU_CLKSRC_IDIVA && SelectDivider <= CGU_CLKSRC_IDIVE) { - RegOffset = CGU_Entity_ControlReg_Offset[SelectDivider]; - - if (RegOffset == -1) { - return CGU_ERROR_INVALID_ENTITY; - } - - tempReg = CGU_ADDRESS32(LPC_CGU, RegOffset); - tempReg &= ~(0xFF << 2); - tempReg |= ((divisor - 1) & 0xFF) << 2; - CGU_ADDRESS32(LPC_CGU, RegOffset) = tempReg; - return CGU_ERROR_SUCCESS; - } - - return CGU_ERROR_INVALID_ENTITY; -} - -/*********************************************************************//** - * @brief Enable clock entity - * @param[in] ClockEntity Clock entity, should be: - * - CGU_CLKSRC_32KHZ_OSC :32Khz oscillator - * - CGU_CLKSRC_IRC :IRC clock - * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock - * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock - * - CGU_CLKSRC_GP_CLKIN :General purpose input clock - * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator - * - CGU_CLKSRC_PLL0 :PLL0 clock - * - CGU_CLKSRC_PLL1 :PLL1 clock - * - CGU_CLKSRC_IDIVA :Integer divider register A - * - CGU_CLKSRC_IDIVB :Integer divider register B - * - CGU_CLKSRC_IDIVC :Integer divider register C - * - CGU_CLKSRC_IDIVD :Integer divider register D - * - CGU_CLKSRC_IDIVE :Integer divider register E - * - CGU_BASE_SAFE :Base safe clock (always on)for WDT - * - CGU_BASE_USB0 :Base clock for USB0 - * - CGU_BASE_PERIPH :Base clock for Peripheral bus - * - CGU_BASE_USB1 :Base clock for USB1 - * - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core - * and APB peripheral blocks #0 and #2 - * - CGU_BASE_SPIFI :Base clock for SPIFI - * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx - * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx - * - CGU_BASE_APB1 :Base clock for APB peripheral block #1 - * - CGU_BASE_APB3 :Base clock for APB peripheral block #3 - * - CGU_BASE_LCD :Base clock for LCD - * - CGU_BASE_SDIO :Base clock for SDIO card reader - * - CGU_BASE_SSP0 :Base clock for SSP0 - * - CGU_BASE_SSP1 :Base clock for SSP1 - * - CGU_BASE_UART0 :Base clock for UART0 - * - CGU_BASE_UART1 :Base clock for UART1 - * - CGU_BASE_UART2 :Base clock for UART2 - * - CGU_BASE_UART3 :Base clock for UART3 - * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin - * @param[in] en status, should be: - * - ENABLE: Enable power - * - DISABLE: Disable power - * @return Setting status, could be: - * - CGU_ERROR_SUCCESS: successful - * - CGU_ERROR_INVALID_ENTITY: Invalid entity - **********************************************************************/ -uint32_t CGU_EnableEntity(CGU_ENTITY_T ClockEntity, uint32_t en) -{ - int32_t RegOffset; - int32_t i; - - if (ClockEntity == CGU_CLKSRC_32KHZ_OSC) { - if (en) { - LPC_CREG->CREG0 &= ~((1 << 3) | (1 << 2)); - LPC_CREG->CREG0 |= (1 << 1) | (1 << 0); - - } else { - LPC_CREG->CREG0 &= ~((1 << 1) | (1 << 0)); - LPC_CREG->CREG0 |= (1 << 3); - } - - for (i = 0; i < 1000000; i++); - - } else if (ClockEntity == CGU_CLKSRC_ENET_RX_CLK) { - scu_pinmux(0xC , 0 , MD_PLN, FUNC3); - - } else if (ClockEntity == CGU_CLKSRC_ENET_TX_CLK) { - scu_pinmux(0x1 , 19 , MD_PLN, FUNC0); - - } else if (ClockEntity == CGU_CLKSRC_GP_CLKIN) { - } else if (ClockEntity == CGU_CLKSRC_TCK) { - } else if (ClockEntity == CGU_CLKSRC_XTAL_OSC) { - if (!en) { - LPC_CGU->XTAL_OSC_CTRL |= CGU_CTRL_EN_MASK; - - } else { - LPC_CGU->XTAL_OSC_CTRL &= ~CGU_CTRL_EN_MASK; - } - - /*Delay for stable clock*/ - for (i = 0; i < 1000000; i++); - - } else { - RegOffset = CGU_Entity_ControlReg_Offset[ClockEntity]; - - if (RegOffset == -1) { - return CGU_ERROR_INVALID_ENTITY; - } - - if (!en) { - CGU_ADDRESS32(CGU_CGU_ADDR, RegOffset) |= CGU_CTRL_EN_MASK; - - } else { - CGU_ADDRESS32(CGU_CGU_ADDR, RegOffset) &= ~CGU_CTRL_EN_MASK; - - /*if PLL is selected check if it is locked */ - if (ClockEntity == CGU_CLKSRC_PLL0) { - while ((LPC_CGU->PLL0USB_STAT & 1) == 0x0); - } - - if (ClockEntity == CGU_CLKSRC_PLL0_AUDIO) { - while ((LPC_CGU->PLL0AUDIO_STAT & 1) == 0x0); - } - - if (ClockEntity == CGU_CLKSRC_PLL1) { - while ((LPC_CGU->PLL1_STAT & 1) == 0x0); - - /*post check lock status */ - if (!(LPC_CGU->PLL1_STAT & 1)) - while (1); - } - } - } - - return CGU_ERROR_SUCCESS; -} - -/*********************************************************************//** - * @brief Connect entity clock source - * @param[in] ClockSource Clock source, should be: - * - CGU_CLKSRC_32KHZ_OSC :32Khz oscillator - * - CGU_CLKSRC_IRC :IRC clock - * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock - * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock - * - CGU_CLKSRC_GP_CLKIN :General purpose input clock - * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator - * - CGU_CLKSRC_PLL0 :PLL0 clock - * - CGU_CLKSRC_PLL1 :PLL1 clock - * - CGU_CLKSRC_IDIVA :Integer divider register A - * - CGU_CLKSRC_IDIVB :Integer divider register B - * - CGU_CLKSRC_IDIVC :Integer divider register C - * - CGU_CLKSRC_IDIVD :Integer divider register D - * - CGU_CLKSRC_IDIVE :Integer divider register E - * @param[in] ClockEntity Clock entity, should be: - * - CGU_CLKSRC_PLL0 :PLL0 clock - * - CGU_CLKSRC_PLL1 :PLL1 clock - * - CGU_CLKSRC_IDIVA :Integer divider register A - * - CGU_CLKSRC_IDIVB :Integer divider register B - * - CGU_CLKSRC_IDIVC :Integer divider register C - * - CGU_CLKSRC_IDIVD :Integer divider register D - * - CGU_CLKSRC_IDIVE :Integer divider register E - * - CGU_BASE_SAFE :Base safe clock (always on)for WDT - * - CGU_BASE_USB0 :Base clock for USB0 - * - CGU_BASE_USB1 :Base clock for USB1 - * - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core - * and APB peripheral blocks #0 and #2 - * - CGU_BASE_SPIFI :Base clock for SPIFI - * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx - * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx - * - CGU_BASE_APB1 :Base clock for APB peripheral block #1 - * - CGU_BASE_APB3 :Base clock for APB peripheral block #3 - * - CGU_BASE_LCD :Base clock for LCD - * - CGU_BASE_SDIO :Base clock for SDIO card reader - * - CGU_BASE_SSP0 :Base clock for SSP0 - * - CGU_BASE_SSP1 :Base clock for SSP1 - * - CGU_BASE_UART0 :Base clock for UART0 - * - CGU_BASE_UART1 :Base clock for UART1 - * - CGU_BASE_UART2 :Base clock for UART2 - * - CGU_BASE_UART3 :Base clock for UART3 - * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin - * @return Setting status, could be: - * - CGU_ERROR_SUCCESS: successful - * - CGU_ERROR_CONNECT_TOGETHER: Error when 2 clock source connect together - * - CGU_ERROR_INVALID_CLOCK_SOURCE: Invalid clock source error - * - CGU_ERROR_INVALID_ENTITY: Invalid entity error - **********************************************************************/ -/* Connect one entity into clock source */ -uint32_t CGU_EntityConnect(CGU_ENTITY_T ClockSource, CGU_ENTITY_T ClockEntity) -{ - int32_t RegOffset; - uint32_t tempReg; - - if (ClockSource > CGU_CLKSRC_IDIVE) { - return CGU_ERROR_INVALID_CLOCK_SOURCE; - } - - if (ClockEntity >= CGU_CLKSRC_PLL0 && ClockEntity <= CGU_BASE_CLKOUT) { - if (CGU_ConnectAlloc_Tbl[ClockSource][ClockEntity]) { - RegOffset = CGU_Entity_ControlReg_Offset[ClockSource]; - - if (RegOffset != -1) { - if (ClockEntity <= CGU_CLKSRC_IDIVE && - ClockEntity >= CGU_CLKSRC_PLL0) { - //RegOffset = (CGU_ADDRESS32(LPC_CGU,RegOffset)>>24)&0xF; - if (((CGU_ADDRESS32(LPC_CGU, RegOffset) >> 24) & 0xF) == ClockEntity) { - return CGU_ERROR_CONNECT_TOGETHER; - } - } - } - - RegOffset = CGU_Entity_ControlReg_Offset[ClockEntity]; - - if (RegOffset == -1) { - return CGU_ERROR_INVALID_ENTITY; - } - - tempReg = CGU_ADDRESS32(LPC_CGU, RegOffset); - tempReg &= ~CGU_CTRL_SRC_MASK; - tempReg |= ClockSource << 24 | CGU_CTRL_AUTOBLOCK_MASK; - CGU_ADDRESS32(LPC_CGU, RegOffset) = tempReg; - return CGU_ERROR_SUCCESS; - - } else { - return CGU_ERROR_INVALID_CLOCK_SOURCE; - } - - } else { - return CGU_ERROR_INVALID_ENTITY; - } -} - - -/*********************************************************************//** - * @brief Get current USB PLL clock from XTAL - * @param[in] None - * @return Returned clock value - **********************************************************************/ -uint32_t CGU_SetPLL0(void) -{ - // Setup PLL550 to generate 480MHz from 12 MHz crystal - LPC_CGU->PLL0USB_CTRL |= 1; // Power down PLL - // P N - LPC_CGU->PLL0USB_NP_DIV = (98 << 0) | (514 << 12); - // SELP SELI SELR MDEC - LPC_CGU->PLL0USB_MDIV = (0xB << 17) | (0x10 << 22) | (0 << 28) | (0x7FFA << 0); - LPC_CGU->PLL0USB_CTRL = (CGU_CLKSRC_XTAL_OSC << 24) | (0x3 << 2) | (1 << 4); - return CGU_ERROR_SUCCESS; -} - - - -/*********************************************************************//** - * @brief Get current Audio PLL clock from XTAL - * @param[in] None - * @return Returned clock value - **********************************************************************/ -uint32_t CGU_SetPLL0audio(void) -{ - /* disable clock, disable skew enable, power down pll, - * (dis/en)able post divider, (dis/en)able pre-divider, - * disable free running mode, disable bandsel, - * enable up limmiter, disable bypass - */ - LPC_CGU->PLL0AUDIO_CTRL = (6 << 24) /* source = XTAL OSC 12 MHz */ - | _BIT(0); /* power down */ - /* PLL should be set to 512fs rate 512 * 48000 = 24576000 Hz */ - /* set mdec register */ -#if 1 // results from gcc program - LPC_CGU->PLL0AUDIO_MDIV = 0x23e34d3; - LPC_CGU->PLL0AUDIO_NP_DIV = 0x3f00e; - LPC_CGU->PLL0AUDIO_CTRL = (6 << 24) /* source = XTAL OSC 12 MHz */ - | (6 << 12) // fractional divider off and bypassed - | _BIT(4); /* CLKEN */ -#else - LPC_CGU->PLL0AUDIO_MDIV = (0 << 28) /* SELR */ - | (40 << 22) /* SELI */ - | (31 << 17) /* SELP */ - | 11372; /* MDEC */ - /* set ndec, pdec register */ - LPC_CGU->PLL0AUDIO_NP_DIV = (22 << 12) /* ndec */ - | (10); /* pdec */ - /* set fraction divider register. [21:15] = m, [14:0] = fractional value */ - LPC_CGU->PLL0AUDIO_FRAC = (86 << 15) | 0x1B7; - LPC_CGU->PLL0AUDIO_CTRL = (6 << 24) /* source = XTAL OSC 12 MHz */ - | _BIT(12) /* enable SD modulator to update mdec*/ - | _BIT(4); /* CLKEN */ -#endif - - /* wait for lock */ - while (!(LPC_CGU->PLL0AUDIO_STAT & 1)); - - return CGU_ERROR_SUCCESS; -} - - -/*********************************************************************//** - * @brief Setting PLL1 - * @param[in] mult Multiple value - * @return Setting status, could be: - * - CGU_ERROR_SUCCESS: successful - * - CGU_ERROR_INVALID_PARAM: Invalid parameter error - **********************************************************************/ -uint32_t CGU_SetPLL1(uint32_t mult) -{ - uint32_t msel = 0, nsel = 0, psel = 0, pval = 1; - uint32_t freq; - uint32_t ClkSrc = (LPC_CGU->PLL1_CTRL & CGU_CTRL_SRC_MASK) >> 24; - freq = CGU_ClockSourceFrequency[ClkSrc]; - freq *= mult; - msel = mult - 1; - LPC_CGU->PLL1_CTRL &= ~(CGU_PLL1_FBSEL_MASK | - CGU_PLL1_BYPASS_MASK | - CGU_PLL1_DIRECT_MASK | - (0x03 << 8) | (0xFF << 16) | (0x03 << 12)); - - if (freq < 156000000) { - //psel is encoded such that 0=1, 1=2, 2=4, 3=8 - while (2 * (pval)*freq < 156000000) { - psel++; - pval *= 2; - } - -// if(2*(pval)*freq > 320000000) { -// //THIS IS OUT OF RANGE!!! -// //HOW DO WE ASSERT IN SAMPLE CODE? -// //__breakpoint(0); -// return CGU_ERROR_INVALID_PARAM; -// } - LPC_CGU->PLL1_CTRL |= (msel << 16) | (nsel << 12) | (psel << 8) | CGU_PLL1_FBSEL_MASK; - - } else if (freq < 320000000) { - LPC_CGU->PLL1_CTRL |= (msel << 16) | (nsel << 12) | (psel << 8) | CGU_PLL1_DIRECT_MASK | CGU_PLL1_FBSEL_MASK; - - } else { - return CGU_ERROR_INVALID_PARAM; - } - - return CGU_ERROR_SUCCESS; -} - - -/*********************************************************************//** - * @brief Get current base status - * @param[in] Base Base type, should be: - * - CGU_BASE_USB0 :Base clock for USB0 - * - CGU_BASE_USB1 :Base clock for USB1 - * - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core - * and APB peripheral blocks #0 and #2 - * - CGU_BASE_SPIFI :Base clock for SPIFI - * - CGU_BASE_APB1 :Base clock for APB peripheral block #1 - * - CGU_BASE_APB3 :Base clock for APB peripheral block #3 - * - CGU_BASE_SDIO :Base clock for SDIO card reader - * - CGU_BASE_SSP0 :Base clock for SSP0 - * - CGU_BASE_SSP1 :Base clock for SSP1 - * - CGU_BASE_UART0 :Base clock for UART0 - * - CGU_BASE_UART1 :Base clock for UART1 - * - CGU_BASE_UART2 :Base clock for UART2 - * - CGU_BASE_UART3 :Base clock for UART3 - * @return Always return 0 - **********************************************************************/ -uint32_t CGU_GetBaseStatus(CGU_ENTITY_T Base) -{ - switch (Base) { - /*CCU1*/ - case CGU_BASE_APB3: - return LPC_CCU1->BASE_STAT & 1; - - case CGU_BASE_APB1: - return (LPC_CCU1->BASE_STAT >> 1) & 1; - - case CGU_BASE_SPIFI: - return (LPC_CCU1->BASE_STAT >> 2) & 1; - - case CGU_BASE_M4: - return (LPC_CCU1->BASE_STAT >> 3) & 1; - - case CGU_BASE_USB0: - return (LPC_CCU1->BASE_STAT >> 7) & 1; - - case CGU_BASE_USB1: - return (LPC_CCU1->BASE_STAT >> 8) & 1; - - /*CCU2*/ - case CGU_BASE_UART3: - return (LPC_CCU2->BASE_STAT >> 1) & 1; - - case CGU_BASE_UART2: - return (LPC_CCU2->BASE_STAT >> 2) & 1; - - case CGU_BASE_UART1: - return (LPC_CCU2->BASE_STAT >> 3) & 1; - - case CGU_BASE_UART0: - return (LPC_CCU2->BASE_STAT >> 4) & 1; - - case CGU_BASE_SSP1: - return (LPC_CCU2->BASE_STAT >> 5) & 1; - - case CGU_BASE_SSP0: - return (LPC_CCU2->BASE_STAT >> 6) & 1; - - case CGU_BASE_SDIO: - return (LPC_CCU2->BASE_STAT >> 7) & 1; - - /*BASE SAFE is used by WWDT and RGU*/ - case CGU_BASE_SAFE: - break; - - default: - break; - } - - return 0; -} - - -/*********************************************************************//** - * @brief Compare one source clock to IRC clock - * @param[in] Clock Clock entity that will be compared to IRC, should be: - * - CGU_CLKSRC_32KHZ_OSC :32Khz crystal oscillator - * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock - * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock - * - CGU_CLKSRC_GP_CLKIN :General purpose input clock - * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator - * - CGU_CLKSRC_PLL0 :PLL0 clock - * - CGU_CLKSRC_PLL1 :PLL1 clock - * - CGU_CLKSRC_IDIVA :Integer divider register A - * - CGU_CLKSRC_IDIVB :Integer divider register B - * - CGU_CLKSRC_IDIVC :Integer divider register C - * - CGU_CLKSRC_IDIVD :Integer divider register D - * - CGU_CLKSRC_IDIVE :Integer divider register E - * - CGU_BASE_SAFE :Base safe clock (always on)for WDT - * - CGU_BASE_USB0 :Base clock for USB0 - * - CGU_BASE_USB1 :Base clock for USB1 - * - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core - * and APB peripheral blocks #0 and #2 - * - CGU_BASE_SPIFI :Base clock for SPIFI - * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx - * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx - * - CGU_BASE_APB1 :Base clock for APB peripheral block #1 - * - CGU_BASE_APB3 :Base clock for APB peripheral block #3 - * - CGU_BASE_LCD :Base clock for LCD - * - CGU_BASE_SDIO :Base clock for SDIO card reader - * - CGU_BASE_SSP0 :Base clock for SSP0 - * - CGU_BASE_SSP1 :Base clock for SSP1 - * - CGU_BASE_UART0 :Base clock for UART0 - * - CGU_BASE_UART1 :Base clock for UART1 - * - CGU_BASE_UART2 :Base clock for UART2 - * - CGU_BASE_UART3 :Base clock for UART3 - * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin - * @param[in] m Multiple value pointer - * @param[in] d Divider value pointer - * @return Compare status, could be: - * - (-1): fail - * - 0: successful - * @note Formula used to compare: - * FClock = F_IRC* m / d - **********************************************************************/ -int CGU_FrequencyMonitor(CGU_ENTITY_T Clock, uint32_t *m, uint32_t *d) -{ - uint32_t n, c, temp; - int i; - /* Maximum allow RCOUNT number */ - c = 511; - /* Check Source Clock Freq is larger or smaller */ - LPC_CGU->FREQ_MON = (Clock << 24) | 1 << 23 | c; - - while (LPC_CGU->FREQ_MON & (1 << 23)); - - for (i = 0; i < 10000; i++); - - temp = (LPC_CGU->FREQ_MON >> 9) & 0x3FFF; - - if (temp == 0) { /* too low F < 12000000/511*/ - return -1; - } - - if (temp > 511) { /* larger */ - c = 511 - (LPC_CGU->FREQ_MON & 0x1FF); - - } else { - do { - c--; - LPC_CGU->FREQ_MON = (Clock << 24) | 1 << 23 | c; - - while (LPC_CGU->FREQ_MON & (1 << 23)); - - for (i = 0; i < 10000; i++); - - n = (LPC_CGU->FREQ_MON >> 9) & 0x3FFF; - } while (n == temp); - - c++; - } - - *m = temp; - *d = c; - return 0; -} - -/*********************************************************************//** - * @brief Compare one source clock to another source clock - * @param[in] Clock Clock entity that will be compared to second source, should be: - * - CGU_CLKSRC_32KHZ_OSC :32Khz crystal oscillator - * - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock - * - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock - * - CGU_CLKSRC_GP_CLKIN :General purpose input clock - * - CGU_CLKSRC_XTAL_OSC :Crystal oscillator - * - CGU_CLKSRC_PLL0 :PLL0 clock - * - CGU_CLKSRC_PLL1 :PLL1 clock - * - CGU_CLKSRC_IDIVA :Integer divider register A - * - CGU_CLKSRC_IDIVB :Integer divider register B - * - CGU_CLKSRC_IDIVC :Integer divider register C - * - CGU_CLKSRC_IDIVD :Integer divider register D - * - CGU_CLKSRC_IDIVE :Integer divider register E - * - CGU_BASE_SAFE :Base safe clock (always on)for WDT - * - CGU_BASE_USB0 :Base clock for USB0 - * - CGU_BASE_USB1 :Base clock for USB1 - * - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core - * and APB peripheral blocks #0 and #2 - * - CGU_BASE_SPIFI :Base clock for SPIFI - * - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx - * - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx - * - CGU_BASE_APB1 :Base clock for APB peripheral block #1 - * - CGU_BASE_APB3 :Base clock for APB peripheral block #3 - * - CGU_BASE_LCD :Base clock for LCD - * - CGU_BASE_SDIO :Base clock for SDIO card reader - * - CGU_BASE_SSP0 :Base clock for SSP0 - * - CGU_BASE_SSP1 :Base clock for SSP1 - * - CGU_BASE_UART0 :Base clock for UART0 - * - CGU_BASE_UART1 :Base clock for UART1 - * - CGU_BASE_UART2 :Base clock for UART2 - * - CGU_BASE_UART3 :Base clock for UART3 - * - CGU_BASE_CLKOUT :Base clock for CLKOUT pin - * @param[in] CompareToClock Clock source that to be compared to first source, should be different - * to first source. - * @param[in] m Multiple value pointer - * @param[in] d Divider value pointer - * @return Compare status, could be: - * - (-1): fail - * - 0: successful - * @note Formula used to compare: - * FClock = m*FCompareToClock/d - **********************************************************************/ -uint32_t CGU_RealFrequencyCompare(CGU_ENTITY_T Clock, CGU_ENTITY_T CompareToClock, uint32_t *m, uint32_t *d) -{ - uint32_t m1, m2, d1, d2; - - /* Check Parameter */ - if ((Clock > CGU_CLKSRC_IDIVE) || (CompareToClock > CGU_CLKSRC_IDIVE)) { - return CGU_ERROR_INVALID_PARAM; - } - - /* Check for Clock Enable - Not yet implement - * The Comparator will hang if Clock has not been set*/ - CGU_FrequencyMonitor(Clock, &m1, &d1); - CGU_FrequencyMonitor(CompareToClock, &m2, &d2); - *m = m1 * d2; - *d = d1 * m2; - return 0; -} - diff --git a/source/hic_hal/nxp/lpc4322/lpc43xx_cgu.h b/source/hic_hal/nxp/lpc4322/lpc43xx_cgu.h deleted file mode 100644 index 8857777d7a..0000000000 --- a/source/hic_hal/nxp/lpc4322/lpc43xx_cgu.h +++ /dev/null @@ -1,265 +0,0 @@ -/** - * @file lpc43xx_cgu.h - * @brief - * - * DAPLink Interface Firmware - * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Peripheral group ----------------------------------------------------------- */ -/** @defgroup CGU CGU (Clock Generation Unit) - * @ingroup LPC4300CMSIS_FwLib_Drivers - * @{ - */ - -#ifndef lpc43xx_CGU_H_ -#define lpc43xx_CGU_H_ - -/* Includes ------------------------------------------------------------------- */ -#include "LPC43xx.h" -#include "lpc_types.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Private Macros -------------------------------------------------------------- */ -/** @defgroup CGU_Private_Macros CGU Private Macros - * @{ - */ - -/** Branch clocks from CGU_BASE_SAFE */ -#define CGU_ENTITY_NONE CGU_ENTITY_NUM - -/** Check bit at specific position is clear or not */ -#define ISBITCLR(x,bit) ((x&(1<BASE_UART0_CLK & ~(0x0F << 24); // clear CLK_SEL. + LPC_CGU->BASE_UART0_CLK = tmp + | (0x01 << 11) // AUTOBLOCK: 0=Disabled, 1=Enabled. + | (0x09 << 24) // CLK_SEL = PLL1. + ; + + LPC_CGU->BASE_UART0_CLK &= ~1; // PD: 0=Power Up. + scu_pinmux(2, 0, UART_RX_TX, FUNC1); /* P2_0: U0_TXD */ scu_pinmux(2, 1, UART_RX_TX, FUNC1); /* P2_1: U0_RXD */