From 1c9c40543009ecd95b56362e6564d26a2755b92a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 10 Oct 2010 16:28:34 +0000 Subject: [PATCH] Fixed bug 3084764. More enhancements to the SPI driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2244 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/spi.h | 15 ++++++++- os/hal/src/spi.c | 65 +++++++++++++++++++++++++++++++++++++- os/hal/templates/spi_lld.h | 6 ++++ readme.txt | 2 ++ 4 files changed, 86 insertions(+), 2 deletions(-) diff --git a/os/hal/include/spi.h b/os/hal/include/spi.h index b09e33089..e6fbe7c90 100644 --- a/os/hal/include/spi.h +++ b/os/hal/include/spi.h @@ -39,7 +39,16 @@ /*===========================================================================*/ /** - * @brief Enables the mutual exclusion APIs on the SPI bus. + * @brief Enables the @p spiWait() API. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. */ #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) #define SPI_USE_MUTUAL_EXCLUSION TRUE @@ -218,6 +227,10 @@ extern "C" { void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf); void spiSend(SPIDriver *spip, size_t n, const void *txbuf); void spiReceive(SPIDriver *spip, size_t n, void *rxbuf); +#if SPI_USE_WAIT + void _spi_wakeup(SPIDriver *spip, mag_t msg); + msg_t spiWait(SPIDriver *spip); +#endif /* SPI_USE_WAIT */ #if SPI_USE_MUTUAL_EXCLUSION void spiAcquireBus(SPIDriver *spip); void spiReleaseBus(SPIDriver *spip); diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c index cd5857aa9..75589c736 100644 --- a/os/hal/src/spi.c +++ b/os/hal/src/spi.c @@ -66,11 +66,16 @@ void spiInit(void) { void spiObjectInit(SPIDriver *spip) { spip->spd_state = SPI_STOP; +#if SPI_USE_WAIT + spip->spd_thread = NULL; +#endif /* SPI_USE_WAIT */ +#if SPI_USE_MUTUAL_EXCLUSION #if CH_USE_MUTEXES chMtxInit(&spip->spd_mutex); -#elif CH_USE_SEMAPHORES +#else chSemInit(&spip->spd_semaphore, 1); #endif +#endif /* SPI_USE_MUTUAL_EXCLUSION */ spip->spd_config = NULL; } @@ -296,6 +301,64 @@ void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) { chSysUnlock(); } +#if SPI_USE_WAIT || defined(__DOXYGEN__) +/** + * @brief Awakens the thread waiting for operation completion, if any. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void _spi_wakeup(SPIDriver *spip) { + + if (spip->spd_thread != NULL) { + Thread *tp = spip->spd_thread; + spip->spd_thread = NULL; + tp->p_u.rdymsg = RDY_RESET; + chSchReadyI(tp); + } +} + +/** + * @brief Wait for operation completion. + * @details This function waits for the driver to complete the current + * operation, if an operation is not running when the function is + * invoked then it immediately returns. + * @note No more than one thread can wait on a SPI driver using + * this function. + * + * @param[in] spip pointer to the @p SPIDriver object + * @return The wait status. + * @retval RDY_OK There was not operation running when the function + * has been invoked. + * @retval RDY_RESET The operation completed. + */ +msg_t spiWait(SPIDriver *spip) { + msg_t msg; + + chDbgCheck(spip != NULL, "spiWait"); + + chSysLock(); + chDbgAssert((spip->spd_state == SPI_READY) || + (spip->spd_state == SPI_SELECTED) || + (spip->spd_state == SPI_ACTIVE) || + (spip->spd_state == SPI_SYNC), + "spiUnselect(), #1", + "invalid state"); + chDbgAssert(spip->spd_thread == NULL, "spiWait(), #3", "already waiting"); + if ((spip->spd_state == SPI_ACTIVE) || (spip->spd_state == SPI_SYNC)) { + spip->spd_thread = chThdSelf(); + chSchGoSleepS(spip->spd_thread, THD_STATE_SUSPENDED); + msg = chThdSelf()->p_u.rdymsg; + } + else + msg = RDY_OK; + chSysUnlock(); + return msg; +} + +#endif /* SPI_USE_WAIT */ + #if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) /** * @brief Gains exclusive access to the SPI bus. diff --git a/os/hal/templates/spi_lld.h b/os/hal/templates/spi_lld.h index 152784701..2aa63b455 100644 --- a/os/hal/templates/spi_lld.h +++ b/os/hal/templates/spi_lld.h @@ -77,6 +77,12 @@ typedef struct { * @brief Driver state. */ spistate_t spd_state; +#if SPI_USE_WAIT || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + Thread *spd_thread; +#endif /* SPI_USE_WAIT */ #if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) #if CH_USE_MUTEXES || defined(__DOXYGEN__) /** diff --git a/readme.txt b/readme.txt index 5fcc39c0d..b5304e069 100644 --- a/readme.txt +++ b/readme.txt @@ -63,6 +63,8 @@ ***************************************************************************** *** 2.1.2 *** +- FIX: Fixed non functioning option SPI_USE_MUTUAL_EXCLUSION=FALSE (bug + 3084764)(backported to 2.0.6). - FIX: Fixed wrong macro check in STM32 serial support (bug 3078891)(backported to 2.0.6). - FIX: Fixed non functioning option CH_USE_NESTED_LOCKS (bug 3075544)