Merge pull request #146 from rbaron/zb-debug++

Fix (minor?) issues with the ZigBee sample
This commit is contained in:
rbaron 2023-07-15 09:25:18 +02:00 committed by GitHub
commit 95ec660cb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 111 additions and 85 deletions

View file

@ -7,7 +7,7 @@ config PRST_ZB_SLEEP_DURATION_SEC
config PRST_ZB_PARENT_POLL_INTERVAL_SEC
int "Interval for when b-parasite polls its parent for data in seconds."
default 60
default 10
config PRST_ZB_BUILD_DATE
string "Zigbee basic cluster build date attribute. Max 16 bytes."
@ -34,6 +34,9 @@ config PRST_ZB_FACTORY_RESET_VIA_RESET_PIN
config PRST_ZB_FACTORY_RESET_VIA_SW1
bool "Resetting while pressing and holding SW1 for 5 seconds will factory reset the device. Only available on v2.0.0+ hardware revisions."
config PRST_ZB_FACTORY_RESET_DISABLED
bool "No factory reset procedure."
endchoice # PRST_ZB_FACTORY_RESET_METHOD
config PRST_ZB_RESTART_WATCHDOG_TIMEOUT_SEC

View file

@ -8,9 +8,6 @@ CONFIG_GPIO=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096
CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
@ -39,8 +36,17 @@ CONFIG_NET_IPV6_RA_RDNSS=n
CONFIG_NET_IP_ADDR_CHECK=n
CONFIG_NET_UDP=n
##
## ZigBee Channel Selection
##
# Get Zigbee to scan every channel.
CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI=y
# By default only scans channel 11 (ZigBee2MQTT default) and 15 (ZHA default).
# Comment to scan all channels - this will make pairing consume more energy.
# CONFIG_ZIGBEE_CHANNEL_MASK=0x8800
# Uncomment to set a specific channel - this will make pairing more energy efficient.
# CONFIG_ZIGBEE_CHANNEL=11
# Enable API for powering down unused RAM parts.
# https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.7.1/nrf/ug_zigbee_configuring.html#power-saving-during-sleep

View file

@ -65,6 +65,7 @@ int prst_debug_counters_increment(const char* counter_name) {
if (written != sizeof(value)) {
LOG_ERR("fs_write returned %d, expected %d", written, sizeof(value));
}
RET_IF_ERR(fs_sync(&file));
return fs_close(&file);
}

View file

@ -66,6 +66,10 @@ int prst_zb_factory_reset_check() {
LOG_DBG("SW1 pressed. Scheduling timer");
k_timer_start(&sw1_factory_reset_check_timer, K_SECONDS(5), K_NO_WAIT);
}
#endif
return 0;
#elif CONFIG_PRST_ZB_FACTORY_RESET_DISABLED
return 0;
#else
#error "No factory reset method selected -- explicitly select CONFIG_PRST_ZB_FACTORY_RESET_DISABLED=y to disable it"
#endif // CONFIG_PRST_ZB_FACTORY_RESET_VIA_RESET_PIN
}

View file

@ -122,87 +122,26 @@ void identify_cb(zb_bufid_t bufid) {
prst_led_flash(15);
}
void zboss_signal_handler(zb_bufid_t bufid) {
// See zigbee_default_signal_handler() for all available signals.
zb_zdo_app_signal_hdr_t *sig_hndler = NULL;
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, /*sg_p=*/&sig_hndler);
zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
switch (sig) {
case ZB_BDB_SIGNAL_STEERING: // New network.
case ZB_BDB_SIGNAL_DEVICE_REBOOT: { // Previously joined network.
LOG_DBG("Steering complete. Status: %d", status);
if (status == RET_OK) {
LOG_DBG("Steering successful. Status: %d", status);
prst_debug_counters_increment("steering_success");
prst_led_flash(/*times=*/3);
k_timer_stop(&led_flashing_timer);
prst_restart_watchdog_stop();
prst_led_off();
} else {
LOG_DBG("Steering failed. Status: %d", status);
prst_debug_counters_increment("steering_failure");
prst_led_flash(/*times=*/7);
prst_restart_watchdog_start();
k_timer_stop(&led_flashing_timer); // Power saving
prst_led_off();
}
}
case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
joining_signal_received = true;
break;
case ZB_ZDO_SIGNAL_LEAVE:
if (status == RET_OK) {
k_timer_start(&led_flashing_timer, K_NO_WAIT, K_SECONDS(1));
zb_zdo_signal_leave_params_t *leave_params = ZB_ZDO_SIGNAL_GET_PARAMS(sig_hndler, zb_zdo_signal_leave_params_t);
LOG_INF("Network left (leave type: %d)", leave_params->leave_type);
void update_sensors_cb(zb_uint8_t arg) {
LOG_DBG("Updating sensors");
/* Set joining_signal_received to false so broken rejoin procedure can be detected correctly. */
if (leave_params->leave_type == ZB_NWK_LEAVE_TYPE_REJOIN) {
joining_signal_received = false;
}
}
case ZB_ZDO_SIGNAL_SKIP_STARTUP: {
stack_initialised = true;
LOG_DBG("Started zigbee stack and waiting for connection to network.");
k_timer_start(&led_flashing_timer, K_NO_WAIT, K_SECONDS(1));
break;
}
case ZB_NLME_STATUS_INDICATION: {
zb_zdo_signal_nlme_status_indication_params_t *nlme_status_ind =
ZB_ZDO_SIGNAL_GET_PARAMS(sig_hndler, zb_zdo_signal_nlme_status_indication_params_t);
if (nlme_status_ind->nlme_status.status == ZB_NWK_COMMAND_STATUS_PARENT_LINK_FAILURE) {
/* Check for broken rejoin procedure and restart the device to recover.
This implements Nordic's suggested workaround for errata KRKNWK-12017, which effects
the recent nRF Connect SDK (v1.8.0 - v2.3.0 at time of writing).
For details see: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/known_issues.html?v=v2-3-0
*/
if (stack_initialised && !joining_signal_received) {
prst_debug_counters_increment("krknwk_12017_reset");
// Reschedule the same callback.
zb_ret_t ret = ZB_SCHEDULE_APP_ALARM(
update_sensors_cb,
/*param=*/0,
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000 * CONFIG_PRST_ZB_SLEEP_DURATION_SEC));
if (ret != RET_OK) {
prst_debug_counters_increment("sens_cb_schedule_err");
zb_reset(0);
}
}
break;
}
}
ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
if (bufid) {
zb_buf_free(bufid);
}
}
void update_sensors_cb(zb_uint8_t arg) {
LOG_INF("Updating sensors");
ZB_SCHEDULE_APP_ALARM(update_sensors_cb,
/*param=*/0,
ZB_TIME_ONE_SECOND * CONFIG_PRST_ZB_SLEEP_DURATION_SEC);
prst_debug_counters_increment("sensors_read_before");
if (prst_sensors_read_all(&sensors)) {
prst_debug_counters_increment("sensors_read_error");
LOG_ERR("Unable to read sensors");
return;
}
prst_debug_counters_increment("sensors_read_after");
// Battery voltage in units of 100 mV.
uint8_t batt_voltage = sensors.batt.adc_read.millivolts / 100;
@ -241,6 +180,81 @@ void update_sensors_cb(zb_uint8_t arg) {
&log_lux);
}
void zboss_signal_handler(zb_bufid_t bufid) {
// See zigbee_default_signal_handler() for all available signals.
zb_zdo_app_signal_hdr_t *sig_hndler = NULL;
zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, /*sg_p=*/&sig_hndler);
zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
switch (sig) {
case ZB_BDB_SIGNAL_STEERING: // New network.
case ZB_BDB_SIGNAL_DEVICE_REBOOT: { // Previously joined network.
LOG_DBG("Steering complete. Status: %d", status);
if (status == RET_OK) {
LOG_DBG("Steering successful. Status: %d", status);
k_timer_stop(&led_flashing_timer);
prst_led_off();
prst_restart_watchdog_stop();
// Update the long polling parent interval - needs to be done after joining.
zb_zdo_pim_set_long_poll_interval(1000 * CONFIG_PRST_ZB_PARENT_POLL_INTERVAL_SEC);
} else {
LOG_DBG("Steering failed. Status: %d", status);
prst_restart_watchdog_start();
// Power saving.
k_timer_stop(&led_flashing_timer);
prst_led_off();
}
joining_signal_received = true;
break;
}
case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
joining_signal_received = true;
break;
case ZB_ZDO_SIGNAL_LEAVE:
if (status == RET_OK) {
k_timer_start(&led_flashing_timer, K_NO_WAIT, K_SECONDS(1));
zb_zdo_signal_leave_params_t *leave_params = ZB_ZDO_SIGNAL_GET_PARAMS(sig_hndler, zb_zdo_signal_leave_params_t);
LOG_DBG("Network left (leave type: %d)", leave_params->leave_type);
/* Set joining_signal_received to false so broken rejoin procedure can be detected correctly. */
if (leave_params->leave_type == ZB_NWK_LEAVE_TYPE_REJOIN) {
joining_signal_received = false;
}
}
break;
case ZB_ZDO_SIGNAL_SKIP_STARTUP: {
stack_initialised = true;
LOG_DBG("Started zigbee stack and waiting for connection to network.");
k_timer_start(&led_flashing_timer, K_NO_WAIT, K_SECONDS(1));
// Kick off main sensor update task.
ZB_SCHEDULE_APP_ALARM(update_sensors_cb,
/*param=*/0,
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000));
break;
}
case ZB_NLME_STATUS_INDICATION: {
zb_zdo_signal_nlme_status_indication_params_t *nlme_status_ind =
ZB_ZDO_SIGNAL_GET_PARAMS(sig_hndler, zb_zdo_signal_nlme_status_indication_params_t);
if (nlme_status_ind->nlme_status.status == ZB_NWK_COMMAND_STATUS_PARENT_LINK_FAILURE) {
/* Check for broken rejoin procedure and restart the device to recover.
This implements Nordic's suggested workaround for errata KRKNWK-12017, which effects
the recent nRF Connect SDK (v1.8.0 - v2.3.0 at time of writing).
For details see: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/known_issues.html?v=v2-3-0
*/
if (stack_initialised && !joining_signal_received) {
zb_reset(0);
}
}
break;
}
}
ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
if (bufid) {
zb_buf_free(bufid);
}
}
void log_counter(const char *counter_name, prst_debug_counter_t value) {
LOG_INF("- %s: %d", counter_name, value);
}
@ -252,6 +266,9 @@ int main(void) {
RET_IF_ERR(prst_flash_fs_init());
RET_IF_ERR(prst_debug_counters_init());
// Initialize sensors - quickly put them into low power mode.
RET_IF_ERR(prst_sensors_read_all(&sensors));
prst_debug_counters_increment("boot");
LOG_INF("Dumping debug counters:");
@ -263,19 +280,14 @@ int main(void) {
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
update_sensors_cb(/*arg=*/0);
zb_zdo_pim_set_long_poll_interval(
ZB_TIME_ONE_SECOND * CONFIG_PRST_ZB_PARENT_POLL_INTERVAL_SEC);
power_down_unused_ram();
RET_IF_ERR(prst_led_flash(2));
k_msleep(100);
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(PRST_ZIGBEE_ENDPOINT, identify_cb);
zigbee_enable();
zigbee_configure_sleepy_behavior(/*enable=*/true);
power_down_unused_ram();
zigbee_enable();
prst_debug_counters_increment("main_finish");