lpcware

LPC1788 and EMC write/read issues

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by ImaginationStation on Mon Nov 18 10:01:21 MST 2013
Hello, I am using an LPC1788 and a 128MB SDRAM chip IS42S32400E-6TL

The problem is that information is either written or read incorrectly on the SDRAM and it only does it when the board with the chips are cold. It also did the same thing with other brand SDRAM chips.

I started working with this combination about 6 months ago. At the time my workbench was in a warm area where the temperatures were commonly above 25C. At the time there was not a problem, it ran flawlessly. I recently moved and my work area ended up in the basement where temperatures range between 18C and 21C. Now once the board is started up from cold it always has the problem, and if the board temperatures get high enough it will stop reading/writing to the EMC incorrectly.

I’m having a hard time figuring out if it is on the read or the write. I believe the issue may be isolated to the reads only and here’s why I believe that. In my application I initialize the EMC to be able to display things on the LCD. When I write to the memory area that maps the display area it displays correctly. But if I read from anything on the display area and rewrite to that same address some of the pixels will display incorrectly.

Since the problem doesn’t exist when it’s warm I believe it could have something to do with my SDRAM setup/initialization.

Here is my initialization sequence:

static void _EMC_Init(void) {
  volatile uint32_t CmdDly;
  volatile uint32_t Dummy;
  volatile uint32_t i;

  LPC_SC->PCONP     |= (1 << 11);   // Turn on EMC peripheral clock
  LPC_SC->EMCDLYCTL  = 0x00001010;
  LPC_EMC->Control   = 1;           // EMC enable
  LPC_EMC->Config    = 0;
  //
  // Port init
  //

  LPC_IOCON->P3_0  = 1;  // D0
  LPC_IOCON->P3_1  = 1;  // D1
  LPC_IOCON->P3_2  = 1;  // D2
  LPC_IOCON->P3_3  = 1;  // D3
  LPC_IOCON->P3_4  = 1;  // D4
  LPC_IOCON->P3_5  = 1;  // D5
  LPC_IOCON->P3_6  = 1;  // D6
  LPC_IOCON->P3_7  = 1;  // D7
  LPC_IOCON->P3_8  = 1;  // D8
  LPC_IOCON->P3_9  = 1;  // D9
  LPC_IOCON->P3_10 = 1;  // D10
  LPC_IOCON->P3_11 = 1;  // D11
  LPC_IOCON->P3_12 = 1;  // D12
  LPC_IOCON->P3_13 = 1;  // D13
  LPC_IOCON->P3_14 = 1;  // D14
  LPC_IOCON->P3_15 = 1;  // D15
  LPC_IOCON->P3_16 = 1;  // D16
  LPC_IOCON->P3_17 = 1;  // D17
  LPC_IOCON->P3_18 = 1;  // D18
  LPC_IOCON->P3_19 = 1;  // D19
  LPC_IOCON->P3_20 = 1;  // D20
  LPC_IOCON->P3_21 = 1;  // D21
  LPC_IOCON->P3_22 = 1;  // D22
  LPC_IOCON->P3_23 = 1;  // D23
  LPC_IOCON->P3_24 = 1;  // D24
  LPC_IOCON->P3_25 = 1;  // D25
  LPC_IOCON->P3_26 = 1;  // D26
  LPC_IOCON->P3_27 = 1;  // D27
  LPC_IOCON->P3_28 = 1;  // D28
  LPC_IOCON->P3_29 = 1;  // D29
  LPC_IOCON->P3_30 = 1;  // D30
  LPC_IOCON->P3_31 = 1;  // D31

  LPC_IOCON->P4_0  = 1;  // A0
  LPC_IOCON->P4_1  = 1;  // A1
  LPC_IOCON->P4_2  = 1;  // A2
  LPC_IOCON->P4_3  = 1;  // A3
  LPC_IOCON->P4_4  = 1;  // A4
  LPC_IOCON->P4_5  = 1;  // A5
  LPC_IOCON->P4_6  = 1;  // A6
  LPC_IOCON->P4_7  = 1;  // A7
  LPC_IOCON->P4_8  = 1;  // A8
  LPC_IOCON->P4_9  = 1;  // A9
  LPC_IOCON->P4_10 = 1;  // A10
  LPC_IOCON->P4_11 = 1;  // A11
  LPC_IOCON->P4_12 = 1;  // A12
  LPC_IOCON->P4_13 = 1;  // A13
  LPC_IOCON->P4_14 = 1;  // A14
  LPC_IOCON->P4_15 = 1;  // A15
  LPC_IOCON->P4_16 = 1;  // A16
  LPC_IOCON->P4_17 = 1;  // A17
  LPC_IOCON->P4_18 = 1;  // A18
  LPC_IOCON->P4_19 = 1;  // A19
  LPC_IOCON->P4_20 = 1;  // A20
  LPC_IOCON->P4_21 = 1;  // A21
  //LPC_IOCON->P4_22 = 1;  // A22
  //LPC_IOCON->P4_23 = 1;  // A23

  LPC_IOCON->P4_24 = 1;  // OE
  LPC_IOCON->P4_25 = 1;  // WE
  LPC_IOCON->P4_26 = 1;  // BLS0
  LPC_IOCON->P4_27 = 1;  // BLS1
  LPC_IOCON->P4_28 = 1;  // BLS2
  LPC_IOCON->P4_29 = 1;  // BLS3
  LPC_IOCON->P4_30 = 1;  // CS0
  LPC_IOCON->P4_31 = 1;  // CS1
  LPC_IOCON->P2_14 = 1;  // CS2
  LPC_IOCON->P2_15 = 1;  // CS3
  LPC_IOCON->P2_16 = 1;  // CAS
  LPC_IOCON->P2_17 = 1;  // RAS
  LPC_IOCON->P2_18 = 1;  // CLKOUT0
  //LPC_IOCON->P2_19 = 1;  // CLKOUT1
  LPC_IOCON->P2_20 = 1;  // DYCS0
  //LPC_IOCON->P2_21 = 1;  // DYCS1
  //LPC_IOCON->P2_22 = 1;  // DYCS2
  //LPC_IOCON->P2_23 = 1;  // DYCS3
  LPC_IOCON->P2_24 = 1;  // CKEOUT0
  //LPC_IOCON->P2_25 = 1;  // CKEOUT1
  //LPC_IOCON->P2_26 = 1;  // CKEOUT2
  //LPC_IOCON->P2_27 = 1;  // CKEOUT3
  LPC_IOCON->P2_28 = 1;  // DQMOUT0
  LPC_IOCON->P2_29 = 1;  // DQMOUT1
  LPC_IOCON->P2_30 = 1;  // DQMOUT2
  LPC_IOCON->P2_31 = 1;  // DQMOUT3
  //
  // Setup EMC config for SDRAM, timings for 60MHz bus
  //
  LPC_EMC->DynamicConfig0    = 0x00005500;  // 128MB, 4Mx32, 4 banks, 12 rows, 9 columns, buffers disabled
  LPC_EMC->DynamicRasCas0    = 0x00000202;  // 2 RAS, 2 CAS latency */
  LPC_EMC->DynamicReadConfig = 0x00000001;  // Command delayed strategy, using EMCCLKDELAY
  LPC_EMC->DynamicRP         = 0x00000001;  // n + 1 clock cycles
  LPC_EMC->DynamicRAS        = 0x00000003;  // n + 1 clock cycles
  LPC_EMC->DynamicSREX       = 0x00000005;  // n + 1 clock cycles
  LPC_EMC->DynamicAPR        = 0x00000002;  // n + 1 clock cycles
  LPC_EMC->DynamicDAL        = 0x00000003;  // n     clock cycles
  LPC_EMC->DynamicWR         = 0x00000001;  // n + 1 clock cycles
  LPC_EMC->DynamicRC         = 0x00000004;  // n + 1 clock cycles
  LPC_EMC->DynamicRFC        = 0x00000004;  // n + 1 clock cycles
  LPC_EMC->DynamicXSR        = 0x00000005;  // n + 1 clock cycles
  LPC_EMC->DynamicRRD        = 0x00000001;  // n + 1 clock cycles
  LPC_EMC->DynamicMRD        = 0x00000001;  // n + 1 clock cycles
  _DelayMs(100);
  LPC_EMC->DynamicControl    = 0x00000183;  // Issue NOP command
  _DelayMs(200);
  LPC_EMC->DynamicControl    = 0x00000103;  // Issue PALL command
  LPC_EMC->DynamicRefresh    = 0x00000002;  // n * 16 clock cycles
  for (i = 0; i < 0x80; i++);               // Wait 128 AHB clock cycles
  LPC_EMC->DynamicRefresh    = 0x0000003A;  // n * 16 clock cycles
  //
  // Init SDRAM
  //
  LPC_EMC->DynamicControl = 0x00000083;                             // Issue MODE command
Dummy = *((volatile uint32_t*)(SDRAM_BASE_ADDR | (0x22 << (10))));  // 4 burst, 2 CAS latency
  //Dummy = *((volatile uint32_t*)(SDRAM_BASE_ADDR | (0x22 << (2+2+9))));  // 4 burst, 2 CAS latency
  LPC_EMC->DynamicControl = 0x00000000;                             // Issue NORMAL command
  LPC_EMC->DynamicConfig0 = 0x00085500;                             // 128MB, 4Mx32, 4 banks, 12 rows, 9 columns, buffers (re-)enabled
  //
  // Auto calibrate timings
  //
  CmdDly = _CalibrateOsc();
  //
  // Find best delay values
  //
  _FindDelay(0);  // EMCDLY
  _FindDelay(1);  // FBCLKDLY
  _AdjustEMCTiming(CmdDly);
}

Outcomes