lpcware

Trouble getting SDRAM up and going

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by bunrockter on Tue Aug 07 00:32:29 MST 2012
I am using the Hitex LPC4350 eval board. I have been able to get it up and running and get my code going. It is now time to hook up an external LCD, but I need to have SDRAM working to have a place to store a frame buffer that is big enough.

First off I am seeing some weird behavior. I am using crossworks, and after initializing the RAM (I hope), when I look at it in the memory viewer the first 32 bit word will change its higher addressed 16 bits between 2 values when I request a memory read. Then eventually all of the memory becomes 0xAAAAAAAA including the registers. The JTAG can't stop the processor, I have to reset the board to get control back.

I have even and a verification error that tells me that the JTAG and what crossworks thought it programmed were not the same. A few times there were all A's and other times there were interleaved block that were invalid.

Now I am at the point, that as soon as I enter the break point on the first line of my code to initialize SDRAM the processor hangs, and I have to reset. If I comment out the call to the method things work just fine, and my other code works great.

Needless to say I am confused, as the first line of code is just a write to a bit int the ECM Control register that should already be set on reset. Is there something else going on? Anyways here is my code

Thanks,

Bun




  //EMC Config
  LPC_EMC->CONTROL |= (1UL);              //Enable EMC
  LPC_EMC->CONTROL |= (1UL << 2);         //Low Power Clocks
  LPC_EMC->CONTROL &= !(1UL << 1);        //Enable normal memory map mode
  LPC_EMC->CONFIG |= (1UL << 8);          //Set clk to half mode

  //clock configuration
  LPC_CCU1->CLK_M4_EMC_CFG |= (1 << 5);      //Set the clock divider into the emc to divide by 2
  LPC_CREG->CREG6 |= (1 << 16);

  //Configuration common to all dynamic memories
  //LPC_EMC->DYNAMICCONTROL       |= (1UL);         //Set All clocks high
  LPC_EMC->DYNAMICREFRESH       = N_TO_EMC_CLOCKS(15625UL)>>4;   // Multiples of 16 CLK (1=16)
  LPC_EMC->DYNAMICREADCONFIG    = N_TO_EMC_CLOCKS(1UL);          // Do not leave at 0
  LPC_EMC->DYNAMICRP            = N_TO_EMC_CLOCKS(18UL) - 1;     // tRP- (n+1 (my data sheet has tRP but no tPR
  LPC_EMC->DYNAMICRAS           = N_TO_EMC_CLOCKS(42UL) - 1;     // tRAS - (n+1) (Data sheet says 42-1000)
  LPC_EMC->DYNAMICSREX          = N_TO_EMC_CLOCKS(66UL) - 1;     // tSREX,tXSR- (n+1)
  LPC_EMC->DYNAMICAPR           = 3UL -1;                        // tAPR - n+1  (Not found in data sheet)
  LPC_EMC->DYNAMICDAL           = N_TO_EMC_CLOCKS(18UL) +2;      // tDAL,tAPW - 2 clk + trp (18ns)
  LPC_EMC->DYNAMICWR            = 2UL -1;                        // tWRt,tDPL,tRWL,,tRDL - (n+1)
  LPC_EMC->DYNAMICRC            = N_TO_EMC_CLOCKS(60UL) - 1;     // tRC - (n+1)
  LPC_EMC->DYNAMICRFC           = N_TO_EMC_CLOCKS(60UL) - 1;     // tRFC,tRC - (n+1)  TODO: couldn't find value used tRC
  LPC_EMC->DYNAMICXSR           = N_TO_EMC_CLOCKS(66UL) - 1;     // tXSR - (n+1)
  LPC_EMC->DYNAMICRRD           = N_TO_EMC_CLOCKS(12UL) - 1;     // tRRD - (n+1)
  LPC_EMC->DYNAMICMRD           = 2UL -1;                        // tMRD,tRSA - (n+1)


  //Configuration specific to each memory by chip select (only setting up chip select 0)
  //Address mapping for our part (IS42S16400F-6TL)
  // 14 12  11:9  8:7
  // 0  0   001   01   64 Mb (4Mx16), 4 banks, row length = 12, column length = 8  enhanced
  // 0  1   001   01   64 Mb (4Mx16), 4 banks, row length = 12, column length = 8  normal

  LPC_EMC->DYNAMICCONFIG0       |= (1UL << 7);    //AM0 12:7 Address mapping
  LPC_EMC->DYNAMICCONFIG0       |= (1UL << 9);
  LPC_EMC->DYNAMICCONFIG0       |= (1UL << 12);

  LPC_EMC->DYNAMICRASCAS0       |= (3UL);         //RAS latency
  LPC_EMC->DYNAMICRASCAS0       |= (3UL << 8);    //CAS latency picked from datasheet and drives all other values


  //Initialization of the SDRAM
  LPC_EMC->DYNAMICCONTROL = (1UL << 0) | (1UL << 1) | (0 << 7); //CS=1 CE=1 OP=Normal   Send idle
  waitUS(100);

  LPC_EMC->DYNAMICCONTROL = (1UL << 0) | (1UL << 1) | (2 << 7); //CS=1 CE=1 OP=Precharge  Send precharge
  LPC_EMC->DYNAMICREFRESH = 1;
  waitUS(100);
 
 
  LPC_EMC->DYNAMICREFRESH = N_TO_EMC_CLOCKS(15625UL) >>4;
  waitUS(100);

  LPC_EMC->DYNAMICCONTROL = (1UL << 0) | (1UL << 1) | (1 << 7); //CS=1 CE=1 OP=MODE Send mode

  uint32_t modeRegValue = 0;

  modeRegValue |= 3UL;         //8 burst
  modeRegValue |= (0UL << 3); //Sequential
  modeRegValue |= (3UL << 4); //CAS of 3
  modeRegValue |= (0UL << 7); //standard
  modeRegValue |= (0UL << 9); //programed

  modeRegValue = SDRAM0_ADDR + (modeRegValue << (8 + 1 + 2));
 
  modeRegValue = *((volatile uint32_t *)modeRegValue);  // Set mode register!
  waitUS(200);

  LPC_EMC->DYNAMICCONTROL = 0;//(0UL << 0) | (0UL << 1) | (0 << 7); //CS=0 CE=0 OP=MODE
  LPC_EMC->DYNAMICCONFIG0 = (1UL << 19);   //enable buffers



  //Mem Test
  volatile uint32_t * ramPtr = (volatile uint32_t *)(SDRAM0_ADDR);

  uint32_t testVal = 0x102;
  while((uint32_t)ramPtr < (SDRAM0_ADDR + 4000000UL))
  {
    *ramPtr = testVal;
    ++ramPtr;
    testVal += 0x101;
  }

Outcomes