Skip to content

Commit 15c6f75

Browse files
jorgesg82FoniksFox
andauthored
ADC implemented with DMA (#590)
* Refactor DMADomain init and test coverage * Migrate ADCDomain to DMA-backed acquisition * Refactor ADC-backed sensors onto a shared base * Document the ST-LIB board contract * feat(ADC): Refactor ADC to not use MPUManager (#592) * Using ADC with new MPU * Updated CLT version to 1.21 * chore(ci): trigger pipeline * ADC tests running with new MPU * fix(adc): address PR review feedback --------- Co-authored-by: Boris Mladenov Beslimov <borisbeslimov@gmail.com>
1 parent 1d2b78f commit 15c6f75

34 files changed

Lines changed: 3533 additions & 1547 deletions

.changesets/adc-dma-minor.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
release: minor
2+
summary: Refactor the ADC stack around DMA-backed acquisition using new MPU
3+
4+
Includes the DMA-backed `ADCDomain` migration, the shared ADC sensor base, and the updated ADC integration/tests in the `adc-dma` branch.

CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@ set(HALAL_CPP_NO_ETH
282282
${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/DMA/DMA2.cpp
283283
${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/PinModel/Pin.cpp
284284
${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/TimerDomain/TimerDomain.cpp
285-
# ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/ADC/ADC.cpp
286285
${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/CORDIC/CORDIC.cpp
287286
${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/FDCAN/FDCAN.cpp
288287
${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/I2C/I2C.cpp
@@ -371,8 +370,6 @@ set(STLIB_LOW_CPP_NO_ETH
371370
${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/ST-LIB_LOW.cpp
372371
${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sd/Sd.cpp
373372
${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.cpp
374-
${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.cpp
375-
${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/NTC/NTC.cpp
376373
${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/SensorInterrupt/SensorInterrupt.cpp
377374
)
378375

@@ -433,6 +430,7 @@ add_library(${STLIB_LIBRARY} OBJECT
433430

434431
$<$<NOT:$<BOOL:${CMAKE_CROSSCOMPILING}>>:${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Time/Scheduler.cpp>
435432
$<$<NOT:$<BOOL:${CMAKE_CROSSCOMPILING}>>:${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/TimerDomain/TimerDomain.cpp>
433+
$<$<NOT:$<BOOL:${CMAKE_CROSSCOMPILING}>>:${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/MPUManager/MPUManager.cpp>
436434
$<$<NOT:$<BOOL:${CMAKE_CROSSCOMPILING}>>:${CMAKE_CURRENT_LIST_DIR}/Src/MockedDrivers/mocked_hal_adc.cpp>
437435
$<$<NOT:$<BOOL:${CMAKE_CROSSCOMPILING}>>:${CMAKE_CURRENT_LIST_DIR}/Src/MockedDrivers/mocked_hal_dma.cpp>
438436
$<$<NOT:$<BOOL:${CMAKE_CROSSCOMPILING}>>:${CMAKE_CURRENT_LIST_DIR}/Src/MockedDrivers/mocked_hal_spi.cpp>

Inc/HALAL/HALAL.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "HALAL/Services/Flash/Flash.hpp"
1313
#include "HALAL/Services/Flash/FlashTests/Flash_Test.hpp"
1414

15-
#include "HALAL/Services/ADC/NewADC.hpp"
15+
#include "HALAL/Services/ADC/ADC.hpp"
1616

1717
// To be implemented
1818
// #include "HALAL/Services/PWM/DualPhasedPWM/DualPhasedPWM.hpp"

Inc/HALAL/Models/DMA/DMA2.hpp

Lines changed: 66 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
#pragma once
22
#include "C++Utilities/CppUtils.hpp"
3+
#include "ErrorHandler/ErrorHandler.hpp"
34
#include "stm32h7xx_hal.h"
45
#include "main.h"
5-
#include "HALAL/Models/MPUManager/MPUManager.hpp"
6-
#include <cassert>
76
#include <array>
8-
#include <variant>
9-
#include <functional>
10-
#include <set>
117

128
using std::array;
139
using std::size_t;
@@ -22,7 +18,7 @@ inline DMA_HandleTypeDef* dma_irq_table[16] = {nullptr};
2218

2319
namespace ST_LIB {
2420
extern void compile_error(const char* msg);
25-
struct DMA_Domain {
21+
struct DMADomain {
2622

2723
enum class Peripheral : uint8_t {
2824
none,
@@ -111,7 +107,7 @@ struct DMA_Domain {
111107
};
112108

113109
template <Stream... Ss> struct DMA {
114-
using domain = DMA_Domain;
110+
using domain = DMADomain;
115111

116112
std::array<Entry, sizeof...(Ss)> e{};
117113

@@ -136,7 +132,7 @@ struct DMA_Domain {
136132
template <class Ctx> consteval array<size_t, sizeof...(Ss)> inscribe(Ctx& ctx) const {
137133
array<size_t, sizeof...(Ss)> indices{};
138134
for (size_t i = 0; i < sizeof...(Ss); i++) {
139-
indices[i] = ctx.template add<DMA_Domain>(e[i], this);
135+
indices[i] = ctx.template add<DMADomain>(e[i], this);
140136
}
141137
return indices;
142138
}
@@ -145,7 +141,7 @@ struct DMA_Domain {
145141
static constexpr std::size_t max_instances{MAX_STREAMS};
146142
static_assert(max_instances > 0, "The number of instances must be greater than 0");
147143

148-
static inline constexpr IRQn_Type get_irqn(Stream stream) {
144+
static consteval IRQn_Type get_irqn(Stream stream) {
149145
if (stream == Stream::dma1_stream0)
150146
return DMA1_Stream0_IRQn;
151147
else if (stream == Stream::dma1_stream1)
@@ -181,16 +177,17 @@ struct DMA_Domain {
181177
return DMA2_Stream7_IRQn;
182178
else if (stream == Stream::none)
183179
return (IRQn_Type)0;
184-
else
185-
compile_error("No tiene que llegar aqui nunca, creo");
180+
else {
181+
compile_error("Invalid DMA stream");
182+
}
186183
return (IRQn_Type)0;
187184
}
188185

189-
static constexpr inline bool is_one_of(Peripheral instance, auto... bases) {
186+
static consteval bool is_one_of(Peripheral instance, auto... bases) {
190187
return ((instance == bases) || ...);
191188
}
192189

193-
static constexpr inline bool is_spi(Peripheral instance) {
190+
static consteval bool is_spi(Peripheral instance) {
194191
return is_one_of(
195192
instance,
196193
Peripheral::spi1,
@@ -202,7 +199,7 @@ struct DMA_Domain {
202199
);
203200
}
204201

205-
static constexpr inline bool is_i2c(Peripheral instance) {
202+
static consteval bool is_i2c(Peripheral instance) {
206203
return is_one_of(
207204
instance,
208205
Peripheral::i2c1,
@@ -212,19 +209,15 @@ struct DMA_Domain {
212209
);
213210
}
214211

215-
static constexpr inline bool is_adc(Peripheral instance) {
212+
static consteval bool is_adc(Peripheral instance) {
216213
return is_one_of(instance, Peripheral::adc1, Peripheral::adc2, Peripheral::adc3);
217214
}
218215

219-
static constexpr inline bool is_fmac(Peripheral instance) {
220-
return instance == Peripheral::fmac;
221-
}
216+
static consteval bool is_fmac(Peripheral instance) { return instance == Peripheral::fmac; }
222217

223-
static constexpr inline bool is_none(Peripheral instance) {
224-
return instance == Peripheral::none;
225-
}
218+
static consteval bool is_none(Peripheral instance) { return instance == Peripheral::none; }
226219

227-
static consteval inline uint32_t get_Request(Peripheral instance, uint8_t i) {
220+
static consteval uint32_t get_Request(Peripheral instance, uint8_t i) {
228221
if (instance == Peripheral::none)
229222
return DMA_REQUEST_MEM2MEM;
230223

@@ -284,7 +277,7 @@ struct DMA_Domain {
284277
return 0;
285278
}
286279

287-
static consteval inline uint32_t get_Direction(Peripheral instance, uint8_t i) {
280+
static consteval uint32_t get_Direction(Peripheral instance, uint8_t i) {
288281
if ((is_fmac(instance) && i == 0) || instance == Peripheral::none) {
289282
return DMA_MEMORY_TO_MEMORY;
290283
} else if ((is_i2c(instance) && i == 1) || (is_spi(instance) && i == 1) || (is_fmac(instance) && i == 1)) {
@@ -293,21 +286,21 @@ struct DMA_Domain {
293286
return DMA_PERIPH_TO_MEMORY;
294287
}
295288

296-
static consteval inline uint32_t get_PeriphInc(Peripheral instance, uint8_t i) {
289+
static consteval uint32_t get_PeriphInc(Peripheral instance, uint8_t i) {
297290
if ((is_fmac(instance) && i == 0) || is_none(instance)) {
298291
return DMA_PINC_ENABLE;
299292
}
300293
return DMA_PINC_DISABLE;
301294
}
302295

303-
static consteval inline uint32_t get_MemInc(Peripheral instance, uint8_t i) {
296+
static consteval uint32_t get_MemInc(Peripheral instance, uint8_t i) {
304297
if (is_fmac(instance) && i == 0) {
305298
return DMA_MINC_DISABLE;
306299
}
307300
return DMA_MINC_ENABLE;
308301
}
309302

310-
static consteval inline uint32_t get_PeriphDataAlignment(Peripheral instance, uint8_t i) {
303+
static consteval uint32_t get_PeriphDataAlignment(Peripheral instance, uint8_t i) {
311304
if (is_spi(instance) || is_i2c(instance)) {
312305
return DMA_PDATAALIGN_BYTE;
313306
} else if (is_none(instance)) {
@@ -316,7 +309,7 @@ struct DMA_Domain {
316309
return DMA_PDATAALIGN_HALFWORD;
317310
}
318311

319-
static consteval inline uint32_t get_MemDataAlignment(Peripheral instance, uint8_t i) {
312+
static consteval uint32_t get_MemDataAlignment(Peripheral instance, uint8_t i) {
320313
if (is_i2c(instance)) {
321314
return DMA_MDATAALIGN_WORD;
322315
} else if (is_spi(instance)) {
@@ -326,49 +319,58 @@ struct DMA_Domain {
326319
return DMA_MDATAALIGN_HALFWORD;
327320
}
328321

329-
static consteval inline uint32_t get_Mode(Peripheral instance, uint8_t i) {
322+
static consteval uint32_t get_Mode(Peripheral instance, uint8_t i) {
330323
if (is_spi(instance) || is_fmac(instance) || is_none(instance)) {
331324
return DMA_NORMAL;
332325
}
333326

334327
return DMA_CIRCULAR;
335328
}
336329

337-
static consteval inline uint32_t get_Priority(Peripheral instance, uint8_t i) {
330+
static consteval uint32_t get_Priority(Peripheral instance, uint8_t i) {
338331
if (is_fmac(instance)) {
339332
return DMA_PRIORITY_HIGH;
340333
}
341334

342335
return DMA_PRIORITY_LOW;
343336
}
344337

345-
static consteval inline uint32_t get_FIFOMode(Peripheral instance, uint8_t i) {
338+
static consteval uint32_t get_FIFOMode(Peripheral instance, uint8_t i) {
346339
if (is_fmac(instance)) {
347340
return DMA_FIFOMODE_ENABLE;
348341
}
349342
return DMA_FIFOMODE_DISABLE;
350343
}
351344

352-
static consteval inline uint32_t get_FIFOThreshold(Peripheral instance, uint8_t i) {
345+
static consteval uint32_t get_FIFOThreshold(Peripheral instance, uint8_t i) {
353346
if (is_spi(instance)) {
354347
return DMA_FIFO_THRESHOLD_FULL;
355348
}
356349
return DMA_FIFO_THRESHOLD_HALFFULL;
357350
}
358351

359-
static consteval inline uint32_t get_MemBurst(Peripheral instance, uint8_t i) {
352+
static consteval uint32_t get_MemBurst(Peripheral instance, uint8_t i) {
360353
return DMA_MBURST_SINGLE;
361354
}
362355

363-
static consteval inline uint32_t get_PeriphBurst(Peripheral instance, uint8_t i) {
356+
static consteval uint32_t get_PeriphBurst(Peripheral instance, uint8_t i) {
364357
return DMA_PBURST_SINGLE;
365358
}
366359

360+
static consteval bool get_NVICEnabled(Peripheral instance, uint8_t i) {
361+
(void)i;
362+
return !is_adc(instance);
363+
}
364+
367365
struct Config {
368-
std::tuple<Peripheral, DMA_InitTypeDef, Stream, IRQn_Type, uint8_t> init_data{};
366+
std::tuple<Peripheral, DMA_InitTypeDef, Stream, IRQn_Type, uint8_t, bool> init_data{};
369367
};
370368

371369
template <size_t N> static consteval std::array<Config, N> build(span<const Entry> instances) {
370+
if (instances.size() != N) {
371+
compile_error("DMA entry count mismatch");
372+
}
373+
372374
std::array<Config, N> cfgs{};
373375
std::array<Entry, N> ents;
374376
for (size_t i = 0; i < N; ++i)
@@ -432,7 +434,14 @@ struct DMA_Domain {
432434
DMA_InitStruct.MemBurst = get_MemBurst(e.instance, e.id);
433435
DMA_InitStruct.PeriphBurst = get_PeriphBurst(e.instance, e.id);
434436

435-
cfgs[i].init_data = std::make_tuple(e.instance, DMA_InitStruct, e.stream, e.irqn, e.id);
437+
cfgs[i].init_data = std::make_tuple(
438+
e.instance,
439+
DMA_InitStruct,
440+
e.stream,
441+
e.irqn,
442+
e.id,
443+
get_NVICEnabled(e.instance, e.id)
444+
);
436445
}
437446
return cfgs;
438447
}
@@ -451,25 +460,42 @@ struct DMA_Domain {
451460
static void init(std::span<const Config, N> cfgs) {
452461
if (N == 0)
453462
return;
463+
454464
__HAL_RCC_DMA1_CLK_ENABLE();
455465
__HAL_RCC_DMA2_CLK_ENABLE();
466+
456467
for (std::size_t i = 0; i < N; ++i) {
457468
const auto& e = cfgs[i];
458-
auto [instance, dma_init, stream, irqn, id] = e.init_data;
469+
auto [instance, dma_init, stream, irqn, id, nvic_enabled] = e.init_data;
470+
(void)instance;
471+
(void)id;
459472

460473
instances[i].dma = {};
474+
if (stream == Stream::none) {
475+
ErrorHandler("DMA stream must be selected before init");
476+
continue;
477+
}
478+
461479
instances[i].dma.Instance = stream_to_DMA_StreamTypeDef(stream);
462480
instances[i].dma.Init = dma_init;
463481

464482
if (HAL_DMA_Init(&instances[i].dma) != HAL_OK) {
483+
instances[i].dma = {};
465484
ErrorHandler("DMA Init failed");
466-
} else {
467-
HAL_NVIC_SetPriority(irqn, 0, 0);
468-
HAL_NVIC_EnableIRQ(irqn);
469-
dma_irq_table[static_cast<uint8_t>(stream) - 1] = &instances[i].dma;
485+
continue;
470486
}
487+
488+
dma_irq_table[static_cast<uint8_t>(stream) - 1] = &instances[i].dma;
489+
490+
if (!nvic_enabled) {
491+
continue;
492+
}
493+
494+
HAL_NVIC_SetPriority(irqn, 0, 0);
495+
HAL_NVIC_EnableIRQ(irqn);
471496
}
472497
}
473498
};
474499
};
500+
using DMA_Domain = DMADomain;
475501
} // namespace ST_LIB

Inc/HALAL/Models/SPI/SPI2.hpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "HALAL/Models/DMA/DMA2.hpp"
1717
#include "HALAL/Models/SPI/SPIConfig.hpp"
1818

19-
using ST_LIB::DMA_Domain;
19+
using ST_LIB::DMADomain;
2020
using ST_LIB::GPIODomain;
2121
using ST_LIB::SPIConfigTypes;
2222

@@ -195,7 +195,7 @@ struct SPIDomain {
195195
* Request Object
196196
* =========================================
197197
*/
198-
template <DMA_Domain::Stream dma_rx_stream, DMA_Domain::Stream dma_tx_stream> struct Device {
198+
template <DMADomain::Stream dma_rx_stream, DMADomain::Stream dma_tx_stream> struct Device {
199199
using domain = SPIDomain;
200200

201201
SPIPeripheral peripheral;
@@ -208,7 +208,7 @@ struct SPIDomain {
208208
GPIODomain::GPIO mosi_gpio;
209209
std::optional<GPIODomain::GPIO> nss_gpio;
210210

211-
DMA_Domain::DMA<dma_rx_stream, dma_tx_stream> dma_rx_tx;
211+
DMADomain::DMA<dma_rx_stream, dma_tx_stream> dma_rx_tx;
212212

213213
consteval Device(
214214
SPIMode mode,
@@ -475,20 +475,20 @@ struct SPIDomain {
475475
}
476476
}
477477

478-
static consteval DMA_Domain::Peripheral dma_peripheral(SPIPeripheral peripheral) {
478+
static consteval DMADomain::Peripheral dma_peripheral(SPIPeripheral peripheral) {
479479
switch (peripheral) {
480480
case SPIPeripheral::spi1:
481-
return DMA_Domain::Peripheral::spi1;
481+
return DMADomain::Peripheral::spi1;
482482
case SPIPeripheral::spi2:
483-
return DMA_Domain::Peripheral::spi2;
483+
return DMADomain::Peripheral::spi2;
484484
case SPIPeripheral::spi3:
485-
return DMA_Domain::Peripheral::spi3;
485+
return DMADomain::Peripheral::spi3;
486486
case SPIPeripheral::spi4:
487-
return DMA_Domain::Peripheral::spi4;
487+
return DMADomain::Peripheral::spi4;
488488
case SPIPeripheral::spi5:
489-
return DMA_Domain::Peripheral::spi5;
489+
return DMADomain::Peripheral::spi5;
490490
case SPIPeripheral::spi6:
491-
return DMA_Domain::Peripheral::spi6;
491+
return DMADomain::Peripheral::spi6;
492492
default:
493493
compile_error("Invalid SPI peripheral specified in SPIDomain::Device");
494494
}
@@ -1331,7 +1331,7 @@ struct SPIDomain {
13311331
static void init(
13321332
std::span<const Config, N> cfgs,
13331333
std::span<GPIODomain::Instance> gpio_instances,
1334-
std::span<DMA_Domain::Instance> dma_peripherals
1334+
std::span<DMADomain::Instance> dma_peripherals
13351335
) {
13361336
for (std::size_t i = 0; i < N; ++i) {
13371337
const auto& e = cfgs[i];
@@ -1398,7 +1398,7 @@ struct SPIDomain {
13981398
auto& dma_rx = dma_peripherals[e.dma_rx_idx];
13991399
auto& dma_tx = dma_peripherals[e.dma_tx_idx];
14001400

1401-
// DMA handles are already configured and initialized by DMA_Domain
1401+
// DMA handles are already configured and initialized by DMADomain
14021402
hspi.hdmarx = &dma_rx.dma;
14031403
hspi.hdmatx = &dma_tx.dma;
14041404

0 commit comments

Comments
 (0)