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,

     

    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.

  • Hi,

     

    When altering device tree, I recommend that you delete/remove the build folder and re-generate it afterwards, to ensure that there's no stale configurations still active.

     

    Did you try probing the lines to see if there's any problems with the voltage level or similar?

     

    Kind regards,

    Håkon

  • Hi Håkon.

    I have tried deleting all builds to be on the safe side, but i still have this problem. But the problem still exists, however a different approach works.

    This example works:

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/uart.h>
    #include <string.h>
    #include <stdio.h>
    #include <zephyr/drivers/gpio.h>
    
    
    #define UART_DEVICE_NODE DT_NODELABEL(uart1)
    static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE);
    
    #define RX_BUF_SIZE 64
    
    
    #define TX_PIN 13  // P1.12
    #define GPIO_PORT DT_NODELABEL(gpio0)  // Use gpio0 if using P0.x
    const struct device *gpio_dev;
    #define BAUD_DELAY_US 104
    
    void uart_send_blocking(const char *msg)
    {
        while (*msg) {
            uart_poll_out(uart_dev, *msg++);
            k_busy_wait(100); // Slight delay between characters
        }
    }
    
    void bitbang_uart_tx_byte(uint8_t byte)
    {
        // Start bit (low)
        gpio_pin_set(gpio_dev, TX_PIN, 0);
        k_busy_wait(BAUD_DELAY_US);
    
        // Send 8 bits, LSB first
        for (int i = 0; i < 8; i++) {
            gpio_pin_set(gpio_dev, TX_PIN, (byte >> i) & 1);
            k_busy_wait(BAUD_DELAY_US);
        }
    
        // Stop bit (high)
        gpio_pin_set(gpio_dev, TX_PIN, 1);
        k_busy_wait(BAUD_DELAY_US);
    }
    
    void uart_receive_for_10_seconds(void)
    {
        uint8_t c;
        char rx_buf[RX_BUF_SIZE];
        int rx_pos = 0;
    
        int64_t start = k_uptime_get();
    
        while (k_uptime_get() - start < 10000) {
            if (uart_poll_in(uart_dev, &c) == 0) {
                if (rx_pos < RX_BUF_SIZE - 1) {
                    rx_buf[rx_pos++] = c;
                    if (c == '\n' || c == '\r') {
                        break;
                    }
                }
            } else {
                k_msleep(10); // Avoid busy-looping
            }
        }
    
        if (rx_pos > 0) {
            rx_buf[rx_pos] = '\0';
            printk("Received: %s\n", rx_buf);
        } else {
            printk("No response received within 10 seconds.\n");
        }
    }
    
    int main(void)
    {
    	printk("UART Polling Example Started\n");
    
        gpio_dev = DEVICE_DT_GET(GPIO_PORT);
        gpio_pin_configure(gpio_dev, TX_PIN, GPIO_OUTPUT);
        gpio_pin_set(gpio_dev, TX_PIN, 1); // Idle high
    
    	while(true) {
    		if (!device_is_ready(uart_dev)) {
    			printk("UART device not ready\n");
    			return 0;
    		}
            bitbang_uart_tx_byte('H');
            bitbang_uart_tx_byte('i');
            bitbang_uart_tx_byte('\r');
            bitbang_uart_tx_byte('\n');
    
    		//uart_send_blocking("Hello from nRF52!\r\n");
    		printk("Message sent. Waiting for reply...\n");
    
    		uart_receive_for_10_seconds();
    		k_msleep(5000); // Avoid busy-looping
    	}
    
        return 0;
    }

    So why does this work, and not the other one?

    Oh, i don't have any good messuring tools, however a voltmeter seems to have a constant voltage (im not sure if that is of any use).

  • Hi,

     

    Please note that you are toggling pin P0.13, and not P1.13, in your firmware.

    Are you certain that you are connecting everything correctly? 

     

    In your overlay, you are using GPIO P1, not P0.

     

    Kind regards,

    Håkon

Reply Children
No Data
Related