diff --git a/.vscode/arduino.json b/.vscode/arduino.json index dc9b2a4..2b2db57 100644 --- a/.vscode/arduino.json +++ b/.vscode/arduino.json @@ -1,7 +1,7 @@ { "board": "esp8266:esp8266:nodemcuv2", "output": "D://Users//Robert//Documents//GitHub//build", - "configuration": "xtal=160,vt=flash,exception=legacy,ssl=all,eesz=4M2M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=sdk,baud=115200", + "configuration": "xtal=160,vt=flash,exception=legacy,ssl=all,eesz=4M2M,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600", "port": "COM4", "prebuild": "D://Users//Robert//Documents//GitHub//Rvdb//autoinc-semver//semver-incr-build.bat ./version.h", "sketch": "OTGW-firmware.ino" diff --git a/.vscode/settings.json b/.vscode/settings.json index 16fbcc2..4c046b1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,6 +14,13 @@ "string": "cpp", "fstream": "cpp", "cstring": "cpp", - "regex": "cpp" + "regex": "cpp", + "array": "cpp", + "deque": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "initializer_list": "cpp", + "sstream": "cpp" } } \ No newline at end of file diff --git a/Debug.h b/Debug.h index 349ed09..a786865 100644 --- a/Debug.h +++ b/Debug.h @@ -12,9 +12,9 @@ /*---- start macro's ------------------------------------------------------------------*/ -#define Debug(...) ({ TelnetStream.print(__VA_ARGS__); }) -#define Debugln(...) ({ TelnetStream.println(__VA_ARGS__); }) -#define Debugf(...) ({ TelnetStream.printf(__VA_ARGS__); }) +#define Debug(...) ({ TelnetStream.print(__VA_ARGS__); }) +#define Debugln(...) ({ TelnetStream.println(__VA_ARGS__); }) +#define Debugf(...) ({ TelnetStream.printf(__VA_ARGS__); }) #define DebugFlush() ({ TelnetStream.flush(); }) diff --git a/FSexplorer.ino b/FSexplorer.ino index fbe3231..a1218fc 100644 --- a/FSexplorer.ino +++ b/FSexplorer.ino @@ -274,7 +274,7 @@ void upgradePIC() { DebugTln(F("Redirect to upgrade PIC ..")); doRedirect("Upgrade OTGW PIC ", 120, "/FSexplorer", false); - upgradenow(); + // upgradenow(); } // upgradePIC() diff --git a/OTGW-Core.ino b/OTGW-Core.ino index 2715328..3314287 100644 --- a/OTGW-Core.ino +++ b/OTGW-Core.ino @@ -11,20 +11,16 @@ *************************************************************************** */ - //define Nodoshop OTGW hardware -// #define OTGW_BUTTON D3 -#define OTGW_RESET 14 -// #define OTGW_LED1 D4 -// #define OTGW_LED2 D0 +#define OTGW_BUTTON 0 //D3 +#define OTGW_RESET 14 //D5 +#define OTGW_LED1 2 //D4 +#define OTGW_LED2 16 //D0 //external watchdog -// #define OTGW_I2C_SCL 5 -// #define OTGW_I2C_SDA 4 -// #define OTGW_EXT_WD_I2C_ADDRESS 0x26 #define EXT_WD_I2C_ADDRESS 0x26 -#define PIN_I2C_SDA 4 -#define PIN_I2C_SCL 5 +#define PIN_I2C_SDA 4 //D2 +#define PIN_I2C_SCL 5 //D1 //Macro to Feed the Watchdog #define FEEDWATCHDOGNOW Wire.beginTransmission(EXT_WD_I2C_ADDRESS); Wire.write(0xA5); Wire.endTransmission(); @@ -52,27 +48,47 @@ //some variable's OpenthermData OTdata; +#define OTGW_BANNER "OpenTherm Gateway " + //===================[ Reset OTGW ]=============================== void resetOTGW() { //lower the right pin for just 100ms and the OTGW is reset DebugTln("OTGW PIC reset"); pinMode(OTGW_RESET, OUTPUT); digitalWrite(OTGW_RESET, LOW); + OTGWSerial.print("GW=R\r\n"); delay(100); digitalWrite(OTGW_RESET, HIGH); pinMode(OTGW_RESET, INPUT_PULLUP); + + //wait for response + OTGWSerial.setTimeout(250); + String line = OTGWSerial.readStringUntil('\n'); + line.trim(); + DebugTf("Received after reset: %s (%d)\r\n", CSTR(line), line.length()); + bOTGWonline = (line.length()>0); + if (bOTGWonline){ + //find version + int p = line.indexOf(OTGW_BANNER); + if (p >= 0) { + p += sizeof(OTGW_BANNER); + sPICfwversion = line.substring(p); + } else sPICfwversion ="No version found"; + } else sPICfwversion = "No OTWG connected!"; + DebugTf("Current firmware version: %s\r\n", CSTR(sPICfwversion)); + OTGWSerial.setTimeout(1000); } //===================[ getpicfwversion ]=========================== String getpicfwversion(){ String _ret=""; - #define BANNER "OpenTherm Gateway" + String line = executeCommand("PR=A"); - int p = line.indexOf(BANNER); + int p = line.indexOf(OTGW_BANNER); if (p >= 0) { - p += sizeof(BANNER); + p += sizeof(OTGW_BANNER); _ret = line.substring(p); } else _ret ="No version found"; - DebugTf("Current firmware version: %s\n", CSTR(_ret)); + DebugTf("Current firmware version: %s\r\n", CSTR(_ret)); _ret.trim(); return _ret; } @@ -80,23 +96,23 @@ String getpicfwversion(){ String executeCommand(const String sCmd){ //send command to OTGW DebugTf("OTGW Send Cmd [%s]\r\n", CSTR(sCmd)); - Serial.setTimeout(1000); + OTGWSerial.setTimeout(1000); DECLARE_TIMER_MS(tmrWaitForIt, 1000); - while((Serial.availableForWrite() < sCmd.length()+2) && !DUE(tmrWaitForIt)){ + while((OTGWSerial.availableForWrite() < sCmd.length()+2) && !DUE(tmrWaitForIt)){ feedWatchDog(); } - Serial.write(CSTR(sCmd)); - Serial.write("\r\n"); - Serial.flush(); + OTGWSerial.write(CSTR(sCmd)); + OTGWSerial.write("\r\n"); + OTGWSerial.flush(); //wait for response RESTART_TIMER(tmrWaitForIt); - while(!Serial.available() && !DUE(tmrWaitForIt)) { + while(!OTGWSerial.available() && !DUE(tmrWaitForIt)) { feedWatchDog(); } String _cmd = sCmd.substring(0,2); DebugTf("Send command: [%s]\r\n", CSTR(_cmd)); //fetch a line - String line = Serial.readStringUntil('\n'); + String line = OTGWSerial.readStringUntil('\n'); line.trim(); String _ret =""; if (line.startsWith(_cmd)){ @@ -129,81 +145,81 @@ String executeCommand(const String sCmd){ return _ret; } -String executeCommandCstyle(const String sCmd){ - return executeCommandCstyle(CSTR(sCmd), sCmd.length()); -} +// String executeCommandCstyle(const String sCmd){ +// return executeCommandCstyle(CSTR(sCmd), sCmd.length()); +// } -String executeCommandCstyle(const char* sCmd, size_t len){ - char _cmd[2]; - char line[80]; - char _ret[80]; - //send command to OTGW - DebugTf("OTGW Send Cmd [%s]=[%s]\r\n", sCmd); - while(Serial.availableForWrite() < len+2){ - feedWatchDog(); - } - Serial.write(sCmd, len); - Serial.write("\r\n"); - Serial.flush(); - //wait for response - Serial.setTimeout(3000); - while(!Serial.available()) { - feedWatchDog(); - } - // DebugTf("Send command: [%s]\r\n", _cmd); - //fetch a line - size_t l = Serial.readBytesUntil('\n', line, sizeof(line)-1); - line[l]='\0'; - _cmd[0]='\0'; - if (l > 0) { - strcpy(_cmd,strtok(line,":")); - } - if (prefix(_cmd, sCmd)){ - // Responses: When a serial command is accepted by the gateway, it responds with the two letters of the command code, a colon, and the interpreted data value. - // Command: "TT=19.125" - // Response: "TT: 19.13" - // [XX:response string] - strcpy(_ret,strtok(NULL,":")); - } else if (prefix("NG", _cmd)){ - strlcpy(_ret, "NG - No Good. The command code is unknown.", sizeof(_ret)); - } else if (prefix("SE", _cmd)){ - strlcpy(_ret, "SE - Syntax Error. The command contained an unexpected character or was incomplete.", sizeof(_ret)); - } else if (prefix("BV", _cmd)){ - strlcpy(_ret, "BV - Bad Value. The command contained a data value that is not allowed.", sizeof(_ret)); - } else if (prefix("OR", _cmd)){ - strlcpy(_ret, "OR - Out of Range. A number was specified outside of the allowed range.", sizeof(_ret)); - } else if (prefix("NS", _cmd)){ - strlcpy(_ret, "NS - No Space. The alternative Data-ID could not be added because the table is full.", sizeof(_ret)); - } else if (prefix("NF", _cmd)){ - strlcpy(_ret, "NF - Not Found. The specified alternative Data-ID could not be removed because it does not exist in the table.", sizeof(_ret)); - } else if (prefix("OE", _cmd)){ - strlcpy(_ret, "OE - Overrun Error. The processor was busy and failed to process all received characters.", sizeof(_ret)); - } else { - strlcpy(_ret, "Error: Different command response [", sizeof(_ret)); - strlcat(_ret, _cmd, sizeof(_ret)); - strlcat(_ret, "] Cmd send [", sizeof(_ret)); - strlcat(_ret, sCmd, sizeof(_ret)); - strlcat(_ret, "]", sizeof(_ret)); - } - DebugTf("Command send - Response returned: [%s]:[%s] - line: [%s]\r\n", _cmd, _ret, line); - return _ret; -} +// String executeCommandCstyle(const char* sCmd, size_t len){ +// char _cmd[2]; +// char line[80]; +// char _ret[80]; +// //send command to OTGW +// DebugTf("OTGW Send Cmd [%s]=[%s]\r\n", sCmd); +// while(OTGWSerial.availableForWrite() < len+2){ +// feedWatchDog(); +// } +// OTGWSerial.write(sCmd, len); +// OTGWSerial.write("\r\n"); +// OTGWSerial.flush(); +// //wait for response +// OTGWSerial.setTimeout(3000); +// while(!OTGWSerial.available()) { +// feedWatchDog(); +// } +// // DebugTf("Send command: [%s]\r\n", _cmd); +// //fetch a line +// size_t l = OTGWSerial.readBytesUntil('\n', line, sizeof(line)-1); +// line[l]='\0'; +// _cmd[0]='\0'; +// if (l > 0) { +// strcpy(_cmd,strtok(line,":")); +// } +// if (prefix(_cmd, sCmd)){ +// // Responses: When a serial command is accepted by the gateway, it responds with the two letters of the command code, a colon, and the interpreted data value. +// // Command: "TT=19.125" +// // Response: "TT: 19.13" +// // [XX:response string] +// strcpy(_ret,strtok(NULL,":")); +// } else if (prefix("NG", _cmd)){ +// strlcpy(_ret, "NG - No Good. The command code is unknown.", sizeof(_ret)); +// } else if (prefix("SE", _cmd)){ +// strlcpy(_ret, "SE - Syntax Error. The command contained an unexpected character or was incomplete.", sizeof(_ret)); +// } else if (prefix("BV", _cmd)){ +// strlcpy(_ret, "BV - Bad Value. The command contained a data value that is not allowed.", sizeof(_ret)); +// } else if (prefix("OR", _cmd)){ +// strlcpy(_ret, "OR - Out of Range. A number was specified outside of the allowed range.", sizeof(_ret)); +// } else if (prefix("NS", _cmd)){ +// strlcpy(_ret, "NS - No Space. The alternative Data-ID could not be added because the table is full.", sizeof(_ret)); +// } else if (prefix("NF", _cmd)){ +// strlcpy(_ret, "NF - Not Found. The specified alternative Data-ID could not be removed because it does not exist in the table.", sizeof(_ret)); +// } else if (prefix("OE", _cmd)){ +// strlcpy(_ret, "OE - Overrun Error. The processor was busy and failed to process all received characters.", sizeof(_ret)); +// } else { +// strlcpy(_ret, "Error: Different command response [", sizeof(_ret)); +// strlcat(_ret, _cmd, sizeof(_ret)); +// strlcat(_ret, "] Cmd send [", sizeof(_ret)); +// strlcat(_ret, sCmd, sizeof(_ret)); +// strlcat(_ret, "]", sizeof(_ret)); +// } +// DebugTf("Command send - Response returned: [%s]:[%s] - line: [%s]\r\n", _cmd, _ret, line); +// return _ret; +// } //===================[ OTGW PS=1 Command ]=============================== void getOTGW_PS_1(){ DebugTln("PS=1"); - Serial.write("PS=1\r\n"); - Serial.flush(); + OTGWSerial.write("PS=1\r\n"); + OTGWSerial.flush(); - while(!Serial.available()) { + while(!OTGWSerial.available()) { feedWatchDog(); } - String line = Serial.readStringUntil('\n'); + String line = OTGWSerial.readStringUntil('\n'); line.trim(); //remove LF and CR (and whitespaces) DebugTln(line); DebugTln("PS=0"); - Serial.write("PS=0\r\n"); - Serial.flush(); + OTGWSerial.write("PS=0\r\n"); + OTGWSerial.flush(); } //===================[ OTGW PS=1 Command ]=============================== //===================[ Watchdog OTGW ]=============================== @@ -720,25 +736,25 @@ int sendOTGW(const char* buf, int len) //Send the buffer to OTGW when the Serial interface is available if (Serial) { //check the write buffer - Debugf("Serial Write Buffer space = [%d] - needed [%d]\r\n",Serial.availableForWrite(), (len+2)); + Debugf("Serial Write Buffer space = [%d] - needed [%d]\r\n",OTGWSerial.availableForWrite(), (len+2)); DebugT("Sending to Serial ["); for (int i = 0; i < len; i++) { Debug((char)buf[i]); } Debug("] ("); Debug(len); Debug(")"); Debugln(); - while (Serial.availableForWrite()==(len+2)) { + while (OTGWSerial.availableForWrite()==(len+2)) { //cannot write, buffer full, wait for some space in serial out buffer feedWatchDog(); //this yields for other processes } - if (Serial.availableForWrite()>= (len+2)) { + if (OTGWSerial.availableForWrite()>= (len+2)) { //write buffer to serial - Serial.write(buf, len); - // Serial.write("PS=0\r\n"); - Serial.write('\r'); - Serial.write('\n'); - Serial.flush(); + OTGWSerial.write(buf, len); + // OTGWSerial.write("PS=0\r\n"); + OTGWSerial.write('\r'); + OTGWSerial.write('\n'); + OTGWSerial.flush(); } else Debugln("Error: Write buffer not big enough!"); } else Debugln("Error: Serial device not found!"); } @@ -929,14 +945,14 @@ void handleOTGW() //handle incoming data from network (port 25238) sent to serial port OTGW (WRITE BUFFER) while (OTGWstream.available()){ - //Serial.write(OTGWstream.read()); //just forward it directly to Serial + //OTGWSerial.write(OTGWstream.read()); //just forward it directly to Serial outByte = OTGWstream.read(); // read from port 25238 - while (Serial.availableForWrite()==0) { + while (OTGWSerial.availableForWrite()==0) { //cannot write, buffer full, wait for some space in serial out buffer feedWatchDog(); //this yields for other processes } - Serial.write(outByte); // write to serial port - Serial.flush(); // wait for write to serial + OTGWSerial.write(outByte); // write to serial port + OTGWSerial.flush(); // wait for write to serial if (outByte == '\n') { //on newline, do something... sWrite[bytes_write] = 0; @@ -960,9 +976,9 @@ void handleOTGW() } //Handle incoming data from OTGW through serial port (READ BUFFER) - while(Serial.available()) + while(OTGWSerial.available()) { - inByte = Serial.read(); // read from serial port + inByte = OTGWSerial.read(); // read from serial port OTGWstream.write(inByte); // write to port 25238 if (inByte== '\n') { //line terminator, continue to process incoming message @@ -1085,6 +1101,17 @@ void startOTGWstream() OTGWstream.begin(); } +void upgradenow() { + if (OTGWSerial.busy()) return; // if already in programming mode, never call it twice + DebugTln("Start PIC upgrade now."); + fwupgradestart(FIRMWARE); + while (OTGWSerial.busy()){ + feedWatchDog(); + } + // When you are done, then reset the PIC one more time, to capture the actual fwversion of the OTGW + resetOTGW(); +} + /*************************************************************************** * * Permission is hereby granted, free of charge, to any person obtaining a diff --git a/OTGW-ModUpdateServer-impl.h b/OTGW-ModUpdateServer-impl.h index dd9d085..79df43c 100644 --- a/OTGW-ModUpdateServer-impl.h +++ b/OTGW-ModUpdateServer-impl.h @@ -30,9 +30,9 @@ #ifndef Debug //#warning Debug() was not defined! - #define Debug(...) ({ Serial.print(__VA_ARGS__); }) - #define Debugln(...) ({ Serial.println(__VA_ARGS__); }) - #define Debugf(...) ({ Serial.printf(__VA_ARGS__); }) + #define Debug(...) ({ OTGWSerial.print(__VA_ARGS__); }) + #define Debugln(...) ({ OTGWSerial.println(__VA_ARGS__); }) + #define Debugf(...) ({ OTGWSerial.printf(__VA_ARGS__); }) //#else // #warning Seems Debug() is already defined! #endif @@ -105,8 +105,8 @@ void ESP8266HTTPUpdateServerTemplate::setup(ESP8266WebServerTemplate if(upload.status == UPLOAD_FILE_START){ _updaterError.clear(); - if (_serial_output) - Serial.setDebugOutput(true); + // if (_serial_output) + // OTGWSerial.setDebugOutput(true); _authenticated = (_username == emptyString || _password == emptyString || _server->authenticate(_username.c_str(), _password.c_str())); if(!_authenticated){ @@ -144,7 +144,8 @@ void ESP8266HTTPUpdateServerTemplate::setup(ESP8266WebServerTemplate } else { _setUpdaterError(); } - if (_serial_output) Serial.setDebugOutput(false); + // if (_serial_output) + // OTGWSerial.setDebugOutput(false); } else if(_authenticated && upload.status == UPLOAD_FILE_ABORTED){ Update.end(); if (_serial_output) Debugln("Update was aborted"); diff --git a/OTGW-firmware.h b/OTGW-firmware.h index 115c9a1..067781d 100644 --- a/OTGW-firmware.h +++ b/OTGW-firmware.h @@ -9,15 +9,36 @@ *************************************************************************** */ +#include #include // https://github.com/ropg/ezTime #include // https://github.com/jandrassy/TelnetStream/commit/1294a9ee5cc9b1f7e51005091e351d60c8cddecf #include // https://arduinojson.org/ #include "Wire.h" #include "Debug.h" #include "safeTimers.h" -#include "networkStuff.h" +#include "OTGWSerial.h" // Bron Schelte's Serial class - it upgrades and more #include "OTGW-Core.h" // Core code for this firmware -#include "OTGW-upgrade.h" // Schelte Bron's upgrade PIC code + +//OTGW Nodoshop hardware definitions +#define I2CSCL D1 +#define I2CSDA D2 +#define BUTTON D3 +#define PICRST D5 + +#define LED1 D4 +#define LED2 D0 + +#define FIRMWARE "/gateway.hex" + +extern OTGWSerial OTGWSerial(PICRST, LED2); +void fwupgradestart(const char *hexfile); + +void blinkLEDnow(); +void blinkLEDnow(uint8_t); +void setLed(int8_t, uint8_t); + +//Now load network suff +#include "networkStuff.h" //Defaults and macro definitions #define _HOSTNAME "OTGW" @@ -45,6 +66,7 @@ const char *flashMode[] { "QIO", "QOUT", "DIO", "DOUT", "Unknown" }; //Information on OTGW String sPICfwversion = ""; +bool bOTGWonline = true; //All things that are settings String settingHostname = _HOSTNAME; diff --git a/OTGW-firmware.ino b/OTGW-firmware.ino index 12a1091..d8d7184 100644 --- a/OTGW-firmware.ino +++ b/OTGW-firmware.ino @@ -30,14 +30,18 @@ #include "OTGW-firmware.h" +#define ON LOW +#define OFF HIGH + //===================================================================== void setup() { - Serial.begin(9600, SERIAL_8N1); - while (!Serial) {} //Wait for OK - - Serial.println(F("\r\n[OTGW firmware - Nodoshop version]\r\n")); - Serial.printf("Booting....[%s]\r\n\r\n", String(_FW_VERSION).c_str()); + // Serial is initialized by OTGWSerial. It resets the pic and opens serialdevice. + // OTGWSerial.begin();//OTGW Serial device that knows about OTGW PIC + // while (!Serial) {} //Wait for OK + + OTGWSerial.println(F("\r\n[OTGW firmware - Nodoshop version]\r\n")); + OTGWSerial.printf("Booting....[%s]\r\n\r\n", String(_FW_VERSION).c_str()); rebootCount = updateRebootCount(); @@ -45,42 +49,46 @@ void setup() randomSeed(RANDOM_REG32); //This is 8266 HWRNG used to seed the Random PRNG: Read more: https://config9.com/arduino/getting-a-truly-random-number-in-arduino/ lastReset = ESP.getResetReason(); - Serial.printf("Last reset reason: [%s]\r\n", CSTR(ESP.getResetReason())); + OTGWSerial.printf("Last reset reason: [%s]\r\n", CSTR(ESP.getResetReason())); //setup the status LED - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, HIGH); //OFF - pinMode(16,OUTPUT); - digitalWrite(16,LOW); + setLed(LED1, ON); + setLed(LED2, ON); //start the debug port 23 startTelnet(); - Serial.print("Use 'telnet "); - Serial.print(WiFi.localIP()); - Serial.println("' for debugging"); - + OTGWSerial.print("Use 'telnet "); + OTGWSerial.print(WiFi.localIP()); + OTGWSerial.println("' for debugging"); + + DebugT("Waiting"); + Debugln(); //================ LittleFS =========================================== if (LittleFS.begin()) { - Serial.println(F("LittleFS Mount succesfull\r")); + OTGWSerial.println(F("LittleFS Mount succesfull\r")); LittleFSmounted = true; } else { - Serial.println(F("LittleFS Mount failed\r")); // Serious problem with LittleFS + OTGWSerial.println(F("LittleFS Mount failed\r")); // Serious problem with LittleFS LittleFSmounted = false; } readSettings(true); // Connect to and initialise WiFi network - Serial.println(F("Attempting to connect to WiFi network\r")); - digitalWrite(LED_BUILTIN, HIGH); + OTGWSerial.println(F("Attempting to connect to WiFi network\r")); + setLed(LED1, ON); startWiFi(_HOSTNAME, 240); // timeout 240 seconds - digitalWrite(LED_BUILTIN, LOW); - + for (int i=0; i<=3;i++) { + blinkLEDnow(LED1); + delay(250); + blinkLEDnow(LED1); + delay(250); + } + setLed(LED1, OFF); + startMDNS(CSTR(settingHostname)); - delay(1000); - // Start MQTT connection startMQTT(); @@ -129,20 +137,15 @@ void setup() httpServer.on("/api", HTTP_ANY, processAPI); //was only HTTP_GET (20210110) httpServer.begin(); - Serial.println("\nHTTP Server started\r"); + OTGWSerial.println("\nHTTP Server started\r"); // Set up first message as the IP address sprintf(cMsg, "%03d.%03d.%d.%d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]); - Serial.printf("\nAssigned IP[%s]\r\n", cMsg); - - for (int i=0; i<50; i++){ - blinkLEDnow(); - delay(200); - }// 50* 200 = 10.0000 msec = 10 seconds of blinking + OTGWSerial.printf("\nAssigned IP=%s\r\n", cMsg); DebugTln("Setup Watchdog"); initWatchDog(); // setup the WatchDog - Serial.println(F("Setup finished!\r\n")); + OTGWSerial.println(F("Setup finished!\r\n")); // After resetting the OTGW PIC never send anything to Serial for debug // and switch to telnet port 23 for debug purposed. // Setup the OTGW PIC @@ -150,29 +153,44 @@ void setup() resetOTGW(); // reset the OTGW pic DebugTln("Start OTGW Stream"); startOTGWstream(); // start port 25238 - DebugTln("Fetch PIC firmware"); - sPICfwversion = getpicfwversion(); // fetch the firmware version DebugTf("OTGW PIC firmware version = [%s]\r\n", CSTR(sPICfwversion)); DebugTf("Reboot count = [%d]\r\n", rebootCount); - pinMode(16,OUTPUT); - digitalWrite(16,HIGH); + setLed(LED1, OFF); + //Blink LED2 to signal setup done + for (int i=0; i<=3;i++) { + blinkLEDnow(LED2); + delay(250); + blinkLEDnow(LED2); + delay(250); + } + setLed(LED2, OFF); } //===================================================================== //===[ blink status led ]=== -void blinkLEDms(uint32_t iDelay){ + +void setLed(uint8_t led, uint8_t status){ + pinMode(led, OUTPUT); + digitalWrite(led, status); +} + +void blinkLEDms(uint32_t delay){ //blink the statusled, when time passed - DECLARE_TIMER_MS(timerBlink, iDelay); + DECLARE_TIMER_MS(timerBlink, delay); if (DUE(timerBlink)) { blinkLEDnow(); } } void blinkLEDnow(){ - pinMode(LED_BUILTIN, OUTPUT); - digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); + blinkLEDnow(LED1); +} + +void blinkLEDnow(uint8_t led = LED1){ + pinMode(led, OUTPUT); + digitalWrite(led, !digitalRead(led)); } //===[ no-blocking delay with running background tasks in ms ]=== diff --git a/data/diagnose.hex b/data/diagnose.hex new file mode 100644 index 0000000..4d0bb2c --- /dev/null +++ b/data/diagnose.hex @@ -0,0 +1,169 @@ +:020000040000FA +:080000008A1500278A150A2861 +:08000800F000030E8301A000CB +:100010000408A1000A08A2008A01230882073728E1 +:1000200037284028402832283728162883161C1BDA +:100030009C1F2228831281019101B201B3018C100F +:100040000D1337281C0D83121211B11F803E0318A7 +:100050003028010831060339B10631170B13202867 +:1000600012152028101083161C0883120D13220865 +:100070008A0021088400200E8300F00E700E090013 +:100080008A1583161C0883123106B1063205031D3A +:0800900097230D138A11372894 +:041000000034003484 +:0C1004006400061D022898011A088A15D5 +:1010100000278A1583018316E73085002730860074 +:1010200007309B00E6309D00193099001815181202 +:101030009816831298171816900183018B13831644 +:10104000D730810006309C000D17831203170A3039 +:101050008F00D8308D00482203170A308F00F130FE +:101060008D004822831710308400981C3A281A08F3 +:101070001812181664008C1E3A28181902281A082B +:101080008000E03903194C286F30040203183A2815 +:1010900000088D22840A3A2808308A000008533E4E +:1010A00003188A0A82003A283A283A283A283A2825 +:1010B0003A283A283A2872283A283A283A283A28E8 +:1010C0007D283A283A283A283A283A283A283A28CD +:1010D0003A283A283A283A283A283A283A283A2800 +:1010E0003A283A281030040203193A2884030830B9 +:1010F0008D228D2208308D223A2880011030840004 +:10110000A301800803199D281A302302031896288A +:101110002308A307A30DA307A30D0008840A393CE5 +:10112000093C031C9628A307031C812803170B30D6 +:101130008F0036308D0048221D2807302302031807 +:101140009628442208308A00A930230703188A0A07 +:101150008200B028B928DA28DA28F1285A29DB29B0 +:101160001030040203191D288610831686108A1178 +:101170000028B2010130B1008316D73081008312FC +:10118000640019220319D7280B1DC0280B11B10BBD +:10119000C0280130B1000310B20DB2080319B21516 +:1011A000B21AB20DD830860432098605C028D8306C +:1011B00086041D2883161C088312B10040302318B2 +:1011C0008030B200A501A030B300B4000D130B179E +:1011D0008B1710146400192203191D2825181F22CB +:1011E000EA28831603309C008312851105129001B2 +:1011F0008E018F010C10101464000C18282983161E +:101200001C088312C039031DFC280B178B1703170A +:101210000B308F006C308D00482208302F210317CF +:101220000B308F0076308D00482208302F210317B5 +:101230000B308F0080308D00482210302F21031793 +:101240000B308F008A308D00482210302F211D284E +:1012500003170B308F003E308D0048221D2890016F +:101260008E018F010C101014850664000C18522991 +:1012700010183529EE300E07AC000F08031C0F03C1 +:10128000AB0083161C0E8312A700050C27060C3931 +:10129000031D5329A62203170B308F0094308D00B5 +:1012A00048220800101003170B308F0056308D00B5 +:1012B00048220800831600309F00D030810083123E +:1012C00003170B308F005C308D00482200308A21DC +:1012D00003170B308F0062308D00482208308A21BE +:1012E00050309F00392283161E088312AB002B0D4D +:1012F0001E08AC00AC0DAB0DAC0DAB0DAC0703186C +:10130000AB0A03170B308F0066308D00482269222C +:1013100044221D28403A9F001030A600333084003C +:101320008313FF308000840AA60B92294030B2005C +:10133000A701392264001E08B10039221E083102BB +:10134000031C003C023C031CA701A70AA71DB329EC +:101350001E0E0F39333E84001E0EF03980008316B6 +:101360001E0E80048312A60B9A29B20B9A293A30DA +:10137000A700333084000018D42927088D228D223D +:1013800033300402A700AB000310AB0C000CAC0020 +:10139000AB0CAC0C000E0F39A70E2707AC070318D7 +:1013A000AB0A69222C30A700840A43300402031CD4 +:1013B000BB2944220800B10164008316D8308100A3 +:1013C000F93092009C088312053092000D130B1720 +:1013D0008B176400192203191D28311BF6298C1C58 +:1013E000E929B30A0319B20A8C10E929B11E122A9D +:1013F0003208AB003308AC005430B11B42308D22B0 +:101400003A308D228D22A622AB010310110DAC00C3 +:10141000AB0DAC0DAB0D31080339AC042E308D2271 +:10142000B22244228030B1063113B11612150B17C7 +:10143000E92903118C1E08001A080D3C0800340825 +:10144000840083170008AB0083130008AC00B40AC3 +:10145000A622340833020319302A2C308D220800CA +:10146000A510A030B300B40025102E308D224422E8 +:1014700008001F14FA3081000B110B1D3D2A1F15A7 +:101480001F19402A1F1008000D308D220A308D2AA6 +:1014900083168C018C170C140000000083120C0DB5 +:1014A0000E0D031360220319080003170C08031321 +:1014B00060220319080003178D0A03198F0A482AAE +:1014C0007F391A3A031908001A3A031D8D2A0311AD +:1014D00008002B0875226430A7002C08C722AC1B1B +:1014E000AB0A2B08A7002E307C2A2511A7009C3EB2 +:1014F000031C7E2AA70031308D222515A60127085E +:10150000A700F63E031C862AA60A802A260803198D +:1015100025198B2227082515303E64000C1E8D2AC4 +:10152000990020341030A600A801A901AA019E2A22 +:101530002A08C022AA002908C022A900AC0DAB0DC0 +:10154000AA0DA90DA80DA60B982A08009222251114 +:101550002808B7222908B7222A08B7222519080027 +:1015600030308D2A922225152908BB222A08A7008F +:10157000270EBB2227080F39031925198B2A0800CB +:10158000333EA700A71DFD3EA71FD03E0800AB01BC +:10159000AC01083AA600083AA6060310AC0DAB0D44 +:1015A000A70D0318AC070318AB0AA60BCD2A080039 +:1015B0008A06F027EE32683AF232A036E133653A15 +:1015C000E13BA03C6932E7306F37F439E334A039AE +:1015D000A016652B7339EF342037AE1800198A0630 +:1015E0001A05AE184C10C4227410F3320D3A0005DF +:1015F0002E194210F4347410ED34EE34A033683AEE +:10160000F232EF36F439F4308A06AE194210F4346F +:101610007410ED34EE34A0336F31EC34F2328A06BC +:101620002E1A4410EC32F9307310ED3CE536723A64 +:101630008D3C0005AE1A5610EC37613AE5336C105C +:10164000F632EC328D3900052E1B49106C32A03277 +:10165000693AE5368D390A05EE22653A2039653A50 +:10166000F4396E10ED3A65313A391A108A06EE24D3 +:10167000613B69362032653AF439000DA311A0119F +:10168000F2226F393A3949107437F2326133E53159 +:10169000A0396F322737203AF0306538F2307410B5 +:1016A000A03765316C10EF3765381A32A311A011DD +:1016B000F2226F390D391A05682AF232EF36F43901 +:1016C000F430000D6F21EC34F232000D65296533E2 +:1016D00065396337BA321A10CB27C1186810E7345E +:1016E0002D346F3AEC16F737201D000DCB27C118AB +:1016F0006C10F737F416AD376934E833201D000D50 +:10170000CB27C2186810E7342D346F3AEC16F73740 +:10171000201D000DCB27C2186C10F737F416AD371B +:0E1720006934E833201D000DF33A8A06000DEF +:02172E000F08A2 +:10173000AF000E08B0000F082F060319A62BAF0646 +:101740000E08B000F930B007031CAF03A51CB92B7D +:101750003309F03903190800330884002E083002D9 +:10176000800083172D08031C013E2F028000B30A5E +:0E17700025143008AE002F08AD00A5140800A7 +:101E0000031E08008B138316031360308F002730E6 +:101E10008600E730850007309B00E6309D000630E5 +:101E20009C00D73081001930990026309800831229 +:101E300098171816FF30860081010130E327C2276A +:101E40001030E3278C1E0800C827031D08008317E5 +:101E500010308400F001C8270319282F0B3A03190A +:101E6000392F013A0319C82772088000F007840A45 +:101E70002B2FF008031D822F031712088D00130863 +:101E80008F00143084001108F1000F308A00100810 +:101E9000083C083C031C822F8207592F5F2F872F95 +:101EA000992FA12FAC2F822F822FED2F0101000F30 +:101EB000FF0F56308D000F308F00123084008316D4 +:101EC0008C170C140000000083120C088000840A98 +:101ED0000E088000840A8D0A03198F0AF10B5F2F08 +:101EE00010300402F1000F30C227F00110308400DE +:101EF0000008F007840AB527F10B782F7009013E1E +:101F0000B527C2270313C8270319282F822F84302F +:101F1000D127FC308D050430F40000088C00840AC1 +:101F200000088E00840AD527F40B8D2FF10B872F24 +:101F3000722F9430D1271F308D04D527F10B992FA4 +:101F4000722F83168C010C1483120C088000840AF3 +:101F50008D0AF10BA12F702F0430D12700088C00BF +:101F6000840AD527F10BAC2F722FF3000F3A031917 +:101F7000BF2F0B3A0319BF2F013A031DC12F0530A4 +:101F8000C2277308640003130C1EC42F9900043485 +:101F90009818ED2F64008C1ECA2F1A08F2000F3A11 +:101FA000080083168C0083120800640083165530E5 +:101FB0008D00AA308D008C148C18DC2F83128D0AB2 +:101FC00003198F0A013464008C1A08000B1DE32FDB +:101FD0000B11FF3E031DE32F0434031386108316F9 +:101FE0008610FF308500860081009B0007309C0032 +:101FF00098019901830198018B018A0164000028EE +:02400E007C3FF5 +:02401000FF3F70 +:00000001FF diff --git a/data/diagnose.ver b/data/diagnose.ver new file mode 100644 index 0000000..5625e59 --- /dev/null +++ b/data/diagnose.ver @@ -0,0 +1 @@ +1.2 diff --git a/data/gateway-4.3.hex b/data/gateway-4.3.hex new file mode 100644 index 0000000..edd2325 --- /dev/null +++ b/data/gateway-4.3.hex @@ -0,0 +1,532 @@ +:020000040000FA +:080000008A1500278A15872CE0 +:08000800F000030E8301F1007A +:100010000408F2000A08B0008A111108E4008C18E4 +:10002000D3250D1B4B2530088A0072088400710E01 +:080030008300F00E700E0900C0 +:08003800751B3C28751A082312 +:100040007508F90076087A06031DE701FA067708B5 +:10005000FB007808FC00DB125B178820ED01F3221F +:1000600003193528DB1E08006728DB165B13A62260 +:10007000DB1E0800F6006728DA1576084E0603191D +:10008000E013751E0823F322F51A751E5128031973 +:100090004C2855398007542876088A1596228A11EB +:1000A0005428FF3A601F80056013DB17DB187D289A +:1000B000DB1A5F288820DB1A61190800672888206E +:1000C00040305B1F7030DA22DB135B1F882078081A +:1000D00077067606F5137506F300F30E7306F30044 +:1000E000F30CF30CF3060130F318F3067318F5174D +:1000F0005230751B41308A11D22B88205030F500C8 +:100100000430F600AA30F7003908F800DB10672841 +:10011000F61B5D2B00308A007608913E03188A0A90 +:100120008200292959296F29672B84298D29932930 +:100130005D2B5D2BA629892A972A892A972AB62919 +:10014000682BBE29672B682B682BEE29682B682B40 +:100150005D2B682B672B682BF729682B682B682B86 +:10016000682B682B682B682B682B5D2B5D2B5D2B18 +:100170005D2B5D2B5D2B5D2B5D2B5D2B5D2B5D2B3F +:100180005D2B012A0B2A682B682B682B682B682BA8 +:10019000682B152A352A682B682B682B682B682B4F +:1001A000682B5D2B5D2B5D2B5D2B5D2B5D2B622BFF +:1001B000552A682B682B682B682B682B682B682BBB +:1001C000682B682B682B682B682B682B682B682B97 +:1001D000682B892A972A892A972A5D2B5D2B5D2B0C +:1001E0005D2B5D2B5D2B5D2B5D2B5C2A622B682BC1 +:1001F000682B682B892A972A892A972A5D2B5D2BE1 +:100200005D2B5D2B682B682B682B682B682B682B6C +:10021000682B682B682B682B682B5D2B782A7E2A2D +:10022000682B603017297908C038F51F7F397506AB +:10023000031DDB16F50600347706031DDB16F706F3 +:1002400000347B081C217C087806031DDB16F806A9 +:100250000034751B3929A0227708C40803193329F3 +:100260000138E11BFE396E1E1C29FD39EE1A0238D9 +:100270001C29F51A08007808FC00413903195A12A4 +:10028000031D5A1A47295A160530CE00E0174D3083 +:100290007E237808083946307E23780804395730A1 +:1002A0007E237808023948307E23770802394330AC +:1002B0007E2B751B6529A02244084506031D751E6B +:1002C000080044081C2145082429F51E0800751A59 +:1002D0000800C40803190800C401C5010800751FFF +:1002E000772901307B051C217C08242113297718EC +:1002F000DE17631A080078080B3C0319E31B08009B +:10030000E317DE1B63170800751F0800AA30770289 +:10031000031D0800132139082429751B682B5F1A57 +:100320005F1B0800DC29751F080060100301F51E23 +:10033000751A9B29780861060339E1061321611CAF +:10034000E010E11C6011770803381C29751F0800B4 +:1003500013215F1E3A081C215F1E3B0824215F13F6 +:10036000E31ADF1D08005F1DDB140800751B080081 +:10037000A022611F080058081C212429751B13297D +:10038000DF195F1B08005F1ADC293B087802F300C5 +:100390003A08031C013E7702031CFF3A031DE329C0 +:1003A000031CF309E0307305031DE3295F190800FE +:1003B0005F15DF134F30802B5F123A083B0403199F +:1003C000EB295F1708005F1DDF0A5F1D0800631B34 +:1003D000EB29BA01BB01DF014F308C2B751F0800E0 +:1003E0001321D31F21293E081C213F082429751BF6 +:1003F0005A1C0800DA18112913213C081C213D0859 +:100400002429751F0800E010F51A682B7708D00022 +:100410007808CF00682B751F08006011F51A682B4B +:100420007708D2007808D100682B751B232AC008F2 +:10043000751EE019031908001030172140081C210F +:10044000410824213834E011F51E0800751E2F2ABA +:1004500013214008031950081C2141082429C00811 +:1004600003190800C001C1010800751B432AC20816 +:10047000751E601A031908001030172142081C214C +:100480004308242139346012F51E0800751E4F2AD6 +:1004900013214208031952081C2143082429C208C9 +:1004A00003190800C201C30108000310460C031819 +:1004B000751B080024211C29751F0800DF1AD60EA1 +:1004C000DB126823DB1A6B2A1321560E0339242111 +:1004D0006B1B78081C21631BDF1E762A560E5606FE +:1004E000031D5F1B762A5F16DF155F17DF120800FA +:1004F000751F0800132103301C212429751FE31FD9 +:10050000080063137708143C0319E316031C6317F0 +:100510000800751F0800DB1ADB1F682B7708F51E23 +:1005200003190800E800760ACE00E0170800751BE2 +:10053000DB1E622BE90A68086902031CE017080049 +:10054000751B0800F322FF3A800508000030F50013 +:10055000F701F801E0080319BF2A60176018063494 +:10056000E018303460193134E0191C2A601A3C2A32 +:10057000E01FBE2A6908F7004E080800E0014D0898 +:10058000031DE32A5B1AD92A2030FD004A0A1F39CD +:10059000CA00E03E8A152F268A1183128D00831629 +:1005A0000C1483120C080313031D0800FD0BC62A4C +:1005B0005B16DB127904F5007B08F7007C08F80075 +:1005C0007A08F60008001030F5007430FD00F301E1 +:1005D0000314EB2AFD0AF30D73084D050319EA2AEB +:1005E000CD067D0808007608F400740CF300730C47 +:1005F0001F39BA3E8400F41B0034033074180C30E9 +:10060000F300F418F30E00097305F30E730E0800DF +:10061000760D031CF51A0800F300730E0F39F30072 +:1006200076080739FD00FD0A2E237306F3067306CC +:10063000B10103100318B10AF30CFD0B1A2B031CB4 +:1006400008004523B107310D103E84008317770859 +:100650008000840A780880008313080003308A0031 +:100660007308353E03188A0A82004334C0340734C5 +:100670001F340034003403340334003400340034B5 +:10068000003400340034F0340F34F30003308A00B7 +:1006900073084D3E03188A0A82000034033405347F +:1006A00008340D340D340D340F3411341134113439 +:1006B00011341134113411341534DB1BDB1E751F5A +:1006C00008006E2BDB1BDB1E751F08006D2BA022A4 +:1006D000DB1BDB1E751F0800FB01FC0176088A1579 +:1006E00045238A11031D08001321831700087C0489 +:1006F00024218413000883137B041C2903198C2BE9 +:100700005F3E84000014FE30000503190800FF3A24 +:100710008605F938E20500345F3E840000100008C9 +:0C0720000319080086040639E2040034C6 +:04072C008A152F26D5 +:100730008A1183128D009F2BB72303178D0A83160E +:100740000C1483120C080313031D9C2B0800962322 +:100750000D30B7230A30B72BF400740EB0237408A1 +:100760000F39F63E0318073E0A3EDA17303ECC0832 +:1007700003190C1EBD2B99000034840037084C0768 +:10078000B03E031C503E903E0406840604068317C8 +:10079000800083134C08503A031DCC0A00345430B7 +:1007A000751B42305B190800B7237508AC23760827 +:1007B000AC237708AC237808AC23A82B5E1908007B +:1007C0008A3096236508AC23A8234530651CD223C4 +:1007D000E50147080319080084000008F3004708F2 +:1007E000AC233D30B7237308AC23A82B4B084B0731 +:1007F000103E840083170008B400840A0008B50086 +:10080000831304308A004B08CB0A093E03188A0A76 +:100810008200222C3A2C222C3A2C4A2C3A2C3A2CAC +:100820003A2C3A2C3A2C3A2C312C3A2C4A2C4A2C81 +:100830003A2C3A2C6D2C6D2C6D2C6D2C6D2C6D2C56 +:100840006D2C6D2C340827242F30B7233508F30086 +:100850000830FD00F30D2F24FD0B2A2C0800070D96 +:10086000B52BB41F3A2CB409B509B50A0319B40A5B +:100870002D30B723350F3E2CB40AB50134084F2470 +:100880006430F30035083A25B51BB40A3408F30088 +:100890002E305C2C34084F242F30B7233508DA1360 +:1008A000F3009C3E031C5E2CF3009C3E031C5B2C5F +:1008B000F30032305C2C3130B723DA17FD017308B6 +:1008C000F300F63E031C662CFD0A602C7D0803191C +:1008D000DA1B6B247308DA17B52B1030FD00B10159 +:1008E000B201B301792C33088A24B30032088A2478 +:1008F000B200B50DB40DB30DB20DB10DFD0B732CDF +:10090000DA13310891243208912433089124DA1B38 +:100910000800B52B333EF300F31DFD3EF31FD03E20 +:100920000800F300730E952473080F390319DA1BBE +:10093000B52B08003608043C031D623404308A00DD +:1009400023085A3C193C031C6834A93E03188A0A40 +:1009500082000F349134A434683468346834182D1C +:100960006834122D683468340434E52C6834CB2C98 +:10097000F92CEA2C012D1B2D0A2D6834C72CF22CE2 +:100980006834683468342308B7233D30B72BC32458 +:100990006B08FD3EB02BC324DF084E300319B72B84 +:1009A0003A083B066E300319B72B560E56060F3920 +:1009B000DF1ED6065430D61C43305F1D2038B723C7 +:1009C0003A08B4003B08B5003A2CC32447307E18DF +:1009D0004D30B72BC3247E0E0739AC3E8A153B261B +:1009E0008A11B72BC3243030EE1A31306E1E4130DD +:1009F000B72BC3245E1C80347430DE187B30962302 +:100A00008334C3244430E31B5230E31A4330631B66 +:100A10004930B72BC3246B0EF300F30CF30C2F24D7 +:100A2000F30C2F2CC324050D803E2F24050D2F2CF5 +:100A3000C324590EAC2BC32402308A153B268A11DD +:100A4000B40003308A153B268A11B5003A2C3608CB +:100A5000043C031D62342308313C013C031C683410 +:100A60000319362DCB015A155B15382D5A115B1120 +:100A70008A11B52BB401B501083AFD00083AFD060C +:100A80000310B50DB40DF30D0318B5070318B40A20 +:060A9000FD0B402D0800E3 +:0A0A960083161C0E83120D135C067C +:100AA0000C3903190800DC0604390319DE1D5B2D1F +:100AB000FF30E5000800031DDE19632DDE15B808C0 +:100AC00003195C1A812DB8080319A22D03305D02A9 +:100AD000031C462E83161C0D8312DE19803EB80BB4 +:100AE000902D031C4B2EDC1B4F2E5B148A115230B1 +:100AF0008C2354308C2342308C238A11DE11121146 +:100B00009F2DB8015C1218305E18083005061839A0 +:100B100085068A1158308C2342308C238A11982DF7 +:100B200080300318DC06F80DF70DF60DF50D5C139B +:100B3000DD01640891020630031C91028C106430C0 +:100B4000810008001219AF2DE508031D9F2D2A30E2 +:100B500091001215DD0183168C1483129F2D0A302B +:100B60005D020318982D83161C0D8312DE19803E3A +:100B7000031C9F2D83161C1E031083120318DE18FE +:100B8000C32DDE145E15DD0803197F2D8A11523046 +:100B900080234230DE19543080238A112130B8007E +:100BA000DC135C13982D8C10DD0A5C1AF12DB8084B +:100BB0000319DE1DEE2D5D08143C03191B2E503069 +:100BC0005D02031C08001211DE1183161C1E0310A7 +:100BD0008312031C0800DE145E150800DD194D2E7B +:100BE00008005D180800B80803190B2E03015C1CEF +:100BF00018305E18103A050648058506DD18182ECF +:100C00005C100314F80DF70DF60DF50D03185C14C8 +:100C1000DD01B803080012115C12481ADC168A11B3 +:100C200058308C2354308C2342308C238A11080096 +:100C30000130DC0608005C190800DE1F372E831621 +:100C400010309C061C1E03101C0E83120D135C0634 +:100C50000C39DC060318392E5E15DE1C08005E1008 +:100C6000DE10051650308A118C238A110800DE161A +:100C700008005E18422E5E14051250308A1180233F +:100C80008A110800DE1408005C179F2D5C1BEB1A0C +:100C9000442E0130502E0230502E0330502E04309E +:100CA000E5080319E5001211B801DD015C128A1193 +:100CB00058308C2352308C2342308C2354308C2378 +:100CC00065090319672E453080237A30E6008A11C2 +:020CD0009F2D56 +:0E0CD200031DC02E5A1BDA0106308A005A0894 +:100CE0001F39763E03188A0ADA0A8200832EE92E1B +:100CF000912E0034832EE72E942E832EE92E9F2EE4 +:100D0000A12EA52EC02E851383168513C226831609 +:100D100085178312C526851B8F2EC3260134DA144E +:100D2000C02E4430EA260034D6267308103C03193E +:100D300001347308283C031D8F2EDA170134BE30AE +:100D4000EA2ED6267308DB000134D626DA1BAE2E37 +:100D5000730C5B0CB400B501B50CB82E5B0EF0390A +:100D6000B500730EF039F3005B0E0F397304B40055 +:100D70005A14DA14553A0319C02E8A15C9210134C0 +:100D80005A170034C326E830C62E363083168C102E +:100D9000120283120A3E910012158C1CCD2E1211E4 +:100DA0008C100800D426D42600000800D726DA26A6 +:100DB000DA26DA2685138316851303108517831226 +:100DC000D326851B0314F30C2D30C62608003330C0 +:100DD000EA2ECC30F300EC26EF26EF26EF26F30CBC +:100DE000851383168513031885173230C62683169C +:060DF00085178312013497 +:0A0DF6006217E21300276213E217F0 +:100E000007308A005908E21B590E07390A3E0318B9 +:100E10008A0A8200152F212F242F242F242F152FEB +:100E2000152F122FF030E21FD9056208C039831642 +:100E300085048312080062093F38831685058312F2 +:100E400008001B27850508001B27FF3A85040800BA +:100E50006217E2132D276213E21707308A00590840 +:100E6000E21B590E0739373E03188A0A8200080030 +:100E7000080008003F2F462F572F592F4D2F0508E8 +:100E8000E21805096205C0398506080005086219DF +:100E900005096205C03985060800DC1E0800B8088F +:100EA0008A1169268A1100380319DC120800050925 +:100EB0005A2F05086205C039031D642F621C080003 +:100EC0006210B401B5016F2F62180800621402307D +:100ED0008A153B26B40003303B26B50001308A1545 +:060EE00035218A11080013 +:041000000034003484 +:0C1004007E19442804303602031C6234BC +:1010100022083D3C031D623408308A002008210666 +:10102000F300E039031D5F3420088A11B72321083B +:10103000B7233A30B7232030B72308308A0073082B +:10104000243E03188A0A820046285128592861281C +:1010500066286E28F3287628BC28BC28BC287B2864 +:101060005F34BC28BC28BC2880288B2893285F3498 +:1010700098285F345F349D285F345F345F34A22842 +:10108000AA28AF285F34B7287E1171342008543A5B +:1010900003192D29153A03196B2A0C3A0319EA2A68 +:1010A0005F342008523A0319A42B013A0319002B8C +:1010B0005F342008503A0319FC2A1B3A03196A2BA3 +:1010C0005F342008503A0319FE2A5F342008563A4C +:1010D0000319332A053A031971295F342008443A69 +:1010E0000319892A123A0319AC29F32820084F3A28 +:1010F00003199F2B5F342008433A03192B2A5F34CE +:101100002008533A0319E029143A0319BF2A043A74 +:101110000319A3295F342008433A0319362B103AE8 +:10112000031963295F342008463A0319AA2A5F3459 +:101130002008443A0319D6295F342008543A031989 +:1011400028295F3420084F3A0319BC291C3A031997 +:101150008A295F342008553A0319512B5F3420083F +:10116000493A0319912B193A0319CE2B5F34200801 +:10117000483A03191B2A5F3420084C3A031D5F3498 +:101180003608043C031D62342308F3005A3C193C22 +:10119000031C683441302102063E4F2223088A1185 +:1011A000B7238A1541302102F3002308B400083028 +:1011B000F318403073190230B10003107318B10DE9 +:1011C000A03084001A30FD0031098005840AFD0B2F +:1011D000E52834085F3E8400310880043408001C90 +:1011E00003158A117E2B2008473C031D5F34360807 +:1011F000043C031D623430302302F300F839031D30 +:101200006234F03021180A295905703C03195A102C +:10121000F30E0F3059057304D900F30001304F224B +:101220006217E213C030211CE2068A110027590818 +:10123000211C590E07398A11B52B03103608043AC0 +:10124000031D62342308313C013C03180800683454 +:101250001624031808000130312916240318080049 +:1012600003305A1B62343521C72956060F39D6067A +:101270000030631F40293A083B04031D5F161030FD +:10128000DF053508BB003408BA00DF155F17DF162D +:10129000B901E31ADB143B0403195F29E31E0800BC +:1012A0003A0856243508B9003B0856243408B907D3 +:1012B000B51BB90A3A08B4003B08B50008005F1630 +:1012C0005610D61008001624031808003504031D14 +:1012D0005A1B623402304F223508F30003304F228C +:1012E000C7291624031808003504031981294F085B +:1012F0007824031C683450087824031D031C8329B8 +:101300006834E01185296118E0153508C1003408FA +:10131000C000C729162403180800350403199A29A8 +:1013200051087824031C683452087824031D031CD8 +:101330009C29683460129E29E11860163508C300A4 +:101340003408C200C7291624031808005A1B623447 +:10135000C4003508C500C729DD230318BA29800851 +:10136000031D6234643C031C6E34730DC6007308A5 +:101370008A114F2CC601C329162403180800B41F74 +:10138000341FC6295A102D308A11B72BC9218A1152 +:10139000312C3408BC000317A60003133508BD0028 +:1013A0000317A70003135A14DA1008003608053C87 +:1013B000031D6234F92303180800C7008A11AC2BFF +:1013C000DD2303180800BE00173C031C6E34000820 +:1013D0003A3C031D6234840ADE2303186234BF00E2 +:1013E0003B3C031C6E3400082F3C031D6234840A0E +:1013F00030300002031D031C6834F300F839031D6C +:101400006834840A8008031D6234F30E0310730DE0 +:10141000BE04F830D3003E081F39F3008A115D2462 +:101420003F08F3003A305C242F30B7233E0EF30020 +:10143000730C0739B52B3608043C031D62346E1259 +:10144000EE122308313C0319EE16FE3903196E160D +:1014500049228A11F32C1D21031C0800031DE113EE +:101460000319E1171B293608043C031D62342308C5 +:10147000393C093C031C6834033EF300E038831612 +:101480009D008312E0306B057304EB004D228A113E +:10149000C82C6E08F3000E304F2AF30000308A1576 +:1014A0002F268A1583128D007308031783160C14D8 +:1014B00083120C060319682A8C0683160C158B13ED +:1014C00055308D00AA308D008C148B170C118312AF +:1014D000031373080800DD230318080003196E3492 +:1014E0008008031D62345B128A152F268A15831229 +:1014F000E0308D00730883160C1483128C080319D6 +:10150000862A8D0A031D7B2A0313653455228A110E +:101510004F2CDD230318080003196E348008031DC7 +:1015200062349622031808008A114F2CF3008A15A2 +:101530002F268A158312E0308D0083160C14831237 +:1015400073080C060319552A8D0A031D9D2A0313DF +:1015500003146B343608043C031D6234E301230892 +:10156000433A0319E3160A3A03196317E308031D04 +:1015700063166308F3000D304F228A11022D3608DE +:10158000043C031D62341D21031CE02A6E14EE0688 +:101590007E060139031DD02AFE14D222FE18A300B4 +:1015A00049229C2B121950347E106E1CFE197E1499 +:1015B00003307E18063083169C008312FE1008004C +:1015C0002308523C031D68346C1486108316861061 +:1015D0008A110028DD230318F82A8008031D6234CD +:1015E000643C031C6E346117643CD8008A114F2C94 +:1015F00061136430D800C3298A119A2C8A11272DCF +:10160000DD230318080003196834F4003A3000029F +:10161000031D6234840AB401DE2303180800800825 +:1016200003191E2BB4002C300002031D6234840AFF +:10163000DE23031808008008031D6234B500740817 +:1016400045230319272B03014523031D6534831705 +:1016500035088000841334088000831384177408CD +:1016600080008A114F243A30B7234A2CDD23031817 +:101670000800031968348008031D62344523031DE4 +:101680006B34800173088A114F2CF300E030840022 +:10169000000873060319080001308407831C482BD7 +:1016A0000034DD2303180800031DB400B41B6834A4 +:1016B0008008031D62348A11F4228A1580043408DC +:1016C0008223D03E8A153B268A157304552234089E +:1016D0008A114F2CDD2303180800031DB400B41B2E +:1016E00068348008031D62348A11F4228A15FF3A97 +:1016F000800534088223D03E8A153B268A15F309DB +:101700007305662B0310F4000130F4180430F30065 +:101710007418F30D7419F30EF40E740D740D1F3953 +:1017200008001D21031C080020302318EB04FF3A99 +:10173000231CEB056B084D2223088A11B72B1D21B2 +:10174000031C08004030952B3608063C031D62340C +:101750000130F3002308483A0319B42B1F3A031D44 +:1017600062340430F30012302406423A0319BD2BD0 +:10177000123A031D62340310F30D2508533A03197E +:10178000C52B1B3A031D6234F30E7308CD042308E6 +:101790008A11B7232408B7232508B72BDD230318A4 +:1017A00008008008031D6234CE00E017E801E9015B +:1017B0008A114F2C233084000800DA230008393CBA +:1017C000093C031CF72BF300840A0008393C093C50 +:1017D000031CF52BB1001A30730203186E34730822 +:1017E00062243107031CE32B6E34730808000314D2 +:1017F0006234DA23032403180800F300F30E0324F1 +:10180000031C7304080030300002031CF72BF63E63 +:10181000031C122CDF39F93E031CF72BFA3E031888 +:101820006234063E0A3E840A03100800DA235A177F +:1018300000082D3C03191F2C5A13023C0319840A7B +:10184000DE2303180800B40100080319422C2E3CC3 +:10185000031DF72B0730FD00840A00080319422CF2 +:10186000393C093C031CF72B7D196224FD18B40791 +:101870000310FD0CFD080319031C2C2CFB3E031860 +:10188000B40A2C2C5A1F4B2CF309B4080319542CFE +:101890003408643CB400B5016824B208031D013E5D +:1018A000B5007308B4000800F30A4B2CB401B5006E +:1018B0005E245E24B5070318B40A08000310B50DB2 +:1018C000B40D0800B200B207B20DB207320D080025 +:1018D0001030FD00B101B201B50DB40DB20D643090 +:1018E00032020318B200B10DFD0B6C2C3108080058 +:0A18F0003402031D0800B5080800CB +:0618FA009A08EA1A832C93 +:10190000EA01462D6C14EC148A1500278A1503137E +:1019100083128601831660308F0007309B00E7300A +:1019200085002730860003300E0640308E18503078 +:10193000831203196C0EFE00031EFE15831603307E +:101940008E00D5308100F930920083120030920071 +:101950008E018F013130900020306325A030632547 +:1019600083171030632581010B1164000B1DB52C0A +:1019700083161930990018151812981683129817A3 +:10198000FE1D181641309F0000303B26EB00E0386A +:1019900083169D000E303B26EE008A15D4228A1550 +:1019A00083160D178C141C0E83010D130C39DC00EB +:1019B0005C0DE7388500FF3086000B17FE1D8B1786 +:1019C000CA090730E0001430CF005030D0000A3090 +:1019D000D1005A30D2006430D8003D30D4000D30F0 +:1019E0003B26E3001030FD00B401D030B1003108D7 +:1019F0003B26B5003408B5080319092DB4000310BF +:101A0000B50C031C072D8A11F4228A158004340AB0 +:101A1000FB2C0730B404B40AB10AFD0BF72C1130CB +:101A20008A11A7238A15F30106303B268A15D62092 +:101A30008A15F30A07303B268A15D6208A15F30A41 +:101A400008303B268A15D6208A15F30A09303B2632 +:101A50008A15D6208A15F30A0A303B268A15D62025 +:101A60008A15F30A0B303B268A15D6208A150130D9 +:101A70003B26D9008A11FB268A15FE1D462D4D30C6 +:101A80008A11802327308A11A7238A156400CC0885 +:101A9000031D1F26FE19462D5B1896255E19C525C8 +:101AA0000B19D8250C18FE250C1B45268A11282752 +:101AB0008A155A190C26671B822C8C1E462D181964 +:101AC0007D2C8325462D84008001840A0409703909 +:101AD000031D642D08003608203E84001A08DB1917 +:101AE000080080000A3A03190800073A03197D2DFF +:101AF0003608013E831CB6000800B608031908002A +:101B00008001DB150800981C882D181218167E1508 +:101B10006B25DB1D08008A150220B601DB118A1136 +:101B20000038031D9623A8238A15C12D8A11CF23BF +:101B30008A155B107E18A82D8A111C208A15611D3C +:101B4000AA2DDC1676087A06031DC12DD50A55127A +:101B5000E701C12D0130DD005C145C1658308A119C +:101B600080234230751B543080230830751B1030A1 +:101B7000C8002230B80083168C148312F93091000B +:101B800012158A11E9238A1508005E1180305E1C47 +:101B9000D42D7430DE1CD12D57087A3C031C08006C +:101BA0007B308A11962383308A11A7238A15080077 +:101BB0000B11D40BE62DDA19E70A5E163D30D4007E +:101BC0006D0FED0005306D0203188511EA1EEA0A5B +:101BD000121D1F158A15FE18D2228A1165090319D4 +:101BE000E501E508031DDE238A15E608031DE60B63 +:101BF000080045308A118C238A1508000C10D31B6D +:101C0000D303DF195F1908008030DF065F054F300E +:101C10008A117E238A1508004C1B08008A11F623BE +:101C20008A1519304B0203181A2E2C308A11B7234B +:101C30008A1508005A118A11A8238A1508000C1E5B +:101C400008003708903E840083170008831399002A +:101C5000B70A503037060319B701CC030800031741 +:101C600083168C1C0800831203138C1E2F2EF40085 +:101C70006B2574082F2E2F268C0183128D0083165E +:101C80000C1483120C08031308000C131E085706CB +:101C9000D70657065702031C003CFC39031D832E50 +:101CA00057087A3C0318DE1A652E743C031C632E19 +:101CB000611D0800343C031C852E61114A308A11D5 +:101CC000A7238A150800E115662EE1116119852EFA +:101CD000611532308A11A7238A1512110B1383164E +:101CE0001C121C0E83120D130B175C060C39DC063C +:101CF000DE01631EE301DF01BA01BB0150308A112E +:101D00008C238A150800611D08007E1C5E1E0800D9 +:101D10000030F500F701F8019F26F600FA008A115D +:101D2000F3228A15031D972EB626F600FA008A11B3 +:101D300067208A15DB12AA25DE01ED0108000E30AE +:101D40008A005508A63E03188A0A8200BE2E19345E +:101D5000CA2EB62E11341B341C34DC2EB62EBE2EE9 +:101D60001934CA2E38343934B62E12348A11A622C8 +:101D70008A155B1E0800F501F701F801C408031D70 +:101D8000E11BC32E77140319E11DC72E7714EE1A39 +:101D9000F714003475164508F8004408031DDA2EC0 +:101DA0000A30E11DD92E4308F8004208031DDA2E3F +:101DB0005208F801F700013475165808F7000E3480 +:101E0000031E08008B138316031360308F002730E6 +:101E10008600E730850007309B00E6309D000630E5 +:101E20009C00D73081001930990026309800831229 +:101E300098171816FF30860081010130E327C2276A +:101E40001030E3278C1E0800C827031D08008317E5 +:101E500010308400F001C8270319282F0B3A03190A +:101E6000392F013A0319C82772088000F007840A45 +:101E70002B2FF008031D822F031712088D00130863 +:101E80008F00143084001108F1000F308A00100810 +:101E9000083C083C031C822F8207592F5F2F872F95 +:101EA000992FA12FAC2F822F822FED2F0101000F30 +:101EB000FF0F56308D000F308F00123084008316D4 +:101EC0008C170C140000000083120C088000840A98 +:101ED0000E088000840A8D0A03198F0AF10B5F2F08 +:101EE00010300402F1000F30C227F00110308400DE +:101EF0000008F007840AB527F10B782F7009013E1E +:101F0000B527C2270313C8270319282F822F84302F +:101F1000D127FC308D050430F40000088C00840AC1 +:101F200000088E00840AD527F40B8D2FF10B872F24 +:101F3000722F9430D1271F308D04D527F10B992FA4 +:101F4000722F83168C010C1483120C088000840AF3 +:101F50008D0AF10BA12F702F0430D12700088C00BF +:101F6000840AD527F10BAC2F722FF3000F3A031917 +:101F7000BF2F0B3A0319BF2F013A031DC12F0530A4 +:101F8000C2277308640003130C1EC42F9900043485 +:101F90009818ED2F64008C1ECA2F1A08F2000F3A11 +:101FA000080083168C0083120800640083165530E5 +:101FB0008D00AA308D008C148C18DC2F83128D0AB2 +:101FC00003198F0A013464008C1A08000B1DE32FDB +:101FD0000B11FF3E031DE32F0434031386108316F9 +:101FE0008610FF308500860081009B0007309C0032 +:101FF00098019901830198018B018A0164000028EE +:02400E00742F0D +:02401000FF3F70 +:1042000066000000100000004C003D004600580011 +:104210004F004D005000430000000000000041002E +:104220003D004F00700065006E005400680065009E +:1042300072006D0020004700610074006500770087 +:1042400061007900200034002E0033000000570088 +:104250004400540020007200650073006500740083 +:104260002100000054006800650072006D006F00BE +:104270007300740061007400200064006900730022 +:1042800063006F006E006E006500630074006500DF +:104290006400000054006800650072006D006F004B +:1042A0007300740061007400200063006F006E00F2 +:1042B0006E006500630074006500640000004E003D +:1042C000470000005300450000004E00530000006E +:1042D0004200560000004E00460000004F00520011 +:1042E00000004F00450000004D00650064006900BB +:1042F00075006D000000480069006700680000005C +:104300004C006F007700200070006F0077006500A0 +:10431000720000004500720072006F007200200001 +:10432000000042003D00310034003A00330030000C +:104330002000300037002D00300031002D00320009 +:10434000300032003100000043003D003400200006 +:104350004D0048007A0000004500430053004C0027 +:0443600050004200C7 +:1043A000000000000000000000000000000000000D +:1043B00000000000000000000000000000000000FD +:1043C0007400750076007700780079007A007B0031 +:1043D00000000000000000000000000000000000DD +:1043E00000000000000000000000000000000000CD +:1043F00000000000000000000000000000000000BD +:00000001FF diff --git a/data/gateway-4.3.ver b/data/gateway-4.3.ver new file mode 100644 index 0000000..69df05f --- /dev/null +++ b/data/gateway-4.3.ver @@ -0,0 +1 @@ +4.3 diff --git a/data/gateway.ver b/data/gateway.ver new file mode 100644 index 0000000..819e07a --- /dev/null +++ b/data/gateway.ver @@ -0,0 +1 @@ +5.0 diff --git a/data/interface.hex b/data/interface.hex new file mode 100644 index 0000000..db0e31b --- /dev/null +++ b/data/interface.hex @@ -0,0 +1,190 @@ +:020000040000FA +:080000008A1500278A157729F3 +:08000800F000030E8301F1007A +:100010000408F2000A08B0008A151108C8008C18FC +:10002000FC220D1B8A2230088A0072088400710E9F +:080030008300F00E700E0900C0 +:041000000034003484 +:0C1004007E1A442804303B02031C4C34CC +:1010100022083D3C031D032908308A0020082106D0 +:10102000F300E039031D493420088A159A2321086A +:101030009A233A309A2320309A2308308A00730882 +:10104000243E03188A0A8200493449344628493428 +:101050004B284934493449346428493449344934A3 +:101060004934642864286428502849344934493470 +:1010700055285A2849344934493449344934493483 +:1010800049345F28493449347E1255342008503C95 +:1010900003198A2849342008563C031997284934F3 +:1010A0002008473C0319F52849342008443C03191B +:1010B0008C2849342008453C0319EB284934200882 +:1010C000493C0319DD28493420084C3C031D4934B0 +:1010D0007F20031C080023088A159A238A154130B3 +:1010E0002102F3000830F3184030B40003107318E5 +:1010F000B40D0608231C06093405860608000310F3 +:101100003B08043A031D4C342308313C013C0318CE +:1011100008004F348A15D72B3B08053C031D4C347F +:101120004C2103180800840000088A15902B3B0806 +:10113000043C031D4C342308393C093C031C4F3448 +:10114000033EF300E03883169D008312E0304B0528 +:101150007304CB00AD208A15F12BF30000308A1503 +:1011600041228A15831203178D0073088316031713 +:101170000C14831203170C060319CA288C06831655 +:1011800003170C158B1355308D00AA308D008C146D +:101190008B170C1183120313730808000310F4005B +:1011A0000130F4180430F3007418F30D7419F30EC1 +:1011B000F40E740D740D1F3908007F20031C080005 +:1011C00020302318CB04FF3A231CCB054B08AD205D +:1011D00023088A159A2B7F20031C0800031DC717BC +:1011E0000319C71323088A159A2B3B08043C031DD7 +:1011F0004C342308523C031D4F34031386108316CE +:1012000086108A1100283B08083A031D4C34203010 +:1012100084004D2103180800F9004D21031808002F +:10122000FA004D2103180800FB004D2103180800A7 +:10123000FC000130C600451445160830791B1030FB +:10124000BE002230BD0083168C148312F930910049 +:1012500012150530791FC2008A15BD2B233084007A +:1012600008000008393C093C031C4A29F300840AA1 +:101270000008393C093C031C4829B2001A307302AB +:1012800003185234730869213207031C362952347B +:101290007308080003144C342E215621031808004B +:1012A000F300F30E5621031C7304080030300002D3 +:1012B000031C4A29F63E031C6529DF39F93E031C4D +:1012C0004A29FA3E03184C34063E0A3E840A0310AB +:0E12D0000800B300B307B30DB307330D0800D9 +:0212DE006400AA +:1012E000061D6F2998011A088A1500278A1503130D +:1012F000831286010516831660308F00E730850063 +:1013000027308600FE01031EFE15D5308100F9301E +:1013100092008312003092003130900081010B1155 +:1013200064000B1D9029033083169C0007309B003E +:101330001930990018151812981683129817181654 +:1013400041309F00203084005030FD00803080010B +:1013500084068001840AFD0BA72900304D22CB00B2 +:10136000E03883169D000D178C14830183161C0E24 +:1013700083120D130C39C500450DE7388500FF3089 +:1013800086000B178B173D30C00004308A158B2365 +:101390008A156400BF08031D30224418052247192E +:1013A0000A220B191D220C1B5B2218196F298C1A9B +:1013B000F221C9293B08203E84001A08C4190800FC +:1013C00080000A3A03190800073A0319EC293B0880 +:1013D000013E831CBB000800BB0803190800800104 +:1013E000C4150800981CF729181218167E16DA2161 +:1013F000C41D08008A150220BB01C4118A150038DB +:10140000031D75238C238A1508008A15B0238A15BD +:101410004410080047116430471C192A5830C71C73 +:10142000162A41087A3C031C08005F308A15752390 +:1014300067308A158B238A1508000B11C00B252AEB +:101440003D30C000C20B08008511121D1F158A1502 +:1014500049090319C901C908031DC9238A150800D0 +:101460000C1E08003C08A03E8400000899000408F7 +:1014700080008013BC0A50303C060319BC01BF0336 +:101480000800831603178C1C0800831203138C1E9C +:10149000412AF400DA217408412A41228C01831286 +:1014A00003178D00831603170C14831203170C08FF +:1014B0008312031308000C131E084106C1064106DF +:1014C0004102031C003CFC39031D080041087A3C22 +:1014D000031C762A4108733C683C0318C41C0800AE +:1014E000C41034308A158B238A150800C4180800EC +:1014F000C4141C308A158B238A1512110B13831602 +:101500001C121C0E83120D130B1745060C39C50651 +:04151000C701080007 +:0C15140083161C0E83120D1345060C39C3 +:1015200003190800C50604390319C71D9A2AFF309C +:10153000C9000800031DC719A22AC715BD08031951 +:10154000451AB82ABD080319D32A03304602031CE2 +:101550005D2B83161C0D8312C719803EBD0BC12A5B +:10156000031C622BC51B662B4414C7111211D02A11 +:10157000BD01451218304718083005061839850690 +:10158000C92A80300318C506F80DF70DF60DF50DC4 +:101590004513C601480891020630031C91028C10C5 +:1015A0006430810008001219E02AC908031DD02AFE +:1015B0002A3091001215C60183168C148312D02A8A +:1015C0000A3046020318C92A83161C0D8312C71954 +:1015D000803E031CD02A83161C1E0310831203189E +:1015E000C718F42AC7144715C6080319B62A2130AC +:1015F000BD00C5134513C92A8C10C60A451A062B0F +:10160000BD080319282BC619642B080046180800CA +:10161000BD080319202B0301451C18304718103A48 +:1016200005063E058506C618252B45100314FC0D3E +:10163000FB0DFA0DF90D03184514C601BD03080092 +:10164000121145123E1AC51608000130C5060800E1 +:10165000C71D08004608143C03193D2B50304602B4 +:10166000031C08001211C71183161C1E03108312DD +:10167000031C0800C71447150800451DC71F0800B4 +:10168000831610309C061C1E03101C0E83120D13B3 +:1016900045060C39C5060318542B4715C71C08000E +:1016A0004710C710051608004718592B4714051294 +:1016B0000800C71408004517D02A451BCB1A5B2B1E +:1016C0000130672B0230672B0330672B0430C908C9 +:1016D0000319C9001211BD01C601451249090319B8 +:0A16E000732B7A30CA008A15D02A55 +:0616EA008A1541228A1559 +:1016F000831203178D00802B9A23831203178D0A00 +:10170000831603170C14831203170C088312031398 +:10171000031D7C2B080075230D309A230A309A2B69 +:10172000F400740E942374080F39F63E0318073E34 +:101730000A3E303EBF0803190C1EA02B990000344E +:1017400084003C083F07B03E031C503EA03E040608 +:101750008406040680003F08503A031DBF0A003487 +:101760005430751B42309A237508902376089023D5 +:1017700077089023780890238C2B5230791B4130C6 +:101780009A23790890237A0890237B0890237C0879 +:10179000902B471908006E307523490890238C233D +:1017A0004530491CB323C9010800070D992B3B089C +:1017B000043A031D4C342308413A03190234153A04 +:1017C0000319EA2B023A0319F02B4F3423089A230A +:1017D0003D309A2BE6234B0EF300F30CF30CD52B84 +:0817E000E6234B08FD3E942BAB +:101E0000031E08008B138316031360308F002730E6 +:101E10008600E730850007309B00E6309D000630E5 +:101E20009C00D73081001930990026309800831229 +:101E300098171816FF30860081010130E327C2276A +:101E40001030E3278C1E0800C827031D08008317E5 +:101E500010308400F001C8270319282F0B3A03190A +:101E6000392F013A0319C82772088000F007840A45 +:101E70002B2FF008031D822F031712088D00130863 +:101E80008F00143084001108F1000F308A00100810 +:101E9000083C083C031C822F8207592F5F2F872F95 +:101EA000992FA12FAC2F822F822FED2F0101000F30 +:101EB000FF0F56308D000F308F00123084008316D4 +:101EC0008C170C140000000083120C088000840A98 +:101ED0000E088000840A8D0A03198F0AF10B5F2F08 +:101EE00010300402F1000F30C227F00110308400DE +:101EF0000008F007840AB527F10B782F7009013E1E +:101F0000B527C2270313C8270319282F822F84302F +:101F1000D127FC308D050430F40000088C00840AC1 +:101F200000088E00840AD527F40B8D2FF10B872F24 +:101F3000722F9430D1271F308D04D527F10B992FA4 +:101F4000722F83168C010C1483120C088000840AF3 +:101F50008D0AF10BA12F702F0430D12700088C00BF +:101F6000840AD527F10BAC2F722FF3000F3A031917 +:101F7000BF2F0B3A0319BF2F013A031DC12F0530A4 +:101F8000C2277308640003130C1EC42F9900043485 +:101F90009818ED2F64008C1ECA2F1A08F2000F3A11 +:101FA000080083168C0083120800640083165530E5 +:101FB0008D00AA308D008C148C18DC2F83128D0AB2 +:101FC00003198F0A013464008C1A08000B1DE32FDB +:101FD0000B11FF3E031DE32F0434031386108316F9 +:101FE0008610FF308500860081009B0007309C0032 +:101FF00098019901830198018B018A0164000028EE +:02400E00742F0D +:02401000FF3F70 +:104200002600000041003D004F00700065006E0078 +:1042100054006800650072006D00200049006E00C7 +:104220007400650072006600610063006500200094 +:1042300031002E003100000054006800650072005B +:104240006D006F0073007400610074002000640052 +:104250006900730063006F006E006E00650063000C +:10426000740065006400000054006800650072007E +:104270006D006F0073007400610074002000630023 +:104280006F006E006E0065006300740065006400DE +:1042900000004E00470000005300450000004200AF +:1042A000560000004F00520000004F004500000083 +:1042B0004D0065006400690075006D000000480055 +:1042C00069006700680000004C006F007700200064 +:1042D00070006F00770065007200000045007200FA +:1042E00072006F00720020000000310037003A00B9 +:1042F000350039002000320030002D003100300040 +:104300002D00320030003100350000003400200064 +:084310004D0048007A00000096 +:00000001FF diff --git a/data/interface.ver b/data/interface.ver new file mode 100644 index 0000000..9459d4b --- /dev/null +++ b/data/interface.ver @@ -0,0 +1 @@ +1.1 diff --git a/libraries/OTGWSerial/OTGWSerial.cpp b/libraries/OTGWSerial/OTGWSerial.cpp new file mode 100644 index 0000000..04b46db --- /dev/null +++ b/libraries/OTGWSerial/OTGWSerial.cpp @@ -0,0 +1,697 @@ +/* + OTGWSerial.cpp - Library for OTGW PIC communication + Copyright (c) 2021 - Schelte Bron + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include "OTGWSerial.h" + +#define STX ((uint8_t)0x0F) +#define ETX ((uint8_t)0x04) +#define DLE ((uint8_t)0x05) + +#define XFER_MAX_ID 16 + +// Relative duration of each programming operation (each unit is actually about 21ms) +#define WEIGHT_RESET 8 +#define WEIGHT_VERSION 1 +#define WEIGHT_DATAREAD 4 +#define WEIGHT_CODEPROG 10 +#define WEIGHT_DATAPROG 20 + +#define byteswap(val) ((val << 8) | (val >> 8)) + +enum { + FWSTATE_IDLE, + FWSTATE_RSET, + FWSTATE_VERSION, + FWSTATE_DUMP, + FWSTATE_PREP, + FWSTATE_CODE, + FWSTATE_DATA +}; + +enum { + CMD_VERSION, + CMD_READPROG, + CMD_WRITEPROG, + CMD_ERASEPROG, + CMD_READDATA, + CMD_WRITEDATA, + CMD_READCFG, + CMD_WRITECFG, + CMD_RESET +}; + +static const char banner[] = "OpenTherm Gateway "; + +OTGWSerial::OTGWSerial(int resetPin, int progressLed) +: HardwareSerial(UART0), _reset(resetPin), _led(progressLed) { + HardwareSerial::begin(9600, SERIAL_8N1); + // The PIC may have been confused by garbage on the + // serial interface when the NodeMCU resets. + resetPic(); + _upgrade_stage = FWSTATE_IDLE; + _version[0] = '\0'; + _version_pos = 0; +} + +int OTGWSerial::available() { + if (upgradeEvent()) return 0; + return HardwareSerial::available(); +} + +int OTGWSerial::read() { + if (upgradeEvent()) return -1; + return HardwareSerial::read(); +} + +// // Reimplement the read function. Other read functions call this to implement their functionality. +// int OTGWSerial::read() { +// int retval; +// char ch; +// if (upgradeEvent()) return -1; +// retval = HardwareSerial::read(); +// if (retval >= 0) { +// ch = retval; +// matchBanner(&ch); +// } +// return retval; +// } + +int OTGWSerial::availableForWrite() { + if (upgradeEvent()) return 0; + return HardwareSerial::availableForWrite(); +} + +size_t OTGWSerial::write(uint8_t c) { + if (upgradeEvent()) return 0; + return HardwareSerial::write(c); +} + + +size_t OTGWSerial::write(const uint8_t *buffer, size_t len) { + if (upgradeEvent()) return 0; + return HardwareSerial::write(buffer, len); +} + +bool OTGWSerial::busy() { + return upgradeEvent(); +} + +void OTGWSerial::resetPic() { + if (_reset >= 0) { + pinMode(_reset, OUTPUT); + digitalWrite(_reset, LOW); + } + HardwareSerial::print("GW=R\r"); + if (_reset >= 0) { + delay(100); + digitalWrite(_reset, HIGH); + pinMode(_reset, INPUT); + } + _banner_matched = 0; +} + +const char *OTGWSerial::firmwareVersion() { + return _version; +} + +void OTGWSerial::registerFinishedCallback(OTGWUpgradeFinished *func) { + _finishedFunc = func; +} + +void OTGWSerial::registerProgressCallback(OTGWUpgradeProgress *func) { + _progressFunc = func; +} + +void OTGWSerial::SetLED(int state) { + if (_led >= 0) { + digitalWrite(_led, state ? LOW : HIGH); + } +} + +void OTGWSerial::progress(int weight) { + if (_progressFunc) { + _upgrade_data->progress += weight; + _progressFunc(_upgrade_data->progress * 100 / _upgrade_data->total); + } +} + +// Look for the banner in the incoming data and extract the version number +void OTGWSerial::matchBanner(const char *str, int len) { + for (int i = 0; i < len; i++) { + if (banner[_banner_matched] == '\0') { + if (isspace(str[i])) { + _version[_version_pos] = '\0'; + _banner_matched = 0; + _version_pos = 0; + } else { + _version[_version_pos++] = str[i]; + } + } else if (str[i] != banner[_banner_matched++]) { + _banner_matched = 0; + } + } +} + +unsigned char OTGWSerial::hexChecksum(char *hex, int len) { + unsigned char sum = 0; + int val; + + while (len-- > 0) { + sscanf(hex, "%02x", &val); + sum -= val; + hex += 2; + } + return sum; +} + +OTGWError OTGWSerial::readHexFile(const char *hexfile, int *total) { + char hexbuf[48]; + int len, addr, tag, data, offs, linecnt = 0, weight; + uint32_t codemap[4] = {}; + byte datamap = 0; + OTGWError rc = OTGW_ERROR_HEX_FORMAT; + File f; + + f = LittleFS.open(hexfile, "r"); + if (!f) return OTGW_ERROR_HEX_ACCESS; + memset(_upgrade_data->codemem, -1, 4096 * sizeof(short)); + memset(_upgrade_data->datamem, -1, 256 * sizeof(char)); + weight = WEIGHT_RESET + WEIGHT_VERSION; + f.setTimeout(0); + while (f.readBytesUntil('\n', hexbuf, sizeof(hexbuf)) != 0) { + linecnt++; + if (sscanf(hexbuf, ":%2x%4x%2x", &len, &addr, &tag) != 3) { + // Parse error + rc = OTGW_ERROR_HEX_FORMAT; + break; + } + if (len & 1) { + // Invalid data size + rc = OTGW_ERROR_HEX_DATASIZE; + break; + } + if (hexChecksum(hexbuf + 1, len + 5) != 0) { + // Checksum error + rc = OTGW_ERROR_HEX_CHECKSUM; + break; + } + offs = 9; + len >>= 1; + if (tag == 0) { + if (addr >= 0x4400) { + // Bogus addresses + continue; + } else if (addr >= 0x4200) { + // Data memory + addr = (addr - 0x4200) >> 1; + while (len > 0) { + if (sscanf(hexbuf + offs, "%04x", &data) != 1) break; + if (!bitRead(datamap, addr / 64)) weight += WEIGHT_DATAPROG; + bitSet(datamap, addr / 64); + _upgrade_data->datamem[addr++] = byteswap(data); + offs += 4; + len--; + } + } else if (addr >= 0x4000) { + // Configuration bits + continue; + } else { + // Program memory + addr >>= 1; + while (len > 0) { + if (sscanf(hexbuf + offs, "%04x", &data) != 1) { + // Didn't find hex data + break; + } + if (!bitRead(codemap[addr / (32 * 32)], (addr / 32) & 31)) weight += WEIGHT_CODEPROG; + bitSet(codemap[addr / (32 * 32)], (addr / 32) & 31); + _upgrade_data->codemem[addr++] = byteswap(data); + offs += 4; + len--; + } + } + if (len) break; + } else if (tag == 1) { + rc = OTGW_ERROR_NONE; + break; + } + } + f.close(); + if (total) *total = weight; + return rc; +} + +int OTGWSerial::versionCompare(const char *version1, const char* version2) { + const char *s1 = version1, *s2 = version2; + int v1, v2, n; + + while (*s1 && *s2) { + if (!sscanf(s1, "%d%n", &v1, &n)) return 0; + s1 += n; + if (!sscanf(s2, "%d%n", &v2, &n)) return 0; + s2 += n; + if (v1 < v2) return -1; + if (v1 > v2) return 1; + if (*s1 != *s2) { + // Alpha versions + if (*s1 == 'a') return -1; + if (*s2 == 'a') return 1; + // Beta versions + if (*s1 == 'b') return -1; + if (*s2 == 'b') return 1; + // Subversions + if (*s1 == 0) return -1; + if (*s2 == 0) return 1; + } + s1++; + s2++; + } +} + +int OTGWSerial::eepromSettings(const char *version, OTGWTransferData *xfer) { + char buffer[64]; + int last = 0, len, id, p1, p2, addr, size, mask, n; + File f; + + f = LittleFS.open("/transfer.dat", "r"); + if (!f) return last; + while (f.available()) { + len = f.readBytesUntil('\n', buffer, sizeof(buffer) - 1); + buffer[len] = '\0'; + if ((n = sscanf(buffer, "%d %n%*s%n %x %d %x", &id, &p1, &p2, &addr, &size, &mask)) == 4) { + if (id >= XFER_MAX_ID); + buffer[p2] = '\0'; + if (versionCompare(version, buffer + p1) < 0) continue; + xfer[id].addr = addr; + xfer[id].size = size; + xfer[id].mask = mask; + if (id > last) last = id; + } + } + f.close(); + return last; +} + +void OTGWSerial::transferSettings(const char *ver1, const char *ver2) { + OTGWTransferData xfer1[XFER_MAX_ID] = {}, xfer2[XFER_MAX_ID] = {}; + int last, i, j, mask; + byte value; + + last = min(eepromSettings(ver1, xfer1), eepromSettings(ver2, xfer2)); + for (i = 0; i <= last; i++) { + if (xfer1[i].size) { + for (j = 0; j < xfer1[i].size; j++) { + if (xfer1[i].addr < 0x100) { + value = _upgrade_data->eedata[xfer1[i].addr + j]; + } else { + value = xfer1[i].addr & 0xff; + } + if (j < xfer2[i].size && xfer2[i].addr < 0x100) { + // Combine the masks + mask = xfer1[i].mask | xfer2[i].mask; + // Insert the old data into the data array + _upgrade_data->datamem[xfer2[i].addr + j] = _upgrade_data->datamem[xfer2[i].addr + j] & mask | value & ~mask; + } + } + } + } +} + +void OTGWSerial::fwCommand(const unsigned char *cmd, int len) { + uint8_t i, ch, sum = 0; + + HardwareSerial::write(STX); + for (i = 0; i <= len; i++) { + ch = i < len ? cmd[i] : sum; + if (ch == STX || ch == ETX || ch == DLE) { + HardwareSerial::write(DLE); + } + HardwareSerial::write(ch); + sum -= ch; + } + HardwareSerial::write(ETX); +} + +bool OTGWSerial::eraseCode(short addr, bool rc) { + byte fwcommand[] = {CMD_ERASEPROG, 1, 0, 0}; + short i; + for (i = 0; i < 32; i++) { + if (_upgrade_data->codemem[addr + i] != 0xffff) { + rc = true; + break; + } + } + if (rc) { + fwcommand[2] = addr & 0xff; + fwcommand[3] = addr >> 8; + fwCommand(fwcommand, sizeof(fwcommand)); + } + return rc; +} + +void OTGWSerial::loadCode(short addr, const unsigned short *code, short len) { + byte i, fwcommand[4 + 2 * len]; + unsigned short *data = (unsigned short *)fwcommand + 2; + fwcommand[0] = CMD_WRITEPROG; + fwcommand[1] = len >> 2; + fwcommand[2] = addr & 0xff; + fwcommand[3] = addr >> 8; + for (i = 0; i < len; i++) { + data[i] = code[i] & 0x3fff; + } + fwCommand(fwcommand, sizeof(fwcommand)); +} + +void OTGWSerial::readCode(short addr, short len) { + byte fwcommand[] = {CMD_READPROG, 32, 0, 0}; + fwcommand[1] = len; + fwcommand[2] = addr & 0xff; + fwcommand[3] = addr >> 8; + fwCommand(fwcommand, sizeof(fwcommand)); +} + +bool OTGWSerial::verifyCode(const unsigned short *code, const unsigned short *data, short len) { + short i; + bool rc = true; + + for (i = 0; i < len; i++) { + if (data[i] != (code[i] & 0x3fff)) { + _upgrade_data->errcnt++; + rc = false; + } + } + return rc; +} + +void OTGWSerial::loadData(short addr) { + byte i; + byte fwcommand[68] = {CMD_WRITEDATA, 64}; + fwcommand[2] = addr & 0xff; + fwcommand[3] = addr >> 8; + for (i = 0; i < 64; i++) { + fwcommand[i + 4] = _upgrade_data->datamem[addr + i]; + } + fwCommand(fwcommand, sizeof(fwcommand)); +} + +void OTGWSerial::readData(short addr) { + byte fwcommand[] = {CMD_READDATA, 64, 0, 0}; + fwcommand[2] = addr & 0xff; + fwCommand(fwcommand, sizeof(fwcommand)); +} + +bool OTGWSerial::verifyData(short pc, const byte *data, short len) { + short i; + bool rc = true; + + for (i = 0; i < len; i++) { + if (data[i] != _upgrade_data->datamem[pc + i]) { + _upgrade_data->errcnt++; + rc = false; + } + } + return rc; +} + +OTGWError OTGWSerial::startUpgrade(const char *hexfile) { + int weight; + unsigned short ptr; + char *s; + OTGWError result; + + if (_upgrade_data != nullptr) { + return OTGW_ERROR_INPROG; + } + + _upgrade_data = (OTGWUpgradeData *)malloc(sizeof(OTGWUpgradeData)); + if (_upgrade_data == nullptr) { + return OTGW_ERROR_MEMORY; + } + + result = readHexFile(hexfile, &weight); + if (result != OTGW_ERROR_NONE) { + return finishUpgrade(result); + } + + if (_upgrade_data->codemem[0] != 0x158a || (_upgrade_data->codemem[1] & 0x3e00) != 0x2600) { + // Bad magic + return finishUpgrade(OTGW_ERROR_MAGIC); + } + // The self-programming code will be skipped (assume 256 program words) + weight -= 8 * WEIGHT_CODEPROG; + + // Look for the new firmware version + _upgrade_data->version = nullptr; + ptr = 0; + while (ptr < 256) { + s = strstr((char *)_upgrade_data->datamem + ptr, banner); + if (s == nullptr) { + ptr += strnlen((char *)_upgrade_data->datamem + ptr, 256 - ptr) + 1; + } else { + s += sizeof(banner) - 1; // Drop the terminating '\0' + _upgrade_data->version = s; + if (*_version) { + // Reading out the EEPROM settings takes 4 reads of 64 bytes + weight += 4 * WEIGHT_DATAREAD; + } + break; + } + } + + _upgrade_data->total = weight; + stateMachine(); + return OTGW_ERROR_NONE; +} + +void OTGWSerial::stateMachine(const unsigned char *packet, int len) { + const unsigned short *data = (const unsigned short *)packet; + byte cmd = 0; + + if (packet == nullptr || len == 0) { + cmd = _upgrade_data->lastcmd; + } else { + cmd = packet[0]; + _upgrade_data->lastcmd = cmd; + } + + if (_upgrade_stage != FWSTATE_IDLE && packet == nullptr) { + int maxtries = (_upgrade_stage == FWSTATE_CODE || _upgrade_stage == FWSTATE_DATA ? 100 : 10); + if (++_upgrade_data->retries >= maxtries) { + finishUpgrade(OTGW_ERROR_RETRIES); + return; + } + } + + switch (_upgrade_stage) { + case FWSTATE_IDLE: + _upgrade_data->errcnt = 0; + _upgrade_data->retries = 0; + _upgrade_data->progress = 0; + resetPic(); + _upgrade_stage = FWSTATE_RSET; + break; + case FWSTATE_RSET: + if (packet != nullptr) { + byte fwcommand[] = {CMD_VERSION, 3}; + progress(WEIGHT_RESET); + fwCommand(fwcommand, sizeof(fwcommand)); + _upgrade_stage = FWSTATE_VERSION; + } else { + resetPic(); + } + break; + case FWSTATE_VERSION: + if (data != nullptr) { + _upgrade_data->protectstart = data[2]; + _upgrade_data->protectend = data[3]; + _upgrade_data->failsafe[0] = 0x158a; // BSF PCLATH,3 + if ((_upgrade_data->protectstart & 0x800) == 0) { + _upgrade_data->failsafe[0] = 0x118a; // BCF PCLATH,3 + } + _upgrade_data->failsafe[1] = 0x2000 | _upgrade_data->protectstart & 0x7ff; // CALL SelfProg + _upgrade_data->failsafe[2] = 0x118a; // BCF PCLATH,3 + _upgrade_data->failsafe[3] = 0x2820; // GOTO 0x20 + progress(WEIGHT_VERSION); + if (*_version && _upgrade_data->version) { + // Both old and new versions are known + // Dump the current eeprom data to be able to transfer the settings + _upgrade_data->pc = 0; + readData(_upgrade_data->pc); + _upgrade_stage = FWSTATE_DUMP; + } else { + _upgrade_data->pc = 0x20; + eraseCode(_upgrade_data->pc, true); + _upgrade_stage = FWSTATE_PREP; + } + } else { + byte fwcommand[] = {CMD_VERSION, 3}; + fwCommand(fwcommand, sizeof(fwcommand)); + _upgrade_stage = FWSTATE_VERSION; + } + break; + case FWSTATE_DUMP: + if (packet != nullptr) { + progress(WEIGHT_DATAREAD); + memcpy(_upgrade_data->eedata + _upgrade_data->pc, packet + 4, 64); + _upgrade_data->pc += 64; + } + if (_upgrade_data->pc < 0x100) { + readData(_upgrade_data->pc); + } else { + // Transfer the EEPROM settings + transferSettings(_version, _upgrade_data->version); + _upgrade_data->pc = 0x20; + eraseCode(_upgrade_data->pc); + _upgrade_stage = FWSTATE_PREP; + } + break; + case FWSTATE_PREP: + // Programming has started; invalidate the firmware version + *_version = '\0'; + if (cmd == CMD_ERASEPROG) { + loadCode(_upgrade_data->pc, _upgrade_data->failsafe, 4); + } else if (cmd == CMD_WRITEPROG) { + readCode(_upgrade_data->pc, 4); + } else { + if (packet != nullptr && packet[1] == 4 && data[1] == _upgrade_data->pc && verifyCode(_upgrade_data->failsafe, data + 2, 4)) { + progress(WEIGHT_CODEPROG); + _upgrade_data->pc = 0; + eraseCode(_upgrade_data->pc); + _upgrade_stage = FWSTATE_CODE; + } else { + // Failed. Try again. + eraseCode(_upgrade_data->pc, true); + } + } + break; + case FWSTATE_CODE: + if (cmd == CMD_ERASEPROG) { + // digitalWrite(LED2, LOW); + loadCode(_upgrade_data->pc, _upgrade_data->codemem + _upgrade_data->pc); + } else if (cmd == CMD_WRITEPROG) { + // digitalWrite(LED2, HIGH); + readCode(_upgrade_data->pc); + } else if (cmd == CMD_READPROG) { + if (packet != nullptr && packet[1] == 32 && data[1] == _upgrade_data->pc && verifyCode(_upgrade_data->codemem + _upgrade_data->pc, data + 2)) { + do { + do { + _upgrade_data->pc += 32; + } while (_upgrade_data->pc + 31 >= _upgrade_data->protectstart && _upgrade_data->pc <= _upgrade_data->protectend); + if (_upgrade_data->pc >= 0x1000) { + _upgrade_data->pc = 0; + loadData(_upgrade_data->pc); + _upgrade_stage = FWSTATE_DATA; + break; + } else if (eraseCode(_upgrade_data->pc)) { + progress(WEIGHT_CODEPROG); + break; + } + } while (_upgrade_data->pc < 0x1000); + } else { + eraseCode(_upgrade_data->pc); + } + } + break; + case FWSTATE_DATA: + if (cmd == CMD_WRITEDATA) { + // digitalWrite(LED2, HIGH); + readData(_upgrade_data->pc); + } else if (cmd == CMD_READDATA) { + if (packet != nullptr && verifyData(_upgrade_data->pc, packet + 4)) { + progress(WEIGHT_DATAPROG); + _upgrade_data->pc += 64; + if (_upgrade_data->pc < 0x100) { + // digitalWrite(LED2, LOW); + loadData(_upgrade_data->pc); + } else { + byte fwcommand[] = {CMD_RESET, 0}; + fwCommand(fwcommand, sizeof(fwcommand)); + finishUpgrade(OTGW_ERROR_NONE); + } + } else { + // digitalWrite(LED2, LOW); + loadData(_upgrade_data->pc); + } + } + break; + } + + if (_upgrade_stage != FWSTATE_IDLE) { + _upgrade_data->lastaction = millis(); + } +} + +OTGWError OTGWSerial::finishUpgrade(OTGWError result) { + short errors = _upgrade_data->errcnt, retries = _upgrade_data->retries; + free((void *)_upgrade_data); + _upgrade_data = nullptr; + _upgrade_stage = FWSTATE_IDLE; + if (_finishedFunc) { + _finishedFunc(result, errors, retries); + } + return result; +} + +// Proceed with the upgrade, if applicable +bool OTGWSerial::upgradeEvent() { + int ch; + bool dle; + if (_upgrade_stage == FWSTATE_IDLE) return false; + while (HardwareSerial::available()) { + ch = HardwareSerial::read(); + dle = _upgrade_data->bufpos < sizeof(_upgrade_data->buffer) && _upgrade_data->buffer[_upgrade_data->bufpos] == DLE; + if (!dle && ch == STX) { + SetLED(1); + _upgrade_data->bufpos = 0; + _upgrade_data->checksum = 0; + _upgrade_data->buffer[0] = '\0'; + } else if ((!dle || _upgrade_stage == FWSTATE_RSET) && ch == ETX) { + SetLED(0); + if (_upgrade_data->checksum == 0 || _upgrade_stage == FWSTATE_RSET) { + stateMachine(_upgrade_data->buffer, _upgrade_data->bufpos); + } else { + // Checksum mismatch + stateMachine(); + } + } else if (_upgrade_data->bufpos >= sizeof(_upgrade_data->buffer)) { + // Prevent overwriting the program data + } else if (!dle && ch == DLE) { + _upgrade_data->buffer[_upgrade_data->bufpos] = ch; + } else { + _upgrade_data->buffer[_upgrade_data->bufpos++] = ch; + _upgrade_data->checksum -= ch; + _upgrade_data->buffer[_upgrade_data->bufpos] = '\0'; + } + } + if (_upgrade_stage != FWSTATE_IDLE && millis() - _upgrade_data->lastaction > 1000) { + // Too much time has passed since the last action + // Send a non-DLE byte in case the PIC is waiting for a byte following a DLE + HardwareSerial::write(STX); + stateMachine(); + } + return true; +} diff --git a/libraries/OTGWSerial/OTGWSerial.h b/libraries/OTGWSerial/OTGWSerial.h new file mode 100644 index 0000000..16984b3 --- /dev/null +++ b/libraries/OTGWSerial/OTGWSerial.h @@ -0,0 +1,132 @@ +/* + OTGWSerial.h - Library for OTGW PIC communication + Copyright (c) 2021 - Schelte Bron + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef OTGWSerial_h +#define OTGWSerial_h + +#include + +typedef enum { + OTGW_ERROR_NONE, // No error + OTGW_ERROR_MEMORY, // Not enough space + OTGW_ERROR_HEX_ACCESS, // Could not open hex file + OTGW_ERROR_HEX_FORMAT, // Invalid format of hex file + OTGW_ERROR_HEX_DATASIZE,// Wrong data size in hex file + OTGW_ERROR_HEX_CHECKSUM,// Bad checksum in hex file + OTGW_ERROR_INPROG, // Firmware upgrade in progress + OTGW_ERROR_MAGIC, // Hex file does not contain expected data + OTGW_ERROR_RESET, // PIC reset failed + OTGW_ERROR_RETRIES, // Too many retries + OTGW_ERROR_MISMATCHES // Too many mismatches +} OTGWError; + +typedef struct { + unsigned char buffer[80]; + unsigned char datamem[256]; + unsigned char eedata[256]; + unsigned short codemem[4096]; + unsigned short failsafe[4]; + unsigned short protectstart, protectend; + unsigned short pc, errcnt, retries, progress, total; + byte bufpos, checksum, lastcmd; + unsigned long lastaction; + char *version; +} OTGWUpgradeData; + +typedef struct { + unsigned short addr; + byte size, mask; +} OTGWTransferData; + +typedef void OTGWUpgradeFinished(OTGWError result, short errors, short retries); +typedef void OTGWUpgradeProgress(int pct); + +class OTGWSerial: public HardwareSerial { + public: + OTGWSerial(int resetPin = -1, int progressLed = -1); + int available(); + int read(); + int availableForWrite(); + size_t write(uint8_t c); + size_t write(const uint8_t *buffer, size_t len); + size_t write(const char *buffer, size_t len) { + return write((const uint8_t *)buffer, len); + } + + // These handle ambiguity for write(0) case, because (0) can be a pointer or an integer + inline size_t write(short t) { return write((uint8_t)t); } + inline size_t write(unsigned short t) { return write((uint8_t)t); } + inline size_t write(int t) { return write((uint8_t)t); } + inline size_t write(unsigned int t) { return write((uint8_t)t); } + inline size_t write(long t) { return write((uint8_t)t); } + inline size_t write(unsigned long t) { return write((uint8_t)t); } + // Enable write(char) to fall through to write(uint8_t) + inline size_t write(char c) { return write((uint8_t) c); } + inline size_t write(int8_t c) { return write((uint8_t) c); } + + size_t write(const char *buffer) { + if(buffer == NULL) + return 0; + return write((const uint8_t *)buffer, strlen(buffer)); + } + + const char *firmwareVersion(); + bool busy(); + void resetPic(); + OTGWError startUpgrade(const char *hexfile); + void registerFinishedCallback(OTGWUpgradeFinished *func); + void registerProgressCallback(OTGWUpgradeProgress *func); + + protected: + OTGWUpgradeData *_upgrade_data = nullptr; + OTGWUpgradeFinished *_finishedFunc = nullptr; + OTGWUpgradeProgress *_progressFunc = nullptr; + char _version[16]; + int _reset, _led; + byte _banner_matched, _version_pos, _upgrade_stage; + + void SetLED(int state); + void progress(int weight); + void matchBanner(const char *str, int len = 1); + unsigned char hexChecksum(char *hex, int len); + OTGWError readHexFile(const char *hexfile, int *total = nullptr); + + int versionCompare(const char *version1, const char* version2); + int eepromSettings(const char *version, OTGWTransferData *xfer); + void transferSettings(const char *ver1, const char *ver2); + void fwCommand(const unsigned char *cmd, int len); + bool eraseCode(short addr, bool rc = false); + void loadCode(short addr, const unsigned short *code, short len = 32); + void readCode(short addr, short len = 32); + bool verifyCode(const unsigned short *code, const unsigned short *data, short len = 32); + void loadData(short addr); + void readData(short addr); + bool verifyData(short pc, const byte *data, short len = 64); + void stateMachine(const unsigned char *packet = nullptr, int len = 0); + OTGWError finishUpgrade(OTGWError result); + bool upgradeEvent(); +}; + +#endif diff --git a/networkStuff.h b/networkStuff.h index db5de26..48e3479 100644 --- a/networkStuff.h +++ b/networkStuff.h @@ -50,7 +50,6 @@ ESP8266WebServer httpServer (80); ESP8266HTTPUpdateServer httpUpdater(true); - static FSInfo LittleFSinfo; bool LittleFSmounted; bool isConnected = false; @@ -76,7 +75,7 @@ void startWiFi(const char* hostname, int timeOut) uint32_t lTime = millis(); String thisAP = String(hostname) + "-" + WiFi.macAddress(); - Serial.println("Start Wifi ..."); + OTGWSerial.println("Start Wifi ..."); manageWiFi.setDebugOutput(true); //--- next line in release needs to be commented out! @@ -94,7 +93,7 @@ void startWiFi(const char* hostname, int timeOut) //--- if it does not connect it starts an access point with the specified name //--- here "-" //--- and goes into a blocking loop awaiting configuration - Serial.printf("AutoConnect to: %s", thisAP.c_str()); + OTGWSerial.printf("AutoConnect to: %s", thisAP.c_str()); if (!manageWiFi.autoConnect(thisAP.c_str())) { //-- fail to connect? Have you tried turning it off and on again? diff --git a/OTGW-upgrade.h b/old-upgrade/OTGW-upgrade.h similarity index 100% rename from OTGW-upgrade.h rename to old-upgrade/OTGW-upgrade.h diff --git a/OTGW-upgrade.ino b/old-upgrade/OTGW-upgrade.ino similarity index 100% rename from OTGW-upgrade.ino rename to old-upgrade/OTGW-upgrade.ino diff --git a/version.h b/version.h index e2bb2fa..4551fc2 100644 --- a/version.h +++ b/version.h @@ -2,13 +2,13 @@ #define _VERSION_MAJOR 0 #define _VERSION_MINOR 7 #define _VERSION_PATCH 3 -#define _VERSION_BUILD 506 +#define _VERSION_BUILD 561 //#define _VERSION_PRERELEASE beta //uncomment to define prerelease labels: alpha - beta - rc -#define _VERSION_DATE "04-02-2021" -#define _VERSION_TIME "00:01:47" +#define _VERSION_DATE "08-02-2021" +#define _VERSION_TIME "00:13:21" #define _SEMVER_CORE "0.7.3" -#define _SEMVER_BUILD "0.7.3+506" -#define _SEMVER_FULL "0.7.3+506" -#define _SEMVER_NOBUILD "0.7.3 (04-02-2021)" -#define _VERSION "0.7.3+506 (04-02-2021)" +#define _SEMVER_BUILD "0.7.3+561" +#define _SEMVER_FULL "0.7.3+561" +#define _SEMVER_NOBUILD "0.7.3 (08-02-2021)" +#define _VERSION "0.7.3+561 (08-02-2021)" //The version information is created automatically, more information here: https://github.com/rvdbreemen/autoinc-semver