From 6d34813f45ac75be07a76dbc5eec6066ae82085d Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 21 Jul 2020 22:39:39 +0200 Subject: [PATCH] Zigbee CC2530 more robust reset --- tasmota/xdrv_23_zigbee_7_statemachine.ino | 16 ++++------------ tasmota/xdrv_23_zigbee_8_parsers.ino | 22 +++++++++++++++++++++- tasmota/xdrv_23_zigbee_9_serial.ino | 10 ++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 50e67f91c..87bae5911 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -114,8 +114,6 @@ const uint8_t ZIGBEE_LABEL_START_ROUTER = 13; // Start ZNP as router const uint8_t ZIGBEE_LABEL_INIT_DEVICE = 14; // Init ZNP as end-device const uint8_t ZIGBEE_LABEL_START_DEVICE = 15; // Start ZNP as end-device const uint8_t ZIGBEE_LABEL_START_ROUTER_DEVICE = 16; // Start common to router and device -const uint8_t ZIGBEE_LABEL_BOOT_OK = 17; // MCU has rebooted -const uint8_t ZIGBEE_LABEL_BOOT_TIME_OUT = 18; // MCU has not rebooted const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST = 19; // common post configuration for router and device const uint8_t ZIGBEE_LABEL_READY = 20; // goto label 20 for main loop const uint8_t ZIGBEE_LABEL_MAIN_LOOP = 21; // main loop @@ -430,18 +428,12 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize //ZI_MQTT_STATE(ZIGBEE_STATUS_BOOT, "Booting") - //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") - ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BOOT_TIME_OUT) // give a second chance - ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 - ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s - ZI_GOTO(ZIGBEE_LABEL_BOOT_OK) + ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") - ZI_LABEL(ZIGBEE_LABEL_BOOT_TIME_OUT) - ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) - ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 + ZI_CALL(&ZNP_Reset_Device, 0) // LOW = reset + ZI_WAIT(100) // wait for .1 second + ZI_CALL(&ZNP_Reset_Device, 1) // HIGH = release reset ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s - - ZI_LABEL(ZIGBEE_LABEL_BOOT_OK) ZI_WAIT(100) ZI_LOG(LOG_LEVEL_DEBUG, kCheckingDeviceConfiguration) // Log Debug: checking device configuration ZI_SEND(ZBS_VERSION) // check ZNP software version diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index c08ff4d28..2382a97a3 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -1065,7 +1065,7 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { } // -// Callback for loading Zigbee configuration from Flash, called by the state machine +// Callback for resetting the NCP, called by the state machine // // value = 0 : drive reset pin and halt MCU // value = 1 : release the reset pin, restart @@ -1147,6 +1147,26 @@ int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu #ifdef USE_ZIGBEE_ZNP +// +// Callback for resetting the NCP, called by the state machine +// +// value = 0 : drive reset pin and halt MCU +// value = 1 : release the reset pin, restart +int32_t ZNP_Reset_Device(uint8_t value) { + // we use Led4i to drive the reset pin. Since it is reverted we need to pass 1 to start reset, and 0 to release reset + if (PinUsed(GPIO_LED1, ZIGBEE_EZSP_RESET_LED - 1)) { + SetLedPowerIdx(ZIGBEE_EZSP_RESET_LED - 1, value ? 0 : 1); + } else { + // no GPIO so we use software Reset instead + if (value) { // send reset only when we are supposed to release reset + // flush the serial buffer, sending 0xFF 256 times. + ZigbeeZNPFlush(); + ZigbeeZNPSend(ZBS_RESET, sizeof(ZBS_RESET)); + } + } + return 0; // continue +} + int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { uint16_t groupid = buf.get16(2); uint16_t clusterid = buf.get16(4); diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index cd5ef3c4f..c4f214bcd 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -302,6 +302,16 @@ void ZigbeeInitSerial(void) #ifdef USE_ZIGBEE_ZNP +// flush any ongoing frame, sending 256 times 0xFF +void ZigbeeZNPFlush(void) { + if (ZigbeeSerial) { + for (uint32_t i = 0; i < 256; i++) { + ZigbeeSerial->write(0xFF); + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " 0xFF x 255")); + } +} + void ZigbeeZNPSend(const uint8_t *msg, size_t len) { if ((len < 2) || (len > 252)) { // abort, message cannot be less than 2 bytes for CMD1 and CMD2