GPDMA configuration with XMC Lib functrions (XMC4700)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User13334
Level 2
Level 2
Dear forum members,

I Need your help,

In a single block transfer, I can use the following procedure when configuring my DMA channel

1.) Fill structure XMC_DMA_CH_CONFIG_t


XMC_DMA_CH_CONFIG_t GPDMA0_Ch0_config =
{
.enable_interrupt = ...,
.src_transfer_width = ...,
.dst_transfer_width = ...,
.src_address_count_mode = ...,
.dst_address_count_mode = ...,
.src_burst_length = ...,
.dst_burst_length = ...,
.enable_src_gather = ...,
.enable_dst_scatter = ...,
.transfer_flow = ....,
.src_addr = (uint32_t) &...
.dst_addr = (uint32_t) &..,
.src_gather_interval = ...,
.src_gather_count = ...,
.dst_scatter_interval = ...,
.dst_scatter_count = ...,
.block_size = ...,
.transfer_type = ....,
.priority = ....,
.src_handshaking = ...,
};


2.) Init the DMA peripheral


void GPDMA_Init(void)
{


XMC_DMA_Init(XMC_DMA0);
XMC_DMA_CH_Init(XMC_DMA0, 0, &GPDMA0_Ch0_config);
XMC_DMA_CH_EnableEvent(XMC_DMA0, 0, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE);
XMC_DMA_IRQHandler(XMC_DMA0);
NVIC_SetPriority(GPDMA0_0_IRQn,11);
NVIC_EnableIRQ(GPDMA0_0_IRQn);

}


3.) Write IRQ Handler


void GPDMA0_0_IRQHandler(void)
{
uint32_t event;

event = XMC_DMA_CH_GetEventStatus(XMC_DMA0,0);

if(event == XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE)
{
..... Do everything
}


4.) Start DMA from application


XMC_DMA_CH_Enable(XMC_DMA0,0);


But if I have to start a multiblock transfer, the writing of the link list is not a problem with the API function

1.) Fill the structure XMC_DMA_LLI_t


XMC_DMA_LLI_t ll[] =
{
{
.src_addr = (uint32_t)....,
.dst_addr = (uint32_t)....,
.llp = &ll[1],
.block_size = ....,
.enable_interrupt = false,
.dst_transfer_width = ....,
.src_transfer_width = ....,
.dst_address_count_mode = ....,
.src_address_count_mode = ....,
.dst_burst_length = ....,
.src_burst_length = ....,
.enable_src_linked_list = ...,
.transfer_flow = ....
},
{
.src_addr = (uint32_t)....,
.dst_addr = (uint32_t)....,
.llp = &ll[2],
.block_size = ....,
.enable_interrupt = false,
.dst_transfer_width = ....,
.src_transfer_width = ....,
.dst_address_count_mode = ....,
.src_address_count_mode = ....,
.dst_burst_length = ....,
.src_burst_length = ....,
.enable_src_linked_list = ...,
.transfer_flow = ....
},
{
.src_addr = (uint32_t)....,
.dst_addr = (uint32_t)....,
.llp = 0,// last linked list item
.block_size = ....,
.enable_interrupt = true, // we enable the interrupts on the last item to detect when the whole transfer is finished
.dst_transfer_width = ....,
.src_transfer_width = ....,
.dst_address_count_mode = ....,
.src_address_count_mode = ....,
.dst_burst_length = ....,
.src_burst_length = ....,
.enable_src_linked_list = ...,
.transfer_flow = ....
}
};


And now how does the initialization continue with the API functions?

Thanks for your helps

EbbeSand
0 Likes
2 Replies
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
0 Likes
User13334
Level 2
Level 2
Hello Jesus,

So I have to go into the configuration structure for the values ​​from the CTLL
Register the register (called uint32_t control in the structure) with the same values ​​as those in the first element of my linked list item and specify the pointer on the list

This is really so easy? If I now start the DMA channel, the list is worked? Okay, I'll try tomorrow


/* DMA linked list */
static __attribute__((aligned(32))) XMC_DMA_LLI_t dma_ll[2] =
{
{
.block_size = RING_BUFFER_SIZE / 2,
.src_addr = (uint32_t)&(WIFI_IO_UART_CH->RBUF),
.dst_addr = (uint32_t)&ring_buffer[0],
.llp = &dma_ll[1],
.enable_interrupt = true,
.dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT,
.src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE,
.dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1,
.src_burst_length = XMC_DMA_CH_BURST_LENGTH_1,
.transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_P2M_DMA,
.enable_dst_linked_list = true,
.enable_src_linked_list = true,
},
{
.block_size = RING_BUFFER_SIZE / 2,
.src_addr = (uint32_t)&(WIFI_IO_UART_CH->RBUF),
.dst_addr = (uint32_t)&ring_buffer[RING_BUFFER_SIZE / 2],
.llp = &dma_ll[0],
.enable_interrupt = true,
.dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT,
.src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE,
.dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1,
.src_burst_length = XMC_DMA_CH_BURST_LENGTH_1,
.transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_P2M_DMA,
.enable_dst_linked_list = true,
.enable_src_linked_list = true,
}
};

static const XMC_DMA_CH_CONFIG_t dma_ch_config =
{
{
.enable_interrupt = true,
.dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT,
.src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE,
.dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1,
.src_burst_length = XMC_DMA_CH_BURST_LENGTH_1,
.transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_P2M_DMA,
},
.block_size = RING_BUFFER_SIZE / 2,
.src_addr = (uint32_t)&(WIFI_IO_UART_CH->RBUF),
.dst_addr = (uint32_t)&ring_buffer[0],
.linked_list_pointer = &dma_ll[0],
.transfer_type = XMC_DMA_CH_TRANSFER_TYPE_MULTI_BLOCK_SRCADR_LINKED_DSTADR_LINKED, /* Transfer type */
.priority = XMC_DMA_CH_PRIORITY_0, /* Priority level */
.src_handshaking = XMC_DMA_CH_SRC_HANDSHAKING_HARDWARE, /* Source handshaking */
.src_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_0, /* Source peripheral trigger */
.dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_SOFTWARE /* Destination handshaking */
};



Thanks for your help

Best regards

EbbeSand
0 Likes