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:
Hello,

In uart_pipe.c code:
static void uart_pipe_isr(struct device *unused)
{
        ARG_UNUSED(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) ||
                   LL_USART_IsActiveFlag_TXE(UartInstance));

TXE is always 1 probably by design because poll_out is working
properly:
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

Thanks,
Dmitry
_______________________________________________
Zephyr-devel mailing list
Zephyr-devel@lists.zephyrproject.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-devel

Join devel@lists.zephyrproject.org to automatically receive all group messages.