From 9915d1ba46e30990ea149c7a09d1d2ed0d13a331 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Wed, 1 Jun 2016 21:03:05 +0200 Subject: Implement circular buffer UART RX using interrupts. --- stm-uart.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'stm-uart.c') diff --git a/stm-uart.c b/stm-uart.c index 297718d..2f3aabe 100644 --- a/stm-uart.c +++ b/stm-uart.c @@ -62,12 +62,7 @@ HAL_StatusTypeDef uart_send_char(uint8_t ch) HAL_StatusTypeDef uart_send_char2(enum stm_uart_port port, uint8_t ch) { - UART_HandleTypeDef *uart = _which_uart(port); - - if (uart) - return HAL_UART_Transmit(uart, &ch, 1, 0x1); - - return HAL_ERROR; + return uart_send_bytes(port, &ch, 1); } /* receive a single character */ @@ -96,21 +91,21 @@ HAL_StatusTypeDef uart_send_string(char *s) /* send a string */ HAL_StatusTypeDef uart_send_string2(enum stm_uart_port port, const char *s) { - UART_HandleTypeDef *uart = _which_uart(port); - - if (uart) - return HAL_UART_Transmit(uart, (uint8_t *) s, strlen(s), 0x1); - - return HAL_ERROR; + return uart_send_bytes(port, (uint8_t *) s, strlen(s)); } /* send raw bytes */ HAL_StatusTypeDef uart_send_bytes(enum stm_uart_port port, uint8_t *buf, size_t len) { + uint32_t timeout = 100; UART_HandleTypeDef *uart = _which_uart(port); - if (uart) + if (uart) { + while (HAL_UART_GetState(uart) != HAL_UART_STATE_READY && timeout--) { ; } + if (! timeout) return HAL_ERROR; + return HAL_UART_Transmit(uart, (uint8_t *) buf, (uint32_t) len, 0x1); + } return HAL_ERROR; } @@ -139,7 +134,6 @@ HAL_StatusTypeDef uart_send_number2(enum stm_uart_port port, uint32_t num, uint8 #define BUFSIZE 32 char buf[BUFSIZE]; char *where = buf + BUFSIZE; - UART_HandleTypeDef *uart = _which_uart(port); /* initialize buf so we can add leading 0 by adjusting the pointer */ memset(buf, '0', BUFSIZE); @@ -163,7 +157,7 @@ HAL_StatusTypeDef uart_send_number2(enum stm_uart_port port, uint32_t num, uint8 /* number is larger than the specified number of digits */ digits = buf + BUFSIZE - where; - return HAL_UART_Transmit(uart, (uint8_t *) where, digits, 0x1); + return uart_send_bytes(port, (uint8_t *) where, digits); } HAL_StatusTypeDef uart_send_hexdump(enum stm_uart_port port, const uint8_t *buf, -- cgit v1.2.3 From ae1ecf87f6b8d7c34b32af0547f118ff7697c2ef Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Thu, 2 Jun 2016 14:56:56 +0200 Subject: Use DMA for UART RX instead of interrupts. DMA is more efficient and less prone to miss characters than interrupts. An open question is if circular mode is really the best. If someone copy-pastes more than the RX buffer size of configuration into the CLI, we risk the DMA controller catching up with the reader and overwriting data not yet read. Since we don't have flow control back to the users terminal, we will always fail if too much data is entered before we can process it. The question is if failing to stuff new data at the end of a buffer might be better than data being overwritten - thus messing up the commands in unpredictable ways. --- stm-uart.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'stm-uart.c') diff --git a/stm-uart.c b/stm-uart.c index 2f3aabe..59bbbe6 100644 --- a/stm-uart.c +++ b/stm-uart.c @@ -37,8 +37,11 @@ #include -UART_HandleTypeDef huart_mgmt; -UART_HandleTypeDef huart_user; +UART_HandleTypeDef huart_mgmt; /* USART1 */ +UART_HandleTypeDef huart_user; /* USART2 */ + +DMA_HandleTypeDef hdma_usart_mgmt_rx; +DMA_HandleTypeDef hdma_usart_user_rx; #define DEFAULT_UART STM_UART_USER -- cgit v1.2.3