lpcware

SDRAM problems at >120Mhz

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by DT1 on Fri May 09 19:32:09 MST 2014
Hi,

our own-made board arrived today and I tried to run the code that was running fine on the MCB4357. Everything looks good, except for the SDRAM. Since it's not the same SDRAM that's on the MCB4357, I took the time to adjust the timings to the best of my knowledge, but I have those problems anyway:

- If I run the M4 at 120MHZ and the SDRAM at 120Mhz, it's working great.
- If I run the M4 at >120MHz and the SDRAM at M4CLK / 2, it's glitchy.

Glitchy means that is crashes the application, stalling in "HardFault_Handler". It always ends up there, but sometime it same some minutes. When not crashed, I can see my application running fine and I see on my LCD what I'm supposed to see, except there are various visual glitches on the display. Not always at the same place. Sometimes it's a line, sometimes some dots. But when I run at 120MHz, no problem.

*Note: On the MCB, I was running at 192MHz (12MHz * 16) and the SDRAM at 192MHz / 2 = 96MHz.

After a lot of research and code trying, here is my init function:


void SDRAM_Init()
{
uint32_t emcdivby2_buf[emcdivby2_szw];
uint32_t div = 0;
uint32_t n;

// Select and enable EMC branch clock
if (SystemCoreClock > 120000000UL)
{
// Use EMC clock divider and EMC clock output delay
div = 1;

// Following code must be executed in RAM to ensure stable operation
LPC_CCU1->CLK_M4_EMCDIV_CFG = (1 << 5) | (1 << 2) | (1 << 1) | 1;
LPC_CREG->CREG6 |= (1 << 16);       // EMC_CLK_DIV divided by 2
while (!(LPC_CCU1->CLK_M4_EMCDIV_STAT & 1));
}
else
{
LPC_CCU1->CLK_M4_EMC_CFG = (1 << 2) | (1 << 1) | 1;
while (!(LPC_CCU1->CLK_M4_EMC_STAT & 1));
}

// Set EMC clock output delay
LPC_SCU->EMCDELAYCLK = 0x7777;

// Configure EMC port pins
[...removed to shorten the post...]

LPC_EMC->CONTROL  = 0x00000001;       // EMC Enable
LPC_EMC->CONFIG   = 0x00000000;       // Little-endian, Clock Ratio 1:1

// Configure EMC clock-out pins
LPC_SCU->SFSCLK_0 = EMC_PIN_SET | 0;  // CLK0
LPC_SCU->SFSCLK_1 = EMC_PIN_SET | 0;  // CLK1
LPC_SCU->SFSCLK_2 = EMC_PIN_SET | 0;  // CLK2
LPC_SCU->SFSCLK_3 = EMC_PIN_SET | 0;  // CLK3
 
// Dynamic memory configuration (chip select 0)
// Set Address mapping: 128Mb(4Mx32), 4 banks, row len = 12, column len = 8
LPC_EMC->DYNAMICCONFIG0 = (1 << 14) |  // AM[14]   = 1
      (0 << 12) |  // AM[12]   = 0
      (2 <<  9) |  // AM[11:9] = 2
      (2 <<  7) ;  // AM[8:7]  = 2

LPC_EMC->DYNAMICRASCAS0    = 0x00000303;  // Latency: RAS 3, CAS 3 CCLK cyc.
LPC_EMC->DYNAMICREADCONFIG = 0x00000001;  // Command delayed by 1/2 CCLK

LPC_EMC->DYNAMICRP         = EMC_NANOSEC (20, SystemCoreClock, div);
LPC_EMC->DYNAMICRAS        = EMC_NANOSEC (45, SystemCoreClock, div);
LPC_EMC->DYNAMICSREX       = EMC_NANOSEC (70, SystemCoreClock, div);
LPC_EMC->DYNAMICAPR        = EMC_NANOSEC (70, SystemCoreClock, div);
LPC_EMC->DYNAMICDAL        = EMC_NANOSEC (70, SystemCoreClock, div);
LPC_EMC->DYNAMICWR         = EMC_NANOSEC (14, SystemCoreClock, div);
LPC_EMC->DYNAMICRC         = EMC_NANOSEC (68, SystemCoreClock, div);
LPC_EMC->DYNAMICRFC        = EMC_NANOSEC (68, SystemCoreClock, div);
LPC_EMC->DYNAMICXSR        = EMC_NANOSEC (70, SystemCoreClock, div);
LPC_EMC->DYNAMICRRD        = EMC_NANOSEC (14, SystemCoreClock, div);
LPC_EMC->DYNAMICMRD        = EMC_NANOSEC (30, SystemCoreClock, div);

WaitUs (100);
LPC_EMC->DYNAMICCONTROL    = 0x00000183;  // Issue NOP command
WaitUs (200);
LPC_EMC->DYNAMICCONTROL    = 0x00000103;  // Issue PALL command
WaitUs (200);
LPC_EMC->DYNAMICCONTROL    = 0x00000183;  // Issue NOP command
WaitUs (10);
LPC_EMC->DYNAMICREFRESH    = EMC_NANOSEC(  200, SystemCoreClock, div) / 16 + 1;
WaitUs (10);
LPC_EMC->DYNAMICREFRESH    = EMC_NANOSEC(15625, SystemCoreClock, div) / 16 + 1;
WaitUs (10);
LPC_EMC->DYNAMICCONTROL    = 0x00000083;  // Issue MODE command

// Mode register: Burst Length: 4, Burst Type: Sequential, CAS Latency: 3
WR_MODE(((3 << 4) | 2) << 12);

WaitUs (200);
LPC_EMC->DYNAMICCONTROL    = 0x00000002;  // Issue NORMAL command
LPC_EMC->DYNAMICCONFIG0   |= (1 << 19);   // Enable buffer
}


So, whenever I enable the CLK/2, I get problems. Since my SDRAM can go up to 166MHz, I tried to disable my code above where I enable the CLK/2 and ran the M4 at 156MHz. No luck, it crashes.

Some info on my system:
- LPC4357
- SDRAM: http://www.issi.com/WW/pdf/42-45S32800D.pdf

Anybody knows what I'm doing wrong??
Thanks for any insight DT

PS: I know that the SDRAM I have installed on the board is bigger than what is configured above, but one problem at a time :)

Outcomes