drivers: serial: Reset UART using RCC before initialization

In multi-image environment, after jump to the image we can have UART in
unexpected state. Reset UART to default state to make sure that UART is
initialized properly and won't cause system to crash or hang.

Signed-off-by: Patryk Duda <pdk@semihalf.com>
This commit is contained in:
Patryk Duda 2022-10-28 14:25:13 +02:00 committed by Marti Bolivar
commit 1aebcec02f
3 changed files with 13 additions and 0 deletions

View file

@ -16,6 +16,7 @@ config UART_STM32
DT_HAS_ST_STM32_DMA_V2BIS_ENABLED || \ DT_HAS_ST_STM32_DMA_V2BIS_ENABLED || \
DT_HAS_ST_STM32U5_DMA_ENABLED DT_HAS_ST_STM32U5_DMA_ENABLED
select DMA if UART_ASYNC_API select DMA if UART_ASYNC_API
select RESET
help help
This option enables the UART driver for STM32 family of This option enables the UART driver for STM32 family of
processors. processors.

View file

@ -21,6 +21,7 @@
#include <zephyr/init.h> #include <zephyr/init.h>
#include <zephyr/drivers/uart.h> #include <zephyr/drivers/uart.h>
#include <zephyr/drivers/clock_control.h> #include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/reset.h>
#include <zephyr/pm/policy.h> #include <zephyr/pm/policy.h>
#include <zephyr/pm/device.h> #include <zephyr/pm/device.h>
@ -1620,6 +1621,14 @@ static int uart_stm32_init(const struct device *dev)
LL_USART_Disable(config->usart); LL_USART_Disable(config->usart);
if (!device_is_ready(data->reset.dev)) {
LOG_ERR("reset controller not ready");
return -ENODEV;
}
/* Reset UART to default state using RCC */
reset_line_toggle_dt(&data->reset);
/* TX/RX direction */ /* TX/RX direction */
LL_USART_SetTransferDirection(config->usart, LL_USART_SetTransferDirection(config->usart,
LL_USART_DIRECTION_TX_RX); LL_USART_DIRECTION_TX_RX);
@ -1896,6 +1905,7 @@ static const struct uart_stm32_config uart_stm32_cfg_##index = { \
\ \
static struct uart_stm32_data uart_stm32_data_##index = { \ static struct uart_stm32_data uart_stm32_data_##index = { \
.baud_rate = DT_INST_PROP(index, current_speed), \ .baud_rate = DT_INST_PROP(index, current_speed), \
.reset = RESET_DT_SPEC_GET(DT_DRV_INST(index)), \
UART_DMA_CHANNEL(index, rx, RX, PERIPHERAL, MEMORY) \ UART_DMA_CHANNEL(index, rx, RX, PERIPHERAL, MEMORY) \
UART_DMA_CHANNEL(index, tx, TX, MEMORY, PERIPHERAL) \ UART_DMA_CHANNEL(index, tx, TX, MEMORY, PERIPHERAL) \
}; \ }; \

View file

@ -76,6 +76,8 @@ struct uart_stm32_data {
uint32_t baud_rate; uint32_t baud_rate;
/* clock device */ /* clock device */
const struct device *clock; const struct device *clock;
/* Reset controller device configuration */
const struct reset_dt_spec reset;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_irq_callback_user_data_t user_cb; uart_irq_callback_user_data_t user_cb;
void *user_data; void *user_data;