Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 45 additions & 16 deletions drivers/serial/uart_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(uart_stm32, CONFIG_UART_LOG_LEVEL);

/* This symbol takes the value 1 if one of the device instances */
/* is configured in dts with an optional clock */
#if STM32_DT_INST_DEV_OPT_CLOCK_SUPPORT
#define STM32_UART_OPT_CLOCK_SUPPORT 1
#else
#define STM32_UART_OPT_CLOCK_SUPPORT 0
#endif

#define HAS_LPUART_1 (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart1), \
st_stm32_lpuart, okay))

Expand Down Expand Up @@ -93,20 +101,28 @@ static void uart_stm32_pm_policy_state_lock_put(const struct device *dev)
}
#endif /* CONFIG_PM */

static inline void uart_stm32_set_baudrate(const struct device *dev,
uint32_t baud_rate)
static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t baud_rate)
{
const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data;

uint32_t clock_rate;

/* Get clock rate */
if (clock_control_get_rate(data->clock,
(clock_control_subsys_t *)&config->pclken,
&clock_rate) < 0) {
LOG_ERR("Failed call clock_control_get_rate");
return;
if (IS_ENABLED(STM32_UART_OPT_CLOCK_SUPPORT) && (config->pclk_len > 1)) {
if (clock_control_get_rate(data->clock,
(clock_control_subsys_t)&config->pclken[1],
&clock_rate) < 0) {
LOG_ERR("Failed call clock_control_get_rate(pclken[1])");
return;
}
} else {
if (clock_control_get_rate(data->clock,
(clock_control_subsys_t)&config->pclken[0],
&clock_rate) < 0) {
LOG_ERR("Failed call clock_control_get_rate(pclken[0])");
return;
}
}

#if HAS_LPUART_1
Expand Down Expand Up @@ -1556,9 +1572,20 @@ static int uart_stm32_init(const struct device *dev)

__uart_stm32_get_clock(dev);
/* enable clock */
if (clock_control_on(data->clock,
(clock_control_subsys_t *)&config->pclken) != 0) {
return -EIO;
err = clock_control_on(data->clock, (clock_control_subsys_t)&config->pclken[0]);
if (err != 0) {
LOG_ERR("Could not enable (LP)UART clock");
return err;
}

if (IS_ENABLED(STM32_UART_OPT_CLOCK_SUPPORT) && (config->pclk_len > 1)) {
err = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
(clock_control_subsys_t) &config->pclken[1],
NULL);
if (err != 0) {
LOG_ERR("Could not select UART source clock");
return err;
}
}

/* Configure dt provided device signals when available */
Expand Down Expand Up @@ -1697,10 +1724,10 @@ static void uart_stm32_irq_config_func_##index(const struct device *dev) \

#ifdef CONFIG_UART_ASYNC_API
#define UART_DMA_CHANNEL(index, dir, DIR, src, dest) \
.dma_##dir = { \
.dma_##dir = { \
COND_CODE_1(DT_INST_DMAS_HAS_NAME(index, dir), \
(UART_DMA_CHANNEL_INIT(index, dir, DIR, src, dest)), \
(NULL)) \
(NULL)) \
},

#else
Expand All @@ -1712,15 +1739,17 @@ STM32_UART_IRQ_HANDLER_DECL(index) \
\
PINCTRL_DT_INST_DEFINE(index); \
\
static const struct stm32_pclken pclken_##index[] = \
STM32_DT_INST_CLOCKS(index);\
\
static const struct uart_stm32_config uart_stm32_cfg_##index = { \
.usart = (USART_TypeDef *)DT_INST_REG_ADDR(index), \
.pclken = { .bus = DT_INST_CLOCKS_CELL(index, bus), \
.enr = DT_INST_CLOCKS_CELL(index, bits) \
}, \
.pclken = pclken_##index, \
.pclk_len = DT_INST_NUM_CLOCKS(index), \
.hw_flow_control = DT_INST_PROP(index, hw_flow_control), \
.parity = DT_INST_ENUM_IDX_OR(index, parity, UART_CFG_PARITY_NONE), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
.single_wire = DT_INST_PROP_OR(index, single_wire, false), \
.single_wire = DT_INST_PROP_OR(index, single_wire, false), \
.tx_rx_swap = DT_INST_PROP_OR(index, tx_rx_swap, false), \
STM32_UART_IRQ_HANDLER_FUNC(index) \
}; \
Expand Down
4 changes: 3 additions & 1 deletion drivers/serial/uart_stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ struct uart_stm32_config {
/* USART instance */
USART_TypeDef *usart;
/* clock subsystem driving this peripheral */
struct stm32_pclken pclken;
const struct stm32_pclken *pclken;
/* number of clock subsystems */
size_t pclk_len;
/* initial hardware flow control, 1 for RTS/CTS */
bool hw_flow_control;
/* initial parity, 0 for none, 1 for odd, 2 for even */
Expand Down