From 0082aedf128a8f872122f1704c0992c2b6e03623 Mon Sep 17 00:00:00 2001 From: Kiril Petrov Date: Sun, 15 Sep 2019 11:08:17 -0700 Subject: [PATCH 1/2] net: lwm2m: add IPSO Push Button example Tested on nRF52840-PCA10056 board with Leshan as bootstrap and LWM2M server. Add up to 4 instances on Push Button object (/3347) and click on their observe methods. Push button on pca10056 board and status on leshan server should became 'true' until button is released. Signed-off-by: Kiril Petrov --- subsys/net/lib/lwm2m/ipso_push_button.c | 184 ++++++++++++++++++++++++ 1 file changed, 184 insertions(+) diff --git a/subsys/net/lib/lwm2m/ipso_push_button.c b/subsys/net/lib/lwm2m/ipso_push_button.c index c84ae6985fb9c..244db6f7e0185 100644 --- a/subsys/net/lib/lwm2m/ipso_push_button.c +++ b/subsys/net/lib/lwm2m/ipso_push_button.c @@ -18,6 +18,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include +#include + #include "lwm2m_object.h" #include "lwm2m_engine.h" @@ -36,6 +38,18 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); */ #define RESOURCE_INSTANCE_COUNT (BUTTON_MAX_ID) +struct sw { + struct gpio_callback button_cb; + struct k_timer button_timer; + struct k_work button_work; + struct device *gpio; + u8_t sw_num; + u8_t pin; +}; + +static struct sw sw; +static u32_t time, last_time; + /* resource state */ struct ipso_button_data { u64_t counter; @@ -148,6 +162,174 @@ static struct lwm2m_engine_obj_inst *button_create(u16_t obj_inst_id) return &inst[avail]; } +#define BUTTON_DEBOUNCE_DELAY_MS 250 + +static uint8_t pin_pos_to_pin(uint32_t pin_pos) +{ + switch (pin_pos) { + case BIT(DT_ALIAS_SW0_GPIOS_PIN): + return DT_ALIAS_SW0_GPIOS_PIN; + case BIT(DT_ALIAS_SW1_GPIOS_PIN): + return DT_ALIAS_SW1_GPIOS_PIN; + case BIT(DT_ALIAS_SW2_GPIOS_PIN): + return DT_ALIAS_SW2_GPIOS_PIN; + case BIT(DT_ALIAS_SW3_GPIOS_PIN): + return DT_ALIAS_SW3_GPIOS_PIN; + } + + LOG_ERR("No match for GPIO pin 0x%08x\n", pin_pos); + + return 0; +} + +static uint8_t pin_pos_to_sw_num(uint32_t pin_pos) +{ + switch (pin_pos) { + case BIT(DT_ALIAS_SW0_GPIOS_PIN): return 0; + case BIT(DT_ALIAS_SW1_GPIOS_PIN): return 1; + case BIT(DT_ALIAS_SW2_GPIOS_PIN): return 2; + case BIT(DT_ALIAS_SW3_GPIOS_PIN): return 3; + } + + LOG_ERR("No match for GPIO pin 0x%08x\n", pin_pos); + + return 0; +} + +static void button_off_timer(struct k_timer *work) +{ + struct sw *sw = CONTAINER_OF(work, struct sw, button_timer); + char pathstr[15]; + u32_t val = 0U; + + gpio_pin_read(sw->gpio, sw->pin, &val); + LOG_DBG("%s: switch=%d, val=%d", __func__, sw->sw_num, val); + + if (val == 0) { + k_timer_start(&sw->button_timer, K_SECONDS(1), 0); + return; + } + + snprintk(pathstr, sizeof(pathstr), "/%u/%u/%u", + IPSO_OBJECT_PUSH_BUTTON_ID, sw->sw_num, + BUTTON_DIGITAL_STATE_ID); + lwm2m_engine_set_bool(pathstr, !val); +} + +static void button_pressed_worker(struct k_work *work) +{ + struct sw *sw = CONTAINER_OF(work, struct sw, button_work); + char pathstr[15]; + u32_t val = 0U; + + LOG_DBG("%s: switch=%d", __func__, sw->sw_num); + + gpio_pin_read(sw->gpio, sw->pin, &val); + + snprintk(pathstr, sizeof(pathstr), "/%u/%u/%u", + IPSO_OBJECT_PUSH_BUTTON_ID, sw->sw_num, + BUTTON_DIGITAL_STATE_ID); + lwm2m_engine_set_bool(pathstr, !val); + + k_timer_stop(&sw->button_timer); + k_timer_start(&sw->button_timer, K_MSEC(500), 0); +} + +static void button_pressed(struct device *dev, struct gpio_callback *cb, + u32_t pin_pos) +{ + struct sw *sw = CONTAINER_OF(cb, struct sw, button_cb); + int i; + + time = k_uptime_get_32(); + + /* debounce the switch */ + if (time < last_time + BUTTON_DEBOUNCE_DELAY_MS) { + last_time = time; + return; + } + + LOG_DBG("%s: pin_pos=0x%08X", __func__, pin_pos); + + /* If any button is already pressed, just return */ + for (i = 0; i < ARRAY_SIZE(inst); i++) { + if (button_data[i].state) { + LOG_ERR("%s: button %d is still pressed", __func__, i); + return; + } + } + + sw->pin = pin_pos_to_pin(pin_pos); + sw->sw_num = pin_pos_to_sw_num(pin_pos); + + k_work_submit(&sw->button_work); + + last_time = time; +} + +static void configure_buttons(void) +{ + /* Initialize the button debouncer */ + last_time = k_uptime_get_32(); + + /* Initialize button worker task */ + k_work_init(&sw.button_work, button_pressed_worker); + + /* Initialize button off timer */ + k_timer_init(&sw.button_timer, button_off_timer, NULL); + + sw.gpio = device_get_binding(DT_ALIAS_SW0_GPIOS_CONTROLLER); + if (!sw.gpio) { + LOG_ERR("Can't get gpio device"); + return; + } + + gpio_pin_configure(sw.gpio, DT_ALIAS_SW0_GPIOS_PIN, + (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | + GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP)); +#ifdef DT_ALIAS_SW1_GPIOS_PIN + gpio_pin_configure(sw.gpio, DT_ALIAS_SW1_GPIOS_PIN, + (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | + GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP)); +#endif +#ifdef DT_ALIAS_SW2_GPIOS_PIN + gpio_pin_configure(sw.gpio, DT_ALIAS_SW2_GPIOS_PIN, + (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | + GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP)); +#endif +#ifdef DT_ALIAS_SW3_GPIOS_PIN + gpio_pin_configure(sw.gpio, DT_ALIAS_SW3_GPIOS_PIN, + (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | + GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP)); +#endif + + gpio_init_callback(&sw.button_cb, button_pressed, + BIT(DT_ALIAS_SW0_GPIOS_PIN) +#ifdef DT_ALIAS_SW1_GPIOS_PIN + | BIT(DT_ALIAS_SW1_GPIOS_PIN) +#endif +#ifdef DT_ALIAS_SW2_GPIOS_PIN + | BIT(DT_ALIAS_SW2_GPIOS_PIN) +#endif +#ifdef DT_ALIAS_SW3_GPIOS_PIN + | BIT(DT_ALIAS_SW3_GPIOS_PIN) +#endif + ); + + gpio_add_callback(sw.gpio, &sw.button_cb); + + gpio_pin_enable_callback(sw.gpio, DT_ALIAS_SW0_GPIOS_PIN); +#ifdef DT_ALIAS_SW1_GPIOS_PIN + gpio_pin_enable_callback(sw.gpio, DT_ALIAS_SW1_GPIOS_PIN); +#endif +#ifdef DT_ALIAS_SW2_GPIOS_PIN + gpio_pin_enable_callback(sw.gpio, DT_ALIAS_SW2_GPIOS_PIN); +#endif +#ifdef DT_ALIAS_SW3_GPIOS_PIN + gpio_pin_enable_callback(sw.gpio, DT_ALIAS_SW3_GPIOS_PIN); +#endif +} + static int ipso_button_init(struct device *dev) { onoff_switch.obj_id = IPSO_OBJECT_PUSH_BUTTON_ID; @@ -157,6 +339,8 @@ static int ipso_button_init(struct device *dev) onoff_switch.create_cb = button_create; lwm2m_register_obj(&onoff_switch); + configure_buttons(); + return 0; } From 5587292a5ddb988e36c43b349cfa1d0e042ebbcf Mon Sep 17 00:00:00 2001 From: Kiril Petrov Date: Sun, 15 Sep 2019 11:09:16 -0700 Subject: [PATCH 2/2] net: OpenThread: Add example conf file Example config for OpenThread with Zephyr Signed-off-by: Kiril Petrov --- samples/net/lwm2m_client/overlay-ot.conf | 123 +++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 samples/net/lwm2m_client/overlay-ot.conf diff --git a/samples/net/lwm2m_client/overlay-ot.conf b/samples/net/lwm2m_client/overlay-ot.conf new file mode 100644 index 0000000000000..7a7510c749a64 --- /dev/null +++ b/samples/net/lwm2m_client/overlay-ot.conf @@ -0,0 +1,123 @@ +# +# ARM Cortex-M0/M0+/M3/M4/M7/M23/M33 options +# +CONFIG_MPU_ALLOW_FLASH_WRITE=y + +# +# Work Queue Options +# +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# +# Other Kernel Object Options +# +CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_ENTROPY_GENERATOR=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_SENSOR=y + +# +# OS Support Library +# +CONFIG_CPLUSPLUS=y + +# +# Debugging Options +# +CONFIG_PRINTK=y + +# +# File Systems +# +CONFIG_NVS=y + +CONFIG_LOG=y +CONFIG_LOG_BUFFER_SIZE=4096 + +# +# Networking +# +CONFIG_NETWORKING=y + +# +# Link layer options +# +CONFIG_NET_L2_OPENTHREAD=y +CONFIG_OPENTHREAD_PLAT=y +CONFIG_OPENTHREAD_DEBUG=y +CONFIG_OPENTHREAD_LOG_LEVEL_INFO=y +CONFIG_OPENTHREAD_PANID=17185 +CONFIG_OPENTHREAD_CHANNEL=11 +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" +CONFIG_OPENTHREAD_XPANID="01:23:45:67:89:AB:CD:EF" +CONFIG_OPENTHREAD_SHELL=y +CONFIG_OPENTHREAD_JOINER=y +CONFIG_OPENTHREAD_JOINER_AUTOSTART=y +CONFIG_OPENTHREAD_JOINER_PSKD="J01NME" + +# +# IP stack +# +CONFIG_NET_IPV6=y +CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=4 +CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4 +# CONFIG_NET_IPV6_MLD is not set +# CONFIG_NET_IPV6_NBR_CACHE is not set +CONFIG_NET_SHELL=y +CONFIG_NET_UDP=y +CONFIG_NET_MAX_CONTEXTS=10 +CONFIG_NET_PKT_RX_COUNT=10 +CONFIG_NET_PKT_TX_COUNT=10 +CONFIG_NET_BUF_RX_COUNT=10 +CONFIG_NET_BUF_TX_COUNT=10 + +# +# Stack usage +# +CONFIG_NET_TX_STACK_SIZE=2048 +CONFIG_NET_RX_STACK_SIZE=5120 +CONFIG_NET_LOG=y + +# +# Network Protocols +# +CONFIG_COAP_EXTENDED_OPTIONS_LEN=y +CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=32 +CONFIG_LWM2M=y +CONFIG_LWM2M_LOG_LEVEL_INF=y +CONFIG_LWM2M_COAP_BLOCK_SIZE=512 +CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP=y +CONFIG_LWM2M_PEER_PORT=25783 +CONFIG_LWM2M_SERVER_DEFAULT_PMIN=1 +CONFIG_LWM2M_SERVER_INSTANCE_COUNT=2 +CONFIG_LWM2M_CONN_MON_OBJ_SUPPORT=y +CONFIG_LWM2M_LOCATION_OBJ_SUPPORT=y + +# +# IPSO Alliance Smart Object Support +# +CONFIG_LWM2M_IPSO_SUPPORT=y +CONFIG_LWM2M_IPSO_TEMP_SENSOR=y +CONFIG_LWM2M_IPSO_LIGHT_CONTROL=y +CONFIG_LWM2M_IPSO_ACCELEROMETER=y +CONFIG_LWM2M_IPSO_BUZZER=y +CONFIG_LWM2M_IPSO_TIMER=y +CONFIG_LWM2M_IPSO_ONOFF_SWITCH=y +CONFIG_LWM2M_IPSO_PUSH_BUTTON=y +CONFIG_LWM2M_IPSO_PUSH_BUTTON_INSTANCE_COUNT=4 + +# +# Network Libraries +# +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" +CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" +CONFIG_NET_SOCKETS=y +CONFIG_NET_SOCKETS_POSIX_NAMES=y +CONFIG_NET_SOCKETS_POLL_MAX=4 +CONFIG_IMG_MANAGER=y +CONFIG_MCUBOOT_IMG_MANAGER=y +CONFIG_IMG_BLOCK_BUF_SIZE=512 +CONFIG_BOOTLOADER_MCUBOOT=y +CONFIG_REBOOT=y