From 935e2fb27f56a3b81d4161d65e116e9da4fe441c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 12 Oct 2010 15:19:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2250 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/adc.c | 207 +++++++++++++++++++++++---------------------- os/hal/src/mmc_spi.c | 30 +++---- os/hal/src/spi.c | 234 +++++++++++++++------------------------------------ 3 files changed, 189 insertions(+), 282 deletions(-) (limited to 'os/hal/src') diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c index 1d407d927..0d33cde4e 100644 --- a/os/hal/src/adc.c +++ b/os/hal/src/adc.c @@ -71,7 +71,17 @@ void adcObjectInit(ADCDriver *adcp) { adcp->ad_depth = 0; adcp->ad_grpp = NULL; #if ADC_USE_WAIT - chSemInit(&adcp->ad_sem, 0); + adcp->ad_thread = NULL; +#endif /* ADC_USE_WAIT */ +#if ADC_USE_MUTUAL_EXCLUSION +#if CH_USE_MUTEXES + chMtxInit(&adcp->ad_mutex); +#else + chSemInit(&adcp->ad_semaphore, 1); +#endif +#endif /* ADC_USE_MUTUAL_EXCLUSION */ +#if defined(ADC_DRIVER_EXT_INIT_HOOK) + ADC_DRIVER_EXT_INIT_HOOK(adcp); #endif } @@ -89,8 +99,7 @@ void adcStart(ADCDriver *adcp, const ADCConfig *config) { chSysLock(); chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY), - "adcStart(), #1", - "invalid state"); + "adcStart(), #1", "invalid state"); adcp->ad_config = config; adc_lld_start(adcp); adcp->ad_state = ADC_READY; @@ -110,8 +119,7 @@ void adcStop(ADCDriver *adcp) { chSysLock(); chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY), - "adcStop(), #1", - "invalid state"); + "adcStop(), #1", "invalid state"); adc_lld_stop(adcp); adcp->ad_state = ADC_STOP; chSysUnlock(); @@ -119,18 +127,7 @@ void adcStop(ADCDriver *adcp) { /** * @brief Starts an ADC conversion. - * @details Starts a conversion operation, there are two kind of conversion - * modes: - * - LINEAR, in this mode the buffer is filled once and then - * the conversion stops automatically. - * - CIRCULAR, in this mode the conversion never stops and - * the buffer is filled circularly.
- * During the conversion the callback function is invoked when - * the buffer is 50% filled and when the buffer is 100% filled, - * this way is possible to process the conversion stream in real - * time. This kind of conversion can only be stopped by explicitly - * invoking @p adcStopConversion(). - * . + * @details Starts an asynchronous conversion operation. * @note The buffer is organized as a matrix of M*N elements where M is the * channels number configured into the conversion group and N is the * buffer depth. The samples are sequentially written into the buffer @@ -141,38 +138,22 @@ void adcStop(ADCDriver *adcp) { * @param[out] samples pointer to the samples buffer * @param[in] depth buffer depth (matrix rows number). The buffer depth * must be one or an even number. - * @return The operation status. - * @retval FALSE the conversion has been started. - * @retval TRUE the driver is busy, conversion not started. * * @api */ -bool_t adcStartConversion(ADCDriver *adcp, - const ADCConversionGroup *grpp, - adcsample_t *samples, - size_t depth) { - bool_t result; +void adcStartConversion(ADCDriver *adcp, + const ADCConversionGroup *grpp, + adcsample_t *samples, + size_t depth) { chSysLock(); - result = adcStartConversionI(adcp, grpp, samples, depth); + adcStartConversionI(adcp, grpp, samples, depth); chSysUnlock(); - return result; } /** * @brief Starts an ADC conversion. - * @details Starts a conversion operation, there are two kind of conversion - * modes: - * - LINEAR, in this mode the buffer is filled once and then - * the conversion stops automatically. - * - CIRCULAR, in this mode the conversion never stops and - * the buffer is filled circularly.
- * During the conversion the callback function is invoked when - * the buffer is 50% filled and when the buffer is 100% filled, - * this way is possible to process the conversion stream in real - * time. This kind of conversion can only be stopped by explicitly - * invoking @p adcStopConversion(). - * . + * @details Starts an asynchronous conversion operation. * @note The buffer is organized as a matrix of M*N elements where M is the * channels number configured into the conversion group and N is the * buffer depth. The samples are sequentially written into the buffer @@ -183,34 +164,25 @@ bool_t adcStartConversion(ADCDriver *adcp, * @param[out] samples pointer to the samples buffer * @param[in] depth buffer depth (matrix rows number). The buffer depth * must be one or an even number. - * @return The operation status. - * @retval FALSE the conversion has been started. - * @retval TRUE the driver is busy, conversion not started. * * @iclass */ -bool_t adcStartConversionI(ADCDriver *adcp, - const ADCConversionGroup *grpp, - adcsample_t *samples, - size_t depth) { +void adcStartConversionI(ADCDriver *adcp, + const ADCConversionGroup *grpp, + adcsample_t *samples, + size_t depth) { chDbgCheck((adcp != NULL) && (grpp != NULL) && (samples != NULL) && ((depth == 1) || ((depth & 1) == 0)), "adcStartConversionI"); - chDbgAssert((adcp->ad_state == ADC_READY) || - (adcp->ad_state == ADC_RUNNING) || - (adcp->ad_state == ADC_COMPLETE), - "adcStartConversionI(), #1", - "invalid state"); - if (adcp->ad_state == ADC_RUNNING) - return TRUE; + chDbgAssert(adcp->ad_state == ADC_READY, + "adcStartConversionI(), #1", "not ready"); adcp->ad_samples = samples; adcp->ad_depth = depth; adcp->ad_grpp = grpp; + adcp->ad_state = ADC_ACTIVE; adc_lld_start_conversion(adcp); - adcp->ad_state = ADC_RUNNING; - return FALSE; } /** @@ -229,21 +201,15 @@ void adcStopConversion(ADCDriver *adcp) { chSysLock(); chDbgAssert((adcp->ad_state == ADC_READY) || - (adcp->ad_state == ADC_RUNNING) || + (adcp->ad_state == ADC_ACTIVE) || (adcp->ad_state == ADC_COMPLETE), - "adcStopConversion(), #1", - "invalid state"); - if (adcp->ad_state == ADC_RUNNING) { + "adcStopConversion(), #1", "invalid state"); + if (adcp->ad_state != ADC_READY) { adc_lld_stop_conversion(adcp); adcp->ad_grpp = NULL; adcp->ad_state = ADC_READY; -#if ADC_USE_WAIT - chSemResetI(&adcp->ad_sem, 0); - chSchRescheduleS(); -#endif + _adc_reset_s(adcp); } - else - adcp->ad_state = ADC_READY; chSysUnlock(); } @@ -262,61 +228,102 @@ void adcStopConversionI(ADCDriver *adcp) { chDbgCheck(adcp != NULL, "adcStopConversionI"); chDbgAssert((adcp->ad_state == ADC_READY) || - (adcp->ad_state == ADC_RUNNING) || + (adcp->ad_state == ADC_ACTIVE) || (adcp->ad_state == ADC_COMPLETE), - "adcStopConversionI(), #1", - "invalid state"); - if (adcp->ad_state == ADC_RUNNING) { + "adcStopConversionI(), #1", "invalid state"); + if (adcp->ad_state != ADC_READY) { adc_lld_stop_conversion(adcp); adcp->ad_grpp = NULL; adcp->ad_state = ADC_READY; -#if ADC_USE_WAIT - chSemResetI(&adcp->ad_sem, 0); -#endif + _adc_reset_i(adcp); } - else - adcp->ad_state = ADC_READY; } #if ADC_USE_WAIT || defined(__DOXYGEN__) /** - * @brief Waits for completion. - * @details If the conversion is not completed or not yet started then the - * invoking thread waits for a conversion completion event. - * @pre In order to use this function the option @p ADC_USE_WAIT must be - * enabled. + * @brief Performs an ADC conversion. + * @details Performs a synchronous conversion operation. + * @note The buffer is organized as a matrix of M*N elements where M is the + * channels number configured into the conversion group and N is the + * buffer depth. The samples are sequentially written into the buffer + * with no gaps. * * @param[in] adcp pointer to the @p ADCDriver object - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . + * @param[in] grpp pointer to a @p ADCConversionGroup object + * @param[out] samples pointer to the samples buffer + * @param[in] depth buffer depth (matrix rows number). The buffer depth + * must be one or an even number. * @return The operation result. - * @retval RDY_OK conversion finished. - * @retval RDY_TIMEOUT conversion not finished within the specified time. + * @retval RDY_OK Conversion finished. + * @retval RDY_RESET The conversion has been stopped using + * @p acdStopConversion() or @p acdStopConversionI(), + * the result buffer may contain incorrect data. * - * @init + * @api */ -msg_t adcWaitConversion(ADCDriver *adcp, systime_t timeout) { +msg_t adcConvert(ADCDriver *adcp, + const ADCConversionGroup *grpp, + adcsample_t *samples, + size_t depth) { + msg_t msg; chSysLock(); - chDbgAssert((adcp->ad_state == ADC_READY) || - (adcp->ad_state == ADC_RUNNING) || - (adcp->ad_state == ADC_COMPLETE), - "adcWaitConversion(), #1", - "invalid state"); - if (adcp->ad_state != ADC_COMPLETE) { - if (chSemWaitTimeoutS(&adcp->ad_sem, timeout) == RDY_TIMEOUT) { - chSysUnlock(); - return RDY_TIMEOUT; - } - } + chDbgAssert(adcp->ad_config->ac_endcb == NULL, + "adcConvert(), #1", "has callback"); + adcStartConversionI(adcp, grpp, samples, depth); + (adcp)->ad_thread = chThdSelf(); + chSchGoSleepS(THD_STATE_SUSPENDED); + msg = chThdSelf()->p_u.rdymsg; chSysUnlock(); - return RDY_OK; + return msg; } #endif /* ADC_USE_WAIT */ +#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) +/** + * @brief Gains exclusive access to the ADC peripheral. + * @details This function tries to gain ownership to the ADC bus, if the bus + * is already being used then the invoking thread is queued. + * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION + * must be enabled. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @api + */ +void adcAcquireBus(ADCDriver *adcp) { + + chDbgCheck(adcp != NULL, "adcAcquireBus"); + +#if CH_USE_MUTEXES + chMtxLock(&adcp->ad_mutex); +#elif CH_USE_SEMAPHORES + chSemWait(&adcp->ad_semaphore); +#endif +} + +/** + * @brief Releases exclusive access to the ADC peripheral. + * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION + * must be enabled. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @api + */ +void adcReleaseBus(ADCDriver *adcp) { + + chDbgCheck(adcp != NULL, "adcReleaseBus"); + +#if CH_USE_MUTEXES + (void)adcp; + chMtxUnlock(); +#elif CH_USE_SEMAPHORES + chSemSignal(&adcp->ad_semaphore); +#endif +} +#endif /* ADC_USE_MUTUAL_EXCLUSION */ + #endif /* CH_HAL_USE_ADC */ /** @} */ diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c index 76b710a03..49f75c3cc 100644 --- a/os/hal/src/mmc_spi.c +++ b/os/hal/src/mmc_spi.c @@ -84,13 +84,13 @@ static void wait(MMCDriver *mmcp) { uint8_t buf[4]; for (i = 0; i < 16; i++) { - spiReceiveWait(mmcp->mmc_spip, 1, buf); + spiReceive(mmcp->mmc_spip, 1, buf); if (buf[0] == 0xFF) break; } /* Looks like it is a long wait.*/ while (TRUE) { - spiReceiveWait(mmcp->mmc_spip, 1, buf); + spiReceive(mmcp->mmc_spip, 1, buf); if (buf[0] == 0xFF) break; #ifdef MMC_NICE_WAITING @@ -121,7 +121,7 @@ static void send_hdr(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) { buf[3] = arg >> 8; buf[4] = arg; buf[5] = 0x95; /* Valid for CMD0 ignored by other commands. */ - spiSendWait(mmcp->mmc_spip, 6, buf); + spiSend(mmcp->mmc_spip, 6, buf); } /** @@ -138,7 +138,7 @@ static uint8_t recvr1(MMCDriver *mmcp) { uint8_t r1[1]; for (i = 0; i < 9; i++) { - spiReceiveWait(mmcp->mmc_spip, 1, r1); + spiReceive(mmcp->mmc_spip, 1, r1); if (r1[0] != 0xFF) return r1[0]; } @@ -178,7 +178,7 @@ static void sync(MMCDriver *mmcp) { spiSelect(mmcp->mmc_spip); while (TRUE) { - spiReceiveWait(mmcp->mmc_spip, 1, buf); + spiReceive(mmcp->mmc_spip, 1, buf); if (buf[0] == 0xFF) break; #ifdef MMC_NICE_WAITING @@ -306,7 +306,7 @@ bool_t mmcConnect(MMCDriver *mmcp) { if (mmcp->mmc_state == MMC_INSERTED) { /* Slow clock mode and 128 clock pulses.*/ spiStart(mmcp->mmc_spip, mmcp->mmc_lscfg); - spiSynchronizeWait(mmcp->mmc_spip, 16); + spiIgnore(mmcp->mmc_spip, 16); /* SPI mode selection.*/ i = 0; @@ -453,11 +453,11 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) { chSysUnlock(); for (i = 0; i < MMC_WAIT_DATA; i++) { - spiReceiveWait(mmcp->mmc_spip, 1, buffer); + spiReceive(mmcp->mmc_spip, 1, buffer); if (buffer[0] == 0xFE) { - spiReceiveWait(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer); + spiReceive(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer); /* CRC ignored. */ - spiIgnoreWait(mmcp->mmc_spip, 2); + spiIgnore(mmcp->mmc_spip, 2); return FALSE; } } @@ -493,7 +493,7 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) { } chSysUnlock(); - spiSendWait(mmcp->mmc_spip, sizeof(stopcmd), stopcmd); + spiSend(mmcp->mmc_spip, sizeof(stopcmd), stopcmd); /* result = recvr1(mmcp) != 0x00;*/ /* Note, ignored r1 response, it can be not zero, unknown issue.*/ recvr1(mmcp); @@ -568,10 +568,10 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) { } chSysUnlock(); - spiSendWait(mmcp->mmc_spip, sizeof(start), start); /* Data prologue. */ - spiSendWait(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer); /* Data. */ - spiIgnoreWait(mmcp->mmc_spip, 2); /* CRC ignored. */ - spiReceiveWait(mmcp->mmc_spip, 1, b); + spiSend(mmcp->mmc_spip, sizeof(start), start); /* Data prologue. */ + spiSend(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer); /* Data. */ + spiIgnore(mmcp->mmc_spip, 2); /* CRC ignored. */ + spiReceive(mmcp->mmc_spip, 1, b); if ((b[0] & 0x1F) == 0x05) { wait(mmcp); return FALSE; @@ -608,7 +608,7 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) { } chSysUnlock(); - spiSendWait(mmcp->mmc_spip, sizeof(stop), stop); + spiSend(mmcp->mmc_spip, sizeof(stop), stop); spiUnselect(mmcp->mmc_spip); chSysLock(); diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c index 414eb61db..fe7b729bd 100644 --- a/os/hal/src/spi.c +++ b/os/hal/src/spi.c @@ -66,6 +66,7 @@ void spiInit(void) { void spiObjectInit(SPIDriver *spip) { spip->spd_state = SPI_STOP; + spip->spd_config = NULL; #if SPI_USE_WAIT spip->spd_thread = NULL; #endif /* SPI_USE_WAIT */ @@ -76,8 +77,6 @@ void spiObjectInit(SPIDriver *spip) { chSemInit(&spip->spd_semaphore, 1); #endif #endif /* SPI_USE_MUTUAL_EXCLUSION */ - spip->spd_config = NULL; - /* Optional, user-defined initializer.*/ #if defined(SPI_DRIVER_EXT_INIT_HOOK) SPI_DRIVER_EXT_INIT_HOOK(spip); #endif @@ -97,8 +96,7 @@ void spiStart(SPIDriver *spip, const SPIConfig *config) { chSysLock(); chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY), - "spiStart(), #1", - "invalid state"); + "spiStart(), #1", "invalid state"); spip->spd_config = config; spi_lld_start(spip); spip->spd_state = SPI_READY; @@ -118,8 +116,7 @@ void spiStop(SPIDriver *spip) { chSysLock(); chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY), - "spiStop(), #1", - "invalid state"); + "spiStop(), #1", "invalid state"); spi_lld_stop(spip); spip->spd_state = SPI_STOP; chSysUnlock(); @@ -137,10 +134,8 @@ void spiSelect(SPIDriver *spip) { chDbgCheck(spip != NULL, "spiSelect"); chSysLock(); - chDbgAssert((spip->spd_state == SPI_READY) || - (spip->spd_state == SPI_SELECTED), - "spiSelect(), #1", - "not idle"); + chDbgAssert(spip->spd_state == SPI_READY, + "spiSelect(), #1", "not ready"); spiSelectI(spip); chSysUnlock(); } @@ -157,40 +152,10 @@ void spiUnselect(SPIDriver *spip) { chDbgCheck(spip != NULL, "spiUnselect"); - chSysLock(); - chDbgAssert((spip->spd_state == SPI_READY) || - (spip->spd_state == SPI_SELECTED), - "spiUnselect(), #1", - "not locked"); - spiUnselectI(spip); - chSysUnlock(); -} - -/** - * @brief Emits a train of clock pulses on the SPI bus. - * @details This asynchronous function starts the emission of a train of - * clock pulses without asserting any slave. - * @note This functionality is not usually required by the SPI protocol - * but it is required by initialization procedure of MMC/SD cards - * in SPI mode. - * @post At the end of the operation the configured callback is invoked. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to be clocked. The number of pulses - * is equal to the number of words multiplied to the - * configured word size in bits. - * - * @api - */ -void spiSynchronize(SPIDriver *spip, size_t n) { - - chDbgCheck((spip != NULL) && (n > 0), "spiSynchronize"); - chSysLock(); chDbgAssert(spip->spd_state == SPI_READY, - "spiSynchronize(), #1", - "not ready"); - spiSynchronizeI(spip, n); + "spiUnselect(), #1", "not ready"); + spiUnselectI(spip); chSysUnlock(); } @@ -207,15 +172,14 @@ void spiSynchronize(SPIDriver *spip, size_t n) { * * @api */ -void spiIgnore(SPIDriver *spip, size_t n) { +void spiStartIgnore(SPIDriver *spip, size_t n) { - chDbgCheck((spip != NULL) && (n > 0), "spiIgnore"); + chDbgCheck((spip != NULL) && (n > 0), "spiStartIgnore"); chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiIgnore(), #1", - "not selected"); - spiIgnoreI(spip, n); + chDbgAssert(spip->spd_state == SPI_READY, + "spiStartIgnore(), #1", "not ready"); + spiStartIgnoreI(spip, n); chSysUnlock(); } @@ -236,16 +200,16 @@ void spiIgnore(SPIDriver *spip, size_t n) { * * @api */ -void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { +void spiStartExchange(SPIDriver *spip, size_t n, + const void *txbuf, void *rxbuf) { chDbgCheck((spip != NULL) && (n > 0) && (rxbuf != NULL) && (txbuf != NULL), - "spiExchange"); + "spiStartExchange"); chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiExchange(), #1", - "not selected"); - spiExchangeI(spip, n, txbuf, rxbuf); + chDbgAssert(spip->spd_state == SPI_READY, + "spiStartExchange(), #1", "not ready"); + spiStartExchangeI(spip, n, txbuf, rxbuf); chSysUnlock(); } @@ -264,16 +228,15 @@ void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { * * @api */ -void spiSend(SPIDriver *spip, size_t n, const void *txbuf) { +void spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) { chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL), - "spiSend"); + "spiStartSend"); chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiSend(), #1", - "not selected"); - spiSendI(spip, n, txbuf); + chDbgAssert(spip->spd_state == SPI_READY, + "spiStartSend(), #1", "not ready"); + spiStartSendI(spip, n, txbuf); chSysUnlock(); } @@ -292,107 +255,44 @@ void spiSend(SPIDriver *spip, size_t n, const void *txbuf) { * * @api */ -void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) { +void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) { chDbgCheck((spip != NULL) && (n > 0) && (rxbuf != NULL), - "spiReceive"); - - chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiReceive(), #1", - "not selected"); - spiReceiveI(spip, n, rxbuf); - chSysUnlock(); -} - -#if SPI_USE_WAIT || defined(__DOXYGEN__) -/** - * @brief Waits 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. - * @pre In order to use this function the option @p SPI_USE_WAIT must be - * enabled. - * @post On exit the SPI driver is ready to accept more commands. - * @note No more than one thread can wait on a SPI driver using - * this function. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @api - */ -void spiWait(SPIDriver *spip) { - - 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), - "spiWait(), #1", - "invalid state"); - if ((spip->spd_state == SPI_ACTIVE) || (spip->spd_state == SPI_SYNC)) - spiWaitS(spip); - chSysUnlock(); -} - -/** - * @brief Emits a train of clock pulses on the SPI bus. - * @details This synchronous function performs the emission of a train of - * clock pulses without asserting any slave. - * @pre In order to use this function the option @p SPI_USE_WAIT must be - * enabled. - * @post At the end of the operation the configured callback is invoked. - * @note This functionality is not usually required by the SPI protocol - * but it is required by initialization procedure of MMC/SD cards - * in SPI mode. - * - * @param[in] spip pointer to the @p SPIDriver object - * @param[in] n number of words to be clocked. The number of pulses - * is equal to the number of words multiplied to the - * configured word size in bits. - * - * @api - */ -void spiSynchronizeWait(SPIDriver *spip, size_t n) { - - chDbgCheck((spip != NULL) && (n > 0), "spiSynchronizeWait"); + "spiStartReceive"); chSysLock(); chDbgAssert(spip->spd_state == SPI_READY, - "spiSynchronizeWait(), #1", - "not ready"); - spiSynchronizeI(spip, n); - spiWaitS(spip); + "spiStartReceive(), #1", "not ready"); + spiStartReceiveI(spip, n, rxbuf); chSysUnlock(); } +#if SPI_USE_WAIT || defined(__DOXYGEN__) /** * @brief Ignores data on the SPI bus. * @details This synchronous function performs the transmission of a series of * idle words on the SPI bus and ignores the received data. - * @pre A slave must have been selected using @p spiSelect() or - * @p spiSelectI(). * @pre In order to use this function the option @p SPI_USE_WAIT must be * enabled. - * @post At the end of the operation the configured callback is invoked. + * @pre In order to use this function the driver must have been configured + * without callbacks (@p spc_endcb = @p NULL). * * @param[in] spip pointer to the @p SPIDriver object * @param[in] n number of words to be ignored * * @api */ -void spiIgnoreWait(SPIDriver *spip, size_t n) { +void spiIgnore(SPIDriver *spip, size_t n) { chDbgCheck((spip != NULL) && (n > 0), "spiIgnoreWait"); chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiIgnoreWait(), #1", - "not selected"); - spiIgnoreI(spip, n); - spiWaitS(spip); + chDbgAssert(spip->spd_state == SPI_READY, + "spiIgnore(), #1", "not ready"); + chDbgAssert(spip->spd_config->spc_endcb == NULL, + "spiIgnore(), #2", "has callback"); + spiStartIgnoreI(spip, n); + _spi_wait(spip); chSysUnlock(); } @@ -400,11 +300,10 @@ void spiIgnoreWait(SPIDriver *spip, size_t n) { * @brief Exchanges data on the SPI bus. * @details This synchronous function performs a simultaneous transmit/receive * operation. - * @pre A slave must have been selected using @p spiSelect() or - * @p spiSelectI(). * @pre In order to use this function the option @p SPI_USE_WAIT must be * enabled. - * @post At the end of the operation the configured callback is invoked. + * @pre In order to use this function the driver must have been configured + * without callbacks (@p spc_endcb = @p NULL). * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * @@ -415,29 +314,29 @@ void spiIgnoreWait(SPIDriver *spip, size_t n) { * * @api */ -void spiExchangeWait(SPIDriver *spip, size_t n, +void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { chDbgCheck((spip != NULL) && (n > 0) && (rxbuf != NULL) && (txbuf != NULL), - "spiExchangeWait"); + "spiExchange"); chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiExchangeWait(), #1", - "not selected"); - spiExchangeI(spip, n, txbuf, rxbuf); - spiWaitS(spip); + chDbgAssert(spip->spd_state == SPI_READY, + "spiExchange(), #1", "not ready"); + chDbgAssert(spip->spd_config->spc_endcb == NULL, + "spiExchange(), #2", "has callback"); + spiStartExchangeI(spip, n, txbuf, rxbuf); + _spi_wait(spip); chSysUnlock(); } /** * @brief Sends data over the SPI bus. * @details This synchronous function performs a transmit operation. - * @pre A slave must have been selected using @p spiSelect() or - * @p spiSelectI(). * @pre In order to use this function the option @p SPI_USE_WAIT must be * enabled. - * @post At the end of the operation the configured callback is invoked. + * @pre In order to use this function the driver must have been configured + * without callbacks (@p spc_endcb = @p NULL). * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * @@ -447,28 +346,28 @@ void spiExchangeWait(SPIDriver *spip, size_t n, * * @api */ -void spiSendWait(SPIDriver *spip, size_t n, const void *txbuf) { +void spiSend(SPIDriver *spip, size_t n, const void *txbuf) { chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL), - "spiSendWait"); + "spiSend"); chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiSendWait(), #1", - "not selected"); - spiSendI(spip, n, txbuf); - spiWaitS(spip); + chDbgAssert(spip->spd_state == SPI_READY, + "spiSend(), #1", "not ready"); + chDbgAssert(spip->spd_config->spc_endcb == NULL, + "spiSend(), #2", "has callback"); + spiStartSendI(spip, n, txbuf); + _spi_wait(spip); chSysUnlock(); } /** * @brief Receives data from the SPI bus. * @details This synchronous function performs a receive operation. - * @pre A slave must have been selected using @p spiSelect() or - * @p spiSelectI(). * @pre In order to use this function the option @p SPI_USE_WAIT must be * enabled. - * @post At the end of the operation the configured callback is invoked. + * @pre In order to use this function the driver must have been configured + * without callbacks (@p spc_endcb = @p NULL). * @note The buffers are organized as uint8_t arrays for data sizes below * or equal to 8 bits else it is organized as uint16_t arrays. * @@ -478,17 +377,18 @@ void spiSendWait(SPIDriver *spip, size_t n, const void *txbuf) { * * @api */ -void spiReceiveWait(SPIDriver *spip, size_t n, void *rxbuf) { +void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) { chDbgCheck((spip != NULL) && (n > 0) && (rxbuf != NULL), - "spiReceiveWait"); + "spiReceive"); chSysLock(); - chDbgAssert(spip->spd_state == SPI_SELECTED, - "spiReceiveWait(), #1", - "not selected"); - spiReceiveI(spip, n, rxbuf); - spiWaitS(spip); + chDbgAssert(spip->spd_state == SPI_READY, + "spiReceive(), #1", "not ready"); + chDbgAssert(spip->spd_config->spc_endcb == NULL, + "spiReceive(), #2", "has callback"); + spiStartReceiveI(spip, n, rxbuf); + _spi_wait(spip); chSysUnlock(); } #endif /* SPI_USE_WAIT */ -- cgit v1.2.3