Add flush loop to XModem start prompt

Add flush loop to XModem start prompt (#8583)
This commit is contained in:
Theo Arends 2020-10-01 12:58:42 +02:00
parent 9f7ea31f73
commit 018964f08f
1 changed files with 40 additions and 15 deletions

View File

@ -99,6 +99,8 @@ char ZigbeeUploadFlashRead(void) {
* XModem protocol
\*********************************************************************************************/
// Number of milliseconds to wait before prompt is received
const uint32_t XMODEM_FLUSH_DELAY = 1000;
// Number of seconds until giving up hope of receiving sync packets from host.
const uint8_t XMODEM_SYNC_TIMEOUT = 30;
// Number of times we try to send a packet to the host until we give up sending..
@ -109,6 +111,7 @@ const uint8_t XMODEM_PACKET_SIZE = 128;
struct XMODEM {
uint32_t timeout = 0;
uint32_t delay = 0;
uint32_t flush_delay = 0xFFFFFFFF;
uint32_t filepos = 0;
int crcBuf = 0;
uint8_t packetNo = 1;
@ -215,21 +218,43 @@ bool ZigbeeUploadBootloaderPrompt(void) {
// Scripts that interact with the bootloader should use only the “BL >” prompt to determine
// when the bootloader is ready for input. While current menu options should remain functionally
// unchanged, the menu title and options text is liable to change, and new options might be added.
uint8_t serial_buffer[255];
uint32_t buf_len = 0;
while (ZigbeeSerial->available()) {
yield();
char bootloader_byte = ZigbeeSerial->read();
switch (ZbUpload.byte_counter) {
case 0:
if ('B' == bootloader_byte) { ZbUpload.byte_counter++; } break;
case 1:
if ('L' == bootloader_byte) { ZbUpload.byte_counter++; } break;
case 2:
if (' ' == bootloader_byte) { ZbUpload.byte_counter++; } break;
case 3:
if ('>' == bootloader_byte) { ZbUpload.byte_counter++; }
if (((uint8_t)bootloader_byte >=0) && (buf_len < sizeof(serial_buffer) -2)) {
serial_buffer[buf_len++] = bootloader_byte;
}
if (ZbUpload.byte_counter != 4) {
switch (ZbUpload.byte_counter) {
case 0:
if ('B' == bootloader_byte) { ZbUpload.byte_counter++; } break;
case 1:
if ('L' == bootloader_byte) { ZbUpload.byte_counter++; } break;
case 2:
if (' ' == bootloader_byte) { ZbUpload.byte_counter++; } break;
case 3:
if ('>' == bootloader_byte) {
ZbUpload.byte_counter++;
XModem.flush_delay = millis() + XMODEM_FLUSH_DELAY;
XModem.delay = XModem.flush_delay + XMODEM_FLUSH_DELAY;
}
}
}
}
return (4 == ZbUpload.byte_counter);
if (buf_len) {
char hex_char[256];
ToHex_P(serial_buffer, buf_len, hex_char, 256);
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("XMD: Rcvd %s"), hex_char);
}
return ((4 == ZbUpload.byte_counter) && (millis() > XModem.flush_delay));
}
bool ZigbeeUploadXmodem(void) {
@ -261,7 +286,7 @@ bool ZigbeeUploadXmodem(void) {
if (EZSP_Serial.to_send == EZSP_Serial.to_end) {
ZbUpload.bootloader = ZBU_SOFTWARE_RESET;
XModem.timeout = millis() + (10 * 1000); // Allow 10 seconds to receive EBL prompt
XModem.delay = millis() + 500;
XModem.delay = millis() + (2 * XMODEM_FLUSH_DELAY);
ZbUpload.byte_counter = 0;
ZbUpload.ota_step = ZBU_PROMPT;
}
@ -271,7 +296,7 @@ bool ZigbeeUploadXmodem(void) {
ZbUpload.bootloader = ZBU_HARDWARE_RESET;
ZigbeeUploadSetBootloader(0); // Reboot MCU EFR32 which returns below text
XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt
XModem.delay = millis() + 500;
XModem.delay = millis() + (2 * XMODEM_FLUSH_DELAY);
ZbUpload.byte_counter = 0;
ZbUpload.ota_step = ZBU_PROMPT;
break;
@ -292,7 +317,7 @@ bool ZigbeeUploadXmodem(void) {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init bootloader"));
ZigbeeUploadSetBootloader(0); // Reboot MCU EFR32 which returns below text
XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt
XModem.delay = millis() + 500;
XModem.delay = millis() + (2 * XMODEM_FLUSH_DELAY);
ZbUpload.byte_counter = 0;
ZbUpload.ota_step = ZBU_PROMPT;
break;
@ -304,12 +329,12 @@ bool ZigbeeUploadXmodem(void) {
return true;
}
#endif // ZIGBEE_BOOTLOADER_SOFTWARE_RESET_FIRST
else if (!ZigbeeSerial->available()) {
else if (!ZigbeeSerial->available() && (millis() < XModem.flush_delay)) {
// The target devices bootloader sends output over its serial port after it receives a
// carriage return from the source device
if (millis() > XModem.delay) {
ZigbeeSerial->write(XM_CR);
XModem.delay = millis() + 500;
XModem.delay = millis() + (2 * XMODEM_FLUSH_DELAY);
}
} else {
// After the bootloader receives a carriage return from the target device, it displays a menu