[STM32. USARTv2] Added receiver timeout handling.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9713 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Uladzimir Pylinski 2016-07-19 18:56:03 +00:00
parent 57dc4418de
commit 0edf3f363b
6 changed files with 73 additions and 1 deletions

View File

@ -279,7 +279,6 @@ typedef enum {
_uart_wakeup_rx_error_isr(uartp); \
}
/**
* @brief Common ISR code for RX on idle.
* @details This code handles the portable part of the ISR code:
@ -298,6 +297,27 @@ typedef enum {
if ((uartp)->config->rxchar_cb != NULL) \
(uartp)->config->rxchar_cb(uartp, (uartp)->rxbuf); \
}
/**
* @brief Timeout ISR code for receiver.
* @details This code handles the portable part of the ISR code:
* - Callback invocation.
* - Waiting thread wakeup, if any.
* - Driver state transitions.
* .
* @note This macro is meant to be used in the low level drivers
* implementation only.
*
* @param[in] uartp pointer to the @p UARTDriver object
*
* @notapi
*/
#define _uart_timeout_isr_code(uartp) { \
if ((uartp)->config->timeout_cb != NULL) \
(uartp)->config->timeout_cb(uartp); \
}
/** @} */
/*===========================================================================*/

View File

@ -220,6 +220,7 @@ static void usart_stop(UARTDriver *uartp) {
*/
static void usart_start(UARTDriver *uartp) {
uint32_t cr1;
const uint32_t tmo = uartp->config->timeout;
USART_TypeDef *u = uartp->usart;
/* Defensive programming, starting from a clean state.*/
@ -242,6 +243,13 @@ static void usart_start(UARTDriver *uartp) {
cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
u->CR1 = uartp->config->cr1 | cr1;
/* Set receive timeout and check it appliance */
if (tmo > 0) {
osalDbgAssert(tmo <= USART_RTOR_RTO, "Timeout overflow");
u->RTOR = tmo;
osalDbgAssert(tmo == u->RTOR, "Timeout feature unsupported in this UART");
}
/* Starting the receiver idle loop.*/
uart_enter_rx_idle_loop(uartp);
}
@ -325,6 +333,10 @@ static void serve_usart_irq(UARTDriver *uartp) {
/* End of transmission, a callback is generated.*/
_uart_tx2_isr_code(uartp);
}
if ((isr & USART_ISR_IDLE) || (isr & USART_ISR_RTOF)) {
_uart_timeout_isr_code(uartp);
}
}
/*===========================================================================*/

View File

@ -585,6 +585,16 @@ typedef struct {
*/
uartecb_t rxerr_cb;
/* End of the mandatory fields.*/
/**
* @brief Receiver timeout callback.
*/
uartcb_t timeout_cb;
/**
* @brief Receiver timeout value in terms of number of bit duration.
* @details Set it to 0 when you want to handle IDLE interrupt instead of
* hardware timeout.
*/
uint32_t timeout;
/**
* @brief Bit rate.
*/

View File

@ -91,6 +91,14 @@ static void rxend(UARTDriver *uartp) {
(void)uartp;
}
/*
* This callback is invoked when configured timeout reached.
*/
static void rxtimeout(UARTDriver *uartp) {
(void)uartp;
}
/*
* UART driver configuration structure.
*/
@ -100,6 +108,8 @@ static UARTConfig uart_cfg_1 = {
rxend,
rxchar,
rxerr,
rxtimeout,
0,
38400,
0,
USART_CR2_LINEN,

View File

@ -91,6 +91,14 @@ static void rxend(UARTDriver *uartp) {
(void)uartp;
}
/*
* This callback is invoked when configured timeout reached.
*/
static void rxtimeout(UARTDriver *uartp) {
(void)uartp;
}
/*
* UART driver configuration structure.
*/
@ -100,6 +108,8 @@ static UARTConfig uart_cfg_1 = {
rxend,
rxchar,
rxerr,
rxtimeout,
0,
38400,
0,
USART_CR2_LINEN,

View File

@ -91,6 +91,14 @@ static void rxend(UARTDriver *uartp) {
(void)uartp;
}
/*
* This callback is invoked when configured timeout reached.
*/
static void rxtimeout(UARTDriver *uartp) {
(void)uartp;
}
/*
* UART driver configuration structure.
*/
@ -100,6 +108,8 @@ static UARTConfig uart_cfg_1 = {
rxend,
rxchar,
rxerr,
rxtimeout,
0,
38400,
0,
USART_CR2_LINEN,