lpcware

SDRAM fails after initialization from startup

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by Alastair on Mon Nov 23 02:22:57 MST 2015
Hi
I am using IS42S16400J(@102MHz) as my external RAM with LPC4357(@204MHz).
I need to initialization my external RAM within startup code as one of my libraries has data area within it. Also the initialization of many library variables is done in the same data space.

I am using the following code to boot my RAM from startup

/***********************************************************************
#include "SDRAM.h"
#include "lpc43xx_cgu.h"
#include "lpc43xx_scu.h"
#include "lpc43xx_gpio.h"
#include "lpc43xx_timer.h"

/************************** PRIVATE DEFINITIONS *************************/
/* SDRAM Address Base for DYCS0*/
#define SDRAM_ADDR_BASE0x28000000

/* SDRAM refresh time to 16 clock num */
#define EMC_SDRAM_REFRESH(freq,time)  \
  (((uint64_t)((uint64_t)time * freq)/16000000000ull)+1)

/*-------------------------PRIVATE FUNCTIONS------------------------------*/
/*********************************************************************
* @briefCalculate EMC Clock from nano second
* @param[in]freq - frequency of EMC Clk
* @param[in]time - nano second
* @return None
**********************************************************************/
uint32_t NS2CLK(uint32_t freq,uint32_t time){
return (((uint64_t)time*freq/1000000000));
}

#define CLK0_DELAY 7
/*********************************************************************
* @briefInit the EMC Controller to connect ex SDRAM
* @param[in]None
* @return None
**********************************************************************/
void SDRAM_Init1(void)
{
uint32_t pclk, temp;
uint64_t tmpclk;
TIM_TIMERCFG_Type TIM_ConfigStruct;

/* Set up EMC pin */
{
scu_pinmux(1,0,MD_PLN_FAST,2);//A5
scu_pinmux(1,1,MD_PLN_FAST,2);//A6
scu_pinmux(1,2,MD_PLN_FAST,2);//A7
//scu_pinmux(1,3,MD_PLN_FAST,3);//OE
//scu_pinmux(1,4,MD_PLN_FAST,3);//BLS0
//scu_pinmux(1,5,MD_PLN_FAST,3);//CS0
scu_pinmux(1,6,MD_PLN_FAST,3);//WE
scu_pinmux(1,7,MD_PLN_FAST,3);//D0
scu_pinmux(1,8,MD_PLN_FAST,3);//D1
scu_pinmux(1,9,MD_PLN_FAST,3);//D2
scu_pinmux(1,10,MD_PLN_FAST,3);//D3
scu_pinmux(1,11,MD_PLN_FAST,3);//D4
scu_pinmux(1,12,MD_PLN_FAST,3);//D5
scu_pinmux(1,13,MD_PLN_FAST,3);//D6
scu_pinmux(1,14,MD_PLN_FAST,3);//D7
scu_pinmux(2,0,MD_PLN_FAST,2);//A13
scu_pinmux(2,1,MD_PLN_FAST,2);//A12
scu_pinmux(2,2,MD_PLN_FAST,2);//A11
scu_pinmux(2,6,MD_PLN_FAST,2);//A10
scu_pinmux(2,7,MD_PLN_FAST,3);//A9
scu_pinmux(2,8,MD_PLN_FAST,3);//A8
scu_pinmux(2,9,MD_PLN_FAST,3);//A0
scu_pinmux(2,10,MD_PLN_FAST,3);//A1
scu_pinmux(2,11,MD_PLN_FAST,3);//A2
scu_pinmux(2,12,MD_PLN_FAST,3);//A3
scu_pinmux(2,13,MD_PLN_FAST,3);//A4
scu_pinmux(5,0,MD_PLN_FAST,2);//D12
scu_pinmux(5,1,MD_PLN_FAST,2);//D13
scu_pinmux(5,2,MD_PLN_FAST,2);//D14
scu_pinmux(5,3,MD_PLN_FAST,2);//D15
scu_pinmux(5,4,MD_PLN_FAST,2);//D8
scu_pinmux(5,5,MD_PLN_FAST,2);//D9
scu_pinmux(5,6,MD_PLN_FAST,2);//D10
scu_pinmux(5,7,MD_PLN_FAST,2);//D11
//scu_pinmux(6,3,MD_PLN_FAST,3);//CS1
scu_pinmux(6,4,MD_PLN_FAST,3);//CAS
scu_pinmux(6,5,MD_PLN_FAST,3);//RAS
//scu_pinmux(6,6,MD_PLN_FAST,1);//A15
scu_pinmux(6,7,MD_PLN_FAST,1);//A15
scu_pinmux(6,8,MD_PLN_FAST,1);//A14
scu_pinmux(6,9,MD_PLN_FAST,3);//DYCS0
scu_pinmux(6,10,MD_PLN_FAST,3);//DQMOUT1
scu_pinmux(6,11,MD_PLN_FAST,3);//CKEOUT0
scu_pinmux(6,12,MD_PLN_FAST,3);//DQMOUT0
//scu_pinmux(10,4,MD_PLN_FAST,3);
//scu_pinmux(13,0,MD_PLN_FAST,2);
//scu_pinmux(13,2,MD_PLN_FAST,2);
//scu_pinmux(13,3,MD_PLN_FAST,2);
//scu_pinmux(13,4,MD_PLN_FAST,2);
//scu_pinmux(13,5,MD_PLN_FAST,2);
//scu_pinmux(13,6,MD_PLN_FAST,2);
//scu_pinmux(13,7,MD_PLN_FAST,2);
//scu_pinmux(13,8,MD_PLN_FAST,2);
//scu_pinmux(13,9,MD_PLN_FAST,2);
//scu_pinmux(13,10,MD_PLN_FAST,2);
//scu_pinmux(13,12,MD_PLN_FAST,2);
//scu_pinmux(13,13,MD_PLN_FAST,2);
//scu_pinmux(13,15,MD_PLN_FAST,2);
//scu_pinmux(13,16,MD_PLN_FAST,2);
//scu_pinmux(14,0,MD_PLN_FAST,3);
//scu_pinmux(14,1,MD_PLN_FAST,3);
//scu_pinmux(14,2,MD_PLN_FAST,3);
//scu_pinmux(14,3,MD_PLN_FAST,3);
//scu_pinmux(14,4,MD_PLN_FAST,3);
//scu_pinmux(14,5,MD_PLN_FAST,3);
//scu_pinmux(14,6,MD_PLN_FAST,3);
//scu_pinmux(14,7,MD_PLN_FAST,3);
//scu_pinmux(14,8,MD_PLN_FAST,3);
//scu_pinmux(14,9,MD_PLN_FAST,3);
//scu_pinmux(14,10,MD_PLN_FAST,3);
//scu_pinmux(14,11,MD_PLN_FAST,3);
//scu_pinmux(14,12,MD_PLN_FAST,3);
//scu_pinmux(14,13,MD_PLN_FAST,3);
}

// Setup EMC delays
  LPC_SCU->EMCDELAYCLK = ((CLK0_DELAY) | (CLK0_DELAY << 4) | (CLK0_DELAY << 8) | (CLK0_DELAY << 12));

  // EMC clock is half of CGU_BASE_M4 if CGU_BASE_M4 is >104 MHz
  if (SystemCoreClock > 104000000)
  {
LPC_CCU1->CLK_M4_EMCDIV_CFG = ( (1<<0) | (1<<1) | (1<<2) | (1<<5) );
LPC_CREG->CREG6 |= (1<<16);
  }
  else
  {
LPC_CCU1->CLK_M4_EMCDIV_CFG = ( (1<<0) | (1<<1) | (1<<2) | (0<<5) );
LPC_CREG->CREG6 &= ~(1<<16);
  }

/* Select EMC clock-out */
LPC_SCU->SFSCLK_0 = MD_PLN_FAST;
LPC_SCU->SFSCLK_1 = MD_PLN_FAST;
LPC_SCU->SFSCLK_2 = MD_PLN_FAST;
LPC_SCU->SFSCLK_3 = MD_PLN_FAST;

TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
TIM_ConfigStruct.PrescaleValue= 1;

// Set configuration for Tim_config and Tim_MatchConfig
TIM_Init(LPC_TIMER0, TIM_TIMER_MODE,&TIM_ConfigStruct);

LPC_EMC->CONTROL = 0x00000001;
LPC_EMC->CONFIG  = 0x00000000;
LPC_EMC->DYNAMICCONFIG0    = 0<<14 | 1<<9 | 1<<7; /* 64Mb, 4Mx16, 4 banks, row=12, column=8 */

pclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);

LPC_EMC->DYNAMICRASCAS0    = 0x00000303; /* 1 RAS, 3 CAS latency */
LPC_EMC->DYNAMICREADCONFIG = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */

LPC_EMC->DYNAMICRP         = NS2CLK(pclk, 20);
LPC_EMC->DYNAMICRAS        = NS2CLK(pclk, 42);
LPC_EMC->DYNAMICSREX       = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICAPR        = 0x00000005;
LPC_EMC->DYNAMICDAL        = 0x00000005;
LPC_EMC->DYNAMICWR         = 2;
LPC_EMC->DYNAMICRC         = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICRFC        = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICXSR        = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICRRD        = NS2CLK(pclk, 14);
LPC_EMC->DYNAMICMRD        = 0x00000002;

TIM_Waitus(100);   /* wait 100ms */
LPC_EMC->DYNAMICCONTROL    = 0x00000183; /* Issue NOP command */

TIM_Waitus(200);   /* wait 200ms */
LPC_EMC->DYNAMICCONTROL    = 0x00000103; /* Issue PALL command */

LPC_EMC->DYNAMICREFRESH    = EMC_SDRAM_REFRESH(pclk,70); /* ( n * 16 ) -> 32 clock cycles */

//for(i = 0; i < 0x80; i++);           /* wait 128 AHB clock cycles */
TIM_Waitus(200);   /* wait 200ms */

tmpclk = (uint64_t)15625*(uint64_t)pclk/1000000000/16;
LPC_EMC->DYNAMICREFRESH    = tmpclk; /* ( n * 16 ) -> 736 clock cycles -> 15.330uS at 48MHz <= 15.625uS ( 64ms / 4096 row ) */

LPC_EMC->DYNAMICCONTROL    = 0x00000083; /* Issue MODE command */

//Timing for 48/60/72MHZ Bus
temp = *((volatile uint32_t *)(SDRAM_ADDR_BASE | (3<<4| 3)<<11)); /* 4 burst, 3 CAS latency */
temp = temp;
LPC_EMC->DYNAMICCONTROL    = 0x00000000; /* Issue NORMAL command */

//[re]enable buffers
LPC_EMC->DYNAMICCONFIG0    |= 1<<19;

}

***********************************************************************/


When I am test running the following test app, Code abruptly reaches Hardfault handler without even reaching the DelayMs function.
that time u32BankWordCounter is 0x00100000
if pExtDataPtr is unsigned short (16 bit) u32BankWordCounter is 0x00080000
if pExtDataPtr is unsigned int (32 bit) u32BankWordCounter is 0x00040000

/***********************************************************************
#define SDRAM_START_ADDRESS0x28000000
#define SDRAM_SIZE_BYTES(1024*1024*8)

unsigned char *pExtDataPtr = (unsigned char *)SDRAM_START_ADDRESS;

int main(void)
{
unsigned int u32BankWordCounter;
unsigned char FlagCorrupt;

DEBUGInit();
pExtDataPtr = (unsigned char*)SDRAM_START_ADDRESS;
{
for(u32BankWordCounter = 0; u32BankWordCounter < SDRAM_SIZE_BYTES; u32BankWordCounter++)
{
*(pExtDataPtr++) = (unsigned char)u32BankWordCounter;
}
}
DEBUG("\r\nWaiting...");
DelayMs(5000);
DEBUG("\r\nVerifing...");
FlagCorrupt = 0;
pExtDataPtr = (unsigned char*)SDRAM_START_ADDRESS;
for(u32BankWordCounter = 0; u32BankWordCounter < SDRAM_SIZE_BYTES; u32BankWordCounter++)
{
if(*(pExtDataPtr++) != (unsigned char)u32BankWordCounter)
{
FlagCorrupt = 1;
break;
}
}
while(1)
{

}
}
***********************************************************************/


Does any one has Idea why this is happening?
Please suggest any ideas to get this issue resolved

Thanks
Alastair


Outcomes