custom led handler with the openthread COAP server example

I want to set an external LED on and off with the coap server example, but It doesn't work. I tried two different methods. The uncommented one is more like a normal blinky and a static const struct device, and the commented one is inspired by the dk_buttons_and_leds.c both don't work. Either I do not get any error when configuring the gpios.

the led handler code.

#include "led_handler.h"
#include <zephyr.h>
#include <logging/log.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>

LOG_MODULE_REGISTER(led_handler, CONFIG_LOG_DEFAULT_LEVEL);

struct gpio_pin {
	const char * const port;
	const uint8_t number;
	const uint8_t flags;
};

//static const struct gpio_pin led_pins_cst[] = {
//#if DT_NODE_HAS_STATUS(DT_ALIAS(cstled0), okay)
//    {DT_GPIO_LABEL(DT_ALIAS(cstled0), gpios),
//     DT_GPIO_PIN(DT_ALIAS(cstled0), gpios),
//     DT_GPIO_FLAGS(DT_ALIAS(cstled0), gpios)},
//#endif
//};

#define LED0_NODE DT_ALIAS(cstled0)

#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)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0	""
#define PIN	0
#define FLAGS	0
#endif

//static const struct device *led_devs_cst[ARRAY_SIZE(led_pins_cst)];
static const struct device *dev;

int gpio_leds_init(void)
{
	int ret;
	dev = device_get_binding(LED0);
	if (dev == NULL) {
		return -ENODEV;
	}
	ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
	if (ret < 0) {
		return ret;
	}
	// for (size_t i = 0; i < ARRAY_SIZE(led_pins_cst); i++) {
	//
	// 	led_devs_cst[i] = device_get_binding(led_pins_cst[i].port);
	// 	if (!led_devs_cst[i]) {
	// 		LOG_ERR("Cannot bind gpio device");
	// 		return -ENODEV;
	// 	}
	//
	// 	err = gpio_pin_configure(led_devs_cst[i], led_pins_cst[i].number,
	// 				 GPIO_OUTPUT_ACTIVE | led_pins_cst[i].flags);
	// 	if (err) {
	// 		LOG_ERR("Cannot configure LED gpio");
	// 		return err;
	// 	}
	// 	LOG_INF("%s, %i, %i", led_pins_cst[i].port, led_pins_cst[i].number, led_pins_cst[i].flags);
	// }
        return 0;
}

//int cst_gpio_set_led(uint8_t led_idx, uint32_t val)
//{
//	int err;

//	if (led_idx >= ARRAY_SIZE(led_pins_cst)) {
//		LOG_ERR("LED index out of the range");
//		return -EINVAL;
//	}
//	err = gpio_pin_set(led_devs_cst[led_idx], led_pins_cst[led_idx].number, (int)val);
//        k_msleep(1000);
//	if (err) {
//		LOG_ERR("Cannot write LED gpio");
//	} else {
//                LOG_INF("GPIO %i is set to %i", led_idx, val);
//        }
//	return err;
//}

// int cst_gpio_set_led_on(uint8_t led_idx)
// {
// 	return cst_gpio_set_led(led_idx, 1);
// }
//
// int cst_gpio_set_led_off(uint8_t led_idx)
// {
// 	return cst_gpio_set_led(led_idx, 0);
// }

void cst_gpio_set_led_on(){
	gpio_pin_set(dev, PIN, (int)1);
}

void cst_gpio_set_led_off(){
	gpio_pin_set(dev, PIN, (int)0);
}

the main file:

/*
 * 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 "led_handler.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 CST_LED1

static struct k_work provisioning_work;

static struct k_timer led_timer;
static struct k_timer provisioning_timer;

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

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

	case THREAD_COAP_UTILS_LIGHT_CMD_OFF:
		// cst_gpio_set_led_off(LIGHT_LED);
		cst_gpio_set_led_off();
		val = 0;
		break;

	case THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE:
		val = !val;
		// cst_gpio_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)
{
	int ret;

	LOG_INF("Start CoAP-server sample");

	k_timer_init(&led_timer, on_led_timer_expiry, on_led_timer_stop);
	k_timer_init(&provisioning_timer, on_provisioning_timer_expiry, NULL);

	k_work_init(&provisioning_work, activate_provisioning);

	ret = ot_coap_init(&deactivate_provisionig, &on_light_request);
	if (ret) {
		LOG_ERR("Could not initialize OpenThread CoAP");
		goto end;
	}

	ret = dk_leds_init();
	ret = gpio_leds_init();
	cst_gpio_set_led_on();
        // cst_gpio_set_led_on(LIGHT_LED);
	if (ret) {
		LOG_ERR("Could not initialize leds, err code: %d", ret);
		goto end;
	}

	ret = dk_buttons_init(on_button_changed);
	if (ret) {
		LOG_ERR("Cannot init buttons (error: %d)", ret);
		goto end;
	}

	//openthread_set_state_changed_cb(on_thread_state_changed);
	//openthread_start(openthread_get_default_context());

end:
	return;
}

the overlay file I use:

/ {
	leds {
		cstled0: cst_led_0 {
			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; /* LED3 was using gpio0 31, change to 26 so it can be used by led4 */
			label = "Green LED 4";
		};
	};
	aliases {
		cstled0 = &cstled0;
	};
};

It's a problem with the way I use the device_get_binding method, I think, but not I'm not sure.

I really appreciate any help you can provide.

(update) I tried to make a blinky in the coap server file with an external LED, which doesn't work.

/*
 * 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 "led_handler.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 CST_LED1

#define LED0_NODE DT_ALIAS(cstled0)

#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)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0	""
#define PIN	0
#define FLAGS	0
#endif

static struct k_work provisioning_work;

static struct k_timer led_timer;
static struct k_timer provisioning_timer;

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

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

	case THREAD_COAP_UTILS_LIGHT_CMD_OFF:
		// cst_gpio_set_led_off(LIGHT_LED);
		cst_gpio_set_led_off();
		val = 0;
		break;

	case THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE:
		val = !val;
		// cst_gpio_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;
//		}
//	}
//}

#define SLEEP_TIME_MS   1000

void main(void)
{
	int ret;
        bool led_is_on = true;
	const struct device *dev;

	LOG_INF("Start CoAP-server sample");

	dev = device_get_binding(LED0);
	if (dev == NULL) {
		LOG_ERR("Can't get binding");
	}

	ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
	if (ret < 0) {
		LOG_ERR("can't configure pin");
	}
	LOG_INF("%s, %i, %i", LED0, PIN, FLAGS);

        while (1) {
		gpio_pin_set(dev, PIN, (int)led_is_on);
		led_is_on = !led_is_on;
		k_msleep(SLEEP_TIME_MS);
	}
  
	//k_timer_init(&led_timer, on_led_timer_expiry, on_led_timer_stop);
	//k_timer_init(&provisioning_timer, on_provisioning_timer_expiry, NULL);

	//k_work_init(&provisioning_work, activate_provisioning);

	//ret = ot_coap_init(&deactivate_provisionig, &on_light_request);
	//if (ret) {
	//	LOG_ERR("Could not initialize OpenThread CoAP");
	//	goto end;
	//}

	//ret = dk_leds_init();
	//ret = gpio_leds_init();
	//cst_gpio_set_led_off();
        // cst_gpio_set_led_on(LIGHT_LED);
	//if (ret) {
	//	LOG_ERR("Could not initialize leds, err code: %d", ret);
	//	goto end;
	//}

	//ret = dk_buttons_init(on_button_changed);
	//if (ret) {
	//	LOG_ERR("Cannot init buttons (error: %d)", ret);
	//	goto end;
	//}

	//openthread_set_state_changed_cb(on_thread_state_changed);
	//openthread_start(openthread_get_default_context());

end:
	return;
}

So I'm there is something in the build setting I think that doesn't seem correct. Only I do not know what is not correct (I'm a beginner in this build environment).

Parents Reply Children
No Data
Related