From ff0bd87f4e5ba697891dac3cfa00966fdc06a378 Mon Sep 17 00:00:00 2001 From: James Cotton Date: Sat, 21 Jan 2012 09:07:06 -0600 Subject: [PATCH] PIOS SPI: Add a second claim bus method for use in ISR. This has no timeout and uses an ISR safe queue claiming method. This avoids deadlocks when ISR blocks other tasks from freeing the bus. --- flight/PiOS/STM32F4xx/pios_spi.c | 21 +++++++++++++++++++++ flight/PiOS/inc/pios_spi.h | 1 + 2 files changed, 22 insertions(+) diff --git a/flight/PiOS/STM32F4xx/pios_spi.c b/flight/PiOS/STM32F4xx/pios_spi.c index de1aa39a9..e030b6826 100644 --- a/flight/PiOS/STM32F4xx/pios_spi.c +++ b/flight/PiOS/STM32F4xx/pios_spi.c @@ -247,6 +247,27 @@ int32_t PIOS_SPI_ClaimBus(uint32_t spi_id) return 0; } +/** + * Claim the SPI bus semaphore from an ISR. Has no timeout. + * \param[in] spi SPI number (0 or 1) + * \return 0 if no error + * \return -1 if timeout before claiming semaphore + */ +int32_t PIOS_SPI_ClaimBusISR(uint32_t spi_id) +{ +#if defined(PIOS_INCLUDE_FREERTOS) + struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id; + + bool valid = PIOS_SPI_validate(spi_dev); + PIOS_Assert(valid) + + if (xQueueGenericReceive(( xQueueHandle ) spi_dev->busy, NULL, 0x0000 , pdFALSE ) != pdTRUE) + return -1; +#endif + return 0; +} + + /** * Release the SPI bus semaphore. Calling the SPI functions does not require this * \param[in] spi SPI number (0 or 1) diff --git a/flight/PiOS/inc/pios_spi.h b/flight/PiOS/inc/pios_spi.h index d5331848e..8147bd5d9 100644 --- a/flight/PiOS/inc/pios_spi.h +++ b/flight/PiOS/inc/pios_spi.h @@ -54,6 +54,7 @@ extern int32_t PIOS_SPI_TransferByte(uint32_t spi_id, uint8_t b); extern int32_t PIOS_SPI_TransferBlock(uint32_t spi_id, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len, void *callback); extern int32_t PIOS_SPI_Busy(uint32_t spi_id); extern int32_t PIOS_SPI_ClaimBus(uint32_t spi_id); +extern int32_t PIOS_SPI_ClaimBusISR(uint32_t spi_id); extern int32_t PIOS_SPI_ReleaseBus(uint32_t spi_id); extern void PIOS_SPI_IRQ_Handler(uint32_t spi_id); extern void PIOS_SPI_SetPrescalar(uint32_t spi_id, uint32_t prescalar);