git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13812 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
c21bbe0fa0
commit
84119d5d52
|
@ -160,12 +160,12 @@ struct hal_sio_operation {
|
|||
* @brief Receive buffer filled callback.
|
||||
* @note Can be @p NULL.
|
||||
*/
|
||||
siocb_t rxne_cb;
|
||||
siocb_t rx_cb;
|
||||
/**
|
||||
* @brief End of transmission buffer callback.
|
||||
* @note Can be @p NULL.
|
||||
*/
|
||||
siocb_t txnf_cb;
|
||||
siocb_t tx_cb;
|
||||
/**
|
||||
* @brief Physical end of transmission callback.
|
||||
* @note Can be @p NULL.
|
||||
|
@ -197,7 +197,7 @@ struct hal_sio_operation {
|
|||
*
|
||||
* @xclass
|
||||
*/
|
||||
#define sioRXIsEmptyX(siop) sio_lld_rx_is_empty(siop)
|
||||
#define sioIsRXEmptyX(siop) sio_lld_is_rx_empty(siop)
|
||||
|
||||
/**
|
||||
* @brief Determines the state of the TX FIFO.
|
||||
|
@ -209,7 +209,7 @@ struct hal_sio_operation {
|
|||
*
|
||||
* @xclass
|
||||
*/
|
||||
#define sioTXIsFullX(siop) sio_lld_tx_is_full(siop)
|
||||
#define sioIsTXFullX(siop) sio_lld_is_tx_full(siop)
|
||||
|
||||
/**
|
||||
* @brief Returns one frame from the RX FIFO.
|
||||
|
@ -218,9 +218,9 @@ struct hal_sio_operation {
|
|||
* @param[in] siop pointer to the @p SIODriver object
|
||||
* @return The frame from RX FIFO.
|
||||
*
|
||||
* @xclass
|
||||
* @iclass
|
||||
*/
|
||||
#define sioRXGetX(siop) sio_lld_rx_get(siop)
|
||||
#define sioGetI(siop) sio_lld_get(siop)
|
||||
|
||||
/**
|
||||
* @brief Pushes one frame into the TX FIFO.
|
||||
|
@ -229,9 +229,9 @@ struct hal_sio_operation {
|
|||
* @param[in] siop pointer to the @p SIODriver object
|
||||
* @param[in] data frame to be written
|
||||
*
|
||||
* @xclass
|
||||
* @iclass
|
||||
*/
|
||||
#define sioTXPutX(siop, data) sio_lld_tx_put(siop, data)
|
||||
#define sioPutI(siop, data) sio_lld_put(siop, data)
|
||||
|
||||
/**
|
||||
* @brief Reads data from the RX FIFO.
|
||||
|
@ -245,9 +245,9 @@ struct hal_sio_operation {
|
|||
* @param[in] size maximum number of frames to read
|
||||
* @return The number of received frames.
|
||||
*
|
||||
* @xclass
|
||||
* @iclass
|
||||
*/
|
||||
#define sioReadX(siop, buffer, size) sio_lld_read(siop, buffer, size)
|
||||
#define sioAsyncReadI(siop, buffer, size) sio_lld_read(siop, buffer, size)
|
||||
|
||||
/**
|
||||
* @brief Writes data into the TX FIFO.
|
||||
|
@ -261,9 +261,9 @@ struct hal_sio_operation {
|
|||
* @param[in] size maximum number of frames to read
|
||||
* @return The number of transmitted frames.
|
||||
*
|
||||
* @xclass
|
||||
* @iclass
|
||||
*/
|
||||
#define sioWriteX(siop, buffer, size) sio_lld_write(siop, buffer, size)
|
||||
#define sioAsyncWriteI(siop, buffer, size) sio_lld_write(siop, buffer, size)
|
||||
|
||||
/**
|
||||
* @brief Control operation on a serial port.
|
||||
|
@ -294,9 +294,13 @@ extern "C" {
|
|||
void sioStop(SIODriver *siop);
|
||||
void sioStartOperation(SIODriver *siop, const SIOOperation *operation);
|
||||
void sioStopOperation(SIODriver *siop);
|
||||
size_t sioAsyncRead(SIODriver *siop, size_t n, uint8_t *buffer);
|
||||
size_t sioAsyncWrite(SIODriver *siop, size_t n, const uint8_t *buffer);
|
||||
#if (HAL_SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||
msg_t sioSynchronizeRX(SIODriver *siop);
|
||||
msg_t sioSynchronizeTX(SIODriver *siop);
|
||||
msg_t sioSynchronizeTXEnd(SIODriver *siop);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
/**
|
||||
* @brief SIO1 driver identifier.
|
||||
*/
|
||||
#if (PLATFORM_SIO_USE_SIO1 == TRUE) || defined(__DOXYGEN__)
|
||||
#if (STM32_SIO_USE_USART1 == TRUE) || defined(__DOXYGEN__)
|
||||
SIODriver SIOD1;
|
||||
#endif
|
||||
|
||||
|
@ -64,7 +64,7 @@ SIODriver SIOD1;
|
|||
*/
|
||||
void sio_lld_init(void) {
|
||||
|
||||
#if PLATFORM_SIO_USE_SIO1 == TRUE
|
||||
#if STM32_SIO_USE_USART1 == TRUE
|
||||
/* Driver initialization.*/
|
||||
sioObjectInit(&SIOD1);
|
||||
#endif
|
||||
|
@ -84,7 +84,7 @@ bool sio_lld_start(SIODriver *siop) {
|
|||
|
||||
if (siop->state == SIO_STOP) {
|
||||
/* Enables the peripheral.*/
|
||||
#if PLATFORM_SIO_USE_SIO1 == TRUE
|
||||
#if STM32_SIO_USE_USART1 == TRUE
|
||||
if (&SIOD1 == siop) {
|
||||
|
||||
}
|
||||
|
@ -108,13 +108,91 @@ void sio_lld_stop(SIODriver *siop) {
|
|||
/* Resets the peripheral.*/
|
||||
|
||||
/* Disables the peripheral.*/
|
||||
#if PLATFORM_SIO_USE_SIO1 == TRUE
|
||||
#if STM32_SIO_USE_USART1 == TRUE
|
||||
if (&SIOD1 == siop) {
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Reads data from the RX FIFO.
|
||||
* @details The function is not blocking, it writes frames until there
|
||||
* is space available without waiting.
|
||||
*
|
||||
* @param[in] siop pointer to an @p SIODriver structure
|
||||
* @param[in] n maximum number of frames to be read
|
||||
* @param[in] buf pointer to the buffer for read frames
|
||||
* @return The number of frames copied from the buffer.
|
||||
* @retval 0 if the TX FIFO is full.
|
||||
*/
|
||||
size_t sio_lld_read(SIODriver *siop, size_t n, uint8_t *buf) {
|
||||
size_t rd;
|
||||
|
||||
rd = 0U;
|
||||
while (true) {
|
||||
|
||||
#if USART_ENABLE_INTERRUPTS == TRUE
|
||||
/* If the RX FIFO has been emptied then the interrupt is enabled again.*/
|
||||
if (sio_lld_is_rx_empty(siop)) {
|
||||
siop->usart->CR3 |= USART_CR3_RXFTIE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Buffer filled condition.*/
|
||||
if (rd > n) {
|
||||
break;
|
||||
}
|
||||
|
||||
*buf++ = (uint8_t)siop->usart->RDR;
|
||||
rd++;
|
||||
}
|
||||
|
||||
return n - rd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes data into the TX FIFO.
|
||||
* @details The function is not blocking, it writes frames until there
|
||||
* is space available without waiting.
|
||||
*
|
||||
* @param[in] siop pointer to an @p SIODriver structure
|
||||
* @param[in] n maximum number of frames to be written
|
||||
* @param[in] buf pointer to the buffer for read frames
|
||||
* @return The number of frames copied from the buffer.
|
||||
* @retval 0 if the TX FIFO is full.
|
||||
*/
|
||||
size_t sio_lld_write(SIODriver *siop, size_t n, const uint8_t *buf) {
|
||||
size_t wr;
|
||||
|
||||
wr = 0U;
|
||||
while (true) {
|
||||
|
||||
#if USART_ENABLE_INTERRUPTS == TRUE
|
||||
/* If the TX FIFO has been filled then the interrupt is enabled again.*/
|
||||
if (sio_lld_is_tx_full(siop)) {
|
||||
siop->usart->CR3 |= USART_CR3_TXFTIE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Buffer emptied condition.*/
|
||||
if (wr >= n) {
|
||||
break;
|
||||
}
|
||||
|
||||
siop->usart->TDR = (uint32_t)*buf++;
|
||||
wr++;
|
||||
}
|
||||
|
||||
#if USART_ENABLE_INTERRUPTS == TRUE
|
||||
/* The transmit complete interrupt is always re-enabled on write.*/
|
||||
siop->usart->CR1 |= USART_CR1_TCIE;
|
||||
#endif
|
||||
|
||||
return n - wr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Control operation on a serial port.
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
* @details If set to @p TRUE the support for SIO1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(PLATFORM_SIO_USE_SIO1) || defined(__DOXYGEN__)
|
||||
#define PLATFORM_SIO_USE_SIO1 FALSE
|
||||
#if !defined(STM32_SIO_USE_USART1) || defined(__DOXYGEN__)
|
||||
#define STM32_SIO_USE_USART1 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
|
@ -133,7 +133,7 @@
|
|||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (PLATFORM_SIO_USE_SIO1 == TRUE) && !defined(__DOXYGEN__)
|
||||
#if (STM32_SIO_USE_USART1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern SIODriver SIOD1;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -129,6 +129,188 @@ void sioStop(SIODriver *siop) {
|
|||
osalSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts n SIO operation.
|
||||
*
|
||||
* @param[in] siop pointer to an @p SIODriver structure
|
||||
* @param[in] operation pointer to an @p SIOOperation structure
|
||||
* encoding the operation to be performed
|
||||
*/
|
||||
void sioStartOperation(SIODriver *siop, const SIOOperation *operation) {
|
||||
|
||||
osalDbgCheck((siop != NULL) && (operation != NULL));
|
||||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert(siop->state == SIO_READY, "invalid state");
|
||||
|
||||
siop->operation = operation;
|
||||
siop->state = SIO_ACTIVE;
|
||||
|
||||
sio_lld_start_operation(siop);
|
||||
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops an ongoing SIO operation, if any.
|
||||
*
|
||||
* @param[in] siop pointer to an @p SIODriver structure
|
||||
*/
|
||||
void sioStopOperation(SIODriver *siop) {
|
||||
|
||||
osalDbgCheck(siop != NULL);
|
||||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
||||
|
||||
sio_lld_stop_operation(siop);
|
||||
|
||||
siop->operation = NULL;
|
||||
siop->state = SIO_READY;
|
||||
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads data from the RX FIFO.
|
||||
* @details This function is non-blocking, data is read if present and the
|
||||
* effective amount is returned.
|
||||
* @note This function can be called from any context but it is meant to
|
||||
* be called from the @p rxne_cb callback handler.
|
||||
*
|
||||
* @param[in] siop pointer to the @p SIODriver object
|
||||
* @param[in] buffer buffer for the received data
|
||||
* @param[in] size maximum number of frames to read
|
||||
* @return The number of received frames.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
size_t sioAsyncReadI(SIODriver *siop, size_t n, uint8_t *buffer) {
|
||||
|
||||
osalDbgCheck((siop != NULL) && (buf != NULL));
|
||||
|
||||
osalSysLock();
|
||||
|
||||
n = sioAsyncReadI(siop, n, buffer);
|
||||
|
||||
osalSysUnlock();
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes data into the TX FIFO.
|
||||
* @details This function is non-blocking, data is written if there is space
|
||||
* in the FIFO and the effective amount is returned.
|
||||
* @note This function can be called from any context but it is meant to
|
||||
* be called from the @p txnf_cb callback handler.
|
||||
*
|
||||
* @param[in] siop pointer to the @p SIODriver object
|
||||
* @param[out] buffer buffer containing the data to be transmitted
|
||||
* @param[in] size maximum number of frames to read
|
||||
* @return The number of transmitted frames.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
size_t sioAsyncWrite(SIODriver *siop, size_t n, const uint8_t *buffer) {
|
||||
|
||||
osalDbgCheck((siop != NULL) && (buf != NULL));
|
||||
|
||||
osalSysLock();
|
||||
|
||||
n = sioAsyncWriteI(siop, n, buffer);
|
||||
|
||||
osalSysUnlock();
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
#if (HAL_SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Synchronizes with RX FIFO data availability.
|
||||
* @note The exact behavior depends on low level FIFO settings such
|
||||
* as thresholds, etc.
|
||||
* @note This function can only be called by a single thread at time.
|
||||
*
|
||||
* @param[in] siop pointer to an @p SIODriver structure
|
||||
* @param[in] timeout synchronization timeout
|
||||
* @return The synchronization result.
|
||||
* @retval MSG_OK if there is space in the TX FIFO.
|
||||
* @retval MSG_TIMEOUT if synchronization timed out.
|
||||
*/
|
||||
msg_t sioSynchronizeRX(SIODriver *siop) {
|
||||
|
||||
osalDbgCheck(siop != NULL);
|
||||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
||||
|
||||
if (sio_lld_is_rx_empty(siop)) {
|
||||
msg = osalThdSuspendTimeoutS(&siop->sync_rx, timeout);
|
||||
}
|
||||
else {
|
||||
msg = MSG_OK;
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Synchronizes with TX FIFO space availability.
|
||||
* @note The exact behavior depends on low level FIFO settings such
|
||||
* as thresholds, etc.
|
||||
* @note This function can only be called by a single thread at time.
|
||||
*
|
||||
* @param[in] siop pointer to an @p SIODriver structure
|
||||
* @param[in] timeout synchronization timeout
|
||||
* @return The synchronization result.
|
||||
* @retval MSG_OK if there is space in the TX FIFO.
|
||||
* @retval MSG_TIMEOUT if synchronization timed out.
|
||||
*/
|
||||
msg_t sioSynchronizeTX(SIODriver *siop) {
|
||||
|
||||
osalDbgCheck(siop != NULL);
|
||||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
||||
|
||||
|
||||
osalSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Synchronizes with TX completion.
|
||||
* @note This function can only be called by a single thread at time.
|
||||
*
|
||||
* @param[in] siop pointer to an @p SIODriver structure
|
||||
* @param[in] timeout synchronization timeout
|
||||
* @return The synchronization result.
|
||||
* @retval MSG_OK if TX operation finished.
|
||||
* @retval MSG_TIMEOUT if synchronization timed out.
|
||||
*/
|
||||
msg_t sioSynchronizeTXEnd(SIODriver *siop) {
|
||||
|
||||
osalDbgCheck(siop != NULL);
|
||||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
|
||||
|
||||
if (sio_lld_is_tx_ongoing(siop)) {
|
||||
msg = osalThdSuspendTimeoutS(&siop->sync_txend, timeout);
|
||||
}
|
||||
else {
|
||||
msg = MSG_OK;
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
}
|
||||
#endif /* HAL_SIO_USE_SYNCHRONIZATION == TRUE */
|
||||
|
||||
#endif /* HAL_USE_SIO == TRUE */
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue