I'm trying to configure the SDRAM for an i.MXRT1052 board embedding the Winbond SDRAM W9825G6JB-6I (16MB).
From the datasheet (attached), I've aligned as much as I could the settings, using the semc SDK example. But clearly, SDRAM configuration is a new subject for me, so I'm not fully confident.
/* Configure SDRAM. */
sdramconfig.csxPinMux = kSEMC_MUXCSX0;
sdramconfig.address = 0x80000000;
sdramconfig.memsize_kbytes = 16 * 1024; /* 16MB = 16*1024*1KBytes */
sdramconfig.portSize = kSEMC_PortSize16Bit;
sdramconfig.burstLen = kSEMC_Sdram_BurstLen8;
sdramconfig.columnAddrBitNum = kSEMC_SdramColunm_9bit;
sdramconfig.casLatency = kSEMC_LatencyThree;
sdramconfig.tPrecharge2Act_Ns = 18; /* Trp 18ns */
sdramconfig.tAct2ReadWrite_Ns = 18; /* Trcd 18ns */
sdramconfig.tRefreshRecovery_Ns = 72; /* Use the maximum of the (Trfc , Txsr). */
sdramconfig.tWriteRecovery_Ns = (1000000000 / clockFrq * 2); /* 2*Tck */
sdramconfig.tCkeOff_Ns = 42; /* The minimum cycle of SDRAM CLK off state. CKE is off in self refresh at a minimum period tRAS.*/
sdramconfig.tAct2Prechage_Ns = 42; /* Tras 42ns */
sdramconfig.tSelfRefRecovery_Ns = 67;
sdramconfig.tRefresh2Refresh_Ns = 60; /* Trc = 60ns */
sdramconfig.tAct2Act_Ns = 60; /* Trc = 60ns */
sdramconfig.tPrescalePeriod_Ns = 160 * (1000000000 / clockFrq);
sdramconfig.tIdleTimeout_Ns = 64 * 1000000; /* Tref = 64ms */
sdramconfig.refreshPeriod_nsPerRow = 64 * 1000000 / 8192; /* 64ms(Tref)/8192 cycles */
sdramconfig.refreshUrgThreshold = sdramconfig.refreshPeriod_nsPerRow;
sdramconfig.refreshBurstLen = 1;
The SDRAM can be properly initialized, but the first test in the example always fails:
/* 32Bit data read and write. */
SEMC_SDRAMReadWrite32Bit(); // <-- fails
/* 16Bit data read and write. */
SEMC_SDRAMReadWrite16Bit(); // <-- succeeds
/* 8Bit data read and write. */
SEMC_SDRAMReadWrite8Bit(); // <-- succeeds
Trying this for comparing:
/* 16Bit data read and write. */
SEMC_SDRAMReadWrite16Bit(); // <-- fails
/* 16Bit data read and write. */
SEMC_SDRAMReadWrite16Bit(); // <-- succeeds
/* 16Bit data read and write. */
SEMC_SDRAMReadWrite16Bit(); // <-- succeeds
It seems like the SDRAM is not properly written with the pattern, but only in the first test.
Any idea? Thanks.
Issue finally identified (timing issue).
The SEMC_DQS pin of the i.MXRT is used to adjust timing and must be left open.
Even if the pin_mux is configured in input, the SEMC_DQS pin must be left open on-board, with a parasitic capacitance as low as possible.
On our board, it was connected to an analog switch. Once the trace has been cut, the timing issue has been solved.