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;
}
Hi John,
Maybe the DMA implementation could be causing the problem, have you tried using the DMA timer trigger example from LPCOpen as base for your application? You can download the package from this link:
LPCOpen Software for LPC43XX|NXP
Hope it helps!
Best Regards,
Carlos Mendoza
Technical Support Engineer
Carlos,thanks for your reply.
I use HSADC DMA trigger to sample the data, and it is right when I use internal RAM (Address starts from 0x10000000).
But when I use EMC to transfer data to external SDRAM, it is wrong ,the trigger source is also HSADC.
You mean that I need to use DMA timer trigger when use EMC SDRAM?
Hi John,
Thanks for your response.
No, I just mentioned the example to make sure the DMA was correctly initialized. Could you tell us which SDRAM are you using? There is an example included in the LPC1857 LPCOpen package that you can use as reference for your application, it is the GPDMA speed example, tt transfers data from memory to memory. Depending on the SDRAM being used you can also take a look to the EMC control signals setup:
LPCOpen Software for LPC18XX|NXP
Let me know if it helps!
Best Regards,
Carlos Mendoza
Technical Support Engineer