From 3f74a8a7b4457fa0978f6b0ca7e9481aa302545c Mon Sep 17 00:00:00 2001 From: Toon Stegen Date: Tue, 27 Aug 2019 19:01:58 +0200 Subject: [PATCH] cpu/stm32_common/uart: init rts at right time once hardware flow control is enabled, rts should only be initialized after the uart is enabled by setting the UE flag. This is stated in the stm32f4 errata. --- cpu/stm32_common/periph/uart.c | 67 +++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/cpu/stm32_common/periph/uart.c b/cpu/stm32_common/periph/uart.c index d2f4aa50bb..c31ad17a5b 100644 --- a/cpu/stm32_common/periph/uart.c +++ b/cpu/stm32_common/periph/uart.c @@ -75,6 +75,30 @@ static inline void uart_init_lpuart(uart_t uart, uint32_t baudrate); #endif #endif +#ifdef MODULE_STM32_PERIPH_UART_HW_FC +static inline void uart_init_rts_pin(uart_t uart) +{ + if (uart_config[uart].cts_pin != GPIO_UNDEF) { + gpio_init(uart_config[uart].rts_pin, GPIO_OUT); +#ifdef CPU_FAM_STM32F1 + gpio_init_af(uart_config[uart].rts_pin, GPIO_AF_OUT_PP); +#else + gpio_init_af(uart_config[uart].rts_pin, uart_config[uart].rts_af); +#endif + } +} + +static inline void uart_init_cts_pin(uart_t uart) +{ + if (uart_config[uart].cts_pin != GPIO_UNDEF) { + gpio_init(uart_config[uart].cts_pin, GPIO_IN); +#ifndef CPU_FAM_STM32F1 + gpio_init_af(uart_config[uart].cts_pin, uart_config[uart].cts_af); +#endif + } +} +#endif + static inline void uart_init_pins(uart_t uart, uart_rx_cb_t rx_cb) { /* configure TX pin */ @@ -94,16 +118,8 @@ static inline void uart_init_pins(uart_t uart, uart_rx_cb_t rx_cb) #endif } #ifdef MODULE_STM32_PERIPH_UART_HW_FC - if (uart_config[uart].cts_pin != GPIO_UNDEF) { - gpio_init(uart_config[uart].cts_pin, GPIO_IN); - gpio_init(uart_config[uart].rts_pin, GPIO_OUT); -#ifdef CPU_FAM_STM32F1 - gpio_init_af(uart_config[uart].rts_pin, GPIO_AF_OUT_PP); -#else - gpio_init_af(uart_config[uart].cts_pin, uart_config[uart].cts_af); - gpio_init_af(uart_config[uart].rts_pin, uart_config[uart].rts_af); -#endif - } + uart_init_cts_pin(uart); + uart_init_rts_pin(uart); #endif } @@ -113,16 +129,6 @@ static inline void uart_enable_clock(uart_t uart) if (isr_ctx[uart].rx_cb) { pm_block(STM32_PM_STOP); } -#endif -#ifdef MODULE_STM32_PERIPH_UART_HW_FC - if (uart_config[uart].cts_pin != GPIO_UNDEF) { - gpio_init(uart_config[uart].rts_pin, GPIO_OUT); -#ifdef CPU_FAM_STM32F1 - gpio_init_af(uart_config[uart].rts_pin, GPIO_AF_OUT_PP); -#else - gpio_init_af(uart_config[uart].rts_pin, uart_config[uart].rts_af); -#endif - } #endif periph_clk_en(uart_config[uart].bus, uart_config[uart].rcc_mask); } @@ -130,12 +136,6 @@ static inline void uart_enable_clock(uart_t uart) static inline void uart_disable_clock(uart_t uart) { periph_clk_dis(uart_config[uart].bus, uart_config[uart].rcc_mask); -#ifdef MODULE_STM32_PERIPH_UART_HW_FC - if (uart_config[uart].cts_pin != GPIO_UNDEF) { - gpio_init(uart_config[uart].rts_pin, GPIO_OUT); - gpio_set(uart_config[uart].rts_pin); - } -#endif #ifdef STM32_PM_STOP if (isr_ctx[uart].rx_cb) { pm_unblock(STM32_PM_STOP); @@ -369,12 +369,27 @@ void uart_poweron(uart_t uart) uart_enable_clock(uart); dev(uart)->CR1 |= (USART_CR1_UE); + +#ifdef MODULE_STM32_PERIPH_UART_HW_FC + /* STM32F4 errata 2.10.9: nRTS is active while RE or UE = 0 + * we should only configure nRTS pin after setting UE */ + uart_init_rts_pin(uart); +#endif } void uart_poweroff(uart_t uart) { assert(uart < UART_NUMOF); +#ifdef MODULE_STM32_PERIPH_UART_HW_FC + /* the uart peripheral does not put RTS high from hardware when + * UE flag is cleared, so we need to do this manually */ + if (uart_config[uart].cts_pin != GPIO_UNDEF) { + gpio_init(uart_config[uart].rts_pin, GPIO_OUT); + gpio_set(uart_config[uart].rts_pin); + } +#endif + dev(uart)->CR1 &= ~(USART_CR1_UE); uart_disable_clock(uart);