ADC DMA event handler inside Thread

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

cross mob
RajivB
Level 2
Level 2
First like received 25 sign-ins 10 replies posted

Any example from Infineon to show how ADC DMA event handler can be  inside a Thread task in XMC4500 MCU assuming FreeRTOS is used as the multi threaded OS ?

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @RajivB ,

    I found an example 'FREERTOS_XMC45' which  demonstrates an implementation of a multi-threaded application using FREERTOS APP that send and receive messages through the FreeRTOS message queues and toggles two digital IOs when the queue transaction is successful. And I tried to pass the DMA Event handler function name in this example, it works well, so you can have a look at it and have a try. As my understanding,  you can let the ADC sampled as one of the task, DMA receive and DMA send as another task, so there will be three task all together. Please refer to the code for details.

    I also found another example which demonstrates the use if GPDMA to transfer AD conversion results of 8 VADC result registers to a destination buffer. 

Owen_Su_0-1662442902578.png

    You can choose the one meets your requirements, please let us know if you have any other questions, hope this can help you.

Regards,

Owen_Su

View solution in original post

0 Likes
8 Replies
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @RajivB ,

    You can find the example codes about ADC and DMA in this link: dave_downloads . Or you can find other examples in our Github: github_xmc . Hope this can help you. Please let us know if you have any other questions.

Regards,

Owen_Su

0 Likes
RajivB
Level 2
Level 2
First like received 25 sign-ins 10 replies posted

I could not find a single example of ADC conversion using DMA Event handler inside a Thread from the links that you have given. Please provide example of Multi-THreaded application using ADC with DMA.

0 Likes
lock attach
Attachments are accessible only for community members.
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @RajivB ,

    Here is an example: generating an interrupt after the sampling of the ADC unit is completed; The interrupt request triggers DMA transfer to transfer the value of ADC result register to the defined register.

1)  First initialize the ADC unit. We can configure it to auto scan mode. The channel is configured as ch0-ch7 of group0. The ADC sampling mode is query mode (software request).
Then interrupt configuration, including interrupt type, interrupt node, interrupt priority and interrupt processing terminal; The interrupt type is configured as result interrupt: interrupt is generated when the result is valid;
Interrupt node: configure as group0line0;
Interrupt processing terminal: DMA;
Interrupt priority: it needs to be configured as DMA channel number. Here, we use DMA channel 1.

2) The next step is the initialization of DMA. It is necessary to define the DMA channel, request source, request source processing, DMA data structure, address space, address offset, source address, target address, etc.

You can follow the codes and familiar with the process. Hope this can help you.

Regards,

Owen_Su

 

0 Likes
RajivB
Level 2
Level 2
First like received 25 sign-ins 10 replies posted

Ok, Owen. I get the point here based on the DMA structure. I am using DAVE4 IDE,  and below is how my DMA configuration for ADC looks like.

The DMA event Handler is "adc_measurement_handler" and the DMA is getting successfully Triggered NOW for the ADC.

My question is can this DMA event handler be placed inside a Thread, instead of part of main process ?

void DMA_CH_0_reload(DMA_CH_t *obj)
{
XMC_DMA_CH_SetBlockSize(obj->dma_global->dma, obj->ch_num, 1);
XMC_DMA_CH_SetSourceAddress(obj->dma_global->dma, obj->ch_num, 0x40004710);
XMC_DMA_CH_SetDestinationAddress(obj->dma_global->dma, obj->ch_num, (uint32_t)adc_buf);
}

DMA_CH_CONFIG_t DMA_CH_0_CONFIG =
{
{
{
.enable_interrupt = true, /* Interrupts enabled */
.dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_16, /* Destination transfer width */
.src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_16, /* Source transfer width */
.dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, /* Destination address count mode */
.src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, /* Source address count mode */
.dst_burst_length = XMC_DMA_CH_BURST_LENGTH_8, /* Destination burst length */
.src_burst_length = XMC_DMA_CH_BURST_LENGTH_8, /* Source burst length */
.enable_src_gather = true, /* Source gather enabled? */
.enable_dst_scatter = false, /* Destination scatter enabled? */
.transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_P2M_DMA, /* Transfer flow */
},
.src_gather_count = (uint32_t)1, /* Gather count */
.src_gather_interval = (uint32_t)1, /* Gather interval */
.block_size = 1U, /* Block size */
.transfer_type = XMC_DMA_CH_TRANSFER_TYPE_MULTI_BLOCK_SRCADR_RELOAD_DSTADR_CONTIGUOUS, /* Transfer type */
.priority = XMC_DMA_CH_PRIORITY_7, /* Priority level */
.src_handshaking = XMC_DMA_CH_SRC_HANDSHAKING_SOFTWARE, /* Source handshaking */
.dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_SOFTWARE /* Destination handshaking */
},
adc_measurement_handler,
XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE | XMC_DMA_CH_EVENT_TRANSFER_COMPLETE
};

DMA_CH_t DMA_CH_0 =
{
.dma_global = &GLOBAL_DMA_0, /* Which DMA_GLOBAL instance? */
.config = &DMA_CH_0_CONFIG, /* Channel configuration */
.ch_num = 0U, /* Channel number */
.reload = DMA_CH_0_reload
};

0 Likes
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @RajivB ,

    As my understanding, you can place this DMA event handler inside a Thread by using 'xTaskCreate' function.  You can refer to the examples below:

Owen_Su_0-1662363143592.pngOwen_Su_1-1662363187908.png

    You can add  task by function 'xTaskCreate', and modify the 'vTaskStartScheduler' , place the DMA event handler into the task.  Hope this can help you.

Regards,

Owen_Su

0 Likes
RajivB
Level 2
Level 2
First like received 25 sign-ins 10 replies posted

Hi Owen,

I am really not sure if the same DMA event handler function would be used as a Thread Task as well as DMA Task which gets triggered when Block DMA transfer is complete. The DMA event handler would be run & triggered in Interrupt context(supervisor mode),  don't understand how it will also run in process/thread(non-supervisor) context ? Can you please check by passing the DMA Event handler function name in "xTaskCreate" ?

0 Likes
lock attach
Attachments are accessible only for community members.
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

Hi, @RajivB ,

    I found an example 'FREERTOS_XMC45' which  demonstrates an implementation of a multi-threaded application using FREERTOS APP that send and receive messages through the FreeRTOS message queues and toggles two digital IOs when the queue transaction is successful. And I tried to pass the DMA Event handler function name in this example, it works well, so you can have a look at it and have a try. As my understanding,  you can let the ADC sampled as one of the task, DMA receive and DMA send as another task, so there will be three task all together. Please refer to the code for details.

    I also found another example which demonstrates the use if GPDMA to transfer AD conversion results of 8 VADC result registers to a destination buffer. 

Owen_Su_0-1662442902578.png

    You can choose the one meets your requirements, please let us know if you have any other questions, hope this can help you.

Regards,

Owen_Su

0 Likes
Owen_Su
Moderator
Moderator
Moderator
250 solutions authored 500 replies posted 50 likes received

You can open a new thread if you have any other questions, thanks for your understanding.

Regards,

Owen_Su 

0 Likes