From 7cf0b962d60f68d106f2372e7dc4699ca8636a42 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 7 Sep 2022 13:59:30 +0200 Subject: [PATCH 1/7] fix: remove useless declaration since _write() syscall moved to Print.cpp Signed-off-by: Frederic Pillon --- libraries/SrcWrapper/src/syscalls.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/SrcWrapper/src/syscalls.c b/libraries/SrcWrapper/src/syscalls.c index bee85bfc99..dc30e931e3 100644 --- a/libraries/SrcWrapper/src/syscalls.c +++ b/libraries/SrcWrapper/src/syscalls.c @@ -13,8 +13,6 @@ #undef errno extern int errno; -extern size_t uart_debug_write(uint8_t *data, uint32_t size); - // Helper macro to mark unused parameters and prevent compiler warnings. // Appends _UNUSED to the variable name to prevent accidentally using them. #ifdef UNUSED From 7af1c67ada9bf4e6d555cfdabeefc767aa873c1b Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 7 Sep 2022 15:10:39 +0200 Subject: [PATCH 2/7] chore(uart): remove useless uart_write() function Signed-off-by: Frederic Pillon --- cores/arduino/stm32/uart.h | 1 - libraries/SrcWrapper/src/stm32/uart.c | 16 ---------------- 2 files changed, 17 deletions(-) diff --git a/cores/arduino/stm32/uart.h b/cores/arduino/stm32/uart.h index 53283ac2ea..cea0b0b305 100644 --- a/cores/arduino/stm32/uart.h +++ b/cores/arduino/stm32/uart.h @@ -228,7 +228,6 @@ void uart_deinit(serial_t *obj); #if defined(HAL_PWR_MODULE_ENABLED) && (defined(UART_IT_WUF) || defined(LPUART1_BASE)) void uart_config_lowpower(serial_t *obj); #endif -size_t uart_write(serial_t *obj, uint8_t data, uint16_t size); int uart_getc(serial_t *obj, unsigned char *c); void uart_attach_rx_callback(serial_t *obj, void (*callback)(serial_t *)); void uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *), size_t size); diff --git a/libraries/SrcWrapper/src/stm32/uart.c b/libraries/SrcWrapper/src/stm32/uart.c index 132df68571..e161e8d3f3 100644 --- a/libraries/SrcWrapper/src/stm32/uart.c +++ b/libraries/SrcWrapper/src/stm32/uart.c @@ -660,22 +660,6 @@ void uart_config_lowpower(serial_t *obj) } #endif -/** - * @brief write the data on the uart - * @param obj : pointer to serial_t structure - * @param data : byte to write - * @param size : number of data to write - * @retval The number of bytes written - */ -size_t uart_write(serial_t *obj, uint8_t data, uint16_t size) -{ - if (HAL_UART_Transmit(uart_handlers[obj->index], &data, size, TX_TIMEOUT) == HAL_OK) { - return size; - } else { - return 0; - } -} - /** * @brief Function called to initialize the debug uart interface * @note Call only if debug U(S)ART peripheral is not already initialized From 469a4f509c2991728aec578f4dc4f99e653d2f8a Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 7 Sep 2022 16:23:32 +0200 Subject: [PATCH 3/7] chore(uart): harden uart_debug_write() Signed-off-by: Frederic Pillon --- libraries/SrcWrapper/src/stm32/uart.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/SrcWrapper/src/stm32/uart.c b/libraries/SrcWrapper/src/stm32/uart.c index e161e8d3f3..1e8c03fb76 100644 --- a/libraries/SrcWrapper/src/stm32/uart.c +++ b/libraries/SrcWrapper/src/stm32/uart.c @@ -714,6 +714,8 @@ size_t uart_debug_write(uint8_t *data, uint32_t size) serial_t *obj = get_serial_obj(uart_handlers[serial_debug.index]); if (obj) { serial_debug.irq = obj->irq; + } else { + return 0; } } } From 9622de38ee83eeee3226655bd17fcdb7a870f78d Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 7 Sep 2022 17:21:32 +0200 Subject: [PATCH 4/7] refactor(uart): check DEBUG_UART only if serial_debug is not initialized It prevents to check this each time uart_debug_write is called as init is done once. Signed-off-by: Frederic Pillon --- libraries/SrcWrapper/src/stm32/uart.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/SrcWrapper/src/stm32/uart.c b/libraries/SrcWrapper/src/stm32/uart.c index 1e8c03fb76..e3d241e8ef 100644 --- a/libraries/SrcWrapper/src/stm32/uart.c +++ b/libraries/SrcWrapper/src/stm32/uart.c @@ -691,10 +691,11 @@ size_t uart_debug_write(uint8_t *data, uint32_t size) { uint32_t tickstart = HAL_GetTick(); - if (DEBUG_UART == NP) { - return 0; - } if (serial_debug.index >= UART_NUM) { + if (DEBUG_UART == NP) { + return 0; + } + /* Search if DEBUG_UART already initialized */ for (serial_debug.index = 0; serial_debug.index < UART_NUM; serial_debug.index++) { if (uart_handlers[serial_debug.index] != NULL) { From c774ab8543e84d92602806eb057ce2226bfbb56a Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 8 Sep 2022 16:51:32 +0200 Subject: [PATCH 5/7] fix(uart): avoid infinite loop during init of serial_debug Since rts/cts has been introduced, the serial debug on dedicated pins was broken as by default the serial_debug pin cts/rts was set to 0 (valid pinname). So core_debug was called during the init leading to an infinite loop. Signed-off-by: Frederic Pillon --- libraries/SrcWrapper/src/stm32/uart.c | 30 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libraries/SrcWrapper/src/stm32/uart.c b/libraries/SrcWrapper/src/stm32/uart.c index e3d241e8ef..8c00d9005c 100644 --- a/libraries/SrcWrapper/src/stm32/uart.c +++ b/libraries/SrcWrapper/src/stm32/uart.c @@ -78,8 +78,14 @@ typedef enum { } uart_index_t; static UART_HandleTypeDef *uart_handlers[UART_NUM] = {NULL}; - -static serial_t serial_debug = { .uart = NP, .index = UART_NUM }; +static serial_t serial_debug = { + .uart = NP, + .pin_tx = NC, + .pin_rx = NC, + .pin_rts = NC, + .pin_cts = NC, + .index = UART_NUM +}; /* Aim of the function is to get serial_s pointer using huart pointer */ /* Highly inspired from magical linux kernel's "container_of" */ @@ -115,22 +121,30 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par /* Pin Tx must not be NP */ if (uart_tx == NP) { - core_debug("ERROR: [U(S)ART] Tx pin has no peripheral!\n"); + if (obj != &serial_debug) { + core_debug("ERROR: [U(S)ART] Tx pin has no peripheral!\n"); + } return; } /* Pin Rx must not be NP if not half-duplex */ if ((obj->pin_rx != NC) && (uart_rx == NP)) { - core_debug("ERROR: [U(S)ART] Rx pin has no peripheral!\n"); + if (obj != &serial_debug) { + core_debug("ERROR: [U(S)ART] Rx pin has no peripheral!\n"); + } return; } /* Pin RTS must not be NP if flow control is enabled */ if ((obj->pin_rts != NC) && (uart_rts == NP)) { - core_debug("ERROR: [U(S)ART] RTS pin has no peripheral!\n"); + if (obj != &serial_debug) { + core_debug("ERROR: [U(S)ART] RTS pin has no peripheral!\n"); + } return; } /* Pin CTS must not be NP if flow control is enabled */ if ((obj->pin_cts != NC) && (uart_cts == NP)) { - core_debug("ERROR: [U(S)ART] CTS pin has no peripheral!\n"); + if (obj != &serial_debug) { + core_debug("ERROR: [U(S)ART] CTS pin has no peripheral!\n"); + } return; } @@ -144,7 +158,9 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par obj->uart = pinmap_merge_peripheral(obj->uart, uart_cts); if (obj->uart == NP) { - core_debug("ERROR: [U(S)ART] Rx/Tx/RTS/CTS pins peripherals mismatch!\n"); + if (obj != &serial_debug) { + core_debug("ERROR: [U(S)ART] Rx/Tx/RTS/CTS pins peripherals mismatch!\n"); + } return; } From d974fb2a80b5ef2fff5384ea641cbcc414f39e9d Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 22 Sep 2022 10:36:30 +0200 Subject: [PATCH 6/7] feat(uart): debug configured in half duplex mode Only TX pin is required. Signed-off-by: Frederic Pillon --- libraries/SrcWrapper/src/stm32/uart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/SrcWrapper/src/stm32/uart.c b/libraries/SrcWrapper/src/stm32/uart.c index 8c00d9005c..84aed3d798 100644 --- a/libraries/SrcWrapper/src/stm32/uart.c +++ b/libraries/SrcWrapper/src/stm32/uart.c @@ -686,13 +686,12 @@ void uart_config_lowpower(serial_t *obj) void uart_debug_init(void) { if (DEBUG_UART != NP) { - serial_debug.pin_rx = pinmap_pin(DEBUG_UART, PinMap_UART_RX); #if defined(DEBUG_PINNAME_TX) serial_debug.pin_tx = DEBUG_PINNAME_TX; #else serial_debug.pin_tx = pinmap_pin(DEBUG_UART, PinMap_UART_TX); #endif - + /* serial_debug.pin_rx set by default to NC to configure in half duplex mode */ uart_init(&serial_debug, DEBUG_UART_BAUDRATE, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1); } } From ff019c1b0f95a2033ac0588dbf0e375ff3b6b0f5 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 7 Sep 2022 17:24:40 +0200 Subject: [PATCH 7/7] fix(uart): ensure debug uart is ready before send Like state is ready not need to loop on the blocking HAL_UART_Transmit(). If not ok it can be HAL_ERROR or HAL_TIMEOUT. Moreover, it avoid to disable the U(S)ART IRQ which prevent to receive data. Fixes #1789 Signed-off-by: Frederic Pillon --- libraries/SrcWrapper/src/stm32/uart.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/libraries/SrcWrapper/src/stm32/uart.c b/libraries/SrcWrapper/src/stm32/uart.c index 84aed3d798..f1ea4bc275 100644 --- a/libraries/SrcWrapper/src/stm32/uart.c +++ b/libraries/SrcWrapper/src/stm32/uart.c @@ -705,6 +705,7 @@ void uart_debug_init(void) size_t uart_debug_write(uint8_t *data, uint32_t size) { uint32_t tickstart = HAL_GetTick(); + serial_t *obj = NULL; if (serial_debug.index >= UART_NUM) { if (DEBUG_UART == NP) { @@ -726,26 +727,22 @@ size_t uart_debug_write(uint8_t *data, uint32_t size) if (serial_debug.index >= UART_NUM) { return 0; } - } else { - serial_t *obj = get_serial_obj(uart_handlers[serial_debug.index]); - if (obj) { - serial_debug.irq = obj->irq; - } else { - return 0; - } } } + obj = get_serial_obj(uart_handlers[serial_debug.index]); + if (!obj) { + return 0; + } - HAL_NVIC_DisableIRQ(serial_debug.irq); - - while (HAL_UART_Transmit(uart_handlers[serial_debug.index], data, size, TX_TIMEOUT) != HAL_OK) { - if ((HAL_GetTick() - tickstart) >= TX_TIMEOUT) { - size = 0; - break; + while (serial_tx_active(obj)) { + if ((HAL_GetTick() - tickstart) >= TX_TIMEOUT) { + return 0; } } - HAL_NVIC_EnableIRQ(serial_debug.irq); + if (HAL_UART_Transmit(&(obj->handle), data, size, TX_TIMEOUT) != HAL_OK) { + size = 0; + } return size; }