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 /os/hal/src/spi.c | |
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
Diffstat (limited to 'os/hal/src/spi.c')
-rw-r--r-- | os/hal/src/spi.c | 65 |
1 files changed, 64 insertions, 1 deletions
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.
|