AnsweredAssumed Answered

SDRAM write/read order problem

Question asked by Tamas Novak on Dec 29, 2014
Latest reply on Feb 13, 2017 by Mootaz Amr
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
}

Outcomes