Trouble getting SDRAM up and going

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

Trouble getting SDRAM up and going

446 Views
lpcware
NXP Employee
NXP Employee
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;
  }
Labels (1)
0 Kudos
5 Replies

391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bunrockter on Wed Sep 26 17:39:59 MST 2012
My problem was the timing register. I had to look at a different example before I found out that there was even a timing register. I think I have it set at 3.5 nS.
0 Kudos

391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bunrockter on Thu Aug 09 00:35:28 MST 2012
Crossworks support thinks it is a bad program in my flash? I booted from a different flash source and it didn't help. I ended up moving my files into a new project, and now it works?

Anyways, I followed your advice and tried to use ='s instead of oring with the registers, I am still not having much luck. I dropped my CPU clock down to 165 since the chip can only run at 166 & that keeps me from having to cut the EMCclock in half.

I put my code in a file this time so that formatting will be preserved. If anyone spots anything I don't I would greatly appreciate the help. right now when I write to the SDRAM and then try to do a read with my JTAG I get back different data every time.

Thanks,

Bun
0 Kudos

391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bunrockter on Tue Aug 07 23:08:07 MST 2012
Well, After I started my program and stopped it during the start up script I hit the reset button inside of crossworks, and magically all of my register went to their normal values? However when I switch PLL1 to external oscilator mode it dies :(

just about had the PLL1 worked out when it crapped out again, and now it is writing 0xFEFEFEFE to the registers, and the reset button isn't working. I am at a loss here
0 Kudos

391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bunrockter on Tue Aug 07 21:51:53 MST 2012
Thanks for the tip. I made the change, however, I am still having issues. I have commented out all of my SDRAM code, and I put a break point on the first functiuon that I call from SystemInit. That function sets the clock. As soon as I hit a break point. All of the registers in my debug windows read 0xfefefefe and the board CPU never returns control after I hit the execute line command. Any clue as to whats going on? Did I overwrite the boot code or something in ROM somehow?

Any help is appreciated. Thanks.
0 Kudos

391 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PhilYoung on Tue Aug 07 14:38:13 MST 2012
I would be inclined to follow the user manual rules more carefully on this register, i.e. do not simply or bits, it specifically states that bits 31:3 read as undefined but must NOT be set, so you should apply a mask when updating the EMC control register.
In  most cases it doesn't matter, but there are always exceptions.

0 Kudos