SRAM initialization

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

SRAM initialization

3,529 Views
lpcware
NXP Employee
NXP Employee

Content originally posted in LPCWare by arion2001 on Tue Jan 13 02:44:33 MST 2015
Hi,

I am using LPC1778, 12 MHz. I am trying to initialize my SRAM to work even after following all the procedures mentioned in the LPC1778 manual, but to no avail. The compiler I am using is Crossworks Rowley 2.2.


Attached is the image of how my SRAM is connected. Also showing the screen shot as I stepped through the code and stopped at the test is writting into memory space seems like it is showing FFFFF values in there.

My init code is as follow:

static void pinConfig_SRAM(void) {
//Select slew rate and also config for EMC use = 0x201
LPC_IOCON->P3_0 |= 0x201; /* D0 @ P3.0 */
LPC_IOCON->P3_1 |= 0x201; /* D1 @ P3.1 */
LPC_IOCON->P3_2 |= 0x201; /* D2 @ P3.2 */
LPC_IOCON->P3_3 |= 0x201; /* D3 @ P3.3 */

LPC_IOCON->P3_4 |= 0x201; /* D4 @ P3.4 */
LPC_IOCON->P3_5 |= 0x201; /* D5 @ P3.5 */
LPC_IOCON->P3_6 |= 0x201; /* D6 @ P3.6 */
LPC_IOCON->P3_7 |= 0x201; /* D7 @ P3.7 */

LPC_IOCON->P3_8 |= 0x201; /* D8 @ P3.8 */
LPC_IOCON->P3_9 |= 0x201; /* D9 @ P3.9 */
LPC_IOCON->P3_10 |= 0x201; /* D10 @ P3.10 */
LPC_IOCON->P3_11 |= 0x201; /* D11 @ P3.11 */

LPC_IOCON->P3_12 |= 0x201; /* D12 @ P3.12 */
LPC_IOCON->P3_13 |= 0x201; /* D13 @ P3.13 */
LPC_IOCON->P3_14 |= 0x201; /* D14 @ P3.14 */
LPC_IOCON->P3_15 |= 0x201; /* D15 @ P3.15 */

LPC_IOCON->P4_1 |= 0x201; /* A1 @ P4.1 */
LPC_IOCON->P4_2 |= 0x201; /* A2 @ P4.2 */
LPC_IOCON->P4_3 |= 0x201; /* A3 @ P4.3 */

LPC_IOCON->P4_4 |= 0x201; /* A4 @ P4.4 */
LPC_IOCON->P4_5 |= 0x201; /* A5 @ P4.5 */
LPC_IOCON->P4_6 |= 0x201; /* A6 @ P4.6 */
LPC_IOCON->P4_7 |= 0x201; /* A7 @ P4.7 */

LPC_IOCON->P4_8 |= 0x201; /* A8 @ P4.8 */
LPC_IOCON->P4_9 |= 0x201; /* A9 @ P4.9 */
LPC_IOCON->P4_10 |= 0x201; /* A10 @ P4.10 */
LPC_IOCON->P4_11 |= 0x201; /* A11 @ P4.11 */

LPC_IOCON->P4_13 |= 0x201; /* A13 @ P4.13 */
LPC_IOCON->P4_14 |= 0x201; /* A14 @ P4.14 */
LPC_IOCON->P4_15 |= 0x201; /* A15 @ P4.15 */
LPC_IOCON->P4_16 |= 0x201; /* A16 @ P4.16 */

LPC_IOCON->P4_17 |= 0x201; /* A17 @ P4.17 */
LPC_IOCON->P4_18 |= 0x201; /* A18 @ P4.18 */
LPC_IOCON->P4_19 |= 0x201; /* A19 @ P4.19 */

LPC_IOCON->P2_24 |= 0x201; /* /OE @ P2.24 ..EMC_CKE0*/ //******ONE mistake here spotted and corrected by Mike 
LPC_IOCON->P4_25 |= 0x201; /* /WEN @ P4.25 */
LPC_IOCON->P4_26 |= 0x201; /* /BLS0 @ P4.27  Lower Byte*/
LPC_IOCON->P4_27 |= 0x201; /* /BLS1 @ P4.27  Upper Byte*/

LPC_IOCON->P2_14 |= 0x201; /* /CS2 @ P2.14*/

}

void EMCInit (void)
{
//SRAM_INIT();
pinConfig_SRAM();
LPC_SC->PCONP |= 0x00000800;

//LPC_SC->EMCDLYCTL = 0x00001010;
//LPC_SC->EMCDLYCTL |= (8<<0);
//LPC_SC->EMCDLYCTL |= (8<<8);

//LPC_SC->EMCDLYCTL |= (8<<16);
LPC_SC->EMCCLKSEL = 0x00000000;  //CLCK = EMCCLK

LPC_EMC->Config   = 0x00000000;
LPC_EMC->StaticExtendedWait = 0x00;
/* Configure memory layout, but MUST DISABLE BUFFERs during configuration */
/*The buffers can be enabled or disabled for static memory using the EMCStaticConfig Registers.*/
LPC_EMC->StaticConfig2 = 0x00000081; //16bit & active low lower and upper byte select

LPC_EMC->StaticWaitWen2   = 0x00000001;            //WaitWen0+1 Delay from CHip Select to Write Enable
LPC_EMC->StaticWaitWr2    = 0x00000001;            // program the delay from the chip select to the write access
LPC_EMC->StaticWaitOen2   = 0x00000001;            // Chip Select to output enable or address change whichever is later
LPC_EMC->StaticWaitRd2    = 0x00000001;            //Chip select to read access
//LPC_EMC->StaticWaitPage2  = 0x00000000;          //Delay for asynchronous page mode sequential accesses for EMC_CS0.
//LPC_EMC->StaticWaitTurn2  = 0x00000000;         //Number of bus turnaround cycles EMC_CS0.

LPC_EMC->Control  = 0x00000001; //May not be needed
}

***************************************************************************************************************************************************************************************
//This portion is to do a test read and write
void Memtest(void)
{
  volatile unsigned long *start= (volatile unsigned long *) 0x98000000UL;
  //volatile unsigned short *start= (volatile unsigned short *) 0x98000000;
  int value=0;
  int i;
  //for(i = 0; i < 1048576; i+= 4)
  for(i = 0; i < 128; i+= 1)  //try just smaller bytes first.
  {
    *start = value; 
    start++;
    value++;
  }
}

int main(void)
{
  EMCInit(); 
  while(1)
  {
    Memtest();
  }
}
Labels (1)
0 Kudos
10 Replies

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Mon Jan 19 07:21:06 MST 2015
Oh dear, I was trying to explain the assember without explaining all the background that is required (i.e. a book). Sigh.

Anyway, the line "emcSWaitOen0 = 0x208" in the asm is the same as "#define emcSWaitOen0 0x208"
It is the offset from the base of the EMC peripheral register block to the EMCStaticWaitWen0 register (as mentioned
in the UM. This (and the other such 'equates') do not write their definitions anywhere, it's just the asm version
of a #define.

The actual setup of this register [Note I am using chip select 0 in my code, you will want the chip select 2 equivalents]
is handled by the pair of asm lines
ldrbr0, [r2], 1; OE delay
strr0, [r3, emcSWaitOen0]; 0..15

I.e. read a byte into register 0 from the pointer in register 2 and increment the pointer by one
(the higher order bytes get zeroed)
then store a word (32-bit value in register 0) to the pointer in register 3 plus the defined offset (i.e. emcSWaitOen0 or
0x208).

Because I have already set register 3 to be the base of the EMC peripheral register block (0x2009C000 as defined in
the UM), these two lines of assembler are the same as the "C"
Allowing for minor peripheral register naming differences and the fact that I need to write to the chip select 0 set of registers.

LPC_EMC->StaticWaitOen0   = (unsigned long) *ramTbl++;


Note also, that my emc clock is much faster than yours, so my timing numbers will be bigger than the ones that
you should be using.

I hope that that clarifies any misunderstanding.

Mike





0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Mon Jan 19 00:39:15 MST 2015
Hi Mike,

Just wondering the discrepancy of value you wrote to

emcSWaitOen0= 0x208

Since based on the calculation I did that you have shown isn't the value in written to this register suppose to be 0x2 instead of 0x208?  Since the value of WAITOEN in the equation you use is 2.


bit 0:3
Wait output enable.
Delay from chip select assertion to output enable.
0x0 = No delay (POR reset value).
0x1 - 0xF = n cycle delay. The delay is WAITOEN x tEMCCLK 
0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Thu Jan 15 06:57:06 MST 2015
Hi.

I am running the LPC1778 at 120 MHz and EMC clock is CPU clk divide by 2;
I.e emcClk = 60MHz = 16.67 ns

From my Memory datasheet I get 70-35 = 35. For my emc clock speed this should be 3
by simple arithmetic, but there is a 2.7 ns constant as seen in the datasheet so 2x16.67+2.7 is OK.

Take the fifth item im my timing list "5-2". This is for staticWaitWrite register.
The UM says the the time is (n+2)xTcyc. So as I want 5 cycles, I put 5-2 as the datum.
The others are similarly adjusted.

First some equates. Think #defines
Not shown in my snippets, all numbers from user manual

emcBase= 0x2009C000; External Memory Controller

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

emcSExtWait= 0x080;

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

one important assignment (not shown previously) as if "C"

pretend we have
long *r3; as a variable. Then
   r3 = (long *) emcBase;   // r3 -> emc register block

and as for ...

ramTbl:.byte 1-0,5-1,4-1; CS-OE, CS-RD, Page RD
.byte 1-1,5-2; CS-WE, CS-WR
.byte 1-1,0,0; Bus Turnround, pad[2]

equivalent to unsigned char ramTbl[] = {1-0, 5-1, 4-1, 1-1, 5-2, 1-1, 0, 0};

Makes it easier to experiment with timing values rather than hard coding a constant in each of the 6 places.

and addr r2, ramTbl is equivalint to variable (i.e.r2 or tblPtr) = &ramTbl[0]; [or simply r2 = ramTbl; in "C" idiom]

ldrbr0, [r2], 1; OE delay
The "C" would be tmp = *r2++; // where r0 = tmp and r2 is the pointer to ramTbl

strr0, [r3, emcSWaitOen0]; 0..15

"C":  *(r3+emcSWaitOen0) = tmp;

Or from your coding

     LPC_EMC->StaticWaitOen2   = (long) (*tblPtr++);



0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Thu Jan 15 02:32:39 MST 2015
Mike,

Yep thanks for the pointers for the memory test, I did mine something like this, putting it here as a sharing. The simplistic test I had earlier was to make me able to see my SRAM working after initialization. Most simplest of all read and write    However only after you shown me what you did, I went to further looked into how things are done.

While checking through the test, I obtained a rather interesting result as shown as in the picture, this problem comes and go because when I put a break point in different parts of the address test code it has this signature of failure, lesser chance of occuring when breakpoint is around. Higher chance of occurence when CPU is on free running. I am thinking should be due to the timing issue as I have not set it up correctly yet.


typedef unsigned short datum;     /* Set the data bus width to 16 bits. */

datum
memTestDataBus(volatile datum * address)
{
    datum pattern;
    /*
     * Perform a walking 1's test at the given address.
     */
    for (pattern = 1; pattern != 0; pattern <<= 1)
    {
        /*
         * Write the test pattern.
         */
        *address = pattern;
        /*
         * Read it back (immediately is okay for this test).
         */
        if (*address != pattern)
        {
            return (pattern);
        }
    }
    return (0);
}   /* memTestDataBus() */


datum *
memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes)
{
    unsigned long addressMask = (nBytes/sizeof(datum) - 1);
    unsigned long offset;
    unsigned long testOffset;
    datum pattern     = (datum) 0xAAAAAAAA;
    datum antipattern = (datum) 0x55555555;
    /*
     * Write the default pattern at each of the power-of-two offsets.
     */
    for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
    {
        baseAddress[offset] = pattern;
    }
    /*
     * Check for address bits stuck high.
     */
    testOffset = 0;
    baseAddress[testOffset] = antipattern;
    for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
    {
        if (baseAddress[offset] != pattern)
        {
            return ((datum *) &baseAddress[offset]);
        }
    }
    baseAddress[testOffset] = pattern;
    /*
     * Check for address bits stuck low or shorted.
     */
    for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
    {
        baseAddress[testOffset] = antipattern;
        if (baseAddress[0] != pattern)
        {
            return ((datum *) &baseAddress[testOffset]);
        }
        for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
        {
            if ((baseAddress[offset] != pattern) && (offset != testOffset))
            {
                return ((datum *) &baseAddress[testOffset]);
            }
        }
        baseAddress[testOffset] = pattern;
    }
    return (NULL);
}   /* memTestAddressBus() */


0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Wed Jan 14 19:48:04 MST 2015
Hi Mike,

Wow...deep assembly stuff. I have to admit I am a bit stumped on some part. Could you kindly explain what you did here.
ramTbl:.byte 1-0,5-1,4-1; CS-OE, CS-RD, Page RD
.byte 1-1,5-2; CS-WE, CS-WR
.byte 1-1,0,0; Bus Turnround, pad[2]



The reason I ask is because based on the SRAM data sheet and also the LPC1778 datasheet(where the equations are for timing), there is something I don't quite get. For example CS-OE means time measured from CS goes low till OE goes low. From what I can understand it means tACS - tOE which is 55-30 = 25ns. This value is from the SRAM device datasheet.

For the EMC portion I am looking at page 81, condition RD2. So looking at the equation, since my Tclk = 1/12Mhz = 83.3ns if I multiply that with WAITOEN value no matter the value, it will always be larger than timing value obtained from SRAM(which is 25ns). Correct me if I am wrong as I am working through it, the 25ns means you need at least 25ns delay from the EMC side for them to talk to each other?

As for WAITRD value I am looking at RD5, from the timing diagram it seems like it is referring to tOE(memory access time) which is 30ns(from the SRAM datasheet in the read cycle). So if I understand you correctly does it mean that (WAITRD-WAITOEN +1)*Tclk -2.83 = 30ns? If I do that the equation will again having the left hand side greater than 30ns as the value of Tclk = 83.3ns.

So would you kindly offer some insights as to how I can decode these information? I really would like to learn how it is done correctly.
0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Wed Jan 14 08:18:23 MST 2015
I find it clearer and easier to understand the timings by writing the value that I want to end up with
and the adjusting for what the register wants (which is variable) your number do not seem to match mine

You really need to check the datasheet for your memory devices and look at the DATASHEET for the 1778; there
are some cool wave form diagrams.
Convert Mem datasheet ns to EMC clock cycles (ROUNDING UP!)

My Static RAM setup
-----------------------------------------------------------------------!
; Init Low Power RAM!
;-----------------------------------------------------------------------!

ramTbl:.byte 1-0,5-1,4-1; CS-OE, CS-RD, Page RD
.byte 1-1,5-2; CS-WE, CS-WR
.byte 1-1,0,0; Bus Turnround, pad[2]


fn InitLPRAM

movsr0, (1<<7)+(0<<6)+(0<<3)+(1<<0) ; Byte lanes active (WE)
; CS is active low
; !Page burst
; 16 bit data bus
movtr0, (0<<4)+(0<<3)+(0<<0); !WP/!buffer/!ext wait
strr0, [r3, emcSConfig0]; set options as above

adrr2, ramTbl; memory timing table

ldrbr0, [r2], 1; OE delay
strr0, [r3, emcSWaitOen0]; 0..15
ldrbr0, [r2], 1; Read delay
strr0, [r3, emcSWaitRd0]; 0..31 +1
ldrbr0, [r2], 1; Page mode read delay
strr0, [r3, emcSWaitPage0]; 0..31 +1

ldrbr0, [r2], 1; WE delay
strr0, [r3, emcSWaitWen0]; 0..15 +1
ldrbr0, [r2], 1; Write delay
strr0, [r3, emcSWaitWr0]; 0..31 +2

ldrbr0, [r2] ; bus turn round delay
strr0, [r3, emcSWaitTurn0]; 0..15 +1
bxlr;

fe InitLPRAM


Your memory test is a tad simplistic, here are mine (change address range to your setup!, and remember that
I am using the address shift feature -- probably does not matter)

Test Data checks for stuck data bus lines
Test Addr checks for stuck addr bus lines
Test Dev is the full address range/data range test

;-----------------------------------------------------------------------!
; MemTestData!
;-----------------------------------------------------------------------!

fn MemTestData

movsr3, 0x80000000; LP RAM
movsr2, (1<<15); D15
0:strr2, [r3]; write data bit
ldrr1, [r3]; read back
subsr0, r1, r2; same?
bne9f; OOPS
lsrsr2, 1; next data bit
bne0b; all done?
9:bxlr; return (0 = ok)

fe MemTestData

;-----------------------------------------------------------------------!
; MemTestAddr!
;-----------------------------------------------------------------------!

fn MemTestAddr

push{r4,r5,r7,lr}; save regs
movsr7, 0x80000000; LP RAM
movwr5, 0x5555; pattern
movwr4, 0xAAAA; inverse

;---------------------------------------;
movsr3, (1<<18); A18
0:strhr5, [r7, r3]; populate SRAM with pattern
lsrsr3, 1;
cmpr3, 1; done (A18..A01)?
bhi0b; not yet

;---------------------------------------;
movsr3, (1<<18); A18
strhr4, [r7]; check for bits stuck high
0:ldrhr1, [r7, r3]; check address bit
subsr0, r1, r5; intact?
bne9f; OOPS
lsrsr3, 1;
cmpr3, 1; done (A18..A01)?
bhi0b; not yet
strhr5, [r7]; now, set base addr to pattern

;---------------------------------------;
movsr3, (1<<18); A18 (test)
0:strhr4, [r7, r3]; set addr bit to inverse

ldrhr1, [r7]; stuck low test
subsr0, r1, r5; intact?
bne9f; OOPS

movsr2, (1<<18); A18 (probe)
1:cmpr2, r3; skip if test = probe
beq2f;
ldrhr1, [r7, r2]; shorted test
subsr0, r1, r5; intact?
bne9f; OOPS

2:lsrsr2, 1; next probe bit
cmpr2, 1; done (A18..A01)?
bhi1b; not yet

strhr5, [r7, r3]; set addr bit back to pattern
lsrsr3, 1; next test bit
cmpr3, 1; done (A18..A01)?
bhi0b; not yet

;---------------------------------------;
9:pop{r4,r5,r7,pc}; return

fe MemTestAddr

;-----------------------------------------------------------------------!
; MemTestDevice!
;-----------------------------------------------------------------------!

fn MemTestDev

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

movsr3, 0x80000000; LP RAM
movsr2, (1<<19); nbr bytes (512 Kb)
movsr1, 7; start value

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

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

movsr3, 0x80000000; LP RAM
movsr2, (1<<19); nbr bytes (512 Kb)
movsr1, 7; 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, 0x80000000; LP RAM
movsr2, (1<<19); nbr bytes (512 Kb)
movsr1, 7; 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 MemTestDev


The forum messed up the tabs a bit, when you re-line up the comments have "C" ish comments

Regards, MIke








0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Wed Jan 14 02:32:11 MST 2015
When I tried your timing, looks ok too.
This is what you meant right when you showed me the timing values? Need to confirm with you just so that I fully understood what you are trying to do.


void EMCInit (void)
{
SRAM_INIT();
pinConfig_SRAM();
LPC_SC->PCONP |= 0x00000800;


LPC_SC->EMCCLKSEL = 0x00000000;  //CLCK = EMCCLK

LPC_EMC->Config   = 0x00000000;
LPC_EMC->StaticExtendedWait = 0x00;

LPC_EMC->StaticConfig2    = 0x00080189; //16bits,Asynch PageMode On, CS active low, active low BLs,Extend Wait, Buffer enable 
LPC_EMC->StaticWaitWen2   = 0x00000000;            //WaitWen0+1 Delay from CHip Select to Write Enable
LPC_EMC->StaticWaitWr2    = 0x00000003;            // program the delay from the chip select to the write access
LPC_EMC->StaticWaitOen2   = 0x00000001;            // Chip Select to output enable or address change whichever is later
LPC_EMC->StaticWaitRd2    = 0x00000003;            //Chip select to read access
LPC_EMC->StaticWaitPage2  = 0x00000003;          //Delay for asynchronous page mode sequential accesses for EMC_CS0.
LPC_EMC->StaticWaitTurn2  = 0x00000000;         //Number of bus turnaround cycles EMC_CS2.

LPC_EMC->Control  = 0x00000001; 
}


My memtest that I am implementing
void Memtest(void)
{
  volatile unsigned long *start= (volatile unsigned long *) 0x98000000UL;
  volatile unsigned long *finish= (volatile unsigned long *) 0x98100000UL;
  
  int value=0;
  int i;
  int Memory_Size = 1048576;
  //int Memory_Size = 2048;
  for(i = 0; i < Memory_Size; i+= 4)
  //for(i = 0; i < 32; i+= 1)  //try just 32 bytes first.
  {
    *start = value; 
    start++;
    value++;
  }
   for(i = Memory_Size; i > 0; i-= 4)
  {
    *finish = value; 
    finish--;
    value--;
  }

}
0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Wed Jan 14 02:19:40 MST 2015
Seems like it is working now.
I do however run into some interesting error message if I leave it running, the message just said memory read operation timed out. I have not changed it to your timing settings yet. Will try it next.
I currently changed my config to the following..


void EMCInit (void)
{
SRAM_INIT();
pinConfig_SRAM();
LPC_SC->PCONP |= 0x00000800;
LPC_SC->EMCCLKSEL = 0x00000000;  //CLCK = EMCCLK

LPC_EMC->Config   = 0x00000000;
LPC_EMC->StaticExtendedWait = 0x00;
/* Configure memory layout, but MUST DISABLE BUFFERs during configuration */
/*The buffers can be enabled or disabled for static memory using the EMCStaticConfig Registers.*/
LPC_EMC->StaticConfig2    = 0x00080189; //16bits,Asynch PageMode On, CS active low, active low BLs,Extend Wait, Buffer enable 
LPC_EMC->StaticWaitWen2   = 0x00000001;            //WaitWen0+1 Delay from CHip Select to Write Enable
LPC_EMC->StaticWaitWr2    = 0x00000001;            // program the delay from the chip select to the write access
LPC_EMC->StaticWaitOen2   = 0x00000001;            // Chip Select to output enable or address change whichever is later
LPC_EMC->StaticWaitRd2    = 0x00000001;            //Chip select to read access
LPC_EMC->StaticWaitPage2  = 0x00000001;          //Delay for asynchronous page mode sequential accesses for EMC_CS0.
LPC_EMC->StaticWaitTurn2  = 0x00000001;         //Number of bus turnaround cycles EMC_CS2.

LPC_EMC->Control  = 0x00000001; 
}
0 Kudos

2,796 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by arion2001 on Wed Jan 14 01:59:14 MST 2015
Hi Mike,

Thanks for your reply, let me get a cleaner image of the hardware posted up. Why CS2 instead of CS0? Well the CS0 to CS1 was used by NOR flash. So the remainder CS is integrated for SRAM. Let me try out your suggestion and will let you know how goes it. Thanks for code tag reminder though. Always too trigger happy with the copy paste.

Good catch with the P2[24]...I really missed that dude as I was scanning through my code.
0 Kudos

2,797 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Wed Jan 14 01:16:18 MST 2015
Your scematic is too fuzzy to read, but OE (pin 41 if TSOP2) on mem device goes to OE on CPU (P4-24)

In your pin setup, you set P2-24 which is CKE0 (clock enable 0 is for SDRAM not SRAM)

Also, I set the pin configs to 0x209, which enables pullups as well as flast slew.
You DO need the final enable to EmcControl.

Again, your image is unclear ...
Traditionally for 16-bit memory, you connect CPU A1 to MEM A0, A2 -> A1 etc.
BUT the 1778 and 1788 has an 'address shift feature'. when enabled, connect A0 to A0, A1 to A1 etc.
See System Controls and Status Register (UM 3.3.20 in latest manual).

Not sure about your timings, this what I used (NB the minus x's are to account for the register
minus x etc.) they are in EMC clock units.
ramTbl:.byte 1-0,5-1,4-1; CS-OE, CS-RD, Page RD
.byte 1-1,5-2; CS-WE, CS-WR
.byte 1-1,0,0; Bus Turnround, pad[2]


I could post my assmbler code if you like (you can get numbers and register settings from it), but I think your
pin config error (and possibly timings) will see you right.
Why CS2 rather than CS0?

Please use code tags!

Hope this helps, Mike.




0 Kudos