-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ADC triggered by timer using DMA (#238)
* add class for timer only for wb55 * change const to ref to an object * enum classes fixed * ADC class refactored in order to be more generic * New class added: adc triggered by timer using dma * add functions to start and stop timer * DMA class extended to be able to configure data size * add dma and timer to the new adc class * fix build * fix build * fix build * dma fixed * struct to configure timing created * adc triggered by timer with dma fixed * ADC triggered by dma fixed * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Richard Peters <richard.peters@philips.com> * dma refactored * interface refactored * integrate new interface from embedded-infra-lib * changes based on interface * buffer name fixed * code adjusted based on the refactored interface * interface has to be public in order to be used in the application * do not invoke onDone callback inside dma interrupt, instead, schedule it * remove really assert to check if instance is set * really assert in case of trying to use a reserved DMA stream * new class added to support internal temperature conversions * adc disable functions replaced by adc stop * changes to support G4 devices * macro to convert digital data into temperature fixed * build fixed for m7 * convertion to celsius degrees extracted to a helper class * helper class refactored * Update hal_st/stm32fxxx/CMakeLists.txt Co-authored-by: Richard Peters <richard.peters@philips.com> * remove include related to wb in timer stm cpp file * struct initialization in timer stm fixed * unnecessary includes removed. Callback being scheduled instead of being called on interrupt context * Update hal_st/stm32fxxx/AdcDmaStm.hpp Co-authored-by: Richard Peters <richard.peters@philips.com> * interface connector removed from adc with dma class * PR comments processed * Apply suggestions from code review * if micro is wb then calibrate before usage --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Richard Peters <richard.peters@philips.com> Co-authored-by: André Jordan <3933856+andjordan@users.noreply.github.com>
- Loading branch information
1 parent
5e5f05f
commit 31adf4e
Showing
10 changed files
with
391 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
#include "hal_st/stm32fxxx/AdcDmaStm.hpp" | ||
#include "infra/event/EventDispatcher.hpp" | ||
|
||
namespace hal | ||
{ | ||
AdcTriggeredByTimerWithDma::AdcTriggeredByTimerWithDma(infra::MemoryRange<uint16_t> buffer, AdcStm& adc, DmaStm::ReceiveStream& receiveStream, TimerBaseStm::Timing timing, hal::GpioPinStm& pin) | ||
: adc(adc) | ||
, buffer(buffer) | ||
, dmaStream(receiveStream, &adc.Handle().Instance->DR, sizeof(uint16_t), [this]() | ||
{ | ||
TransferDone(); | ||
}) | ||
, analogPin(pin) | ||
#if defined(STM32G0) | ||
, timer(3, timing, { TimerBaseStm::CounterMode::up, infra::MakeOptional<TimerBaseStm::Trigger>({ TimerBaseStm::Trigger::TriggerOutput::update, false }) }) | ||
#else | ||
, timer(2, timing, { TimerBaseStm::CounterMode::up, infra::MakeOptional<TimerBaseStm::Trigger>({ TimerBaseStm::Trigger::TriggerOutput::update, false }) }) | ||
#endif | ||
{ | ||
ADC_ChannelConfTypeDef channelConfig; | ||
channelConfig.Channel = adc.Channel(analogPin); | ||
#if !defined(STM32WB) | ||
channelConfig.Rank = 1; | ||
#else | ||
channelConfig.Rank = ADC_REGULAR_RANK_1; | ||
#endif | ||
#if defined(STM32F0) || defined(STM32F3) | ||
channelConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5; | ||
#elif defined(STM32WB) | ||
channelConfig.SingleDiff = ADC_SINGLE_ENDED; | ||
channelConfig.SamplingTime = ADC_SAMPLETIME_92CYCLES_5; | ||
channelConfig.Offset = 0; | ||
channelConfig.OffsetNumber = ADC_OFFSET_NONE; | ||
#elif defined(STM32G0) | ||
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES_5; | ||
#elif defined(STM32G4) | ||
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES_5; | ||
channelConfig.Offset = 0; | ||
#else | ||
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; | ||
channelConfig.Offset = 0; | ||
#endif | ||
ReconfigureTrigger(); | ||
|
||
auto result = HAL_ADC_ConfigChannel(&adc.Handle(), &channelConfig); | ||
assert(result == HAL_OK); | ||
|
||
result = HAL_ADCEx_Calibration_Start(&adc.Handle(), ADC_SINGLE_ENDED); | ||
assert(result == HAL_OK); | ||
} | ||
|
||
void AdcTriggeredByTimerWithDma::Measure(std::size_t numberOfSamples, const infra::Function<void(infra::MemoryRange<uint16_t>)>& onDone) | ||
{ | ||
this->onDone = onDone; | ||
|
||
timer.Start(); | ||
Configure(); | ||
dmaStream.StartReceive(buffer); | ||
LL_ADC_REG_StartConversion(adc.Handle().Instance); | ||
} | ||
|
||
void AdcTriggeredByTimerWithDma::ReconfigureTrigger() | ||
{ | ||
HAL_ADC_Stop(&adc.Handle()); | ||
|
||
#if defined(STM32F4) || defined(STM32F7) | ||
LL_ADC_REG_SetTriggerSource(adc.Handle().Instance, ADC_EXTERNALTRIGCONV_T2_TRGO); | ||
#elif defined(STM32G0) | ||
LL_ADC_REG_SetTriggerSource(adc.Handle().Instance, ADC_EXTERNALTRIG_T3_TRGO); | ||
#else | ||
LL_ADC_REG_SetTriggerSource(adc.Handle().Instance, ADC_EXTERNALTRIG_T2_TRGO); | ||
#endif | ||
LL_ADC_REG_SetTriggerEdge(adc.Handle().Instance, LL_ADC_REG_TRIG_EXT_RISING); | ||
} | ||
|
||
void AdcTriggeredByTimerWithDma::Configure() | ||
{ | ||
auto result = LL_ADC_REG_IsConversionOngoing(adc.Handle().Instance); | ||
assert(result == 0); | ||
|
||
result = ADC_Enable(&adc.Handle()); | ||
assert(result == HAL_OK); | ||
|
||
__HAL_ADC_CLEAR_FLAG(&adc.Handle(), (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR)); | ||
LL_ADC_REG_SetDMATransfer(adc.Handle().Instance, LL_ADC_REG_DMA_TRANSFER_LIMITED); | ||
} | ||
|
||
void AdcTriggeredByTimerWithDma::TransferDone() | ||
{ | ||
auto result = ADC_Disable(&adc.Handle()); | ||
assert(result == HAL_OK); | ||
|
||
timer.Stop(); | ||
|
||
if (this->onDone) | ||
infra::EventDispatcher::Instance().Schedule([this]() | ||
{ | ||
onDone(buffer); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#ifndef HAL_ADC_DMA_STM_HPP | ||
#define HAL_ADC_DMA_STM_HPP | ||
|
||
#include "hal/interfaces/AnalogToDigitalPin.hpp" | ||
#include "hal_st/stm32fxxx/AnalogToDigitalPinStm.hpp" | ||
#include "hal_st/stm32fxxx/DmaStm.hpp" | ||
#include "hal_st/stm32fxxx/TimerStm.hpp" | ||
#include "infra/util/AutoResetFunction.hpp" | ||
|
||
namespace hal | ||
{ | ||
class AdcTriggeredByTimerWithDma | ||
: public AnalogToDigitalPinImplBase<uint16_t> | ||
{ | ||
public: | ||
template<std::size_t Max> | ||
using WithNumberOfSamples = infra::WithStorage<AdcTriggeredByTimerWithDma, std::array<uint16_t, Max>>; | ||
|
||
explicit AdcTriggeredByTimerWithDma(infra::MemoryRange<uint16_t> buffer, AdcStm& adc, DmaStm::ReceiveStream& receiveStream, TimerBaseStm::Timing timing, hal::GpioPinStm& pin); | ||
|
||
void Measure(std::size_t numberOfSamples, const infra::Function<void(infra::MemoryRange<uint16_t>)>& onDone) override; | ||
|
||
private: | ||
void ReconfigureTrigger(); | ||
void TransferDone(); | ||
void Configure(); | ||
|
||
private: | ||
AdcStm& adc; | ||
infra::MemoryRange<uint16_t> buffer; | ||
ReceiveDmaChannel dmaStream; | ||
AnalogPinStm analogPin; | ||
TimerBaseStm timer; | ||
infra::AutoResetFunction<void(infra::MemoryRange<uint16_t>)> onDone; | ||
}; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.