Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
09de7c7
It compiles the old version with constexpr
Cantonplas Oct 22, 2025
8962c95
Draft of the new dma class
Cantonplas Oct 22, 2025
1d158c0
Minor change on where is the instance declared on dma.hpp
Cantonplas Oct 23, 2025
ea78eb3
limpieza de funciones, enums y structs
jorgecanut Oct 25, 2025
b8df87e
feat: distintos inscribe definidos, no creo que sea lo mejor que se p…
jorgecanut Oct 25, 2025
85db060
feat: mejor enfoque, pero no se si el correcto
jorgecanut Oct 26, 2025
52ae1a5
feat: comprueba el numero de perifericos, cambios de nombre a algunas…
jorgecanut Nov 11, 2025
3dd6ae4
feat: struct constructor, better is... logic, refactor inscribe (tech…
jorgecanut Nov 11, 2025
8ca78ee
algunas cosillas para que compile. falta conseguir pasarle las variab…
jorgecanut Nov 11, 2025
3c44a60
feat: agregar static a las variables constexpr
jorgecanut Nov 12, 2025
d2005f2
me lo quiero pasar al PC solamente, luego hago bien el commit
jorgecanut Nov 22, 2025
9d2a930
feat: agregar funciones que comprueban si el stream y la instancias y…
jorgecanut Nov 23, 2025
38fd08b
fuck constexpr, todo en runtime. feat: inscribe funciona, solo quedar…
jorgecanut Nov 24, 2025
4d0e6be
repartir entre archivos las funciones y hacer el start
jorgecanut Nov 25, 2025
cca62c8
feat: start completado, mejor estructura, todos los perifericos confi…
jorgecanut Nov 25, 2025
5212ce9
hacer funciones inline para que pueda compilar
jorgecanut Nov 29, 2025
9655dea
adc inscribe_dma now working, moved dma implementations from cpp to h…
jorgecanut Nov 30, 2025
e2af8c5
Initial structure
jorgesg82 Nov 30, 2025
3eec305
no need to have an id for instance
jorgesg82 Nov 30, 2025
fa3498b
erased no longer needed code
jorgesg82 Dec 1, 2025
c338bf8
Juntar estructura propuesta de compiletime con la clase DMA
jorgecanut Dec 2, 2025
0440eb4
cambio de nombre al antiguo dma y empiezo con la nueva infraestructur…
jorgecanut Dec 2, 2025
98a34fb
añadir funciones de configuracion del handle DMA
jorgecanut Dec 3, 2025
c1966cf
Added DigitalInput and DigitalOutput Services, and added support for …
jorgesg82 Dec 2, 2025
b245442
todo lo facil hecho, queda lo dificil (handle y global_handle)
jorgecanut Dec 3, 2025
ba25865
entry, build e instances_ ahora se rigen por stream y no instancia (l…
jorgecanut Dec 10, 2025
968eee6
se me habia olvidado desreferenciar
jorgecanut Dec 10, 2025
0826a02
modificar STLIB.hpp para meter el contexto de la DMA
jorgecanut Dec 11, 2025
4c8a7f3
throws comentados, una dma menos
jorgecanut Dec 12, 2025
fb86f46
It compiles the old version with constexpr
Cantonplas Oct 22, 2025
ac4df89
Draft of the new dma class
Cantonplas Oct 22, 2025
4b9d4ba
Minor change on where is the instance declared on dma.hpp
Cantonplas Oct 23, 2025
d085938
limpieza de funciones, enums y structs
jorgecanut Oct 25, 2025
2e9252c
feat: distintos inscribe definidos, no creo que sea lo mejor que se p…
jorgecanut Oct 25, 2025
5ad8632
feat: mejor enfoque, pero no se si el correcto
jorgecanut Oct 26, 2025
d832eec
feat: comprueba el numero de perifericos, cambios de nombre a algunas…
jorgecanut Nov 11, 2025
e39e204
feat: struct constructor, better is... logic, refactor inscribe (tech…
jorgecanut Nov 11, 2025
1634bdb
algunas cosillas para que compile. falta conseguir pasarle las variab…
jorgecanut Nov 11, 2025
81fb468
feat: agregar static a las variables constexpr
jorgecanut Nov 12, 2025
5aa3106
me lo quiero pasar al PC solamente, luego hago bien el commit
jorgecanut Nov 22, 2025
d70ab88
feat: agregar funciones que comprueban si el stream y la instancias y…
jorgecanut Nov 23, 2025
6d8552f
fuck constexpr, todo en runtime. feat: inscribe funciona, solo quedar…
jorgecanut Nov 24, 2025
dc97111
repartir entre archivos las funciones y hacer el start
jorgecanut Nov 25, 2025
d70d07f
feat: start completado, mejor estructura, todos los perifericos confi…
jorgecanut Nov 25, 2025
8f496ae
hacer funciones inline para que pueda compilar
jorgecanut Nov 29, 2025
2651dc6
adc inscribe_dma now working, moved dma implementations from cpp to h…
jorgecanut Nov 30, 2025
3996ec0
Initial structure
jorgesg82 Nov 30, 2025
d7e562c
cambio de nombre al antiguo dma y empiezo con la nueva infraestructur…
jorgecanut Dec 2, 2025
c152e48
añadir funciones de configuracion del handle DMA
jorgecanut Dec 3, 2025
61d093c
Added DigitalInput and DigitalOutput Services, and added support for …
jorgesg82 Dec 2, 2025
db10f57
todo lo facil hecho, queda lo dificil (handle y global_handle)
jorgecanut Dec 3, 2025
9a029ec
entry, build e instances_ ahora se rigen por stream y no instancia (l…
jorgecanut Dec 10, 2025
2f65b23
se me habia olvidado desreferenciar
jorgecanut Dec 10, 2025
04fb46b
modificar STLIB.hpp para meter el contexto de la DMA
jorgecanut Dec 11, 2025
1503056
eliminar que reciba el handle
jorgecanut Dec 14, 2025
7974f64
eliminar que reciba el handle
jorgecanut Dec 14, 2025
38778af
sacar streams fuera del struct
jorgecanut Dec 14, 2025
54e9082
conflictos que no deberian de salir
jorgecanut Dec 16, 2025
36e5d71
el commit que se me olvido hacer para que poder testear
jorgecanut Dec 17, 2025
c61c735
resolver conflictos
jorgecanut Dec 17, 2025
10390cf
cambios para poder utilizar none y algunos errores corregidos, queda …
jorgecanut Dec 18, 2025
f908ab5
ni me acuerdo, mañana sigo
jorgecanut Dec 18, 2025
2631a37
debugging validacion
jorgecanut Dec 22, 2025
b6b2c30
cmake cambiado para que se incluya la dma2.cpp
jorgecanut Dec 22, 2025
9e4fb9e
cambios finales, prueba funciona
jorgecanut Dec 23, 2025
0cb7a11
ahora de verdad funciona
jorgecanut Dec 23, 2025
33b4942
limpieza de rama p1
jorgecanut Dec 30, 2025
3f5b436
limpieza de rama p2
jorgecanut Dec 30, 2025
550fde1
cambiar gpio para que el static assert me deje compilar
jorgecanut Dec 30, 2025
d3432a1
feat(SPI): First implementation with most of the infrastructure and h…
FoniksFox Dec 28, 2025
f5cb029
feat(SPI): Baudrate prescaler calculation
FoniksFox Dec 28, 2025
efbf9c0
feat(SPI): Add IRQ handlers and HAL callbacks
FoniksFox Dec 28, 2025
2c95ba0
fix(SPI): Fix error spi number
FoniksFox Dec 28, 2025
a2f0639
fix(SPI): Callback handling
FoniksFox Dec 28, 2025
8ca8bde
feat(SPI): Implement API for both Master and Slave
FoniksFox Dec 28, 2025
baaf149
doc(SPI): Add tooltip comments
FoniksFox Dec 28, 2025
b0e1516
fix(SPI): Typo in ErrorHandler function name
FoniksFox Dec 28, 2025
d6595a3
fix(SPI): Move spi_instances declaration
FoniksFox Dec 28, 2025
7f0e3d8
fix(SPI): General syntax errror fixes
FoniksFox Dec 28, 2025
c090b4b
feat(SPI): Add SPI domain to ST-LIB
FoniksFox Dec 28, 2025
288e5c0
fix(SPI): Remove forgotten line
FoniksFox Dec 28, 2025
4d6f8b4
fix(SPI): General fixes to make it compile
FoniksFox Dec 29, 2025
3af6613
fix(SPI): Forgot to set up max baudrate
FoniksFox Dec 29, 2025
b86ca78
Merge remote-tracking branch 'origin/feat/DMA-updated' into refactor/SPI
FoniksFox Jan 14, 2026
101d022
Merge branch 'development' into feat/DMA-updated
FoniksFox Jan 14, 2026
1bd4fc2
feat(DMA): udpate inscribe method to return indices
FoniksFox Jan 14, 2026
2f20354
Merge branch 'feat/DMA-updated' into refactor/SPI
FoniksFox Jan 15, 2026
eb72bf6
feat(SPI): Add DMA linking
FoniksFox Jan 19, 2026
980fa9c
feat(SPI): Implement configuration API + some cleanup
FoniksFox Jan 19, 2026
ba15465
fix(SPI): Update SPI in ST-LIB.hpp
FoniksFox Jan 19, 2026
a6402af
feat(SPI): Make inscribe return size_t
FoniksFox Jan 20, 2026
5cce7e4
fix(SPI): Fix compile_error
FoniksFox Jan 22, 2026
4ce57b8
Merge remote-tracking branch 'origin/development' into refactor/SPI
FoniksFox Jan 22, 2026
72f165b
fix(SPI): Fix inscribe
FoniksFox Jan 22, 2026
8404700
fix(SPI): Fix things
FoniksFox Jan 22, 2026
2a92b34
Merge remote-tracking branch 'origin/development' into refactor/SPI
FoniksFox Jan 22, 2026
6538aff
fix(SPI): Pin A15 AF were incorrect
FoniksFox Jan 22, 2026
94ae350
Merge remote-tracking branch 'origin/development' into refactor/SPI
FoniksFox Jan 22, 2026
a6cc1e3
fix(SPI): Fix instances array
FoniksFox Jan 23, 2026
ff3cf48
Merge remote-tracking branch 'origin/development' into refactor/SPI
FoniksFox Jan 25, 2026
6d49eb3
feat(SPI): Add templated functions to acccept anything
FoniksFox Jan 26, 2026
770f323
fix(SPI): Alignments and correct frame calculations
FoniksFox Jan 27, 2026
1731518
feat(SPI): Add slave software nss interface
FoniksFox Jan 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ list(FILTER STLIB_HIGH_CPP_NO_ETH EXCLUDE REGEX "${STLIB_HIGH_ETH_REGEX}")
# Librería STLIB_LIBRARY
# ============================
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The library type was changed from STATIC to OBJECT without explanation. OBJECT libraries behave differently than STATIC libraries - they don't create an archive file and their object files are directly linked into targets that use them. This change can affect link-time optimization, symbol visibility, and how the library is consumed by other targets. Please document why this change was made and verify it doesn't break existing build configurations or downstream projects that depend on this library.

Suggested change
# ============================
# ============================
# NOTE / NOTA:
# This target is intentionally an OBJECT library instead of STATIC.
# Historically this library was built as STATIC, but it was changed to
# OBJECT so that its object files can be directly reused by multiple
# firmware / executable targets while still being selected via generator
# expressions (CMAKE_CROSSCOMPILING, USE_ETHERNET, etc.).
#
# Compatibility:
# - Downstream projects must link against the CMake target `${STLIB_LIBRARY}`
# (e.g. `target_link_libraries(<app> PRIVATE ${STLIB_LIBRARY})`) and must
# not rely on a `.a` or `.lib` archive file name.
# - Existing build configurations that referenced the CMake target itself
# continue to work: they still see the same sources and compile options,
# only the internal representation changed from a STATIC archive to an
# OBJECT library.
# - No public interface of the library target has been changed by this
# switch; only the way CMake materializes it at link time is different.
#
# If a downstream project requires a real archive file, it should create its
# own STATIC or SHARED target that links against `${STLIB_LIBRARY}` or wraps
# its object files with `$<TARGET_OBJECTS:${STLIB_LIBRARY}>`.

Copilot uses AI. Check for mistakes.

add_library(${STLIB_LIBRARY} STATIC
add_library(${STLIB_LIBRARY} OBJECT
$<$<BOOL:${CMAKE_CROSSCOMPILING}>:${HAL_SOURCES_COMMON}>
$<$<AND:$<BOOL:${CMAKE_CROSSCOMPILING}>,$<BOOL:${USE_ETHERNET}>>:${HAL_SOURCES_ETH}>
$<$<AND:$<BOOL:${CMAKE_CROSSCOMPILING}>,$<BOOL:${USE_ETHERNET}>>:${LWIP_SOURCES}>
Expand Down
4 changes: 3 additions & 1 deletion Inc/HALAL/HALAL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#include "HALAL/Models/Pin.hpp"

#include "HALAL/Models/HALconfig/HALconfig.hpp"
#include "HALAL/Models/DMA/DMA.hpp"
//#include "HALAL/Models/DMA/DMA.hpp"
#include "HALAL/Models/DMA/DMA2.hpp"

#include "HALAL/Services/DigitalOutputService/DigitalOutputService.hpp"
#include "HALAL/Services/DigitalInputService/DigitalInputService.hpp"
Expand All @@ -28,6 +29,7 @@
#include "HALAL/Services/Encoder/Encoder.hpp"
#include "HALAL/Services/EXTI/EXTI.hpp"

#include "HALAL/Models/SPI/SPI2.hpp"
#include "HALAL/Services/Communication/SPI/SPI.hpp"
#include "HALAL/Services/Communication/UART/UART.hpp"
#include "HALAL/Services/Communication/I2C/I2C.hpp"
Expand Down
2 changes: 1 addition & 1 deletion Inc/HALAL/Models/DMA/DMA.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ class DMA {
private:
static vector<Stream> available_streams;
static vector<Stream> inscribed_streams;
};
};
359 changes: 359 additions & 0 deletions Inc/HALAL/Models/DMA/DMA2.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,359 @@
#pragma once
#include "C++Utilities/CppUtils.hpp"
#include "stm32h7xx_hal.h"
#include "main.h"
#include "HALAL/Models/MPUManager/MPUManager.hpp"
#include <cassert>
#include <array>
#include <variant>
#include <functional>
#include <set>

using std::array;
using std::size_t;
using std::span;
using std::tuple;

#define MAX_STREAMS 16


extern "C" {
inline DMA_HandleTypeDef *dma_irq_table[16] = {nullptr};
}


namespace ST_LIB {
extern void compile_error(const char *msg);
struct DMA_Domain {

enum class Instance : uint8_t {none, adc1, adc2, adc3,
i2c1, i2c2, i2c3, i2c5,
spi1, spi2, spi3, spi4, spi5,
fmac};

enum class Stream : uint8_t {dma1_stream0, dma1_stream1, dma1_stream2, dma1_stream3,
dma1_stream4, dma1_stream5, dma1_stream6, dma1_stream7,
dma2_stream0, dma2_stream1, dma2_stream2, dma2_stream3,
dma2_stream4, dma2_stream5, dma2_stream6, dma2_stream7};


static inline DMA_Stream_TypeDef* stream_to_DMA_StreamTypeDef(Stream s) {
switch (s) {
case Stream::dma1_stream0: return DMA1_Stream0;
case Stream::dma1_stream1: return DMA1_Stream1;
case Stream::dma1_stream2: return DMA1_Stream2;
case Stream::dma1_stream3: return DMA1_Stream3;
case Stream::dma1_stream4: return DMA1_Stream4;
case Stream::dma1_stream5: return DMA1_Stream5;
case Stream::dma1_stream6: return DMA1_Stream6;
case Stream::dma1_stream7: return DMA1_Stream7;

case Stream::dma2_stream0: return DMA2_Stream0;
case Stream::dma2_stream1: return DMA2_Stream1;
case Stream::dma2_stream2: return DMA2_Stream2;
case Stream::dma2_stream3: return DMA2_Stream3;
case Stream::dma2_stream4: return DMA2_Stream4;
case Stream::dma2_stream5: return DMA2_Stream5;
case Stream::dma2_stream6: return DMA2_Stream6;
case Stream::dma2_stream7: return DMA2_Stream7;
}
return nullptr;
}

struct Entry {
Instance instance;
Stream stream;
IRQn_Type irqn;
uint8_t id;
};

template<Stream... Ss>
struct DMA {
using domain = DMA_Domain;

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


consteval DMA(Instance instance) {
static_assert(sizeof...(Ss) <= 3, "Máximo 3 streams");

Stream streams[] = { Ss... };
constexpr uint8_t n = sizeof...(Ss);

for (uint8_t j = 0; j < n; j++) {
e[j].instance = instance;
e[j].stream = streams[j];
e[j].irqn = get_irqn(streams[j]);
e[j].id = j;
}

}

template <class Ctx>
consteval array<size_t, sizeof...(Ss)> inscribe(Ctx &ctx) const {
array<size_t, sizeof...(Ss)> indices{};
for (size_t i = 0; i < sizeof...(Ss); i++) {
indices[i] = ctx.template add<DMA_Domain>(e[i], this);
}
return indices;
}
};

static constexpr std::size_t max_instances {MAX_STREAMS};
static_assert(max_instances > 0, "The number of instances must be greater than 0");

static inline constexpr IRQn_Type get_irqn(Stream stream) {
if (stream == Stream::dma1_stream0) return DMA1_Stream0_IRQn;
else if (stream == Stream::dma1_stream1) return DMA1_Stream1_IRQn;
else if (stream == Stream::dma1_stream2) return DMA1_Stream2_IRQn;
else if (stream == Stream::dma1_stream3) return DMA1_Stream3_IRQn;
else if (stream == Stream::dma1_stream4) return DMA1_Stream4_IRQn;
else if (stream == Stream::dma1_stream5) return DMA1_Stream5_IRQn;
else if (stream == Stream::dma1_stream6) return DMA1_Stream6_IRQn;
else if (stream == Stream::dma1_stream7) return DMA1_Stream7_IRQn;

else if (stream == Stream::dma2_stream0) return DMA2_Stream0_IRQn;
else if (stream == Stream::dma2_stream1) return DMA2_Stream1_IRQn;
else if (stream == Stream::dma2_stream2) return DMA2_Stream2_IRQn;
else if (stream == Stream::dma2_stream3) return DMA2_Stream3_IRQn;
else if (stream == Stream::dma2_stream4) return DMA2_Stream4_IRQn;
else if (stream == Stream::dma2_stream5) return DMA2_Stream5_IRQn;
else if (stream == Stream::dma2_stream6) return DMA2_Stream6_IRQn;
else if (stream == Stream::dma2_stream7) return DMA2_Stream7_IRQn;
else ErrorHandler("Unknown DMA stream");
return DMA1_Stream0_IRQn; // Nunca se alcanza
}

static constexpr inline bool is_one_of(Instance instance, auto... bases) {
return ((instance == bases) || ...);
}

static constexpr inline bool is_spi(Instance instance) {
return is_one_of(instance, Instance::spi1, Instance::spi2,
Instance::spi3, Instance::spi4, Instance::spi5);
}

static constexpr inline bool is_i2c(Instance instance) {
return is_one_of(instance, Instance::i2c1, Instance::i2c2,
Instance::i2c3, Instance::i2c5);
}

static constexpr inline bool is_adc(Instance instance) {
return is_one_of(instance, Instance::adc1, Instance::adc2, Instance::adc3);
}

static constexpr inline bool is_fmac(Instance instance) {
return instance == Instance::fmac;
}

static constexpr inline bool is_none(Instance instance){
return instance == Instance::none;
}

static consteval inline uint32_t get_Request(Instance instance, uint8_t i) {
if (instance == Instance::none) return DMA_REQUEST_MEM2MEM;

if (instance == Instance::adc1) return DMA_REQUEST_ADC1;
if (instance == Instance::adc2) return DMA_REQUEST_ADC2;
if (instance == Instance::adc3) return DMA_REQUEST_ADC3;

if (instance == Instance::i2c1 && i == 0) return DMA_REQUEST_I2C1_RX;
if (instance == Instance::i2c1 && i == 1) return DMA_REQUEST_I2C1_TX;
if (instance == Instance::i2c2 && i == 0) return DMA_REQUEST_I2C2_RX;
if (instance == Instance::i2c2 && i == 1) return DMA_REQUEST_I2C2_TX;
if (instance == Instance::i2c3 && i == 0) return DMA_REQUEST_I2C3_RX;
if (instance == Instance::i2c3 && i == 1) return DMA_REQUEST_I2C3_TX;
if (instance == Instance::i2c5 && i == 0) return DMA_REQUEST_I2C5_RX;
if (instance == Instance::i2c5 && i == 1) return DMA_REQUEST_I2C5_TX;

if (instance == Instance::spi1 && i == 0) return DMA_REQUEST_SPI1_RX;
if (instance == Instance::spi1 && i == 1) return DMA_REQUEST_SPI1_TX;
if (instance == Instance::spi2 && i == 0) return DMA_REQUEST_SPI2_RX;
if (instance == Instance::spi2 && i == 1) return DMA_REQUEST_SPI2_TX;
if (instance == Instance::spi3 && i == 0) return DMA_REQUEST_SPI3_RX;
if (instance == Instance::spi3 && i == 1) return DMA_REQUEST_SPI3_TX;
if (instance == Instance::spi4 && i == 0) return DMA_REQUEST_SPI4_RX;
if (instance == Instance::spi4 && i == 1) return DMA_REQUEST_SPI4_TX;
if (instance == Instance::spi5 && i == 0) return DMA_REQUEST_SPI5_RX;
if (instance == Instance::spi5 && i == 1) return DMA_REQUEST_SPI5_TX;

if (instance == Instance::fmac && i == 0) return DMA_REQUEST_MEM2MEM;
if (instance == Instance::fmac && i == 1) return DMA_REQUEST_FMAC_WRITE;
if (instance == Instance::fmac && i == 2) return DMA_REQUEST_FMAC_READ;

ErrorHandler("Invalid DMA request configuration");
return 0;
}

static consteval inline uint32_t get_Direction(Instance instance, uint8_t i) {
if ((is_fmac(instance) && i == 0) || instance == Instance::none) {
return DMA_MEMORY_TO_MEMORY;
}
else if ((is_i2c(instance) && i == 1) ||
(is_spi(instance) && i == 1) ||
(is_fmac(instance) && i == 1)){
return DMA_MEMORY_TO_PERIPH;
}
return DMA_PERIPH_TO_MEMORY;
}

static consteval inline uint32_t get_PeriphInc(Instance instance, uint8_t i) {
if ((is_fmac(instance) && i == 0) || is_none(instance)){
return DMA_PINC_ENABLE;
}
return DMA_PINC_DISABLE;
}

static consteval inline uint32_t get_MemInc(Instance instance, uint8_t i) {
if (is_fmac(instance) && i == 0){
return DMA_MINC_DISABLE;
}
return DMA_MINC_ENABLE;
}

static consteval inline uint32_t get_PeriphDataAlignment(Instance instance, uint8_t i) {
if (is_spi(instance) || is_i2c(instance)){
return DMA_PDATAALIGN_BYTE;
}
else if (is_none(instance)){
return DMA_PDATAALIGN_WORD;
}
return DMA_PDATAALIGN_HALFWORD;
}

static consteval inline uint32_t get_MemDataAlignment(Instance instance, uint8_t i) {
if (is_i2c(instance)){
return DMA_MDATAALIGN_WORD;
}
else if (is_spi(instance)){
return DMA_MDATAALIGN_BYTE;
}

return DMA_MDATAALIGN_HALFWORD;
}

static consteval inline uint32_t get_Mode(Instance instance, uint8_t i) {
if (is_spi(instance) || is_fmac(instance) || is_none(instance)){
return DMA_NORMAL;
}

return DMA_CIRCULAR;
}

static consteval inline uint32_t get_Priority(Instance instance, uint8_t i) {
if (is_fmac(instance)){
return DMA_PRIORITY_HIGH;
}

return DMA_PRIORITY_LOW;
}

static consteval inline uint32_t get_FIFOMode(Instance instance, uint8_t i) {
if (is_fmac(instance)){
return DMA_FIFOMODE_ENABLE;
}
return DMA_FIFOMODE_DISABLE;
}

static consteval inline uint32_t get_FIFOThreshold(Instance instance, uint8_t i) {
if (is_spi(instance)){
return DMA_FIFO_THRESHOLD_FULL;
}
return DMA_FIFO_THRESHOLD_HALFFULL;
}

static consteval inline uint32_t get_MemBurst(Instance instance, uint8_t i) {
return DMA_MBURST_SINGLE;
}

static consteval inline uint32_t get_PeriphBurst(Instance instance, uint8_t i) {
return DMA_PBURST_SINGLE;
}

struct Config {
std::tuple<Instance,
DMA_InitTypeDef,
Stream,
IRQn_Type,
uint8_t>
init_data{};
};

template <size_t N>
static consteval std::array<Config, N> build(span<const Entry> instances) {
std::array<Config, N> cfgs{};

for (std::size_t i = 0; i < N; ++i){
const auto &e = instances[i];

for (std::size_t j = 0; j < i; ++j){
const auto &prev = instances[j];
if (prev.stream == e.stream){
compile_error("DMA stream already in use");
}
}

DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.Request = get_Request(e.instance, e.id);
DMA_InitStruct.Direction = get_Direction(e.instance, e.id);
DMA_InitStruct.PeriphInc = get_PeriphInc(e.instance, e.id);
DMA_InitStruct.MemInc = get_MemInc(e.instance, e.id);
DMA_InitStruct.PeriphDataAlignment = get_PeriphDataAlignment(e.instance, e.id);
DMA_InitStruct.MemDataAlignment = get_MemDataAlignment(e.instance, e.id);
DMA_InitStruct.Mode = get_Mode(e.instance, e.id);
DMA_InitStruct.Priority = get_Priority(e.instance, e.id);
DMA_InitStruct.FIFOMode = get_FIFOMode(e.instance, e.id);
DMA_InitStruct.FIFOThreshold = get_FIFOThreshold(e.instance, e.id);
DMA_InitStruct.MemBurst = get_MemBurst(e.instance, e.id);
DMA_InitStruct.PeriphBurst = get_PeriphBurst(e.instance, e.id);


cfgs[i].init_data = std::make_tuple(e.instance,
DMA_InitStruct,
e.stream,
e.irqn,
e.id);
}
return cfgs;
}



struct Instances_ {
DMA_HandleTypeDef dma;

void start(uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength){
HAL_DMA_Start_IT(&dma, SrcAddress, DstAddress, DataLength);
}
};


template <std::size_t N> struct Init {
static inline std::array<Instances_, N> instances{};

static void init(std::span<const Config, N> cfgs) {
if (N == 0) return;
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
for (std::size_t i = 0; i < N; ++i) {
const auto &e = cfgs[i];
auto [instance, dma_init, stream, irqn, id] = e.init_data;

instances[i].dma = {};
instances[i].dma.Instance = stream_to_DMA_StreamTypeDef(stream);
instances[i].dma.Init = dma_init;

if (HAL_DMA_Init(&instances[i].dma) != HAL_OK) {
ErrorHandler("DMA Init failed");
}
else{
HAL_NVIC_SetPriority(irqn, 0, 0);
HAL_NVIC_EnableIRQ(irqn);
dma_irq_table[static_cast<uint8_t>(stream)] = &instances[i].dma;
}
}
}
};
};
}

Loading
Loading