diff --git a/.gitignore b/.gitignore index a5309e6..ee1b733 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ build*/ +debug*/ +release*/ diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..ca6bbc7 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,38 @@ +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20 + }, + "configurePresets": [ + { + "name": "release", + "displayName": "Build for nRF52840 Dongle NRF52840", + "generator": "Ninja", + "binaryDir": "${sourceDir}/release", + "cacheVariables": { + "NCS_TOOLCHAIN_VERSION": "NONE", + "BOARD": "nrf52840dongle_nrf52840", + "BOARD_ROOT": "${sourceDir}/", + "CONFIG_SIZE_OPTIMIZATIONS": "y", + "CONF_FILE": "${sourceDir}/prj_release.conf", + "DTC_OVERLAY_FILE": "${sourceDir}/boards/nrf52840dongle_nrf52840.overlay" + } + }, + { + "name": "debug", + "displayName": "Build for nRF52840 Dongle NRF52840", + "generator": "Ninja", + "binaryDir": "${sourceDir}/debug", + "cacheVariables": { + "NCS_TOOLCHAIN_VERSION": "NONE", + "BOARD": "nrf52840dongle_nrf52840", + "BOARD_ROOT": "${sourceDir}/", + "CONFIG_DEBUG_OPTIMIZATIONS": "y", + "CONFIG_DEBUG_THREAD_INFO": "y", + "CONF_FILE": "${sourceDir}/prj_debug.conf", + "DTC_OVERLAY_FILE": "${sourceDir}/boards/nrf52840dongle_nrf52840.overlay" + } + } + ] +} \ No newline at end of file diff --git a/example_production_config.hex b/example_production_config.hex new file mode 100644 index 0000000..d1e2cc9 --- /dev/null +++ b/example_production_config.hex @@ -0,0 +1,6 @@ +:02000004000FEB +:10F00000E737DDF61B8DF2D939000100480C00000E +:10F010001100FFEEDDCCBBAA09090909090909099C +:10F02000090909090909090983FED3407A9397233D +:0DF03000A5C639B26916D505C3B501ABCD33 +:00000001FF diff --git a/example_production_config.yaml b/example_production_config.yaml new file mode 100644 index 0000000..3c4b786 --- /dev/null +++ b/example_production_config.yaml @@ -0,0 +1,5 @@ +channel_mask: 0x00000C48 +install_code: 83FED3407A939723A5C639B26916D505 +extended_address: AABBCCDDEEFF0011 +tx_power: 9 +app_data: 01ABCD \ No newline at end of file diff --git a/include/switch.h b/include/switch.h index 3a7290d..2496b34 100644 --- a/include/switch.h +++ b/include/switch.h @@ -69,7 +69,7 @@ ZB_AF_SIMPLE_DESC_TYPE(2, 1) ep_name ## _desc = { \ } \ }; \ \ -ZBOSS_DEVICE_DECLARE_REPORTING_CTX(ep_name ## _rep_ctx, 1); \ +ZBOSS_DEVICE_DECLARE_REPORTING_CTX(ep_name ## _rep_ctx, 3); \ ZB_AF_DECLARE_ENDPOINT_DESC(ep_name, ep_id, ZB_AF_HA_PROFILE_ID, 0, NULL, ZB_ZCL_ARRAY_SIZE(ep_name ## _clusters, zb_zcl_cluster_desc_t), ep_name ## _clusters, (zb_af_simple_desc_1_1_t *)&ep_name ## _desc, 1, ep_name ## _rep_ctx, 0, NULL) diff --git a/pm_static.yml b/pm_static_release.yml similarity index 100% rename from pm_static.yml rename to pm_static_release.yml diff --git a/prj_debug.conf b/prj_debug.conf new file mode 100644 index 0000000..3028c41 --- /dev/null +++ b/prj_debug.conf @@ -0,0 +1,79 @@ +# Configure serial +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_SERIAL=y + +# Make sure printk is not printing to the UART console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=n + +CONFIG_MAIN_THREAD_PRIORITY=7 + +CONFIG_ZIGBEE=y +CONFIG_ZIGBEE_APP_UTILS=y +CONFIG_ZIGBEE_ROLE_ROUTER=y + +CONFIG_NET_IPV6=n +CONFIG_NET_IP_ADDR_CHECK=n + +# Crypto config +CONFIG_CRYPTO=y +CONFIG_CRYPTO_NRF_ECB=y +CONFIG_CRYPTO_INIT_PRIORITY=80 + +# USB subsystem configuration +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="jamie Shell" +CONFIG_USB_CDC_ACM=y + +# Increase RX serial ring buffer +CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE=128 + +# Let apps control the serial line +CONFIG_UART_LINE_CTRL=y + +CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y + +CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI=y + +CONFIG_SHELL=y +CONFIG_ZIGBEE_SHELL=y +CONFIG_ZIGBEE_SHELL_DEBUG_CMD=y +CONFIG_SENSOR_SHELL=n + +CONFIG_HEAP_MEM_POOL_SIZE=4096 +CONFIG_BOARD_HAS_NRF5_BOOTLOADER=n + +CONFIG_DEBUG=y +CONFIG_DEBUG_THREAD_INFO=y +CONFIG_DEBUG_OPTIMIZATIONS=y + +CONFIG_DEBUG_INFO=y +CONFIG_MPSL_ASSERT_HANDLER=n + +CONFIG_NET_PKT_RX_COUNT=256 +CONFIG_NET_PKT_TX_COUNT=10 +CONFIG_ZIGBEE_SHELL_ENDPOINT=64 +CONFIG_DK_LIBRARY=n + +CONFIG_LOG=y +CONFIG_LOG_PROCESS_THREAD_STARTUP_DELAY_MS=0 + +CONFIG_MPSL_LOG_LEVEL_DBG=y +CONFIG_ZBOSS_TRACE_LOG_LEVEL_DBG=y + +CONFIG_USE_SEGGER_RTT=y +CONFIG_LOG_BACKEND_RTT=y +CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=10240 + +CONFIG_LOG_MODE_IMMEDIATE=y + +CONFIG_SHELL_LOG_BACKEND=n +CONFIG_USB_NRFX_WORK_QUEUE_STACK_SIZE=2048 +CONFIG_IEEE802154_NRF5_RX_STACK_SIZE=2048 +CONFIG_ZBOSS_DEFAULT_THREAD_STACK_SIZE=10240 +CONFIG_USB_WORKQUEUE_STACK_SIZE=4096 + +CONFIG_RESET_ON_FATAL_ERROR=y +CONFIG_FATAL_ERROR_LOG_LEVEL_DBG=y +CONFIG_ZBOSS_TRACE_MASK=0x00000C48 +CONFIG_ZBOSS_RESET_ON_ASSERT=n \ No newline at end of file diff --git a/prj.conf b/prj_release.conf similarity index 66% rename from prj.conf rename to prj_release.conf index af69635..3abd8eb 100644 --- a/prj.conf +++ b/prj_release.conf @@ -1,9 +1,3 @@ -# -# Copyright (c) 2022 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - # LOG configuration CONFIG_LOG=y CONFIG_LOG_MODE_DEFERRED=y @@ -26,36 +20,36 @@ CONFIG_ZIGBEE=y CONFIG_ZIGBEE_APP_UTILS=y CONFIG_ZIGBEE_ROLE_ROUTER=y -# Enable DK LED and Buttons library -CONFIG_DK_LIBRARY=y - -# This example requires more workqueue stack -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 +CONFIG_NET_IPV6=n +CONFIG_NET_IP_ADDR_CHECK=n -# Enable nRF ECB driver +# Crypto config CONFIG_CRYPTO=y CONFIG_CRYPTO_NRF_ECB=y CONFIG_CRYPTO_INIT_PRIORITY=80 -# Networking -CONFIG_NET_IPV6=n -CONFIG_NET_IP_ADDR_CHECK=n - # USB subsystem configuration CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="Zigbee Shell" +CONFIG_USB_DEVICE_PRODUCT="jamie Shell" CONFIG_USB_CDC_ACM=y + +# Let apps control the serial line CONFIG_UART_LINE_CTRL=y -# Initialize USB device as soon as possible as the USB CDC ACM is used -# as backend for both Shell and Logging subsystems. -CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y -CONFIG_BOARD_HAS_NRF5_BOOTLOADER=y +CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y -CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_RESET_ON_FATAL_ERROR=y +CONFIG_ZBOSS_RESET_ON_ASSERT=y CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI=y +CONFIG_SENSOR_SHELL=n + +CONFIG_SHELL=y +CONFIG_ZIGBEE_SHELL=y + +CONFIG_BOARD_HAS_NRF5_BOOTLOADER=y + CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_ZIGBEE_FOTA=y CONFIG_IMG_MANAGER=y @@ -64,6 +58,7 @@ CONFIG_STREAM_FLASH_ERASE=y CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="0.0.0" -CONFIG_SHELL=y -CONFIG_MCUBOOT_SHELL=y -CONFIG_SENSOR_SHELL=n \ No newline at end of file +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 +CONFIG_USB_NRFX_WORK_QUEUE_STACK_SIZE=2048 +CONFIG_IEEE802154_NRF5_RX_STACK_SIZE=2048 +CONFIG_ZBOSS_DEFAULT_THREAD_STACK_SIZE=10240 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 56ab3ae..47618a7 100644 --- a/src/main.c +++ b/src/main.c @@ -9,8 +9,6 @@ #include #include -#include - #include #include "switch.h" @@ -18,6 +16,7 @@ LOG_MODULE_REGISTER(app, LOG_LEVEL_INF); #define INFO_ENDPOINT 64 + #define SW0_EP 1 #define SW1_EP 2 #define SW2_EP 3 @@ -45,21 +44,22 @@ struct app_nvram { enum zb_zcl_on_off_switch_configuration_switch_actions_e actions[4]; }; - /* Zigbee device application context storage. */ static struct app_static app_static = { .basic_attr = { .zcl_version = ZB_ZCL_VERSION, - .power_source = ZB_ZCL_BASIC_POWER_SOURCE_MAINS_SINGLE_PHASE, - .ph_env = ZB_ZCL_BASIC_ENV_UNSPECIFIED, .app_version = 1, .stack_version = 10, .hw_version = 1, + .power_source = ZB_ZCL_BASIC_POWER_SOURCE_MAINS_SINGLE_PHASE, + .ph_env = ZB_ZCL_BASIC_ENV_UNSPECIFIED, + .mf_name = {0}, .model_id = {0}, .date_code = {0}, .location_id = {0}, + .sw_ver = {0}, }, .identify_attr = { .identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, @@ -108,7 +108,12 @@ ZB_DECLARE_SW_EP(sw1_ep, SW1_EP, app_ram.state_attributes[1], app_static.types[1 ZB_DECLARE_SW_EP(sw2_ep, SW2_EP, app_ram.state_attributes[2], app_static.types[2], app_nvram.actions[2]); ZB_DECLARE_SW_EP(sw3_ep, SW3_EP, app_ram.state_attributes[3], app_static.types[3], app_nvram.actions[3]); + +#ifdef CONFIG_ZIGBEE_FOTA +#include +#include extern zb_af_endpoint_desc_t zigbee_fota_client_ep; +#endif ZBOSS_DECLARE_DEVICE_CTX_EP_VA( zigbee_ctx, @@ -117,7 +122,10 @@ ZBOSS_DECLARE_DEVICE_CTX_EP_VA( &sw1_ep, &sw2_ep, &sw3_ep, - &zigbee_fota_client_ep); +#ifdef CONFIG_ZIGBEE_FOTA + &zigbee_fota_client_ep, +#endif + ); static const struct gpio_dt_spec network_led = GPIO_DT_SPEC_GET(DT_NODELABEL(network_led), gpios); static const struct gpio_dt_spec sw[4] = { @@ -137,11 +145,26 @@ static void zigbee_init_clusters(void) char model[] = "jamie"; ZB_ZCL_SET_STRING_VAL(app_static.basic_attr.model_id, model, ZB_ZCL_STRING_CONST_SIZE(model)); - char date[] = "jamie"; + char date[] = __DATE__; ZB_ZCL_SET_STRING_VAL(app_static.basic_attr.date_code, date, ZB_ZCL_STRING_CONST_SIZE(date)); - char location[] = "jamie"; - ZB_ZCL_SET_STRING_VAL(app_static.basic_attr.date_code, location, ZB_ZCL_STRING_CONST_SIZE(location)); + char location[] = "UNKNOWN"; + ZB_ZCL_SET_STRING_VAL(app_static.basic_attr.location_id, location, ZB_ZCL_STRING_CONST_SIZE(location)); + + char build_id[] = "debug"; + ZB_ZCL_SET_STRING_VAL(app_static.basic_attr.sw_ver, build_id, ZB_ZCL_STRING_CONST_SIZE(build_id)); + + for(size_t i = 0; i < 4; i++){ + app_ram.states[i] = gpio_pin_get_dt(&sw[i]); + switch(app_nvram.actions[i]){ + case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TYPE1: + app_ram.state_attributes[i].on_off = app_ram.states[i]; + case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TYPE2: + app_ram.state_attributes[i].on_off = !app_ram.states[i]; + case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TOGGLE: + app_ram.state_attributes[i].on_off = ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE; + } + } } typedef struct queue_item_s { @@ -206,13 +229,29 @@ static void configure_gpio(void) */ void zboss_signal_handler(zb_bufid_t bufid) { +#ifdef CONFIG_ZIGBEE_FOTA zigbee_fota_signal_handler(bufid); +#endif gpio_pin_toggle_dt(&network_led); zb_zdo_app_signal_hdr_t *sig_handler = NULL; zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &sig_handler); + zb_ret_t status = zb_buf_get_status(sig); switch (sig) { + case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY: + LOG_INF("Production config found"); + if (status != RET_OK) { + /* Production config is not present or invalid */ + } else { + zb_uint32_t app_data_length = zb_buf_len(bufid) - sizeof(zb_zdo_app_signal_hdr_t); + if (app_data_length != 0) + { + /* Process production config */ + } + } + break; + default: /* Call default signal handler. */ ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid)); @@ -267,6 +306,10 @@ zb_uint16_t app_nvram_size(void){ * used to pass received data. */ static void zcl_device_cb(zb_bufid_t bufid) { +#ifdef CONFIG_ZIGBEE_FOTA + zigbee_fota_zcl_cb(bufid); +#endif + zb_uint8_t cluster_id; zb_uint8_t attr_id; zb_zcl_device_callback_param_t *device_cb_param = ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t); @@ -285,28 +328,37 @@ static void zcl_device_cb(zb_bufid_t bufid) { case ZB_ZCL_ATTR_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_ID: uint8_t value = device_cb_param->cb_param.set_attr_value_param.values.data8; uint8_t ep = device_cb_param->endpoint; - uint8_t sw = ep - 1; - zb_bool_t sw_val = app_ram.states[sw]; - switch(app_nvram.actions[sw]) { - case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TYPE1: - break; - case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TYPE2: - sw_val = !sw_val; - break; - case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TOGGLE: - sw_val = app_ram.state_attributes[sw].on_off; - break; + uint8_t sw = 0xFF; + for(uint8_t i = 0; i < 4; i++) { + if(sw_ep[i] == ep){ + sw = i; + break; + } } - - ZB_SCHEDULE_APP_CALLBACK(set_sw, ((sw & 0x0F) << 4) + ((sw_val & 0x0F) << 0)); - - LOG_INF("New switch actions: %d - %d", ep, value); - zb_ret_t err = zb_nvram_write_dataset(ZB_NVRAM_APP_DATA1); - if(err){ - LOG_ERR("Failed to write app1 nvram: %e", err); + if(sw != 0xFF) { + zb_bool_t sw_val = app_ram.states[sw]; + switch(app_nvram.actions[sw]) { + case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TYPE1: + break; + case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TYPE2: + sw_val = !sw_val; + break; + case ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_TOGGLE: + sw_val = app_ram.state_attributes[sw].on_off; + break; + } + ZB_SCHEDULE_APP_CALLBACK(set_sw, ((sw & 0x0F) << 4) + ((sw_val & 0x0F) << 0)); + LOG_INF("New switch actions: %d - %d", ep, value); + zb_ret_t err = zb_nvram_write_dataset(ZB_NVRAM_APP_DATA1); + if(err){ + LOG_ERR("Failed to write app1 nvram: %d", err); + } else { + LOG_INF("Wrote app1 nvram"); + } } else { - LOG_INF("Wrote app1 nvram"); + LOG_ERR("Got on off switch configuration for unknown switch endpoint: %d", ep); } + break; default: LOG_WRN("Unhandled on_off_switch_cfg attribute ID: %d", attr_id); @@ -316,20 +368,18 @@ static void zcl_device_cb(zb_bufid_t bufid) { break; default: LOG_WRN("Unhandled cluster ID: %d", cluster_id); - device_cb_param->status = RET_NOT_IMPLEMENTED; break; } break; default: LOG_WRN("Unhandled callback ID: %d", device_cb_param->device_cb_id); - device_cb_param->status = RET_NOT_IMPLEMENTED; break; } - - zigbee_fota_zcl_cb(bufid); } + +#ifdef CONFIG_ZIGBEE_FOTA /**@brief Callback function for handling OTA events. * * @param[in] *evt Structure containing event information @@ -346,6 +396,7 @@ static void ota_evt_handler(const struct zigbee_fota_evt *evt) break; } } +#endif int main(void) { @@ -354,19 +405,20 @@ int main(void) /* Initialize */ configure_gpio(); - /* Register device callback */ - ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb); + zigbee_init_clusters(); /* Register device context (endpoints). */ ZB_AF_REGISTER_DEVICE_CTX(&zigbee_ctx); - /* Initialize Zigbee FOTA download service. */ - zigbee_fota_init(ota_evt_handler); - - zigbee_init_clusters(); + /* Register device callback */ + ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb); ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(INFO_ENDPOINT, identify_cb); + +#ifdef CONFIG_ZIGBEE_FOTA + zigbee_fota_init(ota_evt_handler); ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(CONFIG_ZIGBEE_FOTA_ENDPOINT, identify_cb); +#endif zb_nvram_register_app1_read_cb(app_nvram_read); zb_nvram_register_app1_write_cb(app_nvram_write, app_nvram_size); @@ -375,9 +427,10 @@ int main(void) LOG_INF("Zigbee Stack Initialized"); +#ifdef CONFIG_ZIGBEE_FOTA boot_write_img_confirmed(); - LOG_INF("Confirmed firmware"); +#endif while(true) { queue_item_t* item = (queue_item_t*) k_queue_get(&switch_queue, K_FOREVER);