BASIC UART CLI.

I am looking to set up a basic UART CLI, I want to be able to write commands such as "scan ", "Connect 'MAC' " or "Set LED on" etc. I have been working off the lesson exercise for UART, and have set up a termination for the command "\r\n". the RX buffer is not resetting and so all the commands are merging together. My plan was to then search the receive buffer for the command i.e. "scan" and then act on that.

How can I clear the buffer, length and offset? i had set to 0 and "" but on next callback the values are back.

Am I maybe going in the wrong direction for this? i want to keep this quite simple.

My end goal is to setup a basic version of the ble_app_interactive.

Thanks for your help.

William

Parents
  • This is the code so far for reference

    /*
     * 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 <string.h>
    #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>

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

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

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

    /* 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));


    /* 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};
    static uint8_t CLI_rx_buf[RECEIVE_BUFF_SIZE] = {0};

    int find_data(const uint8_t *data, const char *target) {
        int size = sizeof(data);
        int target_size = strlen(target);
        for (int i = 0; i < size - target_size + 1; i++) {
            if (memcmp(data + i, target, target_size) == 0) {
                return i; // Return the index where the target data was found
            }
        }
        return -1; // Return -1 if the target data was not found in the array
    }

    /* STEP 7 - Define the callback function for UART */
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
        int ret = 0;
        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>0)&&((evt->data.rx.buf[evt->data.rx.len+evt->data.rx.offset-1]=='\n')&&(evt->data.rx.buf[evt->data.rx.len+evt->data.rx.offset-2]=='\r'))){

            printk("\r\nUART message Received\r\n");
            ret = find_data(evt->data.rx.buf,"scan");
            evt->data.rx.buf = "";
            evt->data.rx.len = 0;
            evt->data.rx.offset = 0;
            }
    #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;

    /* 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), SYS_FOREVER_MS);
        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,RECEIVE_TIMEOUT);
        if (ret) {
            return 1;
        }
        while (1) {
            k_msleep(SLEEP_TIME_MS);

        }

    }
Reply
  • This is the code so far for reference

    /*
     * 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 <string.h>
    #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>

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

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

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

    /* 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));


    /* 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};
    static uint8_t CLI_rx_buf[RECEIVE_BUFF_SIZE] = {0};

    int find_data(const uint8_t *data, const char *target) {
        int size = sizeof(data);
        int target_size = strlen(target);
        for (int i = 0; i < size - target_size + 1; i++) {
            if (memcmp(data + i, target, target_size) == 0) {
                return i; // Return the index where the target data was found
            }
        }
        return -1; // Return -1 if the target data was not found in the array
    }

    /* STEP 7 - Define the callback function for UART */
    static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
    {
        int ret = 0;
        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>0)&&((evt->data.rx.buf[evt->data.rx.len+evt->data.rx.offset-1]=='\n')&&(evt->data.rx.buf[evt->data.rx.len+evt->data.rx.offset-2]=='\r'))){

            printk("\r\nUART message Received\r\n");
            ret = find_data(evt->data.rx.buf,"scan");
            evt->data.rx.buf = "";
            evt->data.rx.len = 0;
            evt->data.rx.offset = 0;
            }
    #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;

    /* 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), SYS_FOREVER_MS);
        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,RECEIVE_TIMEOUT);
        if (ret) {
            return 1;
        }
        while (1) {
            k_msleep(SLEEP_TIME_MS);

        }

    }
Children
No Data
Related