From 29be4223e99a26f5e44e79b251f7c91a1b0e2478 Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:59:50 +0200 Subject: [PATCH] Add optional conversion complete callback to `AdcHandle::Start()` --- CHANGELOG.md | 1 + src/per/adc.cpp | 24 +++++++++++++++++++++--- src/per/adc.h | 14 ++++++++++++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5414c151..32115fea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Features +- Add an optional conversion complete callback to `AdcHandle::Start()` ### Bugfixes diff --git a/src/per/adc.cpp b/src/per/adc.cpp index 1ac21acf0..ee7cd1fa0 100644 --- a/src/per/adc.cpp +++ b/src/per/adc.cpp @@ -147,6 +147,8 @@ struct dsy_adc ADC_HandleTypeDef hadc1; DMA_HandleTypeDef hdma_adc1; bool mux_used; // flag set when mux is configured + AdcHandle::ConversionCompleteCallbackFunctionPtr complete_callback; + void* complete_callback_context; }; // Static Functions @@ -350,6 +352,10 @@ void AdcHandle::Init(AdcChannelConfig* cfg, { adc.hadc1.Init.OversamplingMode = DISABLE; } + + adc.complete_callback = nullptr; + adc.complete_callback_context = nullptr; + // Init ADC if(HAL_ADC_Init(&adc.hadc1) != HAL_OK) { @@ -421,8 +427,12 @@ void AdcHandle::Init(AdcChannelConfig* cfg, } } -void AdcHandle::Start() +void AdcHandle::Start(ConversionCompleteCallbackFunctionPtr callback, + void* callback_context) { + adc.complete_callback = callback; + adc.complete_callback_context = callback_context; + HAL_ADCEx_Calibration_Start( &adc.hadc1, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED); HAL_ADC_Start_DMA(&adc.hadc1, (uint32_t*)adc.dma_buffer, adc.channels); @@ -580,9 +590,17 @@ extern "C" void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { - if(hadc->Instance == ADC1 && adc.mux_used) + if(hadc->Instance == ADC1) { - adc_internal_callback(); + if(adc.mux_used) + { + adc_internal_callback(); + } + + if(adc.complete_callback) + { + adc.complete_callback(adc.complete_callback_context); + } } } diff --git a/src/per/adc.h b/src/per/adc.h index 14db03927..a1b510f3b 100644 --- a/src/per/adc.h +++ b/src/per/adc.h @@ -106,6 +106,9 @@ class AdcHandle OVS_LAST, /**< & */ }; + /** A callback to be executed after a conversion is completed. */ + typedef void (*ConversionCompleteCallbackFunctionPtr)(void *context); + AdcHandle() {} ~AdcHandle() {} /** @@ -117,8 +120,15 @@ class AdcHandle void Init(AdcChannelConfig *cfg, size_t num_channels, OverSampling ovs = OVS_32); - /** Starts reading from the ADC */ - void Start(); + /** Starts reading from the ADC. + \param callback an optional callback to be called when a conversion is + complete on all ADC channels. Note that if a mux is used on + a ADC channel, only one of the muxed inputs will have a new + value when this callback is called. + \param callback_context a context pointer that will be handed to the callback + */ + void Start(ConversionCompleteCallbackFunctionPtr callback = nullptr, + void *callback_context = nullptr); /** Stops reading from the ADC */ void Stop();