SDRAM corrupt data

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

SDRAM corrupt data

1,188 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nohabviktor on Wed Nov 05 01:46:49 MST 2014
Hi!

I have a problem to SDRAM on my custom LPC1788 board.
The board has two 16 bit SDRAM on 32 bit data bus.
Two SDRAM not working in 32 bit mode, only one in 16 bit mode.
In 16 bit mode is works fine with 54Mhz and 108 Mhz EMC clock and run the linux kernel, but 32 bit mode two sdram is

not working.
In 32 bit mode the data is corrupt, memtest is fail, linux image is crc error if I downloaded by tftp.

I tried the memory timing incrase and decrase, but nothing changed.

The diff output:
The corrupt data different is always 2 byte in 2 Mbyte file:

39906c39906

< a009be00: 2500ebcb 0a0346a9 46a846a9 0f00f1ba    ...%.F...F.F....
---
> a009be00: 2500b004 0a03ebcb 46a846a9 0f00f1ba    ...%.....F.F....
62027c62027
< a00f2490: ffffffff ffffffff 00800000 0080ffff    ................
---
> a00f2490: ffffffff ffffffff 00800000 ffffffff    ................
62029c62029
< a00f24b0: 00000000 00000000 00000400 00000000    ................
---
> a00f24b0: 00000000 00000000 00000400 00000400    ................
62034c62034
< a00f2500: 00000000 00000000 00000000 00000000    ................
---
> a00f2500: 00000000 00000000 00000001 00000000    ................
62424c62424
< a00f3d60: 00000000 00000001 a00d86bd a00d868c    ................
---
> a00f3d60: 00000000 00000001 a00d8689 a00d86bd    ................
62579c62579
< a00f4710: a00fe7ec a00f0004 00000004 000001a4    ................
---
> a00f4710: a00d8b07 a00fe7ec 00000004 000001a4    ................
62701c62701
< a00f4eb0: ffffffff 00000000 98968000 98960008    ................
---
> a00f4eb0: ffffffff 00000000 98968000 00000008    ................
64149c64149
< a00fa930: ffffffff 00000000 00000000 00007461    ............at..
---
> a00fa930: ffffffff 00000000 00000000 74737461    ............atst


This is my memory init in u-boot:


/*
* Enable power on EMC
*/
lpc178x_periph_enable(LPC178X_SCC_PCONP_PCEMC_MSK, 1);

/*
* Clock delay for EMC
*/
LPC178X_SCC->emcdlyctl = ( 0x8 | (0x8 << 8) | (0x8 << 16) );

/*
* Enable EMC
*/
LPC178X_EMC->emcctrl = LPC178X_EMC_CTRL_EN_MSK;
/*
* Little-endian mode
*/
LPC178X_EMC->emccfg = 0;

...
...
...


/*
* Configure DRAM timing
*/
dy->rascas =
(3 << LPC178X_EMC_DYRASCAS_RAS_BITS) |
(3 << LPC178X_EMC_DYRASCAS_CAS_BITS);
LPC178X_EMC->dy_rdcfg =
(1 << LPC178X_EMC_DYRDCFG_RD_BITS);
LPC178X_EMC->dy_trp  = 1;
LPC178X_EMC->dy_tras = 2;
LPC178X_EMC->dy_srex = 3;
LPC178X_EMC->dy_apr  = 1;
LPC178X_EMC->dy_dal  = 5;
LPC178X_EMC->dy_wr   = 3;
LPC178X_EMC->dy_rc   = 3;
LPC178X_EMC->dy_rfc  = 3;
LPC178X_EMC->dy_xsr  = 3;
LPC178X_EMC->dy_rrd  = 0;
LPC178X_EMC->dy_mrd  = 3;

udelay(100000);



//32bit databus:
#ifdef CONFIG_SDRAM_32_BIT_DATABUS
      dy->cfg = (1u << 14) | (0u << 12) | (3u << 9) | (1u << 7);
#else
      dy->cfg = 0x0000680;
#endif




LPC178X_EMC->dy_ctrl = LPC178X_EMC_DYCTRL_CE_MSK | LPC178X_EMC_DYCTRL_CS_MSK |
(LPC178X_EMC_DYCTRL_I_NOP << LPC178X_EMC_DYCTRL_I_BITS);
udelay(200000);

LPC178X_EMC->dy_ctrl =
LPC178X_EMC_DYCTRL_CE_MSK | LPC178X_EMC_DYCTRL_CS_MSK |
(LPC178X_EMC_DYCTRL_I_PALL << LPC178X_EMC_DYCTRL_I_BITS);

LPC178X_EMC->dy_rfsh = 1;

udelay(1000);

LPC178X_EMC->dy_rfsh = 0x2E;
 
LPC178X_EMC->dy_ctrl =
LPC178X_EMC_DYCTRL_CE_MSK | LPC178X_EMC_DYCTRL_CS_MSK |
(LPC178X_EMC_DYCTRL_I_MODE << LPC178X_EMC_DYCTRL_I_BITS);

#ifdef CONFIG_SDRAM_32_BIT_DATABUS
tmp32 = *(volatile u32 *)(CONFIG_SYS_RAM_BASE | (0x32UL << 13));
#else
tmp32 = *(volatile u32 *)(CONFIG_SYS_RAM_BASE | (0x33UL << 12));
#endif

LPC178X_EMC->dy_ctrl = 0x0000;

/*
* Enable DRAM buffer
*/

//32bit databus:
#ifdef CONFIG_SDRAM_32_BIT_DATABUS
      dy->cfg = (1u << 14) | (0u << 12) | (3u << 9) | (1u << 7) | LPC178X_EMC_DYCFG_B_MSK;
#else
      dy->cfg = 0x0000680 | LPC178X_EMC_DYCFG_B_MSK; //1<<19
#endif



/*
* Fill in global info with description of DRAM configuration
*/
gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE;
gd->bd->bi_dram[0].size  = CONFIG_SYS_RAM_SIZE;

udelay(1000);


Please give me an advice on what could be the problem?

Labels (1)
0 Kudos
Reply
2 Replies

875 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Prabhakaran_Raja on Thu Feb 18 07:13:33 MST 2016
Hi,
I have LPC4357 xplorer++ evl board and NXP LPC-Link debugger.
i using LPCXpresso v7.9.2 IDE.
In my evl board we have MT48LC8M32B2B5-6 SDRAM.
but i'm trying to interface SDRAM in all the way but i'm not able to interface with SDRAM.
some keil examples are there but i cannot flash the *.afx through LPC-Link .


Please any one suggest how flash using LPC-Link with keil examples?
AND please suggest any direct example of SDRAM interface using LPCXpresso v7.9.2 IDE.

0 Kudos
Reply

875 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Wed Nov 05 05:34:42 MST 2014
We have a custom board with 1778 (same as 1788 but no LCD) with 32Mb of SDRAM implemented with 2 16bit wide devices.

The code is in M3 assembler, but since it is mostly loading values and then shoving them in to the EMC registers anyone
with a bit of intelligence who is prepared for a bit  of effort should be able to translate it back to "C".
Or at the very least see what numbers are being fed to which EMC registers.

Note the register offset definitions do not exactly match the names in the UM, but the offsets are a blatent clue
for translation. And, if necessary, see the Arm Architecture Manual version 7-M for the opcodes.

Setting up the pins is not shown, but you should already know how to do this. Nor is enabling the EMC itself.

My setup assumes an EClk of 60MHz (120 divided by 2).
You will have to hand work the macros with (a) you desired clock speed, and (b) the various timings from the datasheet
for your memory devices. [the tXXX names match the datasheet tables]. [Or make "C" macros.]

Anyway, if you are prepared to make an effort, this is a WORKING setup (been stable for 18 months plus).

;=======================================================================!
; LIBRAM.SCopyright (c) 2012 by Data Display UK Ltd.10-08-12!
;=======================================================================!

; vim: set ts=8 sw=8:; [tabs:8]

.file"LibRam.s"
.syntax unified
.thumb
.include "amacs.inc"
.include "LibPid.inc"

;-----------------------------------------------------------------------!
; Publics!
;-----------------------------------------------------------------------!

.globalInitRam, InitLPRAM, InitFPGA, InitSDRAM
.globalMemTestData, MemTestAddr, MemTestDev, MemTestSDRAM

.globalIsRamOk

;-----------------------------------------------------------------------!
; Constants and Equates!
;-----------------------------------------------------------------------!

scsBase= 0x400FC000; APB1-31 System Control & Status

scsSCS= 0x1A0;
scsEClkSel= 0x100;
scsEDelay= 0x1DC;
scsECal= 0x1E0;

;------------------------------------------------------------------------
emcBase= 0x2009C000; External Memory Controller

emcCtrl= 0x000;
emcStatus= 0x004;
emcConfig= 0x008;

emcDCtrl= 0x020;
emcDRefresh= 0x024;
emcDRConfig= 0x028;
emcDRPrchg= 0x030;
emcDRas= 0x034;
emcDSRex= 0x038;
emcDApr= 0x03C;
emcDDal= 0x040;
emcDWr= 0x044;
emcDRC= 0x048;
emcDRfc= 0x04C;
emcDXsr= 0x050;
emcDRrd= 0x054;
emcDMrd= 0x058;

emcDConfig0= 0x100; SDRAM A000 0000 (32 MByte)
emcDRasCas0= 0x104;

;emcDConfig1= 0x120;
;emcDRasCas1= 0x124;

;emcDConfig2= 0x140;
;emcDRasCas2= 0x144;

;emcDConfig3= 0x160;
;emcDRasCas3= 0x164;
                       ;
emcSExtWait= 0x080;

emcSConfig0= 0x200; LPRAM 8000 0000 (512 KByte)
emcSWaitWen0= 0x204;
emcSWaitOen0= 0x208;
emcSWaitRd0= 0x20C;
emcSWaitPage0= 0x210;
emcSWaitWr0= 0x214;
emcSWaitTurn0= 0x218;

emcSConfig1= 0x220;  FPGA 9000 0000 (MMIO)
emcSWaitWen1= 0x224;
emcSWaitOen1= 0x228;
emcSWaitRd1= 0x22C;
emcSWaitPage1= 0x230;
emcSWaitWr1= 0x234;
emcSWaitTurn1= 0x238;

;emcSConfig2= 0x240;
;emcSWaitWen2= 0x244;
;emcSWaitOen2= 0x248;
;emcSWaitRd2= 0x24C;
;emcSWaitPage2= 0x250;
;emcSWaitWr2= 0x254;
;emcSWaitTurn2= 0x258;

;emcSConfig3= 0x260;
;emcSWaitWen3= 0x264;
;emcSWaitOen3= 0x268;
;emcSWaitRd3= 0x26C;
;emcSWaitPage3= 0x270;
;emcSWaitWr3= 0x274;
;emcSWaitTurn3= 0x278;

;-----------------------------------------------------------------------!
; CODE!
;-----------------------------------------------------------------------!
.text
.align 4,0
vTag:.asciz"@(#) LibRam.s v 1.00.0"
.align 4,0

;------------------------------------------------------------------------
emcPins:; Port   Pin      Count    Func  Flags
.word(1<<28)+(25<<20)+( 1<<12)+(5<<8)+0x00; clock out for PLD
.word(2<<28)+(16<<20)+( 3<<12)+(1<<8)+0x09; See
.word(2<<28)+(20<<20)+( 1<<12)+(1<<8)+0x09; Matrix v6
.word(2<<28)+(24<<20)+( 1<<12)+(1<<8)+0x09;
.word(2<<28)+(28<<20)+( 4<<12)+(1<<8)+0x09;
.word(3<<28)+( 0<<20)+(32<<12)+(1<<8)+0x09; Data bus
.word(4<<28)+( 0<<20)+(19<<12)+(1<<8)+0x09; Addr bus
.word(4<<28)+(24<<20)+( 4<<12)+(1<<8)+0x09;
.word(4<<28)+(30<<20)+( 2<<12)+(1<<8)+0x09,0; Terminate

; add pullup and fast slew

;-----------------------------------------------------------------------!
; Init All RAM!
;-----------------------------------------------------------------------!

fn InitRam

push{lr}; save regs
;---------------------------------------;
movsr0, pEMC; enable peripheral clock
blPowerOn; i.e PowerOn(pEMC)
adrr0, emcPins; Assign all pins
blPinSetup;

;---------------------------------------;
ldrr3, =scsBase; emc global options
ldrr0, [r3, scsSCS]; (i.e x = LPC_SYSTEM->scsSCS) LPC Open names are a guess
bicsr0, 0x07; NB equiv to x = x & ~number
orrsr0, 0x04; addr shift/full reset/!burst NB equiv to x = x | number
strr0, [r3, scsSCS]; i.e LP_SYSTEM->scsSCS = x

movr0, 1; EClk selection
strr0, [r3, scsEClkSel]; by 2 to not exceed max (80MHz)

movwr0, (16<<8)+(16<<0); FB = 4, CMD = 2 (x 250 psec)
strr0, [r3, scsEDelay]; for SDRAMFIX ME !!!

;---------------------------------------;
ldrr3, =emcBase; get EMC base addr
movr0, (0<<2)+(0<<1)+(1<<0); !low power/!mirror/enable
strr0, [r3, emcCtrl];
movsr0, (0<<1)+(0<<0); clk ratio 1:1/little endian
strr0, [r3, emcConfig];
movsr0, 0;
strr0, [r3, emcSExtWait]; not using 'extended wait'

;---------------------------------------;
blInitLPRAM; want LPRAM 'call i.e InitLPRAM()'
blInitFPGA; want FPGA
blInitSDRAM; want SDRAM

;---------------------------------------;
movr0, (0<<2)+(0<<1)+(1<<0); !low power/!mirror/enable
strr0, [r3, emcCtrl]; now, (re)enable the EMC
pop{pc}; return

fe InitRam

;-----------------------------------------------------------------------!
; Init Dynamic RAM!
;-----------------------------------------------------------------------!

eClk= (120/2); memory clock (CClk/2) = 60 MHz [i.e a #define]

; select one of Row-Bank-Column or Bank-Row-Column

AMD= 0; addr mode: 0 = R-B-C, 1 = B-R-C
MSF= ((9+2+2)-(AMD*2)); Mode data shift factor
; [9 cols, 4 banks, 32bit bus]
CL= 3; CAS Latency (tClks)

.macrons2clk sym ns; symbol name, duration in nsec*10
\sym= (((\ns*eClk)+9999)/10000); ns to memory clocks (round up)
.endm

ns2clktRP,  200; 20.0 ns see MT48LC16M.pdf
ns2clktRAS, 440; 44.0 ns
ns2clktXSR, 750; 75.0 ns
ns2clktAPR, 200; 20.0 ns (using tRCD)
tDAL  = 5;  5   tClk
ns2clktWR,   75;  7.5 ns [plus 1 tClk]
ns2clktRC,  660; 66.0 ns
ns2clktRFC, 660; 66.0 ns
ns2clktRRD, 150; 15.0 ns
tMRD  = 2;  2   tClk

ns2clktRCD, 200; 20 ns

ns2ClkRFP,  (640000000/4096); 4K refresh cycles per 64 mSec

ModeWd= ((0<<9)+(0<<7)+(CL<<4)+(0<<3)+(2<<0))
; Burst/Normal/CL/Seq/Burst=4

;------------------------------------------------------------------------
fn InitSDRAM

movr0, (0<<2)+(0<<1)+(1<<0); !low power/!mirror/enable
strr0, [r3, emcCtrl]; EMC needs to be enabled for init
movsr0, (0<<8)+(0<<0); clock = 1:1, Little Endian
strr0, [r3, emcConfig];

movwr0, (1<<14)+(AMD<<12)+(2<<9)+(1<<7)+(0<<3)
; 1 = 32bit data bus
; 0 = Row-Bank-Column [AMD]
; 2 = 128 Kbit device
; 1 = 16bit device [times 2]
; 0 = SDRAM
movtr0, (0<<4)+(0<<3); !WP/!buffer
strr0, [r3, emcDConfig0]; set options as above

movwr0, (CL<<8)+(tRAS<<0); set ras and cas
strr0, [r3, emcDRasCas0];
movsr0, 1; read strategy: command delayed
strr0, [r3, emcDRConfig];

movsr0, tRP-1;
strr0, [r3, emcDRPrchg];
movsr0, tRAS-1;
strr0, [r3, emcDRas];
movsr0, tXSR-1;
strr0, [r3, emcDSRex];
movsr0, tAPR-1;
strr0, [r3, emcDApr];
movsr0, tDAL;
strr0, [r3, emcDDal];
movsr0, tWR-1+1;
strr0, [r3, emcDWr];
movsr0, tRC-1;
strr0, [r3, emcDRC];
movsr0, tRFC-1;
strr0, [r3, emcDRfc];
movsr0, tXSR-1;
strr0, [r3, emcDXsr];
movsr0, tRRD-1;
strr0, [r3, emcDRrd];
movsr0, tMRD-1;
strr0, [r3, emcDMrd];

movwr0, (3<<7)+(0<<5)+(0<<2)+(1<<1)+(1<<0)
strr0, [r3, emcDCtrl]; NOP/Clk/!SRef/ClkAll/ClkE

movwr0, (120*100)/3; delay 100 uSec
0:subsr0, 1;
bne0b;

movwr0, (2<<7)+(0<<5)+(0<<2)+(1<<1)+(1<<0)
strr0, [r3, emcDCtrl]; PALL/Clk/!SRef/ClkAll/ClkE
movsr0, 1; set fastest refresh
strr0, [r3, emcDRefresh];

movwr0, (120*10)/3; delay 10 uSec [gt 128 tClk]
0:subsr0, 1;
bne0b;

movsr0, (RFP>>4); set 'normal' refresh rate
movsr0, 25; DEBUG override
strr0, [r3, emcDRefresh];

movwr0, (120*10)/3; delay 10 uSec [gt 128 tClk]
0:subsr0, 1;
bne0b;

movwr0, (1<<7)+(0<<5)+(0<<2)+(1<<1)+(1<<0)
strr0, [r3, emcDCtrl]; MODE/Clk/!SRef/ClkAll/ClkE

movwr0, ModeWd; load the mode register
lslsr0, MSF; apply addr shift
movsr1, 0xA0000000; SDRAM base address
ldrr0, [r1, r0]; 'set' mode

movwr0, (120*10)/3; delay 10 uSec [gt 128 tClk]
0:subsr0, 1;
bne0b;

movwr0, (0<<7)+(0<<5)+(0<<2)+(0<<1)+(0<<0)
strr0, [r3, emcDCtrl]; normal running

movwr0, (1<<14)+(AMD<<12)+(3<<9)+(1<<7)+(0<<3)
; 32bit data bus
; 1 = Bank-Row-Column
; 256 Kbit device
; 16bit device [times 2]
; SDRAM
movtr0, (0<<4)+(1<<3); !WP/buffer [Enable Buffer]
strr0, [r3, emcDConfig0]; set options as above
bxlr;

fe InitSDRAM

;-----------------------------------------------------------------------!
; MemTestSDRAM!
;-----------------------------------------------------------------------!

MemSz= 32*1024*1024; nbr bytes (32 MB)

fn MemTestSDRAM

;---------------------------------------;
; populate ram with deterministic data;

movsr3, 0xA0000000; SDRAM
movsr2, MemSz; nbr bytes (64 MB)
movsr1, 11; start value

0:strr1, [r3], 4; *p++ = v++
ldrr0, [r3, -4]; read back
addsr1, 1;
subsr2, 4; while (--nWords)
bgt0b;

;---------------------------------------;
; validate and invert;

movsr3, 0xA0000000; SDRAM
movsr2, MemSz; nbr bytes (32 MB)
movsr1, 11; start value

0:ldrr0, [r3]; v = *p
subsr0, r0, r1; validate
bne9f; OOPS
mvnsr0, r1; inverse
strr0, [r3], 4; *p++ = ~(v++)
addsr1, 1;
subsr2, 4; while (--nWords)
bgt0b;

;---------------------------------------;
; validate and clear;

movsr3, 0xA0000000; SDRAM
movsr2, MemSz; nbr bytes (32 MB)
movsr1, 11; start value

0:ldrr0, [r3]; v = ~*p
mvnsr0, r0;
subsr0, r0, r1; validate
bne9f; OOPS
movsr0, 0; clear
strr0, [r3], 4; *p++ = 0
addsr1, 1; v++
subsr2, 4; while (--nWords)
bgt0b;

9:bxlr; return (0 = ok)

fe MemTestSDRAM

;-----------------------------------------------------------------------!
; IsRamOk!
;-----------------------------------------------------------------------!

; r0 = start addr, r1 = size bytes

fn IsRamOk

push{r4,lr}; save regs
addsr1, 3; round up
movsr1, r1, lsr 2; cvt  to dwords

0:ldrr4, [r0]; save current
movsr2, 0xAAAAAAAA; probe
strr2, [r0];
ldrr3, [r0];
strr4, [r0]; replace current
subsr2, r3; check
cbnzr2, 9f; OOPS!

movsr2, 0x55555555; probe
strr2, [r0];
ldrr3, [r0];
strr4, [r0], 4; replace current -- bump addr
subsr2, r3; check
cbnzr2, 9f; OOPS!
subsr1, 1; loop
bne0b;

9:movsr0, r2; zero = OK
pop{r4,pc}; return

fe IsRamOk

;-----------------------------------------------------------------------!
; LDR pool!
;-----------------------------------------------------------------------!
.align 2,0xFF

Pool: .pool; LDR pool

;------------------------------------------------------------------------
.align4,0xFF
;========================================================================



I hope this is of use to someone -- Cheers, Mike



0 Kudos
Reply