Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uart_read_fifo() reads only 2 chars on nucleo STM32L43KC and nRF52840-DK #34669

Closed
Sergi22 opened this issue Apr 28, 2021 · 4 comments
Closed
Assignees
Labels
area: UART Universal Asynchronous Receiver-Transmitter platform: nRF Nordic nRFx platform: STM32 ST Micro STM32

Comments

@Sergi22
Copy link

Sergi22 commented Apr 28, 2021

I'm trying to setup RX over UART in INTERRUPT_DRIVEN mode.

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;

        printk("Letter %c\r\n", c);

        if((c == '\n') || (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", 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("UART TX return code\r\n");
        k_msleep(2000);
    }

}

Basically what If get in the terminal when I try to send message over UART and print it with printk()
image
On Nordic it gets 1st and 7th letters, on STM32 it gets first letters.
Did anyone had similar issue ?

@galak galak added area: UART Universal Asynchronous Receiver-Transmitter platform: STM32 ST Micro STM32 labels Apr 29, 2021
@galak galak added the platform: nRF Nordic nRFx label Apr 29, 2021
@erwango
Copy link
Member

erwango commented Apr 30, 2021

If both targets are impacted, this could be an API related usage issue.
@dcpleung would you mind having a look ?

@dcpleung
Copy link
Member

Usage seems correct. I have tried the code with qemu_x86 and it worked fine without any missing characters (though would fault if I paste strings into it too fast).

Could you try running samples/subsys/shell/shell_module on those board? Also which commits are you using? If I remember correctly, there are couple PRs merged for fixing UART issues on both drivers.

@Sergi22
Copy link
Author

Sergi22 commented May 3, 2021

Changed the code a bit and it started to work. Still not sure what the issue was. I was using platform IO to setup the project, may be it affected somehow. Not sure how to check exact commit from platform IO. But I see this line from build output:
PACKAGES:

  • framework-zephyr 2.20500.210226 (2.5.0)

Changed callback code in case it is needed
`
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;
// static uint8_t len = (uart_data *)user_data;

/* 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)) 
{
    (void)uart_fifo_read(uart_device, uart1_data->rx_data++, 1);
    uart1_data->rx_count--;

    if((*(uart1_data->rx_data - 1) == '\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("\r\n");
        printk("%s\r\n", uart1_data->rx_data);     
        memset(uart1_data->rx_data, 0, uart1_data->rx_len);
        uart1_data->rx_count = uart1_data->rx_len;
        uart_irq_rx_enable(uart1_dev);
    }
}

}`
Closing this issue.

@Sergi22 Sergi22 closed this as completed May 3, 2021
@erwango
Copy link
Member

erwango commented May 3, 2021

@Sergi22 thanks for feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: UART Universal Asynchronous Receiver-Transmitter platform: nRF Nordic nRFx platform: STM32 ST Micro STM32
Projects
None yet
Development

No branches or pull requests

5 participants