cant use uart0 to trancieve messages on nrf52840 board.

Hello,
on the nrf52840 board,I have been trying to write code to send byte from nrf52840 to my nrf9160.
for some reason, the same code works when trying to use uart1, but doesn't when trying to use uart0.
the error I am receiving is as follows:

is the uart0 controller preserved only for logs?
thanks in advance, shlomo.

Parents
  • is the uart0 controller preserved only for logs?

    No, it is not preserved for logs, but it is by default used for logs (or the console/printk()). It is, however, possible to disable. If you look at the ncs\nrf\samples\bluetooth\peripheral_uart, this sample uses the UART0 only for application specific use (as well as printk()). So you can see if you are missing any configurations from there to turn off the UART logging. Alternatively, you can upload your application, and I can have a look. 

    Are you able to replicate the EPSR error on an nRF52840 DK?

    Best regards,

    Edvin

  • from what I see, this sample doesnt use nrf52840 board.
    the error I showed happens on nrf52840dk
    this is my application:
    main:

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */

    #include <zephyr/device.h>
    #include <zephyr/kernel.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/uart.h>
    #include <stdlib.h>
    #include <stdio.h>



    const struct device *gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)); // Adjust if using another port
    // const struct device *gpio_dev1 = DEVICE_DT_GET(DT_NODELABEL(gpio1));

    const struct device *uart_dev = DEVICE_DT_GET(DT_NODELABEL(uart1));

    static uint8_t rx_buf[11] = {0};

    static uint8_t tx_buf[] = {"hello world\r\n"};

    static void uart_callback(const struct device* uart_dev, struct uart_event* evt, void* user_data){

      switch (evt->type) {

      case UART_TX_DONE:
        printk("got into TX_DONE\n");
        // do something
        break;

      case UART_TX_ABORTED:
        // do something
        break;
       
      case UART_RX_RDY: {
        printk("got into rx_rdy\n");
        size_t i = 0;
        while(i < evt->data.rx.len){
          printk("%c",evt->data.rx.buf[evt->data.rx.offset + i]);
          i++;
        }
        printk("\n");
        // do something
        break;
      }
      case UART_RX_BUF_REQUEST:
        // do something
        break;

      case UART_RX_BUF_RELEASED:
        // do something
        break;
       
      case UART_RX_DISABLED:
        uart_rx_enable(uart_dev, rx_buf,sizeof(rx_buf),100);
        // do something
        break;

      case UART_RX_STOPPED:
        // do something
        break;
       
      default:
        break;
      }

    }


    int main(void) {
      if(!device_is_ready(uart_dev)){
        printk("device isnt ready\n");
        return 1;
      }

      int err = uart_callback_set(uart_dev, uart_callback, NULL);
      if (err!=0){
        printk("uart callback setting failed error number %d", err);
        return 1;
      }else{
        printk("uart callback setting didnt failed return number %d", err);
      }

      err = uart_rx_enable(uart_dev, rx_buf,sizeof(rx_buf),100);
      if (err!=0){
        printk("uart rx_enable problem %d", err);
        return 1;
      }

      while(1){
        err =  uart_tx(uart_dev, tx_buf, sizeof(tx_buf), SYS_FOREVER_US);
        if (err!=0){
          printk("uart_tx problem %d", err);
          return 1;
        }{
          printk("uart_tx ok\n");
        }
        k_msleep(1000);
      }
      return 0;
    }

    prj,conf:
    CONFIG_GPIO=y
    # CONFIG_I2C=y
    # CONFIG_I2C_NRFX=y
    CONFIG_PRINTK=y

    #CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC=y
    CONFIG_CPP=y
    CONFIG_MINIMAL_LIBCPP=y

    #loggig to uart
    CONFIG_LOG_BACKEND_UART=y
    CONFIG_UART_CONSOLE=y
    CONFIG_CONSOLE=y
    CONFIG_LOG=y

    CONFIG_SERIAL=y
    CONFIG_UART_ASYNC_API=y
    # CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_NET_SHELL=n

    #
    # Copyright (c) 2016 Intel Corporation
    #
    # SPDX-License-Identifier: Apache-2.0
    #

    CONFIG_USE_SEGGER_RTT=n       # Enable RTT support
    CONFIG_RTT_CONSOLE=n          # Use RTT for console output
    CONFIG_LOG_BACKEND_RTT=n      # Use RTT as the log backend

    overlay:

    &uart1 {
        status = "okay";
    };


Reply
  • from what I see, this sample doesnt use nrf52840 board.
    the error I showed happens on nrf52840dk
    this is my application:
    main:

    /*
     * Copyright (c) 2016 Intel Corporation
     *
     * SPDX-License-Identifier: Apache-2.0
     */

    #include <zephyr/device.h>
    #include <zephyr/kernel.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/uart.h>
    #include <stdlib.h>
    #include <stdio.h>



    const struct device *gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)); // Adjust if using another port
    // const struct device *gpio_dev1 = DEVICE_DT_GET(DT_NODELABEL(gpio1));

    const struct device *uart_dev = DEVICE_DT_GET(DT_NODELABEL(uart1));

    static uint8_t rx_buf[11] = {0};

    static uint8_t tx_buf[] = {"hello world\r\n"};

    static void uart_callback(const struct device* uart_dev, struct uart_event* evt, void* user_data){

      switch (evt->type) {

      case UART_TX_DONE:
        printk("got into TX_DONE\n");
        // do something
        break;

      case UART_TX_ABORTED:
        // do something
        break;
       
      case UART_RX_RDY: {
        printk("got into rx_rdy\n");
        size_t i = 0;
        while(i < evt->data.rx.len){
          printk("%c",evt->data.rx.buf[evt->data.rx.offset + i]);
          i++;
        }
        printk("\n");
        // do something
        break;
      }
      case UART_RX_BUF_REQUEST:
        // do something
        break;

      case UART_RX_BUF_RELEASED:
        // do something
        break;
       
      case UART_RX_DISABLED:
        uart_rx_enable(uart_dev, rx_buf,sizeof(rx_buf),100);
        // do something
        break;

      case UART_RX_STOPPED:
        // do something
        break;
       
      default:
        break;
      }

    }


    int main(void) {
      if(!device_is_ready(uart_dev)){
        printk("device isnt ready\n");
        return 1;
      }

      int err = uart_callback_set(uart_dev, uart_callback, NULL);
      if (err!=0){
        printk("uart callback setting failed error number %d", err);
        return 1;
      }else{
        printk("uart callback setting didnt failed return number %d", err);
      }

      err = uart_rx_enable(uart_dev, rx_buf,sizeof(rx_buf),100);
      if (err!=0){
        printk("uart rx_enable problem %d", err);
        return 1;
      }

      while(1){
        err =  uart_tx(uart_dev, tx_buf, sizeof(tx_buf), SYS_FOREVER_US);
        if (err!=0){
          printk("uart_tx problem %d", err);
          return 1;
        }{
          printk("uart_tx ok\n");
        }
        k_msleep(1000);
      }
      return 0;
    }

    prj,conf:
    CONFIG_GPIO=y
    # CONFIG_I2C=y
    # CONFIG_I2C_NRFX=y
    CONFIG_PRINTK=y

    #CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC=y
    CONFIG_CPP=y
    CONFIG_MINIMAL_LIBCPP=y

    #loggig to uart
    CONFIG_LOG_BACKEND_UART=y
    CONFIG_UART_CONSOLE=y
    CONFIG_CONSOLE=y
    CONFIG_LOG=y

    CONFIG_SERIAL=y
    CONFIG_UART_ASYNC_API=y
    # CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_NET_SHELL=n

    #
    # Copyright (c) 2016 Intel Corporation
    #
    # SPDX-License-Identifier: Apache-2.0
    #

    CONFIG_USE_SEGGER_RTT=n       # Enable RTT support
    CONFIG_RTT_CONSOLE=n          # Use RTT for console output
    CONFIG_LOG_BACKEND_RTT=n      # Use RTT as the log backend

    overlay:

    &uart1 {
        status = "okay";
    };


Children
  • CONFIG_LOG_BACKEND_UART=y makes it use the default UART instance (uart0 in this case) for logging, which could be why you are running into the issue you are seeing.

    I don't know if you want to keep logging using UART. If so, I suggest you try to move the log to UART1, and you can use UART0 for your application. Or even easier, just use uart1 in your application. 

    There are two things using the uart0 in addition to your application right now. The console, and the log.

    If you want to disable the console (which is where everything printed using "printk()" ends up) please add this to your prj.conf:

    CONFIG_CONSOLE=n
    CONFIG_UART_CONSOLE=n

    Alternatively, you can move it to RTT:

    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=n
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y

    To disable logging on uart0:

    # Config logger
    CONFIG_LOG=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=n
    CONFIG_LOG_PRINTK=n

    This will move the log to RTT only. If you want to disable it completely, just set CONFIG_LOG=n.

    This should allow you to use uart0 for your application as you like. As I mentioned in the previous reply, you can look at the ncs\nrf\samples\bluetooth\peripheral_uart, as this does something similar.

    Best regards,

    Edvin

Related