Merge pull request #11967 from s-hadinger/zigbee_xmodem_fix

Zigbee allow EFR32 flashing for Tube's device and fix Xmodem retries
This commit is contained in:
s-hadinger 2021-04-30 21:39:04 +02:00 committed by GitHub
commit 32e08c8c9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 16 deletions

View File

@ -2139,6 +2139,7 @@ Y09 {"NAME":"Y09","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0
## Zigbee Bridge
```
Sonoff ZBBridge {"NAME":"Sonoff ZbBridge","GPIO":[320,3552,0,3584,5312,0,0,0,640,576,608,0,32,0],"FLAG":0,"BASE":75}
Tube's CC2652P2 Ethernet to {"NAME":"Tube ZB CC2652","GPIO":[0,0,0,3840,0,3584,0,0,0,0,0,0,5536,3552,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,3840,5792,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Sonoff ZBBridge {"NAME":"Sonoff ZbBridge","GPIO":[320,3552,0,3584,5312,5313,0,0,640,576,608,0,32,0],"FLAG":0,"BASE":75}
Tube's CC2652P2 Ethernet {"NAME":"Tube ZB CC2652","GPIO":[0,0,0,3840,0,3584,0,0,0,0,0,0,5536,3552,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,3840,5792,0,0,0,0,0,0],"FLAG":0,"BASE":1}
Tube's EFR32 Ethernet {"NAME":"Tube ZB EFR32","GPIO":[0,0,0,3840,0,3552,1,0,0,0,0,0,5536,3584,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,5793,5792,0,0,0,0,0,0],"FLAG":0,"BASE":1}
```

View File

@ -700,7 +700,7 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#ifdef USE_ZIGBEE
AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface
AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface
AGPIO(GPIO_ZIGBEE_RST), // Zigbee reset
AGPIO(GPIO_ZIGBEE_RST) + 2, // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode
#endif
#ifdef USE_MHZ19
AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface

View File

@ -302,6 +302,10 @@ void ZigbeeInitSerial(void)
pinMode(Pin(GPIO_ZIGBEE_RST), OUTPUT);
digitalWrite(Pin(GPIO_ZIGBEE_RST), 1);
}
if (PinUsed(GPIO_ZIGBEE_RST, 1)) {
pinMode(Pin(GPIO_ZIGBEE_RST, 1), OUTPUT);
digitalWrite(Pin(GPIO_ZIGBEE_RST, 1), 1);
}
zigbee.active = true;
zigbee.init_phase = true; // start the state machine

View File

@ -42,13 +42,14 @@ enum ZbUploadSteps { ZBU_IDLE, ZBU_INIT,
ZBU_SOFTWARE_RESET, ZBU_SOFTWARE_SEND, ZBU_HARDWARE_RESET, ZBU_PROMPT,
ZBU_SYNC, ZBU_UPLOAD, ZBU_EOT, ZBU_COMPLETE, ZBU_DONE, ZBU_ERROR, ZBU_FINISH };
const uint8_t PIN_ZIGBEE_BOOTLOADER = 5;
const uint8_t PIN_ZIGBEE_DEFAULT_BOOTLOADER = 5; // default pin for Sonoff ZBBridge
struct ZBUPLOAD {
uint32_t ota_size = 0;
uint32_t sector_counter = 0;
int32_t sector_base = -1;
int32_t sector_counter = -1;
uint32_t byte_counter = 0;
char *buffer;
char *buffer = nullptr;
uint8_t ota_step = ZBU_IDLE;
uint8_t bootloader = 0;
uint8_t state = ZBU_IDLE;
@ -65,16 +66,18 @@ uint32_t ZigbeeUploadAvailable(void) {
}
char ZigbeeUploadFlashRead(void) {
if (0 == ZbUpload.byte_counter) {
if (nullptr == ZbUpload.buffer) {
if (!(ZbUpload.buffer = (char *)malloc(SPI_FLASH_SEC_SIZE))) {
return (-1); // Not enough (memory) space
return -1; // Not enough (memory) space
}
}
uint32_t index = ZbUpload.byte_counter % SPI_FLASH_SEC_SIZE;
if (0 == index) {
int32_t sector = ZbUpload.sector_base + ZbUpload.byte_counter / SPI_FLASH_SEC_SIZE;
if (sector != ZbUpload.sector_counter) {
ZbUpload.sector_counter = sector;
ESP.flashRead(ZbUpload.sector_counter * SPI_FLASH_SEC_SIZE, (uint32_t*)ZbUpload.buffer, SPI_FLASH_SEC_SIZE);
ZbUpload.sector_counter++;
// AddLog_P(LOG_LEVEL_DEBUG, "= sector %d %*_H", ZbUpload.sector_counter, 256, ZbUpload.buffer);
}
char data = ZbUpload.buffer[index];
@ -91,7 +94,6 @@ char ZigbeeUploadFlashRead(void) {
// When the source device reaches the last XModem data block, it should be padded to 128 bytes
// of data using SUB (ASCII 0x1A) characters.
data = XM_SUB;
// if (ZbUpload.buffer) { free(ZbUpload.buffer); } // Don't in case of retries
}
return data;
}
@ -146,7 +148,7 @@ char XModemWaitACK(void)
while (!ZigbeeSerial->available()) {
delayMicroseconds(100);
i++;
if (i > 200) { return -1; }
if (i > 4000) { return -1; }
}
in_char = ZigbeeSerial->read();
@ -176,6 +178,7 @@ bool XModemSendPacket(uint32_t packet_no) {
uint8_t packet_num = packet_no;
// AddLog(LOG_LEVEL_DEBUG, "++ Packet %d, retries %d, counter %d", packet_no, retries, ZbUpload.byte_counter);
// Try to send packet, so header first
ZigbeeSerial->write(XM_SOH);
ZigbeeSerial->write(packet_num);
@ -215,8 +218,11 @@ void ZigbeeUploadSetSoftwareBootloader() {
}
void ZigbeeUploadSetBootloader(uint8_t state) {
pinMode(PIN_ZIGBEE_BOOTLOADER, OUTPUT);
digitalWrite(PIN_ZIGBEE_BOOTLOADER, state); // Toggle Gecko bootloader
int32_t pin_bootloader = Pin(GPIO_ZIGBEE_RST, 1);
if (pin_bootloader < 0) { pin_bootloader = PIN_ZIGBEE_DEFAULT_BOOTLOADER; }
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Bootloader pin %d"), pin_bootloader);
pinMode(pin_bootloader, OUTPUT);
digitalWrite(pin_bootloader, state); // Toggle Gecko bootloader
digitalWrite(Pin(GPIO_ZIGBEE_RST), 0);
delay(100); // Need to experiment to find a value as low as possible
digitalWrite(Pin(GPIO_ZIGBEE_RST), 1); // Reboot MCU EFR32
@ -301,6 +307,7 @@ bool ZigbeeUploadXmodem(void) {
XModem.timeout = millis() + (10 * 1000); // Allow 10 seconds to receive EBL prompt
XModem.delay = millis() + (2 * XMODEM_FLUSH_DELAY);
ZbUpload.byte_counter = 0;
ZbUpload.sector_counter = -1;
ZbUpload.ota_step = ZBU_PROMPT;
}
break;
@ -311,6 +318,7 @@ bool ZigbeeUploadXmodem(void) {
XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt
XModem.delay = millis() + (2 * XMODEM_FLUSH_DELAY);
ZbUpload.byte_counter = 0;
ZbUpload.sector_counter = -1;
ZbUpload.ota_step = ZBU_PROMPT;
break;
}
@ -332,6 +340,7 @@ bool ZigbeeUploadXmodem(void) {
XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt
XModem.delay = millis() + (2 * XMODEM_FLUSH_DELAY);
ZbUpload.byte_counter = 0;
ZbUpload.sector_counter = -1;
ZbUpload.ota_step = ZBU_PROMPT;
break;
}
@ -390,8 +399,10 @@ bool ZigbeeUploadXmodem(void) {
XModem.oldChecksum = (xmodem_sync == XM_NAK);
XModem.packet_no = 1;
ZbUpload.byte_counter = 0;
ZbUpload.sector_counter = -1;
ZbUpload.ota_step = ZBU_UPLOAD;
AddLog(LOG_LEVEL_DEBUG, PSTR("XMD: Init packet send"));
delay(100);
}
}
break;
@ -440,6 +451,7 @@ bool ZigbeeUploadXmodem(void) {
AddLog(LOG_LEVEL_DEBUG, PSTR("XMD: " D_SUCCESSFUL));
XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt
ZbUpload.byte_counter = 0;
ZbUpload.sector_counter = -1;
ZbUpload.ota_step = ZBU_COMPLETE;
}
}
@ -479,7 +491,7 @@ bool ZigbeeUploadXmodem(void) {
TasmotaGlobal.sleep = Settings.sleep; // Restore loop sleep
}
// TasmotaGlobal.restart_flag = 2; // Restart to disable bootloader and use new firmware
if (ZbUpload.buffer) { free(ZbUpload.buffer); }
if (ZbUpload.buffer) { free(ZbUpload.buffer); ZbUpload.buffer = nullptr; }
ZbUpload.ota_step = ZBU_FINISH; // Never return to zero without a restart to get a sane Zigbee environment
break;
}
@ -506,7 +518,8 @@ uint8_t ZigbeeUploadStep1Init(void) {
}
void ZigbeeUploadStep1Done(uint32_t data, size_t size) {
ZbUpload.sector_counter = data;
ZbUpload.sector_base = data;
ZbUpload.sector_counter = -1;
ZbUpload.ota_size = size;
ZbUpload.ota_step = ZBU_INIT;
ZbUpload.state = ZBU_UPLOAD; // Signal upload done and ready for delayed upload to MCU EFR32