diff options
Diffstat (limited to 'c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c')
-rw-r--r-- | c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c | 283 |
1 files changed, 272 insertions, 11 deletions
diff --git a/c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c b/c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c index 893ea589e5..50483d49d9 100644 --- a/c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c +++ b/c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c @@ -29,27 +29,290 @@ #include <bsp/start.h> #include <bsp/system-clocks.h> -void bsp_start_hook_0( void) +static void lpc24xx_fatal_error( void) { - /* Re-map interrupt vectors to internal RAM */ - SET_MEMMAP_MAP( MEMMAP, 2); + while (true) { + /* Spin forever */ + } +} + +static void lpc24xx_ram_test_32( void) +{ + volatile unsigned *out = (volatile unsigned *) bsp_ram_ext_start; + + while (out < (volatile unsigned *) bsp_ram_ext_end) { + *out = (unsigned) out; + ++out; + } + + out = (volatile unsigned *) bsp_ram_ext_start; + while (out < (volatile unsigned *) bsp_ram_ext_end) { + if (*out != (unsigned) out) { + lpc24xx_fatal_error(); + } + ++out; + } } -void bsp_start_hook_1( void) +/** + * @brief EMC initialization. + * + * Dynamic Memory 0: Micron M T48LC 4M16 A2 P 75 IT + */ +static void lpc24xx_init_emc( void) +{ + #ifdef LPC24XX_EMC_MICRON + int i = 0; + uint32_t mode = 0; + + /* Enable power */ + PCONP = SET_FLAGS( PCONP, 0x0800); + + /* Set PIN selects */ + PINSEL5 = SET_FLAGS( PINSEL5, 0x05050555); + PINSEL6 = SET_FLAGS( PINSEL6, 0x55555555); + PINSEL8 = SET_FLAGS( PINSEL8, 0x55555555); + PINSEL9 = SET_FLAGS( PINSEL9, 0x50555555); + + /* Enable module, normal memory map and normal power mode */ + EMC_CTRL = 1; + + /* Use little-endian mode and 1:1 clock ratio */ + EMC_CONFIG = 0; + + /* Global dynamic settings */ + + /* FIXME */ + EMC_DYN_APR = 2; + + /* Data-in to active command period tWR + tRP */ + EMC_DYN_DAL = 4; + + /* Load mode register to active or refresh command period 2 tCK */ + EMC_DYN_MRD = 1; + + /* Active to precharge command period 44 ns */ + EMC_DYN_RAS = 3; + + /* Active to active command period 66 ns */ + EMC_DYN_RC = 4; + + /* Use command delayed strategy */ + EMC_DYN_RD_CFG = 1; + + /* Auto refresh period 66 ns */ + EMC_DYN_RFC = 4; + + /* Precharge command period 20 ns */ + EMC_DYN_RP = 1; + + /* Active bank a to active bank b command period 15 ns */ + EMC_DYN_RRD = 1; + + /* FIXME */ + EMC_DYN_SREX = 5; + + /* Write recovery time 15 ns */ + EMC_DYN_WR = 1; + + /* Exit self refresh to active command period 75 ns */ + EMC_DYN_XSR = 5; + + /* Dynamic Memory 0 settings */ + + /* + * 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_micro_seconds_delay( 50); + + /* Send command: NOP */ + EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_NOP; + + /* Wait 50 micro seconds */ + lpc24xx_micro_seconds_delay( 50); + + /* Send command: PRECHARGE ALL */ + EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_PALL; + + /* Shortest possible refresh period */ + EMC_DYN_RFSH = 0x01; + + /* Wait at least 128 ABH clock cycles */ + for (i = 0; i < 128; ++i) { + asm volatile (" nop"); + } + + /* Wait 1 micro second */ + lpc24xx_micro_seconds_delay( 1); + + /* Set refresh period */ + EMC_DYN_RFSH = 0x46; + + /* Send command: MODE */ + EMC_DYN_CTRL = EMC_DYN_CTRL_CE | EMC_DYN_CTRL_CS | EMC_DYN_CTRL_CMD_MODE; + + /* Set mode registerin SDRAM */ + mode = *((volatile uint32_t *) (0xa0000000 | (0x23 << (1 + 2 + 8)))); + + /* Send command: NORMAL */ + EMC_DYN_CTRL = 0; + + /* Enable buffer */ + EMC_DYN_CFG0 |= 0x00080000; + + /* Static Memory 0 settings */ + EMC_STA_WAITWEN0 = 0x02; + EMC_STA_WAITOEN0 = 0x02; + EMC_STA_WAITRD0 = 0x1f; + EMC_STA_WAITPAGE0 = 0x1f; + EMC_STA_WAITWR0 = 0x1f; + EMC_STA_WAITTURN0 = 0x0f; + EMC_STA_CFG0 = 0x81; + + /* Static Memory 1 settings */ + EMC_STA_WAITWEN1 = 0x02; + EMC_STA_WAITOEN1 = 0x02; + EMC_STA_WAITRD1 = 0x08; + EMC_STA_WAITPAGE1 = 0x1f; + EMC_STA_WAITWR1 = 0x08; + EMC_STA_WAITTURN1 = 0x0f; + EMC_STA_CFG1 = 0x80; + + /* RAM test */ + lpc24xx_ram_test_32(); + #endif /* LPC24XX_EMC_MICRON */ +} + +static void lpc24xx_init_pll( void) +{ + #ifndef LPC24XX_HAS_UBOOT + /* Enable main oscillator */ + SCS = SET_FLAGS( SCS, 0x20); + while (IS_FLAG_CLEARED( SCS, 0x40)) { + /* Wait */ + } + + /* Set PLL */ + lpc24xx_set_pll( 1, 0, 11, 3); + #endif /* LPC24XX_HAS_UBOOT */ +} + +void /* __attribute__ ((section (".entry"))) */ bsp_start_hook_0( void) +{ + /* Initialize PLL */ + lpc24xx_init_pll(); + + #ifndef LPC24XX_HAS_UBOOT + /* Set pin functions */ + PINSEL0 = 0; + PINSEL1 = 0; + PINSEL2 = 0; + PINSEL3 = 0; + PINSEL4 = 0; + PINSEL5 = 0; + PINSEL6 = 0; + PINSEL7 = 0; + PINSEL8 = 0; + PINSEL9 = 0; + PINSEL10 = 0; + + /* Set periperal clocks */ + PCLKSEL0 = 0; + PCLKSEL1 = 0; + + /* Disable power for all modules */ + PCONP = 0; + + /* Set memory accelerator module (MAM) */ + MAMCR = 0; + MAMTIM = 4; + + /* Set general purpose IO */ + IODIR0 = 0; + IODIR1 = 0; + IOSET0 = 0xffffffff; + IOSET1 = 0xffffffff; + + /* Set fast IO */ + FIO0DIR = 0; + FIO1DIR = 0; + FIO2DIR = 0; + FIO3DIR = 0; + FIO4DIR = 0; + FIO0SET = 0xffffffff; + FIO1SET = 0xffffffff; + FIO2SET = 0xffffffff; + FIO3SET = 0xffffffff; + FIO4SET = 0xffffffff; + + /* Initialize UART 0 */ + PCONP = SET_FLAGS( PCONP, 0x08); + PCLKSEL0 = SET_FLAGS( PCLKSEL0, 0x40); + PINSEL0 = SET_FLAGS( PINSEL0, 0x50); + U0LCR = 0; + U0IER = 0; + U0LCR = 0x80; + U0DLL = lpc24xx_cclk() / 16 / LPC24XX_UART_BAUD; + U0DLM = 0; + U0LCR = 0x03; + U0FCR = 0x07; + + /* Initialize Timer 1 */ + PCONP = SET_FLAGS( PCONP, 0x04); + PCLKSEL0 = SET_FLAGS( PCLKSEL0, 0x10); + #endif /* LPC24XX_HAS_UBOOT */ +} + +static void lpc24xx_copy_data( void) +{ + #ifndef LPC24XX_HAS_UBOOT + unsigned *in = bsp_section_text_end; + unsigned *out = bsp_section_data_start; + + /* Copy data */ + while (out < bsp_section_data_end) { + *out = *in; + ++out; + ++in; + } + #endif /* LPC24XX_HAS_UBOOT */ +} + +static void lpc24xx_clear_bss( void) { - unsigned zero = 0; unsigned *out = bsp_section_bss_start; /* Clear BSS */ while (out < bsp_section_bss_end) { - *out = zero; + *out = 0; ++out; } } +void /* __attribute__ ((section (".entry"))) */ bsp_start_hook_1( void) +{ + /* Re-map interrupt vectors to internal RAM */ + MEMMAP = SET_MEMMAP_MAP( MEMMAP, 2); + + /* Initialize External Memory Controller (EMC) */ + lpc24xx_init_emc(); + + /* Copy data */ + lpc24xx_copy_data(); + + /* Clear BSS */ + lpc24xx_clear_bss(); +} + void bsp_start( void) { - printk( "CPU Clock: %u\n", lpc24xx_cclk()); + printk( "CPU clock (CCLK): %u\n", lpc24xx_cclk()); /* Exceptions */ rtems_exception_init_mngt(); @@ -57,10 +320,8 @@ void bsp_start( void) /* Interrupts */ if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) { /* FIXME */ - printk( "Cannot intitialize interrupt support\n"); - while (1) { - /* Spin forever */ - } + printk( "cannot intitialize interrupt support\n"); + lpc24xx_fatal_error(); } /* DMA */ |