drivers: serial: stm32: Fix flawed runtime config check

Replace incorrect and limited runtime parity/data bits conditional
configuration with build-time logic using BUILD_ASSERT. This allows for
more flexible UART configurations, while preventing invalid DTS
configurations at build-time.

Signed-off-by: Kenneth J. Miller <ken@miller.ec>
This commit is contained in:
Kenneth J. Miller 2023-06-20 01:45:32 +02:00 committed by Carles Cufí
commit 044de03d57

View file

@ -2166,6 +2166,112 @@ static void uart_stm32_irq_config_func_##index(const struct device *dev) \
#define STM32_UART_PM_WAKEUP(index) /* Not used */
#endif
/* Ensure DTS doesn't present an incompatible parity configuration.
* Mark/space parity isn't supported on the STM32 family.
* If 9 data bits are configured, ensure that a parity bit isn't set.
*/
#define STM32_UART_CHECK_DT_PARITY(index) \
BUILD_ASSERT( \
!(DT_INST_ENUM_IDX_OR(index, parity, STM32_UART_DEFAULT_PARITY) \
== UART_CFG_PARITY_MARK || \
DT_INST_ENUM_IDX_OR(index, parity, STM32_UART_DEFAULT_PARITY) \
== UART_CFG_PARITY_SPACE), \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported parity configuration"); \
BUILD_ASSERT( \
!(DT_INST_ENUM_IDX_OR(index, parity, STM32_UART_DEFAULT_PARITY) \
!= UART_CFG_PARITY_NONE && \
DT_INST_ENUM_IDX_OR(index, data_bits, \
STM32_UART_DEFAULT_DATA_BITS) \
== UART_CFG_DATA_BITS_9), \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported parity + data bits combination");
/* Ensure DTS doesn't present an incompatible data bits configuration
* The STM32 family doesn't support 5 data bits, or 6 data bits without parity.
* Only some series support 7 data bits.
*/
#ifdef LL_USART_DATAWIDTH_7B
#define STM32_UART_CHECK_DT_DATA_BITS(index) \
BUILD_ASSERT( \
!(DT_INST_ENUM_IDX_OR(index, data_bits, \
STM32_UART_DEFAULT_DATA_BITS) \
== UART_CFG_DATA_BITS_5 || \
(DT_INST_ENUM_IDX_OR(index, data_bits, \
STM32_UART_DEFAULT_DATA_BITS) \
== UART_CFG_DATA_BITS_6 && \
DT_INST_ENUM_IDX_OR(index, parity, \
STM32_UART_DEFAULT_PARITY) \
== UART_CFG_PARITY_NONE)), \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported data bits configuration");
#else
#define STM32_UART_CHECK_DT_DATA_BITS(index) \
BUILD_ASSERT( \
!(DT_INST_ENUM_IDX_OR(index, data_bits, \
STM32_UART_DEFAULT_DATA_BITS) \
== UART_CFG_DATA_BITS_5 || \
DT_INST_ENUM_IDX_OR(index, data_bits, \
STM32_UART_DEFAULT_DATA_BITS) \
== UART_CFG_DATA_BITS_6 || \
(DT_INST_ENUM_IDX_OR(index, data_bits, \
STM32_UART_DEFAULT_DATA_BITS) \
== UART_CFG_DATA_BITS_7 && \
DT_INST_ENUM_IDX_OR(index, parity, \
STM32_UART_DEFAULT_PARITY) \
== UART_CFG_PARITY_NONE)), \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported data bits configuration");
#endif
/* Ensure DTS doesn't present an incompatible stop bits configuration.
* Some STM32 series USARTs don't support 0.5 stop bits, and it generally isn't
* supported for LPUART.
*/
#ifndef LL_USART_STOPBITS_0_5
#define STM32_UART_CHECK_DT_STOP_BITS_0_5(index) \
BUILD_ASSERT( \
!(DT_INST_ENUM_IDX_OR(index, stop_bits, \
STM32_UART_DEFAULT_STOP_BITS) \
== UART_CFG_STOP_BITS_0_5), \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported stop bits configuration");
/* LPUARTs don't support 0.5 stop bits configurations */
#else
#define STM32_UART_CHECK_DT_STOP_BITS_0_5(index) \
BUILD_ASSERT( \
!(DT_HAS_COMPAT_STATUS_OKAY(st_stm32_lpuart) && \
DT_INST_ENUM_IDX_OR(index, stop_bits, \
STM32_UART_DEFAULT_STOP_BITS) \
== UART_CFG_STOP_BITS_0_5), \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported stop bits configuration");
#endif
/* Ensure DTS doesn't present an incompatible stop bits configuration.
* Some STM32 series USARTs don't support 1.5 stop bits, and it generally isn't
* supported for LPUART.
*/
#ifndef LL_USART_STOPBITS_1_5
#define STM32_UART_CHECK_DT_STOP_BITS_1_5(index) \
BUILD_ASSERT( \
DT_INST_ENUM_IDX_OR(index, stop_bits, \
STM32_UART_DEFAULT_STOP_BITS) \
!= UART_CFG_STOP_BITS_1_5, \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported stop bits configuration");
/* LPUARTs don't support 1.5 stop bits configurations */
#else
#define STM32_UART_CHECK_DT_STOP_BITS_1_5(index) \
BUILD_ASSERT( \
!(DT_HAS_COMPAT_STATUS_OKAY(st_stm32_lpuart) && \
DT_INST_ENUM_IDX_OR(index, stop_bits, \
STM32_UART_DEFAULT_STOP_BITS) \
== UART_CFG_STOP_BITS_1_5), \
"Node " DT_NODE_PATH(DT_DRV_INST(index)) \
" has unsupported stop bits configuration");
#endif
#define STM32_UART_INIT(index) \
STM32_UART_IRQ_HANDLER_DECL(index) \
\
@ -2221,6 +2327,11 @@ DEVICE_DT_INST_DEFINE(index, \
PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
&uart_stm32_driver_api); \
\
STM32_UART_IRQ_HANDLER(index)
STM32_UART_IRQ_HANDLER(index) \
\
STM32_UART_CHECK_DT_PARITY(index) \
STM32_UART_CHECK_DT_DATA_BITS(index) \
STM32_UART_CHECK_DT_STOP_BITS_0_5(index) \
STM32_UART_CHECK_DT_STOP_BITS_1_5(index)
DT_INST_FOREACH_STATUS_OKAY(STM32_UART_INIT)