This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

UART RX interrupt driven does not receive characters properly Zephyr OS

Hello, I'm trying to setup simple UART reception (interrupt driven) with Zephyr OS.

When a message over UART, only some characters are received, others just skipped.

Here is my code:

#include <zephyr.h>

// #include <zephyr/types.h>
// #include <arch/cpu.h>
#include <string.h>
#include <sys/printk.h>
// #include <sys/util.h>

#include <drivers/uart.h>

static const struct device *uart1_dev;

typedef struct uart_data
{
    char * tx_data;
    char * rx_data;
    uint8_t tx_len;
    uint8_t rx_len;
    uint8_t rx_count;
}uart_data;

static void uart_cb(const struct device *uart_device, void *user_data)
{
    uart_data * uart1_data = (uart_data *)user_data;
    static int sent_len = 10;

    /* Verify uart_irq_update() */
	if (!uart_irq_update(uart_device)) {
		printk("retval should always be 1\r\n");
		return;
	}
 
    if (uart_irq_tx_ready(uart_device))
    {
        if(uart1_data->tx_len)
        {
            sent_len = uart_fifo_fill(uart_device, uart1_data->tx_data, (sent_len < uart1_data->tx_len) ? sent_len : uart1_data->tx_len);
            uart1_data->tx_len -= sent_len;
            uart1_data->tx_data += sent_len;
            printk("Sending data to UART1 with len %d\r\n", sent_len); 
        }
        else
        {
            uart_irq_tx_disable(uart1_dev);
        }
    }

    /* get all of the data off UART as fast as we can */
    if(uart_irq_rx_ready(uart_device)) 
    {
        uint8_t c;

        uart_fifo_read(uart_device, &c, 1);
        uart1_data->rx_count--;
        *uart1_data->rx_data++ = c;

        uart_irq_rx_enable(uart1_dev);

        printk("Letter %c\r\n", *(uart1_data->rx_data - 1));

        if((c == '\r') || (uart1_data->rx_count == 0))
        {
            uart_irq_rx_disable(uart1_dev);
            uart1_data->rx_data -= (uart1_data->rx_len - uart1_data->rx_count);
            printk("Rcvd msg: %s\r\n", uart1_data->rx_data); 
            k_msleep(10);
            memset(uart1_data->rx_data, 0, uart1_data->rx_len);
            
            uart1_data->rx_count = uart1_data->rx_len;
            uart_irq_rx_enable(uart1_dev);
        } 
    }
}

void main(void)
{
    
    char test[21] = "Tx ISR working test\r\n";
    char test_rcv[40] = {0};
    uart1_dev = device_get_binding("UART_1");

    printk("Device ready %d\r\n", device_is_ready(uart1_dev));


    uart_data uart1_data = {test, test_rcv, 20, 40, 40};
    uart_irq_callback_user_data_set(uart1_dev, uart_cb, &uart1_data);

    uart_irq_tx_enable(uart1_dev);
    uart_irq_rx_enable(uart1_dev);

    while(1)
    {
        // printk("Console alive\r\n");
        k_msleep(2000);
    }

}

Proj.conf file:

CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y

Result output:

Did anyone had similar issue?

Related