AnsweredAssumed Answered

SDRAM Mode register configuration

Question asked by Andrea Scauri on Aug 2, 2018
Latest reply on Aug 5, 2018 by jeremyzhou

Hello.

I have a problem during initialization of the SDRAM with set mode register :

wtemp =*(volatile unsigned int *)(DYNAMIC_MEM0_BASE+(MODE_REGISTER << (COL+TBW+BANK)));

sometime the execution block in this code line so much to trigger watchdog.

Does anyone have any idea what it could be?

 

 

SDRAM: MT48LC16M16A2P-75

MPU: LPC1778

 

Complete SDRAM init code 

 

uint32_t i, wtemp;

DbgUart2("> %s\n",__FUNCTION__);


SCS &=~BIT(1); //EMC reset when any resert occures // era EMC Shift Control

PCONP |= PCONP_PCEMC; // BIT(11); // Turn ON EMC PCLK

//EMC_DYN_RD_CFG = 0; // michele

EMCDLYCTL=0x00001010;

// Init SDRAM controller
EMC_CTRL = 1;// enable EMC
EMC_CONFIG = 0;

EMC_DYN_CFG0= ( (0uL << 14) | (0uL << 12) | (Sel9 << 9) | (Sel7 << 7));

/*Dynamic Memory RAS & CAS Delay registers
* 3 CAS PCLK cycles
* 3 RAS PCLK cycles
*/
EMC_DYN_RASCAS0 = (CAS << CAS_BIT) | (3uL << RAS_BIT);

//EMCDynamicReadConfig
EMC_DYN_RD_CFG = 1;

/*
* Dynamic Memory Percentage Command Period register
* The EMCDynamicTRP register enables you to program the precharge command period,
* tRP. This register must only be modified during system initialization. This value is normally
* found in SDRAM data sheets as tRP. This register is accessed with one wait state
*/
EMC_DYN_RP = P2C(SDRAM_TRP); // EMCDynamictRP
EMC_DYN_RAS = P2C(SDRAM_TRAS); // EMCDynamictRAS
EMC_DYN_SREX = P2C(SDRAM_TXSR); // EMCDynamictSREX Self Refresh Exit Time
EMC_DYN_APR = SDRAM_TAPR; // EMCDynamictDAL // Last Data Out to Active Time
EMC_DYN_DAL = SDRAM_TDAL + P2C(SDRAM_TRP); // Data in to Active Command Time
EMC_DYN_WR = SDRAM_TWR; // EMCDynamictWR // Write Recovery Time
EMC_DYN_RC = P2C(SDRAM_TRC); // EMCDynamictRC // Active to Active command Period
EMC_DYN_RFC = P2C(SDRAM_TRFC); // EMCDynamictRFC // Auto Refresh Period
EMC_DYN_XSR = P2C(SDRAM_TXSR); // EMCDynamictXSR // Exit Self Refresh
EMC_DYN_RRD = P2C(SDRAM_TRRD); // EMCDynamictRRD // Active Bank A to Active Bank B Time
EMC_DYN_MRD = SDRAM_TMRD; // EMCDynamictMRD = SDRAM_TMRD; // Load mode register to Active Command Time

Delay_uS(100*MSEC);

//Send command: NOP
EMC_DYN_CTRL = 3 | (3<<7);

// Mem clk enable, CLKOUT runs, send command: NOP
Delay_uS(200*MSEC);

//Send command: PRECHARGE-ALL, shortest possible refresh period
EMC_DYN_CTRL = 3 | (2<<7);
EMC_DYN_RFSH = 0x00000002;

//wait at least 128 ABH clock cycles
for(i=0; i<0x80; i++)
asm volatile(" nop");
//Delay_uS(100*MSEC);


/*
* Some systems refresh every row in a burst of activity involving all rows every 64 mS.
* Other systems refresh one row at a time staggered through out the 64 mS interval.
* For example, a system with 2^13 = 8192 rows would require a staggered refresh rate of one row
* every 7.8 µs which is 64 ms divided by 8192 rows
*/

/* set 28 x 16CCLKs=448CCLK=7us between SDRAM refresh cycles */
EMC_DYN_RFSH = P2C(SDRAM_REFRESH) >> 4;

DbgUart2("1 WDTC: %d, TV %d \n", WDTC, WDTV);

/* To set mode register in SDRAM, enter mode by issue
MODE command, after finishing, bailout and back to NORMAL mode. */

//Send command: MODE
EMC_DYN_CTRL = 3 | (1<<7);

DbgUart2("2 WDTC: %d, TV %d \n", WDTC, WDTV);
/* Set mode register in SDRAM */
/* Mode regitster table for Micron's MT48LCxx */
/* bit 9: Programmed burst length(0)
bit 8~7: Normal mode(0)
bit 6~4: CAS latency 3
bit 3: Sequential(0)
bit 2~0: Burst length is 8

You may calculate the shift value for "high-performance" SDRAM using this
formula:
SHIFT_HIGH_PERFORMANCE = COL + TBW + BANK, where
COL=# of column bits (here: 9)
TBW=total bus width, 1=16 bits, 2=32 bits (here: 2)
BANK=# of bank select bits (here: 2)
Just for completeness: For "low-power" SDRAM leave out the BANK term:
SHIFT_LOW_POWER = COL + TBW
*/

//Delay_uS(100*MSEC);
wtemp =*(volatile unsigned int *)(DYNAMIC_MEM0_BASE+(MODE_REGISTER << (COL+TBW+BANK)));

DbgUart2("3 WDTC: %d, TV %d \n", WDTC, WDTV);

EMC_DYN_CTRL = 0x00000000; /* Send command: NORMAL */

//Enable buffer
EMC_DYN_CFG0 |= BIT(19);

/* Abilito la ethernet per accedere alla 16K di ram */
//PCONP |= BIT(30);

DbgUart2("%s <\n",__FUNCTION__);

Outcomes