From 0edf3f363b0e8222477f1bf956a421ab6e7d2cd5 Mon Sep 17 00:00:00 2001 From: Uladzimir Pylinski Date: Tue, 19 Jul 2016 18:56:03 +0000 Subject: [STM32. USARTv2] Added receiver timeout handling. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9713 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/hal_uart.h | 22 +++++++++++++++++++++- os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c | 12 ++++++++++++ os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h | 10 ++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) (limited to 'os/hal') diff --git a/os/hal/include/hal_uart.h b/os/hal/include/hal_uart.h index 02537aa29..01a505c9a 100644 --- a/os/hal/include/hal_uart.h +++ b/os/hal/include/hal_uart.h @@ -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); \ +} + /** @} */ /*===========================================================================*/ diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c index ceb14fe67..0012ef259 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c +++ b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c @@ -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); + } } /*===========================================================================*/ diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h index abb9bce0a..84afee0e1 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h +++ b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h @@ -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. */ -- cgit v1.2.3