stm32/spi: Make SPI DMA wait routine more power efficient by using WFI.
The routine waits for the DMA to finish, which is signalled from a DMA IRQ handler. Using WFI makes the CPU sleep while waiting for the IRQ to arrive which decreases power consumption. To make it work correctly the check for the change in state must be atomic and so IRQs must be disabled during the check. The key feature of the Cortex MCU that makes this possible is that WFI will exit when an IRQ arrives even if IRQs are disabled.
This commit is contained in:
parent
a44892dd0d
commit
c0496fd44d
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user