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 Reply Children
  • 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

Related