Skip to content

Commit 9ff12b7

Browse files
committed
Adding ability to update firmware over WiFi
1 parent 910d02a commit 9ff12b7

File tree

6 files changed

+45
-159
lines changed

6 files changed

+45
-159
lines changed
Binary file not shown.

Firmware/RTK_Surveyor/AP-Config/index.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,9 +1129,8 @@ <h2>
11291129
</div>
11301130
<div class="col-sm-7 col-6 mt-2">
11311131
<div id="uploadNewFirmwareDiv" class="mb-2">
1132-
<label class="form-check-label" for="uploadNewFirmware">Add Firmware:</label>
1133-
<span class="tt" data-bs-placement="right"
1134-
title="New firmware may be uploaded via WiFi to the SD card. Firmware is only loaded to the SD card and must then be loaded to the unit.">
1132+
<label class="form-check-label" for="uploadNewFirmware">Update Firmware:</label>
1133+
<span class="tt" data-bs-placement="right" title="Update the unit's firmware over WiFi.">
11351134
<span class="icon-info-circle text-primary ms-2"></span>
11361135
</span>
11371136
<form id="uploadNewFirmware" enctype="multipart/form-data" method="post" action="/upload">
@@ -1160,7 +1159,8 @@ <h2>
11601159
<p id="saveBtnSuccess" class="inlineSuccess"></p>
11611160
</div>
11621161
<div align="center" class="col-sm-5 col-12">
1163-
<button type="button" id="exitBtn" class="btn btn-outline-secondary" onclick="exitConfig()">Exit and Reset<span class="icon-remove text-secondary ms-1"></span></button>
1162+
<button type="button" id="exitBtn" class="btn btn-outline-secondary" onclick="exitConfig()">Exit and
1163+
Reset<span class="icon-remove text-secondary ms-1"></span></button>
11641164
<p id="exitBtnError" class="inlineSuccess"></p>
11651165
<p>&nbsp;</p>
11661166
</div>

Firmware/RTK_Surveyor/AP-Config/src/main.js

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,6 @@ function parseIncoming(msg) {
8383
) {
8484
ge(id).innerHTML = val;
8585
}
86-
else if (id.includes("firmwareFileName")) {
87-
show("firmwareAvailable"); //Turn on firmware area
88-
89-
ge(id).innerHTML = val;
90-
if (id.includes("0")) show("firmwareFile0");
91-
if (id.includes("1")) show("firmwareFile1");
92-
if (id.includes("2")) show("firmwareFile2");
93-
if (id.includes("3")) show("firmwareFile3");
94-
if (id.includes("4")) show("firmwareFile4");
95-
if (id.includes("5")) show("firmwareFile5");
96-
}
9786

9887
//Check boxes / radio buttons
9988
else if (val == "true") {
@@ -161,22 +150,6 @@ function sendData() {
161150
ws.send(settingCSV);
162151
}
163152

164-
function sendFirmwareFile() {
165-
var firmwareFileName = "firmwareFileName,";
166-
167-
//ID the firmware file radio
168-
if (ge("file0").checked) firmwareFileName += ge("firmwareFileName0").innerHTML;
169-
else if (ge("file1").checked) firmwareFileName += ge("firmwareFileName1").innerHTML;
170-
else if (ge("file2").checked) firmwareFileName += ge("firmwareFileName2").innerHTML;
171-
else if (ge("file3").checked) firmwareFileName += ge("firmwareFileName3").innerHTML;
172-
else if (ge("file4").checked) firmwareFileName += ge("firmwareFileName4").innerHTML;
173-
else if (ge("file5").checked) firmwareFileName += ge("firmwareFileName5").innerHTML;
174-
175-
firmwareFileName += ","
176-
ws.send(firmwareFileName);
177-
ge("firmwareUpdateMsg").innerHTML = 'Updating, please wait for system reset...';
178-
}
179-
180153
function showError(id, errorText) {
181154
ge(id + 'Error').innerHTML = '<br>Error: ' + errorText;
182155
}
@@ -503,7 +476,7 @@ function exitConfig() {
503476
}
504477

505478
function firmwareUploadWait() {
506-
ge("firmwareUploadMsg").innerHTML = "<br>Uploading, please wait....";
479+
ge("firmwareUploadMsg").innerHTML = "<br>Uploading, please wait...";
507480
}
508481

509482
document.addEventListener("DOMContentLoaded", (event) => {
@@ -661,25 +634,6 @@ document.addEventListener("DOMContentLoaded", (event) => {
661634
}
662635
});
663636

664-
//Enable the check box
665-
ge("firmwareFile0").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
666-
ge("firmwareFile1").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
667-
ge("firmwareFile2").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
668-
ge("firmwareFile3").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
669-
ge("firmwareFile4").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
670-
ge("firmwareFile5").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
671-
672-
ge("enableFirmwareUpdate").addEventListener("change", function () {
673-
if (ge("enableFirmwareUpdate").checked) {
674-
//Enable button
675-
ge("firmwareUpdate").disabled = false;
676-
}
677-
else {
678-
//Disable button
679-
ge("firmwareUpdate").disabled = true;
680-
}
681-
});
682-
683637
ge("dataPortChannel").addEventListener("change", function () {
684638
if (ge("dataPortChannel").value == 0) {
685639
show("dataPortBaudDropdown");

Firmware/RTK_Surveyor/Begin.ino

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,10 @@ void beginGNSS()
360360
zedFirmwareVersionInt = 120;
361361
else if (strstr(zedFirmwareVersion, "1.21") != NULL) //Future F9R HPS v1.21
362362
zedFirmwareVersionInt = 121;
363+
else if (strstr(zedFirmwareVersion, "1.30") != NULL) //ZED-F9P released Dec, 2021
364+
zedFirmwareVersionInt = 130;
363365
else
364-
Serial.printf("Unknown firmware version: %s", zedFirmwareVersion);
366+
Serial.printf("Unknown firmware version: %s\n\r", zedFirmwareVersion);
365367

366368
//Determine if we have a ZED-F9P (Express/Facet) or an ZED-F9R (Express Plus/Facet Plus)
367369
if (strstr(i2cGNSS.minfo.extension[3], "ZED-F9P") != NULL)

Firmware/RTK_Surveyor/Form.ino

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ void startConfigAP()
168168
request->send(response);
169169
});
170170

171-
//Handler for the /update form POST
171+
//Handler for the /upload form POST
172172
server.on("/upload", HTTP_POST, [](AsyncWebServerRequest * request) {
173173
request->send(200);
174174
}, handleFirmwareFileUpload);
@@ -183,65 +183,41 @@ void startConfigAP()
183183
#ifdef COMPILE_WIFI
184184
static void handleFirmwareFileUpload(AsyncWebServerRequest *request, String fileName, size_t index, uint8_t *data, size_t len, bool final)
185185
{
186-
if (online.microSD == false)
186+
//Todo check file name against valid firmware names
187+
188+
if (!index)
187189
{
188-
Serial.println(F("No SD card available"));
189-
return;
190+
if (!Update.begin(UPDATE_SIZE_UNKNOWN))
191+
{
192+
Update.printError(Serial);
193+
return request->send(400, "text/plain", "OTA could not begin");
194+
}
190195
}
191196

192-
//Attempt to write to file system. This avoids collisions with file writing in F9PSerialReadTask()
193-
if (xSemaphoreTake(xFATSemaphore, fatSemaphore_longWait_ms) != pdPASS) {
194-
Serial.println(F("Failed to get file system lock on firmware file"));
195-
return;
197+
// Write chunked data to the free sketch space
198+
if (len)
199+
{
200+
if (Update.write(data, len) != len)
201+
return request->send(400, "text/plain", "OTA could not begin");
196202
}
197203

198-
if (!index) {
199-
//Convert string to array
200-
char tempFileName[100];
201-
fileName.toCharArray(tempFileName, sizeof(tempFileName));
202-
203-
if (sd.exists(tempFileName))
204+
if (final)
205+
{
206+
if (!Update.end(true))
204207
{
205-
sd.remove(tempFileName);
206-
Serial.printf("Removed old firmware file: %s\n\r", tempFileName);
208+
Update.printError(Serial);
209+
return request->send(400, "text/plain", "Could not end OTA");
207210
}
208-
209-
Serial.printf("Start Firmware Upload: %s\n\r", tempFileName);
210-
211-
// O_CREAT - create the file if it does not exist
212-
// O_APPEND - seek to the end of the file prior to each write
213-
// O_WRITE - open for write
214-
if (newFirmwareFile.open(tempFileName, O_CREAT | O_APPEND | O_WRITE) == false)
211+
else
215212
{
216-
Serial.printf("Failed to create firmware file: %s\n\r", tempFileName);
217-
xSemaphoreGive(xFATSemaphore);
218-
return;
213+
Serial.print("Update complete: ");
214+
Serial.println(fileName);
215+
request->send(200, "text/html", "<b>Done</b><br><br>Firmware update complete. RTK device is rebooting.");
216+
Serial.println("Restarting");
217+
delay(100);
218+
ESP.restart();
219219
}
220220
}
221-
222-
//Record to file
223-
if (newFirmwareFile.write(data, len) != len)
224-
log_e("Error writing to firmware file");
225-
else
226-
log_d("Recorded %d bytes to file\n\r", len);
227-
228-
if (final)
229-
{
230-
updateDataFileCreate(&newFirmwareFile); // Update the file create time & date
231-
newFirmwareFile.close();
232-
233-
Serial.print("Upload complete: ");
234-
Serial.println(fileName);
235-
236-
binCount = 0;
237-
xSemaphoreGive(xFATSemaphore); //Must release semaphore before scanning for firmware
238-
scanForFirmware(); //Update firmware file list
239-
240-
//Reload page upon success - this will show all available firmware files
241-
request->send(200, "text/html", "<meta http-equiv=\"Refresh\" content=\"0; url='/'\" />");
242-
}
243-
244-
xSemaphoreGive(xFATSemaphore);
245221
}
246222
#endif
247223

Firmware/RTK_Surveyor/form.h

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,6 @@ function parseIncoming(msg) {
106106
) {
107107
ge(id).innerHTML = val;
108108
}
109-
else if (id.includes("firmwareFileName")) {
110-
show("firmwareAvailable"); //Turn on firmware area
111-
112-
ge(id).innerHTML = val;
113-
if (id.includes("0")) show("firmwareFile0");
114-
if (id.includes("1")) show("firmwareFile1");
115-
if (id.includes("2")) show("firmwareFile2");
116-
if (id.includes("3")) show("firmwareFile3");
117-
if (id.includes("4")) show("firmwareFile4");
118-
if (id.includes("5")) show("firmwareFile5");
119-
}
120109

121110
//Check boxes / radio buttons
122111
else if (val == "true") {
@@ -184,22 +173,6 @@ function sendData() {
184173
ws.send(settingCSV);
185174
}
186175

187-
function sendFirmwareFile() {
188-
var firmwareFileName = "firmwareFileName,";
189-
190-
//ID the firmware file radio
191-
if (ge("file0").checked) firmwareFileName += ge("firmwareFileName0").innerHTML;
192-
else if (ge("file1").checked) firmwareFileName += ge("firmwareFileName1").innerHTML;
193-
else if (ge("file2").checked) firmwareFileName += ge("firmwareFileName2").innerHTML;
194-
else if (ge("file3").checked) firmwareFileName += ge("firmwareFileName3").innerHTML;
195-
else if (ge("file4").checked) firmwareFileName += ge("firmwareFileName4").innerHTML;
196-
else if (ge("file5").checked) firmwareFileName += ge("firmwareFileName5").innerHTML;
197-
198-
firmwareFileName += ","
199-
ws.send(firmwareFileName);
200-
ge("firmwareUpdateMsg").innerHTML = 'Updating, please wait for system reset...';
201-
}
202-
203176
function showError(id, errorText) {
204177
ge(id + 'Error').innerHTML = '<br>Error: ' + errorText;
205178
}
@@ -526,7 +499,7 @@ function exitConfig() {
526499
}
527500

528501
function firmwareUploadWait() {
529-
ge("firmwareUploadMsg").innerHTML = "<br>Uploading, please wait....";
502+
ge("firmwareUploadMsg").innerHTML = "<br>Uploading, please wait...";
530503
}
531504

532505
document.addEventListener("DOMContentLoaded", (event) => {
@@ -575,7 +548,7 @@ document.addEventListener("DOMContentLoaded", (event) => {
575548
ge("fixedEcefX").disabled = false;
576549
ge("fixedEcefY").disabled = false;
577550
ge("fixedEcefZ").disabled = false;
578-
//Disable Geodetic inputs
551+
//Disable Geographic inputs
579552
ge("fixedLat").disabled = true;
580553
ge("fixedLong").disabled = true;
581554
ge("fixedAltitude").disabled = true;
@@ -585,7 +558,7 @@ document.addEventListener("DOMContentLoaded", (event) => {
585558
ge("fixedEcefX").disabled = true;
586559
ge("fixedEcefY").disabled = true;
587560
ge("fixedEcefZ").disabled = true;
588-
//Disable Geodetic inputs
561+
//Disable Geographic inputs
589562
ge("fixedLat").disabled = false;
590563
ge("fixedLong").disabled = false;
591564
ge("fixedAltitude").disabled = false;
@@ -600,7 +573,7 @@ document.addEventListener("DOMContentLoaded", (event) => {
600573
ge("fixedEcefX").disabled = false;
601574
ge("fixedEcefY").disabled = false;
602575
ge("fixedEcefZ").disabled = false;
603-
//Disable Geodetic inputs
576+
//Disable Geographic inputs
604577
ge("fixedLat").disabled = true;
605578
ge("fixedLong").disabled = true;
606579
ge("fixedAltitude").disabled = true;
@@ -610,7 +583,7 @@ document.addEventListener("DOMContentLoaded", (event) => {
610583
ge("fixedEcefX").disabled = true;
611584
ge("fixedEcefY").disabled = true;
612585
ge("fixedEcefZ").disabled = true;
613-
//Disable Geodetic inputs
586+
//Disable Geographic inputs
614587
ge("fixedLat").disabled = false;
615588
ge("fixedLong").disabled = false;
616589
ge("fixedAltitude").disabled = false;
@@ -624,7 +597,7 @@ document.addEventListener("DOMContentLoaded", (event) => {
624597
ge("fixedEcefX").disabled = true;
625598
ge("fixedEcefY").disabled = true;
626599
ge("fixedEcefZ").disabled = true;
627-
//Enable Geodetic inputs
600+
//Enable Geographic inputs
628601
ge("fixedLat").disabled = false;
629602
ge("fixedLong").disabled = false;
630603
ge("fixedAltitude").disabled = false;
@@ -634,7 +607,7 @@ document.addEventListener("DOMContentLoaded", (event) => {
634607
ge("fixedEcefX").disabled = false;
635608
ge("fixedEcefY").disabled = false;
636609
ge("fixedEcefZ").disabled = false;
637-
//Disable Geodetic inputs
610+
//Disable Geographic inputs
638611
ge("fixedLat").disabled = true;
639612
ge("fixedLong").disabled = true;
640613
ge("fixedAltitude").disabled = true;
@@ -684,25 +657,6 @@ document.addEventListener("DOMContentLoaded", (event) => {
684657
}
685658
});
686659

687-
//Enable the check box
688-
ge("firmwareFile0").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
689-
ge("firmwareFile1").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
690-
ge("firmwareFile2").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
691-
ge("firmwareFile3").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
692-
ge("firmwareFile4").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
693-
ge("firmwareFile5").addEventListener("change", function () { ge("enableFirmwareUpdate").disabled = false; });
694-
695-
ge("enableFirmwareUpdate").addEventListener("change", function () {
696-
if (ge("enableFirmwareUpdate").checked) {
697-
//Enable button
698-
ge("firmwareUpdate").disabled = false;
699-
}
700-
else {
701-
//Disable button
702-
ge("firmwareUpdate").disabled = true;
703-
}
704-
});
705-
706660
ge("dataPortChannel").addEventListener("change", function () {
707661
if (ge("dataPortChannel").value == 0) {
708662
show("dataPortBaudDropdown");
@@ -1865,9 +1819,8 @@ static const char *index_html = R"=====(
18651819
</div>
18661820
<div class="col-sm-7 col-6 mt-2">
18671821
<div id="uploadNewFirmwareDiv" class="mb-2">
1868-
<label class="form-check-label" for="uploadNewFirmware">Add Firmware:</label>
1869-
<span class="tt" data-bs-placement="right"
1870-
title="New firmware may be uploaded via WiFi to the SD card. Firmware is only loaded to the SD card and must then be loaded to the unit.">
1822+
<label class="form-check-label" for="uploadNewFirmware">Update Firmware:</label>
1823+
<span class="tt" data-bs-placement="right" title="Update the unit's firmware over WiFi.">
18711824
<span class="icon-info-circle text-primary ms-2"></span>
18721825
</span>
18731826
<form id="uploadNewFirmware" enctype="multipart/form-data" method="post" action="/upload">
@@ -1896,7 +1849,8 @@ static const char *index_html = R"=====(
18961849
<p id="saveBtnSuccess" class="inlineSuccess"></p>
18971850
</div>
18981851
<div align="center" class="col-sm-5 col-12">
1899-
<button type="button" id="exitBtn" class="btn btn-outline-secondary" onclick="exitConfig()">Exit and Reset<span class="icon-remove text-secondary ms-1"></span></button>
1852+
<button type="button" id="exitBtn" class="btn btn-outline-secondary" onclick="exitConfig()">Exit and
1853+
Reset<span class="icon-remove text-secondary ms-1"></span></button>
19001854
<p id="exitBtnError" class="inlineSuccess"></p>
19011855
<p>&nbsp;</p>
19021856
</div>

0 commit comments

Comments
 (0)