AnsweredAssumed Answered

How to use SSP to GPDMA with linked list?

Question asked by koting hsu on Sep 8, 2016
Latest reply on Sep 19, 2016 by Andrea Bettati

I've download LPC open, there is a sample described how to use GPDMA to move data from SSP0 buffer to RAM without using linked list.

I've test it without linked list, its works.

But I need to do it with linked list.

Can anyone provide a GPDMA sample code with linked list?
Or help me to edit my code, thanks!

 

#define BUFFER_SIZE (2000)
uint8 Rx_Buf[2][BUFFER_SIZE];
static uint8_t dmaChSSPRx;
static DMA_TransferDescriptor_t gDMADescriptor[2];

 

Chip_GPDMA_Init(LPC_GPDMA);
NVIC_DisableIRQ(DMA_IRQn);
NVIC_SetPriority(DMA_IRQn, ((0x01 << 3) | 0x01));
NVIC_EnableIRQ(DMA_IRQn);

Chip_SSP_DMA_Enable(LPC_SSP0);

dmaChSSPRx = Chip_GPDMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_SSP0_Rx);

Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &gDMADescriptor[0], GPDMA_CONN_SSP0_Rx, (uint32_t)&Rx_Buf[0][0], BUFFER_SIZE, GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, &gDMADescriptor[1]);

Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &gDMADescriptor[1], GPDMA_CONN_SSP0_Rx, (uint32_t)&Rx_Buf[1][0], BUFFER_SIZE, GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, &gDMADescriptor[0]);

Chip_GPDMA_SGTransfer(LPC_GPDMA, dmaChSSPRx, &gDMADescriptor[0], GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA);

 

I received GPDMA_STAT_INTERR interrupt after I called Chip_GPDMA_SGTransfer. 

 

After I check out the register, I found there may be a error in Chip_GPDMA_PrepareDescriptor.

 

typedef struct DMA_TransferDescriptor {
uint32_t src; /*!< Source address */
uint32_t dst; /*!< Destination address */
uint32_t lli; /*!< Pointer to next descriptor structure */
uint32_t ctrl; /*!< Control word that has transfer size, type etc. */
} DMA_TransferDescriptor_t;

 

The src is incorrect, it should be GPDMA_CONN_SSP0_Rx not &LPC_SSP0->DR.

This will cause Chip_GPDMA_InitChannelCfg called by Chip_GPDMA_SGTransfer operated incorrect.

 

Therefore, I've add some code to fix it.

 

gDMADescriptor[0].src = GPDMA_CONN_SSP0_Rx;

gDMADescriptor[1].src = GPDMA_CONN_SSP0_Rx;

 

After add this, The first block of Rx_Buf which size is BUFFER_SIZE works fine. But after it finished, DMA_IRQHandler happened constantly by GPDMA_STAT_INTERR

 

I do not know what I did wrong.

 

Thank you very much for your assistance.

Outcomes