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:
parent
4c986a266f
commit
d42cef17b0
2 changed files with 17 additions and 4 deletions
|
@ -527,13 +527,19 @@ static void uart_stm32_poll_out(const struct device *dev,
|
||||||
unsigned char c)
|
unsigned char c)
|
||||||
{
|
{
|
||||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||||
|
struct uart_stm32_data *data = DEV_DATA(dev);
|
||||||
|
|
||||||
/* Wait for TXE flag to be raised */
|
/* 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
|
#ifdef CONFIG_PM
|
||||||
struct uart_stm32_data *data = DEV_DATA(dev);
|
|
||||||
|
|
||||||
if (!data->tx_poll_stream_on) {
|
if (!data->tx_poll_stream_on) {
|
||||||
data->tx_poll_stream_on = true;
|
data->tx_poll_stream_on = true;
|
||||||
|
@ -551,6 +557,7 @@ static void uart_stm32_poll_out(const struct device *dev,
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
LL_USART_TransmitData8(UartInstance, (uint8_t)c);
|
LL_USART_TransmitData8(UartInstance, (uint8_t)c);
|
||||||
|
atomic_set(&data->tx_lock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uart_stm32_err_check(const struct device *dev)
|
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)
|
static void uart_stm32_irq_tx_enable(const struct device *dev)
|
||||||
{
|
{
|
||||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
struct uart_stm32_data *data = DEV_DATA(dev);
|
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;
|
data->tx_poll_stream_on = false;
|
||||||
uart_stm32_pm_constraint_set(dev);
|
uart_stm32_pm_constraint_set(dev);
|
||||||
#endif
|
#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)
|
static void uart_stm32_irq_tx_disable(const struct device *dev)
|
||||||
{
|
{
|
||||||
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
USART_TypeDef *UartInstance = UART_STRUCT(dev);
|
||||||
|
struct uart_stm32_data *data = DEV_DATA(dev);
|
||||||
|
|
||||||
LL_USART_DisableIT_TC(UartInstance);
|
LL_USART_DisableIT_TC(UartInstance);
|
||||||
|
|
||||||
|
atomic_set(&data->tx_lock, 0);
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
uart_stm32_pm_constraint_release(dev);
|
uart_stm32_pm_constraint_release(dev);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct uart_stm32_data {
|
||||||
uint32_t baud_rate;
|
uint32_t baud_rate;
|
||||||
/* clock device */
|
/* clock device */
|
||||||
const struct device *clock;
|
const struct device *clock;
|
||||||
|
atomic_t tx_lock;
|
||||||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||||
uart_irq_callback_user_data_t user_cb;
|
uart_irq_callback_user_data_t user_cb;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue