From 0c0a42b4f872dd43cd782f9066f0aeb11dc0df1b Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 4 Mar 2013 18:00:07 +0000 Subject: LPC1788 updates -- OS test configuration now works git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5704 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/arm/src/lpc17xx/lpc178x_clockconfig.c | 233 +++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 nuttx/arch/arm/src/lpc17xx/lpc178x_clockconfig.c (limited to 'nuttx/arch/arm/src/lpc17xx/lpc178x_clockconfig.c') diff --git a/nuttx/arch/arm/src/lpc17xx/lpc178x_clockconfig.c b/nuttx/arch/arm/src/lpc17xx/lpc178x_clockconfig.c new file mode 100644 index 000000000..948c17d7f --- /dev/null +++ b/nuttx/arch/arm/src/lpc17xx/lpc178x_clockconfig.c @@ -0,0 +1,233 @@ +/**************************************************************************** + * arch/arm/src/lpc17xx/lpc17_clockconfig.c + * arch/arm/src/chip/lpc17_clockconfig.c + * + * Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "lpc17_clockconfig.h" +#include "chip/lpc17_syscon.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef LPC178x +# error "The logic in this file applies only to the LPC178x family" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/************************************************************************************ + * Name: lpc17_clockconfig + * + * Description: + * Called to initialize the LPC17xx. This does whatever setup is needed to put the + * SoC in a usable state. This includes the initialization of clocking using the + * settings in board.h. + * + * The LPC176x and LPC178x system control block is *nearly* identical but we have + * found that the LPC178x is more sensitive to the ordering of certain operations. + * So, although the hardware seems very similar, the safer thing to do is to + * separate the LPC176x and LPC178x into separate files. + * + ************************************************************************************/ + +void lpc17_clockconfig(void) +{ + /* TODO: + * + * (1) "Make sure that the PLL output is not already being used. The CCLKSEL, + * USBCLKSEL, and SPIFICLKSEL registers must not select the PLL being set up. + * Clock dividers included in these registers may also be set up at this time + * if writing to any of the noted registers." + * + * (2) "If the main PLL is being set up, and the main clock source is being changed + * (IRC versus main oscillator), change this first by writing the correct + * value to the CLKSRCSEL register." + * + * This is not an issue now because we only setup the clocks on power up, so the + * PLL cannot be the select source. However, this could be an issue at some point + * later when, for example, we may want to implement reduced power mode with other + * clocking. + */ + + /* Enable the main oscillator (or not) and the frequency range of the main oscillator */ + + putreg32(BOARD_SCS_VALUE, LPC17_SYSCON_SCS); + + /* Wait for the main oscillator to be ready. */ + +#ifdef CONFIG_LPC17_MAINOSC + while ((getreg32(LPC17_SYSCON_SCS) & SYSCON_SCS_OSCSTAT) == 0); +#endif + + /* PLL0 is used to generate the CPU clock divider input (PLLCLK). */ + +#ifdef CONFIG_LPC17_PLL0 + /* (3) "Write PLL new setup values to the PLLCFG register. Write a 1 to the + * PLLE bit in the PLLCON register. Perform a PLL feed sequence by writing + * first the value 0xAA, then the value 0x55 to the PLLFEED register" + * + * Select the PLL0 source clock, multiplier, and pre-divider values. NOTE that + * a special "feed" sequence must be written to the PLL0FEED register in order + * for changes to the PLL0CFG register to take effect. + */ + + putreg32(BOARD_CLKSRCSEL_VALUE, LPC17_SYSCON_CLKSRCSEL); + putreg32(BOARD_PLL0CFG_VALUE, LPC17_SYSCON_PLL0CFG); + putreg32(SYSCON_PLLCON_PLLE, LPC17_SYSCON_PLL0CON); + + /* Enable the PLL. NOTE that a special "feed" sequence must be written to the + * PLL0FEED register in order for changes to the PLL0CON register to take effect. + */ + + putreg32(0xaa, LPC17_SYSCON_PLL0FEED); + putreg32(0x55, LPC17_SYSCON_PLL0FEED); + + /* (4) "Set up the necessary clock dividers. These may include the CCLKSEL, + * PCLKSEL, EMCCLKSEL, USBCLKSEL, and the SPIFICLKSEL registers. + */ + + putreg32(BOARD_CCLKSEL_VALUE, LPC17_SYSCON_CCLKSEL); + putreg32(BOARD_PCLKDIV, LPC17_SYSCON_PCLKSEL); + +#ifdef CONFIG_LPC17_EMC + putreg32(BOARD_EMCCLKSEL_VALUE, LPC17_SYSCON_EMCCLKSEL); +#endif +#if defined(CONFIG_LPC17_USBDEV) || defined(CONFIG_LPC17_USBHOST) + putreg32(BOARD_USBCLKSEL_VALUE, LPC17_SYSCON_USBCLKSEL); +#endif +#ifdef CONFIG_LPC17_SPIFI + putreg32(BOARD_SPIFICLKSEL_VALUE, LPC17_SPIFICLKSEL_CCLKSEL); +#endif + + /* (5) "Wait for the PLL to lock. This may be accomplished by polling the + * PLLSTAT register and testing for PLOCK = 1, or by using the PLL lock + * interrupt.Wait for PLL0 to lock. + */ + + while ((getreg32(LPC17_SYSCON_PLL0STAT) & SYSCON_PLL0STAT_PLOCK) == 0); + + /* (6) "Connect the PLL by selecting its output in the appropriate places. This + * may include the CCLKSEL, USBCLKSEL, and SPIFICLKSEL registers. + */ + +#endif /* CONFIG_LPC17_PLL0 */ + + /* PLL1 receives its clock input from the main oscillator only and can be used to + * provide a fixed 48 MHz clock only to the USB subsystem (if that clock cannot be + * obtained from PLL0). + */ + +#ifdef CONFIG_LPC17_PLL1 + /* (3) "Write PLL new setup values to the PLLCFG register. Write a 1 to the + * PLLE bit in the PLLCON register. Perform a PLL feed sequence by writing + * first the value 0xAA, then the value 0x55 to the PLLFEED register" + * + * Select the PLL1 multiplier, and pre-divider values. NOTE that a special "feed" + * sequence must be written to the PLL1FEED register in order for changes to the + * PLL1CFG register to take effect. + */ + + putreg32(BOARD_PLL1CFG_VALUE, LPC17_SYSCON_PLL1CFG); + putreg32(SYSCON_PLLCON_PLLE, LPC17_SYSCON_PLL1CON); + + /* Enable the PLL. NOTE that a special "feed" sequence must be written to the + * PLL1FEED register in order for changes to the PLL1CON register to take effect. + */ + + putreg32(0xaa, LPC17_SYSCON_PLL1FEED); + putreg32(0x55, LPC17_SYSCON_PLL1FEED); + + /* (4) "Set up the necessary clock dividers. These may include the CCLKSEL, + * PCLKSEL, EMCCLKSEL, USBCLKSEL, and the SPIFICLKSEL registers. + */ + + /* (5) "Wait for the PLL to lock. This may be accomplished by polling the + * PLLSTAT register and testing for PLOCK = 1, or by using the PLL lock + * interrupt.Wait for PLL0 to lock. + */ + + while ((getreg32(LPC17_SYSCON_PLL1STAT) & SYSCON_PLL1STAT_PLOCK) == 0); + + /* (6) "Connect the PLL by selecting its output in the appropriate places. This + * may include the CCLKSEL, USBCLKSEL, and SPIFICLKSEL registers. + */ + +#endif /* CONFIG_LPC17_PLL1 */ + + /* Disable power to all peripherals (execpt GPIO). Peripherals must be re-powered + * one at a time by each device driver when the driver is initialized. + */ + + putreg32(SYSCON_PCONP_PCGPIO, LPC17_SYSCON_PCONP); + + /* Disable CLKOUT */ + + putreg32(0, LPC17_SYSCON_CLKOUTCFG); + + /* Configure FLASH */ + +#ifdef CONFIG_LPC17_FLASH + putreg32(BOARD_FLASHCFG_VALUE, LPC17_SYSCON_FLASHCFG); +#endif +} + -- cgit v1.2.3