This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Debug LPC 1788

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).

  • What external RAM are you using?
    Do you already have a C driver for this device?

    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.