SDRAM problems at >120Mhz

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SDRAM problems at >120Mhz

711 Views
lpcware
NXP Employee
NXP Employee
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
Labels (1)
0 Kudos
7 Replies

594 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Fri May 23 07:37:41 MST 2014
My experience is that there is not enough margin for the setup time --> write from MCU to SDRAM.
The read direction is less critical. The SDRAMs from ISSI seem to be the ones with the lowest margin, even if the timing in the data sheets look the same as e.g. for a Samsung SDRAM.

This can only be improved by delaying the SDRAM clock edges in relation to all other signals.
The alternative is to speed up all other things but not the clock. If you find a good way to do this please tell me   :p

From the 4 available clocks the CLK2 has the best timing (it comes last, you win about 0.2ns)
Use a capacitor on the SDRAM clock, this gives you another 0.4ns (depending on the frequency you run and on the capacitor value)

We are working on a new revision of the flash chip version (LPC4357) which solves this problem.

Regards,
NXP Support Team.
0 Kudos

594 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Tue May 20 18:08:56 MST 2014
Just tried it on two problematic boards. It didn't help :(
0 Kudos

594 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mc on Mon May 19 14:11:00 MST 2014
Hi DT1,
Also try to use combined clock function on CLK0 pin. It may help. Please see attached image
0 Kudos

594 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Mon May 19 12:06:57 MST 2014
Alright thanks, will try it.

On the 6 prototypes we have, 3 are working ok at CLK/2, 3 not. As I understand the errata, using CLK1 instead of CLK0 on the final product will make this problem disappear right? Or will I need a capacitor even on CLK1, just in case ??

Thanks
0 Kudos

594 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Wed May 14 06:01:29 MST 2014
Hello,

the following hardware patch will help:  connect a small capacitor (5.6 / 6.8 / 8.2pF) to the SDRAM clock. The effect of the capacitor is a delay of the edge which is important for setup time. Due to the asymmetric behaviour of the clock when the divider is switched on, we loose some margin on the setup time. With the capacitor delay we get something back.
Higher loads on data or address lines are bad, because then the edge in this signal moves into direction "bad", then you need to delay the SDRAM_CLK even more. But you need to be carful that you still have a good peak-to-peak signal for the clock, e.g. 0.1V - 3.2V

There is nothing you can do in software.

Regards,
NXP Support Team
0 Kudos

594 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DT1 on Sat May 10 20:58:16 MST 2014
Hi,

thanks for the quick response. Ok, so I looked at the errata and using CLK1 would help me. I'll look into that for a revision of the board, but right now the prototype uses CLK0 that is directly routed to the SDRAM. So I guess my only option for the prototype is to re-adjust the SDRAM timings.

But where do I start? Any timing register I should look into at first? Any suggestions? I'm not experienced with SDRAMS, so I don't know which timing is more critical than others and which timing should be adjusted when the CLK duty cycle is not 50%..

Thanks for any suggestion, I'll try everything I must to make this work!
0 Kudos

594 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mc on Sat May 10 10:09:15 MST 2014
Hi DT1,
In divide by two mode the duty cycle of SDRAM clock is not 50%. That may be the reason of your problem. You may have to re-adjust your SDRAM timings. Please see below errata

http://www.nxp.com/documents/errata_sheet/ES_LPC435X_3X_2X_1X_FLASH.pdf
0 Kudos