Skip to content

Commit 2d8a989

Browse files
wald-zatchris-durand
authored andcommitted
[stm32] Add DMA capabilities to F0/G0 ADC
Co-authored-by: Christopher Durand <[email protected]>
1 parent 71becdc commit 2d8a989

File tree

5 files changed

+384
-20
lines changed

5 files changed

+384
-20
lines changed

src/modm/platform/adc/stm32f0/adc.hpp.in

+130-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright (c) 2018, Álan Crístoffer
44
* Copyright (c) 2018, Carl Treudler
55
* Copyright (c) 2018-2019, Niklas Hauser
6+
* Copyright (c) 2023, Daniel Waldhaeusl (Zuehlke Engineering)
7+
* Copyright (c) 2024, Christopher Durand
68
*
79
* This file is part of the modm project.
810
*
@@ -15,7 +17,10 @@
1517
#ifndef MODM_STM32{{ target.family | upper }}_ADC{{ id }}_HPP
1618
#define MODM_STM32{{ target.family | upper }}_ADC{{ id }}_HPP
1719

18-
#include <stdint.h>
20+
#include <array>
21+
#include <cstdint>
22+
#include <span>
23+
#include <utility>
1924
#include "../device.hpp"
2025
#include <modm/architecture/interface/adc.hpp>
2126
#include <modm/architecture/interface/register.hpp>
@@ -48,6 +53,14 @@ public:
4853
%% endfor
4954
};
5055

56+
enum class ChannelMask : uint32_t
57+
{
58+
%% for channel, name in channels.items() | sort
59+
{{ name }} = (1u << {{ channel }}),
60+
%% endfor
61+
};
62+
MODM_FLAGS32(ChannelMask);
63+
5164
enum class ClockMode
5265
{
5366
Synchronous,
@@ -140,6 +153,41 @@ public:
140153
};
141154
MODM_FLAGS32(InterruptFlag);
142155

156+
enum class DmaMode : uint32_t
157+
{
158+
Disabled = 0,
159+
OneShot = ADC_CFGR1_DMAEN,
160+
Circular = ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN,
161+
Mask = Circular
162+
};
163+
164+
enum class ExternalTriggerPolarity
165+
{
166+
NoTriggerDetection = 0x0u,
167+
RisingEdge = 0x1u,
168+
FallingEdge = 0x2u,
169+
RisingAndFallingEdge = 0x3u,
170+
};
171+
172+
/**
173+
* Regular conversion external trigger sources
174+
*
175+
* The source mapped to each event varies per controller family,
176+
* refer to the ADC external trigger section in the reference manual
177+
* of your controller for more information
178+
*/
179+
enum class RegularConversionExternalTrigger
180+
{
181+
Event0 = 0x0u,
182+
Event1 = 0x1u,
183+
Event2 = 0x2u,
184+
Event3 = 0x3u,
185+
Event4 = 0x4u,
186+
Event5 = 0x5u,
187+
Event6 = 0x6u,
188+
Event7 = 0x7u,
189+
};
190+
143191
public:
144192
// start inherited documentation
145193
template< class... Signals >
@@ -169,6 +217,9 @@ public:
169217
static void
170218
initialize();
171219

220+
static inline void
221+
enable();
222+
172223
static inline void
173224
disable();
174225

@@ -198,6 +249,9 @@ public:
198249
static inline void
199250
startConversion();
200251

252+
static inline void
253+
stopConversion();
254+
201255
static inline bool
202256
isConversionFinished();
203257

@@ -251,6 +305,37 @@ public:
251305
setChannel(Channel channel);
252306
%% endif
253307

308+
/**
309+
* Set channel scan sequence mask. All selected channels will be converted
310+
* sequentially starting from the lowest.
311+
*
312+
* @param channels Mask of channels to convert
313+
*/
314+
static inline void
315+
setChannels(ChannelMask_t channels);
316+
317+
template<typename... Gpios>
318+
static consteval ChannelMask_t
319+
channelMaskFromPins();
320+
321+
%% if target.family in ["g0"]
322+
/**
323+
* Set channel scan sequence to convert up to 8 channels in arbitrary order.
324+
*
325+
* @warning The sequence provided must contain at least one but no more than 8 channels.
326+
* Channels above 15 are not supported due to hardware limitations. If channels
327+
* 16 to 18 should be sampled the in-order conversion sequence must be used instead.
328+
* @param channels Flag mask of channels to convert
329+
* @return true if provided channel sequence is valid, false otherwise.
330+
*/
331+
static inline bool
332+
setChannels(std::span<const Channel> channels);
333+
334+
template<typename... Gpios>
335+
static consteval std::array<Channel, sizeof...(Gpios)>
336+
channelSequenceFromPins();
337+
%% endif
338+
254339
static inline void
255340
clearChannel(Channel channel);
256341

@@ -287,6 +372,9 @@ public:
287372
%% if target.family in ["g0"]
288373
static inline void
289374
setSampleTime(SampleTime sampleTime, SampleTimeGroup group = SampleTimeGroup::Group1);
375+
376+
static inline void
377+
setSampleTimeGroup(Channel channel, SampleTimeGroup group = SampleTimeGroup::Group1);
290378
%% else
291379
static inline void
292380
setSampleTime(SampleTime sampleTime);
@@ -314,6 +402,47 @@ public:
314402
static inline void
315403
acknowledgeInterruptFlags(InterruptFlag_t flags);
316404

405+
static inline uintptr_t
406+
getDataRegisterAddress();
407+
408+
static inline void
409+
enableRegularConversionExternalTrigger(
410+
ExternalTriggerPolarity externalTriggerPolarity,
411+
RegularConversionExternalTrigger regularConversionExternalTrigger);
412+
413+
/**
414+
* Configure DMA mode (disabled, one-shot or circular)
415+
*
416+
* In one-shot mode DMA requests are disabled at the end of the DMA transfer.
417+
* If circular mode is selected request are being generated as long as
418+
* conversions are performed.
419+
*
420+
* @warning May only be called while no conversion is ongoing
421+
*/
422+
static inline void
423+
setDmaMode(DmaMode mode);
424+
425+
static inline bool
426+
getAdcEnabled();
427+
428+
static inline void
429+
enableInternalChannel(Channel channel);
430+
431+
private:
432+
%% if target.family in ["g0"]
433+
static inline void
434+
waitChannelConfigReady();
435+
436+
static inline void
437+
resetChannelConfigReady();
438+
439+
static inline void
440+
enableOrderedSequenceMode();
441+
442+
static inline void
443+
disableOrderedSequenceMode();
444+
%% endif
445+
317446
public:
318447
static constexpr uint8_t TS_CAL1_TEMP{30};
319448
%% if target.family in ["f0"]

0 commit comments

Comments
 (0)