Skip to content

Commit 234e86b

Browse files
committed
[stm32] Add regular conversion sequences to F3 ADC driver
1 parent 2e40ab4 commit 234e86b

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
#ifndef MODM_STM32F3_ADC{{ id }}_HPP
1616
#define MODM_STM32F3_ADC{{ id }}_HPP
1717

18-
#include <stdint.h>
18+
#include <cstdint>
19+
#include <span>
20+
#include <utility>
1921
#include "../device.hpp"
2022
#include <modm/architecture/interface/register.hpp>
2123
#include <modm/platform/gpio/connector.hpp>
24+
#include <modm/math/algorithm/enumerate.hpp>
2225

2326
namespace modm
2427
{
@@ -260,6 +263,13 @@ public:
260263
Cycles602 = 0b111, //< 601.5 ADC clock cycles
261264
};
262265
%% endif
266+
267+
struct SequenceChannel
268+
{
269+
Channel channel{};
270+
SampleTime sampleTime{};
271+
};
272+
263273
enum class CalibrationMode : uint32_t
264274
{
265275
SingleEndedInputsMode = 0,
@@ -414,6 +424,9 @@ public:
414424
setChannel(const Channel channel,
415425
const SampleTime sampleTime=static_cast<SampleTime>(0b000));
416426

427+
static inline bool
428+
setChannelSequence(std::span<const SequenceChannel> sequence);
429+
417430
/// Setting the channel for a Pin
418431
template< class Gpio >
419432
static inline bool
@@ -464,13 +477,19 @@ public:
464477
static inline void
465478
startConversion();
466479

480+
static inline void
481+
stopConversion();
482+
467483
/**
468484
* @return If the conversion is finished.
469485
* @pre A conversion should have been started with startConversion()
470486
*/
471487
static inline bool
472488
isConversionFinished();
473489

490+
static inline bool
491+
isConversionSequenceFinished();
492+
474493
/**
475494
* Start a new injected conversion sequence.
476495
*

src/modm/platform/adc/stm32f3/adc_impl.hpp.in

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ modm::platform::Adc{{ id }}::configureChannel(Channel channel,
211211

212212
}
213213

214-
215214
bool
216215
modm::platform::Adc{{ id }}::setChannel(Channel channel,
217216
SampleTime sampleTime)
@@ -224,6 +223,42 @@ modm::platform::Adc{{ id }}::setChannel(Channel channel,
224223
return true;
225224
}
226225

226+
bool
227+
modm::platform::Adc{{ id }}::setChannelSequence(std::span<const SequenceChannel> sequence)
228+
{
229+
if (sequence.size() > 16 || sequence.size() == 0) {
230+
return false;
231+
}
232+
233+
ADC{{ id }}->SQR1 = sequence.size() - 1;
234+
235+
for (const auto [i, config] : modm::enumerate(sequence)) {
236+
const auto [channel, sampleTime] = config;
237+
if (!configureChannel(channel, sampleTime)) {
238+
return false;
239+
}
240+
241+
if (i < 4) {
242+
const auto shift = (i + 1) * 6;
243+
const auto mask = 0b111111u << shift;
244+
ADC{{ id }}->SQR1 = (ADC{{ id }}->SQR1 & ~mask) | (std::to_underlying(channel) << shift);
245+
} else if (i < 9) {
246+
const auto shift = (i - 4) * 6;
247+
const auto mask = 0b111111u << shift;
248+
ADC{{ id }}->SQR2 = (ADC{{ id }}->SQR2 & ~mask) | (std::to_underlying(channel) << shift);
249+
} else if (i < 14) {
250+
const auto shift = (i - 9) * 6;
251+
const auto mask = 0b111111u << shift;
252+
ADC{{ id }}->SQR3 = (ADC{{ id }}->SQR3 & ~mask) | (std::to_underlying(channel) << shift);
253+
} else {
254+
const auto shift = (i - 14) * 6;
255+
const auto mask = 0b111111u << shift;
256+
ADC{{ id }}->SQR4 = (ADC{{ id }}->SQR4 & ~mask) | (std::to_underlying(channel) << shift);
257+
}
258+
}
259+
return true;
260+
}
261+
227262
void
228263
modm::platform::Adc{{ id }}::setFreeRunningMode(const bool enable)
229264
{
@@ -239,17 +274,34 @@ modm::platform::Adc{{ id }}::startConversion()
239274
{
240275
// TODO: maybe add more interrupt flags
241276
acknowledgeInterruptFlags(InterruptFlag::EndOfRegularConversion |
242-
InterruptFlag::EndOfSampling | InterruptFlag::Overrun);
277+
InterruptFlag::EndOfSampling | InterruptFlag::Overrun |
278+
InterruptFlag::EndOfRegularSequenceOfConversions);
243279
// starts single conversion for the regular group
244280
ADC{{ id }}->CR |= ADC_CR_ADSTART;
245281
}
246282

283+
void
284+
modm::platform::Adc{{ id }}::stopConversion()
285+
{
286+
ADC{{ id }}->CR |= ADC_CR_ADSTP | ADC_CR_JADSTP;
287+
while ((ADC{{ id }}->CR & (ADC_CR_ADSTP | ADC_CR_JADSTP)) != 0);
288+
289+
acknowledgeInterruptFlags(InterruptFlag::EndOfRegularConversion |
290+
InterruptFlag::EndOfSampling | InterruptFlag::Overrun);
291+
}
292+
247293
bool
248294
modm::platform::Adc{{ id }}::isConversionFinished()
249295
{
250296
return static_cast<bool>(getInterruptFlags() & InterruptFlag::EndOfRegularConversion);
251297
}
252298

299+
bool
300+
modm::platform::Adc{{ id }}::isConversionSequenceFinished()
301+
{
302+
return static_cast<bool>(getInterruptFlags() & InterruptFlag::EndOfRegularSequenceOfConversions);
303+
}
304+
253305
void
254306
modm::platform::Adc{{ id }}::startInjectedConversionSequence()
255307
{

src/modm/platform/adc/stm32f3/module.lb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Instance(Module):
2121
module.description = "Instance {}".format(self.instance)
2222

2323
def prepare(self, module, options):
24-
module.depends(":platform:adc")
24+
module.depends(":platform:adc", ":math:algorithm")
2525
return True
2626

2727
def build(self, env):

0 commit comments

Comments
 (0)