Help understanding RX / TX

I have this main code:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>
#include <string.h>

#define MSG_SIZE 32
K_MSGQ_DEFINE(uart_msgq, MSG_SIZE, 10, 4);

static char rx_buf[MSG_SIZE];
static int rx_buf_pos;

#define UART_DEVICE_NODE DT_NODELABEL(uart1)
static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE);

void serial_cb(const struct device *dev, void *user_data)
{
    uint8_t c;
    if (!uart_irq_update(uart_dev) || !uart_irq_rx_ready(uart_dev)) {
		printk("UART IRQ not ready\r\n");
		return;
	}

	printk("reading datar\r\n");
    while (uart_fifo_read(uart_dev, &c, 1) == 1) {
		printk("RX: %c\n", c);
        if ((c == '\n' || c == '\r') && rx_buf_pos > 0) {
            rx_buf[rx_buf_pos] = '\0';
            k_msgq_put(&uart_msgq, &rx_buf, K_NO_WAIT);
            rx_buf_pos = 0;
        } else if (rx_buf_pos < (sizeof(rx_buf) - 1)) {
            rx_buf[rx_buf_pos++] = c;
        }
    }
}

void print_uart(char *buf)
{
    for (int i = 0; buf[i] != '\0'; i++) {
        uart_poll_out(uart_dev, buf[i]);
        k_busy_wait(100);
    }
}

int main(void)
{
    printk("UART Echo Started\n");

    if (!device_is_ready(uart_dev)) {
        printk("UART device not ready\n");
        return 0;
    }

    uart_irq_callback_user_data_set(uart_dev, serial_cb, NULL);
    uart_irq_rx_enable(uart_dev);

    print_uart("Hello from echo bot\r\n");
	printk("Hello sent\r\n");

	while(true) {
		print_uart("Echo: ");
		print_uart(" is one wild");
		print_uart("\r\n");
		//Sleep for a second
		k_sleep(K_SECONDS(1));
		printk("Sending data to TX\r\n");
    }

    return 0;
}

With this overlay:

&uart1 {
    status = "okay";
    current-speed = <115200>;
    pinctrl-0 = <&uart1_default>;
    pinctrl-1 = <&uart1_sleep>;
    pinctrl-names = "default", "sleep";
};

&pinctrl {
    uart1_default: uart1_default {
        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 9)>,
                    <NRF_PSEL(UART_RX, 0, 10)>;
        };
    };

    uart1_sleep: uart1_sleep {
        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 9)>,
                    <NRF_PSEL(UART_RX, 0, 10)>;
            low-power-enable;
        };
    };
};

and this configuration:

CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_CONSOLE=n

CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_LOG=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_PRINTK=y

I am using a nrf52840 dev board and have connected P0.06 and P0.08.

Why does it not trigger TX and write to JRTTLinkEXE the data sent in the main loop?

Parents
  • Hi,

     

    P0.09 and P0.10 are NFC-pins, and require handling as such, by adding this to the overlay:

    &uicr {
    	nfct-pins-as-gpios;
    };

     

    If you are using the nRF52840-DK, you will also need to adjust some resistors on the board itself:

    https://docs.nordicsemi.com/bundle/ug_nrf52840_dk/page/UG/dk/hw_nfc_if.html#d45e110

     

    Kind regards,

    Håkon

  • Hi.

    But this means it should work with P0.06 and P0.08, right?

    With this configuration:

    pinctrl {
    uart1_default: uart1_default {
    group1 {
    psels = <NRF_PSEL(UART_TX, 0, 6)>,
    <NRF_PSEL(UART_RX, 0, 8)>;
    };
    };

    uart1_sleep: uart1_sleep {
    group1 {
    psels = <NRF_PSEL(UART_TX, 0, 6)>,
    <NRF_PSEL(UART_RX, 0, 8)>;
    low-power-enable;
    };
    };
    };

    And it does not. What am I missing?

  • Hi,

     

    If you still have issues, please try any unused GPIO pair. flip the kit over, and you can see which pins are already connected on the DK itself.

    Boggibill said:
    psels = <NRF_PSEL(UART_TX, 0, 6)>,
    <NRF_PSEL(UART_RX, 0, 8)>;

    Those pins are normally used for uart0. Is uart0 disabled in this case?

     

    Kind regards,

    Håkon

  • Hi.

    Thanks, changing pins solved my issues. Atleast partly, the pins I where using where busy doing other things on the board. And thanks for letting me know about the diagram on the back of the boards.

    I have a new setup, which is a bit strange.

    overlay:

    &uart1 {
        status = "okay";
        current-speed = <9600>;
        pinctrl-0 = <&uart1_default>;
        pinctrl-1 = <&uart1_sleep>;
        pinctrl-names = "default", "sleep";
    };
    
    &pinctrl {
        uart1_default: uart1_default {
            group1 {
                psels = <NRF_PSEL(UART_TX, 1, 12)>,
                        <NRF_PSEL(UART_RX, 1, 11)>;
                bias-pull-up;
            };
        };
    
    };

    main.c:

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/uart.h>
    #include <string.h>
    
    #define MSG_SIZE 32
    K_MSGQ_DEFINE(uart_msgq, MSG_SIZE, 10, 4);
    
    static char rx_buf[MSG_SIZE];
    static int rx_buf_pos;
    static volatile bool uart_tx_done = true;
    
    #define UART_DEVICE_NODE DT_NODELABEL(uart1)
    static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE);
    
    void serial_cb(const struct device *dev, void *user_data)
    {
        uint8_t c;
        if (!uart_irq_update(uart_dev) || !uart_irq_rx_ready(uart_dev)) {
    		printk("UART IRQ not ready\r\n");
    		return;
    	}
    	printk("UART RX Ready\n");
    
        while (uart_fifo_read(uart_dev, &c, 1) == 1) {
    		printk("RX: %c\n", c);
            if ((c == '\n' || c == '\r') && rx_buf_pos > 0) {
                rx_buf[rx_buf_pos] = '\0';
                k_msgq_put(&uart_msgq, &rx_buf, K_NO_WAIT);
                rx_buf_pos = 0;
            } else if (rx_buf_pos < (sizeof(rx_buf) - 1)) {
                rx_buf[rx_buf_pos++] = c;
            }
        }
    }
    
    void print_uart(char *buf)
    {
        for (int i = 0; buf[i] != '\0'; i++) {
            uart_poll_out(uart_dev, buf[i]);
            k_busy_wait(100);
        }
    }
    
    void send_uart_async(const char *msg)
    {
        if (!uart_tx_done) {
            printk("UART busy, skipping TX\n");
            return;
        }
    
        uart_tx_done = false;
        int ret = uart_tx(uart_dev, msg, strlen(msg), SYS_FOREVER_MS);
        if (ret != 0) {
            printk("uart_tx failed with error: %d\n", ret);
            uart_tx_done = true; // reset flag so we don't block forever
        }
    }
    
    int main(void)
    {
        printk("UART Echo Started\n");
    
        if (!device_is_ready(uart_dev)) {
            printk("UART device not ready\n");
            return 0;
        }
    
        uart_irq_callback_user_data_set(uart_dev, serial_cb, NULL);
        uart_irq_rx_enable(uart_dev);
    
        print_uart("Hello from echo bot\r\n");
    	printk("Hello sent\r\n");
    
    	while(true) {
    		print_uart("Hello from nrf52\r\n");
    		printk("Sending data to TX\r\n");
    		k_sleep(K_SECONDS(1));
        }
    
        return 0;
    }

    prj.conf:

    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_ASYNC_API=y
    
    CONFIG_UART_CONSOLE=n
    CONFIG_CONSOLE=n
    
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_LOG=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_PRINTK=y
    

    However, now it seems like it is able to transmit and receive on the pins 11, 12.

    For some reason using uart1, im able to receive but not transmit.

    But my problem is, using uart0 with the following setup, im able to transmit but not receive, the complete oposite.

    &uart0 {
        status = "okay";
        current-speed = <9600>;
        pinctrl-0 = <&uart0_default>;
        pinctrl-1 = <&uart0_sleep>;
        pinctrl-names = "default", "sleep";
    };
    
    &pinctrl {
        uart0_default: uart0_default {
            group1 {
                psels = <NRF_PSEL(UART_TX, 1, 12)>,
                        <NRF_PSEL(UART_RX, 1, 11)>;
                bias-pull-up;
            };
        };
    };

    Any logical reason for that?

  • Hi,

     

    Boggibill said:

    However, now it seems like it is able to transmit and receive on the pins 11, 12.

    For some reason using uart1, im able to receive but not transmit.

    But my problem is, using uart0 with the following setup, im able to transmit but not receive, the complete oposite.

    uart1 is configured to P1.11 and P1.12, can receive, not transmit.

    uart0 is configured to P1.11 and P1.12, can transmit, not receive.

     

    Did you check with a logic analyzer to see if there is a problem with the logic levels or similar?

    Boggibill said:
    Any logical reason for that?

    If you reverse the pins, are you then able to receive but not transmit?

     

    Kind regards,

    Håkon

  • Hi Håkon.

    I have not tested it with a logic analyzer. However reversing the pins yields the same result.

Reply Children
  • Hi,

     

    Boggibill said:
    However reversing the pins yields the same result.

    you mean that if you use RXD on P1.12, it works, and then switch over to P1.11, and it still works?

     

    Ie. that the failure follows the TXD functionality and not the pin it is configured to?

     

    Kind regards,

    Håkon

  • Correct, RXD works with both pins, and TXD works on both pins, if i switch between uart0 and uart1 configuration.

    But RX and TX does not work at the same time on any configuration.

    Meaning the following:

    RXD works on pin1.11 with uart1, but TXD does not work with pin1.12 with uart1 setup

    RXD works on pin1.12 with uart1, but TXD does not work with pin1.11 with uart1 setup

    TXD works on pin1.11 with uart0, but RXD does not work with pin1.12 with uart0 setup

    TXD works on pin1.12 with uart0, but RXD does not work with pin1.11 with uart0 setup

    So, I could get two ways communication to if i communicate over uart1 and uart0 at the same time, if possible.

Related