Can't get UART to work via GPIO interface

I need to use UART0 of the nRF9161 via Tx(P0.27) and Rx(P0.26) for serial communication.  There is no CTS/RTS signal.

I used the code from Lesson 5 of the DevAcademy. i can't get it to work. The code right after int main(void) checking for device availability show no active (when tested in debug mode)

I have a feeling my code does not have right setup for the UART. I spent countless hours to debug and read to fix - but no luck.

i would appreciate if you can please review and provide recommendations for resultion.

BTw, the code complies and build to the end.

==========================

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

/* Controlling LEDs through UART. Press 1-3 on your keyboard to toggle LEDS 1-3 on your development kit */

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/printk.h>
/* STEP 3 - Include the header file of the UART driver in main.c */
#include <zephyr/drivers/uart.h>
/*
 *struct uart_config{
 *  uint32_t baudrate;
 *  uint8_t parity;
 *  uint8_t stop_bits;
 *  uint8_t data_bits;
 *  uint8_t flow_ctrl;
 *};
  */


const struct uart_config uart_cfg = {
    .baudrate = 9600,
    .parity = UART_CFG_STOP_BITS_1,
    .data_bits = UART_CFG_DATA_BITS_8,
    .flow_ctrl = UART_CFG_FLOW_CTRL_NONE
};


/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   100

/* STEP 10.1.1 - Define the size of the receive buffer */
#define RECEIVE_BUFF_SIZE 113

/* STEP 10.2 - Define the receiving timeout period */
#define RECEIVE_TIMEOUT 100

/* STEP 5.1 - Get the device pointers of the LEDs through gpio_dt_spec */
/* The nRF7002dk has only 2 LEDs so this step uses a compile-time condition to reflect the DK you are building for */
#if defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP)|| defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP_NS)
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(DT_ALIAS(led1), gpios);
#else
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(DT_ALIAS(led1), gpios);
static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET(DT_ALIAS(led2), gpios);
#endif

/* STEP 4.1 - Get the device pointer of the UART hardware */
const struct device *uart= DEVICE_DT_GET(DT_NODELABEL(uart0));
int uart_configure(const struct device *dev, const struct uart_config *cfg);

/* STEP 9.1 - Define the transmission buffer, which is a buffer to hold the data to be sent over UART */
static uint8_t tx_buf[] =  {"nRF Connect SDK Fundamentals Course\n\r"
                          "Press 1-3 on your keyboard to toggle LEDS 1-3 on your development kit\n\r"};

/* STEP 10.1.2 - Define the receive buffer */
static uint8_t rx_buf[RECEIVE_BUFF_SIZE] = {0};

/* STEP 7 - Define the callback function for UART */
static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
    switch (evt->type) {

    case UART_RX_RDY:
    #if defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP)|| defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP_NS)
        if((evt->data.rx.len) == 1){

        if(evt->data.rx.buf[evt->data.rx.offset] == '1')
            gpio_pin_toggle_dt(&led0);
        else if (evt->data.rx.buf[evt->data.rx.offset] == '2')
            gpio_pin_toggle_dt(&led1);  
        }
    #else
    if((evt->data.rx.len) == 1){

        if(evt->data.rx.buf[evt->data.rx.offset] == '1')
            gpio_pin_toggle_dt(&led0);
        else if (evt->data.rx.buf[evt->data.rx.offset] == '2')
            gpio_pin_toggle_dt(&led1);
        else if (evt->data.rx.buf[evt->data.rx.offset] == '3')
            gpio_pin_toggle_dt(&led2);                  
        }
#endif
    break;
    case UART_RX_DISABLED:
        uart_rx_enable(dev ,rx_buf,sizeof rx_buf,RECEIVE_TIMEOUT);
        break;
       
    default:
        break;
    }
}

int main(void)
{
    int ret;
    int err = uart_configure (uart, &uart_cfg);


    if (err == -ENOSYS) {
        return -ENOSYS;
    }


/* STEP 4.2 - Verify that the UART device is ready */
    if (!device_is_ready(uart)){
        printk("UART device not ready\r\n");
        return 1 ;
    }
/* STEP 5.2 - Verify that the LED devices are ready */
    if (!device_is_ready(led0.port)){
        printk("GPIO device is not ready\r\n");
        return 1;
    }
/* STEP 6 - Configure the GPIOs of the LEDs */
#if defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP)|| defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP_NS)
    ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT_ACTIVE);
    if (ret < 0) {
        return 1 ;
    }
    ret = gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE);
    if (ret < 0) {
        return 1 ;
    }
#else
    ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT_ACTIVE);
    if (ret < 0) {
        return 1 ;
    }
    ret = gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE);
    if (ret < 0) {
        return 1 ;
    }
    ret = gpio_pin_configure_dt(&led2, GPIO_OUTPUT_ACTIVE);
    if (ret < 0) {
        return 1 ;
    }
#endif

/* STEP 8 - Register the UART callback function */
    ret = uart_callback_set(uart, uart_cb, NULL);
        if (ret) {
            return 1;
        }
/* STEP 9.2 - Send the data over UART by calling uart_tx() */
    ret = uart_tx(uart, tx_buf, sizeof(tx_buf), (-1));
    if (ret) {
        return 1;
    }
/* STEP 10.3  - Start receiving by calling uart_rx_enable() and pass it the address of the receive  buffer */
    ret = uart_rx_enable(uart ,rx_buf,sizeof(rx_buf),(-1));
    if (ret) {
        return 1;
    }

    while (1) {
        k_msleep(SLEEP_TIME_MS);
    }
}
  • Hello

    Were you able to get lesson-5 solution work on the DK without any modifications?

    9161DK is mentioned as a supported board, so it should work without any issue.

    Also, I have noted that you are calling the function uart_configure()outside of main. You should move it inside main.

  • Hi Naeem,

    thanks for the feedback. Two points:

    Point 1:

    Regard the call  of uard_configure(), it is inside main as follows:

       int main(void)
       {
           int ret;
           int err = uart_configure (uart, &uart_cfg);
           if (err == -ENOSYS) {
               return -ENOSYS;
           }
    do you agree?
    Point 2:
    when i use the dubug function and check the start of the UART per the following code:
    /* STEP 4.2 - Verify that the UART device is ready */
        if (!device_is_ready(uart)){
            printk("UART device not ready\r\n");
            return 1 ;
        }
    i get invalid answer in the Watch window for watching: "device_is_ready(uart)"
    why is that?
Related