LPC4370 DMA SDRAM

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

LPC4370 DMA SDRAM

2,120 次查看
wsinter
Contributor I

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;
}

标签 (1)
0 项奖励
回复
5 回复数

1,560 次查看
wsinter
Contributor I

Can someone help for teh problem,still I can not find the solution, the Transfer through DMA to SDRAM.

0 项奖励
回复

1,560 次查看
Carlos_Mendoza
NXP Employee
NXP Employee

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

0 项奖励
回复

1,560 次查看
wsinter
Contributor I

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?

0 项奖励
回复

1,560 次查看
Carlos_Mendoza
NXP Employee
NXP Employee

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

0 项奖励
回复

1,560 次查看
wsinter
Contributor I

Hi,Carlos:

The SDRAM is MT48LC16M16A2, I will check the example and try to modify my project.

Thank you

0 项奖励
回复