LPC54608 SDRAM issue

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

LPC54608 SDRAM issue

Jump to solution
2,431 Views
gschelotto
Contributor V

Hi,

I've designed a custom board with LPC54608J512BD208 and IS42S16160J-7TLI following the OM13098 schematics (RevF) as a reference. Here's my current SDRAM connection

sdram.png

Everything goes well with the board... except the SDRAM test. I've run the lpcxpresso54608_emc_sdram example provided by the SDK (v2.7.0) and the test fails at line 24 of the next of SDRAM_AddressBusCheck function.

status_t SDRAM_AddressBusCheck(volatile uint32_t *address, uint32_t bytes)
{
 uint32_t pattern = 0x55555555;
 uint32_t size = bytes / 4;
 uint32_t offset;
 uint32_t checkOffset;

 /* write the pattern to the power-of-two address. */
 for (offset = 1; offset < size; offset <<= 1)
 {
 address[offset] = pattern;
 }
 address[0] = ~pattern;

 /* Read and check. */
 for (offset = 1; offset < size; offset <<= 1)
 {
 if (address[offset] != pattern)
 {
 return kStatus_Fail;
 }
 }

 if (address[0] != ~pattern)
 {
 return kStatus_Fail;
 }

 /* Change the data to the revert one address each time
 * and check there is no effect to other address. */
 for (offset = 1; offset < size; offset <<= 1)
 {
 address[offset] = ~pattern;
 for (checkOffset = 1; checkOffset < size; checkOffset <<= 1)
 {
 if ((checkOffset != offset) && (address[checkOffset] != pattern))
 {
 return kStatus_Fail;
 }
 }
 address[offset] = pattern;
 }
 return kStatus_Success;
}

In this case, address[0] = 0xaa2aaa2a so it does not match with the expected result (0x55555555). Previous loop (line 16) is terminated successfully.

On the other hand, here's is the IS42S16160J-7TLI SDRAM initialization

  

uint32_t dwtemp = dwtemp;
 uint32_t emcFreq;
 emc_basic_config_t basicConfig;

 emcFreq = CLOCK_GetEmcClkFreq();
 assert(emcFreq != 0); // Check the clock of emc
 // Basic configuration.
 basicConfig.endian = kEMC_LittleEndian;
 basicConfig.fbClkSrc = kEMC_IntloopbackEmcclk;
 // EMC Clock = CPU FREQ/2 here can fit CPU freq from 12M ~ 180M.
 // If you change the divide to 0 and EMC clock is larger than 100M
 // please take refer to emc.dox to adjust EMC clock delay.
 //

 basicConfig.emcClkDiv = 1;
 EMC_Init(EMC, &basicConfig);

 EMC->CONTROL = 1; // EMC controller active
 EMC->CONFIG = 0; // EMC configuration register to 0 according to the DATASHEET
 SYSCON->EMCDLYCTRL = 0x00001010;

 // EMC Memory map selection: 4M x 16bits x 4 banks (banks = 4; row = 13; column = 9):
 EMC->DYNAMIC[0].DYNAMICCONFIG = 0x00001680;

 // EMC Delays configuration selection
 EMC->DYNAMIC[0].DYNAMICRASCAS = 0x00000202; // 2 RAS, 2 CAS latency
 EMC->DYNAMICREADCONFIG = 0x00000001; // Command delayed strategy, using EMCCLKDELAY
 EMC->DYNAMICRP = 0x00000001; // ( n + 1 ) -> 2 clock cycles - Precharge to activate delay min 20nS --> 2 clock at 60Mhz
 EMC->DYNAMICRAS = 0x00000002; // ( n + 1 ) -> 3 clock cycles - Activate to precharge delay min 45ns --> 3 clock at 60Mhz
 EMC->DYNAMICSREX = 0x00000004; // ( n + 1 ) -> 5 clock cycles - SelfRegister exit time delay min 70nS --> 5 clock at 60Mhz
 EMC->DYNAMICAPR = 0x00000002; // ( n + 1 ) -> 3 clock cycles //??????????
 EMC->DYNAMICDAL = 0x00000004; // ( n + 0 ) -> 3 clock cycles - Data-in to activate delay 3.2 clocks at rounded to 4
 EMC->DYNAMICWR = 0x00000001; // ( n + 1 ) -> 2 clock cycles - Write recovery time 2 clock cycles
 EMC->DYNAMICRC = 0x00000003; // ( n + 1 ) -> 4 clock cycles - Active to active command period delay min 54ns --> 3.2 clock at 60Mhz
 EMC->DYNAMICRFC = 0x00000003; // ( n + 1 ) -> 4 clock cycles - Autorefresh to active comand period delay 54ns --> 3.2 clock at 60Mhz
 EMC->DYNAMICXSR = 0x00000003; // ( n + 1 ) -> 4 clock cycles - Exit self-refresh to active mode delay min 60ns --> 3.6 clock at 60Mhz
 EMC->DYNAMICRRD = 0x00000000; // ( n + 1 ) -> 1 clock cycles - Activate A to activate B delay 14nS --> 1 clock at 60Mhz
 EMC->DYNAMICMRD = 0x00000001; // ( n + 1 ) -> 2 clock cycles - Mode register to any command delay 2 clock cycles

 // SDRAM initialization
 SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);// wait 100ms to have the supply stable
 EMC->DYNAMICCONTROL = 0x00000183; // Issue NOP command
 SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);// Wait for some time to stabilization
 EMC->DYNAMICCONTROL = 0x00000103; // Issue PALL command to precharge the SDRAM
 EMC->DYNAMICREFRESH = 0x00000001; // Autorefresh must be as short as possible to precharge quickly the SDRAM !!!!!OJO habia 2
 SDK_DelayAtLeastUs(100000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);// Wait for autorefresh command to execute at least two times
 EMC->DYNAMICREFRESH = 0x0000003A; //Configure the right autorefresh cycle to th SDRAM

 EMC->DYNAMICCONTROL = 0x00000083; // Mode command for the SDRAM to configure the mode of operation
 dwtemp = *((volatile uint32_t *)(0xA0000000 | (0x23<<(10)))); // Force a command with the command in the address contents 8 burst, 2 CAS latency
 EMC->DYNAMICCONTROL = 0x00000000; // Normal command to SDRAM to operate
 EMC->DYNAMIC[0].DYNAMICCONFIG = 0x00081680; // Enable the buffers

Please could anyone help me with this issue? I also attach the mcuxpresso ide project.

regards,
gaston

1 Solution
2,229 Views
carstengroen
Senior Contributor II

Higher values for CMD_DELAY and FBCLK_DELAY ?

I use 0x1010 on 54608 running at 180 MHz and EMC at 90 MHz. I use the same value on projects with the 54628 running at 200 MHz and EMC at 100 MHz. This does not mean that it is a "universal value" that works for all. I could also be something else with the design/setup.

Have you tried all kinds of bit patterns to see if they work ?

pastedImage_1.png

View solution in original post

0 Kudos
9 Replies
2,229 Views
carstengroen
Senior Contributor II

Gaston,

in all my designs with 54608, 54628 and SDRAM (and also on the NXP eval board!) I need to add:

SYSCON->EMCDLYCTRL = 0x1010; // Handles EMC clock=90 MHz !!!

to get the SDRAM to work properly.

0 Kudos
2,229 Views
gschelotto
Contributor V

Hi Carsten, The SYSCON->EMCDLYCTRL register is already set as you suggested. See line 20 of my SDRAM initialization.

regards,
gaston

2,229 Views
carstengroen
Senior Contributor II

Oh sorry! Didn't see that one!

Have you tried with even more conservative values in this register ?

0 Kudos
2,229 Views
gschelotto
Contributor V

More conservative values? Could you provide any example?
gaston

0 Kudos
2,230 Views
carstengroen
Senior Contributor II

Higher values for CMD_DELAY and FBCLK_DELAY ?

I use 0x1010 on 54608 running at 180 MHz and EMC at 90 MHz. I use the same value on projects with the 54628 running at 200 MHz and EMC at 100 MHz. This does not mean that it is a "universal value" that works for all. I could also be something else with the design/setup.

Have you tried all kinds of bit patterns to see if they work ?

pastedImage_1.png

0 Kudos
2,229 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Gaston,

pls try to adjust the setting of the EMC clock delay control register and check if you get improvement as Garsten said.

BR

Xiangjun Rong

0 Kudos
2,229 Views
gschelotto
Contributor V

At the end I have come to the conclusion that the PCB design (routing, stack-up) is not very suitable for the required SDRAM speeds. I will have to redo the design prioritizing this point.

Xiangjun & Carsten, thank you both for the given support.

regards,
gaston

2,229 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Gaston,

From your description, I see that you use the similar SDRAM chip as the that of LPC54608 evaluation board and the example code in SDK package. I think the code is okay, because most of reading data are correct.

Regarding the issue that you write address[0]=0xaaaaaaaa, but you read as 0xaa2aaa2a, obviously, the D7 is read as 0 which should have been 1. I think it is a hardware issue, for high speed SDRAM access, you have to consider the signal integrity, in other words, 4 layers board, all data bus pins should connect to a serial resistor which locates as close as possible to the SDRAM data bus. BTW, if you decrease the SDRAM clock frequency, what is the result?

BR

Xiangjun Rong

0 Kudos
2,229 Views
gschelotto
Contributor V

Hi Xiangjun, I'm not sure is a Harware issue.The design includes a 4-layer PCB (one internal layer as solid GND) and the distribution is close enough (I hope) with the 22R resistors connected to the data bus.

sdram2.png

Indeed the sdram test fails at the mentioned line. However if I write (outside from the test routine) ~0x55555555 at 0xA0000000 and read back from the same address I get 0xAAAAAAAA as expected.

In fact, there is no problem if I write/read back a 32-bit word to/from any SDRAM address in this way:

*(uint32_t *)(sdram) = ~0x55555555;
    readData = *(uint32_t *)(sdram);‍‍‍‍

Why can't I pass the full test?

It's really puzzled me.

I've also tested it with lower EMC clks for example:

basicConfig.emcClkDiv = 1, 2, 3, 4, 5 and even 6 without success...

gaston

0 Kudos