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
128using std::array;
139using std::size_t ;
@@ -22,7 +18,7 @@ inline DMA_HandleTypeDef* dma_irq_table[16] = {nullptr};
2218
2319namespace ST_LIB {
2420extern 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
0 commit comments