Conversation
…es of the DMA without removing double entries with the dfsdm.
…st in my test has worked fine.
* Fixed copy pointers leading with possible missalignment * fix(tcp): handle fragmented order streams and queue backpressure * fix(server): own and recycle ServerSocket instances safely * fix(udp): harden DatagramSocket lifecycle and pbuf parsing * fix(lwip): align ICMP checksum settings with hw offload * fix(net): harden socket teardown and unify TCP order parsing * Applied formatter * perf(net): benchmark-driven TCP TX fast path * feat(error): decouple transport from legacy update * Modified warning to decouple from protections * Better timestamp in error and warning * Protection manager more robust * Always enqueuing msgs even when there are no sockets * sorry, I forgot one file * SNTP set * minor fix on protections * Being able to compile without ehternet * formatter
* Prescaler was not initialized in init * formatting: Remove spaces * formatting * hardened a lot the encoder, being sure that instances are properly set * minor fix, not setting properly the encoder start * added tests for the encoder * reverted nullptr checks, and made builder private * applied formatter * Make constructors private in Encoder, PWM, DualPWM * applied formatter * fixed merge mess --------- Co-authored-by: Víctor López <120128034+victor-Lopez25@users.noreply.github.com> Co-authored-by: Jorge Sáez <jorgeesg82@gmail.com>
* Scheduler now "reserves" a timer from timerdomain * Also remove possibility of getting scheduler timer from bits32_timers * stupid change to get precommit to work (?) * fix formatting (?) * more format fix * fix segfault in tests (?) * fix formatting * move Scheduler_global_timer in scheduler_test.cpp
* Fixed issues with MSVC on windows * Move implementation into cpp * Return to inlining clz and ctz * fix formatting (hopefully) * more formatting fixes * fix formatting final please
* Fix: rcc_enable_timer for scheduler timer * formatting nº1
* No more fixed_vector(idk why I did that) * First version implementing std::tupple * No more copy constructor bullshit * Equal operator fixed, now it compiles * Compiling version, tests to be done * Okay now we check for duplicates * Some formating changes * Clanker made me do this so the start and exit functions stop when the condition is true * Made nesting consteval * Fix short circuit no use on return warning * Added state machine tests * Formating errors fixed * Ok now format errors are fixed * More tests need to be addes * Compile testing added, as well as reduced task array to only allow 16 task * Formating errores fixed * Delete tests for the tests * Now you cant use state machine without start * Fixed logic for nested machine start * Formating error fix * clanker commit Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Now we use a concept for a correct tuple in state machine helper function * Formating fix --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Max ARR * fix encoder test * actually fix tests now * fix formatting
* chore(release): add semver foundation and tooling * ci(release): require changesets on pull requests * ci(release): automate release preparation and publishing * chore(release): add bootstrap changeset for release infra * fix(release): address Copilot review feedback
|
@claude review |
ST-LIB Release Plan
Pending changes
|
There was a problem hiding this comment.
Pull request overview
This PR adds a new DFSDM (Digital Filter for Sigma-Delta Modulators) service/domain and wires it into the ST-LIB board build/init pipeline (including DMA integration and IRQ handlers), plus supporting updates to timer trigger configuration and mocks.
Changes:
- Introduces
DFSDM_CHANNEL_DOMAINandDFSDM_CLK_DOMAIN, plus DFSDM IRQ handlers and build-time DMA contributions. - Extends DMA + mocked HAL definitions to support DFSDM filter DMA requests and richer TIM TRGO/TRGO2 options.
- Minor build/tooling updates (Linux STM32CubeCLT path globbing, small formatting cleanup, changeset entry).
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| toolchains/stm32.cmake | Makes Linux STM32CubeCLT discovery more case-insensitive via glob patterns. |
| Src/HALAL/Services/DFSDM/DFSDM.cpp | Adds DFSDM filter IRQ handlers that forward to DFSDM domain IRQ dispatcher. |
| Inc/HALAL/Services/DFSDM/DFSDM.hpp | New DFSDM domains: config/build logic, DMA contribution helpers, runtime instances, and IRQ dispatch. |
| Inc/ST-LIB_LOW/ST-LIB_LOW.hpp | Exposes DFSDM header through the low-level umbrella include. |
| Inc/ST-LIB.hpp | Registers DFSDM domains in DomainsCtx, adds DFSDM config building, DMA merging, and init wiring. |
| Inc/MockedDrivers/stm32h7xx_hal_mock.h | Adds DFSDM DMA request IDs and expands TIM TRGO/TRGO2 constants for simulation. |
| Inc/HALAL/Services/ADC/ADC.hpp | Constructor formatting change only. |
| Inc/HALAL/Models/TimerDomain/TimerDomain.hpp | Adds TRGO/TRGO2 selection to timer entries/configs and applies master sync configuration. |
| Inc/HALAL/Models/Pin.hpp | Updates pin metadata bitfields for several pins used by DFSDM/timers. |
| Inc/HALAL/Models/DMA/DMA2.hpp | Adds DFSDM DMA peripherals and request mapping; tweaks alignment handling for DFSDM. |
| Inc/HALAL/HALAL.hpp | Includes DFSDM service header in HALAL umbrella. |
| CMakeLists.txt | Adds DFSDM.cpp to the HALAL source list. |
| .changesets/dfsdm-module-minor.md | Declares a minor release changeset for DFSDM addition. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (isr & (channels_enabled << DFSDM_FLTICR_CLRSCDF_Pos)) { | ||
| uint32_t ch = __builtin_ctz(isr & DFSDM_FLTISR_SCDF_Msk) >> DFSDM_FLTISR_SCDF_Pos; | ||
| if (channel_instances[ch] != nullptr && | ||
| channel_instances[ch]->short_circuit_cb != nullptr) | ||
| channel_instances[ch]->short_circuit_cb(); |
There was a problem hiding this comment.
Short-circuit IRQ decoding uses __builtin_ctz(masked) >> DFSDM_FLTISR_SCDF_Pos, but ctz returns a bit index, so shifting will not yield the channel number (it should be adjusted by subtracting the field position, or by shifting the masked value down first). As written, callbacks may fire for the wrong channel.
| if (isr & (channels_enabled << DFSDM_FLTISR_CKABF_Pos)) { | ||
| uint32_t ch = __builtin_ctz(isr & DFSDM_FLTISR_CKABF_Msk) >> DFSDM_FLTISR_CKABF_Pos; | ||
| if (channel_instances[ch] != nullptr && | ||
| channel_instances[ch]->clock_absence_cb != nullptr) | ||
| channel_instances[ch]->clock_absence_cb(); |
There was a problem hiding this comment.
Clock-absence IRQ decoding has the same issue as short-circuit: __builtin_ctz(masked) >> DFSDM_FLTISR_CKABF_Pos does not compute the channel index correctly from a positioned bitfield. This can dispatch clock_absence_cb on the wrong channel; shift the bitfield down or subtract the position from the ctz result.
| .trgo1 = requests[i].trgo1, | ||
| .trgo2 = requests[i].trgo2 |
There was a problem hiding this comment.
In TimerDomain::build(), the AnyGeneralPurpose allocation loop sets trgo1/trgo2 from requests[i] even though it picks the request via remaining_requests[i] (const Entry& e = requests[remaining_requests[i]]). This can assign triggers from the wrong timer request; use e.trgo1/e.trgo2 instead.
| .trgo1 = requests[i].trgo1, | |
| .trgo2 = requests[i].trgo2 | |
| .trgo1 = e.trgo1, | |
| .trgo2 = e.trgo2 |
| } | ||
| // check that dma buffer size is 1 if there is more than one channel per filter and add the | ||
| // buffer_pos_ini to every channel | ||
| std::array<std::array<uint8_t, 8>, 4> channels_filter = {}; |
There was a problem hiding this comment.
channels_filter stores cfgs[i].buffer_size into a uint8_t matrix. Since buffer_size is size_t, values >255 will truncate, which can break the active_channels and > 1 validation logic. Use a wider element type (e.g., std::size_t/uint16_t) for channels_filter.
| std::array<std::array<uint8_t, 8>, 4> channels_filter = {}; | |
| std::array<std::array<std::size_t, 8>, 4> channels_filter = {}; |
| if (isr & DFSDM_FLTISR_JEOCF_Msk) { | ||
| // Save it in the address provide by the user | ||
| int32_t data = filter->FLTJDATAR; | ||
| uint8_t channel = (data & DFSDM_FLTJDATAR_JDATACH_Msk); |
There was a problem hiding this comment.
In the JEOCF IRQ path, channel is extracted as (data & DFSDM_FLTJDATAR_JDATACH_Msk) but never shifted by DFSDM_FLTJDATAR_JDATACH_Pos. This will index channel_instances with the raw masked bits rather than the channel number. Extract the field the same way as the regular path (mask then shift).
| uint8_t channel = (data & DFSDM_FLTJDATAR_JDATACH_Msk); | |
| uint8_t channel = (data & DFSDM_FLTJDATAR_JDATACH_Msk) >> DFSDM_FLTJDATAR_JDATACH_Pos; |
| __attribute__((section(".mpu_ram_d1_nc.buffer"))) alignas(32 | ||
| ) static inline int32_t DFSDM_Buffer_Pool[MAX_BUFFER_SIZE_TOTAL]; |
There was a problem hiding this comment.
DFSDM_Buffer_Pool reserves MAX_BUFFER_SIZE_TOTAL int32s in the D1 non-cached section but is never referenced anywhere in this header. On embedded targets this is a permanent RAM cost; remove it or wire it into the actual buffering strategy.
| __attribute__((section(".mpu_ram_d1_nc.buffer"))) alignas(32 | |
| ) static inline int32_t DFSDM_Buffer_Pool[MAX_BUFFER_SIZE_TOTAL]; |
| static void handle_irq(uint8_t filter_index) { | ||
|
|
||
| DFSDM_Filter_TypeDef* filter = filter_hw[filter_index]; | ||
|
|
||
| uint32_t isr = filter->FLTISR; | ||
|
|
There was a problem hiding this comment.
The DFSDM module introduces substantial new logic (compile-time config building, DMA contributions, and IRQ dispatch in handle_irq) but there are no corresponding unit tests under Tests/ (the repo already uses googletest for ADC/DMA/SPI). Adding at least a simulation test covering config validation and IRQ channel decoding would help prevent regressions.
| .trgo1 = requests[i].trgo1, | ||
| .trgo2 = requests[i].trgo2 |
There was a problem hiding this comment.
In TimerDomain::build(), when allocating Any32bit requests you compute const Entry& e = requests[remaining_requests[i]] but the config copies trgo1/trgo2 from requests[i] instead of e. This will misconfigure triggers whenever remaining_requests[i] != i; use the selected entry (e.trgo1/e.trgo2).
| .trgo1 = requests[i].trgo1, | |
| .trgo2 = requests[i].trgo2 | |
| .trgo1 = e.trgo1, | |
| .trgo2 = e.trgo2 |
| } | ||
| cfg.buffer_pos_ini = buffer_pos[cfg.filter]; | ||
| buffer_pos[cfg.filter] += cfg.buffer_size; |
There was a problem hiding this comment.
buffer_pos_ini is set to 0 for regular conversions, but then it is immediately overwritten unconditionally with buffer_pos[cfg.filter]. This defeats the intent of giving regular conversions the whole buffer starting at 0. Make the second assignment conditional (e.g., else) or otherwise preserve the regular-mode behavior.
| } | |
| cfg.buffer_pos_ini = buffer_pos[cfg.filter]; | |
| buffer_pos[cfg.filter] += cfg.buffer_size; | |
| // Keep buffer_pos in sync, even though multiple regular channels per filter | |
| // are not allowed by earlier validation. | |
| buffer_pos[cfg.filter] += cfg.buffer_size; | |
| } else { | |
| cfg.buffer_pos_ini = buffer_pos[cfg.filter]; | |
| buffer_pos[cfg.filter] += cfg.buffer_size; | |
| } |
| filter->FLTICR |= DFSDM_FLTICR_CLRROVRF_Msk; | ||
| } | ||
| if (isr & DFSDM_FLTISR_JOVRF_Msk) { | ||
| Instance* inst = channel_instances[filter->FLTJDATAR & DFSDM_FLTJDATAR_JDATACH_Msk]; |
There was a problem hiding this comment.
In the JOVRF handler, filter->FLTJDATAR & DFSDM_FLTJDATAR_JDATACH_Msk is used directly as an index into channel_instances[] without shifting. Like the JEOCF path, this should be mask+shift to obtain the channel number before indexing.
| Instance* inst = channel_instances[filter->FLTJDATAR & DFSDM_FLTJDATAR_JDATACH_Msk]; | |
| uint32_t jdata = filter->FLTJDATAR; | |
| uint8_t channel = (jdata & DFSDM_FLTJDATAR_JDATACH_Msk) >> DFSDM_FLTJDATAR_JDATACH_Pos; | |
| Instance* inst = channel_instances[channel]; |
DFSDM module finished and tested. Only missing try in the hyperNucleo