This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

UART isue

Hi,

I experience a very strange issue with UART.

When I try to send data via /dev/ttyACM0 device it looks like the characters sent are buffered and sent only upon the following transmission,

and in some circumstances the first character gets overwritten.

For instance, using minicom, when I type-in: 1234,
The following output is printed: 

in uart_irq_handler!                                                            
RX is ready!                                                                    
value: ~                                                                        
in uart_irq_handler!                                                            
RX is ready!                                                                    
value: 1                                                                          
in uart_irq_handler!                                                            
RX is ready!                                                                    
value: 2                                                                          
in uart_irq_handler!                                                            
RX is ready!                                                                    
value: 3      

trying afterwards: echo -en "1,abc" > /dev/ttyACM0

I get:

in uart_irq_handler!                                                            
RX is ready!                                                                    
value: 4                                                                        
value: ,                                                                        
value: a                                                                        
value: b                                                                        
value: c                                                                        
in uart_irq_handler!                                                            
RX is not ready! 

Details about my environment:

  • nrf52833DK
  • nRF Connect SDK 1.7.1
  • minicom is configured with 115200, 8N1, Hardware & Software flow control Np
  • I have modified the nrf25833,dtsi file to contain the following uart&lpuart sections:
  • uart1: uart@40028000 {
    	        compatible = "nordic,nrf-uarte";
    	        current-speed = <115200>;
    	        reg = <0x40028000 0x1000>;
    	        interrupts = <40 5>;
    	        label = "UART_1";
    	        status = "okay";
    	        /delete-property/ rts-pin;
    	        /delete-property/ cts-pin;
    	        /delete-property/ hw-flow-control;
    
    	        lpuart: nrf-sw-lpuart {
    	                compatible = "nordic,nrf-sw-lpuart";
    	                status = "okay";
    	                label = "LPUART";
    	                req-pin = <46>;
    	                rdy-pin = <47>;
    	        };
    		};

Source code:

#include <zephyr.h>
#include <zephyr/types.h>
#include <sys/printk.h>
#include <drivers/uart.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

static void uart_irq_handler(const struct device *lpuart_device, void *context)
{
    int result;

    printk("in uart_irq_handler!\n");
    result = uart_irq_update(lpuart_device);
    if (result != 1) {
        printk("uart_irq_update failed, with error: %d\n", result);
        return ;
    }

	if (uart_irq_rx_ready(lpuart_device)) {
		uint8_t buffer[100];
        char command[100];
		int length;
        printk("RX is ready!\n", result);
		do {
            length = uart_fifo_read(lpuart_device, buffer, sizeof(buffer));
            if (length > 0) {
                sprintf(command, "%c", buffer[0]);
                printk("value: %s\n",command);
                buffer[0] = '-1';
            }
		} while (length > 0) ;
	} else {
         printk("RX is not ready!\n", result);
         uart_irq_update(lpuart_device);
    }
}


void start_uart(void) {

    const struct device *lpuart_device;
    uint8_t buffer[1];

    printk("in start_uart\n");
	lpuart_device = device_get_binding("UART_0");
	if (lpuart_device == NULL) {
        printk("Error! CANNOT get low power UART device!\n");
        return ;
    }
	uart_irq_callback_set(lpuart_device, uart_irq_handler);
	uart_irq_rx_enable(lpuart_device);
    printk("in start_uart, successfully set UART IRQ\n");
}

Parents
  • Hi,

    lpuart can only be used with another instance of lpuart on the other side. It implements 2 pin control protocol which replaces CTS/RTS and allows receiver to go to sleep in idle.

    You need standard UART with or without flow control in that case.

  • Thanks for your response. I understand from the documentation here https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/drivers/uart_nrf_sw_lpuart.html that LPUART supersedes regular UART, and provides the same communication API & protocol above the HW level.

    If this is not the case, can you please point me to documentation regarding using regular UART in the nRF Connect SDK? 
    I have not found any reference to regular UART and thought that LPUART is the way to implement UART now.
    I'm not using nRF5 SDK so libuarte and the similar will not work for me.


    Thanks!

  • Additionally, correct me if I'm wrong, if it would have been an issue with CTS/RTS I would have received no data at all. Here it seems like a flow control / driver issue.What do you think? Perhaps it needs to be configured differently?

  • Standard uart is not documented in nRF Connect SDK because it is part of zephyr. Lpuart implements the same interface so the only change is device that is used.

    Now, when i looked at the code you provided, i realized that you are actually using standard UART device. In device tree overlay you configure lpuart on top of UART_1 device but in the code snippet you are using UART_0 (device_get_binding("UART_0")).

    Though, not sure why reception is corrupted.

Reply
  • Standard uart is not documented in nRF Connect SDK because it is part of zephyr. Lpuart implements the same interface so the only change is device that is used.

    Now, when i looked at the code you provided, i realized that you are actually using standard UART device. In device tree overlay you configure lpuart on top of UART_1 device but in the code snippet you are using UART_0 (device_get_binding("UART_0")).

    Though, not sure why reception is corrupted.

Children
Related