AnsweredAssumed Answered

SDRAM self refresh

Question asked by Vincent LE GARREC on Aug 14, 2018
Latest reply on Sep 17, 2018 by Victor Jimenez

Dear,

 

I'm using a LPC1778 and an external SDRAM (IS42S16800F-7TL) controlled by EMC.
The memory has an external battery.

 

I have some trouble to put the SDRAM in self-refresh and to exit it.
I go in self-refresh when the input voltage is too low.

 

I do :

 

 

 

LPC_EMC->DynamicControl    = 0x00000103;    // Issue PALL command
for(volatile int i = 0; i < 512; i++);          // wait
LPC_EMC->DynamicControl    = 0x00000183;    // Issue NOP command
for(volatile int i = 0; i < 512; i++);          // wait
LPC_EMC->DynamicControl |= 1<<2;           //enter self-refresh mode
while((LPC_EMC->Status&(1<<2))!=1<<2);         //wait validation mode self-refresh

 

 

 

When the microcontroleur start up, I have about 100 wrong bits in 60Ko of external memory.
I have this problem with all cards we produced.

 

The code when the microcontroleur starts is the same no matter that the external memory is in self-refresh or not.

 

 

//EMC clock
if(CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) > 80000000)
{
    CLKPWR_SetCLKDiv(CLKPWR_CLKTYPE_EMC, 1); // CPU clock / 2
}
else
{
    CLKPWR_SetCLKDiv(CLKPWR_CLKTYPE_EMC, 0); // Same clock as CPU
}

 

delay_us(1000);

 

//EMC pin
for(i=0;i<16;i++)
    PINSEL_ConfigPin(3,i,1);    //D0 a D15
for(i=0;i<=16;i++)
    PINSEL_ConfigPin(4,i,1);    //A0 a A16

 

PINSEL_ConfigPin(4,25,1);    //WR WE
PINSEL_ConfigPin(4,24,1);    //OE
PINSEL_ConfigPin(4,26,1);    //BLS0    (driver bus)

 

PINSEL_ConfigPin(2,16,1);    //p2.16 EMC_CAS
PINSEL_ConfigPin(2,17,1);    //p2.17 EMC_RAS
PINSEL_ConfigPin(2,18,1);    //p2.18 EMC_CCLK emc_clk0

 

 PINSEL_ConfigPin(2,22,1);    //CS2    CS_SDRAM

 

PINSEL_ConfigPin(2,26,1);    //p2.26 EMC_CKE EMC_CKe2

 

PINSEL_ConfigPin(2,28,1);    //p2.28 EMC_DQML
PINSEL_ConfigPin(2,29,1);    //p2.29 EMC_DQMH

 

delay_us(1000);
//GPIO_OutputValue(2,26,1);
delay_us(1000);

 

LPC_SC->PCONP       |= 0x00000800;        //PCEMC = 1  Mise sous tension
LPC_SC->EMCDLYCTL   = 0x00001010;//0x1000
/*Set data read delay*/
LPC_SC->EMCDLYCTL |=(8<<8);                //FBCLKDLY 4<<8 mini
LPC_SC->EMCDLYCTL |= (0x08 <<16);

 

//LPC_EMC->Control     = 0x00000000;
LPC_EMC->Control     = 0x00000001;
LPC_EMC->Config      = 0x00000000;
LPC_SC->SCS |= 0x00000001;                //Disable Auto-Byte Addressing
//LPC_SC->SCS &= 0xFFFFFFFE;            //EMC Shift    Control
LPC_SC->SCS |= 0x00000004;                //Disable burst acces pour CS3
LPC_SC->SCS |= 0x00000002;                //Disable EMC reset

 

LPC_EMC->StaticExtendedWait=0;    //Extended wait enabled

 

 //SDRAM external
LPC_EMC->DynamicReadConfig=1;            //delay of CCLk with EMCCLKDELAY
LPC_EMC->DynamicRasCas2=0b1100000011;        //RAS latency:3cclk CAS latency:3cclk    //????
LPC_EMC->DynamicRP=calcul_nb_cclk(22);//20ns mini
LPC_EMC->DynamicRAS=calcul_nb_cclk(46);//44ns mini 100us maxi
LPC_EMC->DynamicSREX=calcul_nb_cclk(70);        //63+1.5ns mini
LPC_EMC->DynamicAPR=calcul_nb_cclk(21);                //??? no specification in datasheet
LPC_EMC->DynamicWR=MAX(calcul_nb_cclk(6)+2, calcul_nb_cclk(12));//2tck
LPC_EMC->DynamicDAL=calcul_nb_cclk(50);//tWR plus tRP
LPC_EMC->DynamicRC=calcul_nb_cclk(66);//66ns mini
LPC_EMC->DynamicRFC=calcul_nb_cclk(66);//66ns mini
LPC_EMC->DynamicXSR=calcul_nb_cclk(76);//75ns mini
LPC_EMC->DynamicRRD=calcul_nb_cclk(16);//15ns mini
LPC_EMC->DynamicMRD=3;                //2clk

 

LPC_EMC->DynamicConfig2=0x00000680;        //mode row bank column 256Mbits 16M*16bits col=9 row=13

 

 

 

// HERE I TRIED TO WRITE A DIFFERENT CODE BASED ON
// if ((LPC_EMC->Status&(1<<2))==0)
// BUT I DON'T KNOW WHAT TO WRITE.

// I know that I should write something like :

// delay_us(100);
// LPC_EMC->DynamicControl    = 0x00000183;    // Issue NOP command

// delay_us(100);

// LPC_EMC->DynamicControl &= ~(1<<2);        //exit self-refresh mode
// while((LPC_EMC->Status&(1<<2))!=0);     // wait exit mode self-refresh

// But this do not works.

// I try to replace the following code by these 4 lines but without success.

 

delay_us(100);
LPC_EMC->DynamicControl    = 0x00000183;    // Issue NOP command
delay_us(100);
LPC_EMC->DynamicControl    = 0x00000183;    // Issue NOP command
delay_us(100);
LPC_EMC->DynamicControl    = 0x00000103;    // Issue PALL command
LPC_EMC->DynamicRefresh    = 0x00000002;     // ( n * 16 ) -> 32 clock cycles
for(i= 128; i; --i);
LPC_EMC->DynamicRefresh=((EMCClock*(64000/4096)/16)/1000000);    //15.625us de refresh CCLk EMCClock
LPC_EMC->DynamicControl    = 0x00000083;     // Issue MODE command

 

// Lit la donnée volatile et le (void) dit qu'on s'en fout du retour.
(void) *((volatile uint32_t *)(0xC0000000 | (0x33<<12))); // 8 burst(128bit), 3 CAS latency  //bankbit:2 columnbit:9 16bits:1

 

LPC_EMC->DynamicControl    = 0x00000000; /* Issue NORMAL command */
LPC_EMC->DynamicConfig2    |= 0x00080000; // Buffer enable

 

 

 


Any help will be appreciated.
Thanks,

Attachments

Outcomes