drivers: serial: stm32 databits depends on parity
On stm32, the M bits defines the length of the frame between the start bit and the stop bit, eventually including the parity bit when enabled. Fix configuration of databits to set correct M bits when parity is enabled. This commit tries to address issue zephyrproject-rtos/zephyr#33351 Signed-off-by: Nicolas VINCENT <nicolas.vincent@vossloh.com>
This commit is contained in:
parent
d4d038b176
commit
573eec1014
1 changed files with 40 additions and 8 deletions
|
@ -227,13 +227,18 @@ static inline enum uart_config_stop_bits uart_stm32_ll2cfg_stopbits(uint32_t sb)
|
|||
}
|
||||
}
|
||||
|
||||
static inline uint32_t uart_stm32_cfg2ll_databits(enum uart_config_data_bits db)
|
||||
static inline uint32_t uart_stm32_cfg2ll_databits(enum uart_config_data_bits db,
|
||||
enum uart_config_parity p)
|
||||
{
|
||||
switch (db) {
|
||||
/* Some MCU's don't support 7B or 9B datawidth */
|
||||
#ifdef LL_USART_DATAWIDTH_7B
|
||||
case UART_CFG_DATA_BITS_7:
|
||||
return LL_USART_DATAWIDTH_7B;
|
||||
if (p == UART_CFG_PARITY_NONE) {
|
||||
return LL_USART_DATAWIDTH_7B;
|
||||
} else {
|
||||
return LL_USART_DATAWIDTH_8B;
|
||||
}
|
||||
#endif /* LL_USART_DATAWIDTH_7B */
|
||||
#ifdef LL_USART_DATAWIDTH_9B
|
||||
case UART_CFG_DATA_BITS_9:
|
||||
|
@ -241,25 +246,45 @@ static inline uint32_t uart_stm32_cfg2ll_databits(enum uart_config_data_bits db)
|
|||
#endif /* LL_USART_DATAWIDTH_9B */
|
||||
case UART_CFG_DATA_BITS_8:
|
||||
default:
|
||||
if (p == UART_CFG_PARITY_NONE) {
|
||||
return LL_USART_DATAWIDTH_8B;
|
||||
#ifdef LL_USART_DATAWIDTH_9B
|
||||
} else {
|
||||
return LL_USART_DATAWIDTH_9B;
|
||||
#endif
|
||||
}
|
||||
return LL_USART_DATAWIDTH_8B;
|
||||
}
|
||||
}
|
||||
|
||||
static inline enum uart_config_data_bits uart_stm32_ll2cfg_databits(uint32_t db)
|
||||
static inline enum uart_config_data_bits uart_stm32_ll2cfg_databits(uint32_t db,
|
||||
uint32_t p)
|
||||
{
|
||||
switch (db) {
|
||||
/* Some MCU's don't support 7B or 9B datawidth */
|
||||
#ifdef LL_USART_DATAWIDTH_7B
|
||||
case LL_USART_DATAWIDTH_7B:
|
||||
return UART_CFG_DATA_BITS_7;
|
||||
if (p == LL_USART_PARITY_NONE) {
|
||||
return UART_CFG_DATA_BITS_7;
|
||||
} else {
|
||||
return UART_CFG_DATA_BITS_6;
|
||||
}
|
||||
#endif /* LL_USART_DATAWIDTH_7B */
|
||||
#ifdef LL_USART_DATAWIDTH_9B
|
||||
case LL_USART_DATAWIDTH_9B:
|
||||
return UART_CFG_DATA_BITS_9;
|
||||
if (p == LL_USART_PARITY_NONE) {
|
||||
return UART_CFG_DATA_BITS_9;
|
||||
} else {
|
||||
return UART_CFG_DATA_BITS_8;
|
||||
}
|
||||
#endif /* LL_USART_DATAWIDTH_9B */
|
||||
case LL_USART_DATAWIDTH_8B:
|
||||
default:
|
||||
return UART_CFG_DATA_BITS_8;
|
||||
if (p == LL_USART_PARITY_NONE) {
|
||||
return UART_CFG_DATA_BITS_8;
|
||||
} else {
|
||||
return UART_CFG_DATA_BITS_7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,7 +327,8 @@ static int uart_stm32_configure(const struct device *dev,
|
|||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const uint32_t parity = uart_stm32_cfg2ll_parity(cfg->parity);
|
||||
const uint32_t stopbits = uart_stm32_cfg2ll_stopbits(cfg->stop_bits);
|
||||
const uint32_t databits = uart_stm32_cfg2ll_databits(cfg->data_bits);
|
||||
const uint32_t databits = uart_stm32_cfg2ll_databits(cfg->data_bits,
|
||||
cfg->parity);
|
||||
const uint32_t flowctrl = uart_stm32_cfg2ll_hwctrl(cfg->flow_ctrl);
|
||||
|
||||
/* Hardware doesn't support mark or space parity */
|
||||
|
@ -311,6 +337,12 @@ static int uart_stm32_configure(const struct device *dev,
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Driver does not supports parity + 9 databits */
|
||||
if ((cfg->parity != UART_CFG_PARITY_NONE) &&
|
||||
(cfg->data_bits == UART_CFG_DATA_BITS_9)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
#if defined(LL_USART_STOPBITS_0_5) && HAS_LPUART_1
|
||||
if (IS_LPUART_INSTANCE(UartInstance) &&
|
||||
(cfg->stop_bits == UART_CFG_STOP_BITS_0_5)) {
|
||||
|
@ -388,7 +420,7 @@ static int uart_stm32_config_get(const struct device *dev,
|
|||
cfg->stop_bits = uart_stm32_ll2cfg_stopbits(
|
||||
uart_stm32_get_stopbits(dev));
|
||||
cfg->data_bits = uart_stm32_ll2cfg_databits(
|
||||
uart_stm32_get_databits(dev));
|
||||
uart_stm32_get_databits(dev), uart_stm32_get_parity(dev));
|
||||
cfg->flow_ctrl = uart_stm32_ll2cfg_hwctrl(
|
||||
uart_stm32_get_hwctrl(dev));
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue