summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c')
-rw-r--r--c/src/lib/libbsp/arm/lpc24xx/startup/bspstart.c283
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 */