I have 2 projects:
bootloader project - mount the SD card and load application.hex to the external RAM application project - RTOS and application
I would like to use bootload to load a application.hex(on SD card) to the external RAM and run. But how to debug the application?
I have a similar setup.
What I did was I wrote a debug INI file that configures the EMC and I let the debugger load the application into the external RAM directly.
(Note to run out of the external RAM you will need to configure the MPU)
could you send me your ini file?
or could you point it out to me how to write ini file.
What external RAM are you using? Do you already have a C driver for this device?
See this forum: www.lpcware.com/.../dk-57vts-lpc1788-configuring-emc-sdram
I will post my INI file but it may not help if it's a different device:
DEFINE INT SDRAM_BASE_ADDR; DEFINE INT EMC_BASE; // EMC Base Address DEFINE INT EMC_CTRL_REG; DEFINE INT EMC_STAT_REG; DEFINE INT EMC_CONFIG_REG; DEFINE INT EMC_DYN_CTRL_REG; DEFINE INT EMC_DYN_RFSH_REG; DEFINE INT EMC_DYN_RD_CFG_REG; DEFINE INT EMC_DYN_RP_REG; DEFINE INT EMC_DYN_RAS_REG; DEFINE INT EMC_DYN_SREX_REG; DEFINE INT EMC_DYN_APR_REG; DEFINE INT EMC_DYN_DAL_REG; DEFINE INT EMC_DYN_WR_REG; DEFINE INT EMC_DYN_RC_REG; DEFINE INT EMC_DYN_RFC_REG; DEFINE INT EMC_DYN_XSR_REG; DEFINE INT EMC_DYN_RRD_REG; DEFINE INT EMC_DYN_MRD_REG; DEFINE INT EMC_DYN_CFG0_REG; DEFINE INT EMC_DYN_RASCAS0_REG; //note: missing the other dyn mem register offsets. DEFINE INT EMC_STA_CFG0_REG; DEFINE INT EMC_STA_WWEN0_REG; DEFINE INT EMC_STA_WOEN0_REG; DEFINE INT EMC_STA_WRD0_REG; DEFINE INT EMC_STA_WPAGE0_REG; DEFINE INT EMC_STA_WWR0_REG; DEFINE INT EMC_STA_WTURN0_REG; //note: missing the other static mem register offsets. DEFINE INT EMC_STA_EXT_W_REG; DEFINE INT PCONP_REG; DEFINE INT EMCDLYCTL_REG; DEFINE INT EMCCAL_REG; DEFINE INT EMCClock; DEFINE INT SCS_REG; SDRAM_BASE_ADDR = 0xA0000000; EMC_BASE = 0x2009C000; // EMC Base Address EMC_CTRL_REG = EMC_BASE + 0x000; EMC_STAT_REG = EMC_BASE + 0x004; EMC_CONFIG_REG = EMC_BASE + 0x008; EMC_DYN_CTRL_REG = EMC_BASE + 0x020; EMC_DYN_RFSH_REG = EMC_BASE + 0x024; EMC_DYN_RD_CFG_REG = EMC_BASE + 0x028; EMC_DYN_RP_REG = EMC_BASE + 0x030; EMC_DYN_RAS_REG = EMC_BASE + 0x034; EMC_DYN_SREX_REG = EMC_BASE + 0x038; EMC_DYN_APR_REG = EMC_BASE + 0x03C; EMC_DYN_DAL_REG = EMC_BASE + 0x040; EMC_DYN_WR_REG = EMC_BASE + 0x044; EMC_DYN_RC_REG = EMC_BASE + 0x048; EMC_DYN_RFC_REG = EMC_BASE + 0x04C; EMC_DYN_XSR_REG = EMC_BASE + 0x050; EMC_DYN_RRD_REG = EMC_BASE + 0x054; EMC_DYN_MRD_REG = EMC_BASE + 0x058; EMC_DYN_CFG0_REG = EMC_BASE + 0x100; EMC_DYN_RASCAS0_REG = EMC_BASE + 0x104; EMC_STA_CFG0_REG = EMC_BASE + 0x200; EMC_STA_WWEN0_REG = EMC_BASE + 0x204; EMC_STA_WOEN0_REG = EMC_BASE + 0x208; EMC_STA_WRD0_REG = EMC_BASE + 0x20C; EMC_STA_WPAGE0_REG = EMC_BASE + 0x210; EMC_STA_WWR0_REG = EMC_BASE + 0x214; EMC_STA_WTURN0_REG = EMC_BASE + 0x218; EMC_STA_EXT_W_REG = EMC_BASE + 0x080; PCONP_REG = 0x400FC0C4; EMCDLYCTL_REG = 0x400FC1DC; EMCCAL_REG = 0x400FC1E0; EMCClock = 78000000; SCS_REG = 0x400FC1A0; FUNC int NS_2_CLKS(int ns) { double tCLK_ns; tCLK_ns = ((double)EMCClock / 1000000000.0 ); // CCLK period in ns return (int)((double)(ns) * tCLK_ns ); // convert ns to CCLKs } FUNC void Setup (void) { printf("START - Setup() \r\n"); SP = _RDWORD(0x00040000); // Setup Stack Pointer PC = _RDWORD(0x00040004); // Setup Program Counter _WDWORD(0xE000ED08, 0x00040000); // Setup Vector Table Offset Register //SP = _RDWORD(0x00000000); // Setup Stack Pointer //PC = _RDWORD(0x00000004); // Setup Program Counter //_WDWORD(0xE000ED08, 0x00000000); // Setup Vector Table Offset Register printf("END - Setup() \r\n"); }
FUNC void init_emc(void) { //********************************************* // PIN CONFIGURATION //********************************************* _WDWORD(0x4002C140, _RDWORD(0x4002C140) | 0x1); //LPC_IOCON->P2_16 |= 1; // CASN @ P2.16 (SDRAM Column Address Strobe) _WDWORD(0x4002C144, _RDWORD(0x4002C144) | 0x1); //LPC_IOCON->P2_17 |= 1; // RASN @ P2.17 (SDRAM Row Address Strobe) _WDWORD(0x4002C148, _RDWORD(0x4002C148) | 0x1); //LPC_IOCON->P2_18 |= 1; // CLK[0] @ P2.18 (SDRAM System Clock) _WDWORD(0x4002C150, _RDWORD(0x4002C150) | 0x1); //LPC_IOCON->P2_20 |= 1; // DYCSN[0] @ P2.20 (SDRAM Chip Select) _WDWORD(0x4002C160, _RDWORD(0x4002C160) | 0x1); //LPC_IOCON->P2_24 |= 1; // CKE[0] @ P2.24 (SDRAM Clock Enable) _WDWORD(0x4002C170, _RDWORD(0x4002C170) | 0x1); //LPC_IOCON->P2_28 |= 1; // DQM[0] @ P2.28 (SDRAM Data Input/Output Mask) _WDWORD(0x4002C174, _RDWORD(0x4002C174) | 0x1); //LPC_IOCON->P2_29 |= 1; // DQM[1] @ P2.29 (SDRAM Data Input/Output Mask) _WDWORD(0x4002C180, _RDWORD(0x4002C180) | 0x1); // LPC_IOCON->P3_0 |= 1; /* D0 @ P3.0 */ _WDWORD(0x4002C184, _RDWORD(0x4002C184) | 0x1); // LPC_IOCON->P3_1 |= 1; /* D1 @ P3.1 */ _WDWORD(0x4002C188, _RDWORD(0x4002C188) | 0x1); // LPC_IOCON->P3_2 |= 1; /* D2 @ P3.2 */ _WDWORD(0x4002C18C, _RDWORD(0x4002C18C) | 0x1); // LPC_IOCON->P3_3 |= 1; /* D3 @ P3.3 */ _WDWORD(0x4002C190, _RDWORD(0x4002C190) | 0x1); // LPC_IOCON->P3_4 |= 1; /* D4 @ P3.4 */ _WDWORD(0x4002C194, _RDWORD(0x4002C194) | 0x1); // LPC_IOCON->P3_5 |= 1; /* D5 @ P3.5 */ _WDWORD(0x4002C198, _RDWORD(0x4002C198) | 0x1); // LPC_IOCON->P3_6 |= 1; /* D6 @ P3.6 */ _WDWORD(0x4002C19C, _RDWORD(0x4002C19C) | 0x1); // LPC_IOCON->P3_7 |= 1; /* D7 @ P3.7 */ _WDWORD(0x4002C1A0, _RDWORD(0x4002C1A0) | 0x1); // LPC_IOCON->P3_8 |= 1; /* D8 @ P3.8 */ _WDWORD(0x4002C1A4, _RDWORD(0x4002C1A4) | 0x1); // LPC_IOCON->P3_9 |= 1; /* D9 @ P3.9 */ _WDWORD(0x4002C1A8, _RDWORD(0x4002C1A8) | 0x1); // LPC_IOCON->P3_10 |= 1; /* D10 @ P3.10 */ _WDWORD(0x4002C1AC, _RDWORD(0x4002C1AC) | 0x1); // LPC_IOCON->P3_11 |= 1; /* D11 @ P3.11 */ _WDWORD(0x4002C1B0, _RDWORD(0x4002C1B0) | 0x1); // LPC_IOCON->P3_12 |= 1; /* D12 @ P3.12 */ _WDWORD(0x4002C1B4, _RDWORD(0x4002C1B4) | 0x1); // LPC_IOCON->P3_13 |= 1; /* D13 @ P3.13 */ _WDWORD(0x4002C1B8, _RDWORD(0x4002C1B8) | 0x1); // LPC_IOCON->P3_14 |= 1; /* D14 @ P3.14 */ _WDWORD(0x4002C1BC, _RDWORD(0x4002C1BC) | 0x1); // LPC_IOCON->P3_15 |= 1; /* D15 @ P3.15 */ _WDWORD(0x4002C200, _RDWORD(0x4002C200) | 0x1); // LPC_IOCON->P4_0 |= 1; /* A0 @ P4.0 */ _WDWORD(0x4002C204, _RDWORD(0x4002C204) | 0x1); // LPC_IOCON->P4_1 |= 1; /* A1 @ P4.1 */ _WDWORD(0x4002C208, _RDWORD(0x4002C208) | 0x1); // LPC_IOCON->P4_2 |= 1; /* A2 @ P4.2 */ _WDWORD(0x4002C20C, _RDWORD(0x4002C20C) | 0x1); // LPC_IOCON->P4_3 |= 1; /* A3 @ P4.3 */ _WDWORD(0x4002C210, _RDWORD(0x4002C210) | 0x1); // LPC_IOCON->P4_4 |= 1; /* A4 @ P4.4 */ _WDWORD(0x4002C214, _RDWORD(0x4002C214) | 0x1); // LPC_IOCON->P4_5 |= 1; /* A5 @ P4.5 */ _WDWORD(0x4002C218, _RDWORD(0x4002C218) | 0x1); // LPC_IOCON->P4_6 |= 1; /* A6 @ P4.6 */ _WDWORD(0x4002C21C, _RDWORD(0x4002C21C) | 0x1); // LPC_IOCON->P4_7 |= 1; /* A7 @ P4.7 */ _WDWORD(0x4002C220, _RDWORD(0x4002C220) | 0x1); // LPC_IOCON->P4_8 |= 1; /* A8 @ P4.8 */ _WDWORD(0x4002C224, _RDWORD(0x4002C224) | 0x1); // LPC_IOCON->P4_9 |= 1; /* A9 @ P4.9 */ _WDWORD(0x4002C228, _RDWORD(0x4002C228) | 0x1); // LPC_IOCON->P4_10 |= 1; /* A10 @ P4.10 */ _WDWORD(0x4002C22C, _RDWORD(0x4002C22C) | 0x1); // LPC_IOCON->P4_11 |= 1; /* A11 @ P4.11 */ _WDWORD(0x4002C230, _RDWORD(0x4002C230) | 0x1); // LPC_IOCON->P4_12 |= 1; /* A12 @ P4.12 */ _WDWORD(0x4002C234, _RDWORD(0x4002C234) | 0x1); // LPC_IOCON->P4_13 |= 1; /* A13 @ P4.13 */ _WDWORD(0x4002C238, _RDWORD(0x4002C238) | 0x1); // LPC_IOCON->P4_14 |= 1; /* A14 @ P4.14 */ _WDWORD(0x4002C23C, _RDWORD(0x4002C23C) | 0x1); // LPC_IOCON->P4_15 |= 1; /* A15 @ P4.15 */ _WDWORD(0x4002C240, _RDWORD(0x4002C240) | 0x1); // LPC_IOCON->P4_16 |= 1; /* A16 @ P4.16 */ _WDWORD(0x4002C244, _RDWORD(0x4002C244) | 0x1); // LPC_IOCON->P4_17 |= 1; /* A17 @ P4.17 */ _WDWORD(0x4002C248, _RDWORD(0x4002C248) | 0x1); // LPC_IOCON->P4_18 |= 1; /* A18 @ P4.18 */ _WDWORD(0x4002C24C, _RDWORD(0x4002C24C) | 0x1); // LPC_IOCON->P4_19 |= 1; /* A19 @ P4.19 */ _WDWORD(0x4002C250, _RDWORD(0x4002C250) | 0x1); // LPC_IOCON->P4_20 |= 1; /* A20 @ P4.20 */ _WDWORD(0x4002C254, _RDWORD(0x4002C254) | 0x1); // LPC_IOCON->P4_21 |= 1; /* A21 @ P4.21 */ _WDWORD(0x4002C258, _RDWORD(0x4002C258) | 0x1); // LPC_IOCON->P4_22 |= 1; /* A22 @ P4.22 */ _WDWORD(0x4002C25C, _RDWORD(0x4002C25C) | 0x1); // LPC_IOCON->P4_23 |= 1; /* A23 @ P4.23 */ _WDWORD(0x4002C260, _RDWORD(0x4002C260) | 0x1); // LPC_IOCON->P4_24 |= 1; /* OEN @ P4.24 */ _WDWORD(0x4002C264, _RDWORD(0x4002C264) | 0x1); // LPC_IOCON->P4_25 |= 1; /* WEN @ P4.25 */ _WDWORD(0x4002C268, _RDWORD(0x4002C268) | 0x1); // LPC_IOCON->P4_26 |= 1; /* BLSN[0] @ P4.26 */ _WDWORD(0x4002C26C, _RDWORD(0x4002C26C) | 0x1); // LPC_IOCON->P4_27 |= 1; /* BLSN[1] @ P4.27 */ _WDWORD(0x4002C270, _RDWORD(0x4002C270) | 0x1); // LPC_IOCON->P4_28 |= 1; /* BLSN[2] @ P4.28 */ _WDWORD(0x4002C274, _RDWORD(0x4002C274) | 0x1); // LPC_IOCON->P4_29 |= 1; /* BLSN[3] @ P4.29 */ _WDWORD(0x4002C278, _RDWORD(0x4002C278) | 0x1); // LPC_IOCON->P4_30 |= 1; /* CSN[0] @ P4.30 */ _WDWORD(0x4002C27C, _RDWORD(0x4002C27C) | 0x1); // LPC_IOCON->P4_31 |= 1; /* CSN[1] @ P4.31 */ _WDWORD(0x4002C138, _RDWORD(0x4002C138) | 0x1); // LPC_IOCON->P2_14 |= 1; /* CSN[2] @ P2.14 */ _WDWORD(0x4002C13C, _RDWORD(0x4002C13C) | 0x1); // LPC_IOCON->P2_15 |= 1; /* CSN[3] @ P2.15 */ _WDWORD(PCONP_REG, _RDWORD(PCONP_REG) | 0x00000800); // LPC_SC->PCONP |= 0x00000800;
//********************************************* // DYNAMIC MEMORY CONFIGURATION //********************************************* _WDWORD(EMCDLYCTL_REG, 0x00000A05); //LPC_SC->EMCDLYCTL = 0x00000A05; _WDWORD(EMC_CTRL_REG, 0x1); // LPC_EMC->Control = 0x00000001; _WDWORD(EMC_CONFIG_REG, 0x0); // LPC_EMC->Config = 0x00000000; _WDWORD(SCS_REG, _RDWORD(SCS_REG) | (1<<1)); //LPC_SC->SCS |= (1<<1); _WDWORD(SCS_REG, _RDWORD(SCS_REG) & ~(0x00000001)); //LPC_SC->SCS &= ~(0x00000001); _WDWORD(EMC_DYN_CFG0_REG, 0x00001680); //LPC_EMC->DynamicConfig0 = 0x00001680; _WDWORD(EMCDLYCTL_REG, 0x00000A05); _WDWORD(EMC_DYN_RASCAS0_REG, 2 + (2<<8)); //LPC_EMC->DynamicRasCas0 = RAS_Latency + (CAS_Latency<<8); _WDWORD(EMC_DYN_RD_CFG_REG, 0x00000001); //LPC_EMC->DynamicReadConfig = 0x00000001; _WDWORD(EMC_DYN_RP_REG, NS_2_CLKS(18)); //LPC_EMC->DynamicRP = NS_2_CLKS(18); _WDWORD(EMC_DYN_RAS_REG, NS_2_CLKS(42)); //LPC_EMC->DynamicRAS = NS_2_CLKS(42); _WDWORD(EMC_DYN_SREX_REG, NS_2_CLKS(70)); //LPC_EMC->DynamicSREX = NS_2_CLKS(70); _WDWORD(EMC_DYN_APR_REG, NS_2_CLKS(18)); //LPC_EMC->DynamicAPR = NS_2_CLKS(18); _WDWORD(EMC_DYN_DAL_REG, 4); //LPC_EMC->DynamicDAL = CAS_Latency+2; _WDWORD(EMC_DYN_WR_REG, (NS_2_CLKS(6)+1)); //LPC_EMC->DynamicWR = (NS_2_CLKS(6)+1); _WDWORD(EMC_DYN_RC_REG, NS_2_CLKS(60)); //LPC_EMC->DynamicRC = NS_2_CLKS(60); _WDWORD(EMC_DYN_RFC_REG, NS_2_CLKS(60)); //LPC_EMC->DynamicRFC = NS_2_CLKS(60); _WDWORD(EMC_DYN_XSR_REG, NS_2_CLKS(70)); //LPC_EMC->DynamicXSR = NS_2_CLKS(70); _WDWORD(EMC_DYN_RRD_REG, NS_2_CLKS(12)); //LPC_EMC->DynamicRRD = NS_2_CLKS(12); _WDWORD(EMC_DYN_MRD_REG, 2); //LPC_EMC->DynamicMRD = 2; _WDWORD(EMC_DYN_CTRL_REG, 0x00000183); //LPC_EMC->DynamicControl = 0x00000183; _sleep_(2); _WDWORD(EMC_DYN_CTRL_REG, 0x00000103); //LPC_EMC->DynamicControl = 0x00000103; _WDWORD(EMC_DYN_RFSH_REG, 0x00000001); //LPC_EMC->DynamicRefresh = 0x00000001; // 1 x 16 = 16 CCLKs between SDRAM refresh cycles _sleep_(1); _WDWORD(EMC_DYN_RFSH_REG, NS_2_CLKS(7813 + 1)>>4); //LPC_EMC->DynamicRefresh = NS_2_CLKS(7813 + 1)>>4; // Refresh units are x16 (8192 rows...) _sleep_(1); _WDWORD(EMC_DYN_CTRL_REG, 0x00000083); //LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */ _RDWORD(SDRAM_BASE_ADDR|((0x03+(2<<4))<<10)); //Temp = *((volatile uint32_t *)(SDRAM_BASE_ADDR|((0x03+(CAS_Latency<<4))<<10))); _sleep_(1); _WDWORD(EMC_DYN_CTRL_REG, 0x00000000); //LPC_EMC->DynamicControl = 0x00000000; _WDWORD(EMC_DYN_CFG0_REG, _RDWORD(EMC_DYN_CFG0_REG) | 0x00080000); //LPC_EMC->DynamicConfig0 |= 0x00080000; //********************************************* // STATIC MEMORY CONFIGURATION //********************************************* _WDWORD(EMC_STA_CFG0_REG, 0x00000081); // LPC_EMC->StaticConfig0 = 0x00000081; _WDWORD(EMC_STA_WWEN0_REG, 0x00000003); // LPC_EMC->StaticWaitWen0 = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ _WDWORD(EMC_STA_WOEN0_REG, 0x00000003); // LPC_EMC->StaticWaitOen0 = 0x00000003; /* ( n ) -> 0 clock cycles */ _WDWORD(EMC_STA_WRD0_REG, 0x00000006); // LPC_EMC->StaticWaitRd0 = 0x00000006; /* ( n + 1 ) -> 7 clock cycles */ _WDWORD(EMC_STA_WPAGE0_REG, 0x00000003); // LPC_EMC->StaticWaitPage0 = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ _WDWORD(EMC_STA_WWR0_REG, 0x00000005); // LPC_EMC->StaticWaitWr0 = 0x00000005; /* ( n + 2 ) -> 7 clock cycles */ _WDWORD(EMC_STA_WTURN0_REG, 0x00000003); // LPC_EMC->StaticWaitTurn0 = 0x00000003; /* ( n + 1 ) -> 4 clock cycles */ } init_emc(); Setup();
I am using SOMDIMM-LPC1788 from FDI (DK-57VTS-LPC1788).
I imagine the link I posted above will help you quite a bit.
SDRAM: MT48LC2M32B2, which is a 2Mx32bit chip
Marc,
What external RAM are you using?
I'm using the MT48LC16M16.
All the timings should be the same you just need to adjust the pin configuration and the mem type.