This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Unable to initialize USB CDC and I2C in Open Thread examples

Hello developers,

I would like to know what is wrong with open thread examples, literally tired of trying now. Firstly my two FTD sensor nodes are not able to reconnect, so i thought to again start with a demo example and build the example. Than i face this issue as mentioned in headline. I have been using nRF connect SDK from past 2 months have developed solutions using USB CDC and also using I2C. So it's not like i don't know how to interface USB CDC or I2C using NCS.

I would like to know how can i enable USB CDC in the open thread examples. Here is my normal sensor example, were i am just reading the i2c address of the sensor and printing on terminal.

Simple Code:

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

#include <zephyr.h>
#include <sys/printk.h>
#include <sys/util.h>
#include <string.h>
#include <usb/usb_device.h>
#include <drivers/uart.h>
#include <stdio.h>
#include <drivers/i2c.h>
#include <sys/printk.h>
#include <usb/usb_device.h>
#include <devicetree.h>
#include <drivers/gpio.h>

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0	DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN	DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS	DT_GPIO_FLAGS(LED0_NODE, gpios)
#endif

static struct device *i2c_dev;

int i2cscanner()
{
    printk("i2c scanner\r\n");
    i2c_dev = device_get_binding("I2C_1");
    if (!i2c_dev) {
            printk("I2C: Device driver not found.\n");
            return 0;
    }
    i2c_configure(i2c_dev, I2C_SPEED_SET(I2C_SPEED_STANDARD)| I2C_MODE_MASTER);  
    for (uint8_t i = 4; i <= 0x77; i++) {
		struct i2c_msg msgs[1];
		uint8_t dst[2];

		/* Send the address to read from */
		msgs[0].buf = &dst[0];
		msgs[0].len = 1U;
		msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

		if (i2c_transfer(i2c_dev, &msgs[0], 1, i) == 0) {
			printk("----------------------------0x%2x FOUND\n", i);
		} 
	}
        //k_msleep(1000);
        return 1;
}
void main(void)
{
	const struct device *dev = device_get_binding(
			CONFIG_UART_CONSOLE_ON_DEV_NAME);
	uint32_t dtr = 0;

	if (usb_enable(NULL)) {
		return;
	}

	/* Poll if the DTR flag was set, optional */
	//while (!dtr) {
		uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
	//}

	if (strlen(CONFIG_UART_CONSOLE_ON_DEV_NAME) !=
	    strlen("CDC_ACM_0") ||
	    strncmp(CONFIG_UART_CONSOLE_ON_DEV_NAME, "CDC_ACM_0",
		    strlen(CONFIG_UART_CONSOLE_ON_DEV_NAME))) {
		printk("Error: Console device name is not USB ACM\n");

		return;
	}


const struct device *gpio_dev1;

		gpio_dev1 = device_get_binding("GPIO_1");

 gpio_pin_configure(gpio_dev1, 8, GPIO_OUTPUT_INACTIVE| FLAGS);
      gpio_pin_set(gpio_dev1, 8,1); //      1--- off
	while (1) {
		//printk("Hello World! %s\n", CONFIG_ARCH);
        printk("USB_CDC\r\n");
        i2cscanner();
		k_sleep(K_SECONDS(1));
	}
}
 

And here is my proj.conf for the same.

proj.conf

CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_I2C=y
CONFIG_I2C_1=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

CONFIG_USB=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_MANUFACTURER="DnK"
CONFIG_USB_DEVICE_PRODUCT="S_Node_test"
CONFIG_USB_UART_CONSOLE=y

CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=y
CONFIG_UART_CONSOLE_ON_DEV_NAME="CDC_ACM_0"


The above example easily runs smoothly without any error. But whenever i try to add the same example in Open thread client server examples. How can i do that ?  If i debug the program in open thread it gives me hard fault error after execution of this statement         uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);  in the below program. I am doing all the experiment on the NCS demo examples itself, haven't invented anything by myself.

Below is the code where i am trying to use USB CDC in my coap server example.

/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr.h>
#include <dk_buttons_and_leds.h>
#include <logging/log.h>
#include <net/openthread.h>
#include <openthread/thread.h>

#include "ot_coap_utils.h"

#include <sys/printk.h>
#include <sys/util.h>
#include <string.h>
#include <usb/usb_device.h>
#include <drivers/uart.h>
#include <stdio.h>
#include <drivers/i2c.h>
#include <devicetree.h>
#include <drivers/gpio.h>

LOG_MODULE_REGISTER(coap_server, CONFIG_COAP_SERVER_LOG_LEVEL);

#define OT_CONNECTION_LED DK_LED1
#define PROVISIONING_LED DK_LED3
#define LIGHT_LED DK_LED4

static struct device *i2c_dev;
static struct k_work provisioning_work;

static struct k_timer led_timer;
static struct k_timer provisioning_timer;



/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0	DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN	DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS	DT_GPIO_FLAGS(LED0_NODE, gpios)
#endif

static struct device *i2c_dev;
int i2cscanner()
{
    printk("i2c scanner\r\n");
    i2c_dev = device_get_binding("I2C_1");
    if (!i2c_dev) {
            printk("I2C: Device driver not found.\n");
            return 0;
    }
    i2c_configure(i2c_dev, I2C_SPEED_SET(I2C_SPEED_STANDARD)| I2C_MODE_MASTER);  
    for (uint8_t i = 4; i <= 0x77; i++) {
		struct i2c_msg msgs[1];
		uint8_t dst[2];

		/* Send the address to read from */
		msgs[0].buf = &dst[0];
		msgs[0].len = 1U;
		msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

		if (i2c_transfer(i2c_dev, &msgs[0], 1, i) == 0) {
			printk("----------------------------0x%2x FOUND\n", i);
		} 
	}
        //k_msleep(1000);
        return 1;
}

static void on_light_request(uint8_t command)
{
	static uint8_t val;

	switch (command) {
	case THREAD_COAP_UTILS_LIGHT_CMD_ON:
		dk_set_led_on(LIGHT_LED);
		val = 1;
		break;

	case THREAD_COAP_UTILS_LIGHT_CMD_OFF:
		dk_set_led_off(LIGHT_LED);
		val = 0;
		break;

	case THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE:
		val = !val;
		dk_set_led(LIGHT_LED, val);
		break;

	default:
		break;
	}
}

static void activate_provisioning(struct k_work *item)
{
	ARG_UNUSED(item);

	ot_coap_activate_provisioning();

	k_timer_start(&led_timer, K_MSEC(100), K_MSEC(100));
	k_timer_start(&provisioning_timer, K_SECONDS(5), K_NO_WAIT);

	LOG_INF("Provisioning activated");
}

static void deactivate_provisionig(void)
{
	k_timer_stop(&led_timer);
	k_timer_stop(&provisioning_timer);

	if (ot_coap_is_provisioning_active()) {
		ot_coap_deactivate_provisioning();
		LOG_INF("Provisioning deactivated");
	}
}

static void on_provisioning_timer_expiry(struct k_timer *timer_id)
{
	ARG_UNUSED(timer_id);

	deactivate_provisionig();
}

static void on_led_timer_expiry(struct k_timer *timer_id)
{
	static uint8_t val = 1;

	ARG_UNUSED(timer_id);

	dk_set_led(PROVISIONING_LED, val);
	val = !val;
}

static void on_led_timer_stop(struct k_timer *timer_id)
{
	ARG_UNUSED(timer_id);

	dk_set_led_off(PROVISIONING_LED);
}

static void on_button_changed(uint32_t button_state, uint32_t has_changed)
{
	uint32_t buttons = button_state & has_changed;

	if (buttons & DK_BTN4_MSK) {
		k_work_submit(&provisioning_work);
	}
}

static void on_thread_state_changed(uint32_t flags, void *context)
{
	struct openthread_context *ot_context = context;

	if (flags & OT_CHANGED_THREAD_ROLE) {
		switch (otThreadGetDeviceRole(ot_context->instance)) {
		case OT_DEVICE_ROLE_CHILD:
		case OT_DEVICE_ROLE_ROUTER:
		case OT_DEVICE_ROLE_LEADER:
			dk_set_led_on(OT_CONNECTION_LED);
			break;

		case OT_DEVICE_ROLE_DISABLED:
		case OT_DEVICE_ROLE_DETACHED:
		default:
			dk_set_led_off(OT_CONNECTION_LED);
			deactivate_provisionig();
			break;
		}
	}
}

void main(void)
{
	const struct device *dev = device_get_binding(
			CONFIG_UART_CONSOLE_ON_DEV_NAME);
	uint32_t dtr = 0;

	if (usb_enable(NULL)) {
		return;
	}

	/* Poll if the DTR flag was set, optional */
	//while (!dtr) {
		uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
	//}

	if (strlen(CONFIG_UART_CONSOLE_ON_DEV_NAME) !=
	    strlen("CDC_ACM_0") ||
	    strncmp(CONFIG_UART_CONSOLE_ON_DEV_NAME, "CDC_ACM_0",
		    strlen(CONFIG_UART_CONSOLE_ON_DEV_NAME))) {
		printk("Error: Console device name is not USB ACM\n");

		return;
	}


    const struct device *gpio_dev1;

		gpio_dev1 = device_get_binding("GPIO_1");

      gpio_pin_configure(gpio_dev1, 8, GPIO_OUTPUT_INACTIVE| FLAGS);
      gpio_pin_set(gpio_dev1, 8,1); //      1--- off
	while (1) {
		//printk("Hello World! %s\n", CONFIG_ARCH);
        printk("USB_CDC\r\n");
        i2cscanner();
		k_sleep(K_SECONDS(1));
	}


}

So can somebody please provide me the code snippet how to use this peripherals in open thread. My whole open thread development is halted thanks to this.

Parents
  • Hi McGregor,

    Thanks for your patience. I spend some time finding the issue of USB CDC.

    Here is my configuration adding to openthread/coap_server/prj.conf:

    CONFIG_USB=y
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Zephyr USB console sample"
    CONFIG_USB_UART_CONSOLE=y
    CONFIG_LOG_BACKEND_UART=y
    
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_LINE_CTRL=y
    CONFIG_UART_CONSOLE_ON_DEV_NAME="CDC_ACM_0"

    You also need to comment on the following line in openthread/common/overlay-ot-defaults.conf, because it will cover some settings in prj.conf.

    #CONFIG_NCS_SAMPLES_DEFAULTS=y

    Please also be aware that the Console subsystem does not seem to fully support the USB transport. The USB console config setting help text mentioned:

    Note that console inputs from the USB UART are not functional yet.
    It should be OK as long as you only use it for log output.
    Best regards,
    Charlie
Reply
  • Hi McGregor,

    Thanks for your patience. I spend some time finding the issue of USB CDC.

    Here is my configuration adding to openthread/coap_server/prj.conf:

    CONFIG_USB=y
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Zephyr USB console sample"
    CONFIG_USB_UART_CONSOLE=y
    CONFIG_LOG_BACKEND_UART=y
    
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_LINE_CTRL=y
    CONFIG_UART_CONSOLE_ON_DEV_NAME="CDC_ACM_0"

    You also need to comment on the following line in openthread/common/overlay-ot-defaults.conf, because it will cover some settings in prj.conf.

    #CONFIG_NCS_SAMPLES_DEFAULTS=y

    Please also be aware that the Console subsystem does not seem to fully support the USB transport. The USB console config setting help text mentioned:

    Note that console inputs from the USB UART are not functional yet.
    It should be OK as long as you only use it for log output.
    Best regards,
    Charlie
Children
No Data
Related