From d74ed4ad4bde98dda6b685515b2523539e04ea1f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 19 May 2011 12:30:00 +0000 Subject: 2011-05-19 Sebastian Huber * i2c/i2c-config.c: New file. * include/lcd.h: Removed EMC definitions. * misc/dma.c: Fixed initialization. * include/i2c.h, include/io.h, include/lpc-ethernet-config.h, include/lpc24xx.h, console/console-config.c, i2c/i2c.c, misc/io.c, misc/lcd.c, startup/bspstart.c, startup/bspstarthooks.c: New pin configuration API. * Makefile.am, preinstall.am: Update. --- .../lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c | 311 +++++++++++++-------- 1 file changed, 188 insertions(+), 123 deletions(-) (limited to 'c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c') diff --git a/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c index be44953217..c8a50b00a7 100644 --- a/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c +++ b/c/src/lib/libbsp/arm/lpc24xx/startup/bspstarthooks.c @@ -7,12 +7,13 @@ */ /* - * Copyright (c) 2008, 2009 - * embedded brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * + * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -23,13 +24,48 @@ #include #include -#include #include +#include +#include #if defined(LPC24XX_EMC_MICRON) || defined(LPC24XX_EMC_NUMONYX) #define LPC24XX_EMC_INIT #endif +static volatile lpc_emc *const emc = (lpc_emc *) EMC_BASE_ADDR; + +typedef struct { + uint32_t refresh; + uint32_t readconfig; + uint32_t trp; + uint32_t tras; + uint32_t tsrex; + uint32_t tapr; + uint32_t tdal; + uint32_t twr; + uint32_t trc; + uint32_t trfc; + uint32_t txsr; + uint32_t trrd; + uint32_t tmrd; +} lpc24xx_emc_dynamic_config; + +typedef struct { + uint32_t config; + uint32_t rascas; + uint32_t mode; +} lpc24xx_emc_dynamic_chip_config; + +typedef struct { + uint32_t config; + uint32_t waitwen; + uint32_t waitoen; + uint32_t waitrd; + uint32_t waitpage; + uint32_t waitwr; + uint32_t waitrun; +} lpc24xx_emc_static_chip_config; + #ifdef LPC24XX_EMC_MICRON static void BSP_START_TEXT_SECTION lpc24xx_ram_test_32(void) { @@ -55,9 +91,7 @@ #endif } - static void BSP_START_TEXT_SECTION lpc24xx_cpu_delay( - unsigned ticks - ) + static void BSP_START_TEXT_SECTION lpc24xx_cpu_delay(unsigned ticks) { unsigned i = 0; @@ -68,173 +102,206 @@ __asm__ volatile ("nop"); } } + + static void BSP_START_TEXT_SECTION lpc24xx_udelay(unsigned us) + { + lpc24xx_cpu_delay(us * (LPC24XX_CCLK / 1000000)); + } #endif -/** - * @brief EMC initialization hook 0. - */ -static void BSP_START_TEXT_SECTION lpc24xx_init_emc_0(void) +static void BSP_START_TEXT_SECTION lpc24xx_init_emc_pinsel(void) +{ + #ifdef LPC24XX_EMC_INIT + static const BSP_START_DATA_SECTION uint32_t pinsel_5_9 [5] = { + 0x05010115, + 0x55555555, + 0x0, + 0x55555555, + 0x40050155 + }; + + bsp_start_memcpy( + (int *) &PINSEL5, + (const int *) &pinsel_5_9, + sizeof(pinsel_5_9) + ); + #endif +} + +static void BSP_START_TEXT_SECTION lpc24xx_init_emc_static(void) { #ifdef LPC24XX_EMC_NUMONYX /* * Static Memory 1: Numonyx M29W160EB * * 1 clock cycle = 1/72MHz = 13.9ns - * - * We cannot use an initializer since this will result in the usage of the - * read-only data section which is not available here. - */ - lpc24xx_emc_static numonyx; - - /* - * 16 bit, page mode disabled, active LOW chip select, extended wait - * disabled, writes not protected, byte lane state LOW/LOW (!). */ - numonyx.cfg = 0x81; - - /* 1 clock cycles delay from the chip select 1 to the write enable */ - numonyx.waitwen = 0; + static const BSP_START_DATA_SECTION lpc24xx_emc_static_chip_config chip_config = { + /* + * 16 bit, page mode disabled, active LOW chip select, extended wait + * disabled, writes not protected, byte lane state LOW/LOW (!). + */ + .config = 0x81, - /* - * 0 clock cycles delay from the chip select 1 or address change - * (whichever is later) to the output enable - */ - numonyx.waitoen = 0; + /* 1 clock cycles delay from the chip select 1 to the write enable */ + .waitwen = 0, - /* 7 clock cycles delay from the chip select 1 to the read access */ - numonyx.waitrd = 0x6; + /* + * 0 clock cycles delay from the chip select 1 or address change + * (whichever is later) to the output enable + */ + .waitoen = 0, - /* - * 32 clock cycles delay for asynchronous page mode sequential accesses - */ - numonyx.waitpage = 0x1f; + /* 7 clock cycles delay from the chip select 1 to the read access */ + .waitrd = 0x6, - /* 5 clock cycles delay from the chip select 1 to the write access */ - numonyx.waitwr = 0x3; + /* + * 32 clock cycles delay for asynchronous page mode sequential accesses + */ + .waitpage = 0x1f, - /* 16 bus turnaround cycles */ - numonyx.waitrun = 0xf; - #endif + /* 5 clock cycles delay from the chip select 1 to the write access */ + .waitwr = 0x3, - #ifdef LPC24XX_EMC_INIT - /* Set pin functions for EMC */ - PINSEL5 = (PINSEL5 & 0xf000f000) | 0x05550555; - PINSEL6 = 0x55555555; - PINSEL8 = 0x55555555; - PINSEL9 = (PINSEL9 & 0x0f000000) | 0x50555555; - #endif + /* 16 bus turnaround cycles */ + .waitrun = 0xf + }; + lpc24xx_emc_static_chip_config chip_config_on_stack; - #ifdef LPC24XX_EMC_NUMONYX - /* Static Memory 1 settings */ + bsp_start_memcpy( + (int *) &chip_config_on_stack, + (const int *) &chip_config, + sizeof(chip_config_on_stack) + ); bsp_start_memcpy( (int *) EMC_STA_BASE_1, - (const int *) &numonyx, - sizeof(numonyx) + (const int *) &chip_config_on_stack, + sizeof(chip_config_on_stack) ); #endif } -/** - * @brief EMC initialization hook 1. - */ -static void BSP_START_TEXT_SECTION lpc24xx_init_emc_1(void) +static void BSP_START_TEXT_SECTION lpc24xx_init_emc_memory_map(void) { #ifdef LPC24XX_EMC_INIT /* Use normal memory map */ EMC_CTRL &= ~0x2U; #endif +} +static void BSP_START_TEXT_SECTION lpc24xx_init_emc_dynamic(void) +{ #ifdef LPC24XX_EMC_MICRON - /* Check if we need to initialize it */ - if ((EMC_DYN_CFG0 & 0x00080000) == 0) { - /* - * The buffer enable bit is not set. Now we assume that the controller - * is not properly initialized. - */ + /* Dynamic Memory 0: Micron M T48LC 4M16 A2 P 75 IT */ - /* Global dynamic settings */ - - /* FIXME */ - EMC_DYN_APR = 2; + static const BSP_START_DATA_SECTION lpc24xx_emc_dynamic_config dynamic_config = { + /* Auto-refresh command every 15.6 us */ + .refresh = 0x46, - /* Data-in to active command period tWR + tRP */ - EMC_DYN_DAL = 4; + /* Use command delayed strategy */ + .readconfig = 1, - /* Load mode register to active or refresh command period 2 tCK */ - EMC_DYN_MRD = 1; + /* Precharge command period 20 ns */ + .trp = 1, /* Active to precharge command period 44 ns */ - EMC_DYN_RAS = 3; + .tras = 3, - /* Active to active command period 66 ns */ - EMC_DYN_RC = 4; - - /* Use command delayed strategy */ - EMC_DYN_RD_CFG = 1; + /* FIXME */ + .tsrex = 5, - /* Auto refresh period 66 ns */ - EMC_DYN_RFC = 4; + /* FIXME */ + .tapr = 2, - /* Precharge command period 20 ns */ - EMC_DYN_RP = 1; + /* Data-in to active command period tWR + tRP */ + .tdal = 4, - /* Active bank a to active bank b command period 15 ns */ - EMC_DYN_RRD = 1; + /* Write recovery time 15 ns */ + .twr = 1, - /* FIXME */ - EMC_DYN_SREX = 5; + /* Active to active command period 66 ns */ + .trc = 4, - /* Write recovery time 15 ns */ - EMC_DYN_WR = 1; + /* Auto refresh period 66 ns */ + .trfc = 4, /* Exit self refresh to active command period 75 ns */ - EMC_DYN_XSR = 5; + .txsr = 5, - /* Dynamic Memory 0: Micron M T48LC 4M16 A2 P 75 IT */ + /* Active bank a to active bank b command period 15 ns */ + .trrd = 1, + /* Load mode register to active or refresh command period 2 tCK */ + .tmrd = 1, + }; + static const BSP_START_DATA_SECTION lpc24xx_emc_dynamic_chip_config chip_config = { /* * Use SDRAM, 0 0 001 01 address mapping, disabled buffer, unprotected writes */ - EMC_DYN_CFG0 = 0x0280; - - /* CAS and RAS latency */ - EMC_DYN_RASCAS0 = 0x0202; - - /* Wait 50 micro seconds */ - lpc24xx_cpu_delay(3600); + .config = 0x280, - /* Send command: NOP */ - EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_NOP; + .rascas = EMC_DYN_RASCAS_RAS(2) | EMC_DYN_RASCAS_CAS(2, 0), + .mode = 0xa0000000 | (0x23 << (1 + 2 + 8)) + }; - /* Wait 50 micro seconds */ - lpc24xx_cpu_delay(3600); + volatile lpc_emc_dynamic *chip = &emc->dynamic [0]; + uint32_t dynamiccontrol = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS; - /* Send command: PRECHARGE ALL */ - EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_PALL; + /* Check if we need to initialize it */ + if ((chip->config & EMC_DYN_CFG_B) == 0) { + /* + * The buffer enable bit is not set. Now we assume that the controller + * is not properly initialized. + */ - /* Shortest possible refresh period */ - EMC_DYN_RFSH = 0x01; + /* Global dynamic settings */ + emc->dynamicreadconfig = dynamic_config.readconfig; + emc->dynamictrp = dynamic_config.trp; + emc->dynamictras = dynamic_config.tras; + emc->dynamictsrex = dynamic_config.tsrex; + emc->dynamictapr = dynamic_config.tapr; + emc->dynamictdal = dynamic_config.tdal; + emc->dynamictwr = dynamic_config.twr; + emc->dynamictrc = dynamic_config.trc; + emc->dynamictrfc = dynamic_config.trfc; + emc->dynamictxsr = dynamic_config.txsr; + emc->dynamictrrd = dynamic_config.trrd; + emc->dynamictmrd = dynamic_config.tmrd; + + /* Wait 100us after the power is applied and the clocks have stabilized */ + lpc24xx_udelay(100); + + /* NOP period, disable self-refresh */ + emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_NOP; + lpc24xx_udelay(200); + + /* Precharge all */ + emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_PALL; - /* Wait at least 128 AHB clock cycles */ + /* + * 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). + */ + emc->dynamicrefresh = 1; lpc24xx_cpu_delay(128); - /* Wait 1 micro second */ - lpc24xx_cpu_delay(72); - /* Set refresh period */ - EMC_DYN_RFSH = 0x46; + emc->dynamicrefresh = dynamic_config.refresh; - /* Send command: MODE */ - EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_MODE; + /* Operational values for the chip */ + chip->rascas = chip_config.rascas; + chip->config = chip_config.config; - /* Set mode register in SDRAM */ - *((volatile uint32_t *) (0xa0000000 | (0x23 << (1 + 2 + 8)))); + /* Mode */ + emc->dynamiccontrol = dynamiccontrol | EMC_DYN_CTRL_I_MODE; + *((volatile uint32_t *) chip_config.mode); - /* Send command: NORMAL */ - EMC_DYN_CTRL = 0; + /* Normal operation */ + emc->dynamiccontrol = 0; /* Enable buffer */ - EMC_DYN_CFG0 |= 0x00080000; + chip->config |= EMC_DYN_CFG_B; /* Test RAM */ lpc24xx_ram_test_32(); @@ -355,11 +422,9 @@ static void BSP_START_TEXT_SECTION lpc24xx_clear_bss(void) void BSP_START_TEXT_SECTION bsp_start_hook_0(void) { - /* Initialize PLL */ lpc24xx_init_pll(); - - /* Initialize EMC hook 0 */ - lpc24xx_init_emc_0(); + lpc24xx_init_emc_pinsel(); + lpc24xx_init_emc_static(); } void BSP_START_TEXT_SECTION bsp_start_hook_1(void) @@ -395,8 +460,8 @@ void BSP_START_TEXT_SECTION bsp_start_hook_1(void) FIO3CLR = 0xffffffff; FIO4CLR = 0xffffffff; - /* Initialize EMC hook 1 */ - lpc24xx_init_emc_1(); + lpc24xx_init_emc_memory_map(); + lpc24xx_init_emc_dynamic(); #ifdef LPC24XX_STOP_GPDMA if ((PCONP & PCONP_GPDMA) != 0) { -- cgit v1.2.3