summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/spi.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c
index 3cd470ccb..2b5bdb038 100644
--- a/ports/stm32/spi.c
+++ b/ports/stm32/spi.c
@@ -404,11 +404,16 @@ void spi_deinit(SPI_HandleTypeDef *spi) {
}
STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t timeout) {
- // Note: we can't use WFI to idle in this loop because the DMA completion
- // interrupt may occur before the WFI. Hence we miss it and have to wait
- // until the next sys-tick (up to 1ms).
uint32_t start = HAL_GetTick();
- while (HAL_SPI_GetState(spi) != HAL_SPI_STATE_READY) {
+ for (;;) {
+ // Do an atomic check of the state; WFI will exit even if IRQs are disabled
+ uint32_t irq_state = disable_irq();
+ if (spi->State == HAL_SPI_STATE_READY) {
+ enable_irq(irq_state);
+ return HAL_OK;
+ }
+ __WFI();
+ enable_irq(irq_state);
if (HAL_GetTick() - start >= timeout) {
return HAL_TIMEOUT;
}