From c29fa6d5d144c0c0e31dd3e32e1b2216b063a2d8 Mon Sep 17 00:00:00 2001 From: AndyMt Date: Sat, 17 Feb 2024 18:16:41 +0100 Subject: [PATCH 1/5] Added OTA update via WiFi and FPGA update via SD card. --- .gitignore | 7 ++ Controller/Controller.ino | 218 ++++++++++++++++++++++++++++++-------- README.md | 19 +++- 3 files changed, 199 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 259148f..8b4d23e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,10 @@ *.exe *.out *.app + +Controller/build/*.* +Controller/build/esp32.esp32.esp32s3/Controller.ino.bin +Controller/build/esp32.esp32.esp32s3/Controller.ino.bootloader.bin +Controller/build/esp32.esp32.esp32s3/Controller.ino.elf +Controller/build/esp32.esp32.esp32s3/Controller.ino.map +Controller/build/esp32.esp32.esp32s3/Controller.ino.partitions.bin diff --git a/Controller/Controller.ino b/Controller/Controller.ino index f526a4a..605092e 100644 --- a/Controller/Controller.ino +++ b/Controller/Controller.ino @@ -13,16 +13,24 @@ #include #include #include "flashmem.h" +#include "esp_partition.h" #include #include #include + +#include +#include +#include + #include "ESPIcialWebDAV.h" +#define VERSION "VERA ESPIcial V1.0.0" #define HOSTNAME "X16WebDAV" #define AP_NAME "X16Connect" #define AP_PASSWORD "12345678" #define RESET_FILE "/RESETWIFI" +#define VERA_FILE "/VERA.BIN" #define ESP_BUILTIN_LED 2 @@ -56,6 +64,9 @@ void switchToESP(); FS& gfs = SD; //WiFiServerSecure tcp(443); // ToDo: try https WiFiServer tcp(80); + +AsyncWebServer server(8080); + ESPIcialWebDAV dav; uint32_t startTimeoutSD = 0; @@ -226,6 +237,22 @@ void setupWiFi() { Serial.println("connected...yeey :)"); } + + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { + request->send(200, "text/plain", VERSION); + }); + +} + +//--------------------------------------------------------------------- +// Setup OTA update +//--------------------------------------------------------------------- +void setupOTA() +{ + AsyncElegantOTA.setID(VERSION); + AsyncElegantOTA.begin(&server); // Start ElegantOTA + server.begin(); + Serial.println("HTTP server started"); } //--------------------------------------------------------------------- @@ -269,6 +296,15 @@ void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(ESP_BUILTIN_LED, OUTPUT); + // setup WiFi + setupWiFi(); + + // setup SebDAV access + setupWebDav(); + + // setup SebDAV access + setupOTA(); + // show reset is done ENABLE_FPGA_CFG(); digitalWrite(ESP_FPGA_RESET, 0); @@ -289,8 +325,8 @@ void setup() { // variables for FPGA binary transfer uint8_t header_bytes_read = 0; uint8_t magic; -uint16_t transfer_size; -uint16_t bytes_transferred = 0; +uint32_t transfer_size; +uint32_t bytes_transferred = 0; //--------------------------------------------------------------------- // switches SD card access to ESP, start timeout to switch back to FPGA @@ -319,49 +355,10 @@ void switchToX16() } //--------------------------------------------------------------------- -// main loop +// handle serial fpga upload //--------------------------------------------------------------------- -void loop() +void handleSerialUploadFPGA() { - uint8_t isX16SD = digitalRead(FPGA_SD_EN); // who is in control of the SD card? - - if (fpga_configured) - { - dav.handleClient(); - - // switch back SD card to FPGA when timeout is due - if (startTimeoutSD - && millis()-startTimeoutSD > 5000 - && !isX16SD) - switchToX16(); - } - - uint8_t cur_fpga_creset = digitalRead(FPGA_CRESET_B); - - if (cur_fpga_creset == 0 && last_fpga_creset == 1) - { - Serial.println("ENABLE_FPGA_CFG()"); - // Reset was just asserted - // Make sure that FPGA SPI bus is connected to config flash - fpga_configured = 0; - ENABLE_FPGA_CFG(); - } else if (cur_fpga_creset == 1 && fpga_configured == 0 && digitalRead(FPGA_CDONE) == 1) { - // FPGA has finished configuration, switch SD card access to SD card - fpga_configured = 1; - - // setup WiFi - setupWiFi(); - - // setup SebDAV access - setupWebDav(); - - // give sd card control to X16 - ENABLE_FPGA_SD(); - switchToX16(); - Serial.println("Init done"); - - } - // // serial management, for uploading FPGA binary // @@ -411,6 +408,141 @@ void loop() } } } +} + + +//--------------------------------------------------------------------- +// handle file based fpga upload. Checks for file "VERA.BIN" +//--------------------------------------------------------------------- +void handleFileUploadFPGA() +{ + char buffer[256]; + + // checking for a vera binary + Serial.println("Checking for VERA update..."); + switchToESP(); + + // no VERA.BIN file? then skip this + if (!gfs.exists(VERA_FILE)) + return; + + Serial.println("VERA.BIN found. Flashing to FPGA"); + + // setup flashing FPGA via SPI + digitalWrite(FPGA_CFG_EN, 0); // Disable communication between FPGA and Flash + spi_begin(); + + cfg_spi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0)); + digitalWrite(cfg_spi->pinSS(), LOW); + + bytes_transferred = 0; + + // open vera binary + switchToESP(); + File f = gfs.open(VERA_FILE); + + transfer_size = f.size(); + sprintf(buffer, "Vera file size: %d Bytes", transfer_size); + Serial.println(buffer); + + // transfer file + while(bytes_transferred < transfer_size) + { + uint8_t len = f.readBytes(buffer, 64); + if (len <= 0) + { + sprintf(buffer, "flashed %d", bytes_transferred); + Serial.println(buffer); + Serial.println("EOF?"); + break; + } + + for (int n=0; ntransfer(buffer[n]); + } + digitalWrite(ESP_BUILTIN_LED, (bytes_transferred & 0x200) == 0 ? 0 : 1); + bytes_transferred += len; + + delay(10); + if (bytes_transferred % 1024 == 0) + Serial.print("."); + } + + Serial.println(""); + sprintf(buffer, "flashed %d", bytes_transferred); + Serial.println(buffer); + + // cleanup + f.close(); + gfs.remove(VERA_FILE); + + // ending spi transfer + digitalWrite(cfg_spi->pinSS(), HIGH); + cfg_spi->endTransaction(); + + // reset VERA + Serial.println("Resetting FPGA"); + digitalWrite(FPGA_CFG_EN, 1); // Enable communication between FPGA and Flash + digitalWrite(ESP_FPGA_RESET, 0); + digitalWrite(ESP_BUILTIN_LED, 1); + delay(250); + digitalWrite(ESP_BUILTIN_LED, 0); + digitalWrite(ESP_FPGA_RESET, 1); + + digitalWrite(ESP_BUILTIN_LED, 0); + // Release SPI bus + spi_end(); + +} + +//--------------------------------------------------------------------- +// main loop +//--------------------------------------------------------------------- +void loop() +{ + uint8_t isX16SD = digitalRead(FPGA_SD_EN); // who is in control of the SD card? + uint8_t cur_fpga_creset = digitalRead(FPGA_CRESET_B); + + //if (fpga_configured) + dav.handleClient(); + + // switch back SD card to FPGA when timeout is due + if (startTimeoutSD + && millis()-startTimeoutSD > 5000 + && !isX16SD) + switchToX16(); + + if (cur_fpga_creset == 0 && last_fpga_creset == 1) + { + // Reset was just asserted + // Make sure that FPGA SPI bus is connected to config flash + fpga_configured = 0; + ENABLE_FPGA_CFG(); + } else if (cur_fpga_creset == 1 && fpga_configured == 0 && digitalRead(FPGA_CDONE) == 1) { + // FPGA has finished configuration, switch SD card access to SD card + fpga_configured = 1; + + /*// setup WiFi + setupWiFi(); + + // setup SebDAV access + setupWebDav(); + + // setup SebDAV access + setupOTA(); +*/ + handleFileUploadFPGA(); + + // give sd card control to X16 + switchToX16(); + Serial.println("Init done"); + + + } + + // handle serial upload to FPGA + handleSerialUploadFPGA(); // make led blink digitalWrite(ESP_BUILTIN_LED, (millis() & 0x200) == 0 ? 0 : 1); diff --git a/README.md b/README.md index 4d8cde5..00385d5 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,26 @@ Once the ESP32 board is added to Arduino, use these settings for building the fi Press the checkmark button on the Arduino IDE to build the firmware. This may take a few minutes to complete. -### Updating the ESP32 Firmware +### Connecting the ESPIcial to your WiFi + +If no WiFi credentials are configured the ESPIcial will create a temporary AP for 60 seconds namend "X16Connect" and provide a captive portal. There you can select your WiFi AP and enter the password. Be aware that the portal is not encrypted, but the credentials will be, once connected. +If you want to reset credentials or connect to a different network, create a file named "RESETWIFI" in the root folder of the SD card. +At each reset the ESPIcial checks for this file and if found, delete credentials and create the temporary AP again. + +### Updating the ESP32 Firmware via OTA + +The ESP32 Firmware can be updated via WiFi by connecting to http://x16webdav:8080/update and uploading a compiled sketch in binary form. + +### Updating the FPGA Firmware via SD card + +You can place a file named VERA.BIN in the root folder of the SD card. At each reset the ESPIcial checks if this file exists and updates the FPGA. +The LED is blinking quickly during this time. + +### Updating the ESP32 Firmware via Arduino IDE The ESP32 Firmware can be updated directly from the Arduino IDE by pressing the "Upload" button. -### Updating the FPGA Firmware +### Updating the FPGA Firmware via serial The ESP32 Firmware contains an interface that allows the FPGA bitstream to be updated over the USB C serial interface. A Python script, `espi_update_fpga.py` is included here to facilitate From 920631d84b9ce93355e2c7cbe7f930717473bbba Mon Sep 17 00:00:00 2001 From: AndyMt Date: Sat, 17 Feb 2024 18:25:14 +0100 Subject: [PATCH 2/5] Updates to readme --- .gitignore | 5 ----- README.md | 5 ++++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 8b4d23e..8c05a2b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,8 +32,3 @@ *.app Controller/build/*.* -Controller/build/esp32.esp32.esp32s3/Controller.ino.bin -Controller/build/esp32.esp32.esp32s3/Controller.ino.bootloader.bin -Controller/build/esp32.esp32.esp32s3/Controller.ino.elf -Controller/build/esp32.esp32.esp32s3/Controller.ino.map -Controller/build/esp32.esp32.esp32s3/Controller.ino.partitions.bin diff --git a/README.md b/README.md index 00385d5..2c11e29 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,10 @@ and retro enthusiasts to add to their own designs. Key features of the ESPIcial include: -* Easy update interface for both ESP32 and FPGA through USB C connector +* Easy WebDAV access to the SD card via WiFi +* OTA capability for the ESP32 firmware via WiFi +* Update via SD card for FPGA +* Backup update interface for ESP32 and FPGA through USB C connector via serial * Supports all video and audio features of the original VERA * 640x480 @60Hz Resolution * Video output From cefeb38e8c1f7eb8b6812ff6337df739eff12959 Mon Sep 17 00:00:00 2001 From: AndyMt Date: Sun, 18 Feb 2024 15:43:20 +0100 Subject: [PATCH 3/5] Updated readme --- README.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2c11e29..81e5523 100644 --- a/README.md +++ b/README.md @@ -61,18 +61,31 @@ Once the ESP32 board is added to Arduino, use these settings for building the fi ### Building Firmware -Press the checkmark button on the Arduino IDE to build the firmware. This may take a few -minutes to complete. +Install the following libraries: + * WiFiMulti_Generic + * WiFiManager + * MDNS_Generic + * ESPAsyncTCP + * ESPAsyncWebCerver + * AsyncElegantOTA +Press the checkmark button on the Arduino IDE to build the firmware. This may take a few minutes to complete. ### Connecting the ESPIcial to your WiFi +Make sure the X16 is powered on and USB-C on the ESPIcial is NOT connected! If no WiFi credentials are configured the ESPIcial will create a temporary AP for 60 seconds namend "X16Connect" and provide a captive portal. There you can select your WiFi AP and enter the password. Be aware that the portal is not encrypted, but the credentials will be, once connected. If you want to reset credentials or connect to a different network, create a file named "RESETWIFI" in the root folder of the SD card. -At each reset the ESPIcial checks for this file and if found, delete credentials and create the temporary AP again. +At each reset the ESPIcial checks for this file and if found, deletes credentials and creates the temporary AP again for 60 seconds. + +### Using WebDAV + +Connect your webdav client to http://x16webdav. Mount share via file explorer on Windows 10+ or various options on Linux. +This will give you direct access to the SD card via WiFi. Control of the SD card is shared with the X16. With every request via WebDAV the ESPIcial will get the SD card exclusively for at least 5 seconds. Each request within that time will extend access by 5 seconds. So 5 seconds after the last request control of the SD card is returned to the X16. +While the ESPIcial has control over the SD card the X16 won't see the SD card and any file access will end with a "device not present" error. ### Updating the ESP32 Firmware via OTA -The ESP32 Firmware can be updated via WiFi by connecting to http://x16webdav:8080/update and uploading a compiled sketch in binary form. +The ESP32 Firmware can be updated via WiFi by connecting to http://x16webdav:8080/update and uploading a sketch in compiled binary form. ### Updating the FPGA Firmware via SD card @@ -93,4 +106,4 @@ Obtain a VERA firmware and execute the following: `python espi_update_fpga.py /dev/ttyS3 ~/vera.bin` -Replace `/dev/ttyS3` with the path to the serial port device on your computer (could be `COM3` on Windows) and replace `~/vera.bin` with the path to the VERA bitstream. +Replace `/dev/ttyS3` with the path to the serial port device on your computer (could be `COMx` on Windows) and replace `~/vera.bin` with the path to the VERA bitstream. From 0dea371228d18e8c841d0cbdd464196904ecaea4 Mon Sep 17 00:00:00 2001 From: AndyMt Date: Sun, 18 Feb 2024 15:46:12 +0100 Subject: [PATCH 4/5] Readme updates --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 81e5523..8874b71 100644 --- a/README.md +++ b/README.md @@ -74,13 +74,16 @@ Press the checkmark button on the Arduino IDE to build the firmware. This may ta Make sure the X16 is powered on and USB-C on the ESPIcial is NOT connected! If no WiFi credentials are configured the ESPIcial will create a temporary AP for 60 seconds namend "X16Connect" and provide a captive portal. There you can select your WiFi AP and enter the password. Be aware that the portal is not encrypted, but the credentials will be, once connected. + If you want to reset credentials or connect to a different network, create a file named "RESETWIFI" in the root folder of the SD card. At each reset the ESPIcial checks for this file and if found, deletes credentials and creates the temporary AP again for 60 seconds. ### Using WebDAV Connect your webdav client to http://x16webdav. Mount share via file explorer on Windows 10+ or various options on Linux. + This will give you direct access to the SD card via WiFi. Control of the SD card is shared with the X16. With every request via WebDAV the ESPIcial will get the SD card exclusively for at least 5 seconds. Each request within that time will extend access by 5 seconds. So 5 seconds after the last request control of the SD card is returned to the X16. + While the ESPIcial has control over the SD card the X16 won't see the SD card and any file access will end with a "device not present" error. ### Updating the ESP32 Firmware via OTA @@ -98,9 +101,7 @@ The ESP32 Firmware can be updated directly from the Arduino IDE by pressing the ### Updating the FPGA Firmware via serial -The ESP32 Firmware contains an interface that allows the FPGA bitstream to be updated over -the USB C serial interface. A Python script, `espi_update_fpga.py` is included here to facilitate -this. The script requires PySerial to communicate with the ESP32 firmware. +The ESP32 Firmware contains an interface that allows the FPGA bitstream to be updated over the USB C serial interface. A Python script, `espi_update_fpga.py` is included here to facilitate this. The script requires PySerial to communicate with the ESP32 firmware. Obtain a VERA firmware and execute the following: From 8e61fbc3a61b571f1dbb1e1eebd82c0fc9c5e1f9 Mon Sep 17 00:00:00 2001 From: AndyMt Date: Sun, 18 Feb 2024 16:27:14 +0100 Subject: [PATCH 5/5] Preparation for password protected OTA portal --- Controller/Controller.ino | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Controller/Controller.ino b/Controller/Controller.ino index 605092e..d277bf3 100644 --- a/Controller/Controller.ino +++ b/Controller/Controller.ino @@ -25,10 +25,12 @@ #include "ESPIcialWebDAV.h" -#define VERSION "VERA ESPIcial V1.0.0" +#define VERSION "VERA ESPIcial V1.0.1" #define HOSTNAME "X16WebDAV" #define AP_NAME "X16Connect" #define AP_PASSWORD "12345678" +#define UP_NAME "X16Update" +#define UP_PASSWORD "12345678" #define RESET_FILE "/RESETWIFI" #define VERA_FILE "/VERA.BIN" @@ -250,9 +252,10 @@ void setupWiFi() { void setupOTA() { AsyncElegantOTA.setID(VERSION); - AsyncElegantOTA.begin(&server); // Start ElegantOTA + AsyncElegantOTA.begin(&server); // Start ElegantOTA without username/password + //AsyncElegantOTA.begin(&server, UP_NAME, UP_PASSWORD); // Start ElegantOTA with username/password server.begin(); - Serial.println("HTTP server started"); + Serial.println("Update server started"); } //---------------------------------------------------------------------