diff options
author | Uladzimir Pylinski <barthess@yandex.ru> | 2016-07-19 18:56:03 +0000 |
---|---|---|
committer | Uladzimir Pylinski <barthess@yandex.ru> | 2016-07-19 18:56:03 +0000 |
commit | 0edf3f363b0e8222477f1bf956a421ab6e7d2cd5 (patch) | |
tree | 9f53cb6ac75e50776abe22373a41d820ca4255f2 | |
parent | 57dc4418deee2b123301d36eec3a020acee3814b (diff) | |
download | ChibiOS-0edf3f363b0e8222477f1bf956a421ab6e7d2cd5.tar.gz ChibiOS-0edf3f363b0e8222477f1bf956a421ab6e7d2cd5.tar.bz2 ChibiOS-0edf3f363b0e8222477f1bf956a421ab6e7d2cd5.zip |
[STM32. USARTv2] Added receiver timeout handling.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9713 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r-- | os/hal/include/hal_uart.h | 22 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c | 12 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h | 10 | ||||
-rw-r--r-- | testhal/STM32/STM32F0xx/UART/main.c | 10 | ||||
-rw-r--r-- | testhal/STM32/STM32F37x/UART/main.c | 10 | ||||
-rw-r--r-- | testhal/STM32/STM32F3xx/UART/main.c | 10 |
6 files changed, 73 insertions, 1 deletions
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 @@ -586,6 +586,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.
*/
uint32_t speed;
diff --git a/testhal/STM32/STM32F0xx/UART/main.c b/testhal/STM32/STM32F0xx/UART/main.c index 16a7ba582..08c60b9ad 100644 --- a/testhal/STM32/STM32F0xx/UART/main.c +++ b/testhal/STM32/STM32F0xx/UART/main.c @@ -92,6 +92,14 @@ static void rxend(UARTDriver *uartp) { }
/*
+ * This callback is invoked when configured timeout reached.
+ */
+static void rxtimeout(UARTDriver *uartp) {
+
+ (void)uartp;
+}
+
+/*
* UART driver configuration structure.
*/
static UARTConfig uart_cfg_1 = {
@@ -100,6 +108,8 @@ static UARTConfig uart_cfg_1 = { rxend,
rxchar,
rxerr,
+ rxtimeout,
+ 0,
38400,
0,
USART_CR2_LINEN,
diff --git a/testhal/STM32/STM32F37x/UART/main.c b/testhal/STM32/STM32F37x/UART/main.c index c31077c79..431763070 100644 --- a/testhal/STM32/STM32F37x/UART/main.c +++ b/testhal/STM32/STM32F37x/UART/main.c @@ -92,6 +92,14 @@ static void rxend(UARTDriver *uartp) { }
/*
+ * This callback is invoked when configured timeout reached.
+ */
+static void rxtimeout(UARTDriver *uartp) {
+
+ (void)uartp;
+}
+
+/*
* UART driver configuration structure.
*/
static UARTConfig uart_cfg_1 = {
@@ -100,6 +108,8 @@ static UARTConfig uart_cfg_1 = { rxend,
rxchar,
rxerr,
+ rxtimeout,
+ 0,
38400,
0,
USART_CR2_LINEN,
diff --git a/testhal/STM32/STM32F3xx/UART/main.c b/testhal/STM32/STM32F3xx/UART/main.c index 30abb55d3..1ef5bb6b9 100644 --- a/testhal/STM32/STM32F3xx/UART/main.c +++ b/testhal/STM32/STM32F3xx/UART/main.c @@ -92,6 +92,14 @@ static void rxend(UARTDriver *uartp) { }
/*
+ * This callback is invoked when configured timeout reached.
+ */
+static void rxtimeout(UARTDriver *uartp) {
+
+ (void)uartp;
+}
+
+/*
* UART driver configuration structure.
*/
static UARTConfig uart_cfg_1 = {
@@ -100,6 +108,8 @@ static UARTConfig uart_cfg_1 = { rxend,
rxchar,
rxerr,
+ rxtimeout,
+ 0,
38400,
0,
USART_CR2_LINEN,
|