Skip to content

Commit 23e3549

Browse files
committed
drivers: serial: stm32: propagate baud rate config failure
The uart_stm32 driver gives no way for a user to tell if setting a new baud rate was successful. Propagate error checks up to the API level. Signed-off-by: Eden Frosst <[email protected]>
1 parent a10f807 commit 23e3549

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

drivers/serial/uart_stm32.c

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -140,28 +140,34 @@ static void uart_stm32_pm_policy_state_lock_put(const struct device *dev)
140140
}
141141
#endif /* CONFIG_PM */
142142

143-
static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t baud_rate)
143+
static inline int uart_stm32_set_baudrate(const struct device *dev, uint32_t baud_rate)
144144
{
145145
const struct uart_stm32_config *config = dev->config;
146146
USART_TypeDef *usart = config->usart;
147147
struct uart_stm32_data *data = dev->data;
148148

149+
if (baud_rate == 0) {
150+
return -EINVAL;
151+
}
152+
149153
uint32_t clock_rate;
150154

151155
/* Get clock rate */
152156
if (IS_ENABLED(STM32_UART_DOMAIN_CLOCK_SUPPORT) && (config->pclk_len > 1)) {
153-
if (clock_control_get_rate(data->clock,
154-
(clock_control_subsys_t)&config->pclken[1],
155-
&clock_rate) < 0) {
157+
int ret = clock_control_get_rate(data->clock,
158+
(clock_control_subsys_t)&config->pclken[1],
159+
&clock_rate);
160+
if (ret < 0) {
156161
LOG_ERR("Failed call clock_control_get_rate(pclken[1])");
157-
return;
162+
return ret;
158163
}
159164
} else {
160-
if (clock_control_get_rate(data->clock,
161-
(clock_control_subsys_t)&config->pclken[0],
162-
&clock_rate) < 0) {
165+
int ret = clock_control_get_rate(data->clock,
166+
(clock_control_subsys_t)&config->pclken[0],
167+
&clock_rate);
168+
if (ret < 0) {
163169
LOG_ERR("Failed call clock_control_get_rate(pclken[0])");
164-
return;
170+
return ret;
165171
}
166172
}
167173

@@ -181,7 +187,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t ba
181187

182188
if (presc_idx == ARRAY_SIZE(LPUART_PRESCALER_TAB)) {
183189
LOG_ERR("Unable to set %s to %d", dev->name, baud_rate);
184-
return;
190+
return -EINVAL;
185191
}
186192

187193
presc_val = presc_idx << USART_PRESC_PRESCALER_Pos;
@@ -191,7 +197,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t ba
191197
lpuartdiv = lpuartdiv_calc(clock_rate, baud_rate);
192198
if (lpuartdiv < LPUART_BRR_MIN_VALUE || lpuartdiv > LPUART_BRR_MASK) {
193199
LOG_ERR("Unable to set %s to %d", dev->name, baud_rate);
194-
return;
200+
return -EINVAL;
195201
}
196202
#endif /* USART_PRESC_PRESCALER */
197203
LL_LPUART_SetBaudRate(usart,
@@ -213,6 +219,17 @@ static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t ba
213219
LL_USART_SetOverSampling(usart,
214220
LL_USART_OVERSAMPLING_16);
215221
#endif
222+
223+
uint32_t usartdiv = __LL_USART_DIV_SAMPLING16(clock_rate,
224+
#ifdef USART_PRESC_PRESCALER
225+
LL_USART_PRESCALER_DIV1,
226+
#endif
227+
baud_rate);
228+
if (usartdiv < 16) {
229+
LOG_ERR("Unable to set %s to %d", dev->name, baud_rate);
230+
return -EINVAL;
231+
}
232+
216233
LL_USART_SetBaudRate(usart,
217234
clock_rate,
218235
#ifdef USART_PRESC_PRESCALER
@@ -229,6 +246,8 @@ static inline void uart_stm32_set_baudrate(const struct device *dev, uint32_t ba
229246
#if HAS_LPUART
230247
}
231248
#endif /* HAS_LPUART */
249+
250+
return 0;
232251
}
233252

234253
static inline void uart_stm32_set_parity(const struct device *dev,
@@ -487,7 +506,7 @@ static inline enum uart_config_flow_control uart_stm32_ll2cfg_hwctrl(uint32_t fc
487506
return UART_CFG_FLOW_CTRL_NONE;
488507
}
489508

490-
static void uart_stm32_parameters_set(const struct device *dev,
509+
static int uart_stm32_parameters_set(const struct device *dev,
491510
const struct uart_config *cfg)
492511
{
493512
const struct uart_stm32_config *config = dev->config;
@@ -501,6 +520,7 @@ static void uart_stm32_parameters_set(const struct device *dev,
501520
#if HAS_DRIVER_ENABLE
502521
bool driver_enable = cfg->flow_ctrl == UART_CFG_FLOW_CTRL_RS485;
503522
#endif
523+
int ret = 0;
504524

505525
if (cfg == uart_cfg) {
506526
/* Called via (re-)init function, so the SoC either just booted,
@@ -512,7 +532,10 @@ static void uart_stm32_parameters_set(const struct device *dev,
512532
parity,
513533
stopbits);
514534
uart_stm32_set_hwctrl(dev, flowctrl);
515-
uart_stm32_set_baudrate(dev, cfg->baudrate);
535+
ret = uart_stm32_set_baudrate(dev, cfg->baudrate);
536+
if (ret < 0) {
537+
return ret;
538+
}
516539
} else {
517540
/* Called from application/subsys via uart_configure syscall */
518541
if (parity != uart_stm32_get_parity(dev)) {
@@ -538,10 +561,15 @@ static void uart_stm32_parameters_set(const struct device *dev,
538561
#endif
539562

540563
if (cfg->baudrate != uart_cfg->baudrate) {
541-
uart_stm32_set_baudrate(dev, cfg->baudrate);
564+
ret = uart_stm32_set_baudrate(dev, cfg->baudrate);
565+
if (ret < 0) {
566+
return ret;
567+
}
542568
uart_cfg->baudrate = cfg->baudrate;
543569
}
544570
}
571+
572+
return 0;
545573
}
546574

547575
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
@@ -598,7 +626,9 @@ static int uart_stm32_configure(const struct device *dev,
598626
LL_USART_Disable(usart);
599627

600628
/* Set basic parameters, such as data-/stop-bit, parity, and baudrate */
601-
uart_stm32_parameters_set(dev, cfg);
629+
if (uart_stm32_parameters_set(dev, cfg) < 0) {
630+
return -ENOTSUP;
631+
}
602632

603633
LL_USART_Enable(usart);
604634

@@ -2090,7 +2120,9 @@ static int uart_stm32_registers_configure(const struct device *dev)
20902120
LL_USART_SetTransferDirection(usart, LL_USART_DIRECTION_TX_RX);
20912121

20922122
/* Set basic parameters, such as data-/stop-bit, parity, and baudrate */
2093-
uart_stm32_parameters_set(dev, uart_cfg);
2123+
if (uart_stm32_parameters_set(dev, uart_cfg) < 0) {
2124+
return -EINVAL;
2125+
}
20942126

20952127
/* Enable the single wire / half-duplex mode */
20962128
if (config->single_wire) {

0 commit comments

Comments
 (0)