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,