From ad4bda06247719f5fc715a3360d8abccfd881503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Wed, 17 Dec 2025 00:32:57 +0100 Subject: [PATCH 1/6] fixed getting wrong instance --- Inc/HALAL/Models/GPIO.hpp | 3 ++- Inc/ST-LIB.hpp | 43 ++----------------------------- Inc/ST-LIB_LOW/DigitalInput2.hpp | 3 ++- Inc/ST-LIB_LOW/DigitalOutput2.hpp | 3 ++- 4 files changed, 8 insertions(+), 44 deletions(-) diff --git a/Inc/HALAL/Models/GPIO.hpp b/Inc/HALAL/Models/GPIO.hpp index c19131e37..370f46162 100644 --- a/Inc/HALAL/Models/GPIO.hpp +++ b/Inc/HALAL/Models/GPIO.hpp @@ -172,6 +172,7 @@ struct GPIODomain { struct GPIO { using domain = GPIODomain; + size_t index; Entry e; @@ -184,7 +185,7 @@ struct GPIODomain { } template consteval void inscribe(Ctx &ctx) const { - ctx.template add(e); + index = ctx.template add(e); } }; diff --git a/Inc/ST-LIB.hpp b/Inc/ST-LIB.hpp index 32fb54814..c17d73f5b 100644 --- a/Inc/ST-LIB.hpp +++ b/Inc/ST-LIB.hpp @@ -126,51 +126,12 @@ template struct Board { // ... } - template - static consteval std::size_t domain_size_for_instance() { - return domain_size(); - } - - template - static consteval std::size_t domain_index_of_impl() { - std::size_t idx = 0; - bool found = false; - - ( - [&] { - using DevT = std::remove_cvref_t; - if constexpr (std::is_same_v) { - if (!found) { - if (&devs == &Target) { - found = true; - } else { - ++idx; - } - } - } - }(), - ...); - - if (!found) { - compile_error("Device not found for domain"); - } - - return idx; - } - - template - static consteval std::size_t domain_index_of() { - return domain_index_of_impl(); - } - template static auto &instance_of() { using DevT = std::remove_cvref_t; using Domain = typename DevT::domain; - constexpr std::size_t idx = domain_index_of(); - constexpr std::size_t N = domain_size_for_instance(); - - return Domain::template Init::instances[idx]; + constexpr std::size_t N = domain_size(); + return Domain::template Init::instances[Target.index]; } }; diff --git a/Inc/ST-LIB_LOW/DigitalInput2.hpp b/Inc/ST-LIB_LOW/DigitalInput2.hpp index e161e39a5..66d95ce0e 100644 --- a/Inc/ST-LIB_LOW/DigitalInput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalInput2.hpp @@ -12,6 +12,7 @@ struct DigitalInputDomain { struct DigitalInput { GPIODomain::GPIO gpio; using domain = DigitalInputDomain; + size_t index; consteval DigitalInput(const GPIODomain::Pin &pin, GPIODomain::Pull pull = GPIODomain::Pull::None, @@ -21,7 +22,7 @@ struct DigitalInputDomain { template consteval void inscribe(Ctx &ctx) const { const auto gpio_idx = ctx.template add(gpio.e); Entry e{.gpio_idx = gpio_idx}; - ctx.template add(e); + index = ctx.template add(e); } }; diff --git a/Inc/ST-LIB_LOW/DigitalOutput2.hpp b/Inc/ST-LIB_LOW/DigitalOutput2.hpp index 7dcad5b65..9d817be05 100644 --- a/Inc/ST-LIB_LOW/DigitalOutput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalOutput2.hpp @@ -18,6 +18,7 @@ struct DigitalOutputDomain { struct DigitalOutput { GPIODomain::GPIO gpio; using domain = DigitalOutputDomain; + size_t index; consteval DigitalOutput(const GPIODomain::Pin &pin, OutputMode mode = OutputMode::PUSH_PULL, @@ -29,7 +30,7 @@ struct DigitalOutputDomain { template consteval void inscribe(Ctx &ctx) const { const auto gpio_idx = ctx.template add(gpio.e); Entry e{.gpio_idx = gpio_idx}; - ctx.template add(e); + index = ctx.template add(e); } }; From 328cca0369c020bd0808e6f66276cf449847e757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Wed, 17 Dec 2025 00:39:39 +0100 Subject: [PATCH 2/6] marked indexs as mutable --- Inc/HALAL/Models/GPIO.hpp | 2 +- Inc/ST-LIB_LOW/DigitalInput2.hpp | 2 +- Inc/ST-LIB_LOW/DigitalOutput2.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Inc/HALAL/Models/GPIO.hpp b/Inc/HALAL/Models/GPIO.hpp index 370f46162..953d8b19f 100644 --- a/Inc/HALAL/Models/GPIO.hpp +++ b/Inc/HALAL/Models/GPIO.hpp @@ -172,7 +172,7 @@ struct GPIODomain { struct GPIO { using domain = GPIODomain; - size_t index; + mutable size_t index; Entry e; diff --git a/Inc/ST-LIB_LOW/DigitalInput2.hpp b/Inc/ST-LIB_LOW/DigitalInput2.hpp index 66d95ce0e..a900b924c 100644 --- a/Inc/ST-LIB_LOW/DigitalInput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalInput2.hpp @@ -12,7 +12,7 @@ struct DigitalInputDomain { struct DigitalInput { GPIODomain::GPIO gpio; using domain = DigitalInputDomain; - size_t index; + mutable size_t index; consteval DigitalInput(const GPIODomain::Pin &pin, GPIODomain::Pull pull = GPIODomain::Pull::None, diff --git a/Inc/ST-LIB_LOW/DigitalOutput2.hpp b/Inc/ST-LIB_LOW/DigitalOutput2.hpp index 9d817be05..8889691b4 100644 --- a/Inc/ST-LIB_LOW/DigitalOutput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalOutput2.hpp @@ -18,7 +18,7 @@ struct DigitalOutputDomain { struct DigitalOutput { GPIODomain::GPIO gpio; using domain = DigitalOutputDomain; - size_t index; + mutable size_t index; consteval DigitalOutput(const GPIODomain::Pin &pin, OutputMode mode = OutputMode::PUSH_PULL, From f27035cc0d9cbef462507fcbc7595dd81a1646e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Thu, 18 Dec 2025 00:04:37 +0100 Subject: [PATCH 3/6] Fixed instance_of method. Now add interface needs the Device --- Inc/HALAL/Models/GPIO.hpp | 3 +-- Inc/ST-LIB.hpp | 33 ++++++++++++++++++++++++++++--- Inc/ST-LIB_LOW/DigitalInput2.hpp | 5 ++--- Inc/ST-LIB_LOW/DigitalOutput2.hpp | 5 ++--- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/Inc/HALAL/Models/GPIO.hpp b/Inc/HALAL/Models/GPIO.hpp index 953d8b19f..e69c94c16 100644 --- a/Inc/HALAL/Models/GPIO.hpp +++ b/Inc/HALAL/Models/GPIO.hpp @@ -172,7 +172,6 @@ struct GPIODomain { struct GPIO { using domain = GPIODomain; - mutable size_t index; Entry e; @@ -185,7 +184,7 @@ struct GPIODomain { } template consteval void inscribe(Ctx &ctx) const { - index = ctx.template add(e); + ctx.template add(e, this); } }; diff --git a/Inc/ST-LIB.hpp b/Inc/ST-LIB.hpp index c17d73f5b..221035b08 100644 --- a/Inc/ST-LIB.hpp +++ b/Inc/ST-LIB.hpp @@ -32,6 +32,7 @@ template struct BuildCtx { static constexpr std::size_t max_count_v = D::max_instances; std::tuple, max_count_v>...> storage{}; + std::tuple>...> owners{}; std::array sizes{}; template @@ -47,12 +48,17 @@ template struct BuildCtx { } } - template consteval std::size_t add(typename D::Entry e) { + template + consteval std::size_t add(typename D::Entry e, const Owner *owner) { constexpr std::size_t I = domain_index(); auto &arr = std::get(storage); + auto &own = std::get(owners); auto &size = sizes[I]; + const auto idx = size; - arr[size++] = e; + arr[size] = e; + own[size] = owner; + ++size; return idx; } @@ -64,6 +70,13 @@ template struct BuildCtx { return std::span{arr.data(), size}; } + template consteval auto owners_span() const { + constexpr std::size_t I = domain_index(); + auto const &arr = std::get(owners); + auto const size = sizes[I]; + return std::span{arr.data(), size}; + } + template consteval std::size_t size() const { constexpr std::size_t I = domain_index(); return sizes[I]; @@ -126,12 +139,26 @@ template struct Board { // ... } + template + static consteval std::size_t owner_index_of() { + constexpr auto owners = ctx.template owners_span(); + + if constexpr (I >= owners.size()) { + compile_error("Device not registered in domain"); + return 0; + } else { + return owners[I] == &Target ? I : owner_index_of(); + } + } + template static auto &instance_of() { using DevT = std::remove_cvref_t; using Domain = typename DevT::domain; + constexpr std::size_t idx = owner_index_of(); + constexpr std::size_t N = domain_size(); - return Domain::template Init::instances[Target.index]; + return Domain::template Init::instances[idx]; } }; diff --git a/Inc/ST-LIB_LOW/DigitalInput2.hpp b/Inc/ST-LIB_LOW/DigitalInput2.hpp index a900b924c..4dec87413 100644 --- a/Inc/ST-LIB_LOW/DigitalInput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalInput2.hpp @@ -12,7 +12,6 @@ struct DigitalInputDomain { struct DigitalInput { GPIODomain::GPIO gpio; using domain = DigitalInputDomain; - mutable size_t index; consteval DigitalInput(const GPIODomain::Pin &pin, GPIODomain::Pull pull = GPIODomain::Pull::None, @@ -20,9 +19,9 @@ struct DigitalInputDomain { : gpio{pin, GPIODomain::OperationMode::INPUT, pull, speed} {} template consteval void inscribe(Ctx &ctx) const { - const auto gpio_idx = ctx.template add(gpio.e); + const auto gpio_idx = ctx.template add(gpio.e, &gpio); Entry e{.gpio_idx = gpio_idx}; - index = ctx.template add(e); + ctx.template add(e, this); } }; diff --git a/Inc/ST-LIB_LOW/DigitalOutput2.hpp b/Inc/ST-LIB_LOW/DigitalOutput2.hpp index 8889691b4..8c99b9f24 100644 --- a/Inc/ST-LIB_LOW/DigitalOutput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalOutput2.hpp @@ -18,7 +18,6 @@ struct DigitalOutputDomain { struct DigitalOutput { GPIODomain::GPIO gpio; using domain = DigitalOutputDomain; - mutable size_t index; consteval DigitalOutput(const GPIODomain::Pin &pin, OutputMode mode = OutputMode::PUSH_PULL, @@ -28,9 +27,9 @@ struct DigitalOutputDomain { } template consteval void inscribe(Ctx &ctx) const { - const auto gpio_idx = ctx.template add(gpio.e); + const auto gpio_idx = ctx.template add(gpio.e, &gpio); Entry e{.gpio_idx = gpio_idx}; - index = ctx.template add(e); + ctx.template add(e, this); } }; From bc9d908c4886970222bfe83529c61ca2fc448ea9 Mon Sep 17 00:00:00 2001 From: Foniks Date: Thu, 25 Dec 2025 15:59:57 +0100 Subject: [PATCH 4/6] feat(ST-LIB): Use inscribe inside inscribe --- Inc/HALAL/Models/GPIO.hpp | 4 ++-- Inc/ST-LIB_LOW/DigitalInput2.hpp | 6 +++--- Inc/ST-LIB_LOW/DigitalOutput2.hpp | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Inc/HALAL/Models/GPIO.hpp b/Inc/HALAL/Models/GPIO.hpp index e69c94c16..26ca34189 100644 --- a/Inc/HALAL/Models/GPIO.hpp +++ b/Inc/HALAL/Models/GPIO.hpp @@ -183,8 +183,8 @@ struct GPIODomain { } } - template consteval void inscribe(Ctx &ctx) const { - ctx.template add(e, this); + template consteval auto inscribe(Ctx &ctx) const { + return ctx.template add(e, this); } }; diff --git a/Inc/ST-LIB_LOW/DigitalInput2.hpp b/Inc/ST-LIB_LOW/DigitalInput2.hpp index 4dec87413..77585edf3 100644 --- a/Inc/ST-LIB_LOW/DigitalInput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalInput2.hpp @@ -18,10 +18,10 @@ struct DigitalInputDomain { GPIODomain::Speed speed = GPIODomain::Speed::Low) : gpio{pin, GPIODomain::OperationMode::INPUT, pull, speed} {} - template consteval void inscribe(Ctx &ctx) const { - const auto gpio_idx = ctx.template add(gpio.e, &gpio); + template consteval auto inscribe(Ctx &ctx) const { + const auto gpio_idx = gpio.inscribe(ctx); Entry e{.gpio_idx = gpio_idx}; - ctx.template add(e, this); + return ctx.template add(e, this); } }; diff --git a/Inc/ST-LIB_LOW/DigitalOutput2.hpp b/Inc/ST-LIB_LOW/DigitalOutput2.hpp index 8c99b9f24..cc3c2f87d 100644 --- a/Inc/ST-LIB_LOW/DigitalOutput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalOutput2.hpp @@ -26,10 +26,10 @@ struct DigitalOutputDomain { : gpio{pin, static_cast(mode), pull, speed} { } - template consteval void inscribe(Ctx &ctx) const { - const auto gpio_idx = ctx.template add(gpio.e, &gpio); + template consteval auto inscribe(Ctx &ctx) const { + const auto gpio_idx = gpio.inscribe(ctx); Entry e{.gpio_idx = gpio_idx}; - ctx.template add(e, this); + return ctx.template add(e, this); } }; From 40561bc7e0089a5292430281454aa6ad4e6fd456 Mon Sep 17 00:00:00 2001 From: Foniks Date: Thu, 25 Dec 2025 16:00:35 +0100 Subject: [PATCH 5/6] refactor(ST-LIB)!: Define domains once in ST-LIB.hpp, every domain declares it's dependencies, everything else is automatic --- Inc/HALAL/Models/GPIO.hpp | 15 +++-- Inc/ST-LIB.hpp | 94 +++++++++++++++++++------------ Inc/ST-LIB_LOW/DigitalInput2.hpp | 7 ++- Inc/ST-LIB_LOW/DigitalOutput2.hpp | 7 ++- 4 files changed, 76 insertions(+), 47 deletions(-) diff --git a/Inc/HALAL/Models/GPIO.hpp b/Inc/HALAL/Models/GPIO.hpp index 26ca34189..b2bc00023 100644 --- a/Inc/HALAL/Models/GPIO.hpp +++ b/Inc/HALAL/Models/GPIO.hpp @@ -191,7 +191,8 @@ struct GPIODomain { static constexpr std::size_t max_instances{110}; struct Config { - std::tuple init_data{}; + Port port; + GPIO_InitTypeDef init_data; }; template @@ -216,7 +217,9 @@ struct GPIODomain { GPIO_InitStruct.Alternate = static_cast(e.af); } - cfgs[i].init_data = std::make_tuple(e.port, GPIO_InitStruct); + // Assign directly to struct members + cfgs[i].port = e.port; + cfgs[i].init_data = GPIO_InitStruct; } return cfgs; @@ -242,14 +245,16 @@ struct GPIODomain { GPIO_PinState read() { return HAL_GPIO_ReadPin(port, pin); } }; - template struct Init { + template cfgs> struct Init { static inline std::array instances{}; - static void init(std::span cfgs) { + static void init() { static_assert(N > 0); for (std::size_t i = 0; i < N; ++i) { const auto &e = cfgs[i]; - auto [port, gpio_init] = e.init_data; + + auto port = e.port; + auto gpio_init = e.init_data; enable_gpio_clock(port); HAL_GPIO_Init(port_to_reg(port), &gpio_init); diff --git a/Inc/ST-LIB.hpp b/Inc/ST-LIB.hpp index 221035b08..f7c5f07ce 100644 --- a/Inc/ST-LIB.hpp +++ b/Inc/ST-LIB.hpp @@ -83,12 +83,21 @@ template struct BuildCtx { } }; -using DomainsCtx = BuildCtx; +template struct UnpackToCtx; +template struct UnpackToCtx> { + using type = BuildCtx; +}; template struct Board { + using Domains = std::tuple< + /* Level 0: Base Domains */ + GPIODomain, + /* Level 1: Domains depending on Level 0 */ + DigitalOutputDomain, DigitalInputDomain /*, ADCDomain, PWMDomain, ...*/>; + using CtxType = typename UnpackToCtx::type; + static consteval auto build_ctx() { - DomainsCtx ctx{}; + CtxType ctx{}; (devs.inscribe(ctx), ...); return ctx; } @@ -99,44 +108,56 @@ template struct Board { return ctx.template span().size(); } + template + static consteval auto build_configs(std::index_sequence) { + return std::make_tuple( + std::tuple_element_t::template build< + domain_size>()>( + ctx.template span>())...); + } + static consteval auto build() { - constexpr std::size_t gpioN = domain_size(); - constexpr std::size_t doutN = domain_size(); - constexpr std::size_t dinN = domain_size(); - // ... - - struct ConfigBundle { - std::array gpio_cfgs; - std::array dout_cfgs; - std::array din_cfgs; - // ... - }; - - return ConfigBundle{ - .gpio_cfgs = - GPIODomain::template build(ctx.template span()), - .dout_cfgs = DigitalOutputDomain::template build( - ctx.template span()), - .din_cfgs = DigitalInputDomain::template build( - ctx.template span()), - // ... - }; + return build_configs( + std::make_index_sequence>{}); } static constexpr auto cfg = build(); - static void init() { - constexpr std::size_t gpioN = domain_size(); - constexpr std::size_t doutN = domain_size(); - constexpr std::size_t dinN = domain_size(); - // ... + template static consteval auto get_config() { + constexpr std::size_t I = CtxType::template domain_index(); + return std::get(cfg); + } - GPIODomain::Init::init(cfg.gpio_cfgs); - DigitalOutputDomain::Init::init(cfg.dout_cfgs, - GPIODomain::Init::instances); - DigitalInputDomain::Init::init(cfg.din_cfgs, - GPIODomain::Init::instances); - // ... + template static auto &get_instances() { + constexpr std::size_t N = domain_size(); + return Domain::template Init()>::instances; + } + + template + static void init_with_deps(std::tuple *) { // Pointer to deduce types easily, not used + InitT::init(get_instances()...); + } + + template static void init_domain() { + constexpr std::size_t N = domain_size(); + constexpr auto cfgs = get_config(); + using InitT = typename Domain::template Init; + + if constexpr (requires { typename Domain::dependencies; }) { + // Resolve dependencies + init_with_deps(static_cast(nullptr)); + } else { + InitT::init(); + } + } + + static void init() { + Domains domains; + std::apply( + [](auto &...d) { + (init_domain>(), ...); + }, + domains); } template @@ -158,7 +179,8 @@ template struct Board { constexpr std::size_t idx = owner_index_of(); constexpr std::size_t N = domain_size(); - return Domain::template Init::instances[idx]; + + return Domain::template Init()>::instances[idx]; } }; diff --git a/Inc/ST-LIB_LOW/DigitalInput2.hpp b/Inc/ST-LIB_LOW/DigitalInput2.hpp index 77585edf3..cef57b799 100644 --- a/Inc/ST-LIB_LOW/DigitalInput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalInput2.hpp @@ -6,6 +6,8 @@ using ST_LIB::GPIODomain; namespace ST_LIB { struct DigitalInputDomain { + using dependencies = std::tuple; + struct Entry { size_t gpio_idx; }; @@ -47,11 +49,10 @@ struct DigitalInputDomain { GPIO_PinState read() { return gpio_instance->read(); } }; - template struct Init { + template cfgs> struct Init { static inline std::array instances{}; - static void init(std::span cfgs, - std::span gpio_instances) { + static void init(std::span gpio_instances) { for (std::size_t i = 0; i < N; ++i) { const auto &e = cfgs[i]; diff --git a/Inc/ST-LIB_LOW/DigitalOutput2.hpp b/Inc/ST-LIB_LOW/DigitalOutput2.hpp index cc3c2f87d..8ce11f4d8 100644 --- a/Inc/ST-LIB_LOW/DigitalOutput2.hpp +++ b/Inc/ST-LIB_LOW/DigitalOutput2.hpp @@ -6,6 +6,8 @@ using ST_LIB::GPIODomain; namespace ST_LIB { struct DigitalOutputDomain { + using dependencies = std::tuple; + enum class OutputMode : uint8_t { PUSH_PULL = static_cast(GPIODomain::OperationMode::OUTPUT_PUSHPULL), @@ -59,11 +61,10 @@ struct DigitalOutputDomain { void toggle() { gpio_instance->toggle(); } }; - template struct Init { + template cfgs> struct Init { static inline std::array instances{}; - static void init(std::span cfgs, - std::span gpio_instances) { + static void init(std::span gpio_instances) { for (std::size_t i = 0; i < N; ++i) { const auto &e = cfgs[i]; From 3011ca622d0240543515391b7964add1ba342e8a Mon Sep 17 00:00:00 2001 From: Foniks Date: Thu, 25 Dec 2025 17:12:22 +0100 Subject: [PATCH 6/6] fix(ST-LIB): Fix unnecessary domain initialization --- Inc/ST-LIB.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Inc/ST-LIB.hpp b/Inc/ST-LIB.hpp index f7c5f07ce..ed86031aa 100644 --- a/Inc/ST-LIB.hpp +++ b/Inc/ST-LIB.hpp @@ -151,13 +151,13 @@ template struct Board { } } + template + static void init_domains(std::index_sequence) { + (init_domain>(), ...); + } + static void init() { - Domains domains; - std::apply( - [](auto &...d) { - (init_domain>(), ...); - }, - domains); + init_domains(std::make_index_sequence>{}); } template