754 lines
23 KiB
C
754 lines
23 KiB
C
/*
|
|
ChibiOS - Copyright (C) 2006..2023 Giovanni Di Sirio
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @file hal_spi.c
|
|
* @brief Generated SPI Driver source.
|
|
* @note This is a generated file, do not edit directly.
|
|
*
|
|
* @addtogroup HAL_SPI
|
|
* @{
|
|
*/
|
|
|
|
#include "hal.h"
|
|
|
|
#if (HAL_USE_SPI == TRUE) || defined(__DOXYGEN__)
|
|
|
|
/*===========================================================================*/
|
|
/* Module local definitions. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Module local macros. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Module exported variables. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Module local types. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Module local variables. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Module local functions. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Module exported functions. */
|
|
/*===========================================================================*/
|
|
|
|
/**
|
|
* @brief SPI Driver initialization.
|
|
* @note This function is implicitly invoked by @p halInit(), there is
|
|
* no need to explicitly initialize the driver.
|
|
*
|
|
* @init
|
|
*/
|
|
void spiInit(void) {
|
|
|
|
spi_lld_init();
|
|
}
|
|
|
|
/*===========================================================================*/
|
|
/* Module class "hal_spi_driver_c" methods. */
|
|
/*===========================================================================*/
|
|
|
|
/**
|
|
* @name Methods implementations of hal_spi_driver_c
|
|
* @{
|
|
*/
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @protected
|
|
*
|
|
* @brief Implementation of object creation.
|
|
* @note This function is meant to be used by derived classes.
|
|
*
|
|
* @param[out] ip Pointer to a @p hal_spi_driver_c instance to be
|
|
* initialized.
|
|
* @param[in] vmt VMT pointer for the new object.
|
|
* @return A new reference to the object.
|
|
*/
|
|
void *__spi_objinit_impl(void *ip, const void *vmt) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
|
|
/* Initialization of the ancestors-defined parts.*/
|
|
__cbdrv_objinit_impl(self, vmt);
|
|
|
|
/* Initialization code.*/
|
|
|
|
/* Optional, user-defined initializer.*/
|
|
#if defined(SPI_DRIVER_EXT_INIT_HOOK)
|
|
SPI_DRIVER_EXT_INIT_HOOK(self);
|
|
#endif
|
|
|
|
return self;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @protected
|
|
*
|
|
* @brief Implementation of object finalization.
|
|
* @note This function is meant to be used by derived classes.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance to be
|
|
* disposed.
|
|
*/
|
|
void __spi_dispose_impl(void *ip) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
|
|
/* No finalization code.*/
|
|
(void)self;
|
|
|
|
/* Finalization of the ancestors-defined parts.*/
|
|
__cbdrv_dispose_impl(self);
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @protected
|
|
*
|
|
* @brief Override of method @p __drv_start().
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @return The operation status.
|
|
*/
|
|
msg_t __spi_start_impl(void *ip) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
|
|
return spi_lld_start(self);
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @protected
|
|
*
|
|
* @brief Override of method @p __drv_stop().
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
*/
|
|
void __spi_stop_impl(void *ip) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
|
|
spi_lld_stop(self);
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @protected
|
|
*
|
|
* @brief Override of method @p __drv_do_configure().
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] config New driver configuration.
|
|
* @return The configuration pointer.
|
|
*/
|
|
const void *__spi_doconf_impl(void *ip, const void *config) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
|
|
return (const void *)spi_lld_configure(self, (const hal_spi_config_t *)config);
|
|
}
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief VMT structure of SPI driver class.
|
|
* @note It is public because accessed by the inlined constructor.
|
|
*/
|
|
const struct hal_spi_driver_vmt __hal_spi_driver_vmt = {
|
|
.dispose = __spi_dispose_impl,
|
|
.start = __spi_start_impl,
|
|
.stop = __spi_stop_impl,
|
|
.doconf = __spi_doconf_impl,
|
|
.setcb = __cbdrv_setcb_impl
|
|
};
|
|
|
|
/**
|
|
* @name Regular methods of hal_spi_driver_c
|
|
* @{
|
|
*/
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Ignores data on the SPI bus.
|
|
* @details This asynchronous function starts 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 spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be ignored.
|
|
* @return The operation status.
|
|
*
|
|
* @iclass
|
|
*/
|
|
msg_t spiStartIgnoreI(void *ip, size_t n) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_ignore(self, n);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Ignores data on the SPI bus.
|
|
* @details This asynchronous function starts 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 spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be ignored.
|
|
* @return The operation status.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiStartIgnore(void *ip, size_t n) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartIgnoreI(self, n);
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Exchanges data on the SPI bus.
|
|
* @details This asynchronous function starts a simultaneous
|
|
* transmit/receive operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[in] txbuf Pointer to the transmit buffer.
|
|
* @param[out] rxbuf Pointer to the receive buffer.
|
|
* @return The operation status.
|
|
*
|
|
* @iclass
|
|
*/
|
|
msg_t spiStartExchangeI(void *ip, size_t n, const void *txbuf, void *rxbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U) &&
|
|
(rxbuf != NULL) && (txbuf != NULL));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_exchange(self, n, txbuf, rxbuf);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Exchanges data on the SPI bus.
|
|
* @details This asynchronous function starts a simultaneous
|
|
* transmit/receive operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[in] txbuf Pointer to the transmit buffer.
|
|
* @param[out] rxbuf Pointer to the receive buffer.
|
|
* @return The operation status.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiStartExchange(void *ip, size_t n, const void *txbuf, void *rxbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartExchangeI(self, n, txbuf, rxbuf);
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Sends data over the SPI bus.
|
|
* @details This asynchronous function starts a transmit operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[in] txbuf Pointer to the transmit buffer.
|
|
* @return The operation status.
|
|
*
|
|
* @iclass
|
|
*/
|
|
msg_t spiStartSendI(void *ip, size_t n, const void *txbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U) && (txbuf != NULL));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_send(self, n, txbuf);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Sends data over the SPI bus.
|
|
* @details This asynchronous function starts a transmit operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[in] txbuf Pointer to the transmit buffer.
|
|
* @return The operation status.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiStartSend(void *ip, size_t n, const void *txbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartSendI(self, n, txbuf);
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Receives data from the SPI bus.
|
|
* @details This asynchronous function starts a receive operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[out] rxbuf Pointer to the receive buffer.
|
|
* @return The operation status.
|
|
*
|
|
* @iclass
|
|
*/
|
|
msg_t spiStartReceiveI(void *ip, size_t n, void *rxbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U) && (rxbuf != NULL));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_receive(self, n, rxbuf);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Receives data from the SPI bus.
|
|
* @details This asynchronous function starts a receive operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @post At the end of the operation the callback is invoked, if
|
|
* enabled.
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[out] rxbuf Pointer to the receive buffer.
|
|
* @return The operation status.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiStartReceive(void *ip, size_t n, void *rxbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartReceiveI(self, n, rxbuf);
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Stops the ongoing SPI operation.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[out] np Pointer to the counter of frames not yet
|
|
* transferred or @p NULL.
|
|
* @return The operation status.
|
|
*
|
|
* @iclass
|
|
*/
|
|
msg_t spiStopTransferI(void *ip, size_t *np) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck(self != NULL);
|
|
|
|
osalDbgAssert((self->state == HAL_DRV_STATE_READY) ||
|
|
(self->state == HAL_DRV_STATE_ACTIVE) ||
|
|
(self->state == HAL_DRV_STATE_COMPLETE),
|
|
"invalid state");
|
|
|
|
if ((self->state == HAL_DRV_STATE_ACTIVE) ||
|
|
(self->state == HAL_DRV_STATE_COMPLETE)) {
|
|
|
|
/* Stopping transfer at low level.*/
|
|
msg = spi_lld_stop_transfer(self, np);
|
|
self->state = HAL_DRV_STATE_READY;
|
|
|
|
#if SPI_USE_SYNCHRONIZATION == TRUE
|
|
osalThreadResumeI(&self->sync_transfer, MSG_RESET);
|
|
#endif
|
|
}
|
|
else {
|
|
msg = HAL_RET_SUCCESS;
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Stops the ongoing SPI operation.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[out] np Pointer to the counter of frames not yet
|
|
* transferred or @p NULL.
|
|
* @return The operation status.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiStopTransfer(void *ip, size_t *np) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
|
|
msg = spiStopTransferI(self, np);
|
|
osalOsRescheduleS();
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
#if (SPI_USE_SYNCHRONIZATION == TRUE) || defined (__DOXYGEN__)
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @note This function can only be called by a single thread at time.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] timeout Synchronization timeout.
|
|
* @return The synchronization result.
|
|
* @retval MSG_OK If operation completed without errors.
|
|
* @retval MSG_TIMEOUT If synchronization timed out.
|
|
* @retval MSG_RESET If the transfer has been stopped.
|
|
*
|
|
* @sclass
|
|
*/
|
|
msg_t spiSynchronizeS(void *ip, sysinterval_t timeout) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalDbgCheck(self != NULL);
|
|
osalDbgAssert((self->state == HAL_DRV_STATE_ACTIVE) ||
|
|
(self->state == HAL_DRV_STATE_READY),
|
|
"invalid state");
|
|
|
|
if (self->state == HAL_DRV_STATE_ACTIVE) {
|
|
msg = osalThreadSuspendTimeoutS(&self->sync_transfer, timeout);
|
|
}
|
|
else {
|
|
msg = MSG_OK;
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @note This function can only be called by a single thread at time.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] timeout Synchronization timeout.
|
|
* @return The synchronization result.
|
|
* @retval MSG_OK If operation completed without errors.
|
|
* @retval MSG_TIMEOUT If synchronization timed out.
|
|
* @retval MSG_RESET If the transfer has been stopped.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiSynchronize(void *ip, sysinterval_t timeout) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiSynchronizeS(self, timeout);
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @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 spiSelectX().
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be ignored.
|
|
* @return The operation status.
|
|
* @retval MSG_OK If operation completed without errors.
|
|
* @retval MSG_TIMEOUT If synchronization timed out.
|
|
* @retval MSG_RESET If the transfer has been stopped.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiIgnore(void *ip, size_t n) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
|
|
msg = spiStartIgnoreI(self, n);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @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 spiSelectX().
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[in] txbuf Pointer to the transmit buffer.
|
|
* @param[out] rxbuf Pointer to the receive buffer.
|
|
* @return The operation status.
|
|
* @retval MSG_OK If operation completed without errors.
|
|
* @retval MSG_TIMEOUT If synchronization timed out.
|
|
* @retval MSG_RESET If the transfer has been stopped.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiExchange(void *ip, size_t n, const void *txbuf, void *rxbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
|
|
msg = spiStartExchangeI(self, n, txbuf, rxbuf);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Sends data over the SPI bus.
|
|
* @details This synchronous function performs a transmit operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[in] txbuf Pointer to the transmit buffer.
|
|
* @return The operation status.
|
|
* @retval MSG_OK If operation completed without errors.
|
|
* @retval MSG_TIMEOUT If synchronization timed out.
|
|
* @retval MSG_RESET If the transfer has been stopped.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiSend(void *ip, size_t n, const void *txbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
msg = spiStartSendI(self, n, txbuf);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @memberof hal_spi_driver_c
|
|
* @public
|
|
*
|
|
* @brief Receives data from the SPI bus.
|
|
* @details This synchronous function performs a receive operation.
|
|
* @pre A slave must have been selected using @p spiSelectX().
|
|
* @note Buffers are organized as uint8_t arrays for frame sizes below
|
|
* or equal to 8 bits else uint16_t is used.
|
|
*
|
|
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
|
* @param[in] n Number of frames to be exchanged.
|
|
* @param[out] rxbuf Pointer to the receive buffer.
|
|
* @return The operation status.
|
|
* @retval MSG_OK If operation completed without errors.
|
|
* @retval MSG_TIMEOUT If synchronization timed out.
|
|
* @retval MSG_RESET If the transfer has been stopped.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t spiReceive(void *ip, size_t n, void *rxbuf) {
|
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
|
msg_t msg;
|
|
|
|
msg = spiStartReceiveI(self, n, rxbuf);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;
|
|
}
|
|
#endif /* SPI_USE_SYNCHRONIZATION == TRUE */
|
|
/** @} */
|
|
|
|
#endif /* HAL_USE_SPI == TRUE */
|
|
|
|
/** @} */
|