3
\$\begingroup\$

This is my PCB layout:

enter image description here

My problem is:

When i tried to Access SDRam with my example code (Memory test Code) everything seems ok. All the SDRam Data changes what i need. But when i tried to Access bunch of a place on SDRam, Data corrupts. Code is OK, i have tried the code on my eval. board and no problem ocurred. I could understand that if all the data corrupts on my every try.

Here are the codes with problem and without problem:

I will Show how memory has been effected.

First Photo Shows Successfull Read Write:

enter image description here

Second photo shows Faulty Datas:

enter image description here

And interesting one is Third Photo. I have changed nothing. just scroll up and down. And faulty data changes and move to the other places. if there is a read problem exist why doesnt it occurs when i use scroll, on memory window with successfull code tray. I hope photos can be helpfull.

enter image description here

This is my ground :

enter image description here

here is my working code simply. with no fault. Every time it Works perfectly.

   SDRAMInit();

wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
char_wr_ptr = (uint8_t *)wr_ptr;
/* Clear content before 8 bit access test */
_DBG_("Clear content of SDRAM...");
for ( i= 0; i < SDRAM_SIZE/4; i++ )
{
  *wr_ptr++ = 0x00;
}

/* 8 bit write */
_DBG_("Writing in 8 bits format...");
for (i=0; i<SDRAM_SIZE/4; i++)
{
  *char_wr_ptr++ = 0x11;
  *char_wr_ptr++ = 0x22;
  *char_wr_ptr++ = 0x33;
  *char_wr_ptr++ = 0x44;
}

/* verifying */
_DBG_("Verifying data...");
wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
for ( i= 0; i < SDRAM_SIZE/8; i++ )
{
    if ( *wr_ptr != 0x44332211 )    /* be aware of endianess */
    {
        /* byte comparison failure */
        _DBG_("Verifying fail, testing terminated!");
        while ( 1 );    /* fatal error */
    }
    wr_ptr++;
}

/* byte comparison succeed. */
_DBG_("Continue writing in 16 bits format...");
wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
short_wr_ptr = (uint16_t *)wr_ptr;

/* Clear content before 16 bit access test */
_DBG_("Clear content of SRAM...");
for ( i= 0; i < SDRAM_SIZE/4; i++ )
{
    *wr_ptr++ = 0;
}

/* 16 bit write */
_DBG_("Writing in 16 bits format...");
for (i=0; i<(SDRAM_SIZE/4); i++)
{
    *short_wr_ptr++ = 0x5AA5;
    *short_wr_ptr++ = 0xAA55;
}

/* Verifying */
wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;

//wr_ptr -= SDRAM_BASE_ADDR/4;
for ( i= 0; i < SDRAM_SIZE/4; i++ )
{
    if ( *wr_ptr != 0xAA555AA5 )    /* be aware of endianess */
    {
        /* 16-bit half word failure */
        _DBG_("Verifying fail, testing termintated!");
    while ( 1 );    /* fatal error */
    }
    wr_ptr++;
}

/* 16-bit half word comparison succeed. */

_DBG_("Verifying complete, testing terminated!");
    while(1);
\$\endgroup\$
  • \$\begingroup\$ What are IC5 and IC6 - also is it a double-sided board or are there power layers? \$\endgroup\$ – Andy aka Jan 6 '14 at 10:08
  • \$\begingroup\$ IC5->SDRAM and IC6->uC. There is no power planes. double-sided board. \$\endgroup\$ – freewave Jan 6 '14 at 10:17
  • \$\begingroup\$ If you performed memory operations at a slower rate i.e. giving times for address and chip select lines to settle, then allowing times for outputted data to settle does the problem reduce? I suspect that the main problem is earth plane problems. Maybe you can just post a picture of the blue side of the board to make it easier to see? Alternatively try bolstering up ground between CPU and RAM with copper tape to make a "fake" earth plane. Also, if you re-read continuously from one block of memory (no writing) do you get consistent results? \$\endgroup\$ – Andy aka Jan 6 '14 at 10:28
  • \$\begingroup\$ I've added my ground side. Yeah i slowed down my clock to 30 Mhz and still same problem occures. I've tried to write 0 to 0xFFFFFF in a for loop everything goes OK. And then readed them with a piece of code and verified. But when i tried to write part by part (16 bytes at Address A0001000 and then 50 bytes at Address A00010F5 for example) i see that totally corrupted datas. I will add clear photos of it. \$\endgroup\$ – freewave Jan 6 '14 at 10:48
  • \$\begingroup\$ Why are the address/control series terminations at the receive end of the PCB trace? \$\endgroup\$ – Brian Drummond Jan 6 '14 at 11:35
2
\$\begingroup\$

This is not an answer but more a long comment.

I think you may have some signal integrity and layout problems as some people noticed in comments:

  • First of all : you don't have a continuous GND plane under your SDRAM lines.

Your SDRAM lines need to have a controlled impedance. To do this we usually put a GND plane under traces and adjust the vertical distance to have the right impedance. When you have a GND "hole", you are making an impedance change and your signal will be altered. Also having via makes some impedance changes.

Here is your PCB layout with most impedance change highlighted, on some lines there is way to much impedance changes.

enter image description here

  • Second thing: it seems you haven't balanced the length of your traces.

Some are shorter than others. SDRAM specs should specified an authorized skew or length difference between traces.

As some people suggested, you should look at your signals with an oscilloscope. And maybe a logic analyzer to check the validity of your timings.

\$\endgroup\$
  • \$\begingroup\$ yes doesnt have a way just bottom of the trace(solid ground or power) but i've tried to provide a returning path for Data, Commands and clock. But yes it is a poor returning path. But that was the best i could do with double sided pcb. Second one it seems really long traces in here but they dont. Longest Data trace is 5,5 centimeter. shortest data line is nearly 3,5 centimeter. i think 2 centimeter is not a big deal for propogation delay. I will add a code to my first message that works properly . in fact i wonder that how that code works perfectly \$\endgroup\$ – freewave Jan 6 '14 at 17:17
  • \$\begingroup\$ As far I as I seen, each signal going to the SDRAM have at least one GND plane gap. You couldn't have a plain GND plane, but you could have optimized your routing (for example at the top right corner, tens of via for just one signal, why not the inverting ?). For traces skew it depends of the frequency, but I see short traces on the top right and very long going by the bottom and right side, if they belong to the data bus, that may be a problem. Check the SDRAM specs for the skew tolerance. And finally it may be a problem of skew plus impedance change at the same time. \$\endgroup\$ – zeqL Jan 6 '14 at 18:02
  • \$\begingroup\$ Do you have the layout of the eval board ? Is it a 2-sides PCB or 4-layers ? \$\endgroup\$ – zeqL Jan 6 '14 at 18:03
  • \$\begingroup\$ the trace you've pointed is clock signal. I didn't want to use via on it. So i had to use these tens of vias ob other traces. I have added my working code. I wonder that why this code Works properly. \$\endgroup\$ – freewave Jan 6 '14 at 18:20
  • \$\begingroup\$ no i dont have, just schematics. yes it is 4-layers. \$\endgroup\$ – freewave Jan 6 '14 at 18:22
0
\$\begingroup\$

About: "...just scroll up and down. And faulty data changes and move to the other places. if there is a read problem exist why doesnt it occurs when i use scroll, on memory window with successfull code tray."
The EMC of the LPC1788 has 4 small buffers for read/write (each buffer has 16 DWORDs). These buffers work as "cache" and can hide SDRAM access errors (if you would write and read back a small data block, you read from one of the buffers, without real SDRAM access).
Another effect you should be aware of: after writing to SDRAM over debugger you need to make 1-2 steps ("Step Into" in LPCXpresso) to see the SDRAM fault in memory browser.

\$\endgroup\$
0
\$\begingroup\$

You must place the SDRAM under the lpc1788 on the bottom layer and you must be carefull about GND on the bottom layer near the SDRAM. If you do this your tracks will be shortened and your PCB will work ok.

\$\endgroup\$
0
\$\begingroup\$

Check Your All Errors and write all errors Address, Source Data, Error Data in binary format. check which bit have error. is error in data bus or in address bus. then Fix that net (the filter of that net in Altium Designer is good technique). Excuse for my bad english

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.