Hi all,
I am trying to interface SDRAM - AS4C8M16SA from Alliance, with LPC4357 (LQFP208 package). I'm not familiar with EMC or SDRAM. I got the RAM get initialized. But ,I cannot successfully write beyond 64 bytes into it. My connection details and initialization code are given below.
SDRAM Details
- Alliance AS4C8M16SA
- 128M - 8M x 16 bit , 2M word x 16-bit x 4-bank
- CAS Latency: 2, or 3
Burst Length: 1, 2, 4, 8, or full page
Burst Type: Sequential or Interleaved - 4096 refresh cycles/64ms
Connections
SDRAM LPC4357
DQ0 - DQ15 EMC_D0 - EMC_D15
A0 - A11 EMC_A1 - EMC_A12
BA0 EMC_A13
BA1 EMC_A14
RAS EMC_RAS
CAS EMC_CAS
CS EMC_DYCS0
WE EMC_WE
NC/RFU NC
LDQM EMC_DQMOUT0
UDQM EMC_DQMOUT1
CLK EMC_CLK0
CKE EMC_CKEOUT0
Note: EMC_A6, EMC_A7, EMC_A8 and EMC_A0 pins are connected to some pull-up circuits to select the ISP method. The connection picture is attached.
Code
void SDRAM_Init () {
uint32_t pclk, temp;
uint32_t tmpclk;
TIM_TIMERCFG_Type TIM_ConfigStruct;
/* Set up EMC pin */
scu_pinmux( 1 , 0 , MD_PLN_FAST , 2 ); //A5
scu_pinmux( 1 , 1 , MD_PLN_FAST , 2 ); //A6
scu_pinmux( 1 , 2 , MD_PLN_FAST , 2 ); //A7
scu_pinmux( 1 , 3 , MD_PLN_FAST , 3 ); //OE
scu_pinmux( 1 , 4 , MD_PLN_FAST , 3 ); //BLS0
scu_pinmux( 1 , 5 , MD_PLN_FAST , 3 ); //CS0
scu_pinmux( 1 , 6 , MD_PLN_FAST , 3 ); //WE
scu_pinmux( 1 , 7 , MD_PLN_FAST , 3 );//D0
scu_pinmux( 1 , 8 , MD_PLN_FAST , 3 );//D1
scu_pinmux( 1 , 9 , MD_PLN_FAST , 3 );//D2
scu_pinmux( 1 , 10 , MD_PLN_FAST , 3 );//D3
scu_pinmux( 1 , 11 , MD_PLN_FAST , 3 );//D4
scu_pinmux( 1 , 12 , MD_PLN_FAST , 3 );//D5
scu_pinmux( 1 , 13 , MD_PLN_FAST , 3 );//D6
scu_pinmux( 1 , 14 , MD_PLN_FAST , 3 );//D7
scu_pinmux( 2 , 0 , MD_PLN_FAST , 2 );//A13
scu_pinmux( 2 , 1 , MD_PLN_FAST , 2 );//A12
scu_pinmux( 2 , 2 , MD_PLN_FAST , 2 );//A11
scu_pinmux( 2 , 6 , MD_PLN_FAST , 2 );//A10
scu_pinmux( 2 , 7 , MD_PLN_FAST , 3 );//A9
scu_pinmux( 2 , 8 , MD_PLN_FAST , 3 );//A8
scu_pinmux( 2 , 9 , MD_PLN_FAST , 0 );//A0// changed as GPIO
scu_pinmux( 2 , 10 , MD_PLN_FAST , 3 );//A1
scu_pinmux( 2 , 11 , MD_PLN_FAST , 3 );//A2
scu_pinmux( 2 , 12 , MD_PLN_FAST , 3 );//A3
scu_pinmux( 2 , 13 , MD_PLN_FAST , 3 );//A4
scu_pinmux( 5 , 0 , MD_PLN_FAST , 2 );//D12
scu_pinmux( 5 , 1 , MD_PLN_FAST , 2 );//D13
scu_pinmux( 5 , 2 , MD_PLN_FAST , 2 );//D14
scu_pinmux( 5 , 3 , MD_PLN_FAST , 2 );//D15
scu_pinmux( 5 , 4 , MD_PLN_FAST , 2 );//D8
scu_pinmux( 5 , 5 , MD_PLN_FAST , 2 );//D9
scu_pinmux( 5 , 6 , MD_PLN_FAST , 2 );//D10
scu_pinmux( 5 , 7 , MD_PLN_FAST , 2 );//D11
scu_pinmux( 6 , 1 , MD_PLN_FAST , 1 );//DYCS1
scu_pinmux( 6 , 3 , MD_PLN_FAST , 3 );//CS1
scu_pinmux( 6 , 4 , MD_PLN_FAST , 3 );//CAS
scu_pinmux( 6 , 5 , MD_PLN_FAST , 3 );//RAS
scu_pinmux( 6 , 6 , MD_PLN_FAST , 1 );//BLS1
scu_pinmux( 6 , 7 , MD_PLN_FAST , 1 );//A15
scu_pinmux( 6 , 8 , MD_PLN_FAST , 1 );//A14
scu_pinmux( 6 , 9 , MD_PLN_FAST , 3 );//DYCS0
scu_pinmux( 6 , 10 , MD_PLN_FAST , 3 );//DQMOUT1
scu_pinmux( 6 , 11 , MD_PLN_FAST , 3 );//CKEOUT0
scu_pinmux( 6 , 12 , MD_PLN_FAST , 3 );//DQMOUT0
scu_pinmux( 10 , 4 , MD_PLN_FAST , 3 );//A23
scu_pinmux( 13 , 0 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 2 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 3 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 4 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 5 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 6 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 7 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 8 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 9 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 10 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 12 , MD_PLN_FAST , 2 );
scu_pinmux( 13 , 13 , MD_PLN_FAST , 2 );//
scu_pinmux( 13 , 11 , MD_PLN_FAST , 2 );//CS3
scu_pinmux( 13 , 14 , MD_PLN_FAST , 2 );//DYCS2
scu_pinmux( 13 , 15 , MD_PLN_FAST , 2 );//A17
scu_pinmux( 13 , 16 , MD_PLN_FAST , 2 );//A16
scu_pinmux( 14 , 0 , MD_PLN_FAST , 3 );//A18
scu_pinmux( 14 , 1 , MD_PLN_FAST , 3 );//A19
scu_pinmux( 14 , 2 , MD_PLN_FAST , 3 );//A20
scu_pinmux( 14 , 3 , MD_PLN_FAST , 3 );//A21
scu_pinmux( 14 , 4 , MD_PLN_FAST , 3 );//A22
scu_pinmux( 14 , 5 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 6 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 7 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 8 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 9 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 10 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 11 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 12 , MD_PLN_FAST , 3 );
scu_pinmux( 14 , 13 , MD_PLN_FAST , 3 );
/* Select EMC clock-out */
LPC_SCU->SFSCLK_0 = MD_PLN_FAST;
LPC_SCU->SFSCLK_1 = MD_PLN_FAST;
LPC_SCU->SFSCLK_2 = MD_PLN_FAST;
LPC_SCU->SFSCLK_3 = MD_PLN_FAST;
TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
TIM_ConfigStruct.PrescaleValue = 1;
// Set configuration for Tim_config and Tim_MatchConfig
TIM_Init(LPC_TIMER0, TIM_TIMER_MODE,&TIM_ConfigStruct);
LPC_EMC->CONTROL = 0x00000001;
LPC_EMC->CONFIG = 0x00000000;
LPC_EMC->DYNAMICCONFIG0 = 0<<19 | 1<<12 | 1<<10 | 1<<7; /* 128Mb, 8Mx16, 4 banks, row=12, column=9 */
pclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);
_DBG("pclk = ");
_DBD32(pclk);
LPC_EMC->DYNAMICRASCAS0 = 0x00000303; /* 1 RAS, 3 CAS latency */
LPC_EMC->DYNAMICREADCONFIG = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */
LPC_EMC->DYNAMICRP = NS2CLK(pclk, 20);
LPC_EMC->DYNAMICRAS = NS2CLK(pclk, 42);
LPC_EMC->DYNAMICSREX = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICAPR = 0x00000005;
LPC_EMC->DYNAMICDAL = 0x00000005;
LPC_EMC->DYNAMICWR = 2;
LPC_EMC->DYNAMICRC = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICRFC = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICXSR = NS2CLK(pclk, 63);
LPC_EMC->DYNAMICRRD = NS2CLK(pclk, 14);
LPC_EMC->DYNAMICMRD = 0x00000002;
TIM_Waitus(100); /* wait 100ms */
LPC_EMC->DYNAMICCONTROL = 0x00000183; /* Issue NOP command */
TIM_Waitus(200); /* wait 200ms */
LPC_EMC->DYNAMICCONTROL = 0x00000103; /* Issue PALL command */
LPC_EMC->DYNAMICREFRESH = EMC_SDRAM_REFRESH(pclk,70); /* ( n * 16 ) -> 32 clock cycles */
//for(i = 0; i < 0x80; i++); /* wait 128 AHB clock cycles */
TIM_Waitus(200); /* wait 200ms */
tmpclk = (uint32_t)15625*(uint32_t)pclk/1000000000/16;
LPC_EMC->DYNAMICREFRESH = tmpclk; /* ( n * 16 ) -> 736 clock cycles -> 15.330uS at 48MHz <= 15.625uS ( 64ms / 4096 row ) */
LPC_EMC->DYNAMICCONTROL = 0x00000083; /* Issue MODE command */
//Timing for 48/60/72MHZ Bus
temp = *((volatile uint32_t *) 0x28023000);//(SDRAM_ADDR_BASE | (0x23<<12)) );//(3<<4| 3)<<11)); /* 4 burst, 3 CAS latency */
temp = temp;
LPC_EMC->DYNAMICCONTROL = 0x00000000; /* Issue NORMAL command */
//[re]enable buffers
LPC_EMC->DYNAMICCONFIG0 |= 1<<19;
}
after init, i used this code
#define FRAMEBUFFER_ADDR 0x28000000
len = 64;
memcpy((uint8_t *)FRAMEBUFFER_ADDR,Buffer720,len);
This will successfully copy 64 bytes. Length above 64 is not working.
Also, if the code is like this, I can copy upto 256 Bytes.
len = 64;
for( i=0;i<4;i++)
{
memcpy((uint8_t *)FRAMEBUFFER_ADDR+(i*64),Buffer720+(i*64),len);
memcmp(FrameBuff,(uint8_t *)FRAMEBUFFER_ADDR+(i*64),len);
}
ie, if reading the values after each 64 bytes, it can copy upto 256 Bytes.
What is wrong in this? Can anyone help me to solve this?