diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2010-10-10 16:28:34 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2010-10-10 16:28:34 +0000 |
commit | 1c9c40543009ecd95b56362e6564d26a2755b92a (patch) | |
tree | 208f9e85f725d1daec144fb8c06c3ae265255626 | |
parent | 70ab312f0f88f24cf1e4f33218cff877c6c0b3c2 (diff) | |
download | ChibiOS-1c9c40543009ecd95b56362e6564d26a2755b92a.tar.gz ChibiOS-1c9c40543009ecd95b56362e6564d26a2755b92a.tar.bz2 ChibiOS-1c9c40543009ecd95b56362e6564d26a2755b92a.zip |
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
-rw-r--r-- | os/hal/include/spi.h | 15 | ||||
-rw-r--r-- | os/hal/src/spi.c | 65 | ||||
-rw-r--r-- | os/hal/templates/spi_lld.h | 6 | ||||
-rw-r--r-- | 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)
|