2018-06-28 06:03 PM
I am using the STM32F091. I have been trying to use the ADC with DMA in circular mode writing to a large array for use as a sort of double buffer by shifting the first half of the values out on the half transfer complete callback the the other half on the transfer complete callback. However the documentation is super vague on what these callbacks are called and how they should be used.
Anybody know what these callbacks are called? How would I use them in my main to run code on a
half transfer and transfer complete interrupt?
2018-06-28 07:05 PM
STM32Cube_FW_F0_V1.9.0\Projects\STM32F072RB-Nucleo\Examples\ADC\ADC_AnalogWatchdog\Src\main.c
/**
* @brief Conversion complete callback in non blocking mode * @param AdcHandle : ADC handle * @note This example shows a simple way to report end of conversion * and get conversion result. You can add your own implementation. * @retval None */void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle){}
/**
* @brief Conversion DMA half-transfer callback in non blocking mode * @param hadc: ADC handle * @retval None */void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc){}
STM32Cube_FW_F0_V1.9.0\Projects\STM32F072RB-Nucleo\Examples\ADC\ADC_AnalogWatchdog\Src\stm32f0xx_it.c
/**
* @brief This function handles DMA interrupt request.* @param None* @retval None*/void ADCx_DMA_IRQHandler(void){ HAL_DMA_IRQHandler(AdcHandle.DMA_Handle);}>>How would I use them in my main to run code on a
half transfer and transfer complete interrupt?
Honestly you'd want to do the work in the callback itself (memcpy ?), but if you want to do something in main(), have the callback flag via a 'volatile int'
2018-06-28 07:29 PM
Do the
HAL_ADC_ConvCpltCallback &
HAL_ADC_ConvHalfCpltCallback trigger on the end of conversion/sequence flag or are they tied to the DMA transfer?
What I am after, one way or another, is something that triggers when my buffer is half full/full. To keep overhead down that will likely be after 200 or more adc conversion sequences (of 8 channels so 1600 samples or more in the buffer).
What I don't want is something that triggers after every conversion sequence (8 samples in buffer), I could probably make this work but I'd rather not have to deal with that overhead.
you're right it makes more sense to do the work in the callback.
2018-06-28 10:00 PM
>>Do the
HAL_ADC_ConvCpltCallback &
HAL_ADC_ConvHalfCpltCallback trigger on the end of conversion/sequence flag or are they tied to the DMA transfer?
I believe it is tied to the DMA, surely something trivially easy to prove.
2018-06-28 10:04 PM
I can help if you are stuck, I have this running on the '091.
typedef enum {
Rs8_Ad1, // initialised in the Cube Rs5_Ad5, Rs1_Ad6, Rs2_Ad7, Rs3_Ad8, Rs4_Ad9, CurrentSense_Ad13, Rs6_Ad14, Rs7_Ad15, VTemp_Ad16, VRef_Ad17, VBat_Ad18, ADC_ChannelCount,} ADCresultsAveColumn_t;HAL_ADC_Start_DMA(&hadc, (uint32_t *)ADC_DMABuffer, ADC_ChannelCount);
I use this callback: I fill a row with this new set of DMAdata
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { // transfer to 16 rows of data
HAL_ADC_CompleteCycle = true; // signal foreground to process
// copy 15 results away now for(int i = 0 ; i < ADC_ChannelCount ; i++) { //here add 2nd dimension to the array HAL_ADC_Channel_Buffer[ADC_RowCounter][i] = ADC_DMABuffer[i]; // AVEColumnSum += HAL_ADC_Channel_Buffer [Ave_ADC_RowCounter][Ave_ADC_ChannelCounter]; }ADC_RowCounter++; // for next time through the loop
if(ADC_RowCounter >= ADC_RowCount) ADC_RowCounter = 0; }2018-07-03 03:02 AM
Hi
taylor.welsh
,I share a participation to the following link:
https://community.st.com/0D50X00009XkXZ3SAN
https://community.st.com/0D50X00009XkXZ3SAN
It gives some details on how callbacks are done in other ADC use-case.
Hoping this brings some help for your case also.
Regards.
Cyril