lpcware

LPC4357 SDRAM test only half valid

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
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?

Outcomes