AnsweredAssumed Answered

LPC4370 DMA SDRAM

Question asked by John Wang on Nov 7, 2016
Latest reply on Nov 29, 2016 by John Wang

I use the EMC of LPC4370 to transfer data to SDRAM, it is right when I write and read the data using for loop.

 

piAddr = (uint32_t *)SDRAM_ADDR_BASE + 0;
for (i = 0; i < 12 * 1024 * 1024; i++) {
*piAddr++ = EMCData;
}

 

piAddr = (uint32_t *)SDRAM_ADDR_BASE + 0;

for (i = 0; i < 12 * 1024 * 1024; i++) { 
EMCtemp = *piAddr++;
if (EMCtemp != EMCData) {
SPIDataToSend = 1 ;
}
}

But I need to transfer the data from HSADC to SDRAM through DMA, I found the write operation failed.

 Can some one help me with the problem?

Below is the config for the SDRAM&DMA,  the burst size of DMA is 8.

 

void DMALLISET(uint16_t DataTotal,unsigned char SingleDMA)
{
DMA_LLI_Struct[0].SrcAddr = (uint32_t)&LPC_ADCHS->FIFO_OUTPUT[0] ;
DMA_LLI_Struct[0].DstAddr = (uint32_t )SDRAM_ADDR_BASE ;
DMA_LLI_Struct[0].NextLLI = (uint32_t)&DMA_LLI_Struct[1];
DMA_LLI_Struct[0].Control = (GPDMA_DMACCxControl_TransferSize(DataTotal)|GPDMA_DMACCxControl_SBSize(8)|GPDMA_DMACCxControl_DBSize(8)\
|GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)|GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)\
|GPDMA_DMACCxControl_SrcTransUseAHBMaster1|GPDMA_DMACCxControl_DI);


DMA_LLI_Struct[1].SrcAddr = (uint32_t)&LPC_ADCHS->FIFO_OUTPUT[0] ;
DMA_LLI_Struct[1].DstAddr = (uint32_t)(SDRAM_ADDR_BASE+DataTotal) ;
DMA_LLI_Struct[1].NextLLI = (uint32_t)&DMA_LLI_Struct[2];
DMA_LLI_Struct[1].Control = (GPDMA_DMACCxControl_TransferSize(DataTotal)|GPDMA_DMACCxControl_SBSize(8)|GPDMA_DMACCxControl_DBSize(8)\
|GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)|GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)\
|GPDMA_DMACCxControl_SrcTransUseAHBMaster1|GPDMA_DMACCxControl_DI);


DMA_LLI_Struct[2].SrcAddr = (uint32_t)&LPC_ADCHS->FIFO_OUTPUT[0] ;
DMA_LLI_Struct[2].DstAddr = (uint32_t)(SDRAM_ADDR_BASE+DataTotal*2) ;
DMA_LLI_Struct[2].NextLLI = (uint32_t)&DMA_LLI_Struct[3];
DMA_LLI_Struct[2].Control = (GPDMA_DMACCxControl_TransferSize(DataTotal)|GPDMA_DMACCxControl_SBSize(8)|GPDMA_DMACCxControl_DBSize(8)\
|GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)|GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)\
|GPDMA_DMACCxControl_SrcTransUseAHBMaster1|GPDMA_DMACCxControl_DI);


DMA_LLI_Struct[3].SrcAddr = (uint32_t)&LPC_ADCHS->FIFO_OUTPUT[0] ;
DMA_LLI_Struct[3].DstAddr = (uint32_t)(SDRAM_ADDR_BASE+DataTotal*3) ;
DMA_LLI_Struct[3].NextLLI = 0;
DMA_LLI_Struct[3].Control = (GPDMA_DMACCxControl_TransferSize(DataTotal)|GPDMA_DMACCxControl_SBSize(8)|GPDMA_DMACCxControl_DBSize(8)\
|GPDMA_DMACCxControl_SWidth(GPDMA_WIDTH_WORD)|GPDMA_DMACCxControl_DWidth(GPDMA_WIDTH_WORD)\
|GPDMA_DMACCxControl_SrcTransUseAHBMaster1|GPDMA_DMACCxControl_DI|GPDMA_DMACCxControl_I);
}

 

void SDRAM_Init(void)
{
uint32_t pclk, temp;
uint64_t tmpclk;

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 , 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 , 3 );//A0
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 , 4 , MD_PLN_FAST , 3 );//CAS
scu_pinmux( 6 , 5 , MD_PLN_FAST , 3 );//RAS
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

LPC_SCU->SFSCLK_0 = MD_PLN_FAST; /* Select EMC clock-out */
LPC_SCU->SFSCLK_1 = MD_PLN_FAST;
LPC_SCU->SFSCLK_2 = MD_PLN_FAST;
LPC_SCU->SFSCLK_3 = MD_PLN_FAST;

LPC_EMC->CONTROL = 0x00000001;
LPC_EMC->CONFIG = 0x00000000;
LPC_EMC->DYNAMICCONFIG0 = 0<<14 | 3<<9 | 1<<7; /* 64Mb, 4Mx16, 4 banks, row=12, column=8 */

pclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);

LPC_EMC->DYNAMICRASCAS0 = 0x00000303; //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;

Delay_us(100); /* wait 100ms */
LPC_EMC->DYNAMICCONTROL = 0x00000183; /* Issue NOP command */

Delay_us(200); /* wait 200ms */
LPC_EMC->DYNAMICCONTROL = 0x00000103; /* Issue PALL command */

LPC_EMC->DYNAMICREFRESH = EMC_SDRAM_REFRESH(pclk,20); /* ( n * 16 ) -> 32 clock cycles */

Delay_us(200); /* wait 200ms */

tmpclk = (uint64_t)15625*(uint64_t)pclk/1000000000/16; //15625
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 */

temp = *((volatile uint32_t *)(SDRAM_ADDR_BASE | (3<<4| 3)<<12)); //3<<4 /* 8 burst, 3 CAS latency */
temp = temp;
LPC_EMC->DYNAMICCONTROL = 0x00000000; /* Issue NORMAL command */

LPC_EMC->DYNAMICCONFIG0 |= 1<<19;
LPC_EMC->DYNAMICCONFIG1 |= 1<<19;
LPC_EMC->DYNAMICCONFIG2 |= 1<<19;
LPC_EMC->DYNAMICCONFIG3 |= 1<<19;
}

Outcomes