SDRAM self refresh

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SDRAM self refresh

2,497 Views
vincentlegarrec
Contributor I

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,

Labels (1)
0 Kudos
11 Replies

1,925 Views
vincentlegarrec
Contributor I

After few weeks, I think I solved the problem. At least, it looks better.

It first, I found a "impossible" case in my code that leave self-refresh during the "alim low" interrupt. I removed that code. I can't tell if that was the problem but it looks to work better.

Another thing is I still lose some random bit every time I program the LPC1778. I think it's because the JTAG freeze the CKE pin during programming while the SDRAM is not in self-refresh. Can someone confirm ?

For now, the problem is over.

Thanks for your help,

Vincent,

0 Kudos

1,925 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Vincent,

If the JTAG freezes the CKE pin and you are not in self-refresh mode then the SDRAM doesn't have any clock signal so it make sense that you lose some random bit. 

Regards,

Victor. 

0 Kudos

1,925 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Vincent LE GARREC,

Regarding your doubt that you are not sure you are actually entering the self-refresh mode. I was checking the example periph_memtest  of the LPCOpen. And when you reset the EMC module you go into self-refresh mode, I was able to see this change directly in the registers.

pastedImage_2.jpg

And after, in  the function initDynMem once you make all the configurations of the memory you change to normal mode by just writing to the DynamicControl register. At this point I'm able to see also in the register that I enter successfully to normal mode. 

pastedImage_4.jpg

Are you able to see these changes in your registers? This way you can be sure that you enter/exit correctly the self-refresh mode. 

You mentioned that there is something wrong with the power off. A good idea to see if the problem is due to you are powering off the LPC would be to send the memory to self-refresh mode, then send the LPC to a low power mode (where you keep the state of the pins) and when you wake up the LPC you can check the state of the memory.

Sending the LPC to a low power mode instead of powering off the entire LPC will help to maintain the state of the EMC lines. When you power off the LPC you lose immediately the state of the EMC lines but since the memory is still active you might be changing the configuration of the memory.     

Hope it helps!

Victor.

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------   

0 Kudos

1,925 Views
vincentlegarrec
Contributor I

Thanks for your long explanation.

Yes, I'm able to change the "SR" register from 0 to 1 and 1 to 0. The only difference I have with you is the CE register is always HIGH.

I tried to put this register on POWERSAVE just after writing the SR register to ENTER-SELF-REFRESH and write SR register to NORMAL_MODE at wake up but it's worse. I have much more bits corrupt.

The fact is I put the SDRAM in self refresh in case of low power. I need the memory even without main power (but with external battery). Thanks for pointing me about the state of the EMC lines. I checked the schematic. I have a door that force the CKE pin to down few time after the low power is detected. So I this time, the SDRAM is already in self-refresh when this door is activate and the LPC is not down.

I will check if the door is working as excepted. I also will try to sleep and to wake up the LPC.

Thanks, I will come back in few days after the tries.

0 Kudos

1,925 Views
vincentlegarrec
Contributor I

I made some tests. I have something wrong.

I can go on self-refresh with the following command :

            LPC_EMC->DynamicControl    = 0x00000103;    // Issue PALL command,
            delay_us(15);
            LPC_EMC->DynamicControl    = 0x00000183;    // Issue NOP command,
            delay_us(200);
            LPC_EMC->DynamicControl |= 1<<2;       //enter self-refresh mode
            while((LPC_EMC->Status&(1<<2))!=1<<2); //wait validation of self-refresh

At this point, I can't read anymore my external RAM.

Then I wait a while (1s)

Then I try to exit self-refresh with :

                LPC_EMC->DynamicControl |= 0x3 << 7;    // Issue NOP command,
                delay_us(200);
                LPC_EMC->DynamicControl &= ~(1<<2);       //exit self-refresh mode
                while((LPC_EMC->Status&(1<<2))!=0); //attente validation du mode self-refresh

But my LPC1778 crashes (I lose debug)

Do you have an idea what's wrong on my "exit self-refresh" function ?

Thanks,

0 Kudos

1,925 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Vincent LE GARREC,

Are you executing the code from the external RAM? 

Regards, 

Victor.

0 Kudos

1,925 Views
vincentlegarrec
Contributor I

No, the code is inside the microcontroller. Actually, I'm wondering if there is not nothing wrong with the schematic.

I made another test. I enter successfully (I think) in self-refresh with the code I posted two posts above. And I also successfully exit self-refresh (no lost of data) by running the same code I use to init the RAM (see my first post) WITHOUT shutting down the power.

So there's something wrong with power off.

I tried to use a bigger battery (3.6V) without success. I also tried to replace the external RAM (IS42S16800F-7TL) with another same RAM (MT48LC8M16A2P-6A:L) from another constructor and I have the same problem.

Regards,

0 Kudos

1,925 Views
vincentlegarrec
Contributor I

Hi,

Thanks for the link for lpcopen v2.10. I'm using an old one (v2.00). The code is very different so I will compare with mine.

To be more precise, my question is : on microcontroller' startup, my SDRAM is on self-refresh. How do you initialize the EMC and wake up the SDRAM? Do I have to follow the classic procedure then just add LPC_EMC->CONTROL &= ~(1 << 2); ?

And why do I am loosing some random bits ?

Thanks,

Regards,

0 Kudos

1,925 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello, 

Both examples mentioned before use the EMC interface, is a good starting point to understand how the External Memory Controller works. What I forgot to mentioned is that you can refer also to the periph_memtest demo in LPCOpen library to adjust the SDRAM initialization code to your needs. 

Regards, 

Victor.  

0 Kudos

1,925 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello  Vincent LE GARREC

The LPC1778 and the LPC1788 are from the same family, so you can use the examples provided in the LPCOpen for the LPC1788 as a guide for your project. 

You can download the LPCOpen from the following page: 

LPCOpen Software for LPC17XX|NXP 

You will find two examples that you can use: 

  1. nandflash_prog
  2. norflash_prog

Both examples use the EMC interface. 

Hope it helps!

Victor.

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos

1,925 Views
carstengroen
Senior Contributor II

Vincent is asking about _SDRAM_ and _SELF REFRESH_

How does the two samples you direct him to, have anything to do with this ???

0 Kudos