Skip to content

drivers: fix DMA request disable ordering in timer IRQ handlers and stop functions#11589

Open
sensei-hacker wants to merge 1 commit into
iNavFlight:maintenance-9.xfrom
sensei-hacker:fix/dma-disable-ordering-stdperiph
Open

drivers: fix DMA request disable ordering in timer IRQ handlers and stop functions#11589
sensei-hacker wants to merge 1 commit into
iNavFlight:maintenance-9.xfrom
sensei-hacker:fix/dma-disable-ordering-stdperiph

Conversation

@sensei-hacker
Copy link
Copy Markdown
Member

Summary

Fixes incorrect DMA stream disable ordering in timer_impl_stdperiph.c, timer_impl_stdperiph_at32.c, and timer_impl_hal.c.

STM32 Reference Manual (RM0090 §10.3.17) requires disabling the timer DMA request first, then the DMA stream. Five locations had this backwards, creating a race window where the timer peripheral could issue a DMA request to an already-disabled stream via the hardware DMA request line (which bypasses CPU interrupts and operates even inside an ATOMIC_BLOCK).

Changes

timer_impl_stdperiph.c (3 sites):

  • impl_timerPWMStopDMA — swapped disable order
  • impl_timerPWMPrepareDMA — swapped disable order inside ATOMIC_BLOCK
  • DMA TC IRQ handler — swapped disable order

timer_impl_stdperiph_at32.c (1 site):

  • impl_timerPWMStopDMA — swapped dma_channel_enable/tmr_dma_request_enable order

timer_impl_hal.c (1 site):

  • DMA TC IRQ handler — swapped LL_DMA_DisableStream/LL_TIM_DisableDMAReq_CCx order

The correct ordering was already present in impl_timerPWMSetDMACircular (both stdperiph files, added in #11260) and impl_timerPWMStopDMA (HAL file), which serve as the reference implementation.

Testing

  • Built AIKONF4V3 (STM32F4/stdperiph) — clean build, no warnings in changed files
  • Built MATEKF405 (STM32F4/stdperiph) — clean build
  • Flashed AIKONF4V3 and verified FC boots and responds normally
  • Ran 3000-iteration disarmed DShot DMA stress test before and after — stable latency, zero MSP timeouts in both runs; no regressions observed

Code Review

Reviewed for ISR safety, ordering correctness against RM0090 §10.3.17, and consistency with reference implementations.

…top functions

STM32 RM (RM0090 §10.3.17) requires disabling the timer DMA request
before disabling the DMA stream. The previous code had this backwards
in five places across three driver files, creating a race window where
the timer could issue a DMA request to an already-disabled stream.

The incorrect ordering:
  DMA_Cmd(stream, DISABLE);          // stream disabled first
  TIM_DMACmd(tim, source, DISABLE);  // timer request disabled second

Corrected ordering:
  TIM_DMACmd(tim, source, DISABLE);  // timer request disabled first
  DMA_Cmd(stream, DISABLE);          // stream disabled second

Affected locations:
- timer_impl_stdperiph.c: impl_timerPWMStopDMA, impl_timerPWMPrepareDMA,
  DMA TC IRQ handler
- timer_impl_stdperiph_at32.c: impl_timerPWMStopDMA
- timer_impl_hal.c: DMA TC IRQ handler

The correct ordering was already used in impl_timerPWMSetDMACircular
(both stdperiph files) and impl_timerPWMStopDMA (HAL file), which
serve as the reference implementation.
@qodo-code-review
Copy link
Copy Markdown
Contributor

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@github-actions
Copy link
Copy Markdown

Test firmware build ready — commit fc432d9

Download firmware for PR #11589

237 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant