LPC4357 SDRAM test only half valid

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

LPC4357 SDRAM test only half valid

535 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by emfytech on Thu Nov 19 21:10:43 MST 2015
Hello,

I have connected a  ISSI IS42SM16400K-75BLI to the LPC4357.
Datasheet: http://www.mouser.com/ds/2/198/42SM-RM-VM16400K-258276.pdf

I am having two test functions:


uint32_t sdram_test( void )
{
  volatile uint32_t *wr_ptr;
  volatile uint16_t *short_wr_ptr;
  uint32_t data;
  uint32_t i, j;
  uint32_t uiGood = 0;
  uint32_t uiBad = 0;

  wr_ptr = (uint32_t *)SDRAM_BASE;
  short_wr_ptr = (uint16_t *)wr_ptr;

  /* 16 bit write */
  for (i = 0; i < SDRAM_SIZE/0x40000; i++)
  {
    for (j = 0; j < 0x100; j++)
    {
      *short_wr_ptr++ = (i + j) & 0xFFFF;
      *short_wr_ptr++ = ((i + j) + 1) & 0xFFFF;
    }
  }

  /* Verifying */
  wr_ptr = (uint32_t *)SDRAM_BASE;
  for (i = 0; i < SDRAM_SIZE/0x40000; i++)
  {
    for (j = 0; j < 0x100; j++)
    {
      data = *wr_ptr;
      if (data != (((((i + j) + 1) & 0xFFFF) << 16) | ((i + j) & 0xFFFF)))
      {
      uiBad++;
        //return 0x0;
      }
      else
      uiGood++;
      wr_ptr++;
    }
  }
  return 0x1;
}


This results in 4096 Good read/write and 4096 Bad read/write.

And a second test function:

uint32_t sdram_test2(void)
{
uint32_t *ramdata;
uint32_t uiGood = 0;
  uint32_t uiBad = 0;
  uint32_t i  = 0;

ramdata = (uint32_t *)SDRAM_BASE;
for(i=0;i < SDRAM_SIZE/4; i++){
*ramdata = i;
ramdata++;
}

 ramdata = (uint32_t *)SDRAM_BASE;
for(i=0;i < SDRAM_SIZE/4; i++){
if(*ramdata != i) {
uiBad++;
}
else
uiGood++;
ramdata++;
}

return 1;

}


This result in 1048592 Good read/write and 1048560 Bad read/write.

It seems partly initialized because it writes about 50% of the test function without any problems.
I just have trouble figuring out what this could be, I have tried changing timings but it all resulted in the same.

I am initializing the chip the following way:

uint32_t sdram_init (void)
{
  uint32_t temp;
  uint32_t emcclk;

  /* Select EMC clock-out */
  LPC_SCU->SFSCLK_0 = (MD_PLN | MD_EZI | MD_ZI | MD_EHS);
  LPC_SCU->SFSCLK_1 = (MD_PLN | MD_EZI | MD_ZI | MD_EHS);
  LPC_SCU->SFSCLK_2 = (MD_PLN | MD_EZI | MD_ZI | MD_EHS);
  LPC_SCU->SFSCLK_3 = (MD_PLN | MD_EZI | MD_ZI | MD_EHS);

  /* Setup EMC delays */
  LPC_SCU->EMCDELAYCLK = ((CLK0_DELAY) | (CLK0_DELAY << 4) | (CLK0_DELAY << 8) | (CLK0_DELAY << 12));

  /* EMC clock is half of CGU_BASE_M4 if CGU_BASE_M4 is >104 MHz */
  long SystemCoreClock = 204000000;
  if (SystemCoreClock > 104000000)
  {
    LPC_CCU1->CLK_M4_EMCDIV_CFG = ( (1<<0) | (1<<1) | (1<<2) | (1<<5) );
    LPC_CREG->CREG6 |= (1<<16);
    emcclk = SystemCoreClock / 2;
  }
  else
  {
    LPC_CCU1->CLK_M4_EMCDIV_CFG = ( (1<<0) | (1<<1) | (1<<2) | (0<<5) );
    LPC_CREG->CREG6 &= ~(1<<16);
    emcclk = SystemCoreClock;
  }

  LPC_EMC->CONTROL   = 0x00000001;
  LPC_EMC->CONFIG    = 0x00000000;
  LPC_EMC->DYNAMICCONFIG0    = 0<<14 | 1<<12 | 1<<9 | 1<<7; /* 64Mb, 1Mx16, 4 banks, row=12, column=8 */

  LPC_EMC->DYNAMICRASCAS0    = 0x00000303; /* 3 RAS, 3 CAS latency */
  LPC_EMC->DYNAMICREADCONFIG = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */

  LPC_EMC->DYNAMICRP         = NS2CLK(emcclk, 20); //tRP
  LPC_EMC->DYNAMICRAS        = NS2CLK(emcclk, 45); //tRAS
  LPC_EMC->DYNAMICSREX       = NS2CLK(emcclk, 80); //tXSR
  LPC_EMC->DYNAMICAPR        = 0x00000005;
  LPC_EMC->DYNAMICDAL        = NS2CLK(emcclk, 40); //tDAL
  LPC_EMC->DYNAMICWR         = NS2CLK(emcclk, 15); //tDPL
  LPC_EMC->DYNAMICRC         = NS2CLK(emcclk, 68); //tRC
  LPC_EMC->DYNAMICRFC        = NS2CLK(emcclk, 80); //tRFC
  LPC_EMC->DYNAMICXSR        = NS2CLK(emcclk, 80); //tXSR
  LPC_EMC->DYNAMICRRD        = NS2CLK(emcclk, 15); //tRRD
  LPC_EMC->DYNAMICMRD        = 0x00000002;

  chThdSleepMicroseconds(100);               /* wait 100us */
  LPC_EMC->DYNAMICCONTROL    = 0x00000183; /* Issue NOP command */

  chThdSleepMicroseconds(200);               /* wait 200us */
  LPC_EMC->DYNAMICCONTROL    = 0x00000103; /* Issue PALL command */

  LPC_EMC->DYNAMICREFRESH    = 2; /* ( n * 16 ) -> 32 clock cycles */

  chThdSleepMicroseconds(200);               /* wait 200us */

  /* (64ms / 4096 row) */
  LPC_EMC->DYNAMICREFRESH    = NS2CLK(emcclk, 64000000 / 4096)/16; /* ( n * 16 ) */

  LPC_EMC->DYNAMICCONTROL    = 0x00000083; /* Issue MODE command */

  temp = *((volatile uint32_t *)(SDRAM_BASE | (3<<4| 2)<<(9+2+2))); /* 4 burst, 3 CAS latency */
  temp = temp;
  LPC_EMC->DYNAMICCONTROL    = 0x00000000; /* Issue NORMAL command */

  //[re]enable buffers
  LPC_EMC->DYNAMICCONFIG0    |= 1<<19;

  return 1;
}


Does anyone have an idea what could be going on here or anything I could check?
Labels (1)
0 Kudos
Reply
2 Replies

466 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wmues on Fri Nov 20 06:56:25 MST 2015
Yes, burst == 4 is for 32bit data bus width, and burst == 8 for 16bit data bus width.
So each burst gives the same amount of bytes, regardless of the bus width.

Result: the performance of 32bit bus with is not the double of 16bit width. It's less.


0 Kudos
Reply

466 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by emfytech on Thu Nov 19 23:29:33 MST 2015
Finally got it to work, the burst had to be on 8 which was on 4.

So by changing this:

temp = *((volatile uint32_t *)(SDRAM_BASE | (3<<4| 2)<<(9+2+2))); /* 4 burst, 3 CAS latency */
temp = temp;


Into this:

  *((volatile uint32_t *)(SDRAM_BASE | ((3 | (3 << 4)) << (8 + 1))));


It passed both test successfully.
0 Kudos
Reply