EmbeddedRelated.com
Forums

LPC2468 SDRAM setup (again...)

Started by Marcel Boom November 19, 2008
Hello all,

This is one of those topics that keep popping up. I have searched the
newsgroup and found several threads on the topic (and tried them all,
but still not working).

I have a demonstration board of Olimex (LPC-E2468) which has a Samsung
K4S281632F-TC75 SDRAM mounted. The example code uses uC Linux which I
do not want to use (I am currently using IAR EWARM + powerpack).

Can any one point out the failure in the configuration:

// Assign pins to EMC controller(SDRAM)
PINSEL5 &= BIN32(11110000,11111100,11111100,11000000);
PINSEL5 |= BIN32(00000101,00000001,00000001,00010101);
PINMODE5&= BIN32(11110000,11111100,11111100,11000000); // No
resistors on control bus
PINMODE5|= BIN32(00001010,00000010,00000010,00101010);

PINSEL6 = BIN32(01010101,01010101,01010101,01010101); // D0-D15 is
databus
PINMODE6 = BIN32(10101010,10101010,10101010,10101010); // No
resistors on bus

PINSEL8 &= BIN32(11000000,00000000,00000000,00000000); // A0-A14 is
addressbus
PINSEL8 |= BIN32(00010101,01010101,01010101,01010101);
PINMODE8&= BIN32(11000000,00000000,00000000,00000000); // No
resistors on bus
PINMODE8|= BIN32(00101010,10101010,10101010,10101010);

// Init SDRAM controller
EMCCONTROL = 1; // enable EMC
PCONP_bit.PCEMC = 1; // Enable
power to the EMC
EMCDYNAMICRP = 2; // (tRP
should be in the SDRAM datasheet)
EMCDYNAMICRAS = 3; // (tRAS
should be in the SDRAM datasheet)
EMCDYNAMICSREX = 1; // Self
Refresh Exit Time
EMCDYNAMICAPR = 1; // Last Data
Out to Active Time
EMCDYNAMICDAL = 4; // Data in
to Active Command Time
EMCDYNAMICWR = 2; // Write
Recovery Time
EMCDYNAMICRC = 6; // Active to
Active command Period
EMCDYNAMICRFC = 6 // Auto
Refresh Period
EMCDYNAMICXSR = 1; // Exit Self
Refresh
EMCDYNAMICRRD = 2; // Active
Bank A to Active Bank B Time
EMCDYNAMICMRD = 1; // Load mode
register to Active Command Time
EMCDINAMICRDCFG = 1; // Command
delayed strategy, using EMCCLKDELAY (command delayed, clock out not
delayed)
EMCDYNAMICRASCAS0 = 0x00000303; // RAS, CAS
both 3 CCLK cycles
EMCDYNAMICCFG0 = 0x00000680; // 12 row, 9
- col, standard SDRAM
for (volatile Int32U i = 200*30; i;i--); // DELAY to
allow power and clocks to stabilize ~200 us
EMCDINAMICCTRL = 0x00000183; // Mem clk
enable, CLKOUT runs, send command: NOP
for (volatile Int32U i = 200*30; i;i--); // DELAY to
allow power and clocks to stabilize ~200 us

// JEDEC General SDRAM Initialization Sequence
EMCDINAMICCTRL = 0x00000103; // Send
command PALL (precharge all), shorest possible refresh period
EMCDINAMICRFR = 0x00000002; // Set 32
CCLKs between SDRAM refresh cycles
for (volatile Int32U i= 128; i; --i); // > 128 clk
EMCDINAMICRFR = 23; // Set
Refresh time
EMCDINAMICCTRL = 0x00000083; // Enter
Mode by issue MODE command, after finishing bailout and back to NORMAL
mode, mem clk enable, CLKOUT runs, send command: MODE

/*
SHIFT_HIGH_PERFORMANCE = COL + TBW + BANK, where
COL=# of column bits (here: 9)
TBW=total bus width, 1 bits, 22 bits (here: 1)
BANK=# of bank select bits (here: 2)

Just for completeness: For "low-power" SDRAM leave out the BANK term:
SHIFT_LOW_POWER = COL + TBW
*/
#define SHIFT_HIGH_PERFORMANCE (9+1+2)

// Burst 8, Sequential, CAS-2
volatile unsigned short int Dummy = *(volatile unsigned short *)
(((Int32U)&SDRAM_BASE_ADDR) | (0x33
<< (SHIFT_HIGH_PERFORMANCE)));

EMCDINAMICCTRL = 0x00000000; // Go into
normal operation mode
EMCDYNAMICCFG0 = 0x00080000; // Enable
buffering
for(volatile Int32U i = 10000; i;i--); // Wait
somewhat more before continuing

An Engineer's Guide to the LPC2100 Series

Hi,

if you have a running Linux distro, then you can check the source of the
boot-loader (usually uboot) to see how it configures the hardware.
When the kernel is started the hardware has to be fully (at least clock
domains, external memories, and the MMU) configured. So this is done by
the boot-loader.

Foltos

Marcel Boom wrote:
> Hello all,
>
> This is one of those topics that keep popping up. I have searched the
> newsgroup and found several threads on the topic (and tried them all,
> but still not working).
>
> I have a demonstration board of Olimex (LPC-E2468) which has a Samsung
> K4S281632F-TC75 SDRAM mounted. The example code uses uC Linux which I
> do not want to use (I am currently using IAR EWARM + powerpack).
>
> Can any one point out the failure in the configuration:
> // Assign pins to EMC controller(SDRAM)
> PINSEL5 &= BIN32(11110000,11111100,11111100,11000000);
> PINSEL5 |= BIN32(00000101,00000001,00000001,00010101);
> PINMODE5&= BIN32(11110000,11111100,11111100,11000000); // No
> resistors on control bus
> PINMODE5|= BIN32(00001010,00000010,00000010,00101010);
>
> PINSEL6 = BIN32(01010101,01010101,01010101,01010101); // D0-D15 is
> databus
> PINMODE6 = BIN32(10101010,10101010,10101010,10101010); // No
> resistors on bus
>
> PINSEL8 &= BIN32(11000000,00000000,00000000,00000000); // A0-A14 is
> addressbus
> PINSEL8 |= BIN32(00010101,01010101,01010101,01010101);
> PINMODE8&= BIN32(11000000,00000000,00000000,00000000); // No
> resistors on bus
> PINMODE8|= BIN32(00101010,10101010,10101010,10101010);
>
> // Init SDRAM controller
> EMCCONTROL = 1; // enable EMC
> PCONP_bit.PCEMC = 1; // Enable
> power to the EMC
> EMCDYNAMICRP = 2; // (tRP
> should be in the SDRAM datasheet)
> EMCDYNAMICRAS = 3; // (tRAS
> should be in the SDRAM datasheet)
> EMCDYNAMICSREX = 1; // Self
> Refresh Exit Time
> EMCDYNAMICAPR = 1; // Last Data
> Out to Active Time
> EMCDYNAMICDAL = 4; // Data in
> to Active Command Time
> EMCDYNAMICWR = 2; // Write
> Recovery Time
> EMCDYNAMICRC = 6; // Active to
> Active command Period
> EMCDYNAMICRFC = 6 // Auto
> Refresh Period
> EMCDYNAMICXSR = 1; // Exit Self
> Refresh
> EMCDYNAMICRRD = 2; // Active
> Bank A to Active Bank B Time
> EMCDYNAMICMRD = 1; // Load mode
> register to Active Command Time
> EMCDINAMICRDCFG = 1; // Command
> delayed strategy, using EMCCLKDELAY (command delayed, clock out not
> delayed)
> EMCDYNAMICRASCAS0 = 0x00000303; // RAS, CAS
> both 3 CCLK cycles
> EMCDYNAMICCFG0 = 0x00000680; // 12 row, 9
> - col, standard SDRAM
> for (volatile Int32U i = 200*30; i;i--); // DELAY to
> allow power and clocks to stabilize ~200 us
> EMCDINAMICCTRL = 0x00000183; // Mem clk
> enable, CLKOUT runs, send command: NOP
> for (volatile Int32U i = 200*30; i;i--); // DELAY to
> allow power and clocks to stabilize ~200 us
>
> // JEDEC General SDRAM Initialization Sequence
> EMCDINAMICCTRL = 0x00000103; // Send
> command PALL (precharge all), shorest possible refresh period
> EMCDINAMICRFR = 0x00000002; // Set 32
> CCLKs between SDRAM refresh cycles
> for (volatile Int32U i= 128; i; --i); // > 128 clk
> EMCDINAMICRFR = 23; // Set
> Refresh time
> EMCDINAMICCTRL = 0x00000083; // Enter
> Mode by issue MODE command, after finishing bailout and back to NORMAL
> mode, mem clk enable, CLKOUT runs, send command: MODE
>
> /*
> SHIFT_HIGH_PERFORMANCE = COL + TBW + BANK, where
> COL=# of column bits (here: 9)
> TBW=total bus width, 1 bits, 22 bits (here: 1)
> BANK=# of bank select bits (here: 2)
>
> Just for completeness: For "low-power" SDRAM leave out the BANK term:
> SHIFT_LOW_POWER = COL + TBW
> */
> #define SHIFT_HIGH_PERFORMANCE (9+1+2)
>
>
>
> // Burst 8, Sequential, CAS-2
> volatile unsigned short int Dummy = *(volatile unsigned short *)
> (((Int32U)&SDRAM_BASE_ADDR) | (0x33
> << (SHIFT_HIGH_PERFORMANCE)));
>
> EMCDINAMICCTRL = 0x00000000; // Go into
> normal operation mode
> EMCDYNAMICCFG0 = 0x00080000; // Enable
> buffering
> for(volatile Int32U i = 10000; i;i--); // Wait
> somewhat more before continuing
>
>
--- In l..., Foltos wrote:
>
> Hi,
>
> if you have a running Linux distro, then you can check the source of
the
> boot-loader (usually uboot) to see how it configures the hardware.
> When the kernel is started the hardware has to be fully (at least clock
> domains, external memories, and the MMU) configured. So this is done by
> the boot-loader.
>
> Foltos

Hi,

Thanks for the reply. I will certainly have a second look into that.
However, I did a quick scan. There is a enormous number of files to
look into. I did a search for the EMC register and did not find them.
Nevertheless, the idea is good and I will have a second glance at it!

Marcel.

>
> Marcel Boom wrote:
> > Hello all,
> >
> > This is one of those topics that keep popping up. I have searched the
> > newsgroup and found several threads on the topic (and tried them all,
> > but still not working).
> >
> > I have a demonstration board of Olimex (LPC-E2468) which has a Samsung
> > K4S281632F-TC75 SDRAM mounted. The example code uses uC Linux which I
> > do not want to use (I am currently using IAR EWARM + powerpack).
> >
> > Can any one point out the failure in the configuration:
> >
> >
> >
> >
> > // Assign pins to EMC controller(SDRAM)
> > PINSEL5 &= BIN32(11110000,11111100,11111100,11000000);
> > PINSEL5 |= BIN32(00000101,00000001,00000001,00010101);
> > PINMODE5&= BIN32(11110000,11111100,11111100,11000000); // No
> > resistors on control bus
> > PINMODE5|= BIN32(00001010,00000010,00000010,00101010);
> >
> > PINSEL6 = BIN32(01010101,01010101,01010101,01010101); // D0-D15 is
> > databus
> > PINMODE6 = BIN32(10101010,10101010,10101010,10101010); // No
> > resistors on bus
> >
> > PINSEL8 &= BIN32(11000000,00000000,00000000,00000000); // A0-A14 is
> > addressbus
> > PINSEL8 |= BIN32(00010101,01010101,01010101,01010101);
> > PINMODE8&= BIN32(11000000,00000000,00000000,00000000); // No
> > resistors on bus
> > PINMODE8|= BIN32(00101010,10101010,10101010,10101010);
> >
> > // Init SDRAM controller
> > EMCCONTROL = 1; //
enable EMC
> > PCONP_bit.PCEMC = 1; // Enable
> > power to the EMC
> > EMCDYNAMICRP = 2; // (tRP
> > should be in the SDRAM datasheet)
> > EMCDYNAMICRAS = 3; // (tRAS
> > should be in the SDRAM datasheet)
> > EMCDYNAMICSREX = 1; // Self
> > Refresh Exit Time
> > EMCDYNAMICAPR = 1; // Last Data
> > Out to Active Time
> > EMCDYNAMICDAL = 4; // Data in
> > to Active Command Time
> > EMCDYNAMICWR = 2; // Write
> > Recovery Time
> > EMCDYNAMICRC = 6; // Active to
> > Active command Period
> > EMCDYNAMICRFC = 6 // Auto
> > Refresh Period
> > EMCDYNAMICXSR = 1; // Exit Self
> > Refresh
> > EMCDYNAMICRRD = 2; // Active
> > Bank A to Active Bank B Time
> > EMCDYNAMICMRD = 1; // Load mode
> > register to Active Command Time
> > EMCDINAMICRDCFG = 1; // Command
> > delayed strategy, using EMCCLKDELAY (command delayed, clock out not
> > delayed)
> > EMCDYNAMICRASCAS0 = 0x00000303; // RAS, CAS
> > both 3 CCLK cycles
> > EMCDYNAMICCFG0 = 0x00000680; // 12 row, 9
> > - col, standard SDRAM
> > for (volatile Int32U i = 200*30; i;i--); // DELAY to
> > allow power and clocks to stabilize ~200 us
> > EMCDINAMICCTRL = 0x00000183; // Mem clk
> > enable, CLKOUT runs, send command: NOP
> > for (volatile Int32U i = 200*30; i;i--); // DELAY to
> > allow power and clocks to stabilize ~200 us
> >
> > // JEDEC General SDRAM Initialization Sequence
> > EMCDINAMICCTRL = 0x00000103; // Send
> > command PALL (precharge all), shorest possible refresh period
> > EMCDINAMICRFR = 0x00000002; // Set 32
> > CCLKs between SDRAM refresh cycles
> > for (volatile Int32U i= 128; i; --i); // > 128
clk
> > EMCDINAMICRFR = 23; // Set
> > Refresh time
> > EMCDINAMICCTRL = 0x00000083; // Enter
> > Mode by issue MODE command, after finishing bailout and back to NORMAL
> > mode, mem clk enable, CLKOUT runs, send command: MODE
> >
> > /*
> > SHIFT_HIGH_PERFORMANCE = COL + TBW + BANK, where
> > COL=# of column bits (here: 9)
> > TBW=total bus width, 1 bits, 22 bits (here: 1)
> > BANK=# of bank select bits (here: 2)
> >
> > Just for completeness: For "low-power" SDRAM leave out the BANK
term:
> > SHIFT_LOW_POWER = COL + TBW
> > */
> > #define SHIFT_HIGH_PERFORMANCE (9+1+2)
> >
> >
> >
> > // Burst 8, Sequential, CAS-2
> > volatile unsigned short int Dummy = *(volatile unsigned short *)
> > (((Int32U)&SDRAM_BASE_ADDR) | (0x33
> > << (SHIFT_HIGH_PERFORMANCE)));
> >
> > EMCDINAMICCTRL = 0x00000000; // Go into
> > normal operation mode
> > EMCDYNAMICCFG0 = 0x00080000; // Enable
> > buffering
> > for(volatile Int32U i = 10000; i;i--); // Wait
> > somewhat more before continuing
> >
> >
> >
> >
> >
> >
--- In l..., "Marcel Boom" wrote:
>
> --- In l..., Foltos wrote:
> >
> > Hi,
> >
> > if you have a running Linux distro, then you can check the source of
> the
> > boot-loader (usually uboot) to see how it configures the hardware.
> > When the kernel is started the hardware has to be fully (at least
clock
> > domains, external memories, and the MMU) configured. So this is
done by
> > the boot-loader.
> >
> > Foltos
>
> Hi,
>
> Thanks for the reply. I will certainly have a second look into that.
> However, I did a quick scan. There is a enormous number of files to
> look into. I did a search for the EMC register and did not find them.
> Nevertheless, the idea is good and I will have a second glance at it!
>
> Marcel.
>

I have extracted this from uboot sources found on Olimex CD comming
with the LPC-E2468 board. You can find it easily searching diff file
supplied from Olimex. My board is running with PLL setup for cclk = 72
MHz.

Regards Zdravko Dimitrov

///////////////////////////////////////////////////////////

void ConfigureEMC(void)
{
volatile unsigned int i, dummy;

SCS &= ~0x00000002;
// SCS |= 0x00000002;

EMC_CTRL = (1<<0);
PCONP |= (1<<11);
PINSEL4 = 0x50000000;
#ifdef USE_32_BIT_DATABUS
PINSEL5 = 0x55010115;
PINSEL7 = 0x55555555;
#else
PINSEL5 = 0x05050555;
#endif
PINSEL6 = 0x55555555;
PINSEL8 = 0x55555555;
PINSEL9 = 0x50555555;

//all registers...
#ifdef USE_32_BIT_DATABUS
EMC_DYN_RP = 1; //>20ns = 2 clk
EMC_DYN_RAS = 3; //>45ns = 3 clk
EMC_DYN_SREX = 5; //>80-100ns = 6 clk
EMC_DYN_APR = 1; //
EMC_DYN_DAL = 5; //2 clk
EMC_DYN_WR = 1; //2 clk
EMC_DYN_RC = 5; //>65ns = 4 clk
EMC_DYN_RFC = 5; //>80-100ns = 6 clk
EMC_DYN_XSR = 5; //>80-100ns = 6 clk
EMC_DYN_RRD = 1; //>15ns = 1-2 clk
EMC_DYN_MRD = 1; //2 clk
EMC_DYN_RD_CFG = 1; //or 1,2,3

//
EMC_DYN_RASCAS0 = 0x00000202;

//
EMC_DYN_CFG0 = 0x00005480;
#else
EMC_DYN_RP = 2; //>20ns = 2 clk
EMC_DYN_RAS = 3; //>45ns = 3 clk
EMC_DYN_SREX = 7; //>80-100ns = 6 clk
EMC_DYN_APR = 2; //
EMC_DYN_DAL = 5; //2 clk
EMC_DYN_WR = 1; //2 clk
EMC_DYN_RC = 5; //>65ns = 4 clk
EMC_DYN_RFC = 5; //>80-100ns = 6 clk
EMC_DYN_XSR = 7; //>80-100ns = 6 clk
EMC_DYN_RRD = 1; //>15ns = 1-2 clk
EMC_DYN_MRD = 2; //2 clk
EMC_DYN_RD_CFG = 1; //or 1,2,3

//
EMC_DYN_RASCAS0 = 0x00000303;

//
EMC_DYN_CFG0 = 0x00000680;
#endif

//wait 100mS
Delay_ms(100);

//Send command: NOP
EMC_DYN_CTRL = 0x00000183;

//wait 200mS
Delay_ms(200);

//Send command: PRECHARGE-ALL, shortest possible refresh period
EMC_DYN_CTRL = 0x00000103;
EMC_DYN_RFSH = 0x00000002;

//wait 128 ABH clock cycles
for(i=0; i<0x40; i++)
{
asm volatile(" nop");
}

//Set correct refresh period
EMC_DYN_RFSH = 28;

//Send command: MODE
EMC_DYN_CTRL = 0x00000083;

//Set mode register in SDRAM
#ifdef USE_32_BIT_DATABUS
dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x22 << 11)));
#else
dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x33 << 12)));
#endif

//Send command: NORMAL
EMC_DYN_CTRL = 0x00000000;

//Enable buffer
EMC_DYN_CFG0 |= 0x00080000;

//initial system delay
Delay_ms(1);

EMC_STA_WAITWEN0 = 0x2;
EMC_STA_WAITOEN0 = 0x2;
EMC_STA_WAITRD0 = 0x1f;
EMC_STA_WAITPAGE0 = 0x1f;
EMC_STA_WAITWR0 = 0x1f;
EMC_STA_WAITTURN0 = 0xf;
EMC_STA_CFG0 = 0x00000081;

EMC_STA_WAITWEN1 = 0x2;
EMC_STA_WAITOEN1 = 0x2;
EMC_STA_WAITRD1 = 0x8;
EMC_STA_WAITPAGE1 = 0x1f;
EMC_STA_WAITWR1 = 0x8;
EMC_STA_WAITTURN1 = 0xf;
EMC_STA_CFG1 = 0x00000080;
}
Hello all,

Thanks for all the replies (and tips on how to search).

Nevertheless, I have solved the problem. I forgot to set PINMODE for WE...

Small failure, big problems...

Thanks all!

Marcel.
--- In l..., "Zdravko" wrote:
>
> --- In l..., "Marcel Boom" wrote:
> >
> > --- In l..., Foltos wrote:
> > >
> > > Hi,
> > >
> > > if you have a running Linux distro, then you can check the source of
> > the
> > > boot-loader (usually uboot) to see how it configures the hardware.
> > > When the kernel is started the hardware has to be fully (at least
> clock
> > > domains, external memories, and the MMU) configured. So this is
> done by
> > > the boot-loader.
> > >
> > > Foltos
> >
> > Hi,
> >
> > Thanks for the reply. I will certainly have a second look into that.
> > However, I did a quick scan. There is a enormous number of files to
> > look into. I did a search for the EMC register and did not find them.
> > Nevertheless, the idea is good and I will have a second glance at it!
> >
> > Marcel.
> > I have extracted this from uboot sources found on Olimex CD comming
> with the LPC-E2468 board. You can find it easily searching diff file
> supplied from Olimex. My board is running with PLL setup for cclk = 72
> MHz.
>
> Regards Zdravko Dimitrov
>
> ///////////////////////////////////////////////////////////
>
> void ConfigureEMC(void)
> {
> volatile unsigned int i, dummy;
>
> SCS &= ~0x00000002;
> // SCS |= 0x00000002;
>
> EMC_CTRL = (1<<0);
> PCONP |= (1<<11);
> PINSEL4 = 0x50000000;
> #ifdef USE_32_BIT_DATABUS
> PINSEL5 = 0x55010115;
> PINSEL7 = 0x55555555;
> #else
> PINSEL5 = 0x05050555;
> #endif
> PINSEL6 = 0x55555555;
> PINSEL8 = 0x55555555;
> PINSEL9 = 0x50555555;
>
> //all registers...
> #ifdef USE_32_BIT_DATABUS
> EMC_DYN_RP = 1; //>20ns = 2 clk
> EMC_DYN_RAS = 3; //>45ns = 3 clk
> EMC_DYN_SREX = 5; //>80-100ns = 6 clk
> EMC_DYN_APR = 1; //
> EMC_DYN_DAL = 5; //2 clk
> EMC_DYN_WR = 1; //2 clk
> EMC_DYN_RC = 5; //>65ns = 4 clk
> EMC_DYN_RFC = 5; //>80-100ns = 6 clk
> EMC_DYN_XSR = 5; //>80-100ns = 6 clk
> EMC_DYN_RRD = 1; //>15ns = 1-2 clk
> EMC_DYN_MRD = 1; //2 clk
> EMC_DYN_RD_CFG = 1; //or 1,2,3
>
> //
> EMC_DYN_RASCAS0 = 0x00000202;
>
> //
> EMC_DYN_CFG0 = 0x00005480;
> #else
> EMC_DYN_RP = 2; //>20ns = 2 clk
> EMC_DYN_RAS = 3; //>45ns = 3 clk
> EMC_DYN_SREX = 7; //>80-100ns = 6 clk
> EMC_DYN_APR = 2; //
> EMC_DYN_DAL = 5; //2 clk
> EMC_DYN_WR = 1; //2 clk
> EMC_DYN_RC = 5; //>65ns = 4 clk
> EMC_DYN_RFC = 5; //>80-100ns = 6 clk
> EMC_DYN_XSR = 7; //>80-100ns = 6 clk
> EMC_DYN_RRD = 1; //>15ns = 1-2 clk
> EMC_DYN_MRD = 2; //2 clk
> EMC_DYN_RD_CFG = 1; //or 1,2,3
>
> //
> EMC_DYN_RASCAS0 = 0x00000303;
>
> //
> EMC_DYN_CFG0 = 0x00000680;
> #endif
>
> //wait 100mS
> Delay_ms(100);
>
> //Send command: NOP
> EMC_DYN_CTRL = 0x00000183;
>
> //wait 200mS
> Delay_ms(200);
>
> //Send command: PRECHARGE-ALL, shortest possible refresh period
> EMC_DYN_CTRL = 0x00000103;
> EMC_DYN_RFSH = 0x00000002;
>
> //wait 128 ABH clock cycles
> for(i=0; i<0x40; i++)
> {
> asm volatile(" nop");
> }
>
> //Set correct refresh period
> EMC_DYN_RFSH = 28;
>
> //Send command: MODE
> EMC_DYN_CTRL = 0x00000083;
>
> //Set mode register in SDRAM
> #ifdef USE_32_BIT_DATABUS
> dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x22 << 11)));
> #else
> dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x33 << 12)));
> #endif
>
> //Send command: NORMAL
> EMC_DYN_CTRL = 0x00000000;
>
> //Enable buffer
> EMC_DYN_CFG0 |= 0x00080000;
>
> //initial system delay
> Delay_ms(1);
>
> EMC_STA_WAITWEN0 = 0x2;
> EMC_STA_WAITOEN0 = 0x2;
> EMC_STA_WAITRD0 = 0x1f;
> EMC_STA_WAITPAGE0 = 0x1f;
> EMC_STA_WAITWR0 = 0x1f;
> EMC_STA_WAITTURN0 = 0xf;
> EMC_STA_CFG0 = 0x00000081;
>
> EMC_STA_WAITWEN1 = 0x2;
> EMC_STA_WAITOEN1 = 0x2;
> EMC_STA_WAITRD1 = 0x8;
> EMC_STA_WAITPAGE1 = 0x1f;
> EMC_STA_WAITWR1 = 0x8;
> EMC_STA_WAITTURN1 = 0xf;
> EMC_STA_CFG1 = 0x00000080;
> }
>

Oeps, I meant PINSEL...

Marcel.

--- In l..., "Marcel Boom" wrote:
>
> Hello all,
>
> Thanks for all the replies (and tips on how to search).
>
> Nevertheless, I have solved the problem. I forgot to set PINMODE for
WE...
>
> Small failure, big problems...
>
> Thanks all!
>
> Marcel.
> --- In l..., "Zdravko" wrote:
> >
> > --- In l..., "Marcel Boom" wrote:
> > >
> > > --- In l..., Foltos wrote:
> > > >
> > > > Hi,
> > > >
> > > > if you have a running Linux distro, then you can check the
source of
> > > the
> > > > boot-loader (usually uboot) to see how it configures the hardware.
> > > > When the kernel is started the hardware has to be fully (at least
> > clock
> > > > domains, external memories, and the MMU) configured. So this is
> > done by
> > > > the boot-loader.
> > > >
> > > > Foltos
> > >
> > > Hi,
> > >
> > > Thanks for the reply. I will certainly have a second look into that.
> > > However, I did a quick scan. There is a enormous number of files to
> > > look into. I did a search for the EMC register and did not find
them.
> > > Nevertheless, the idea is good and I will have a second glance
at it!
> > >
> > > Marcel.
> > >
> >
> > I have extracted this from uboot sources found on Olimex CD comming
> > with the LPC-E2468 board. You can find it easily searching diff file
> > supplied from Olimex. My board is running with PLL setup for cclk = 72
> > MHz.
> >
> > Regards Zdravko Dimitrov
> >
> > ///////////////////////////////////////////////////////////
> >
> > void ConfigureEMC(void)
> > {
> > volatile unsigned int i, dummy;
> >
> > SCS &= ~0x00000002;
> > // SCS |= 0x00000002;
> >
> > EMC_CTRL = (1<<0);
> > PCONP |= (1<<11);
> > PINSEL4 = 0x50000000;
> > #ifdef USE_32_BIT_DATABUS
> > PINSEL5 = 0x55010115;
> > PINSEL7 = 0x55555555;
> > #else
> > PINSEL5 = 0x05050555;
> > #endif
> > PINSEL6 = 0x55555555;
> > PINSEL8 = 0x55555555;
> > PINSEL9 = 0x50555555;
> >
> > //all registers...
> > #ifdef USE_32_BIT_DATABUS
> > EMC_DYN_RP = 1; //>20ns = 2 clk
> > EMC_DYN_RAS = 3; //>45ns = 3 clk
> > EMC_DYN_SREX = 5; //>80-100ns = 6 clk
> > EMC_DYN_APR = 1; //
> > EMC_DYN_DAL = 5; //2 clk
> > EMC_DYN_WR = 1; //2 clk
> > EMC_DYN_RC = 5; //>65ns = 4 clk
> > EMC_DYN_RFC = 5; //>80-100ns = 6 clk
> > EMC_DYN_XSR = 5; //>80-100ns = 6 clk
> > EMC_DYN_RRD = 1; //>15ns = 1-2 clk
> > EMC_DYN_MRD = 1; //2 clk
> > EMC_DYN_RD_CFG = 1; //or 1,2,3
> >
> > //
> > EMC_DYN_RASCAS0 = 0x00000202;
> >
> > //
> > EMC_DYN_CFG0 = 0x00005480;
> > #else
> > EMC_DYN_RP = 2; //>20ns = 2 clk
> > EMC_DYN_RAS = 3; //>45ns = 3 clk
> > EMC_DYN_SREX = 7; //>80-100ns = 6 clk
> > EMC_DYN_APR = 2; //
> > EMC_DYN_DAL = 5; //2 clk
> > EMC_DYN_WR = 1; //2 clk
> > EMC_DYN_RC = 5; //>65ns = 4 clk
> > EMC_DYN_RFC = 5; //>80-100ns = 6 clk
> > EMC_DYN_XSR = 7; //>80-100ns = 6 clk
> > EMC_DYN_RRD = 1; //>15ns = 1-2 clk
> > EMC_DYN_MRD = 2; //2 clk
> > EMC_DYN_RD_CFG = 1; //or 1,2,3
> >
> > //
> > EMC_DYN_RASCAS0 = 0x00000303;
> >
> > //
> > EMC_DYN_CFG0 = 0x00000680;
> > #endif
> >
> > //wait 100mS
> > Delay_ms(100);
> >
> > //Send command: NOP
> > EMC_DYN_CTRL = 0x00000183;
> >
> > //wait 200mS
> > Delay_ms(200);
> >
> > //Send command: PRECHARGE-ALL, shortest possible refresh period
> > EMC_DYN_CTRL = 0x00000103;
> > EMC_DYN_RFSH = 0x00000002;
> >
> > //wait 128 ABH clock cycles
> > for(i=0; i<0x40; i++)
> > {
> > asm volatile(" nop");
> > }
> >
> > //Set correct refresh period
> > EMC_DYN_RFSH = 28;
> >
> > //Send command: MODE
> > EMC_DYN_CTRL = 0x00000083;
> >
> > //Set mode register in SDRAM
> > #ifdef USE_32_BIT_DATABUS
> > dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x22 << 11)));
> > #else
> > dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x33 << 12)));
> > #endif
> >
> > //Send command: NORMAL
> > EMC_DYN_CTRL = 0x00000000;
> >
> > //Enable buffer
> > EMC_DYN_CFG0 |= 0x00080000;
> >
> > //initial system delay
> > Delay_ms(1);
> >
> > EMC_STA_WAITWEN0 = 0x2;
> > EMC_STA_WAITOEN0 = 0x2;
> > EMC_STA_WAITRD0 = 0x1f;
> > EMC_STA_WAITPAGE0 = 0x1f;
> > EMC_STA_WAITWR0 = 0x1f;
> > EMC_STA_WAITTURN0 = 0xf;
> > EMC_STA_CFG0 = 0x00000081;
> >
> > EMC_STA_WAITWEN1 = 0x2;
> > EMC_STA_WAITOEN1 = 0x2;
> > EMC_STA_WAITRD1 = 0x8;
> > EMC_STA_WAITPAGE1 = 0x1f;
> > EMC_STA_WAITWR1 = 0x8;
> > EMC_STA_WAITTURN1 = 0xf;
> > EMC_STA_CFG1 = 0x00000080;
> > }
>
Hi,

I just checked the official "u-boot-2008.10-rc3" release ant it misses
the LPC2468 files. So you have to check the package coming with your
board for the sources. (I have them for the Olimex LPC-E2468 board.)
Maybe it is worth to check the latest snapshot or their git repository.

Foltos

Marcel Boom wrote:
> --- In l..., Foltos wrote:
>
>> Hi,
>>
>> if you have a running Linux distro, then you can check the source of
>>
> the
>
>> boot-loader (usually uboot) to see how it configures the hardware.
>> When the kernel is started the hardware has to be fully (at least clock
>> domains, external memories, and the MMU) configured. So this is done by
>> the boot-loader.
>>
>> Foltos
>>
>
> Hi,
>
> Thanks for the reply. I will certainly have a second look into that.
> However, I did a quick scan. There is a enormous number of files to
> look into. I did a search for the EMC register and did not find them.
> Nevertheless, the idea is good and I will have a second glance at it!
>
> Marcel.
>
>
>> Marcel Boom wrote:
>>
>>> Hello all,
>>>
>>> This is one of those topics that keep popping up. I have searched the
>>> newsgroup and found several threads on the topic (and tried them all,
>>> but still not working).
>>>
>>> I have a demonstration board of Olimex (LPC-E2468) which has a Samsung
>>> K4S281632F-TC75 SDRAM mounted. The example code uses uC Linux which I
>>> do not want to use (I am currently using IAR EWARM + powerpack).
>>>
>>> Can any one point out the failure in the configuration:
>>>
>>>
>>>
>>>
>>> // Assign pins to EMC controller(SDRAM)
>>> PINSEL5 &= BIN32(11110000,11111100,11111100,11000000);
>>> PINSEL5 |= BIN32(00000101,00000001,00000001,00010101);
>>> PINMODE5&= BIN32(11110000,11111100,11111100,11000000); // No
>>> resistors on control bus
>>> PINMODE5|= BIN32(00001010,00000010,00000010,00101010);
>>>
>>> PINSEL6 = BIN32(01010101,01010101,01010101,01010101); // D0-D15 is
>>> databus
>>> PINMODE6 = BIN32(10101010,10101010,10101010,10101010); // No
>>> resistors on bus
>>>
>>> PINSEL8 &= BIN32(11000000,00000000,00000000,00000000); // A0-A14 is
>>> addressbus
>>> PINSEL8 |= BIN32(00010101,01010101,01010101,01010101);
>>> PINMODE8&= BIN32(11000000,00000000,00000000,00000000); // No
>>> resistors on bus
>>> PINMODE8|= BIN32(00101010,10101010,10101010,10101010);
>>>
>>> // Init SDRAM controller
>>> EMCCONTROL = 1; //
>>>
> enable EMC
>
>>> PCONP_bit.PCEMC = 1; // Enable
>>> power to the EMC
>>> EMCDYNAMICRP = 2; // (tRP
>>> should be in the SDRAM datasheet)
>>> EMCDYNAMICRAS = 3; // (tRAS
>>> should be in the SDRAM datasheet)
>>> EMCDYNAMICSREX = 1; // Self
>>> Refresh Exit Time
>>> EMCDYNAMICAPR = 1; // Last Data
>>> Out to Active Time
>>> EMCDYNAMICDAL = 4; // Data in
>>> to Active Command Time
>>> EMCDYNAMICWR = 2; // Write
>>> Recovery Time
>>> EMCDYNAMICRC = 6; // Active to
>>> Active command Period
>>> EMCDYNAMICRFC = 6 // Auto
>>> Refresh Period
>>> EMCDYNAMICXSR = 1; // Exit Self
>>> Refresh
>>> EMCDYNAMICRRD = 2; // Active
>>> Bank A to Active Bank B Time
>>> EMCDYNAMICMRD = 1; // Load mode
>>> register to Active Command Time
>>> EMCDINAMICRDCFG = 1; // Command
>>> delayed strategy, using EMCCLKDELAY (command delayed, clock out not
>>> delayed)
>>> EMCDYNAMICRASCAS0 = 0x00000303; // RAS, CAS
>>> both 3 CCLK cycles
>>> EMCDYNAMICCFG0 = 0x00000680; // 12 row, 9
>>> - col, standard SDRAM
>>> for (volatile Int32U i = 200*30; i;i--); // DELAY to
>>> allow power and clocks to stabilize ~200 us
>>> EMCDINAMICCTRL = 0x00000183; // Mem clk
>>> enable, CLKOUT runs, send command: NOP
>>> for (volatile Int32U i = 200*30; i;i--); // DELAY to
>>> allow power and clocks to stabilize ~200 us
>>>
>>> // JEDEC General SDRAM Initialization Sequence
>>> EMCDINAMICCTRL = 0x00000103; // Send
>>> command PALL (precharge all), shorest possible refresh period
>>> EMCDINAMICRFR = 0x00000002; // Set 32
>>> CCLKs between SDRAM refresh cycles
>>> for (volatile Int32U i= 128; i; --i); // > 128
>>>
> clk
>
>>> EMCDINAMICRFR = 23; // Set
>>> Refresh time
>>> EMCDINAMICCTRL = 0x00000083; // Enter
>>> Mode by issue MODE command, after finishing bailout and back to NORMAL
>>> mode, mem clk enable, CLKOUT runs, send command: MODE
>>>
>>> /*
>>> SHIFT_HIGH_PERFORMANCE = COL + TBW + BANK, where
>>> COL=# of column bits (here: 9)
>>> TBW=total bus width, 1 bits, 22 bits (here: 1)
>>> BANK=# of bank select bits (here: 2)
>>>
>>> Just for completeness: For "low-power" SDRAM leave out the BANK
>>>
> term:
>
>>> SHIFT_LOW_POWER = COL + TBW
>>> */
>>> #define SHIFT_HIGH_PERFORMANCE (9+1+2)
>>>
>>>
>>>
>>> // Burst 8, Sequential, CAS-2
>>> volatile unsigned short int Dummy = *(volatile unsigned short *)
>>> (((Int32U)&SDRAM_BASE_ADDR) | (0x33
>>> << (SHIFT_HIGH_PERFORMANCE)));
>>>
>>> EMCDINAMICCTRL = 0x00000000; // Go into
>>> normal operation mode
>>> EMCDYNAMICCFG0 = 0x00080000; // Enable
>>> buffering
>>> for(volatile Int32U i = 10000; i;i--); // Wait
>>> somewhat more before continuing
>>>
>>>
>>>
>>>
>>>
>>>