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
This commit is contained in:
gdisirio 2010-10-10 16:28:34 +00:00
parent 70ab312f0f
commit 1c9c405430
4 changed files with 86 additions and 2 deletions

View File

@ -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);

View File

@ -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.

View File

@ -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__)
/**

View File

@ -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)