AnsweredAssumed Answered

SDRAM access problem(setup problem?)

Question asked by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by hiroto on Mon Sep 09 23:23:24 MST 2013
Hi.
I'm testing now for Micron MT48LC32M16A2 on lpc1788 system,
It is a 16bit 512Mbit SDRAM.
No problem in the sequential write (increment pattern)of 64byte .
problem occurs at a 65byte data write.
But all data is abnormal by writing at 65 or later access.
Please comment if there is a factor to be considered.

Best regards.
  
<sdram>
  MT48LC32M16A2  8Meg×16×4banks
  Refresh Count 8k
  Row Addressing 8K(A0-A12)
  Bank Addressing 4(BA0,BA1)
  Column Addressing 1k(A0-A9)
<clock>
CCLK 120MHz
        EMC Clock 60MHz

<conection>
  lpc1788    sdram
  A[12:0]    A[12:0]
  A[14:13]   BA[1:0]
  D[15:0]    D[15:0]
  CAS        CAS#
  RAS        RAS#
  CS         CS#
  CLK        CLK
  CKE        CKE
  DQMH       DQMH
  DQML       DQML


<EMC & sdram setting>

EMC Dynamic Config0
// RBC
    EMCDynamicConfig0_bit.AML = 0x11;  // RBC 512Mb(32M×16),4banks row length= 13,column length = 10
// BRC
    EMCDynamicConfig0_bit.AML = 0x31;  // BRC 512Mb(32M×16),4banks row length= 13,column length = 10
                                       // AML 0x11 ->Config0 (0x0880)
                                       // AML 0x31 ->Config0 (0x1880)
Mode Register access

// RBC  row address length 13(A12-A0),4banks,column address length 10(A9-A0)
// 2(bank)+10(col length)+1(16bit device,A0 not used)=13 shift value
    Dummy = *((volatile unsigned short *)(0xA0000000 | (0x31<<13)));  // RBC


//BRC   4banks,row address length 13(A12-A0),column address length 10(A9-0)
// 10(col length)+1(16bit device,A0 not used) = 11 shift value
    Dummy = *((volatile unsigned short *)(0xA0000000 | (0x31<<11)));  // BRC





<Test Procedure>
1)Test Program Download
2)reset
3)run and break on program (initialize,SDRAM Write data test,break)
4)dump test area

<Test program>

void  sdramTest(int tno)
{ unsigned char cdt;
  unsigned short sdt;
  unsigned idt;
  unsigned char  *src_ucp,*dst_ucp;
  unsigned short *src_usp,*dst_usp,ss;
  unsigned int   *src_uip,*dst_uip,ii,cc;

 
  // sequential bytes write 
  dst_ucp = (unsigned char *)0xa0000000;
  for(cc=0;cc<64;cc++)                  // <--- write 64bytes
  {  
   *dst_ucp++ = cc;
  }


>> good case
>> sdram display the contents of the program at the terminated.
>> 0xa0000000 to 0xa0000000+64 has Increment data , so good

a0000000  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
a0000010  10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
a0000020  20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
a0000030  30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
a0000040  02 41 02 43 02 43 02 43 02 43 02 43 02 43 02 43








  // sequential bytes write 
  dst_ucp = (unsigned char *)0xa0000000;
  for(cc=0;cc<64+1;cc++)                  // <--- write 64bytes
  {  
   *dst_ucp++ = cc;
  }
>> bad case
>> sdram display the contents of the program at the terminated.
>> 0xa0000000 to 0xa0000000+64 has not increment data , bad!!!!!!!!

a0000000  02 01 02 03 02 03 02 03 02 03 02 03 02 03 02 03
a0000010  12 11 12 13 12 13 12 13 12 13 12 13 12 13 12 13
a0000020  22 21 22 23 22 23 22 23 22 23 22 23 22 23 22 23
a0000030  32 31 32 33 32 33 32 33 32 33 32 33 32 33 32 33
a0000040  02 41 02 43 02 43 02 43 02 43 02 43 02 43 02 43





<initialize code>

void emc_configure_pin()
{

  IOCON_P2_16 = 0x21;    // EMC_CAS      (no pull-up/down) 
  IOCON_P2_17 = 0x21;    // EMC_RAS      (no pull-up/down)
  IOCON_P2_18 = 0x21;    // EMC_CLKOUT0  (no pull-up/down)
  IOCON_P2_20 = 0x21;    // EMC_DYCS0*   (no pull-up/down)
  IOCON_P2_24 = 0x21;    // EMC_CKEOUT0* (no pull-up/down)
  IOCON_P2_28 = 0x21;    // EMC_DQMOUT0  (no pull-up/down)
  IOCON_P2_29 = 0x21;    // EMC_DQMOUT1  (no pull-up/down)
  IOCON_P3_00 = 0x21;    // EMC_D[ 0]    (no pull-up/down)
  IOCON_P3_01 = 0x21;    // EMC_D[ 1]    (no pull-up/down)
  IOCON_P3_02 = 0x21;    // EMC_D[ 2]    (no pull-up/down)
  IOCON_P3_03 = 0x21;    // EMC_D[ 3]    (no pull-up/down)
  IOCON_P3_04 = 0x21;    // EMC_D[ 4]    (no pull-up/down)
  IOCON_P3_05 = 0x21;    // EMC_D[ 5]    (no pull-up/down)
  IOCON_P3_06 = 0x21;    // EMC_D[ 6]    (no pull-up/down)
  IOCON_P3_07 = 0x21;    // EMC_D[ 7]    (no pull-up/down)
  IOCON_P3_08 = 0x21;    // EMC_D[ 8]    (no pull-up/down)
  IOCON_P3_09 = 0x21;    // EMC_D[ 9]    (no pull-up/down)
  IOCON_P3_10 = 0x21;    // EMC_D[10]    (no pull-up/down)
  IOCON_P3_11 = 0x21;    // EMC_D[11]    (no pull-up/down)
  IOCON_P3_12 = 0x21;    // EMC_D[12]    (no pull-up/down)
  IOCON_P3_13 = 0x21;    // EMC_D[13]    (no pull-up/down)
  IOCON_P3_14 = 0x21;    // EMC_D[14]    (no pull-up/down)
  IOCON_P3_15 = 0x21;    // EMC_D[15]    (no pull-up/down)

  IOCON_P4_00 = 0x21;    // EMC_A[ 0]    (no pull-up/down)
  IOCON_P4_01 = 0x21;    // EMC_A[ 1]    (no pull-up/down)
  IOCON_P4_02 = 0x21;    // EMC_A[ 2]    (no pull-up/down)
  IOCON_P4_03 = 0x21;    // EMC_A[ 3]    (no pull-up/down)
  IOCON_P4_04 = 0x21;    // EMC_A[ 4]    (no pull-up/down)
  IOCON_P4_05 = 0x21;    // EMC_A[ 5]    (no pull-up/down)
  IOCON_P4_06 = 0x21;    // EMC_A[ 6]    (no pull-up/down)
  IOCON_P4_07 = 0x21;    // EMC_A[ 7]    (no pull-up/down)
  IOCON_P4_08 = 0x21;    // EMC_A[ 8]    (no pull-up/down)
  IOCON_P4_09 = 0x21;    // EMC_A[ 9]    (no pull-up/down)
  IOCON_P4_10 = 0x21;    // EMC_A[10]    (no pull-up/down)
  IOCON_P4_11 = 0x21;    // EMC_A[11]    (no pull-up/down)
  IOCON_P4_12 = 0x21;    // EMC_A[12]    (no pull-up/down)
  IOCON_P4_13 = 0x21;    // BA0 EMC_A[13]  (no pull-up/down)
  IOCON_P4_14 = 0x21;    // BA1 EMC_A[14]  (no pull-up/down)

  IOCON_P4_25 = 0x21;    // EMC_WE*      (no pull-up/down)
}


void emc_init()
{
    int i;
   
    volatile unsigned long Dummy;
    if(!(PCONP_bit.PCEMC)){
        PCONP_bit.PCEMC = 0x01;//電源、CLKの供給
    }
    emc_configure_pin();

   
    EMCCLKSEL_bit.EMCDIV = 1; // 120MHHz/1+(1)= 60MHz emcclk
   
    EMCDynamicConfig0_bit.B   = 0;  // Buffer disable
  
    EMCControl = 0; //disable
   
    for(Dummy = 0; Dummy<100000;Dummy++);
   
    //EMCStaticExtendedWait = 128;  // ?
   
    //EMCレジスタ設定   
    EMCDLYCTL_bit.CMDDLY = 31; //31;  // 7.75ns
    EMCDLYCTL_bit.FBCLKDLY = 31; //31;  // 7.75ns
    EMCDLYCTL_bit.CLKOUT0DLY = 31; //31;  // 7.75ns

    EMCControl = 1;//EMC enable
    
    EMCDynamicReadConfig = 1; //3; //2; //1;      // Clock out delayed strategy,using CLKOUT

    EMCDynamicRasCas0_bit.RAS = 3; //3; //2; RAS delay (CCLK)
    EMCDynamicRasCas0_bit.CAS = 3; //3; //2;
   
    EMCDynamictRP =  2;        //20nS 20nS*60MHz = 1.2 -> 2 
    EMCDynamictRAS = 3; //44nS  44nS*60MHz = 2.64 -> 3
    EMCDynamictSREX = 5; // 75nS 75nS*60MHz = 4.5 -> 5
    EMCDynamictAPR  = 5; // 5tCK?
    EMCDynamictDAL  = 5; // 6;          // 5tCK
    EMCDynamictWR   = 2; // 1CLK+7.5nS = 24nS -> 2tCK(33nS)
    EMCDynamictRC   = 4; // 66nS * 60MHz = 3.96 -> 4
    EMCDynamictRFC  = 4; // 4;          // 66nS * 60MHz = 3.96 -> 4
    EMCDynamictXSR  = 5; //8         // 75nS * 60MHz = 4.5 -> 5
    EMCDynamictRRD  = 15;         // 15tCK
    EMCDynamictMRD  = 2;          // 2tCK
   
    EMCDynamicConfig0_bit.MD = 0; // device is SDRAM
//  EMCDynamicConfig0_bit.AML = 0x11;  // RBC 512Mb(32M×16),4banks row length= 13,column length = 10
    EMCDynamicConfig0_bit.AML = 0x31;  // BRC 512Mb(32M×16),4banks row length= 13,column length = 10
                                       // AML 0x11 ->Config0 (0x0880)
                                       // AML 0x31 ->Config0 (0x1880)

    EMCDynamicConfig0_bit.B  = 0; // Buffer disable
    EMCDynamicConfig0_bit.P = 0;  // Writes not protect
      
// issue SDRAM NOP Command
    EMCDynamicControl = 0x00000183;
   for(volatile unsigned int kk = 2500; kk;kk--);
    

// issue SDRAM PRECHARGE Command
    EMCDynamicControl_bit.I   = 2;  // SDRAM PRECHARGE ALL command
    EMCDynamicRefresh = 1;
    for(volatile unsigned int kk = 2000; kk;kk--);  // > 128clk
    EMCDynamicRefresh = 27;        // (7.8uS*60MHz)/16 =29.25
   

// issue SDRAM MODE Command
    EMCDynamicControl_bit.I   = 1;  // SDRAM MODE command
   
//  Dummy = *((volatile unsigned short *)(0xA0000000 | (0x21<<13)));  // RBC
    Dummy = *((volatile unsigned short *)(0xA0000000 | (0x31<<11)));  // BRC
    EMCDynamicControl  = 0;  // SDRAM Normal Operation    
    EMCDynamicConfig0_bit.B   = 1;  // Buffer enable
}

Outcomes