drivers: serial: stm32: store USART instance

Instead of using "generic" uart_device_config fields, store the right
pointer to avoid unnecessary casts. This change makes code simpler and
more idiomatic.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2022-01-25 16:14:12 +01:00 committed by Anas Nashif
commit 32a3a028f2
2 changed files with 137 additions and 140 deletions

View file

@ -41,10 +41,6 @@ LOG_MODULE_REGISTER(uart_stm32);
#define HAS_LPUART_1 (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart1), \ #define HAS_LPUART_1 (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart1), \
st_stm32_lpuart, okay)) st_stm32_lpuart, okay))
#define UART_STRUCT(dev) \
((USART_TypeDef *) \
((const struct uart_stm32_config *const)(dev)->config)->uconf.base)
#if HAS_LPUART_1 #if HAS_LPUART_1
#ifdef USART_PRESC_PRESCALER #ifdef USART_PRESC_PRESCALER
uint32_t lpuartdiv_calc(const uint64_t clock_rate, const uint16_t presc_idx, uint32_t lpuartdiv_calc(const uint64_t clock_rate, const uint16_t presc_idx,
@ -102,7 +98,6 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
{ {
const struct uart_stm32_config *config = dev->config; const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
USART_TypeDef *UartInstance = UART_STRUCT(dev);
uint32_t clock_rate; uint32_t clock_rate;
@ -115,7 +110,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
} }
#if HAS_LPUART_1 #if HAS_LPUART_1
if (IS_LPUART_INSTANCE(UartInstance)) { if (IS_LPUART_INSTANCE(config->usart)) {
uint32_t lpuartdiv; uint32_t lpuartdiv;
#ifdef USART_PRESC_PRESCALER #ifdef USART_PRESC_PRESCALER
uint8_t presc_idx; uint8_t presc_idx;
@ -135,7 +130,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
presc_val = presc_idx << USART_PRESC_PRESCALER_Pos; presc_val = presc_idx << USART_PRESC_PRESCALER_Pos;
LL_LPUART_SetPrescaler(UartInstance, presc_val); LL_LPUART_SetPrescaler(config->usart, presc_val);
#else #else
lpuartdiv = lpuartdiv_calc(clock_rate, baud_rate); lpuartdiv = lpuartdiv_calc(clock_rate, baud_rate);
if (lpuartdiv < LPUART_BRR_MIN_VALUE || lpuartdiv > LPUART_BRR_MASK) { if (lpuartdiv < LPUART_BRR_MIN_VALUE || lpuartdiv > LPUART_BRR_MASK) {
@ -143,7 +138,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
return; return;
} }
#endif /* USART_PRESC_PRESCALER */ #endif /* USART_PRESC_PRESCALER */
LL_LPUART_SetBaudRate(UartInstance, LL_LPUART_SetBaudRate(config->usart,
clock_rate, clock_rate,
#ifdef USART_PRESC_PRESCALER #ifdef USART_PRESC_PRESCALER
presc_val, presc_val,
@ -152,10 +147,10 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
} else { } else {
#endif /* HAS_LPUART_1 */ #endif /* HAS_LPUART_1 */
#ifdef USART_CR1_OVER8 #ifdef USART_CR1_OVER8
LL_USART_SetOverSampling(UartInstance, LL_USART_SetOverSampling(config->usart,
LL_USART_OVERSAMPLING_16); LL_USART_OVERSAMPLING_16);
#endif #endif
LL_USART_SetBaudRate(UartInstance, LL_USART_SetBaudRate(config->usart,
clock_rate, clock_rate,
#ifdef USART_PRESC_PRESCALER #ifdef USART_PRESC_PRESCALER
LL_USART_PRESCALER_DIV1, LL_USART_PRESCALER_DIV1,
@ -173,61 +168,61 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
static inline void uart_stm32_set_parity(const struct device *dev, static inline void uart_stm32_set_parity(const struct device *dev,
uint32_t parity) uint32_t parity)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_SetParity(UartInstance, parity); LL_USART_SetParity(config->usart, parity);
} }
static inline uint32_t uart_stm32_get_parity(const struct device *dev) static inline uint32_t uart_stm32_get_parity(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
return LL_USART_GetParity(UartInstance); return LL_USART_GetParity(config->usart);
} }
static inline void uart_stm32_set_stopbits(const struct device *dev, static inline void uart_stm32_set_stopbits(const struct device *dev,
uint32_t stopbits) uint32_t stopbits)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_SetStopBitsLength(UartInstance, stopbits); LL_USART_SetStopBitsLength(config->usart, stopbits);
} }
static inline uint32_t uart_stm32_get_stopbits(const struct device *dev) static inline uint32_t uart_stm32_get_stopbits(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
return LL_USART_GetStopBitsLength(UartInstance); return LL_USART_GetStopBitsLength(config->usart);
} }
static inline void uart_stm32_set_databits(const struct device *dev, static inline void uart_stm32_set_databits(const struct device *dev,
uint32_t databits) uint32_t databits)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_SetDataWidth(UartInstance, databits); LL_USART_SetDataWidth(config->usart, databits);
} }
static inline uint32_t uart_stm32_get_databits(const struct device *dev) static inline uint32_t uart_stm32_get_databits(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
return LL_USART_GetDataWidth(UartInstance); return LL_USART_GetDataWidth(config->usart);
} }
static inline void uart_stm32_set_hwctrl(const struct device *dev, static inline void uart_stm32_set_hwctrl(const struct device *dev,
uint32_t hwctrl) uint32_t hwctrl)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_SetHWFlowCtrl(UartInstance, hwctrl); LL_USART_SetHWFlowCtrl(config->usart, hwctrl);
} }
static inline uint32_t uart_stm32_get_hwctrl(const struct device *dev) static inline uint32_t uart_stm32_get_hwctrl(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
return LL_USART_GetHWFlowCtrl(UartInstance); return LL_USART_GetHWFlowCtrl(config->usart);
} }
static inline uint32_t uart_stm32_cfg2ll_parity(enum uart_config_parity parity) static inline uint32_t uart_stm32_cfg2ll_parity(enum uart_config_parity parity)
@ -395,8 +390,8 @@ static inline enum uart_config_flow_control uart_stm32_ll2cfg_hwctrl(uint32_t fc
static int uart_stm32_configure(const struct device *dev, static int uart_stm32_configure(const struct device *dev,
const struct uart_config *cfg) const struct uart_config *cfg)
{ {
const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
USART_TypeDef *UartInstance = UART_STRUCT(dev);
const uint32_t parity = uart_stm32_cfg2ll_parity(cfg->parity); const uint32_t parity = uart_stm32_cfg2ll_parity(cfg->parity);
const uint32_t stopbits = uart_stm32_cfg2ll_stopbits(cfg->stop_bits); 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,
@ -416,7 +411,7 @@ static int uart_stm32_configure(const struct device *dev,
} }
#if defined(LL_USART_STOPBITS_0_5) && HAS_LPUART_1 #if defined(LL_USART_STOPBITS_0_5) && HAS_LPUART_1
if (IS_LPUART_INSTANCE(UartInstance) && if (IS_LPUART_INSTANCE(config->usart) &&
(cfg->stop_bits == UART_CFG_STOP_BITS_0_5)) { (cfg->stop_bits == UART_CFG_STOP_BITS_0_5)) {
return -ENOTSUP; return -ENOTSUP;
} }
@ -427,7 +422,7 @@ static int uart_stm32_configure(const struct device *dev,
#endif #endif
#if defined(LL_USART_STOPBITS_1_5) && HAS_LPUART_1 #if defined(LL_USART_STOPBITS_1_5) && HAS_LPUART_1
if (IS_LPUART_INSTANCE(UartInstance) && if (IS_LPUART_INSTANCE(config->usart) &&
(cfg->stop_bits == UART_CFG_STOP_BITS_1_5)) { (cfg->stop_bits == UART_CFG_STOP_BITS_1_5)) {
return -ENOTSUP; return -ENOTSUP;
} }
@ -449,13 +444,13 @@ static int uart_stm32_configure(const struct device *dev,
/* Driver supports only RTS CTS flow control */ /* Driver supports only RTS CTS flow control */
if (cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) { if (cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) {
if (!IS_UART_HWFLOW_INSTANCE(UartInstance) || if (!IS_UART_HWFLOW_INSTANCE(config->usart) ||
UART_CFG_FLOW_CTRL_RTS_CTS != cfg->flow_ctrl) { UART_CFG_FLOW_CTRL_RTS_CTS != cfg->flow_ctrl) {
return -ENOTSUP; return -ENOTSUP;
} }
} }
LL_USART_Disable(UartInstance); LL_USART_Disable(config->usart);
if (parity != uart_stm32_get_parity(dev)) { if (parity != uart_stm32_get_parity(dev)) {
uart_stm32_set_parity(dev, parity); uart_stm32_set_parity(dev, parity);
@ -478,7 +473,7 @@ static int uart_stm32_configure(const struct device *dev,
data->baud_rate = cfg->baudrate; data->baud_rate = cfg->baudrate;
} }
LL_USART_Enable(UartInstance); LL_USART_Enable(config->usart);
return 0; return 0;
}; };
@ -501,22 +496,22 @@ static int uart_stm32_config_get(const struct device *dev,
static int uart_stm32_poll_in(const struct device *dev, unsigned char *c) static int uart_stm32_poll_in(const struct device *dev, unsigned char *c)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
/* Clear overrun error flag */ /* Clear overrun error flag */
if (LL_USART_IsActiveFlag_ORE(UartInstance)) { if (LL_USART_IsActiveFlag_ORE(config->usart)) {
LL_USART_ClearFlag_ORE(UartInstance); LL_USART_ClearFlag_ORE(config->usart);
} }
/* /*
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by * On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
* the uart_err_check function call (on errors flags clearing) * the uart_err_check function call (on errors flags clearing)
*/ */
if (!LL_USART_IsActiveFlag_RXNE(UartInstance)) { if (!LL_USART_IsActiveFlag_RXNE(config->usart)) {
return -1; return -1;
} }
*c = (unsigned char)LL_USART_ReceiveData8(UartInstance); *c = (unsigned char)LL_USART_ReceiveData8(config->usart);
return 0; return 0;
} }
@ -524,7 +519,7 @@ static int uart_stm32_poll_in(const struct device *dev, unsigned char *c)
static void uart_stm32_poll_out(const struct device *dev, static void uart_stm32_poll_out(const struct device *dev,
unsigned char c) unsigned char c)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
#ifdef CONFIG_PM #ifdef CONFIG_PM
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
#endif #endif
@ -536,9 +531,9 @@ static void uart_stm32_poll_out(const struct device *dev,
* interlaced with the characters potentially send with interrupt transmission API * interlaced with the characters potentially send with interrupt transmission API
*/ */
while (1) { while (1) {
if (LL_USART_IsActiveFlag_TXE(UartInstance)) { if (LL_USART_IsActiveFlag_TXE(config->usart)) {
key = irq_lock(); key = irq_lock();
if (LL_USART_IsActiveFlag_TXE(UartInstance)) { if (LL_USART_IsActiveFlag_TXE(config->usart)) {
break; break;
} }
irq_unlock(key); irq_unlock(key);
@ -561,17 +556,17 @@ static void uart_stm32_poll_out(const struct device *dev,
/* Enable TC interrupt so we can release suspend /* Enable TC interrupt so we can release suspend
* constraint when done * constraint when done
*/ */
LL_USART_EnableIT_TC(UartInstance); LL_USART_EnableIT_TC(config->usart);
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
LL_USART_TransmitData8(UartInstance, (uint8_t)c); LL_USART_TransmitData8(config->usart, (uint8_t)c);
irq_unlock(key); irq_unlock(key);
} }
static int uart_stm32_err_check(const struct device *dev) static int uart_stm32_err_check(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
uint32_t err = 0U; uint32_t err = 0U;
/* Check for errors, then clear them. /* Check for errors, then clear them.
@ -579,25 +574,25 @@ static int uart_stm32_err_check(const struct device *dev)
* one is cleared. (e.g. F4X, F1X, and F2X). * one is cleared. (e.g. F4X, F1X, and F2X).
* The stm32 F4X, F1X, and F2X also reads the usart DR when clearing Errors * The stm32 F4X, F1X, and F2X also reads the usart DR when clearing Errors
*/ */
if (LL_USART_IsActiveFlag_ORE(UartInstance)) { if (LL_USART_IsActiveFlag_ORE(config->usart)) {
err |= UART_ERROR_OVERRUN; err |= UART_ERROR_OVERRUN;
} }
if (LL_USART_IsActiveFlag_PE(UartInstance)) { if (LL_USART_IsActiveFlag_PE(config->usart)) {
err |= UART_ERROR_PARITY; err |= UART_ERROR_PARITY;
} }
if (LL_USART_IsActiveFlag_FE(UartInstance)) { if (LL_USART_IsActiveFlag_FE(config->usart)) {
err |= UART_ERROR_FRAMING; err |= UART_ERROR_FRAMING;
} }
#if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT) #if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT)
if (LL_USART_IsActiveFlag_LBD(UartInstance)) { if (LL_USART_IsActiveFlag_LBD(config->usart)) {
err |= UART_BREAK; err |= UART_BREAK;
} }
if (err & UART_BREAK) { if (err & UART_BREAK) {
LL_USART_ClearFlag_LBD(UartInstance); LL_USART_ClearFlag_LBD(config->usart);
} }
#endif #endif
/* Clearing error : /* Clearing error :
@ -606,20 +601,20 @@ static int uart_stm32_err_check(const struct device *dev)
* --> so is the RXNE flag also cleared ! * --> so is the RXNE flag also cleared !
*/ */
if (err & UART_ERROR_OVERRUN) { if (err & UART_ERROR_OVERRUN) {
LL_USART_ClearFlag_ORE(UartInstance); LL_USART_ClearFlag_ORE(config->usart);
} }
if (err & UART_ERROR_PARITY) { if (err & UART_ERROR_PARITY) {
LL_USART_ClearFlag_PE(UartInstance); LL_USART_ClearFlag_PE(config->usart);
} }
if (err & UART_ERROR_FRAMING) { if (err & UART_ERROR_FRAMING) {
LL_USART_ClearFlag_FE(UartInstance); LL_USART_ClearFlag_FE(config->usart);
} }
/* Clear noise error as well, /* Clear noise error as well,
* it is not represented by the errors enum * it is not represented by the errors enum
*/ */
LL_USART_ClearFlag_NE(UartInstance); LL_USART_ClearFlag_NE(config->usart);
return err; return err;
} }
@ -638,11 +633,11 @@ static int uart_stm32_fifo_fill(const struct device *dev,
const uint8_t *tx_data, const uint8_t *tx_data,
int size) int size)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
uint8_t num_tx = 0U; uint8_t num_tx = 0U;
int key; int key;
if (!LL_USART_IsActiveFlag_TXE(UartInstance)) { if (!LL_USART_IsActiveFlag_TXE(config->usart)) {
return num_tx; return num_tx;
} }
@ -650,11 +645,11 @@ static int uart_stm32_fifo_fill(const struct device *dev,
key = irq_lock(); key = irq_lock();
while ((size - num_tx > 0) && while ((size - num_tx > 0) &&
LL_USART_IsActiveFlag_TXE(UartInstance)) { LL_USART_IsActiveFlag_TXE(config->usart)) {
/* TXE flag will be cleared with byte write to DR|RDR register */ /* TXE flag will be cleared with byte write to DR|RDR register */
/* Send a character (8bit , parity none) */ /* Send a character (8bit , parity none) */
LL_USART_TransmitData8(UartInstance, tx_data[num_tx++]); LL_USART_TransmitData8(config->usart, tx_data[num_tx++]);
} }
irq_unlock(key); irq_unlock(key);
@ -665,19 +660,19 @@ static int uart_stm32_fifo_fill(const struct device *dev,
static int uart_stm32_fifo_read(const struct device *dev, uint8_t *rx_data, static int uart_stm32_fifo_read(const struct device *dev, uint8_t *rx_data,
const int size) const int size)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
uint8_t num_rx = 0U; uint8_t num_rx = 0U;
while ((size - num_rx > 0) && while ((size - num_rx > 0) &&
LL_USART_IsActiveFlag_RXNE(UartInstance)) { LL_USART_IsActiveFlag_RXNE(config->usart)) {
/* RXNE flag will be cleared upon read from DR|RDR register */ /* RXNE flag will be cleared upon read from DR|RDR register */
/* Receive a character (8bit , parity none) */ /* Receive a character (8bit , parity none) */
rx_data[num_rx++] = LL_USART_ReceiveData8(UartInstance); rx_data[num_rx++] = LL_USART_ReceiveData8(config->usart);
/* Clear overrun error flag */ /* Clear overrun error flag */
if (LL_USART_IsActiveFlag_ORE(UartInstance)) { if (LL_USART_IsActiveFlag_ORE(config->usart)) {
LL_USART_ClearFlag_ORE(UartInstance); LL_USART_ClearFlag_ORE(config->usart);
/* /*
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by * On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
* the uart_err_check function call (on errors flags clearing) * the uart_err_check function call (on errors flags clearing)
@ -690,7 +685,7 @@ static int uart_stm32_fifo_read(const struct device *dev, uint8_t *rx_data,
static void uart_stm32_irq_tx_enable(const struct device *dev) static void uart_stm32_irq_tx_enable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
#ifdef CONFIG_PM #ifdef CONFIG_PM
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
int key; int key;
@ -702,7 +697,7 @@ static void uart_stm32_irq_tx_enable(const struct device *dev)
data->tx_int_stream_on = true; data->tx_int_stream_on = true;
uart_stm32_pm_constraint_set(dev); uart_stm32_pm_constraint_set(dev);
#endif #endif
LL_USART_EnableIT_TC(UartInstance); LL_USART_EnableIT_TC(config->usart);
#ifdef CONFIG_PM #ifdef CONFIG_PM
irq_unlock(key); irq_unlock(key);
@ -711,7 +706,7 @@ static void uart_stm32_irq_tx_enable(const struct device *dev)
static void uart_stm32_irq_tx_disable(const struct device *dev) static void uart_stm32_irq_tx_disable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
#ifdef CONFIG_PM #ifdef CONFIG_PM
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
int key; int key;
@ -719,7 +714,7 @@ static void uart_stm32_irq_tx_disable(const struct device *dev)
key = irq_lock(); key = irq_lock();
#endif #endif
LL_USART_DisableIT_TC(UartInstance); LL_USART_DisableIT_TC(config->usart);
#ifdef CONFIG_PM #ifdef CONFIG_PM
data->tx_int_stream_on = false; data->tx_int_stream_on = false;
@ -733,83 +728,83 @@ static void uart_stm32_irq_tx_disable(const struct device *dev)
static int uart_stm32_irq_tx_ready(const struct device *dev) static int uart_stm32_irq_tx_ready(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
return LL_USART_IsActiveFlag_TXE(UartInstance) && return LL_USART_IsActiveFlag_TXE(config->usart) &&
LL_USART_IsEnabledIT_TC(UartInstance); LL_USART_IsEnabledIT_TC(config->usart);
} }
static int uart_stm32_irq_tx_complete(const struct device *dev) static int uart_stm32_irq_tx_complete(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
return LL_USART_IsActiveFlag_TC(UartInstance); return LL_USART_IsActiveFlag_TC(config->usart);
} }
static void uart_stm32_irq_rx_enable(const struct device *dev) static void uart_stm32_irq_rx_enable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_EnableIT_RXNE(UartInstance); LL_USART_EnableIT_RXNE(config->usart);
} }
static void uart_stm32_irq_rx_disable(const struct device *dev) static void uart_stm32_irq_rx_disable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_DisableIT_RXNE(UartInstance); LL_USART_DisableIT_RXNE(config->usart);
} }
static int uart_stm32_irq_rx_ready(const struct device *dev) static int uart_stm32_irq_rx_ready(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
/* /*
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by * On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
* the uart_err_check function call (on errors flags clearing) * the uart_err_check function call (on errors flags clearing)
*/ */
return LL_USART_IsActiveFlag_RXNE(UartInstance); return LL_USART_IsActiveFlag_RXNE(config->usart);
} }
static void uart_stm32_irq_err_enable(const struct device *dev) static void uart_stm32_irq_err_enable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
/* Enable FE, ORE interruptions */ /* Enable FE, ORE interruptions */
LL_USART_EnableIT_ERROR(UartInstance); LL_USART_EnableIT_ERROR(config->usart);
#if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT) #if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT)
/* Enable Line break detection */ /* Enable Line break detection */
if (IS_UART_LIN_INSTANCE(UartInstance)) { if (IS_UART_LIN_INSTANCE(config->usart)) {
LL_USART_EnableIT_LBD(UartInstance); LL_USART_EnableIT_LBD(config->usart);
} }
#endif #endif
/* Enable parity error interruption */ /* Enable parity error interruption */
LL_USART_EnableIT_PE(UartInstance); LL_USART_EnableIT_PE(config->usart);
} }
static void uart_stm32_irq_err_disable(const struct device *dev) static void uart_stm32_irq_err_disable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
/* Disable FE, ORE interruptions */ /* Disable FE, ORE interruptions */
LL_USART_DisableIT_ERROR(UartInstance); LL_USART_DisableIT_ERROR(config->usart);
#if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT) #if !defined(CONFIG_SOC_SERIES_STM32F0X) || defined(USART_LIN_SUPPORT)
/* Disable Line break detection */ /* Disable Line break detection */
if (IS_UART_LIN_INSTANCE(UartInstance)) { if (IS_UART_LIN_INSTANCE(config->usart)) {
LL_USART_DisableIT_LBD(UartInstance); LL_USART_DisableIT_LBD(config->usart);
} }
#endif #endif
/* Disable parity error interruption */ /* Disable parity error interruption */
LL_USART_DisableIT_PE(UartInstance); LL_USART_DisableIT_PE(config->usart);
} }
static int uart_stm32_irq_is_pending(const struct device *dev) static int uart_stm32_irq_is_pending(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
return ((LL_USART_IsActiveFlag_RXNE(UartInstance) && return ((LL_USART_IsActiveFlag_RXNE(config->usart) &&
LL_USART_IsEnabledIT_RXNE(UartInstance)) || LL_USART_IsEnabledIT_RXNE(config->usart)) ||
(LL_USART_IsActiveFlag_TC(UartInstance) && (LL_USART_IsActiveFlag_TC(config->usart) &&
LL_USART_IsEnabledIT_TC(UartInstance))); LL_USART_IsEnabledIT_TC(config->usart)));
} }
static int uart_stm32_irq_update(const struct device *dev) static int uart_stm32_irq_update(const struct device *dev)
@ -964,18 +959,18 @@ static void uart_stm32_isr(const struct device *dev)
{ {
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
#if defined(CONFIG_PM) || defined(CONFIG_UART_ASYNC_API) #if defined(CONFIG_PM) || defined(CONFIG_UART_ASYNC_API)
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
#endif #endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
if (LL_USART_IsEnabledIT_TC(UartInstance) && if (LL_USART_IsEnabledIT_TC(config->usart) &&
LL_USART_IsActiveFlag_TC(UartInstance)) { LL_USART_IsActiveFlag_TC(config->usart)) {
if (data->tx_poll_stream_on) { if (data->tx_poll_stream_on) {
/* A poll stream transmition just completed, /* A poll stream transmition just completed,
* allow system to suspend * allow system to suspend
*/ */
LL_USART_DisableIT_TC(UartInstance); LL_USART_DisableIT_TC(config->usart);
data->tx_poll_stream_on = false; data->tx_poll_stream_on = false;
uart_stm32_pm_constraint_release(dev); uart_stm32_pm_constraint_release(dev);
} }
@ -993,10 +988,10 @@ static void uart_stm32_isr(const struct device *dev)
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
#ifdef CONFIG_UART_ASYNC_API #ifdef CONFIG_UART_ASYNC_API
if (LL_USART_IsEnabledIT_IDLE(UartInstance) && if (LL_USART_IsEnabledIT_IDLE(config->usart) &&
LL_USART_IsActiveFlag_IDLE(UartInstance)) { LL_USART_IsActiveFlag_IDLE(config->usart)) {
LL_USART_ClearFlag_IDLE(UartInstance); LL_USART_ClearFlag_IDLE(config->usart);
LOG_DBG("idle interrupt occurred"); LOG_DBG("idle interrupt occurred");
@ -1007,25 +1002,25 @@ static void uart_stm32_isr(const struct device *dev)
if (data->dma_rx.timeout == 0) { if (data->dma_rx.timeout == 0) {
uart_stm32_dma_rx_flush(dev); uart_stm32_dma_rx_flush(dev);
} }
} else if (LL_USART_IsEnabledIT_TC(UartInstance) && } else if (LL_USART_IsEnabledIT_TC(config->usart) &&
LL_USART_IsActiveFlag_TC(UartInstance)) { LL_USART_IsActiveFlag_TC(config->usart)) {
LL_USART_DisableIT_TC(UartInstance); LL_USART_DisableIT_TC(config->usart);
LL_USART_ClearFlag_TC(UartInstance); LL_USART_ClearFlag_TC(config->usart);
/* Generate TX_DONE event when transmission is done */ /* Generate TX_DONE event when transmission is done */
async_evt_tx_done(data); async_evt_tx_done(data);
#ifdef CONFIG_PM #ifdef CONFIG_PM
uart_stm32_pm_constraint_release(dev); uart_stm32_pm_constraint_release(dev);
#endif #endif
} else if (LL_USART_IsEnabledIT_RXNE(UartInstance) && } else if (LL_USART_IsEnabledIT_RXNE(config->usart) &&
LL_USART_IsActiveFlag_RXNE(UartInstance)) { LL_USART_IsActiveFlag_RXNE(config->usart)) {
#ifdef USART_SR_RXNE #ifdef USART_SR_RXNE
/* clear the RXNE flag, because Rx data was not read */ /* clear the RXNE flag, because Rx data was not read */
LL_USART_ClearFlag_RXNE(UartInstance); LL_USART_ClearFlag_RXNE(config->usart);
#else #else
/* clear the RXNE by flushing the fifo, because Rx data was not read */ /* clear the RXNE by flushing the fifo, because Rx data was not read */
LL_USART_RequestRxDataFlush(UartInstance); LL_USART_RequestRxDataFlush(config->usart);
#endif /* USART_SR_RXNE */ #endif /* USART_SR_RXNE */
} }
@ -1051,24 +1046,24 @@ static int uart_stm32_async_callback_set(const struct device *dev,
static inline void uart_stm32_dma_tx_enable(const struct device *dev) static inline void uart_stm32_dma_tx_enable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_EnableDMAReq_TX(UartInstance); LL_USART_EnableDMAReq_TX(config->usart);
} }
static inline void uart_stm32_dma_tx_disable(const struct device *dev) static inline void uart_stm32_dma_tx_disable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
LL_USART_DisableDMAReq_TX(UartInstance); LL_USART_DisableDMAReq_TX(config->usart);
} }
static inline void uart_stm32_dma_rx_enable(const struct device *dev) static inline void uart_stm32_dma_rx_enable(const struct device *dev)
{ {
USART_TypeDef *UartInstance = UART_STRUCT(dev); const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
LL_USART_EnableDMAReq_RX(UartInstance); LL_USART_EnableDMAReq_RX(config->usart);
data->dma_rx.enabled = true; data->dma_rx.enabled = true;
} }
@ -1082,8 +1077,8 @@ static inline void uart_stm32_dma_rx_disable(const struct device *dev)
static int uart_stm32_async_rx_disable(const struct device *dev) static int uart_stm32_async_rx_disable(const struct device *dev)
{ {
const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
USART_TypeDef *UartInstance = UART_STRUCT(dev);
struct uart_event disabled_event = { struct uart_event disabled_event = {
.type = UART_RX_DISABLED .type = UART_RX_DISABLED
}; };
@ -1093,7 +1088,7 @@ static int uart_stm32_async_rx_disable(const struct device *dev)
return -EFAULT; return -EFAULT;
} }
LL_USART_DisableIT_IDLE(UartInstance); LL_USART_DisableIT_IDLE(config->usart);
uart_stm32_dma_rx_flush(dev); uart_stm32_dma_rx_flush(dev);
@ -1109,7 +1104,7 @@ static int uart_stm32_async_rx_disable(const struct device *dev)
data->rx_next_buffer_len = 0; data->rx_next_buffer_len = 0;
/* When async rx is disabled, enable interruptable instance of uart to function normally*/ /* When async rx is disabled, enable interruptable instance of uart to function normally*/
LL_USART_EnableIT_RXNE(UartInstance); LL_USART_EnableIT_RXNE(config->usart);
LOG_DBG("rx: disabled"); LOG_DBG("rx: disabled");
@ -1144,6 +1139,7 @@ void uart_stm32_dma_tx_cb(const struct device *dma_dev, void *user_data,
static void uart_stm32_dma_replace_buffer(const struct device *dev) static void uart_stm32_dma_replace_buffer(const struct device *dev)
{ {
const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
/* Replace the buffer and relod the DMA */ /* Replace the buffer and relod the DMA */
@ -1166,9 +1162,7 @@ static void uart_stm32_dma_replace_buffer(const struct device *dev)
dma_start(data->dma_rx.dma_dev, data->dma_rx.dma_channel); dma_start(data->dma_rx.dma_dev, data->dma_rx.dma_channel);
USART_TypeDef *UartInstance = UART_STRUCT(dev); LL_USART_ClearFlag_IDLE(config->usart);
LL_USART_ClearFlag_IDLE(UartInstance);
/* Request next buffer */ /* Request next buffer */
async_evt_rx_buf_request(data); async_evt_rx_buf_request(data);
@ -1214,8 +1208,8 @@ void uart_stm32_dma_rx_cb(const struct device *dma_dev, void *user_data,
static int uart_stm32_async_tx(const struct device *dev, static int uart_stm32_async_tx(const struct device *dev,
const uint8_t *tx_data, size_t buf_size, int32_t timeout) const uint8_t *tx_data, size_t buf_size, int32_t timeout)
{ {
const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
USART_TypeDef *UartInstance = UART_STRUCT(dev);
int ret; int ret;
if (data->dma_tx.dma_dev == NULL) { if (data->dma_tx.dma_dev == NULL) {
@ -1233,10 +1227,10 @@ static int uart_stm32_async_tx(const struct device *dev,
LOG_DBG("tx: l=%d", data->dma_tx.buffer_length); LOG_DBG("tx: l=%d", data->dma_tx.buffer_length);
/* Clear TC flag */ /* Clear TC flag */
LL_USART_ClearFlag_TC(UartInstance); LL_USART_ClearFlag_TC(config->usart);
/* Enable TC interrupt so we can signal correct TX done */ /* Enable TC interrupt so we can signal correct TX done */
LL_USART_EnableIT_TC(UartInstance); LL_USART_EnableIT_TC(config->usart);
/* set source address */ /* set source address */
data->dma_tx.blk_cfg.source_address = (uint32_t)data->dma_tx.buffer; data->dma_tx.blk_cfg.source_address = (uint32_t)data->dma_tx.buffer;
@ -1273,8 +1267,8 @@ static int uart_stm32_async_tx(const struct device *dev,
static int uart_stm32_async_rx_enable(const struct device *dev, static int uart_stm32_async_rx_enable(const struct device *dev,
uint8_t *rx_buf, size_t buf_size, int32_t timeout) uint8_t *rx_buf, size_t buf_size, int32_t timeout)
{ {
const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
USART_TypeDef *UartInstance = UART_STRUCT(dev);
int ret; int ret;
if (data->dma_rx.dma_dev == NULL) { if (data->dma_rx.dma_dev == NULL) {
@ -1293,7 +1287,7 @@ static int uart_stm32_async_rx_enable(const struct device *dev,
data->dma_rx.timeout = timeout; data->dma_rx.timeout = timeout;
/* Disable RX interrupts to let DMA to handle it */ /* Disable RX interrupts to let DMA to handle it */
LL_USART_DisableIT_RXNE(UartInstance); LL_USART_DisableIT_RXNE(config->usart);
data->dma_rx.blk_cfg.block_size = buf_size; data->dma_rx.blk_cfg.block_size = buf_size;
data->dma_rx.blk_cfg.dest_address = (uint32_t)data->dma_rx.buffer; data->dma_rx.blk_cfg.dest_address = (uint32_t)data->dma_rx.buffer;
@ -1317,10 +1311,10 @@ static int uart_stm32_async_rx_enable(const struct device *dev,
/* Enable IRQ IDLE to define the end of a /* Enable IRQ IDLE to define the end of a
* RX DMA transaction. * RX DMA transaction.
*/ */
LL_USART_ClearFlag_IDLE(UartInstance); LL_USART_ClearFlag_IDLE(config->usart);
LL_USART_EnableIT_IDLE(UartInstance); LL_USART_EnableIT_IDLE(config->usart);
LL_USART_EnableIT_ERROR(UartInstance); LL_USART_EnableIT_ERROR(config->usart);
/* Request next buffer */ /* Request next buffer */
async_evt_rx_buf_request(data); async_evt_rx_buf_request(data);
@ -1398,8 +1392,8 @@ static int uart_stm32_async_rx_buf_rsp(const struct device *dev, uint8_t *buf,
static int uart_stm32_async_init(const struct device *dev) static int uart_stm32_async_init(const struct device *dev)
{ {
const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
USART_TypeDef *UartInstance = UART_STRUCT(dev);
data->uart_dev = dev; data->uart_dev = dev;
@ -1432,10 +1426,10 @@ static int uart_stm32_async_init(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32F4X) || \ defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_SOC_SERIES_STM32L1X) defined(CONFIG_SOC_SERIES_STM32L1X)
data->dma_rx.blk_cfg.source_address = data->dma_rx.blk_cfg.source_address =
LL_USART_DMA_GetRegAddr(UartInstance); LL_USART_DMA_GetRegAddr(config->usart);
#else #else
data->dma_rx.blk_cfg.source_address = data->dma_rx.blk_cfg.source_address =
LL_USART_DMA_GetRegAddr(UartInstance, LL_USART_DMA_GetRegAddr(config->usart,
LL_USART_DMA_REG_DATA_RECEIVE); LL_USART_DMA_REG_DATA_RECEIVE);
#endif #endif
@ -1471,10 +1465,10 @@ static int uart_stm32_async_init(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32F4X) || \ defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_SOC_SERIES_STM32L1X) defined(CONFIG_SOC_SERIES_STM32L1X)
data->dma_tx.blk_cfg.dest_address = data->dma_tx.blk_cfg.dest_address =
LL_USART_DMA_GetRegAddr(UartInstance); LL_USART_DMA_GetRegAddr(config->usart);
#else #else
data->dma_tx.blk_cfg.dest_address = data->dma_tx.blk_cfg.dest_address =
LL_USART_DMA_GetRegAddr(UartInstance, LL_USART_DMA_GetRegAddr(config->usart,
LL_USART_DMA_REG_DATA_TRANSMIT); LL_USART_DMA_REG_DATA_TRANSMIT);
#endif #endif
@ -1550,7 +1544,6 @@ static int uart_stm32_init(const struct device *dev)
{ {
const struct uart_stm32_config *config = dev->config; const struct uart_stm32_config *config = dev->config;
struct uart_stm32_data *data = dev->data; struct uart_stm32_data *data = dev->data;
USART_TypeDef *UartInstance = UART_STRUCT(dev);
uint32_t ll_parity; uint32_t ll_parity;
uint32_t ll_datawidth; uint32_t ll_datawidth;
int err; int err;
@ -1568,10 +1561,10 @@ static int uart_stm32_init(const struct device *dev)
return err; return err;
} }
LL_USART_Disable(UartInstance); LL_USART_Disable(config->usart);
/* TX/RX direction */ /* TX/RX direction */
LL_USART_SetTransferDirection(UartInstance, LL_USART_SetTransferDirection(config->usart,
LL_USART_DIRECTION_TX_RX); LL_USART_DIRECTION_TX_RX);
/* Determine the datawidth and parity. If we use other parity than /* Determine the datawidth and parity. If we use other parity than
@ -1596,7 +1589,7 @@ static int uart_stm32_init(const struct device *dev)
} }
/* Set datawidth and parity, 1 start bit, 1 stop bit */ /* Set datawidth and parity, 1 start bit, 1 stop bit */
LL_USART_ConfigCharacter(UartInstance, LL_USART_ConfigCharacter(config->usart,
ll_datawidth, ll_datawidth,
ll_parity, ll_parity,
LL_USART_STOPBITS_1); LL_USART_STOPBITS_1);
@ -1610,20 +1603,20 @@ static int uart_stm32_init(const struct device *dev)
/* Enable the single wire / half-duplex mode */ /* Enable the single wire / half-duplex mode */
if (config->single_wire) { if (config->single_wire) {
LL_USART_EnableHalfDuplex(UartInstance); LL_USART_EnableHalfDuplex(config->usart);
} }
LL_USART_Enable(UartInstance); LL_USART_Enable(config->usart);
#ifdef USART_ISR_TEACK #ifdef USART_ISR_TEACK
/* Wait until TEACK flag is set */ /* Wait until TEACK flag is set */
while (!(LL_USART_IsActiveFlag_TEACK(UartInstance))) { while (!(LL_USART_IsActiveFlag_TEACK(config->usart))) {
} }
#endif /* !USART_ISR_TEACK */ #endif /* !USART_ISR_TEACK */
#ifdef USART_ISR_REACK #ifdef USART_ISR_REACK
/* Wait until REACK flag is set */ /* Wait until REACK flag is set */
while (!(LL_USART_IsActiveFlag_REACK(UartInstance))) { while (!(LL_USART_IsActiveFlag_REACK(config->usart))) {
} }
#endif /* !USART_ISR_REACK */ #endif /* !USART_ISR_REACK */
@ -1719,8 +1712,8 @@ STM32_UART_IRQ_HANDLER_DECL(index) \
PINCTRL_DT_INST_DEFINE(index); \ PINCTRL_DT_INST_DEFINE(index); \
\ \
static const struct uart_stm32_config uart_stm32_cfg_##index = { \ static const struct uart_stm32_config uart_stm32_cfg_##index = { \
.usart = (USART_TypeDef *)DT_INST_REG_ADDR(index), \
.uconf = { \ .uconf = { \
.base = (uint8_t *)DT_INST_REG_ADDR(index), \
STM32_UART_IRQ_HANDLER_FUNC(index) \ STM32_UART_IRQ_HANDLER_FUNC(index) \
}, \ }, \
.pclken = { .bus = DT_INST_CLOCKS_CELL(index, bus), \ .pclken = { .bus = DT_INST_CLOCKS_CELL(index, bus), \

View file

@ -14,8 +14,12 @@
#include <drivers/pinctrl.h> #include <drivers/pinctrl.h>
#include <stm32_ll_usart.h>
/* device config */ /* device config */
struct uart_stm32_config { struct uart_stm32_config {
/* USART instance */
USART_TypeDef *usart;
struct uart_device_config uconf; struct uart_device_config uconf;
/* clock subsystem driving this peripheral */ /* clock subsystem driving this peripheral */
struct stm32_pclken pclken; struct stm32_pclken pclken;