From 173a6d917b61da223992a3c29e6fe47c34b1dfea Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 4 Jul 2020 19:59:59 +0200 Subject: [PATCH] Zigbee EZSP minor improvements --- tasmota/xdrv_23_zigbee_0_constants.ino | 1 + tasmota/xdrv_23_zigbee_7_statemachine.ino | 24 +++++++++++------------ tasmota/xdrv_23_zigbee_8_parsers.ino | 14 +++++++++++-- tasmota/xdrv_23_zigbee_9_serial.ino | 23 ++++++++++++++++++++++ 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 92af3a046..ac63d9878 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -27,6 +27,7 @@ #endif #define OCCUPANCY "Occupancy" // global define for Aqara +#define ZIGBEE_EZSP_RESET_LED 4 // Led number to drive the EZSP Reset pin typedef uint64_t Z_IEEEAddress; typedef uint16_t Z_ShortAddress; diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index bfc07793e..bc7fccf06 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -647,11 +647,11 @@ ZBM(ZBR_VERSION, EZSP_version, 0x00, 0x08, 0x02) // 00000802 - expect v8, p // general configuration // inspired from bellows: https://github.com/zigpy/bellows/blob/dev/bellows/config/ezsp.py -ZBM(ZBS_SET_ADDR_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x04, 0x00) // 53001E0400 +ZBM(ZBS_SET_ADDR_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x02, 0x00) // 53001E0400 ZBM(ZBS_SET_MCAST_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MULTICAST_TABLE_SIZE, 0x10, 0x00) // 5300061000 ZBM(ZBS_SET_STK_PROF, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_STACK_PROFILE, 0x02, 0x00) // 53000C0200 ZBM(ZBS_SET_SEC_LEVEL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SECURITY_LEVEL, 0x05, 0x00) // 53000D0500 -ZBM(ZBS_SET_MAX_DEVICES, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MAX_END_DEVICE_CHILDREN, 0x18, 0x00) // 5300111800 +ZBM(ZBS_SET_MAX_DEVICES, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MAX_END_DEVICE_CHILDREN, 0x20, 0x00) // 5300111800 ZBM(ZBS_SET_INDIRECT_TMO, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT, 0x00, 0x1E) // 530012001E ZBM(ZBS_SET_TC_CACHE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE, 0x02, 0x00) // 5300190200 ZBM(ZBS_SET_ROUTE_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE, 0x10, 0x00) // 53001A1000 @@ -671,21 +671,21 @@ ZBM(ZBR_SET_OK2, 0x00, 0x00 /*high*/, 0x00 /*ok*/) // 000000 - TODO why does // Add Endpoints ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, - 0x0E /* inputClusterCount */, // actually all clusters will be received + 0x00 /* inputClusterCount */, // actually all clusters will be received 0X00 /* outputClusterCount */, // 02000104010500000000 - 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 - 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 - 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 - 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + // 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + // 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + // 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + // 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 ) ZBM(ZBS_ADD_ENDPOINTB, EZSP_addEndpoint, 0x00 /*high*/, 0x0B /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, - 0x0E /* inputClusterCount */, // actually all clusters will be received + 0x00 /* inputClusterCount */, // actually all clusters will be received 0X00 /* outputClusterCount */, // 02000B04010500000000 - 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 - 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 - 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 - 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + // 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + // 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + // 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + // 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 ) ZBM(ZBR_ADD_ENDPOINT, EZSP_addEndpoint, 0x00 /*high*/, 0x00 /*ok*/) // 020000 diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 57313f687..d1b5d6b05 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -1026,9 +1026,19 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { // // Callback for loading Zigbee configuration from Flash, called by the state machine // +// value = 0 : drive reset pin and halt MCU +// value = 1 : release the reset pin, restart int32_t EZ_Reset_Device(uint8_t value) { - // TODO - GPIO is hardwired to GPIO4 - digitalWrite(4, value ? HIGH : LOW); + // 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_LED4, 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 + uint8_t ezsp_reset[1] = { 0xC0 }; // EZSP ASH Reset + ZigbeeEZSPSendRaw(ezsp_reset, sizeof(ezsp_reset), true); + } + } return 0; // continue } diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index 75c33e387..354bb507a 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -31,6 +31,9 @@ const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte +const uint32_t ZIGBEE_LED_RECEIVE = 0; // LED<1> blinks when receiving +const uint32_t ZIGBEE_LED_SEND = 0; // LED<2> blinks when receiving + class EZSP_Serial_t { public: uint8_t to_ack = 0; // 0..7, frame number of next id to send @@ -144,12 +147,17 @@ void ZigbeeInputLoop(void) { static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte static bool escape = false; // was the previous byte an escape? bool frame_complete = false; // frame is ready and complete + bool led_status_on = false; // did we turn on the led receive led // Receive only valid EZSP frames: // 1A - Cancel - cancel all previous bytes // 7D - Escape byte - following byte is escaped // 7E - end of frame while (ZigbeeSerial->available()) { + // turn on receive LED<1> + SetLedPowerIdx(ZIGBEE_LED_RECEIVE, 1); + led_status_on = true; // don't forget to switch it off + yield(); uint8_t zigbee_in_byte = ZigbeeSerial->read(); AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); @@ -194,6 +202,10 @@ void ZigbeeInputLoop(void) { zigbee_polling_window = millis(); // Wait for more data } // adding bytes } // while (ZigbeeSerial->available()) + // turn receive led off + if (led_status_on) { + SetLedPowerIdx(ZIGBEE_LED_RECEIVE, 0); + } uint32_t frame_len = zigbee_buffer->len(); if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { @@ -402,6 +414,8 @@ void ZigbeeEZSPSend_Out(uint8_t out_byte) { // - send frame // send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { + bool led_status_on = false; + if ((len < 1) || (len > 252)) { // abort, message cannot be less than 2 bytes for CMD1 and CMD2 AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len); @@ -409,6 +423,10 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { } uint8_t data_len = len - 2; // removing CMD1 and CMD2 + // turn send led on + SetLedPowerIdx(ZIGBEE_LED_SEND, 1); + led_status_on = true; + if (ZigbeeSerial) { if (send_cancel) { ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A @@ -448,6 +466,11 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { // finally send End of Frame ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A } + // turn send led off + if (led_status_on) { + SetLedPowerIdx(ZIGBEE_LED_SEND, 0); + } + // Now send a MQTT message to report the sent message char hex_char[(len * 2) + 2]; AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %s"),