Skip to content

Commit

Permalink
uart_stm32: Fix conflit between poll_out and irq API
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jdascenzio committed Nov 23, 2021
1 parent 9bea59a commit 755e5c8
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
20 changes: 16 additions & 4 deletions drivers/serial/uart_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,13 +473,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;
Expand All @@ -497,6 +503,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)
Expand Down Expand Up @@ -593,10 +600,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
Expand All @@ -606,9 +615,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
Expand Down
1 change: 1 addition & 0 deletions drivers/serial/uart_stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 755e5c8

Please sign in to comment.