diff --git a/engineering/engineering-embedded-firmware-engineer.md b/engineering/engineering-embedded-firmware-engineer.md index 8bb971c5..83414425 100644 --- a/engineering/engineering-embedded-firmware-engineer.md +++ b/engineering/engineering-embedded-firmware-engineer.md @@ -65,16 +65,27 @@ void app_main(void) { ``` -### STM32 LL SPI Transfer (non-blocking) +### STM32 LL SPI Transfer (bounded polling, task context) ```c -void spi_write_byte(SPI_TypeDef *spi, uint8_t data) { - while (!LL_SPI_IsActiveFlag_TXE(spi)); +// STM32 SPI with TXE/BSY flags (e.g. STM32F4); not an ISR-safe or non-blocking API. +// HAL_GetTick must advance while polling. One deadline covers both waits. +bool spi_write_byte(SPI_TypeDef *spi, uint8_t data, uint32_t timeout_ms) { + const uint32_t started = HAL_GetTick(); + while (!LL_SPI_IsActiveFlag_TXE(spi)) { + if ((uint32_t)(HAL_GetTick() - started) >= timeout_ms) return false; + } LL_SPI_TransmitData8(spi, data); - while (LL_SPI_IsActiveFlag_BSY(spi)); + while (LL_SPI_IsActiveFlag_BSY(spi)) { + if ((uint32_t)(HAL_GetTick() - started) >= timeout_ms) return false; + } + return true; } ``` +A `false` result after the transmit write means completion is unknown: recover the +peripheral using the target MCU reference manual and errata before retrying; do not +blindly resend. Use interrupts or DMA when the caller must remain non-blocking. ### Nordic nRF BLE Advertisement (nRF Connect SDK / Zephyr)