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:
parent
34339e2560
commit
32a3a028f2
2 changed files with 137 additions and 140 deletions
|
@ -41,10 +41,6 @@ LOG_MODULE_REGISTER(uart_stm32);
|
|||
#define HAS_LPUART_1 (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(lpuart1), \
|
||||
st_stm32_lpuart, okay))
|
||||
|
||||
#define UART_STRUCT(dev) \
|
||||
((USART_TypeDef *) \
|
||||
((const struct uart_stm32_config *const)(dev)->config)->uconf.base)
|
||||
|
||||
#if HAS_LPUART_1
|
||||
#ifdef USART_PRESC_PRESCALER
|
||||
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;
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
|
||||
uint32_t clock_rate;
|
||||
|
||||
|
@ -115,7 +110,7 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
|
|||
}
|
||||
|
||||
#if HAS_LPUART_1
|
||||
if (IS_LPUART_INSTANCE(UartInstance)) {
|
||||
if (IS_LPUART_INSTANCE(config->usart)) {
|
||||
uint32_t lpuartdiv;
|
||||
#ifdef USART_PRESC_PRESCALER
|
||||
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;
|
||||
|
||||
LL_LPUART_SetPrescaler(UartInstance, presc_val);
|
||||
LL_LPUART_SetPrescaler(config->usart, presc_val);
|
||||
#else
|
||||
lpuartdiv = lpuartdiv_calc(clock_rate, baud_rate);
|
||||
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;
|
||||
}
|
||||
#endif /* USART_PRESC_PRESCALER */
|
||||
LL_LPUART_SetBaudRate(UartInstance,
|
||||
LL_LPUART_SetBaudRate(config->usart,
|
||||
clock_rate,
|
||||
#ifdef USART_PRESC_PRESCALER
|
||||
presc_val,
|
||||
|
@ -152,10 +147,10 @@ static inline void uart_stm32_set_baudrate(const struct device *dev,
|
|||
} else {
|
||||
#endif /* HAS_LPUART_1 */
|
||||
#ifdef USART_CR1_OVER8
|
||||
LL_USART_SetOverSampling(UartInstance,
|
||||
LL_USART_SetOverSampling(config->usart,
|
||||
LL_USART_OVERSAMPLING_16);
|
||||
#endif
|
||||
LL_USART_SetBaudRate(UartInstance,
|
||||
LL_USART_SetBaudRate(config->usart,
|
||||
clock_rate,
|
||||
#ifdef USART_PRESC_PRESCALER
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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,
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -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,
|
||||
const struct uart_config *cfg)
|
||||
{
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
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 stopbits = uart_stm32_cfg2ll_stopbits(cfg->stop_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 (IS_LPUART_INSTANCE(UartInstance) &&
|
||||
if (IS_LPUART_INSTANCE(config->usart) &&
|
||||
(cfg->stop_bits == UART_CFG_STOP_BITS_0_5)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
@ -427,7 +422,7 @@ static int uart_stm32_configure(const struct device *dev,
|
|||
#endif
|
||||
|
||||
#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)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
@ -449,13 +444,13 @@ static int uart_stm32_configure(const struct device *dev,
|
|||
|
||||
/* Driver supports only RTS CTS flow control */
|
||||
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) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
LL_USART_Disable(UartInstance);
|
||||
LL_USART_Disable(config->usart);
|
||||
|
||||
if (parity != uart_stm32_get_parity(dev)) {
|
||||
uart_stm32_set_parity(dev, parity);
|
||||
|
@ -478,7 +473,7 @@ static int uart_stm32_configure(const struct device *dev,
|
|||
data->baud_rate = cfg->baudrate;
|
||||
}
|
||||
|
||||
LL_USART_Enable(UartInstance);
|
||||
LL_USART_Enable(config->usart);
|
||||
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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
|
||||
/* Clear overrun error flag */
|
||||
if (LL_USART_IsActiveFlag_ORE(UartInstance)) {
|
||||
LL_USART_ClearFlag_ORE(UartInstance);
|
||||
if (LL_USART_IsActiveFlag_ORE(config->usart)) {
|
||||
LL_USART_ClearFlag_ORE(config->usart);
|
||||
}
|
||||
|
||||
/*
|
||||
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
|
||||
* 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;
|
||||
}
|
||||
|
||||
*c = (unsigned char)LL_USART_ReceiveData8(UartInstance);
|
||||
*c = (unsigned char)LL_USART_ReceiveData8(config->usart);
|
||||
|
||||
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,
|
||||
unsigned char c)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
#ifdef CONFIG_PM
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
#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
|
||||
*/
|
||||
while (1) {
|
||||
if (LL_USART_IsActiveFlag_TXE(UartInstance)) {
|
||||
if (LL_USART_IsActiveFlag_TXE(config->usart)) {
|
||||
key = irq_lock();
|
||||
if (LL_USART_IsActiveFlag_TXE(UartInstance)) {
|
||||
if (LL_USART_IsActiveFlag_TXE(config->usart)) {
|
||||
break;
|
||||
}
|
||||
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
|
||||
* constraint when done
|
||||
*/
|
||||
LL_USART_EnableIT_TC(UartInstance);
|
||||
LL_USART_EnableIT_TC(config->usart);
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
LL_USART_TransmitData8(UartInstance, (uint8_t)c);
|
||||
LL_USART_TransmitData8(config->usart, (uint8_t)c);
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* 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).
|
||||
* 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;
|
||||
}
|
||||
|
||||
if (LL_USART_IsActiveFlag_PE(UartInstance)) {
|
||||
if (LL_USART_IsActiveFlag_PE(config->usart)) {
|
||||
err |= UART_ERROR_PARITY;
|
||||
}
|
||||
|
||||
if (LL_USART_IsActiveFlag_FE(UartInstance)) {
|
||||
if (LL_USART_IsActiveFlag_FE(config->usart)) {
|
||||
err |= UART_ERROR_FRAMING;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
if (err & UART_BREAK) {
|
||||
LL_USART_ClearFlag_LBD(UartInstance);
|
||||
LL_USART_ClearFlag_LBD(config->usart);
|
||||
}
|
||||
#endif
|
||||
/* Clearing error :
|
||||
|
@ -606,20 +601,20 @@ static int uart_stm32_err_check(const struct device *dev)
|
|||
* --> so is the RXNE flag also cleared !
|
||||
*/
|
||||
if (err & UART_ERROR_OVERRUN) {
|
||||
LL_USART_ClearFlag_ORE(UartInstance);
|
||||
LL_USART_ClearFlag_ORE(config->usart);
|
||||
}
|
||||
|
||||
if (err & UART_ERROR_PARITY) {
|
||||
LL_USART_ClearFlag_PE(UartInstance);
|
||||
LL_USART_ClearFlag_PE(config->usart);
|
||||
}
|
||||
|
||||
if (err & UART_ERROR_FRAMING) {
|
||||
LL_USART_ClearFlag_FE(UartInstance);
|
||||
LL_USART_ClearFlag_FE(config->usart);
|
||||
}
|
||||
/* Clear noise error as well,
|
||||
* it is not represented by the errors enum
|
||||
*/
|
||||
LL_USART_ClearFlag_NE(UartInstance);
|
||||
LL_USART_ClearFlag_NE(config->usart);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -638,11 +633,11 @@ static int uart_stm32_fifo_fill(const struct device *dev,
|
|||
const uint8_t *tx_data,
|
||||
int size)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
uint8_t num_tx = 0U;
|
||||
int key;
|
||||
|
||||
if (!LL_USART_IsActiveFlag_TXE(UartInstance)) {
|
||||
if (!LL_USART_IsActiveFlag_TXE(config->usart)) {
|
||||
return num_tx;
|
||||
}
|
||||
|
||||
|
@ -650,11 +645,11 @@ static int uart_stm32_fifo_fill(const struct device *dev,
|
|||
key = irq_lock();
|
||||
|
||||
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 */
|
||||
|
||||
/* 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);
|
||||
|
@ -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,
|
||||
const int size)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
uint8_t num_rx = 0U;
|
||||
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
if (LL_USART_IsActiveFlag_ORE(UartInstance)) {
|
||||
LL_USART_ClearFlag_ORE(UartInstance);
|
||||
if (LL_USART_IsActiveFlag_ORE(config->usart)) {
|
||||
LL_USART_ClearFlag_ORE(config->usart);
|
||||
/*
|
||||
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
|
||||
* 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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
#ifdef CONFIG_PM
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
int key;
|
||||
|
@ -702,7 +697,7 @@ static void uart_stm32_irq_tx_enable(const struct device *dev)
|
|||
data->tx_int_stream_on = true;
|
||||
uart_stm32_pm_constraint_set(dev);
|
||||
#endif
|
||||
LL_USART_EnableIT_TC(UartInstance);
|
||||
LL_USART_EnableIT_TC(config->usart);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
#ifdef CONFIG_PM
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
int key;
|
||||
|
@ -719,7 +714,7 @@ static void uart_stm32_irq_tx_disable(const struct device *dev)
|
|||
key = irq_lock();
|
||||
#endif
|
||||
|
||||
LL_USART_DisableIT_TC(UartInstance);
|
||||
LL_USART_DisableIT_TC(config->usart);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
|
||||
return LL_USART_IsActiveFlag_TXE(UartInstance) &&
|
||||
LL_USART_IsEnabledIT_TC(UartInstance);
|
||||
return LL_USART_IsActiveFlag_TXE(config->usart) &&
|
||||
LL_USART_IsEnabledIT_TC(config->usart);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
|
||||
/* 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)
|
||||
/* Enable Line break detection */
|
||||
if (IS_UART_LIN_INSTANCE(UartInstance)) {
|
||||
LL_USART_EnableIT_LBD(UartInstance);
|
||||
if (IS_UART_LIN_INSTANCE(config->usart)) {
|
||||
LL_USART_EnableIT_LBD(config->usart);
|
||||
}
|
||||
#endif
|
||||
/* 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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
|
||||
/* 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)
|
||||
/* Disable Line break detection */
|
||||
if (IS_UART_LIN_INSTANCE(UartInstance)) {
|
||||
LL_USART_DisableIT_LBD(UartInstance);
|
||||
if (IS_UART_LIN_INSTANCE(config->usart)) {
|
||||
LL_USART_DisableIT_LBD(config->usart);
|
||||
}
|
||||
#endif
|
||||
/* 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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
|
||||
return ((LL_USART_IsActiveFlag_RXNE(UartInstance) &&
|
||||
LL_USART_IsEnabledIT_RXNE(UartInstance)) ||
|
||||
(LL_USART_IsActiveFlag_TC(UartInstance) &&
|
||||
LL_USART_IsEnabledIT_TC(UartInstance)));
|
||||
return ((LL_USART_IsActiveFlag_RXNE(config->usart) &&
|
||||
LL_USART_IsEnabledIT_RXNE(config->usart)) ||
|
||||
(LL_USART_IsActiveFlag_TC(config->usart) &&
|
||||
LL_USART_IsEnabledIT_TC(config->usart)));
|
||||
}
|
||||
|
||||
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;
|
||||
#if defined(CONFIG_PM) || defined(CONFIG_UART_ASYNC_API)
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (LL_USART_IsEnabledIT_TC(UartInstance) &&
|
||||
LL_USART_IsActiveFlag_TC(UartInstance)) {
|
||||
if (LL_USART_IsEnabledIT_TC(config->usart) &&
|
||||
LL_USART_IsActiveFlag_TC(config->usart)) {
|
||||
|
||||
if (data->tx_poll_stream_on) {
|
||||
/* A poll stream transmition just completed,
|
||||
* allow system to suspend
|
||||
*/
|
||||
LL_USART_DisableIT_TC(UartInstance);
|
||||
LL_USART_DisableIT_TC(config->usart);
|
||||
data->tx_poll_stream_on = false;
|
||||
uart_stm32_pm_constraint_release(dev);
|
||||
}
|
||||
|
@ -993,10 +988,10 @@ static void uart_stm32_isr(const struct device *dev)
|
|||
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
|
||||
|
||||
#ifdef CONFIG_UART_ASYNC_API
|
||||
if (LL_USART_IsEnabledIT_IDLE(UartInstance) &&
|
||||
LL_USART_IsActiveFlag_IDLE(UartInstance)) {
|
||||
if (LL_USART_IsEnabledIT_IDLE(config->usart) &&
|
||||
LL_USART_IsActiveFlag_IDLE(config->usart)) {
|
||||
|
||||
LL_USART_ClearFlag_IDLE(UartInstance);
|
||||
LL_USART_ClearFlag_IDLE(config->usart);
|
||||
|
||||
LOG_DBG("idle interrupt occurred");
|
||||
|
||||
|
@ -1007,25 +1002,25 @@ static void uart_stm32_isr(const struct device *dev)
|
|||
if (data->dma_rx.timeout == 0) {
|
||||
uart_stm32_dma_rx_flush(dev);
|
||||
}
|
||||
} else if (LL_USART_IsEnabledIT_TC(UartInstance) &&
|
||||
LL_USART_IsActiveFlag_TC(UartInstance)) {
|
||||
} else if (LL_USART_IsEnabledIT_TC(config->usart) &&
|
||||
LL_USART_IsActiveFlag_TC(config->usart)) {
|
||||
|
||||
LL_USART_DisableIT_TC(UartInstance);
|
||||
LL_USART_ClearFlag_TC(UartInstance);
|
||||
LL_USART_DisableIT_TC(config->usart);
|
||||
LL_USART_ClearFlag_TC(config->usart);
|
||||
/* Generate TX_DONE event when transmission is done */
|
||||
async_evt_tx_done(data);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
uart_stm32_pm_constraint_release(dev);
|
||||
#endif
|
||||
} else if (LL_USART_IsEnabledIT_RXNE(UartInstance) &&
|
||||
LL_USART_IsActiveFlag_RXNE(UartInstance)) {
|
||||
} else if (LL_USART_IsEnabledIT_RXNE(config->usart) &&
|
||||
LL_USART_IsActiveFlag_RXNE(config->usart)) {
|
||||
#ifdef USART_SR_RXNE
|
||||
/* clear the RXNE flag, because Rx data was not read */
|
||||
LL_USART_ClearFlag_RXNE(UartInstance);
|
||||
LL_USART_ClearFlag_RXNE(config->usart);
|
||||
#else
|
||||
/* 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 */
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
|
||||
LL_USART_EnableDMAReq_RX(UartInstance);
|
||||
LL_USART_EnableDMAReq_RX(config->usart);
|
||||
|
||||
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)
|
||||
{
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
struct uart_event disabled_event = {
|
||||
.type = UART_RX_DISABLED
|
||||
};
|
||||
|
@ -1093,7 +1088,7 @@ static int uart_stm32_async_rx_disable(const struct device *dev)
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
LL_USART_DisableIT_IDLE(UartInstance);
|
||||
LL_USART_DisableIT_IDLE(config->usart);
|
||||
|
||||
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;
|
||||
|
||||
/* 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");
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
|
||||
/* 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);
|
||||
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
|
||||
LL_USART_ClearFlag_IDLE(UartInstance);
|
||||
LL_USART_ClearFlag_IDLE(config->usart);
|
||||
|
||||
/* Request next buffer */
|
||||
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,
|
||||
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;
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
int ret;
|
||||
|
||||
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);
|
||||
|
||||
/* Clear TC flag */
|
||||
LL_USART_ClearFlag_TC(UartInstance);
|
||||
LL_USART_ClearFlag_TC(config->usart);
|
||||
|
||||
/* Enable TC interrupt so we can signal correct TX done */
|
||||
LL_USART_EnableIT_TC(UartInstance);
|
||||
LL_USART_EnableIT_TC(config->usart);
|
||||
|
||||
/* set source address */
|
||||
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,
|
||||
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;
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
int ret;
|
||||
|
||||
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;
|
||||
|
||||
/* 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.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
|
||||
* RX DMA transaction.
|
||||
*/
|
||||
LL_USART_ClearFlag_IDLE(UartInstance);
|
||||
LL_USART_EnableIT_IDLE(UartInstance);
|
||||
LL_USART_ClearFlag_IDLE(config->usart);
|
||||
LL_USART_EnableIT_IDLE(config->usart);
|
||||
|
||||
LL_USART_EnableIT_ERROR(UartInstance);
|
||||
LL_USART_EnableIT_ERROR(config->usart);
|
||||
|
||||
/* Request next buffer */
|
||||
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)
|
||||
{
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(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_STM32L1X)
|
||||
data->dma_rx.blk_cfg.source_address =
|
||||
LL_USART_DMA_GetRegAddr(UartInstance);
|
||||
LL_USART_DMA_GetRegAddr(config->usart);
|
||||
#else
|
||||
data->dma_rx.blk_cfg.source_address =
|
||||
LL_USART_DMA_GetRegAddr(UartInstance,
|
||||
LL_USART_DMA_GetRegAddr(config->usart,
|
||||
LL_USART_DMA_REG_DATA_RECEIVE);
|
||||
#endif
|
||||
|
||||
|
@ -1471,10 +1465,10 @@ static int uart_stm32_async_init(const struct device *dev)
|
|||
defined(CONFIG_SOC_SERIES_STM32F4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32L1X)
|
||||
data->dma_tx.blk_cfg.dest_address =
|
||||
LL_USART_DMA_GetRegAddr(UartInstance);
|
||||
LL_USART_DMA_GetRegAddr(config->usart);
|
||||
#else
|
||||
data->dma_tx.blk_cfg.dest_address =
|
||||
LL_USART_DMA_GetRegAddr(UartInstance,
|
||||
LL_USART_DMA_GetRegAddr(config->usart,
|
||||
LL_USART_DMA_REG_DATA_TRANSMIT);
|
||||
#endif
|
||||
|
||||
|
@ -1550,7 +1544,6 @@ static int uart_stm32_init(const struct device *dev)
|
|||
{
|
||||
const struct uart_stm32_config *config = dev->config;
|
||||
struct uart_stm32_data *data = dev->data;
|
||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||
uint32_t ll_parity;
|
||||
uint32_t ll_datawidth;
|
||||
int err;
|
||||
|
@ -1568,10 +1561,10 @@ static int uart_stm32_init(const struct device *dev)
|
|||
return err;
|
||||
}
|
||||
|
||||
LL_USART_Disable(UartInstance);
|
||||
LL_USART_Disable(config->usart);
|
||||
|
||||
/* TX/RX direction */
|
||||
LL_USART_SetTransferDirection(UartInstance,
|
||||
LL_USART_SetTransferDirection(config->usart,
|
||||
LL_USART_DIRECTION_TX_RX);
|
||||
|
||||
/* 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 */
|
||||
LL_USART_ConfigCharacter(UartInstance,
|
||||
LL_USART_ConfigCharacter(config->usart,
|
||||
ll_datawidth,
|
||||
ll_parity,
|
||||
LL_USART_STOPBITS_1);
|
||||
|
@ -1610,20 +1603,20 @@ static int uart_stm32_init(const struct device *dev)
|
|||
|
||||
/* Enable the single wire / half-duplex mode */
|
||||
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
|
||||
/* Wait until TEACK flag is set */
|
||||
while (!(LL_USART_IsActiveFlag_TEACK(UartInstance))) {
|
||||
while (!(LL_USART_IsActiveFlag_TEACK(config->usart))) {
|
||||
}
|
||||
#endif /* !USART_ISR_TEACK */
|
||||
|
||||
#ifdef USART_ISR_REACK
|
||||
/* Wait until REACK flag is set */
|
||||
while (!(LL_USART_IsActiveFlag_REACK(UartInstance))) {
|
||||
while (!(LL_USART_IsActiveFlag_REACK(config->usart))) {
|
||||
}
|
||||
#endif /* !USART_ISR_REACK */
|
||||
|
||||
|
@ -1719,8 +1712,8 @@ STM32_UART_IRQ_HANDLER_DECL(index) \
|
|||
PINCTRL_DT_INST_DEFINE(index); \
|
||||
\
|
||||
static const struct uart_stm32_config uart_stm32_cfg_##index = { \
|
||||
.usart = (USART_TypeDef *)DT_INST_REG_ADDR(index), \
|
||||
.uconf = { \
|
||||
.base = (uint8_t *)DT_INST_REG_ADDR(index), \
|
||||
STM32_UART_IRQ_HANDLER_FUNC(index) \
|
||||
}, \
|
||||
.pclken = { .bus = DT_INST_CLOCKS_CELL(index, bus), \
|
||||
|
|
|
@ -14,8 +14,12 @@
|
|||
|
||||
#include <drivers/pinctrl.h>
|
||||
|
||||
#include <stm32_ll_usart.h>
|
||||
|
||||
/* device config */
|
||||
struct uart_stm32_config {
|
||||
/* USART instance */
|
||||
USART_TypeDef *usart;
|
||||
struct uart_device_config uconf;
|
||||
/* clock subsystem driving this peripheral */
|
||||
struct stm32_pclken pclken;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue