summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c')
-rw-r--r--c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c533
1 files changed, 0 insertions, 533 deletions
diff --git a/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c
deleted file mode 100644
index 6ceb066935..0000000000
--- a/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/**
- * @file
- *
- * @ingroup lpc24xx
- *
- * @brief Startup code.
- */
-
-/*
- * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <bsp.h>
-#include <bsp/io.h>
-#include <bsp/start.h>
-#include <bsp/lpc24xx.h>
-#include <bsp/lpc-emc.h>
-#include <bsp/start-config.h>
-
-static BSP_START_TEXT_SECTION void lpc24xx_cpu_delay(unsigned ticks)
-{
- unsigned i = 0;
-
- /* One loop execution needs four instructions */
- ticks /= 4;
-
- for (i = 0; i <= ticks; ++i) {
- __asm__ volatile ("nop");
- }
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_udelay(unsigned us)
-{
- lpc24xx_cpu_delay(us * (LPC24XX_CCLK / 1000000));
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_pinsel(void)
-{
- lpc24xx_pin_config(
- &lpc24xx_start_config_pinsel [0],
- LPC24XX_PIN_SET_FUNCTION
- );
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_emc_static(void)
-{
- size_t i = 0;
- size_t chip_count = lpc24xx_start_config_emc_static_chip_count;
-
- for (i = 0; i < chip_count; ++i) {
- const lpc24xx_emc_static_chip_config *chip_config =
- &lpc24xx_start_config_emc_static_chip [i];
- lpc24xx_emc_static_chip_config chip_config_on_stack;
- size_t config_size = sizeof(chip_config_on_stack.config);
-
- bsp_start_memcpy(
- (int *) &chip_config_on_stack.config,
- (const int *) &chip_config->config,
- config_size
- );
- bsp_start_memcpy(
- (int *) chip_config->chip_select,
- (const int *) &chip_config_on_stack.config,
- config_size
- );
- }
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_emc_dynamic(void)
-{
- size_t chip_count = lpc24xx_start_config_emc_dynamic_chip_count;
-
- if (chip_count > 0) {
- bool do_initialization = true;
- size_t i = 0;
-
- for (i = 0; do_initialization && i < chip_count; ++i) {
- const lpc24xx_emc_dynamic_chip_config *chip_cfg =
- &lpc24xx_start_config_emc_dynamic_chip [i];
- volatile lpc_emc_dynamic *chip_select = chip_cfg->chip_select;
-
- do_initialization = (chip_select->config & EMC_DYN_CFG_B) == 0;
- }
-
- if (do_initialization) {
- volatile lpc_emc *emc = (volatile lpc_emc *) EMC_BASE_ADDR;
- const lpc24xx_emc_dynamic_config *cfg =
- &lpc24xx_start_config_emc_dynamic [0];
- uint32_t dynamiccontrol = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS;
-
- #ifdef ARM_MULTILIB_ARCH_V7M
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
-
- /* Delay control */
- scb->emcdlyctl = cfg->emcdlyctl;
- #endif
-
- emc->dynamicreadconfig = cfg->readconfig;
-
- /* Timings */
- emc->dynamictrp = cfg->trp;
- emc->dynamictras = cfg->tras;
- emc->dynamictsrex = cfg->tsrex;
- emc->dynamictapr = cfg->tapr;
- emc->dynamictdal = cfg->tdal;
- emc->dynamictwr = cfg->twr;
- emc->dynamictrc = cfg->trc;
- emc->dynamictrfc = cfg->trfc;
- emc->dynamictxsr = cfg->txsr;
- emc->dynamictrrd = cfg->trrd;
- emc->dynamictmrd = cfg->tmrd;
-
- /* NOP period */
- emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_NOP;
- lpc24xx_udelay(200);
-
- /* Precharge */
- emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_PALL;
- emc->dynamicrefresh = 1;
-
- /*
- * Perform several refresh cycles with a memory refresh every 16 AHB
- * clock cycles. Wait until eight SDRAM refresh cycles have occurred
- * (128 AHB clock cycles).
- */
- lpc24xx_cpu_delay(128);
-
- /* Refresh timing */
- emc->dynamicrefresh = cfg->refresh;
- lpc24xx_cpu_delay(128);
-
- for (i = 0; i < chip_count; ++i) {
- const lpc24xx_emc_dynamic_chip_config *chip_cfg =
- &lpc24xx_start_config_emc_dynamic_chip [i];
- volatile lpc_emc_dynamic *chip_select = chip_cfg->chip_select;
- uint32_t config = chip_cfg->config;
-
- /* Chip select */
- chip_select->config = config;
- chip_select->rascas = chip_cfg->rascas;
-
- /* Set modes */
- emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_MODE;
- *(volatile uint32_t *)(chip_cfg->address + chip_cfg->mode);
-
- /* Enable buffer */
- chip_select->config = config | EMC_DYN_CFG_B;
- }
-
- emc->dynamiccontrol = 0;
- }
- }
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_main_oscillator(void)
-{
- #ifdef ARM_MULTILIB_ARCH_V4
- if ((SCS & 0x40) == 0) {
- SCS |= 0x20;
- while ((SCS & 0x40) == 0) {
- /* Wait */
- }
- }
- #else
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
-
- if ((scb->scs & LPC17XX_SCB_SCS_OSC_STATUS) == 0) {
- scb->scs |= LPC17XX_SCB_SCS_OSC_ENABLE;
- while ((scb->scs & LPC17XX_SCB_SCS_OSC_STATUS) == 0) {
- /* Wait */
- }
- }
- #endif
-}
-
-#ifdef ARM_MULTILIB_ARCH_V4
-
-static BSP_START_TEXT_SECTION void lpc24xx_pll_config(
- uint32_t val
-)
-{
- PLLCON = val;
- PLLFEED = 0xaa;
- PLLFEED = 0x55;
-}
-
-/**
- * @brief Sets the Phase Locked Loop (PLL).
- *
- * All parameter values are the actual register field values.
- *
- * @param clksrc Selects the clock source for the PLL.
- *
- * @param nsel Selects PLL pre-divider value (sometimes named psel).
- *
- * @param msel Selects PLL multiplier value.
- *
- * @param cclksel Selects the divide value for creating the CPU clock (CCLK)
- * from the PLL output.
- */
-static BSP_START_TEXT_SECTION void lpc24xx_set_pll(
- unsigned clksrc,
- unsigned nsel,
- unsigned msel,
- unsigned cclksel
-)
-{
- uint32_t pllstat = PLLSTAT;
- uint32_t pllcfg = SET_PLLCFG_NSEL(0, nsel) | SET_PLLCFG_MSEL(0, msel);
- uint32_t clksrcsel = SET_CLKSRCSEL_CLKSRC(0, clksrc);
- uint32_t cclkcfg = SET_CCLKCFG_CCLKSEL(0, cclksel | 1);
- bool pll_enabled = (pllstat & PLLSTAT_PLLE) != 0;
-
- /* Disconnect PLL if necessary */
- if ((pllstat & PLLSTAT_PLLC) != 0) {
- if (pll_enabled) {
- /* Check if we run already with the desired settings */
- if (PLLCFG == pllcfg && CLKSRCSEL == clksrcsel && CCLKCFG == cclkcfg) {
- /* Nothing to do */
- return;
- }
- lpc24xx_pll_config(PLLCON_PLLE);
- } else {
- lpc24xx_pll_config(0);
- }
- }
-
- /* Set CPU clock divider to a reasonable save value */
- CCLKCFG = 0;
-
- /* Disable PLL if necessary */
- if (pll_enabled) {
- lpc24xx_pll_config(0);
- }
-
- /* Select clock source */
- CLKSRCSEL = clksrcsel;
-
- /* Set PLL Configuration Register */
- PLLCFG = pllcfg;
-
- /* Enable PLL */
- lpc24xx_pll_config(PLLCON_PLLE);
-
- /* Wait for lock */
- while ((PLLSTAT & PLLSTAT_PLOCK) == 0) {
- /* Wait */
- }
-
- /* Set CPU clock divider and ensure that we have an odd value */
- CCLKCFG = cclkcfg;
-
- /* Connect PLL */
- lpc24xx_pll_config(PLLCON_PLLE | PLLCON_PLLC);
-}
-
-#else /* ARM_MULTILIB_ARCH_V4 */
-
-static BSP_START_TEXT_SECTION void lpc17xx_pll_config(
- volatile lpc17xx_pll *pll,
- uint32_t val
-)
-{
- pll->con = val;
- pll->feed = 0xaa;
- pll->feed = 0x55;
-}
-
-static BSP_START_TEXT_SECTION void lpc17xx_set_pll(
- unsigned msel,
- unsigned psel,
- unsigned cclkdiv
-)
-{
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
- volatile lpc17xx_pll *pll = &scb->pll_0;
- uint32_t pllcfg = LPC17XX_PLL_SEL_MSEL(msel)
- | LPC17XX_PLL_SEL_PSEL(psel);
- uint32_t pllstat = LPC17XX_PLL_STAT_PLLE
- | LPC17XX_PLL_STAT_PLOCK | pllcfg;
- uint32_t cclksel_cclkdiv = LPC17XX_SCB_CCLKSEL_CCLKDIV(cclkdiv);
- uint32_t cclksel = LPC17XX_SCB_CCLKSEL_CCLKSEL | cclksel_cclkdiv;
-
- if (
- pll->stat != pllstat
- || scb->cclksel != cclksel
- || scb->clksrcsel != LPC17XX_SCB_CLKSRCSEL_CLKSRC
- ) {
- /* Use SYSCLK for CCLK */
- scb->cclksel = LPC17XX_SCB_CCLKSEL_CCLKDIV(1);
-
- /* Turn off USB */
- scb->usbclksel = 0;
-
- /* Disable PLL */
- lpc17xx_pll_config(pll, 0);
-
- /* Select main oscillator as clock source */
- scb->clksrcsel = LPC17XX_SCB_CLKSRCSEL_CLKSRC;
-
- /* Set PLL configuration */
- pll->cfg = pllcfg;
-
- /* Set the CCLK, PCLK and EMCCLK divider */
- scb->cclksel = cclksel_cclkdiv;
- scb->pclksel = LPC17XX_SCB_PCLKSEL_PCLKDIV(cclkdiv * LPC24XX_PCLKDIV);
- scb->emcclksel = LPC24XX_EMCCLKDIV == 1 ? 0 : LPC17XX_SCB_EMCCLKSEL_EMCDIV;
-
- /* Enable PLL */
- lpc17xx_pll_config(pll, LPC17XX_PLL_CON_PLLE);
-
- /* Wait for lock */
- while ((pll->stat & LPC17XX_PLL_STAT_PLOCK) == 0) {
- /* Wait */
- }
-
- /* Use the PLL clock */
- scb->cclksel = cclksel;
- }
-}
-
-#endif /* ARM_MULTILIB_ARCH_V4 */
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_pll(void)
-{
- #ifdef ARM_MULTILIB_ARCH_V4
- #if LPC24XX_OSCILLATOR_MAIN == 12000000U
- #if LPC24XX_CCLK == 72000000U
- lpc24xx_set_pll(1, 0, 11, 3);
- #elif LPC24XX_CCLK == 51612800U
- lpc24xx_set_pll(1, 30, 399, 5);
- #else
- #error "unexpected CCLK"
- #endif
- #elif LPC24XX_OSCILLATOR_MAIN == 3686400U
- #if LPC24XX_CCLK == 58982400U
- lpc24xx_set_pll(1, 0, 47, 5);
- #else
- #error "unexpected CCLK"
- #endif
- #else
- #error "unexpected main oscillator frequency"
- #endif
- #else
- #if LPC24XX_OSCILLATOR_MAIN == 12000000U
- #if LPC24XX_CCLK == 120000000U
- lpc17xx_set_pll(9, 0, 1);
- #elif LPC24XX_CCLK == 96000000U
- lpc17xx_set_pll(7, 0, 1);
- #elif LPC24XX_CCLK == 72000000U
- lpc17xx_set_pll(5, 1, 1);
- #elif LPC24XX_CCLK == 48000000U
- lpc17xx_set_pll(3, 1, 1);
- #else
- #error "unexpected CCLK"
- #endif
- #else
- #error "unexpected main oscillator frequency"
- #endif
- #endif
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_memory_map(void)
-{
- #ifdef ARM_MULTILIB_ARCH_V4
- /* Re-map interrupt vectors to internal RAM */
- MEMMAP = SET_MEMMAP_MAP(MEMMAP, 2);
- #else
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
-
- scb->memmap = LPC17XX_SCB_MEMMAP_MAP;
- #endif
-
- /* Use normal memory map */
- EMC_CTRL &= ~0x2U;
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_memory_accelerator(void)
-{
- #ifdef ARM_MULTILIB_ARCH_V4
- /* Fully enable memory accelerator module functions (MAM) */
- MAMCR = 0;
- #if LPC24XX_CCLK <= 20000000U
- MAMTIM = 0x1;
- #elif LPC24XX_CCLK <= 40000000U
- MAMTIM = 0x2;
- #elif LPC24XX_CCLK <= 60000000U
- MAMTIM = 0x3;
- #else
- MAMTIM = 0x4;
- #endif
- MAMCR = 0x2;
-
- /* Enable fast IO for ports 0 and 1 */
- SCS |= 0x1;
- #else
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
-
- #if LPC24XX_CCLK <= 20000000U
- scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x0);
- #elif LPC24XX_CCLK <= 40000000U
- scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x1);
- #elif LPC24XX_CCLK <= 60000000U
- scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x2);
- #elif LPC24XX_CCLK <= 80000000U
- scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x3);
- #elif LPC24XX_CCLK <= 100000000U
- scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x4);
- #else
- scb->flashcfg = LPC17XX_SCB_FLASHCFG_FLASHTIM(0x5);
- #endif
- #endif
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_stop_gpdma(void)
-{
- #ifdef LPC24XX_STOP_GPDMA
- #ifdef ARM_MULTILIB_ARCH_V4
- bool has_power = (PCONP & PCONP_GPDMA) != 0;
- #else
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
- bool has_power = (scb->pconp & LPC17XX_SCB_PCONP_GPDMA) != 0;
- #endif
-
- if (has_power) {
- GPDMA_CONFIG = 0;
-
- #ifdef ARM_MULTILIB_ARCH_V4
- PCONP &= ~PCONP_GPDMA;
- #else
- scb->pconp &= ~LPC17XX_SCB_PCONP_GPDMA;
- #endif
- }
- #endif
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_stop_ethernet(void)
-{
- #ifdef LPC24XX_STOP_ETHERNET
- #ifdef ARM_MULTILIB_ARCH_V4
- bool has_power = (PCONP & PCONP_ETHERNET) != 0;
- #else
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
- bool has_power = (scb->pconp & LPC17XX_SCB_PCONP_ENET) != 0;
- #endif
-
- if (has_power) {
- MAC_COMMAND = 0x38;
- MAC_MAC1 = 0xcf00;
- MAC_MAC1 = 0;
-
- #ifdef ARM_MULTILIB_ARCH_V4
- PCONP &= ~PCONP_ETHERNET;
- #else
- scb->pconp &= ~LPC17XX_SCB_PCONP_ENET;
- #endif
- }
- #endif
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_stop_usb(void)
-{
- #ifdef LPC24XX_STOP_USB
- #ifdef ARM_MULTILIB_ARCH_V4
- bool has_power = (PCONP & PCONP_USB) != 0;
- #else
- volatile lpc17xx_scb *scb = &LPC17XX_SCB;
- bool has_power = (scb->pconp & LPC17XX_SCB_PCONP_USB) != 0;
- #endif
-
- if (has_power) {
- OTG_CLK_CTRL = 0;
-
- #ifdef ARM_MULTILIB_ARCH_V4
- PCONP &= ~PCONP_USB;
- #else
- scb->pconp &= ~LPC17XX_SCB_PCONP_USB;
- scb->usbclksel = 0;
- #endif
- }
- #endif
-}
-
-static BSP_START_TEXT_SECTION void lpc24xx_init_mpu(void)
-{
- #ifdef ARM_MULTILIB_ARCH_V7M
- volatile ARMV7M_MPU *mpu = _ARMV7M_MPU;
- size_t region_count = lpc24xx_start_config_mpu_region_count;
- size_t i = 0;
-
- for (i = 0; i < region_count; ++i) {
- mpu->rbar = lpc24xx_start_config_mpu_region [i].rbar;
- mpu->rasr = lpc24xx_start_config_mpu_region [i].rasr;
- }
-
- if (region_count > 0) {
- mpu->ctrl = ARMV7M_MPU_CTRL_ENABLE;
- }
- #endif
-}
-
-BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
-{
- lpc24xx_init_main_oscillator();
- lpc24xx_init_pll();
- lpc24xx_init_pinsel();
- lpc24xx_init_emc_static();
-}
-
-BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
-{
- lpc24xx_init_memory_map();
- lpc24xx_init_memory_accelerator();
- lpc24xx_init_emc_dynamic();
- lpc24xx_init_mpu();
- lpc24xx_stop_gpdma();
- lpc24xx_stop_ethernet();
- lpc24xx_stop_usb();
- bsp_start_copy_sections();
- bsp_start_clear_bss();
-
- /* At this point we can use objects outside the .start section */
-}