Feat/clock domain#667
Draft
FoniksFox wants to merge 24 commits into
Draft
Conversation
diff --git c/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp i/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp index 680bf82..4c09a80 100644 --- c/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp +++ i/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp @@ -18,6 +18,7 @@ #include <array> #include "ErrorHandler/ErrorHandler.hpp" +#include "HALAL/Models/Clocks/ClockDomain.hpp" #ifndef SCHEDULER_TIMER_DOMAIN /* default is tim2 */ @@ -293,6 +294,7 @@ struct TimerDomain { struct Config { uint8_t timer_idx; + TimerRequest request; SelectionTrigger1 trgo1; SelectionTrigger2 trgo2; }; @@ -639,6 +641,7 @@ struct TimerDomain { Config cfg = { .timer_idx = timer_idxmap[reqint], + .request = requests[i].request, .trgo1 = requests[i].trgo1, .trgo2 = requests[i].trgo2 }; @@ -672,7 +675,7 @@ struct TimerDomain { uint8_t reqint = remaining_32bit_timers[count_32bit_requests]; Config cfg = - {.timer_idx = timer_idxmap[reqint], .trgo1 = e.trgo1, .trgo2 = e.trgo2}; + {.timer_idx = timer_idxmap[reqint], .request = e.request, .trgo1 = e.trgo1, .trgo2 = e.trgo2}; cfgs[cfg_idx++] = cfg; // unordered remove @@ -719,7 +722,7 @@ struct TimerDomain { ST_LIB::compile_error("This only processes TimerRequest::AnyGeneralPurpose"); } uint8_t reqint = remaining_timers[i]; - Config cfg = {.timer_idx = timer_idxmap[reqint], .trgo1 = e.trgo1, .trgo2 = e.trgo2}; + Config cfg = {.timer_idx = timer_idxmap[reqint], .request = e.request, .trgo1 = e.trgo1, .trgo2 = e.trgo2}; cfgs[cfg_idx++] = cfg; } @@ -732,8 +735,27 @@ struct TimerDomain { TIM_HandleTypeDef* hal_tim; TIM_MasterConfigTypeDef master{}; uint8_t timer_idx; + uint32_t clock_frequency = 0; // from ClockTree }; + static constexpr bool is_timer_on_apb1(TimerRequest r) { + switch (r) { + case TimerRequest::GeneralPurpose32bit_2: + case TimerRequest::GeneralPurpose_3: + case TimerRequest::GeneralPurpose_4: + case TimerRequest::GeneralPurpose32bit_5: + case TimerRequest::Basic_6: + case TimerRequest::Basic_7: + case TimerRequest::SlaveTimer_12: + case TimerRequest::SlaveTimer_13: + case TimerRequest::SlaveTimer_14: + case TimerRequest::GeneralPurpose32bit_23: + case TimerRequest::GeneralPurpose32bit_24: + return true; + default: return false; + } + } + static void (*callbacks[TimerDomain::max_instances])(void*); static void* callback_data[TimerDomain::max_instances]; @@ -742,7 +764,7 @@ struct TimerDomain { static void TIM_Default_Callback(void* raw) { (void)raw; } - static void init(std::span<const Config, N> cfgs) { + static void init(std::span<const Config, N> cfgs, const ClockDomain::ClockTree& tree) { Scheduler_global_timer = cmsis_timers[timer_idxmap[SCHEDULER_TIMER_DOMAIN]]; rcc_enable_timer(Scheduler_global_timer); @@ -802,6 +824,8 @@ struct TimerDomain { inst->tim = tim; inst->hal_tim = handle; inst->timer_idx = e.timer_idx; + inst->clock_frequency = is_timer_on_apb1(e.request) + ? ClockDomain::timer_apb1(tree) : ClockDomain::timer_apb2(tree); TIM_MasterConfigTypeDef sMasterConfig = {}; sMasterConfig.MasterOutputTrigger = static_cast<uint32_t>(e.trgo1); sMasterConfig.MasterOutputTrigger2 = static_cast<uint32_t>(e.trgo2); diff --git c/Inc/HALAL/Services/Time/TimerWrapper.hpp i/Inc/HALAL/Services/Time/TimerWrapper.hpp index 051849b..d41878c 100644 --- c/Inc/HALAL/Services/Time/TimerWrapper.hpp +++ i/Inc/HALAL/Services/Time/TimerWrapper.hpp @@ -135,19 +135,10 @@ template <const TimerDomain::Timer& dev> struct TimerWrapper { } inline uint32_t get_clock_frequency() { - uint32_t result; - if constexpr (this->is_on_APB1) { - result = HAL_RCC_GetPCLK1Freq(); - if ((RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) != RCC_HCLK_DIV1) { - result *= 2; - } - } else { - result = HAL_RCC_GetPCLK2Freq(); - if ((RCC->D2CFGR & RCC_D2CFGR_D2PPRE2) != RCC_HCLK_DIV1) { - result *= 2; - } + if (instance->clock_frequency == 0) { + PANIC("Timer clock not configured by ClockDomain"); } - return result; + return instance->clock_frequency; } template <TimerPin pin> diff --git c/Inc/ST-LIB.hpp i/Inc/ST-LIB.hpp index 168dacd..e65ec55 100644 --- c/Inc/ST-LIB.hpp +++ i/Inc/ST-LIB.hpp @@ -316,7 +316,7 @@ public: MPUDomain::Init<mpuN, cfg.mpu_cfgs>::init(); GPIODomain::Init<gpioN>::init(cfg.gpio_cfgs); - TimerDomain::Init<timN>::init(cfg.tim_cfgs); + TimerDomain::Init<timN>::init(cfg.tim_cfgs, cfg.clock_tree); DMADomain::Init<dmaN>::init(cfg.dma_cfgs); SPIDomain::Init<spiN>::init( cfg.spi_cfgs,
Contributor
ST-LIB Release Plan
Pending changes
|
victor-Lopez25
requested changes
Jun 21, 2026
Comment on lines
+247
to
252
| // Build: validate the tree against peripheral requirements | ||
| ClockDomain::build(ctx.template span<ClockDomain>(), ClockTreeDef); | ||
|
|
||
| return ConfigBundle{ | ||
| .clock_tree = ClockTreeDef, | ||
| .mpu_cfgs = MPUDomain::template build<mpuN>(ctx.template span<MPUDomain>()), |
Contributor
There was a problem hiding this comment.
Is there no way to have it work like the others, so we can simplify creating Board?
Contributor
Author
There was a problem hiding this comment.
Not really, not in any way that makes sense at least. If you have any idea, I'd like to hear it!
* fix: Fix a warning about symbols missmatch * chore: Add changeset
diff --git c/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp i/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp index db1a014..8219d4f 100644 --- c/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp +++ i/Inc/HALAL/Models/TimerDomain/TimerDomain.hpp @@ -672,11 +672,8 @@ struct TimerDomain { } uint8_t reqint = remaining_32bit_timers[count_32bit_requests]; - Config cfg = { - .timer_idx = timer_idxmap[reqint], - .trgo1 = e.trgo1, - .trgo2 = e.trgo2 - }; + Config cfg = + {.timer_idx = timer_idxmap[reqint], .trgo1 = e.trgo1, .trgo2 = e.trgo2}; cfgs[cfg_idx++] = cfg; // unordered remove @@ -723,11 +720,7 @@ struct TimerDomain { ST_LIB::compile_error("This only processes TimerRequest::AnyGeneralPurpose"); } uint8_t reqint = remaining_timers[i]; - Config cfg = { - .timer_idx = timer_idxmap[reqint], - .trgo1 = e.trgo1, - .trgo2 = e.trgo2 - }; + Config cfg = {.timer_idx = timer_idxmap[reqint], .trgo1 = e.trgo1, .trgo2 = e.trgo2}; cfgs[cfg_idx++] = cfg; }
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #665
Add ClockDomain, a centralised clock validator and applicator
Clock configuration is a precomputed
ClockTree(from a host tool or hand-written). The firmware validates it at compile time and applies it at runtime. No solver runs in the firmware.ClockTreestores only decisions (M/N/P/Q/R, prescalers, source enums); all frequencies are derived via accessors (sysclk(t),source_frequency(t, src), etc.)Board<>takes a mandatoryClockTreeas the second template parameterClockDomain::Devicewith typed models:SPIClockModel<Group, MaxBaud, MinBaud>,ADCClockModel<MaxADCCLK>,SDClockModel<MaxFreq, MinFreq>ClockDomain::build()validates PLL ranges, bus consistency, and peripheral requirements at compile time - refuses to compile on failureClockDomain::Init::init(tree)applies the validated tree to HAL registersHALconfigClock-tree solver was not implement in compile time because of the added complexity (worst cases were not possible to compile unless willing to let the compiler do billions of operations). The solver may be implement at a further date via a brute force function in the domain that only exists on simulator builds, such that you can build your project with the simulation preset, solve the clock-tree and print it to a header file (it could be added as a build step or as a standalone script).