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).