Re: uart_pipe spinning problem for stm32

Michael Hope

Hi Dmitry.  I'm working on a Zephyr port for the SAMD21.  The way I interpreted 'is_pending' is 'has unmasked interrupts pending' so if the TX interrupt is masked then is_pending should ignore TXE.

Here's my implementation:

which is:

static int uart_sam0_irq_is_pending(struct device *dev)
    SercomUsart *const regs = DEV_CFG(dev)->regs;

    return (regs->INTENSET.reg & regs->INTFLAG.reg) != 0;

-- Michael

On 30 November 2017 at 01:07, Dmitry Shmidt via Zephyr-devel <zephyr-devel@...> wrote:

In uart_pipe.c code:
static void uart_pipe_isr(struct device *unused)

        while (uart_irq_update(uart_pipe_dev)
                  && uart_irq_is_pending(uart_pipe_dev)) {

uart_irq_update() is returning 1 and
uart_irq_is_pending() is always TRUE for stm32, because
despite RXNE is cleared, TXE is always 1.
static int uart_stm32_irq_is_pending(struct device *dev)
        USART_TypeDef *UartInstance = UART_STRUCT(dev);

        return (LL_USART_IsActiveFlag_RXNE(UartInstance) ||

TXE is always 1 probably by design because poll_out is working
static unsigned char uart_stm32_poll_out(struct device *dev,

unsigned char c)
        USART_TypeDef *UartInstance = UART_STRUCT(dev);

        /* Wait for TXE flag to be raised */
        while (!LL_USART_IsActiveFlag_TXE(UartInstance))

Please advise what is the right way to fix this issue:
1) Use uart_irq_rx_ready() instead of  uart_irq_is_pending() in
while() in uart_pipe.c
2) Change uart_stm32_irq_is_pending() to return only RNXE -
however other drivers also return RXE || TXE
3) Clear TXE during input processing

Zephyr-devel mailing list

Join to automatically receive all group messages.