Skip to content

Commit f48d096

Browse files
WonderMrclaude
andcommitted
furi_hal_spi: fix same DMA timeout race in TRX/RX path
The TRX/RX branch (else of furi_hal_spi_bus_trx_dma) had the same race as the TX-only path fixed in b51e744: on timeout the cleanup released spi_dma_completed before disabling LL_DMA_DisableIT_TC, so a late or pending DMA completion ISR would call furi_semaphore_release() on an already-full binary semaphore and crash furi_check. Pre-existing bug, not introduced by this PR — fixed for symmetry with the TX-only path now that the pattern is documented. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b51e744 commit f48d096

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

targets/f7/furi_hal/furi_hal_spi.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,19 @@ bool furi_hal_spi_bus_trx_dma(
393393
ret = false;
394394
FURI_LOG_E(TAG, "DMA timeout\r\n");
395395
}
396-
// release semaphore, because we are using it as a flag
397-
furi_semaphore_release(spi_dma_completed);
398396

397+
// Disable TC IRQ and clear pending TC flag BEFORE releasing the
398+
// semaphore. On timeout the ISR may still fire and would try to
399+
// re-release the binary semaphore, crashing furi_check.
399400
LL_DMA_DisableIT_TC(SPI_DMA_RX_DEF);
401+
#if SPI_DMA_RX_CHANNEL == LL_DMA_CHANNEL_6
402+
LL_DMA_ClearFlag_TC6(SPI_DMA);
403+
#else
404+
#error Update this code. Would you kindly?
405+
#endif
406+
407+
// release semaphore, because we are using it as a flag
408+
furi_semaphore_release(spi_dma_completed);
400409

401410
LL_DMA_DisableChannel(SPI_DMA_TX_DEF);
402411
LL_DMA_DisableChannel(SPI_DMA_RX_DEF);

0 commit comments

Comments
 (0)