uart_stm32: Fix conflit between poll_out and irq API

A lock was added to manage situation where the API poll_out and irq API
are used in same time.

Signed-off-by: Julien D'ascenzio <julien.dascenzio@paratronic.fr>
This commit is contained in:
Julien D'ascenzio 2021-11-08 12:47:25 +01:00 committed by Anas Nashif
parent 4c986a266f
commit d42cef17b0
2 changed files with 17 additions and 4 deletions

View file

@ -527,13 +527,19 @@ static void uart_stm32_poll_out(const struct device *dev,
unsigned char c)
{
USART_TypeDef *UartInstance = UART_STRUCT(dev);
struct uart_stm32_data *data = DEV_DATA(dev);
/* Wait for TXE flag to be raised */
while (!LL_USART_IsActiveFlag_TXE(UartInstance)) {
while (1) {
if (atomic_cas(&data->tx_lock, 0, 1)) {
if (LL_USART_IsActiveFlag_TXE(UartInstance)) {
break;
}
atomic_set(&data->tx_lock, 0);
}
}
#ifdef CONFIG_PM
struct uart_stm32_data *data = DEV_DATA(dev);
if (!data->tx_poll_stream_on) {
data->tx_poll_stream_on = true;
@ -551,6 +557,7 @@ static void uart_stm32_poll_out(const struct device *dev,
#endif /* CONFIG_PM */
LL_USART_TransmitData8(UartInstance, (uint8_t)c);
atomic_set(&data->tx_lock, 0);
}
static int uart_stm32_err_check(const struct device *dev)
@ -647,10 +654,12 @@ 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);
#ifdef CONFIG_PM
struct uart_stm32_data *data = DEV_DATA(dev);
while (atomic_cas(&data->tx_lock, 0, 1) == false) {
}
#ifdef CONFIG_PM
data->tx_poll_stream_on = false;
uart_stm32_pm_constraint_set(dev);
#endif
@ -660,9 +669,12 @@ 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);
struct uart_stm32_data *data = DEV_DATA(dev);
LL_USART_DisableIT_TC(UartInstance);
atomic_set(&data->tx_lock, 0);
#ifdef CONFIG_PM
uart_stm32_pm_constraint_release(dev);
#endif

View file

@ -58,6 +58,7 @@ struct uart_stm32_data {
uint32_t baud_rate;
/* clock device */
const struct device *clock;
atomic_t tx_lock;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_irq_callback_user_data_t user_cb;
void *user_data;