SDRAM setup problem

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

SDRAM setup problem

5,296 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tjoAG on Thu May 31 03:18:27 MST 2012
Hi all

Hope someone can help me. I have some problems getting the EMC and SDRAM setup correctly.
I think I may have something to do with the value loaded to the mode register!?

Basics:
I'm using a LPC1788 at 120 MHz and the EMC clk is set to 120 MHz as well.
I'm using Micron MT48LC8M16A2. It is a 16 bit 128 Mbit SDRAM. 4 banks. Using CAS 3 133 MHz is possible

Address Connections

LPC     SDRAM
A0       A0
A1       A0
..       ..
..       ..
A11      A11
A12      BA0
A13      BA1

See the init code i'm using below.

This is what I see:

32 bit writes:
Value 0x11223344 written to base address.
Also written the value to base address + 8 and base address + 12

Memory view:
44 33 22 11 00 00 00 00 44 33 22 11 44 33 22 11 00 00 0....

8 bit writes

Write value 0x11 at offset 0:
11 00 00 00 00 00 00 00 00 0.....  <-- OK

Write value 0x22 at offset 1:
11 22 00 00 00 00 00 00 00 0.....  <-- OK

Write value 0x33 at offset 2:
11 22 33 00 00 00 00 00 00 0.....  <-- OK

Write value 0x44 at offset 3
33 44 33 44 00 00 00 11 22 33 44 33 44 33 44 00 00 0.... <-- Aggghhhhhh

Something seems to happen when the SDRAM is addressed if the high area?. I cant figure out what!!??

Is it OK using the A12 and A13 as BA0 and BA1 or must it be A13 and A14??

All help is appreciated

Best regards Thomas



EMC init code:
<code>
CLKPWR_SetCLKDiv(CLKPWR_CLKTYPE_EMC, 0x00000000); // 120 MHz EMC clk
LPC_SC->PCONP      |= 0x00000800;
LPC_SC->EMCDLYCTL   = 0x00001010;
LPC_EMC->Control    = 0x00000001;
LPC_EMC->Config     = 0x00000000;

LPC_IOCON->P2_16 |= 0x201; // CAS
LPC_IOCON->P2_17 |= 0x201; // RAS
LPC_IOCON->P2_18 |= 0x201; // RAM clk
LPC_IOCON->P2_20 |= 0x201; // DYSC0
LPC_IOCON->P2_24 |= 0x201; // CLKEN0
LPC_IOCON->P2_28 |= 0x201; // LDQM
LPC_IOCON->P2_29 |= 0x201; // UDQM
// D0-15
LPC_IOCON->P3_0 |= 0x201;
LPC_IOCON->P3_1 |= 0x201;
LPC_IOCON->P3_2 |= 0x201;
LPC_IOCON->P3_3 |= 0x201;
LPC_IOCON->P3_4 |= 0x201;
LPC_IOCON->P3_5 |= 0x201;
LPC_IOCON->P3_6 |= 0x201;
LPC_IOCON->P3_7 |= 0x201;
LPC_IOCON->P3_8 |= 0x201;
LPC_IOCON->P3_9 |= 0x201;
LPC_IOCON->P3_10 |= 0x201;
LPC_IOCON->P3_11 |= 0x201;
LPC_IOCON->P3_12 |= 0x201;
LPC_IOCON->P3_13 |= 0x201;
LPC_IOCON->P3_14 |= 0x201;
LPC_IOCON->P3_15 |= 0x201;
//A0-13
LPC_IOCON->P4_0 |= 0x201;
LPC_IOCON->P4_1 |= 0x201;
LPC_IOCON->P4_2 |= 0x201;
LPC_IOCON->P4_3 |= 0x201;
LPC_IOCON->P4_4 |= 0x201;
LPC_IOCON->P4_5 |= 0x201;
LPC_IOCON->P4_6 |= 0x201;
LPC_IOCON->P4_7 |= 0x201;
LPC_IOCON->P4_8 |= 0x201;
LPC_IOCON->P4_9 |= 0x201;
LPC_IOCON->P4_10 |= 0x201;
LPC_IOCON->P4_11 |= 0x201;
LPC_IOCON->P4_12 |= 0x201; // BA0
LPC_IOCON->P4_13 |= 0x201; // BA1

LPC_IOCON->P4_25 |= 0x201; // WE

LPC_EMC->DynamicConfig0    = 0x00000480; /* 128B, 8Mx16, row=12, 4 banks,  column=9 */
//Timing for 120MHz Bus: 8.333333 ns/clk
LPC_EMC->DynamicRasCas0    = 0x00000303; // 3 RAS, 3 CAS latency */
//LPC_EMC->DynamicReadConfig = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
LPC_EMC->DynamicRP         = 0x00000003; // Min 20ns. (n + 1) -> 3 clock cycles
LPC_EMC->DynamicRAS        = 0x00000006; // Min 44 ns.(n + 1) -> 6 clock cycles
LPC_EMC->DynamicSREX       = 0x0000000A; // Min 75 ns. ( n + 1 ) -> 10 clock cycles */
LPC_EMC->DynamicAPR        = 0x00000005; // ??? ( n + 1 ) -> 2 clock cycles */
LPC_EMC->DynamicDAL        = 0x00000006; // tWR + tRP: min 35 ns (n + 1) -> 5 clock cycles */
LPC_EMC->DynamicWR         = 0x00000002; // Min 15 ns. ( n + 1 ) -> 2 clock cycles */
LPC_EMC->DynamicRC         = 0x00000008; // Min 66 ns. ( n + 1 ) -> 8 clock cycles */
LPC_EMC->DynamicRFC        = 0x00000008; // Min 66 ns. ( n + 1 ) -> 8 clock cycles */
LPC_EMC->DynamicXSR        = 0x0000000A; // Min 75 ns. ( n + 1 ) -> 10 clock cycles */
LPC_EMC->DynamicRRD        = 0x00000002; // Min 15 ns. ( n + 1 ) -> 2 clock cycles */
LPC_EMC->DynamicMRD        = 0x00000002; // 2 tCK. ( n + 1 ) -> 2 clock cycles */

TIM_Waitms(100);   /* wait 100ms */
LPC_EMC->DynamicControl    = 0x00000183; /* Issue NOP command */
TIM_Waitms(200);   /* wait 200ms */
LPC_EMC->DynamicControl    = 0x00000103; /* Issue PALL command */
LPC_EMC->DynamicRefresh    = 0x00000002; /* ( n * 16 ) -> 32 clock cycles */

for(i = 0; i < 0x80; i++);           /* wait 128 AHB clock cycles */

//Timing for 120MHz Bus
LPC_EMC->DynamicRefresh    = 0x2E;
LPC_EMC->DynamicControl    = 0x00000083; /* Issue MODE command */

//Timing for 48/60/72MHZ Bus
dwtemp = *((volatile uint32_t *)(SDRAM_BASE_ADDR | (0x33<<(13)))); /* 8 burst, 3 CAS latency */
LPC_EMC->DynamicControl    = 0x00000000; /* Issue NORMAL command */

//[re]enable buffers
LPC_EMC->DynamicConfig0    |= 0x00080000; // Buffer enable
TIM_Waitms(100);
</code>
Labels (1)
0 Kudos
Reply
14 Replies

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Prabhakaran_Raja on Thu Feb 18 07:12:25 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

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Marc Crandall on Wed Jun 20 09:27:02 MST 2012
Same comments as other thread...



The mapping of address lines to address bits can be found here:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0269a/Bgbgcgbf.html

Note, this changes based on the type of memory you are using.

Also note that the EMC of the LPC1788 is only rated to 80MHz not 120MHz and the EMC clock is feed from the CPU clock not the MUX as shown in the diagram above. This means that when your CPU is running at 120MHz the max your EMC can run at is 60MHz (CPU/2)

MAC
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tjoAG on Thu Jun 14 22:32:33 MST 2012
Hi Phil

Thanks a lot for you help. I now have my SDRAM working as expected :-)

If you ever come to DK I will give you free Beer :-)

I also have tried running at 120 MHz EMC clock. But after if I run RAM test continual it fail at some point.
Maybe I just need to change some timing parameters, I don't know.

But it doesn't matter for my application to have fats RAM access.

Thomas
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PhilYoung on Wed Jun 13 16:33:59 MST 2012
Hi Thomas,
I think you have mis-understood my posts. I never argued about the connection of BS0/1 to PINS A13/A14, this is definitely a requirement. My point is that these are just pin names and do not represent the actual signals that they carry in SDRAM mode. in SDRAM mode they should be called BS0/BS1, but they are shared with the Static controller so their function depends on what device owns the external bus interface at any particular instant.
In reality the BS0/BS1 address bits are selected by the SDRAM controller depending on the active configuration and routed to these pins when the SDRAM is being accessed.
what is important is is understanding that they are NOT A13/A14, but are in fact really A10/A11, or A22/A23 depending on the mode in your configuration ( RBC / BRC ).

now, as you expect 0x0102 at the base address, but actually get 0x0502 you can compute where the address overflowed.
after 0x0100 writes you get 0x0202, after 0x400 you get 0x0502, so that would be at location 0x0800 ( address bit A11 ) as the address increments by 2 for each write.

in RBC mode A11 should be mapped to BS1, so it suggests that BS1 (PIN A14) is not driving the SDRAM pin correctly.

regards

Phil.
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tjoAG on Wed Jun 13 06:29:51 MST 2012
Hi Phil

I do appreciate the time you take to answer the postings...

I'm pretty sure I use the memory controller and MODE register is loaded with the correct values. But again, something state otherwise :-)

I have lowered the EMC clock to 60MHz to be a bit larger with the timing.

I'm using the Micron MT48LC8M16-75. It has 16 MBytes. According to the datasheet, unless I read it wrongly, it is a 128 Mb, 8M16, 12 row, 9 column and 4 banks.

So I set the SDRAM selection in the EMC to:
RBC: LPC_EMC->DynamicConfig0 = 0x00000480 --> 128 Mb (8Mx16), 4 banks, row length = 12, column length = 9
BRC: LPC_EMC->DynamicConfig0 = 0x00001480 --> 128 Mb (8Mx16), 4 banks, row length = 12, column length = 9

The mode register is loaded with:
RBC: Temp = *(volatile uint32_t *)(SDRAM_BASE_ADDR|((0x33<<12))); 
BRC: Temp = *(volatile uint32_t *)(SDRAM_BASE_ADDR|((0x33<<10)));

This matches the shift values in your post.
The SDRAM i use has a CAS latency of 3 with clocks <= 133Mhz and 2 with clocks < 100 MHz
I just use CAS 3 to be sure, I can always change it when I get the SDRAM working.

I'm a bit unsure about the burst value 3. It sets the burst length to 8 for the given SDRAM?
But any other value makes it worse!!!

But running the SDRAM in RBC or BRC behaves a bit different!!!

I'm using your suggested RAM test pattern:

<code>
uint16_t data = 0x0102;
for (i=0; i<(0x01000000/2); i++)
{
  *short_wr_ptr++ = data;
  data += 0x0101;
}
</code>

In RBC:

I can write to all location of the SDRAM size of 16 MB(0x01000000)
But at some point the starting address is overwritten:

At address 0xA000 0000 the value 0x0502
At address 0xA002 0000 the value 0x0603
At address 0xA004 0000 the value 0x0704

It is not the first time the value overflow. But a write to address 0xA0000800 also alternate the address 0xA000000

Bank select???

In BRC:

Here I have memory holes (x2) that always reads 0xFF (0xA040 0000 - 0xA072 0000 and 0xA0C0 0000 - 0xA100 0000)
But here the starting address isn't overwritten.
After writes to the total length of the SDRAM I have

At address 0xA000 0000 the value 0x0102
At address 0xA002 0000 the value 0x0203
At address 0xA004 0000 the value 0x0304

So I still believe there is an issue by either the MODE register, the selected SDRAM in the EMC module ot how I have attached the SDRAM.

I have written to NXP tech support and they responded by saying:

"Always connect the LPC1788 - A13 and A14 to the SDRAM's BA0 or BA1 lines."

I know you have argued that it is not the case.

Hopes the input make sense

Thomas
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PhilYoung on Tue Jun 12 10:59:50 MST 2012
Hi Thomas.
the address bus from the CPU is a byte address bus, so for 32 bit accesses the word address is A31..A2, for 16 bit it's A31..A1, and A31..A0 for 8 bits.
( by Word address I refer here to the memory word size, which is 32,16, and8 bits in the 3 modes respectively ).

ignore the pin naming on the device, just use the CPU addresses.
the memory is 16 bits wide, so A31..A1 addresses memory words, depending on the memory size

with collumn address length of 9, 4 banks, row lenbgth of 12 that uses the following signals.
for BRC
  BS = A23..A22,  row address = A21..A10, collum Address = A9..A1
for RBC
  row address = A23..A12, BS = A11..A10, collum Address = A9..A1

The fact that both Row and Collumn address are output from the chip using An..A0 is irrelevant, the address is internally multiplized according to the SDRAM size.

Mode in the SDRAM is loaded from the Row Address, so <<10 for BRC, and <<12 for RBC

If you have a memory hole it suggests that the memory controller is configured for the wrong sized memory, i.e. for 1 extra row address bit. The error occurs when A22 is high.
This would also be consistent with incorrect connection of the BS0 / BS1 signals to the SDRAM.

regards

Phil.
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tjoAG on Mon Jun 11 01:21:23 MST 2012
Hi Phil

Thanks for your help.

It did help me understand it a bit better. I still have some issue though!!!

First of all, I can't see how you come to the the shift values of 12 and 10 for RBC and BRC based on the bank, collumn and row address lines?

The issue still remain for me when running the SDRAM in BRC mode.

I set the dynamic config to 0x1480 : 16 bit LP SDRAM, 128MB (8M*16), banks 4, rows 12, collumn 9
In the MODE command I issue 0x33 shifted 10 times:

dwtemp = *((volatile uint32_t *)(SDRAM_BASE_ADDR | (0x33<<(10))));

Burst length of 8 and a CAS of 3. According to the SDRAM spec, the CAS latency must be 3 if the speed is < then 133 MHz
I'm running EMC clock at 120 MHz

If I do this I have memory holes from address:
0xA040 0000 to 0xA071 FFFF
0xA0C0 0000 to 0xA100 0000

I cant write anything to these areas.

Bank select issue?

At the other addresses I can read/write data with no problems

Running the SDRAM in RBC mode I can read write data at all location. But here, if I enable the LCD controller the data in the SDRAM is corrupted???

But I believe I have to solve the RBC and BRC issue first. Think it will help me with the LCD problem :-)

Any suggestions?

Thomas
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PhilYoung on Sat Jun 09 16:08:25 MST 2012
No,
the external A13/A14 must always be connected to the bank select pins of the SDRAM but when the SDRAM is accessed they are not really A13/A14, they become BS0 / BS1, the address mux is controlled by the SDRAM controller to mux the correct address pins onto them according to the way the SDRAM controller is configured.

the MODE register in the SDRAM must be written to set the CAS delay and the burst length, the controller performs 4 word bursts ( that's 4 32 bit words ), so if you use a 16 bit SDRAM it will actually perform a burst of 8 16 bit transfers, so you would need to set the burst length to 8 in the mode register.

The MODE register is loaded from the ROW address bits, working out which address bits are used for the ROW address is important ( the SDRAM controller will ensure that these are correctly multiplexed onto the external address pins, so you just need to consider the CPU address for this operation ).
if you run RBC ( Row bank Collumn) mode then you need to add collumn address bits + 2 to get the lsb of the row address field, and not if you use BRC ( Bank, Row, Collumn ).
next you have to consider what address bit is actually the LSB of the collumn adddress, for 32 bit SDRAM this is bit 2, for 16 bit it is bit 1.

so if I have a 16 bit SDRAM, 9 bit CAS address, 4 banks, 12 bit row address the mapping is as follows.
for RBC mode
   A0 : Not used ( 16 bit )
   A1..A9 : collumn address
   A10..A11 : Bank Select
   A12..A23 : Row address
   so a left shift of 12 is required
for BRC mode, using the same SDRAM
   A0 : Not used ( 16 bit )
   A1..A9 : collumn address
   A10..A21 : Row address
   A22..A23 : Bank Select
   so a left shift of 10 is required

in reality, the SDRAM controller outputs the CPU address to the pins as follows ( for RBC mode )
CPU Address bits  >>  Address Pins
A12..A23 >> A0..A11 ( row address )
A10..A11 >> A12..A13 ( Bank select )
A1..A9 >> A0..A8 ( collumn address )
and for BRC mode
A11..A21 >> A0..A11 ( row address )
A22..A23 >> A12..A13 ( Bank select )
A1..A9 >> A0..A8 ( collumn address )
because the SDRAM address is multiplexed the SDRAM controller has always to re-map the CPU address to the physical address pins, the address pin numbering will only correspond directly to the CPU address for static memory accesses.

Hope this helps

regards

Phil.

0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tjoAG on Wed Jun 06 02:30:28 MST 2012
Yes, it is very confusing.. :-)

So just to be sure:

Not setting MODE register in the SDRAM requires to use the CPU A13 and A14 as bank select
Setting MODE register in the SDRAM, "any" address pin can be used as bank select

Thomas
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PhilYoung on Tue Jun 05 12:45:24 MST 2012
This is confusing a few people.
The EXTERNAL connection  to the SDRAM requires A13,A14 to be used as the bank select.
Internally however the routing of CPU address lines to the device pins is not fixed, it is changed dynamically since these are shared by multiple interfaces.
for the static controller they are routed directly, but for the dynamic controller the routing is determined by the collum address length and the mode ( i.e. RBC, BRC ).

So you are both correct. You MUST use the external A13,A14 for the bank select, and you should ignore this when computing the values to set the mode register in the SDRAM.

so in SDRAM mode the Address pin numbering does NOT correspond to the CPU address.

regards

Phil.
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tjoAG on Tue Jun 05 03:47:01 MST 2012
Hi

Well, it seems I have got it to work now.

I set the wrong addressing during MODE seting of the SDRAM.

It seems to work using A12 and A13 fromt he CPU as bank select BA0 and BA1??

Thomas
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ole.reinhardt on Fri Jun 01 02:10:36 MST 2012
Hello,

> Is it OK using the A12 and A13 as BA0 and BA1 or must it be A13 and A14??

No, you _have_ to use A13 and A14 as bank select, regardless of the number of address lines the SDRAM has. I got this confirmed from NXP yesterday.

Unfortunately the datasheet does not clearly point this out!

bye,

Ole Reinhardt
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tjoAG on Thu May 31 23:18:01 MST 2012
Hi PhilYoung

You are so right :-)

I was of by one bit. I have done the calculation many times! Wonder where I did the error :-)


Thomas
0 Kudos
Reply

4,112 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PhilYoung on Thu May 31 14:55:57 MST 2012
according to the user manual,
LPC_EMC->DynamicConfig0    = 0x00000480; /* 128B, 8Mx16, row=12, 4 banks,  column=9 */
Address mapping is 0 0 010 01 ( Row Bank Collumn mode ).

so
A0 is not used
Collumn is A9..A1
Bank is A11..A10
Row is A23..A12

so I would expect
dwtemp = *((volatile uint32_t *)(SDRAM_BASE_ADDR | (0x33<<(12)))); /* 8 burst, 3 CAS latency */

0 Kudos
Reply