cancel
Showing results for 
Search instead for 
Did you mean: 

SDRAM write/read order problem

Tamas Novak
Associate III
Posted on December 29, 2014 at 15:09

My project contains a STM32F429 and a AS4C4M16S SDRAM (own designed PCB)

I have tested writing-reading by the next function:

void    SDRAM_TEST(void) {

int i;

int err=0;

int ok=0;

HAL_StatusTypeDef ret;

#define TEST_ARRAY_SIZE_WORD   10000

uint16_t x1[TEST_ARRAY_SIZE_WORD];

uint16_t x2[TEST_ARRAY_SIZE_WORD];

for (i=0; i<TEST_ARRAY_SIZE_WORD; i++) {    //random data into the buffer

    x1[i]= rand();

    }   

ret= HAL_SDRAM_Write_16b(&hsdram, SDRAM0, x1, TEST_ARRAY_SIZE_WORD);    //write to SDRAM

ret= HAL_SDRAM_Read_16b(&hsdram, SDRAM0, x2,  TEST_ARRAY_SIZE_WORD);    //reading SDRAM back into other buffer

for (i=0; i<TEST_ARRAY_SIZE_WORD; i++) {

    if (x1[i] != x2[i])      err++; else     ok++;    //check if fits

    }   

 }

Surprisingly the ''err'' and ''ok'' values came out as 5000-5000!

The debug values of x1 and x2 arrays are

0   f42d   a01d

1   8ccf    8ccf

2   f646    f42d

3   3129   3129

4   5b04   f646

5   5db4   5db4

6   7f78    5b04

7   59d8   59d8

...

So even words are fine, odd words are shifted.

It seems to be a word-order problem.

Internally two 16-bit words are probably linked into one 32bit word, and

the problem must be there somewhere...

full code for FMC init is

void MX_FMC_Init(void) {    //**********************************************

int i;

HAL_StatusTypeDef  ret;  

FMC_SDRAM_TimingTypeDef  timing;

hsdram.Instance = FMC_SDRAM_DEVICE;    //Perform the SDRAM1 memory initialization sequence

hsdram.Init.SDBank = FMC_SDRAM_BANK1;

hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;

hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;

hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;

hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;

hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;

hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;

hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;  

hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;

hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;    //1??

//168MHz, tcycle= 11.9nsec

timing.LoadToActiveDelay= 2;    // TMRD: 2 Clock cycles

timing.ExitSelfRefreshDelay= 7;    //TXSR: min=65ns (6x11.9ns)   

timing.SelfRefreshTime= 5;            //TRAS: min=49ns (5x11.90ns)

timing.RowCycleDelay= 7;            //TRC:  min=63 nsec (6x11.90ns)

timing.WriteRecoveryTime= 2;    //TWR:  2 Clock cycles

timing.RPDelay= 2;                        //TRP:  min=21nsec  (2x11.90ns)

timing.RCDDelay= 2;                    //TRCD: min=21nsec (2x11.90ns )

ret= HAL_SDRAM_Init(&hsdram, &timing);        //Initialize the SDRAM controller

if(ret != HAL_OK)   {

    i= 99;   //bp here debug

    }

SDRAM_Initialization_Sequence(&hsdram);   //Program the SDRAM external device

}

void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram) {    //***********************************************

//static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Cmd) {    //***********************************************

FMC_SDRAM_CommandTypeDef Cmd;

__IO uint32_t tmpmrd =0;

Cmd.CommandMode= FMC_SDRAM_CMD_CLK_ENABLE;    //Step 3:  Configure a clock configuration enable command

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 1;

Cmd.ModeRegisterDefinition= 0;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000);    //Send the command

HAL_Delay(100);    //Step 4: Insert 100 ms delay

Cmd.CommandMode= FMC_SDRAM_CMD_PALL;    //Step 5: Configure a PALL (precharge all) command

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 1;

Cmd.ModeRegisterDefinition= 0;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000);

Cmd.CommandMode= FMC_SDRAM_CMD_AUTOREFRESH_MODE;    //Step 6 : Configure a Auto-Refresh command

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 4;

Cmd.ModeRegisterDefinition= 0;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000);

tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2          |        //Step 7: Program the external memory mode register

                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |

                     SDRAM_MODEREG_CAS_LATENCY_3           |

                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |

                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

Cmd.CommandMode= FMC_SDRAM_CMD_LOAD_MODE;

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 1;

Cmd.ModeRegisterDefinition= tmpmrd;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000);

    /* Step 8: Set the refresh rate counter

64msec / 4096 fresh = 15.62 us

refresh count= 15.62usec * 84MHz  - 20 =  1292 */

HAL_SDRAM_ProgramRefreshRate(hsdram, 1292);     //refresh count

}

5 REPLIES 5
bmh
Associate II
Posted on November 22, 2015 at 18:55

Hi, I'm facing a similar problem with same SDRAM. Can you publish the configuration that worked for you?

Thanks,

Posted on December 29, 2014 at 15:45

> So even words are fine, odd words are shifted.

You mean, odd halfwords are fine, even are shifted.

What is the result of direct reading, after the above test, e.g. if you add

somevariable = *(uint16_t *)SDRAM0;

someothervariable = *(uint32_t *)SDRAM0;

after the above test, what are the x1[]/x2[]/somevariable/someothervariable?

JW

Tamas Novak
Associate III
Posted on December 30, 2014 at 20:47

Thanks, Jan,

the FMC_SDRAM_CMD_LOAD_MODE   command in SDRAM_Initialization_Sequence() was bad.  I have simply copied the Mode parameters from some example code, which was for a different type of SDRAM...it was a miracle that even half of bytes fitted:)))

I couldn't clearly understand how that happened...

but now it's 10k/10k good!!!

thanks,

 Tamas

Posted on February 03, 2017 at 16:44

I'm a bit late, but here is the working source:

void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram) { //***********************************************

//static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Cmd) { //***********************************************

FMC_SDRAM_CommandTypeDef Cmd;

__IO uint32_t tmpmrd =0;

Cmd.CommandMode= FMC_SDRAM_CMD_CLK_ENABLE; //Step 3: Configure a clock configuration enable command

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 1;

Cmd.ModeRegisterDefinition= 0;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000); //Send the command

HAL_Delay(100); //Step 4: Insert 100 ms delay

Cmd.CommandMode= FMC_SDRAM_CMD_PALL; //Step 5: Configure a PALL (precharge all) command

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 1;

Cmd.ModeRegisterDefinition= 0;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000);

Cmd.CommandMode= FMC_SDRAM_CMD_AUTOREFRESH_MODE; //Step 6 : Configure a Auto-Refresh command

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 4;

Cmd.ModeRegisterDefinition= 0;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000);

tmpmrd = (uint32_t) //Step 7: Program the external memory mode register

      0x0200 | //bit9: write burst length 1=single bit

      0x0000 | //bit 8..7: test mode=0 normal mode

      0x0020 | //bit 6..4: cas latency= 2

      0x0000 | //bit 3: burst type=1 sequential

      0x0000; //bit 2..0: burst length= 1 word

Cmd.CommandMode= FMC_SDRAM_CMD_LOAD_MODE;

Cmd.CommandTarget= FMC_SDRAM_CMD_TARGET_BANK1;

Cmd.AutoRefreshNumber= 1;

Cmd.ModeRegisterDefinition= tmpmrd;

HAL_SDRAM_SendCommand(hsdram, &Cmd, 0x1000);

/* Step 8: Set the refresh rate counter

64msec / 4096 fresh = 15.62 us

refresh count= 15.62usec * 84MHz - 20 = 1292 */

HAL_SDRAM_ProgramRefreshRate(hsdram, 1292); //refresh count

}
Mootaz Amr
Associate II
Posted on February 13, 2017 at 16:49

Hi Thomas Novak

Ihave a custom made board around an STM32F429IIT6 connected to an external SDRAM AS4C4M16SA, I followed initialization steps embedded in the STM32F429 Reference Manual

/external-link.jspa?url=http%3A%2F%2Fwww.st.com%2Fcontent%2Fccc%2Fresource%2Ftechnical%2Fdocument%2Freference_manual%2F3d%2F6d%2F5a%2F66%2Fb4%2F99%2F40%2Fd4%2FDM00031pdf%2Ffiles%2FDM00031pdf%2Fjcr%3Acontent%2Ftranslations%2Fen.DM00031pdf

page 1663, and the Power Up sequence described in Note 11 of the AS4C4M16SA

/external-link.jspa?url=http%3A%2F%2Fwww.alliancememory.com%2Fpdf%2Fdram%2F64M-AS4C4M16SA.pdf

page

I configured also the same settings and initialization stepsthat you usedbutit fails for me.

Iused previously the MT48LC4M16 chip and it works fine, but the PCB design has changed and the old code doesn't fit the new AS4C4M16SA, the pins of the 2 chips are the same, and connections with the microcontroller are then the same.

Iuploaded my configuration files, my test functions, my serial_debug results and my schematic related to the memory power and pins.

Is there any difference inmy and your schematics ? Is there any problem with my code ?

I don't think that the problem is from a difference in the used libraries,CMSIS (for my case) and HAL

(for yours)arealmost the same especially for the SDRAM controller, and migrating toHAL library isn't a solution since I will be forcedto rewrite the wholeproject.

Thanks

________________

Attachments :

Schematic and config Files.rar : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hyvn&d=%2Fa%2F0X0000000bE6%2FF0LAei5EkL4yZ8xgOI73RcJmHvXpUXtT7uosBBWwCbU&asPdf=false