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);
    }
}
Parents
  • 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?
  • Yes, uart_configure() inside main is okay.

    I want to ask whether you were able to successfully run the exercise solution or not?

    I think you first you should make it sure that there were no problems in running that exercise and then make the changes.

  • thanks for the update.  Yes it does run and it turns no the 3 LEDs correctly.  But the "    ret = uart_rx_enable(uart ,rx_buf,sizeof(rx_buf),(-1));" does not get anything!

    I know you are busy, but is there anyway i get faster response or even better connect in real-time to help look a this holistically for resolution?

  • RamizB said:
    Yes it does run and it turns no the 3 LEDs correctly.  But the "    ret = uart_rx_enable(uart ,rx_buf,sizeof(rx_buf),(-1));" does not get anything!

    In the exercise solution, or in your code?

    And what you mean by "does not get anything"? Does it produce error? What are the logs you see.

Reply Children
Related