├── .DS_Store ├── .gitattributes ├── ESP32 ├── src │ └── ESPSerialFlasher │ │ ├── extras │ │ ├── NINAFW.BIN │ │ ├── roots.bin │ │ ├── README.TXT │ │ └── nullTermRootsPem.py │ │ ├── img │ │ └── DownloadAndFlash.png │ │ ├── library.properties │ │ ├── keywords.txt │ │ ├── src │ │ ├── md5_hash.h │ │ ├── ESPSerialFlasher.h │ │ ├── esp_targets.h │ │ ├── serial_comm.h │ │ ├── serial_io.h │ │ ├── serial_comm_prv.h │ │ ├── esp_targets.c │ │ ├── esp_loader.h │ │ └── md5_hash.c │ │ ├── .github │ │ └── workflows │ │ │ ├── check-arduino.yml │ │ │ ├── report-size-deltas.yml │ │ │ └── compile-examples.yml │ │ ├── examples │ │ ├── DownloadLatestFW │ │ │ ├── arduino_secrets.h │ │ │ ├── wifi_functions.h │ │ │ ├── SDUpdate.h │ │ │ ├── DownloadLatestFW.ino │ │ │ └── JustHTTPClient.h │ │ ├── EspFlasher │ │ │ └── EspFlasher.ino │ │ ├── FlashRootCerts │ │ │ └── FlashRootCerts.ino │ │ └── FlashRootCertsNoSDCard │ │ │ └── FlashRootCertsNoSDCard.ino │ │ ├── README.md │ │ ├── CODE_OF_CONDUCT.md │ │ └── LICENSE ├── debug_custom.json ├── debug.cfg ├── flashing.ino ├── ESP32.ino ├── configFIle.ino └── SDcard.ino ├── ESP8266 ├── src │ └── ESPSerialFlasher │ │ ├── extras │ │ ├── roots.bin │ │ ├── NINAFW.BIN │ │ ├── README.TXT │ │ └── nullTermRootsPem.py │ │ ├── img │ │ └── DownloadAndFlash.png │ │ ├── library.properties │ │ ├── keywords.txt │ │ ├── src │ │ ├── md5_hash.h │ │ ├── ESPSerialFlasher.h │ │ ├── esp_targets.h │ │ ├── serial_comm.h │ │ ├── serial_io.h │ │ ├── serial_comm_prv.h │ │ ├── esp_targets.c │ │ ├── esp_loader.h │ │ └── md5_hash.c │ │ ├── .github │ │ └── workflows │ │ │ ├── check-arduino.yml │ │ │ ├── report-size-deltas.yml │ │ │ └── compile-examples.yml │ │ ├── examples │ │ ├── DownloadLatestFW │ │ │ ├── arduino_secrets.h │ │ │ ├── wifi_functions.h │ │ │ ├── SDUpdate.h │ │ │ ├── DownloadLatestFW.ino │ │ │ └── JustHTTPClient.h │ │ ├── EspFlasher │ │ │ └── EspFlasher.ino │ │ ├── FlashRootCerts │ │ │ └── FlashRootCerts.ino │ │ └── FlashRootCertsNoSDCard │ │ │ └── FlashRootCertsNoSDCard.ino │ │ ├── README.md │ │ ├── CODE_OF_CONDUCT.md │ │ └── LICENSE ├── debug_custom.json ├── debug.cfg ├── ESP8266.ino ├── flashing.ino └── sdcard.ino └── config.txt /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/ESP-Offline-Programmer/HEAD/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/extras/NINAFW.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/ESP-Offline-Programmer/HEAD/ESP32/src/ESPSerialFlasher/extras/NINAFW.BIN -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/extras/roots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/ESP-Offline-Programmer/HEAD/ESP32/src/ESPSerialFlasher/extras/roots.bin -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/extras/roots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/ESP-Offline-Programmer/HEAD/ESP8266/src/ESPSerialFlasher/extras/roots.bin -------------------------------------------------------------------------------- /config.txt: -------------------------------------------------------------------------------- 1 | bootNameOffset=0xe000 2 | bootloaderNameOffset=0x1000 3 | partitionsNameOffset=0x8000 4 | firmwareNameOffset=0x10000 5 | spiffsNameOffset=0x3D0000 -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/extras/NINAFW.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/ESP-Offline-Programmer/HEAD/ESP8266/src/ESPSerialFlasher/extras/NINAFW.BIN -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/img/DownloadAndFlash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/ESP-Offline-Programmer/HEAD/ESP32/src/ESPSerialFlasher/img/DownloadAndFlash.png -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/img/DownloadAndFlash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techiesms/ESP-Offline-Programmer/HEAD/ESP8266/src/ESPSerialFlasher/img/DownloadAndFlash.png -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/extras/README.TXT: -------------------------------------------------------------------------------- 1 | NINAFW.BIN is stock firmware binary for u-blox w102 module 2 | 3 | roots.pem is certificates that comebwith wifinina library, you can add your own personal certificates to this file and run 4 | nullTermRootsPem.py to create a null terminated bin file (roots.bin) suitable to flash to your wifi module from your sd card 5 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/extras/README.TXT: -------------------------------------------------------------------------------- 1 | NINAFW.BIN is stock firmware binary for u-blox w102 module 2 | 3 | roots.pem is certificates that comebwith wifinina library, you can add your own personal certificates to this file and run 4 | nullTermRootsPem.py to create a null terminated bin file (roots.bin) suitable to flash to your wifi module from your sd card 5 | -------------------------------------------------------------------------------- /ESP32/debug_custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"Arduino on ESP32", 3 | "toolchainPrefix":"xtensa-esp32-elf", 4 | "svdFile":"esp32.svd", 5 | "request":"attach", 6 | "postAttachCommands":[ 7 | "set remote hardware-watchpoint-limit 2", 8 | "monitor reset halt", 9 | "monitor gdb_sync", 10 | "thb setup", 11 | "c" 12 | ], 13 | "overrideRestartCommands":[ 14 | "monitor reset halt", 15 | "monitor gdb_sync", 16 | "thb setup", 17 | "c" 18 | ] 19 | } -------------------------------------------------------------------------------- /ESP8266/debug_custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"Arduino on ESP32", 3 | "toolchainPrefix":"xtensa-esp32-elf", 4 | "svdFile":"esp32.svd", 5 | "request":"attach", 6 | "postAttachCommands":[ 7 | "set remote hardware-watchpoint-limit 2", 8 | "monitor reset halt", 9 | "monitor gdb_sync", 10 | "thb setup", 11 | "c" 12 | ], 13 | "overrideRestartCommands":[ 14 | "monitor reset halt", 15 | "monitor gdb_sync", 16 | "thb setup", 17 | "c" 18 | ] 19 | } -------------------------------------------------------------------------------- /ESP32/debug.cfg: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | # 3 | # Example OpenOCD configuration file for ESP32-WROVER-KIT board. 4 | # 5 | # For example, OpenOCD can be started for ESP32 debugging on 6 | # 7 | # openocd -f board/esp32-wrover-kit-3.3v.cfg 8 | # 9 | 10 | # Source the JTAG interface configuration file 11 | source [find interface/ftdi/esp32_devkitj_v1.cfg] 12 | set ESP32_FLASH_VOLTAGE 3.3 13 | # Source the ESP32 configuration file 14 | source [find target/esp32.cfg] 15 | -------------------------------------------------------------------------------- /ESP8266/debug.cfg: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-or-later 2 | # 3 | # Example OpenOCD configuration file for ESP32-WROVER-KIT board. 4 | # 5 | # For example, OpenOCD can be started for ESP32 debugging on 6 | # 7 | # openocd -f board/esp32-wrover-kit-3.3v.cfg 8 | # 9 | 10 | # Source the JTAG interface configuration file 11 | source [find interface/ftdi/esp32_devkitj_v1.cfg] 12 | set ESP32_FLASH_VOLTAGE 3.3 13 | # Source the ESP32 configuration file 14 | source [find target/esp32.cfg] 15 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/library.properties: -------------------------------------------------------------------------------- 1 | name=ESPSerialFlasher 2 | version=0.1.7 3 | author=Winner10920 4 | maintainer=Winner10920 5 | sentence=[EXPERIMENTAL] Flash the WiFiNiNa module on your arduino nano 33 iot 6 | paragraph= with the newest nina-fw version or even your own, just make sure the firmware is good first! 7 | category=Other 8 | url=https://github.com/winner10920/ESPSerialFlasher 9 | architectures=esp32 10 | depends=SD 11 | includes=ESPSerialFlasher.h 12 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/library.properties: -------------------------------------------------------------------------------- 1 | name=ESPSerialFlasher 2 | version=0.1.7 3 | author=Winner10920 4 | maintainer=Winner10920 5 | sentence=[EXPERIMENTAL] Flash the WiFiNiNa module on your arduino nano 33 iot 6 | paragraph= with the newest nina-fw version or even your own, just make sure the firmware is good first! 7 | category=Other 8 | url=https://github.com/winner10920/ESPSerialFlasher 9 | architectures=esp32 10 | depends=SD 11 | includes=ESPSerialFlasher.h 12 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For ESPSerialFlasher 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | ESPFlasherInit KEYWORD2 16 | ESPFlasherConnect KEYWORD2 17 | ESPFlashBin KEYWORD2 18 | ESPFlashCert KEYWORD2 19 | greenLED KEYWORD2 -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For ESPSerialFlasher 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | ESPFlasherInit KEYWORD2 16 | ESPFlasherConnect KEYWORD2 17 | ESPFlashBin KEYWORD2 18 | ESPFlashCert KEYWORD2 19 | greenLED KEYWORD2 -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/md5_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MD5 hash implementation and interface functions 3 | * Copyright (c) 2003-2005, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | struct MD5Context { 17 | uint32_t buf[4]; 18 | uint32_t bits[2]; 19 | uint8_t in[64]; 20 | }; 21 | 22 | void MD5InitESP(struct MD5Context *context); 23 | void MD5UpdateESP(struct MD5Context *context, unsigned char const *buf, unsigned len); 24 | void MD5FinalESP(unsigned char digest[16], struct MD5Context *context); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/md5_hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MD5 hash implementation and interface functions 3 | * Copyright (c) 2003-2005, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | struct MD5Context { 17 | uint32_t buf[4]; 18 | uint32_t bits[2]; 19 | uint8_t in[64]; 20 | }; 21 | 22 | void MD5InitESP(struct MD5Context *context); 23 | void MD5UpdateESP(struct MD5Context *context, unsigned char const *buf, unsigned len); 24 | void MD5FinalESP(unsigned char digest[16], struct MD5Context *context); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/extras/nullTermRootsPem.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys; 4 | import os 5 | 6 | 7 | __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) 8 | certsData = open(os.path.join(__location__,"roots.pem"), "rb").read() 9 | 10 | # calculate the output binary size, app offset 11 | outputSize = 0x20000 12 | outputData = bytearray(b'\xff') * outputSize 13 | 14 | for i in range(0, len(certsData)): 15 | outputData[i] = certsData[i] 16 | 17 | # zero terminate the pem file 18 | outputData[len(certsData)] = 0 19 | 20 | outputFilename = "roots.bin" 21 | if (len(sys.argv) > 1): 22 | outputFilename = sys.argv[1] 23 | 24 | # write out 25 | with open(outputFilename,"w+b") as f: 26 | f.seek(0) 27 | f.write(outputData) 28 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/extras/nullTermRootsPem.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys; 4 | import os 5 | 6 | 7 | __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) 8 | certsData = open(os.path.join(__location__,"roots.pem"), "rb").read() 9 | 10 | # calculate the output binary size, app offset 11 | outputSize = 0x20000 12 | outputData = bytearray(b'\xff') * outputSize 13 | 14 | for i in range(0, len(certsData)): 15 | outputData[i] = certsData[i] 16 | 17 | # zero terminate the pem file 18 | outputData[len(certsData)] = 0 19 | 20 | outputFilename = "roots.bin" 21 | if (len(sys.argv) > 1): 22 | outputFilename = sys.argv[1] 23 | 24 | # write out 25 | with open(outputFilename,"w+b") as f: 26 | f.seek(0) 27 | f.write(outputData) 28 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/.github/workflows/check-arduino.yml: -------------------------------------------------------------------------------- 1 | name: Check Arduino 2 | 3 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows 4 | on: 5 | push: 6 | pull_request: 7 | schedule: 8 | # Run every Tuesday at 8 AM UTC to catch breakage caused by new rules added to Arduino Lint. 9 | - cron: "0 8 * * TUE" 10 | workflow_dispatch: 11 | repository_dispatch: 12 | 13 | jobs: 14 | lint: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v2 20 | 21 | - name: Arduino Lint 22 | uses: arduino/arduino-lint-action@v1 23 | with: 24 | library-manager: update 25 | compliance: strict 26 | project-type: library 27 | 28 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/.github/workflows/check-arduino.yml: -------------------------------------------------------------------------------- 1 | name: Check Arduino 2 | 3 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows 4 | on: 5 | push: 6 | pull_request: 7 | schedule: 8 | # Run every Tuesday at 8 AM UTC to catch breakage caused by new rules added to Arduino Lint. 9 | - cron: "0 8 * * TUE" 10 | workflow_dispatch: 11 | repository_dispatch: 12 | 13 | jobs: 14 | lint: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v2 20 | 21 | - name: Arduino Lint 22 | uses: arduino/arduino-lint-action@v1 23 | with: 24 | library-manager: update 25 | compliance: strict 26 | project-type: library 27 | 28 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/ESPSerialFlasher.h: -------------------------------------------------------------------------------- 1 | #ifndef ESP_FLASHER_H 2 | #define ESP_FLASHER_H 3 | 4 | #include "serial_io.h" 5 | 6 | #include "Arduino.h" 7 | #include "SD.h" 8 | 9 | 10 | extern Print *ESPDebugPort; 11 | extern bool _ESPDebug; 12 | 13 | 14 | void ESPFlasherInit(bool _debug = false, Print *_debugPort = &Serial ); 15 | bool ESPFlasherConnect(); 16 | bool ESPFlashBin(const char* binFilename, unsigned long startAddress); 17 | void ESPFlashCert(const char* certFilename); 18 | void ESPFlashCertFromMemory(const char* Certificates, unsigned long size); 19 | 20 | 21 | esp_loader_error_t connect_to_target(uint32_t higher_baudrate); 22 | esp_loader_error_t flash_binary(File file, size_t size, unsigned long address); 23 | esp_loader_error_t flash_binary_from_memory(const uint8_t *bin, size_t size, size_t address); 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/ESPSerialFlasher.h: -------------------------------------------------------------------------------- 1 | #ifndef ESP_FLASHER_H 2 | #define ESP_FLASHER_H 3 | 4 | #include "serial_io.h" 5 | 6 | #include "Arduino.h" 7 | #include "SD.h" 8 | 9 | 10 | extern Print *ESPDebugPort; 11 | extern bool _ESPDebug; 12 | 13 | 14 | void ESPFlasherInit(bool _debug = false, Print *_debugPort = &Serial ); 15 | bool ESPFlasherConnect(); 16 | bool ESPFlashBin(const char* binFilename, unsigned long startAddress); 17 | void ESPFlashCert(const char* certFilename); 18 | void ESPFlashCertFromMemory(const char* Certificates, unsigned long size); 19 | 20 | 21 | esp_loader_error_t connect_to_target(uint32_t higher_baudrate); 22 | esp_loader_error_t flash_binary(File file, size_t size, unsigned long address); 23 | esp_loader_error_t flash_binary_from_memory(const uint8_t *bin, size_t size, size_t address); 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/DownloadLatestFW/arduino_secrets.h: -------------------------------------------------------------------------------- 1 | #ifndef _SECRETS_ 2 | #define _SECRETS_ 3 | #define SECRET_SSID "" //enter Wifi Name here 4 | #define SECRET_PASS "" //enter Wifi password here 5 | 6 | bool DEBUG = false; //change to false to not get any debug messages from the additional pages 7 | Print *debugPort = &Serial; //change to change where debug messages go, could be any Print class inheritor, e.g Serial, Serial1, WifiClient, (*untested* Sd file) 8 | 9 | 10 | 11 | unsigned long HTTPResponseTime = 10000; //timer for how long to wait for the http response 12 | 13 | #define SDCARD_SS_PIN 10 //pin hooked up to the sd card 14 | 15 | 16 | const char DEVICE[]= "Arduino NANO 33 IoT";//inserted as user agent for the http request 17 | 18 | 19 | 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/DownloadLatestFW/arduino_secrets.h: -------------------------------------------------------------------------------- 1 | #ifndef _SECRETS_ 2 | #define _SECRETS_ 3 | #define SECRET_SSID "" //enter Wifi Name here 4 | #define SECRET_PASS "" //enter Wifi password here 5 | 6 | bool DEBUG = false; //change to false to not get any debug messages from the additional pages 7 | Print *debugPort = &Serial; //change to change where debug messages go, could be any Print class inheritor, e.g Serial, Serial1, WifiClient, (*untested* Sd file) 8 | 9 | 10 | 11 | unsigned long HTTPResponseTime = 10000; //timer for how long to wait for the http response 12 | 13 | #define SDCARD_SS_PIN 10 //pin hooked up to the sd card 14 | 15 | 16 | const char DEVICE[]= "Arduino NANO 33 IoT";//inserted as user agent for the http request 17 | 18 | 19 | 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/.github/workflows/report-size-deltas.yml: -------------------------------------------------------------------------------- 1 | name: Report Size Deltas 2 | 3 | on: 4 | push: 5 | paths: 6 | - ".github/workflows/report-size-deltas.yml" 7 | #schedule: 8 | # - cron: '*/5 * * * *' 9 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_dispatch 10 | workflow_dispatch: 11 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#repository_dispatch 12 | repository_dispatch: 13 | 14 | jobs: 15 | report: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | # See: https://github.com/arduino/actions/blob/master/libraries/report-size-deltas/README.md 20 | - name: Comment size deltas reports to PRs 21 | uses: arduino/report-size-deltas@v1 22 | with: 23 | # The name of the workflow artifact created by the "Compile Examples" workflow 24 | sketches-reports-source: sketches-reports 25 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/.github/workflows/report-size-deltas.yml: -------------------------------------------------------------------------------- 1 | name: Report Size Deltas 2 | 3 | on: 4 | push: 5 | paths: 6 | - ".github/workflows/report-size-deltas.yml" 7 | #schedule: 8 | # - cron: '*/5 * * * *' 9 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_dispatch 10 | workflow_dispatch: 11 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#repository_dispatch 12 | repository_dispatch: 13 | 14 | jobs: 15 | report: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | # See: https://github.com/arduino/actions/blob/master/libraries/report-size-deltas/README.md 20 | - name: Comment size deltas reports to PRs 21 | uses: arduino/report-size-deltas@v1 22 | with: 23 | # The name of the workflow artifact created by the "Compile Examples" workflow 24 | sketches-reports-source: sketches-reports 25 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/esp_targets.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include "esp_loader.h" 20 | 21 | typedef struct { 22 | uint32_t cmd; 23 | uint32_t usr; 24 | uint32_t usr1; 25 | uint32_t usr2; 26 | uint32_t w0; 27 | uint32_t mosi_dlen; 28 | uint32_t miso_dlen; 29 | } target_registers_t; 30 | 31 | esp_loader_error_t loader_detect_chip(target_chip_t *target, const target_registers_t **regs); 32 | esp_loader_error_t loader_read_spi_config(target_chip_t target_chip, uint32_t *spi_config); -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/esp_targets.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include "esp_loader.h" 20 | 21 | typedef struct { 22 | uint32_t cmd; 23 | uint32_t usr; 24 | uint32_t usr1; 25 | uint32_t usr2; 26 | uint32_t w0; 27 | uint32_t mosi_dlen; 28 | uint32_t miso_dlen; 29 | } target_registers_t; 30 | 31 | esp_loader_error_t loader_detect_chip(target_chip_t *target, const target_registers_t **regs); 32 | esp_loader_error_t loader_read_spi_config(target_chip_t target_chip, uint32_t *spi_config); -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/serial_comm.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include "esp_loader.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | esp_loader_error_t loader_flash_begin_cmd(uint32_t offset, uint32_t erase_size, uint32_t block_size, uint32_t blocks_to_write, target_chip_t target); 27 | 28 | esp_loader_error_t loader_flash_data_cmd(const uint8_t *data, uint32_t size); 29 | 30 | esp_loader_error_t loader_flash_end_cmd(bool stay_in_loader); 31 | 32 | esp_loader_error_t loader_write_reg_cmd(uint32_t address, uint32_t value, uint32_t mask, uint32_t delay_us); 33 | 34 | esp_loader_error_t loader_read_reg_cmd(uint32_t address, uint32_t *reg); 35 | 36 | esp_loader_error_t loader_sync_cmd(void); 37 | 38 | esp_loader_error_t loader_spi_attach_cmd(uint32_t config); 39 | 40 | esp_loader_error_t loader_change_baudrate_cmd(uint32_t baudrate); 41 | 42 | esp_loader_error_t loader_md5_cmd(uint32_t address, uint32_t size, uint8_t *md5_out); 43 | 44 | esp_loader_error_t loader_spi_parameters(uint32_t total_size); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/serial_comm.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include "esp_loader.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | esp_loader_error_t loader_flash_begin_cmd(uint32_t offset, uint32_t erase_size, uint32_t block_size, uint32_t blocks_to_write, target_chip_t target); 27 | 28 | esp_loader_error_t loader_flash_data_cmd(const uint8_t *data, uint32_t size); 29 | 30 | esp_loader_error_t loader_flash_end_cmd(bool stay_in_loader); 31 | 32 | esp_loader_error_t loader_write_reg_cmd(uint32_t address, uint32_t value, uint32_t mask, uint32_t delay_us); 33 | 34 | esp_loader_error_t loader_read_reg_cmd(uint32_t address, uint32_t *reg); 35 | 36 | esp_loader_error_t loader_sync_cmd(void); 37 | 38 | esp_loader_error_t loader_spi_attach_cmd(uint32_t config); 39 | 40 | esp_loader_error_t loader_change_baudrate_cmd(uint32_t baudrate); 41 | 42 | esp_loader_error_t loader_md5_cmd(uint32_t address, uint32_t size, uint8_t *md5_out); 43 | 44 | esp_loader_error_t loader_spi_parameters(uint32_t total_size); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/EspFlasher/EspFlasher.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "SD.h" 4 | 5 | /* 6 | in extras folder is a binary file with the WifiNiNa module firmware version 14.8 7 | please put this binary file in root directory of SD card 8 | easiest way is to drag and drop on a computer, but how youbget it there is up to you. 9 | The binary could be downloaded remotely, for example with an older firmware version, 10 | to the sd card. Then you would use this routine to update the wifi firmware. 11 | 12 | ***WARNING*** 13 | *Trying to flash with a non-working binary or interupting the process 14 | *mid-way will leave your wifi-module in a non functional state. 15 | *The only way to fix this (other than putting a proper binary on the sd card) 16 | *will be the the IDE WIFI Firmware updater tool 17 | *Having your board on an uninteruptible power supply is recommended for the 18 | *flashing process. 19 | 20 | */ 21 | 22 | void setup() { 23 | Serial.begin(115200); // Start communication With IDE to see whats going on 24 | delay(5000); // wait 5 seconds before atarting 25 | if(SD.begin(10)) //Must begin SD CARD before trying to flash Wifi module, will fail if not connected 26 | { 27 | ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 28 | //ESPFlasherInit(true); //sets up communication to wifi module, sets printing debug statements to Serial 29 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 30 | ESPFlasherConnect(); //connects to wifi module 31 | ESPFlashBin("NINAFW.BIN"); //flashes "NINAFW.BIN" binary file from SD card to wifi module 32 | } 33 | } 34 | 35 | void loop() { 36 | // put your main code here, to run repeatedly: 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/EspFlasher/EspFlasher.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "SD.h" 4 | 5 | /* 6 | in extras folder is a binary file with the WifiNiNa module firmware version 14.8 7 | please put this binary file in root directory of SD card 8 | easiest way is to drag and drop on a computer, but how youbget it there is up to you. 9 | The binary could be downloaded remotely, for example with an older firmware version, 10 | to the sd card. Then you would use this routine to update the wifi firmware. 11 | 12 | ***WARNING*** 13 | *Trying to flash with a non-working binary or interupting the process 14 | *mid-way will leave your wifi-module in a non functional state. 15 | *The only way to fix this (other than putting a proper binary on the sd card) 16 | *will be the the IDE WIFI Firmware updater tool 17 | *Having your board on an uninteruptible power supply is recommended for the 18 | *flashing process. 19 | 20 | */ 21 | 22 | void setup() { 23 | Serial.begin(115200); // Start communication With IDE to see whats going on 24 | delay(5000); // wait 5 seconds before atarting 25 | if(SD.begin(10)) //Must begin SD CARD before trying to flash Wifi module, will fail if not connected 26 | { 27 | ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 28 | //ESPFlasherInit(true); //sets up communication to wifi module, sets printing debug statements to Serial 29 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 30 | ESPFlasherConnect(); //connects to wifi module 31 | ESPFlashBin("NINAFW.BIN"); //flashes "NINAFW.BIN" binary file from SD card to wifi module 32 | } 33 | } 34 | 35 | void loop() { 36 | // put your main code here, to run repeatedly: 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/README.md: -------------------------------------------------------------------------------- 1 | [![Arduino Badge](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/check-arduino.yml/badge.svg)](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/check-arduino.yml) 2 | [![Compile Badge](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/compile-examples.yml) 3 | # Esp Serial flasher 4 | 5 | ## Overview 6 | Provides the ability to flash the ESP32 that is onboard the Arduino nano 33 iot board 7 | 8 | ## ESPprogrammer Branch modified to run on ESP32 to upload other ESP32s from SD card 9 | 10 | ## Limitations 11 | This library is made by myself with limited knowledge of the underlying ESP Flasher code, it's basically an Arduino port of the espressif flasher (https://github.com/espressif/esp-serial-flasher) . It's worked well for me but there are no guaruntees and I welcome other people to help contribute to make this more refined and more usable for the general public 12 | 13 | ## Requirements 14 | An Arduino nano 33 iot with an sd card module attached to standard SPI pins. Uses the SD library included with the arduino IDE. 15 | The binary file ive tested it with is made from the combine.py script in the nina-fw repo. (https://github.com/arduino/nina-fw) 16 | 17 | ## Example 18 | Below is a screenshot from the Download and flash example 19 | Demonstrates updating from Nina firmware version 1.4.6 to 1.4.7 in the same program 20 | 21 | 22 | 23 | ## Dependencies 24 | - [SD](https://github.com/arduino-libraries/SD) 25 | 26 | ## Licence 27 | 28 | Code is distributed under Apache 2.0 license. 29 | 30 | ## Credits 31 | This Library is based off of code from (https://github.com/espressif/esp-serial-flasher) 32 | 33 | ## Contact Me 34 | If you have any Questions, Comments, Concerns please email me rjfedor@hotmail.com 35 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/README.md: -------------------------------------------------------------------------------- 1 | [![Arduino Badge](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/check-arduino.yml/badge.svg)](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/check-arduino.yml) 2 | [![Compile Badge](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/winner10920/ESPSerialFlasher/actions/workflows/compile-examples.yml) 3 | # Esp Serial flasher 4 | 5 | ## Overview 6 | Provides the ability to flash the ESP32 that is onboard the Arduino nano 33 iot board 7 | 8 | ## ESPprogrammer Branch modified to run on ESP32 to upload other ESP32s from SD card 9 | 10 | ## Limitations 11 | This library is made by myself with limited knowledge of the underlying ESP Flasher code, it's basically an Arduino port of the espressif flasher (https://github.com/espressif/esp-serial-flasher) . It's worked well for me but there are no guaruntees and I welcome other people to help contribute to make this more refined and more usable for the general public 12 | 13 | ## Requirements 14 | An Arduino nano 33 iot with an sd card module attached to standard SPI pins. Uses the SD library included with the arduino IDE. 15 | The binary file ive tested it with is made from the combine.py script in the nina-fw repo. (https://github.com/arduino/nina-fw) 16 | 17 | ## Example 18 | Below is a screenshot from the Download and flash example 19 | Demonstrates updating from Nina firmware version 1.4.6 to 1.4.7 in the same program 20 | 21 | 22 | 23 | ## Dependencies 24 | - [SD](https://github.com/arduino-libraries/SD) 25 | 26 | ## Licence 27 | 28 | Code is distributed under Apache 2.0 license. 29 | 30 | ## Credits 31 | This Library is based off of code from (https://github.com/espressif/esp-serial-flasher) 32 | 33 | ## Contact Me 34 | If you have any Questions, Comments, Concerns please email me rjfedor@hotmail.com 35 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/FlashRootCerts/FlashRootCerts.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "SD.h" 4 | 5 | /* 6 | in extras folder is a binary file called roots.pem. You can add your own personal 7 | root certificatesbtonthe end of that file then run the python script nullTermRootsPem 8 | this will create a binary file that can be flashed to the wifi nina module without disrupting 9 | the firmware. Its also considerably faster than reflashing the entire firmware over. 10 | please put this binary file in root directory of SD card to use this example 11 | easiest way is to drag and drop on a computer, but how you get it there is up to you. 12 | 13 | ***WARNING*** 14 | *Trying to flash with a non-working binary or interupting the process 15 | *mid-way will leave your wifi-module in a non functional state. 16 | *The only way to fix this (other than putting a proper binary on the sd card) 17 | *will be the the IDE WIFI Firmware updater tool 18 | *Having your board on an uninteruptible power supply is recommended for the 19 | *flashing process. 20 | 21 | */ 22 | 23 | void setup() { 24 | Serial.begin(115200); // Start communication With IDE to see whats going on 25 | delay(5000); // wait 5 seconds before atarting 26 | if(SD.begin(10)) //Must begin SD CARD before trying to flash Wifi module, will fail if not connected 27 | { 28 | ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 29 | //ESPFlasherInit(true); //sets up communication to wifi module, sets printing debug statements to Serial 30 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 31 | ESPFlasherConnect(); //connects to wifi module 32 | ESPFlashCert("roots.bin"); //flashes "roots.bin" binary file from SD card to wifi module 33 | } 34 | } 35 | 36 | void loop() { 37 | // put your main code here, to run repeatedly: 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/FlashRootCerts/FlashRootCerts.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "SD.h" 4 | 5 | /* 6 | in extras folder is a binary file called roots.pem. You can add your own personal 7 | root certificatesbtonthe end of that file then run the python script nullTermRootsPem 8 | this will create a binary file that can be flashed to the wifi nina module without disrupting 9 | the firmware. Its also considerably faster than reflashing the entire firmware over. 10 | please put this binary file in root directory of SD card to use this example 11 | easiest way is to drag and drop on a computer, but how you get it there is up to you. 12 | 13 | ***WARNING*** 14 | *Trying to flash with a non-working binary or interupting the process 15 | *mid-way will leave your wifi-module in a non functional state. 16 | *The only way to fix this (other than putting a proper binary on the sd card) 17 | *will be the the IDE WIFI Firmware updater tool 18 | *Having your board on an uninteruptible power supply is recommended for the 19 | *flashing process. 20 | 21 | */ 22 | 23 | void setup() { 24 | Serial.begin(115200); // Start communication With IDE to see whats going on 25 | delay(5000); // wait 5 seconds before atarting 26 | if(SD.begin(10)) //Must begin SD CARD before trying to flash Wifi module, will fail if not connected 27 | { 28 | ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 29 | //ESPFlasherInit(true); //sets up communication to wifi module, sets printing debug statements to Serial 30 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 31 | ESPFlasherConnect(); //connects to wifi module 32 | ESPFlashCert("roots.bin"); //flashes "roots.bin" binary file from SD card to wifi module 33 | } 34 | } 35 | 36 | void loop() { 37 | // put your main code here, to run repeatedly: 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/FlashRootCertsNoSDCard/FlashRootCertsNoSDCard.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "Certs.h" 4 | 5 | /* 6 | This example allows you to upload new certificates to your wifinina module, without the sd card! 7 | ofcourse adding alotnofncertificates will take uo a tonnofnfoash space on your arduino board however so use with caution. 8 | the certificates included in Certs.h are from the wifinina firmware, there are alot. if your only connecting to a few sites you 9 | can simply put just what you need in there and be able to download new ones with a more simple ota update to your arduino board board. 10 | i dont imagine this example finding much use but i wanted to include it just because it is possible to do it this way 11 | and a long time ago i wamted to do this exact thing until i realized updating the entire firmware would prove more useful. 12 | for those who want ssl connections to self signed certs this may be very useful. 13 | ***WARNING*** 14 | *Trying to flash with a non-working binary or interupting the process 15 | *mid-way will leave your wifi-module in a non functional state. 16 | *The only way to fix this (other than putting a proper binary on the sd card) 17 | *will be the the IDE WIFI Firmware updater tool 18 | *Having your board on an uninteruptible power supply is recommended for the 19 | *flashing process. 20 | 21 | */ 22 | 23 | void setup() { 24 | Serial.begin(115200); // Start communication With IDE to see whats going on 25 | delay(5000); // wait 5 seconds before atarting 26 | Serial.println("hello"); 27 | ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 28 | //ESPFlasherInit(true); //sets up communication to wifi module, sets printing debug statements to Serial 29 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 30 | ESPFlasherConnect(); //connects to wifi module 31 | ESPFlashCertFromMemory(Certificates, sizeof(Certificates)); //flashes "roots.bin" binary file from SD card to wifi module 32 | 33 | 34 | } 35 | 36 | void loop() { 37 | // put your main code here, to run repeatedly: 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/FlashRootCertsNoSDCard/FlashRootCertsNoSDCard.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "Certs.h" 4 | 5 | /* 6 | This example allows you to upload new certificates to your wifinina module, without the sd card! 7 | ofcourse adding alotnofncertificates will take uo a tonnofnfoash space on your arduino board however so use with caution. 8 | the certificates included in Certs.h are from the wifinina firmware, there are alot. if your only connecting to a few sites you 9 | can simply put just what you need in there and be able to download new ones with a more simple ota update to your arduino board board. 10 | i dont imagine this example finding much use but i wanted to include it just because it is possible to do it this way 11 | and a long time ago i wamted to do this exact thing until i realized updating the entire firmware would prove more useful. 12 | for those who want ssl connections to self signed certs this may be very useful. 13 | ***WARNING*** 14 | *Trying to flash with a non-working binary or interupting the process 15 | *mid-way will leave your wifi-module in a non functional state. 16 | *The only way to fix this (other than putting a proper binary on the sd card) 17 | *will be the the IDE WIFI Firmware updater tool 18 | *Having your board on an uninteruptible power supply is recommended for the 19 | *flashing process. 20 | 21 | */ 22 | 23 | void setup() { 24 | Serial.begin(115200); // Start communication With IDE to see whats going on 25 | delay(5000); // wait 5 seconds before atarting 26 | Serial.println("hello"); 27 | ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 28 | //ESPFlasherInit(true); //sets up communication to wifi module, sets printing debug statements to Serial 29 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 30 | ESPFlasherConnect(); //connects to wifi module 31 | ESPFlashCertFromMemory(Certificates, sizeof(Certificates)); //flashes "roots.bin" binary file from SD card to wifi module 32 | 33 | 34 | } 35 | 36 | void loop() { 37 | // put your main code here, to run repeatedly: 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ESP8266/ESP8266.ino: -------------------------------------------------------------------------------- 1 | // Tested with ESP32 Boards Package Version 2.0.17 2 | 3 | #include "src/ESPSerialFlasher/src/ESPSerialFlasher.h" 4 | #include 5 | #include "SD.h" 6 | const int SD_CS_pin = 5; 7 | const int startProgramming_pin = 21; 8 | const int En3VPin = 4; 9 | unsigned long greenLEDstartTime; 10 | 11 | //the 4 files we're looking for must contain these keywords in the title 12 | const char bootKey[] = "boot_app"; 13 | const char bootloaderKey[] = "bootloader"; 14 | const char partitionsKey[] = "partitions"; 15 | const char firmwareKey[] = ".ino.bin";//when you flash over USB, it looks like this 16 | const char firmwareSecondKey[] = "esp32.bin";//when you export compiled binary, this is the file it generates 17 | const char SPIFFSKey[] = "spiffs.bin";///Users/kevindarrah/Library/Arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool --chip esp32 --port /dev/cu.usbserial-DA00XJ7V --baud 230400 read_flash 0x3D0000 0x30000 spiffs.bin 18 | boolean flashSPIFFS = false;//that way we only flash if present on card 19 | 20 | const char hiddenFileKey[] = "/._";//on mac, we may find duplicates that start with this, so we filter out 21 | 22 | //these title names will be stored here 23 | char bootName[100] = {NULL}; 24 | char bootloaderName[100] = {NULL}; 25 | char partitionsName[100] = {NULL}; 26 | char firmwareName[100] = {NULL}; 27 | char spiffsName[100] = {NULL}; 28 | 29 | 30 | SPIClass spiSD(VSPI); 31 | 32 | void initSDcard(); 33 | bool startFlashing(); 34 | void getFileNames(); 35 | 36 | void setup() { 37 | Serial.begin(115200); 38 | delay(2000); 39 | redLED(true); 40 | initSDcard(); 41 | pinMode(startProgramming_pin, INPUT_PULLUP); 42 | pinMode(En3VPin, OUTPUT); 43 | digitalWrite(En3VPin, HIGH); 44 | redLED(false); 45 | } 46 | 47 | void loop() { 48 | if (millis() - greenLEDstartTime > 500) { 49 | greenLEDstartTime = millis(); 50 | greenLEDflash(); 51 | } 52 | 53 | if (!digitalRead(startProgramming_pin)) { 54 | if (!startFlashing()) { 55 | digitalWrite(En3VPin, LOW); 56 | while (1) { 57 | greenLED(false); 58 | yelLED(false); 59 | redLED(true); 60 | } 61 | } 62 | digitalWrite(En3VPin, LOW); 63 | delay(1000); 64 | digitalWrite(En3VPin, HIGH); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/.github/workflows/compile-examples.yml: -------------------------------------------------------------------------------- 1 | name: Compile Examples 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/compile-examples.yml" 7 | - "library.properties" 8 | - "examples/**" 9 | - "src/**" 10 | push: 11 | paths: 12 | - ".github/workflows/compile-examples.yml" 13 | - "library.properties" 14 | - "examples/**" 15 | - "src/**" 16 | # Scheduled trigger checks for breakage caused by changes to external resources (libraries, platforms) 17 | schedule: 18 | # run every Saturday at 3 AM UTC 19 | - cron: "0 3 * * 6" 20 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_dispatch 21 | workflow_dispatch: 22 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#repository_dispatch 23 | repository_dispatch: 24 | 25 | jobs: 26 | build: 27 | name: ${{ matrix.board.fqbn }} 28 | runs-on: ubuntu-latest 29 | 30 | env: 31 | SKETCHES_REPORTS_PATH: sketches-reports 32 | 33 | strategy: 34 | fail-fast: false 35 | 36 | matrix: 37 | board: 38 | - fqbn: arduino:samd:mkrwifi1010 39 | #- fqbn: arduino:samd:mkrvidor4000 40 | - fqbn: arduino:samd:nano_33_iot 41 | #- fqbn: arduino:megaavr:uno2018:mode=on 42 | - fqbn: arduino:mbed_nano:nanorp2040connect 43 | 44 | steps: 45 | - name: Checkout 46 | uses: actions/checkout@v2 47 | 48 | - name: Compile examples 49 | uses: arduino/compile-sketches@v1 50 | with: 51 | github-token: ${{ secrets.GITHUB_TOKEN }} 52 | fqbn: ${{ matrix.board.fqbn }} 53 | libraries: | 54 | # Install the library from the local path. 55 | - source-path: ./ 56 | # Install library dependencies. 57 | - name: VidorPeripherals 58 | - name: SD 59 | - name: WiFiNINA 60 | sketch-paths: | 61 | - ./examples/ 62 | enable-deltas-report: true 63 | sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} 64 | 65 | - name: Save memory usage change report as artifact 66 | uses: actions/upload-artifact@v2 67 | with: 68 | if-no-files-found: error 69 | name: ${{ env.SKETCHES_REPORTS_PATH }} 70 | path: ${{ env.SKETCHES_REPORTS_PATH }} 71 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/.github/workflows/compile-examples.yml: -------------------------------------------------------------------------------- 1 | name: Compile Examples 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/compile-examples.yml" 7 | - "library.properties" 8 | - "examples/**" 9 | - "src/**" 10 | push: 11 | paths: 12 | - ".github/workflows/compile-examples.yml" 13 | - "library.properties" 14 | - "examples/**" 15 | - "src/**" 16 | # Scheduled trigger checks for breakage caused by changes to external resources (libraries, platforms) 17 | schedule: 18 | # run every Saturday at 3 AM UTC 19 | - cron: "0 3 * * 6" 20 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_dispatch 21 | workflow_dispatch: 22 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#repository_dispatch 23 | repository_dispatch: 24 | 25 | jobs: 26 | build: 27 | name: ${{ matrix.board.fqbn }} 28 | runs-on: ubuntu-latest 29 | 30 | env: 31 | SKETCHES_REPORTS_PATH: sketches-reports 32 | 33 | strategy: 34 | fail-fast: false 35 | 36 | matrix: 37 | board: 38 | - fqbn: arduino:samd:mkrwifi1010 39 | #- fqbn: arduino:samd:mkrvidor4000 40 | - fqbn: arduino:samd:nano_33_iot 41 | #- fqbn: arduino:megaavr:uno2018:mode=on 42 | - fqbn: arduino:mbed_nano:nanorp2040connect 43 | 44 | steps: 45 | - name: Checkout 46 | uses: actions/checkout@v2 47 | 48 | - name: Compile examples 49 | uses: arduino/compile-sketches@v1 50 | with: 51 | github-token: ${{ secrets.GITHUB_TOKEN }} 52 | fqbn: ${{ matrix.board.fqbn }} 53 | libraries: | 54 | # Install the library from the local path. 55 | - source-path: ./ 56 | # Install library dependencies. 57 | - name: VidorPeripherals 58 | - name: SD 59 | - name: WiFiNINA 60 | sketch-paths: | 61 | - ./examples/ 62 | enable-deltas-report: true 63 | sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} 64 | 65 | - name: Save memory usage change report as artifact 66 | uses: actions/upload-artifact@v2 67 | with: 68 | if-no-files-found: error 69 | name: ${{ env.SKETCHES_REPORTS_PATH }} 70 | path: ${{ env.SKETCHES_REPORTS_PATH }} 71 | -------------------------------------------------------------------------------- /ESP8266/flashing.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | boot_app0.bin 4 | bootloader_qio_80m.bin 5 | trigBoardV8_BaseFirmware.ino.bin 6 | trigBoardV8_BaseFirmware.ino.partitions.bin 7 | */ 8 | bool startFlashing() { 9 | delay(1000); 10 | digitalWrite(En3VPin, HIGH); // Ensure target device is powered 11 | 12 | // Initialize the flasher to set up Serial communication to ESP8266 13 | ESPFlasherInit(true, &Serial); 14 | 15 | // Connect to the ESP8266 module 16 | if (ESPFlasherConnect()) { 17 | Serial.println("Flashing firmware..."); 18 | 19 | // Flash the firmware file at the correct address (0x00000 for ESP8266) 20 | if (ESPFlashBin(firmwareName, 0x0)) { 21 | Serial.println("Firmware flashed successfully!"); 22 | return true; 23 | } else { 24 | Serial.println("Firmware flashing failed!"); 25 | return false; 26 | } 27 | } else { 28 | Serial.println("Failed to connect to ESP8266!"); 29 | return false; 30 | } 31 | } 32 | 33 | // bool startFlashing() { 34 | // delay(1000); 35 | // digitalWrite(En3VPin, HIGH); 36 | // ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 37 | // if (ESPFlasherConnect()) { //connects to wifi module 38 | // Serial.println("fleser start boot app"); 39 | // if (ESPFlashBin(bootName, 0xe000)) { //bootapp 40 | // ESPFlasherInit(true, &Serial); 41 | // if (ESPFlasherConnect()) { 42 | // Serial.println("fleser start bootloader app"); 43 | // if (ESPFlashBin(bootloaderName, 0x1000)) { //bootloader 44 | // ESPFlasherInit(true, &Serial); 45 | // if (ESPFlasherConnect()) { 46 | // Serial.println("fleser start firmware app"); 47 | // if (ESPFlashBin(firmwareName, 0x10000)) { //firmware 48 | // ESPFlasherInit(true, &Serial); 49 | // if (ESPFlasherConnect()) { 50 | // Serial.println("fleser start partition app"); 51 | // if (ESPFlashBin(partitionsName, 0x8000)) { //partitions 52 | // if (flashSPIFFS) {//only if SPIFFS bin is present! 53 | // ESPFlasherInit(true, &Serial); 54 | // if (ESPFlasherConnect()) { 55 | // if (ESPFlashBin(spiffsName, 0x3D0000)) { //SPIFFS - minimal SPIFFS settings, you need to change this for your settings! 56 | // Serial.println("!!!EVERYTHING IS FLASHED AND COMPLETE!!!"); 57 | // return true; 58 | // } else 59 | // return false; 60 | // } else 61 | // return false; 62 | // } else { 63 | // Serial.println("!!!EVERYTHING IS FLASHED AND COMPLETE!!!"); 64 | // return true; 65 | // } 66 | // } 67 | // } 68 | // } 69 | // } 70 | // } 71 | // } 72 | // } 73 | // } 74 | // return false; 75 | // } 76 | -------------------------------------------------------------------------------- /ESP32/flashing.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | boot_app0.bin 4 | bootloader_qio_80m.bin 5 | trigBoardV8_BaseFirmware.ino.bin 6 | trigBoardV8_BaseFirmware.ino.partitions.bin 7 | */ 8 | /* 9 | /Users/kevindarrah/Library/Arduino15/packages/esp32/tools/esptool_py/4.5.1/esptool --chip esp32c3 --port /dev/cu.usbserial-D30DAC4E --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 10 | 11 | 0x0 /var/folders/gv/dqd77lfs72xgzhcbwrp3f6vc0000gn/T/arduino_build_30965/Fargo_ESP32C3_SlotTask.ino.bootloader.bin 12 | 13 | 0x8000 /var/folders/gv/dqd77lfs72xgzhcbwrp3f6vc0000gn/T/arduino_build_30965/Fargo_ESP32C3_SlotTask.ino.partitions.bin 14 | 15 | 0xe000 /Users/kevindarrah/Library/Arduino15/packages/esp32/hardware/esp32/2.0.11/tools/partitions/boot_app0.bin 16 | 17 | 0x10000 /var/folders/gv/dqd77lfs72xgzhcbwrp3f6vc0000gn/T/arduino_build_30965/Fargo_ESP32C3_SlotTask.ino.bin 18 | * 19 | * 20 | */ 21 | 22 | void putInBootMode() { 23 | Serial2.end(); 24 | digitalWrite(En3VPin, LOW); 25 | digitalWrite(dtrPin, LOW); 26 | delay(1000); 27 | digitalWrite(En3VPin, HIGH); 28 | delay(1000); 29 | digitalWrite(dtrPin, HIGH); 30 | } 31 | bool startFlashing() { 32 | //delay(1000); 33 | putInBootMode(); 34 | ESPFlasherInit(true, &Serial);//sets up Serial communication to wifi module, with debug messages, to Print Class of your choice 35 | if (ESPFlasherConnect()) { //connects to wifi module 36 | if (ESPFlashBin(bootName, bootNameOffset)) { //bootapp 37 | putInBootMode(); 38 | ESPFlasherInit(true, &Serial); 39 | if (ESPFlasherConnect()) { 40 | if (ESPFlashBin(bootloaderName, bootloaderNameOffset)) { //bootloader 41 | putInBootMode(); 42 | ESPFlasherInit(true, &Serial); 43 | if (ESPFlasherConnect()) { 44 | if (ESPFlashBin(partitionsName, partitionsNameOffset)) { //partitions 45 | putInBootMode(); 46 | ESPFlasherInit(true, &Serial); 47 | if (ESPFlasherConnect()) { 48 | if (ESPFlashBin(firmwareName, firmwareNameOffset)) { //firmware 49 | if (flashSPIFFS) {//only if SPIFFS bin is present! 50 | putInBootMode(); 51 | ESPFlasherInit(true, &Serial); 52 | if (ESPFlasherConnect()) { 53 | if (ESPFlashBin(spiffsName, spiffsNameOffset)) { //SPIFFS - minimal SPIFFS settings, you need to change this for your settings! 54 | Serial.println("!!!EVERYTHING IS FLASHED AND COMPLETE!!!"); 55 | return true; 56 | } else 57 | return false; 58 | } else 59 | return false; 60 | } else { 61 | Serial.println("!!!EVERYTHING IS FLASHED AND COMPLETE!!!"); 62 | 63 | 64 | digitalWrite(dtrPin, LOW); 65 | digitalWrite(En3VPin, LOW); 66 | delay(1000); 67 | digitalWrite(dtrPin, HIGH); 68 | delay(1000); 69 | digitalWrite(En3VPin, HIGH); 70 | return true; 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } 79 | } 80 | return false; 81 | } 82 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/serial_io.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include "esp_loader.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** 26 | * @brief Changes baud rate of serial peripheral. 27 | */ 28 | esp_loader_error_t loader_port_change_baudrate(uint32_t baudrate); 29 | 30 | /** 31 | * @brief Writes data to serial interface. 32 | * 33 | * @param data[in] Buffer with data to be written. 34 | * @param size[in] Size of data in bytes. 35 | * @param timeout[in] Timeout in milliseconds. 36 | * 37 | * @return 38 | * - ESP_LOADER_SUCCESS Success 39 | * - ESP_LOADER_ERROR_TIMEOUT Timeout elapsed 40 | */ 41 | esp_loader_error_t loader_port_serial_write(const uint8_t *data, uint16_t size, uint32_t timeout); 42 | 43 | /** 44 | * @brief Reads data from serial interface. 45 | * 46 | * @param data[out] Buffer into which received data will be written. 47 | * @param size[in] Number of bytes to read. 48 | * @param timeout[in] Timeout in milliseconds. 49 | * 50 | * @return 51 | * - ESP_LOADER_SUCCESS Success 52 | * - ESP_LOADER_ERROR_TIMEOUT Timeout elapsed 53 | */ 54 | esp_loader_error_t loader_port_serial_read(uint8_t *data, uint16_t size, uint32_t timeout); 55 | 56 | /** 57 | * @brief Delay in milliseconds. 58 | * 59 | * @param ms[in] Number of milliseconds. 60 | * 61 | */ 62 | void loader_port_delay_ms(uint32_t ms); 63 | 64 | /** 65 | * @brief Starts timeout timer. 66 | * 67 | * @param ms[in] Number of milliseconds. 68 | * 69 | */ 70 | void loader_port_start_timer(uint32_t ms); 71 | 72 | /** 73 | * @brief Returns remaining time since timer was started by calling esp_loader_start_timer. 74 | * 0 if timer has elapsed. 75 | * 76 | * @return Number of milliseconds. 77 | * 78 | */ 79 | uint32_t loader_port_remaining_time(void); 80 | 81 | /** 82 | * @brief Asserts bootstrap pins to enter boot mode and toggles reset pin. 83 | * 84 | * @note Reset pin should stay asserted for at least 20 milliseconds. 85 | */ 86 | void loader_port_enter_bootloader(void); 87 | 88 | /** 89 | * @brief Toggles reset pin. 90 | * 91 | * @note Reset pin should stay asserted for at least 20 milliseconds. 92 | */ 93 | void loader_port_reset_target(void); 94 | 95 | /** 96 | * @brief Function can be defined by user to print debug message. 97 | * 98 | * @note Empty weak function is used, otherwise. 99 | * 100 | */ 101 | void loader_port_debug_print(const char *str); 102 | 103 | void greenLED(bool state); 104 | void greenLEDflash(); 105 | void redLED(bool state); 106 | void yelLED(bool state); 107 | 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/serial_io.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include "esp_loader.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** 26 | * @brief Changes baud rate of serial peripheral. 27 | */ 28 | esp_loader_error_t loader_port_change_baudrate(uint32_t baudrate); 29 | 30 | /** 31 | * @brief Writes data to serial interface. 32 | * 33 | * @param data[in] Buffer with data to be written. 34 | * @param size[in] Size of data in bytes. 35 | * @param timeout[in] Timeout in milliseconds. 36 | * 37 | * @return 38 | * - ESP_LOADER_SUCCESS Success 39 | * - ESP_LOADER_ERROR_TIMEOUT Timeout elapsed 40 | */ 41 | esp_loader_error_t loader_port_serial_write(const uint8_t *data, uint16_t size, uint32_t timeout); 42 | 43 | /** 44 | * @brief Reads data from serial interface. 45 | * 46 | * @param data[out] Buffer into which received data will be written. 47 | * @param size[in] Number of bytes to read. 48 | * @param timeout[in] Timeout in milliseconds. 49 | * 50 | * @return 51 | * - ESP_LOADER_SUCCESS Success 52 | * - ESP_LOADER_ERROR_TIMEOUT Timeout elapsed 53 | */ 54 | esp_loader_error_t loader_port_serial_read(uint8_t *data, uint16_t size, uint32_t timeout); 55 | 56 | /** 57 | * @brief Delay in milliseconds. 58 | * 59 | * @param ms[in] Number of milliseconds. 60 | * 61 | */ 62 | void loader_port_delay_ms(uint32_t ms); 63 | 64 | /** 65 | * @brief Starts timeout timer. 66 | * 67 | * @param ms[in] Number of milliseconds. 68 | * 69 | */ 70 | void loader_port_start_timer(uint32_t ms); 71 | 72 | /** 73 | * @brief Returns remaining time since timer was started by calling esp_loader_start_timer. 74 | * 0 if timer has elapsed. 75 | * 76 | * @return Number of milliseconds. 77 | * 78 | */ 79 | uint32_t loader_port_remaining_time(void); 80 | 81 | /** 82 | * @brief Asserts bootstrap pins to enter boot mode and toggles reset pin. 83 | * 84 | * @note Reset pin should stay asserted for at least 20 milliseconds. 85 | */ 86 | void loader_port_enter_bootloader(void); 87 | 88 | /** 89 | * @brief Toggles reset pin. 90 | * 91 | * @note Reset pin should stay asserted for at least 20 milliseconds. 92 | */ 93 | void loader_port_reset_target(void); 94 | 95 | /** 96 | * @brief Function can be defined by user to print debug message. 97 | * 98 | * @note Empty weak function is used, otherwise. 99 | * 100 | */ 101 | void loader_port_debug_print(const char *str); 102 | 103 | void greenLED(bool state); 104 | void greenLEDflash(); 105 | void redLED(bool state); 106 | void yelLED(bool state); 107 | 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | -------------------------------------------------------------------------------- /ESP32/ESP32.ino: -------------------------------------------------------------------------------- 1 | 2 | // Tested with ESP32 Boards Package Version 2.0.17 3 | 4 | #include "src/ESPSerialFlasher/src/ESPSerialFlasher.h" //inspired by https://github.com/winner10920/ESPSerialFlasher 5 | #include 6 | #include "SD.h" 7 | const int SD_CS_pin = 5; 8 | const int startProgramming_pin = 21; 9 | const int En3VPin = 4; 10 | const int dtrPin = 14; 11 | unsigned long greenLEDstartTime; 12 | 13 | #define FILE_NAME "/config.txt" // the programmer offsets here 14 | #define KEY_MAX_LENGTH 30 // change it if key is longer 15 | #define VALUE_MAX_LENGTH 30 // change it if value is longer 16 | 17 | // offsets from config.txt file 18 | uint32_t bootNameOffset = 0x00; 19 | uint32_t bootloaderNameOffset = 0x00; 20 | uint32_t partitionsNameOffset = 0x00; 21 | uint32_t firmwareNameOffset = 0x00; 22 | uint32_t spiffsNameOffset = 0x00; 23 | String bootNameOffsetStr; 24 | String bootloaderNameOffsetStr; 25 | String partitionsNameOffsetStr; 26 | String firmwareNameOffsetStr; 27 | String spiffsNameOffsetStr; 28 | 29 | //the 4 files we're looking for must contain these keywords in the title 30 | const char bootKey[] = "boot_app"; 31 | const char bootloaderKey[] = "bootloader"; 32 | const char partitionsKey[] = "partitions"; 33 | const char firmwareKey[] = ".ino.bin"; //when you flash over USB, it looks like this 34 | const char firmwareSecondKey[] = "esp32.bin"; //when you export compiled binary, this is the file it generates 35 | const char SPIFFSKey[] = "spiffs.bin"; ///Users/kevindarrah/Library/Arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool --chip esp32 --port /dev/cu.usbserial-DA00XJ7V --baud 230400 read_flash 0x3D0000 0x30000 spiffs.bin 36 | boolean flashSPIFFS = false; //that way we only flash if present on card 37 | 38 | const char hiddenFileKey[] = "._"; //on mac, we may find duplicates that start with this, so we filter out 39 | 40 | //these title names will be stored here 41 | char bootName[100] = { NULL }; 42 | char bootloaderName[100] = { NULL }; 43 | char partitionsName[100] = { NULL }; 44 | char firmwareName[100] = { NULL }; 45 | char spiffsName[100] = { NULL }; 46 | 47 | 48 | SPIClass spiSD(VSPI); 49 | 50 | void initSDcard(); 51 | bool startFlashing(); 52 | void getFileNames(); 53 | bool SD_available(const __FlashStringHelper *key); 54 | int SD_findInt(const __FlashStringHelper *key); 55 | float SD_findFloat(const __FlashStringHelper *key); 56 | String SD_findString(const __FlashStringHelper *key); 57 | int SD_findKey(const __FlashStringHelper *key, char *value); 58 | uint32_t HELPER_ascii2Int(char *ascii, int length); 59 | float HELPER_ascii2Float(char *ascii, int length); 60 | String HELPER_ascii2String(char *ascii, int length); 61 | 62 | void setup() { 63 | Serial.begin(115200); 64 | delay(1000); 65 | redLED(true); 66 | initSDcard(); 67 | pinMode(startProgramming_pin, INPUT_PULLUP); 68 | pinMode(En3VPin, OUTPUT); 69 | pinMode(dtrPin, OUTPUT); 70 | digitalWrite(dtrPin, HIGH); 71 | delay(10); 72 | digitalWrite(En3VPin, HIGH); 73 | redLED(false); 74 | Serial2.begin(115200); 75 | } 76 | 77 | void loop() { 78 | if (millis() - greenLEDstartTime > 500) { 79 | greenLEDstartTime = millis(); 80 | greenLEDflash(); 81 | } 82 | if (Serial2.available()) { 83 | Serial.print("TARGET----"); 84 | while (Serial2.available()) { 85 | Serial.write(Serial2.read()); 86 | } 87 | } 88 | 89 | if (!digitalRead(startProgramming_pin)) { 90 | if (!startFlashing()) { 91 | digitalWrite(En3VPin, LOW); 92 | while (1) { 93 | greenLED(false); 94 | yelLED(false); 95 | redLED(true); 96 | } 97 | } 98 | Serial2.end(); 99 | Serial2.begin(115200); 100 | digitalWrite(En3VPin, LOW); 101 | delay(1000); 102 | digitalWrite(En3VPin, HIGH); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/DownloadLatestFW/wifi_functions.h: -------------------------------------------------------------------------------- 1 | #ifndef _WIFIFUNCTIONS_ 2 | #define _WIFIFUNCTIONS_ 3 | #include "arduino_secrets.h" 4 | #include 5 | #include 6 | #include "arduino_secrets.h" 7 | 8 | 9 | int status = WL_IDLE_STATUS; // the Wifi radio's status 10 | int retries = 5; 11 | 12 | 13 | void printMacAddress(byte mac[]); 14 | 15 | void printWifiData(); 16 | void checkWifi(); 17 | 18 | 19 | 20 | 21 | 22 | void printMacAddress(byte mac[]) { 23 | 24 | 25 | for (int i = 5; i >= 0; i--) { 26 | if (mac[i] < 16) { 27 | debugPort->print("0"); 28 | } 29 | debugPort->print(mac[i], HEX); 30 | if (i > 0) { 31 | debugPort->print(":"); 32 | } 33 | } 34 | debugPort->println(); 35 | } 36 | 37 | 38 | 39 | void printWifiData() { 40 | debugPort->println("Wifi data"); 41 | 42 | // print your board's IP address: 43 | IPAddress ip = WiFi.localIP(); 44 | debugPort->print("IP Address: "); 45 | debugPort->println(ip); 46 | 47 | IPAddress gatewayip = WiFi.gatewayIP(); 48 | debugPort->print("Gateway Address: "); 49 | debugPort->println(gatewayip); 50 | 51 | 52 | // print your MAC address: 53 | byte mac[6]; 54 | WiFi.macAddress(mac); 55 | debugPort->print("MAC address: "); 56 | printMacAddress(mac); 57 | debugPort->println("Firmware version"); 58 | debugPort->println(WiFi.firmwareVersion()); 59 | 60 | } 61 | 62 | void printCurrentNet() { 63 | debugPort->println("Current Net"); 64 | 65 | // print the SSID of the network you're attached to: 66 | debugPort->print("SSID: "); 67 | debugPort->println(WiFi.SSID()); 68 | 69 | // print the MAC address of the router you're attached to: 70 | byte bssid[6]; 71 | WiFi.BSSID(bssid); 72 | debugPort->print("BSSID: "); 73 | printMacAddress(bssid); 74 | 75 | // print the received signal strength: 76 | long rssi = WiFi.RSSI(); 77 | debugPort->print("signal strength (RSSI):"); 78 | debugPort->println(rssi); 79 | 80 | // print the encryption type: 81 | byte encryption = WiFi.encryptionType(); 82 | debugPort->print("Encryption Type:"); 83 | debugPort->println(encryption, HEX); 84 | debugPort->println(); 85 | } 86 | 87 | 88 | void checkWifi(){ 89 | 90 | status = WiFi.status(); 91 | if(DEBUG) debugPort->print("checking wifi- current status:"); 92 | if(DEBUG) debugPort->println(status); 93 | retries = 5; 94 | // check for the WiFi module: 95 | if (WiFi.status() == WL_NO_MODULE) { 96 | if(DEBUG) debugPort->println("Communication with WiFi module failed!"); 97 | delay(10000); 98 | 99 | } 100 | 101 | 102 | 103 | 104 | // attempt to connect to Wifi network: 105 | while (status != WL_CONNECTED) { 106 | if(DEBUG) debugPort->println("Attempting to connect to WPA SSID: "); 107 | if(DEBUG) debugPort->println(SECRET_SSID); 108 | // Connect to WPA/WPA2 network: 109 | status = WiFi.begin(SECRET_SSID, SECRET_PASS); 110 | delay(2000); 111 | if(retries < 0){ 112 | if(DEBUG) debugPort->println("max retries met, returning to loop"); 113 | return; 114 | } 115 | retries --; 116 | 117 | 118 | String fv = WiFi.firmwareVersion(); 119 | if (fv < WIFI_FIRMWARE_LATEST_VERSION) if(DEBUG) debugPort->println("Please upgrade the firmware"); 120 | 121 | 122 | }// end while not connected 123 | 124 | 125 | if (status == WL_CONNECT_FAILED || status == WL_DISCONNECTED || status == WL_CONNECTION_LOST){ 126 | 127 | if(DEBUG) debugPort->println("Connection to Wifi not made"); 128 | delay(1000); 129 | retries = 5; 130 | }//end if connection not made 131 | 132 | // you're connected now, so print out the data: 133 | if(WiFi.status() == WL_CONNECTED){ 134 | if(DEBUG) debugPort->println("You're connected to the network"); 135 | if(DEBUG) printCurrentNet(); 136 | if(DEBUG) printWifiData(); 137 | retries = 5; 138 | } 139 | 140 | } 141 | 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/DownloadLatestFW/wifi_functions.h: -------------------------------------------------------------------------------- 1 | #ifndef _WIFIFUNCTIONS_ 2 | #define _WIFIFUNCTIONS_ 3 | #include "arduino_secrets.h" 4 | #include 5 | #include 6 | #include "arduino_secrets.h" 7 | 8 | 9 | int status = WL_IDLE_STATUS; // the Wifi radio's status 10 | int retries = 5; 11 | 12 | 13 | void printMacAddress(byte mac[]); 14 | 15 | void printWifiData(); 16 | void checkWifi(); 17 | 18 | 19 | 20 | 21 | 22 | void printMacAddress(byte mac[]) { 23 | 24 | 25 | for (int i = 5; i >= 0; i--) { 26 | if (mac[i] < 16) { 27 | debugPort->print("0"); 28 | } 29 | debugPort->print(mac[i], HEX); 30 | if (i > 0) { 31 | debugPort->print(":"); 32 | } 33 | } 34 | debugPort->println(); 35 | } 36 | 37 | 38 | 39 | void printWifiData() { 40 | debugPort->println("Wifi data"); 41 | 42 | // print your board's IP address: 43 | IPAddress ip = WiFi.localIP(); 44 | debugPort->print("IP Address: "); 45 | debugPort->println(ip); 46 | 47 | IPAddress gatewayip = WiFi.gatewayIP(); 48 | debugPort->print("Gateway Address: "); 49 | debugPort->println(gatewayip); 50 | 51 | 52 | // print your MAC address: 53 | byte mac[6]; 54 | WiFi.macAddress(mac); 55 | debugPort->print("MAC address: "); 56 | printMacAddress(mac); 57 | debugPort->println("Firmware version"); 58 | debugPort->println(WiFi.firmwareVersion()); 59 | 60 | } 61 | 62 | void printCurrentNet() { 63 | debugPort->println("Current Net"); 64 | 65 | // print the SSID of the network you're attached to: 66 | debugPort->print("SSID: "); 67 | debugPort->println(WiFi.SSID()); 68 | 69 | // print the MAC address of the router you're attached to: 70 | byte bssid[6]; 71 | WiFi.BSSID(bssid); 72 | debugPort->print("BSSID: "); 73 | printMacAddress(bssid); 74 | 75 | // print the received signal strength: 76 | long rssi = WiFi.RSSI(); 77 | debugPort->print("signal strength (RSSI):"); 78 | debugPort->println(rssi); 79 | 80 | // print the encryption type: 81 | byte encryption = WiFi.encryptionType(); 82 | debugPort->print("Encryption Type:"); 83 | debugPort->println(encryption, HEX); 84 | debugPort->println(); 85 | } 86 | 87 | 88 | void checkWifi(){ 89 | 90 | status = WiFi.status(); 91 | if(DEBUG) debugPort->print("checking wifi- current status:"); 92 | if(DEBUG) debugPort->println(status); 93 | retries = 5; 94 | // check for the WiFi module: 95 | if (WiFi.status() == WL_NO_MODULE) { 96 | if(DEBUG) debugPort->println("Communication with WiFi module failed!"); 97 | delay(10000); 98 | 99 | } 100 | 101 | 102 | 103 | 104 | // attempt to connect to Wifi network: 105 | while (status != WL_CONNECTED) { 106 | if(DEBUG) debugPort->println("Attempting to connect to WPA SSID: "); 107 | if(DEBUG) debugPort->println(SECRET_SSID); 108 | // Connect to WPA/WPA2 network: 109 | status = WiFi.begin(SECRET_SSID, SECRET_PASS); 110 | delay(2000); 111 | if(retries < 0){ 112 | if(DEBUG) debugPort->println("max retries met, returning to loop"); 113 | return; 114 | } 115 | retries --; 116 | 117 | 118 | String fv = WiFi.firmwareVersion(); 119 | if (fv < WIFI_FIRMWARE_LATEST_VERSION) if(DEBUG) debugPort->println("Please upgrade the firmware"); 120 | 121 | 122 | }// end while not connected 123 | 124 | 125 | if (status == WL_CONNECT_FAILED || status == WL_DISCONNECTED || status == WL_CONNECTION_LOST){ 126 | 127 | if(DEBUG) debugPort->println("Connection to Wifi not made"); 128 | delay(1000); 129 | retries = 5; 130 | }//end if connection not made 131 | 132 | // you're connected now, so print out the data: 133 | if(WiFi.status() == WL_CONNECTED){ 134 | if(DEBUG) debugPort->println("You're connected to the network"); 135 | if(DEBUG) printCurrentNet(); 136 | if(DEBUG) printWifiData(); 137 | retries = 5; 138 | } 139 | 140 | } 141 | 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/DownloadLatestFW/SDUpdate.h: -------------------------------------------------------------------------------- 1 | #ifndef _SDUPDATE_ 2 | #define _SDUPDATE_ 3 | 4 | #include "arduino_secrets.h" 5 | #include "SD.h" 6 | 7 | 8 | File updateFile; 9 | File root; 10 | 11 | bool gotUpdate = false; 12 | unsigned long downloadTime = 120000; 13 | 14 | 15 | void getUpdate(); 16 | bool downloadToSD( Stream &client, unsigned long contentLengthk, const char* filename); 17 | void printDirectory(File dir, int numTabs); 18 | bool setupSD(); 19 | void reboot(); 20 | 21 | 22 | bool downloadToSD( Stream &client, unsigned long contentLengthk, const char* filename ){ 23 | if(DEBUG){ 24 | debugPort->println("Download to SD"); 25 | } 26 | 27 | File UpdateFile; 28 | if(!setupSD()) return false; 29 | if(SD.exists(filename)) SD.remove(filename); 30 | UpdateFile = SD.open(filename, FILE_WRITE); 31 | if (UpdateFile) { 32 | if(DEBUG) {debugPort->print("Writing to ");debugPort->print(filename); debugPort->print(" ...");} 33 | unsigned long downloadTimer = millis() + downloadTime; 34 | unsigned long downloadProgress = 0; 35 | unsigned long kbDownloaded = 0; 36 | while((downloadTimer > millis()) && (downloadProgress < contentLengthk )){ 37 | while(client.available()){ 38 | UpdateFile.write(client.read()); 39 | downloadProgress++; 40 | } 41 | if((downloadProgress / 1024) > kbDownloaded){ 42 | kbDownloaded = downloadProgress / 1024; 43 | if(DEBUG) {debugPort->print(kbDownloaded);debugPort->print(" kb, ");} 44 | } 45 | } 46 | 47 | //UpdateFile.print(response); 48 | // close the file: 49 | UpdateFile.close(); 50 | if(DEBUG){debugPort->print("done in: "); debugPort->println(downloadTime - (downloadTimer - millis()));} 51 | } else { 52 | // if the file didn't open, print an error: 53 | if(DEBUG) debugPort->println("error opening UPDATE.BIN"); 54 | } 55 | UpdateFile = SD.open(filename, FILE_READ); 56 | unsigned long fileSize = UpdateFile.size(); 57 | if(DEBUG){ 58 | debugPort->print("fileSize :"); 59 | debugPort->println(fileSize); 60 | debugPort->print("contentLength :"); 61 | debugPort->println(contentLengthk); 62 | } 63 | UpdateFile.close(); 64 | //client.stop(); 65 | 66 | if(fileSize != contentLengthk){ 67 | SD.remove(filename); 68 | if(DEBUG) debugPort->println("download failed"); 69 | return false; 70 | } else { 71 | if(DEBUG) debugPort->println("download successful"); 72 | gotUpdate = true; 73 | return true; 74 | } 75 | 76 | if(DEBUG){ 77 | root = SD.open("/"); 78 | printDirectory(root, 0); 79 | root.close(); 80 | } 81 | 82 | } 83 | 84 | 85 | 86 | bool setupSD(){ 87 | if(DEBUG){ 88 | debugPort->println("SD begin"); 89 | } 90 | 91 | bool SDCardPresent = SD.begin(SDCARD_SS_PIN); 92 | 93 | if(DEBUG){ 94 | debugPort->print("SD status: "); 95 | debugPort->println(SDCardPresent); 96 | debugPort->println("Sd card Root:"); 97 | root = SD.open("/"); 98 | printDirectory(root, 0); 99 | root.close(); 100 | } 101 | 102 | return SDCardPresent; 103 | } 104 | 105 | 106 | void printDirectory(File dir, int numTabs) { 107 | 108 | 109 | debugPort->println("Print SD Directory"); 110 | while (true) { 111 | 112 | File entry = dir.openNextFile(); 113 | 114 | if (! entry) { 115 | 116 | // no more files 117 | 118 | break; 119 | 120 | } 121 | 122 | for (uint8_t i = 0; i < numTabs; i++) { 123 | 124 | debugPort->print('\t'); 125 | 126 | } 127 | 128 | debugPort->print(entry.name()); 129 | 130 | if (entry.isDirectory()) { 131 | 132 | debugPort->println("/"); 133 | 134 | printDirectory(entry, numTabs + 1); 135 | 136 | } else { 137 | 138 | // files have sizes, directories do not 139 | 140 | debugPort->print("\t\t"); 141 | 142 | debugPort->println(entry.size(), DEC); 143 | 144 | } 145 | 146 | entry.close(); 147 | 148 | } 149 | } 150 | 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/DownloadLatestFW/SDUpdate.h: -------------------------------------------------------------------------------- 1 | #ifndef _SDUPDATE_ 2 | #define _SDUPDATE_ 3 | 4 | #include "arduino_secrets.h" 5 | #include "SD.h" 6 | 7 | 8 | File updateFile; 9 | File root; 10 | 11 | bool gotUpdate = false; 12 | unsigned long downloadTime = 120000; 13 | 14 | 15 | void getUpdate(); 16 | bool downloadToSD( Stream &client, unsigned long contentLengthk, const char* filename); 17 | void printDirectory(File dir, int numTabs); 18 | bool setupSD(); 19 | void reboot(); 20 | 21 | 22 | bool downloadToSD( Stream &client, unsigned long contentLengthk, const char* filename ){ 23 | if(DEBUG){ 24 | debugPort->println("Download to SD"); 25 | } 26 | 27 | File UpdateFile; 28 | if(!setupSD()) return false; 29 | if(SD.exists(filename)) SD.remove(filename); 30 | UpdateFile = SD.open(filename, FILE_WRITE); 31 | if (UpdateFile) { 32 | if(DEBUG) {debugPort->print("Writing to ");debugPort->print(filename); debugPort->print(" ...");} 33 | unsigned long downloadTimer = millis() + downloadTime; 34 | unsigned long downloadProgress = 0; 35 | unsigned long kbDownloaded = 0; 36 | while((downloadTimer > millis()) && (downloadProgress < contentLengthk )){ 37 | while(client.available()){ 38 | UpdateFile.write(client.read()); 39 | downloadProgress++; 40 | } 41 | if((downloadProgress / 1024) > kbDownloaded){ 42 | kbDownloaded = downloadProgress / 1024; 43 | if(DEBUG) {debugPort->print(kbDownloaded);debugPort->print(" kb, ");} 44 | } 45 | } 46 | 47 | //UpdateFile.print(response); 48 | // close the file: 49 | UpdateFile.close(); 50 | if(DEBUG){debugPort->print("done in: "); debugPort->println(downloadTime - (downloadTimer - millis()));} 51 | } else { 52 | // if the file didn't open, print an error: 53 | if(DEBUG) debugPort->println("error opening UPDATE.BIN"); 54 | } 55 | UpdateFile = SD.open(filename, FILE_READ); 56 | unsigned long fileSize = UpdateFile.size(); 57 | if(DEBUG){ 58 | debugPort->print("fileSize :"); 59 | debugPort->println(fileSize); 60 | debugPort->print("contentLength :"); 61 | debugPort->println(contentLengthk); 62 | } 63 | UpdateFile.close(); 64 | //client.stop(); 65 | 66 | if(fileSize != contentLengthk){ 67 | SD.remove(filename); 68 | if(DEBUG) debugPort->println("download failed"); 69 | return false; 70 | } else { 71 | if(DEBUG) debugPort->println("download successful"); 72 | gotUpdate = true; 73 | return true; 74 | } 75 | 76 | if(DEBUG){ 77 | root = SD.open("/"); 78 | printDirectory(root, 0); 79 | root.close(); 80 | } 81 | 82 | } 83 | 84 | 85 | 86 | bool setupSD(){ 87 | if(DEBUG){ 88 | debugPort->println("SD begin"); 89 | } 90 | 91 | bool SDCardPresent = SD.begin(SDCARD_SS_PIN); 92 | 93 | if(DEBUG){ 94 | debugPort->print("SD status: "); 95 | debugPort->println(SDCardPresent); 96 | debugPort->println("Sd card Root:"); 97 | root = SD.open("/"); 98 | printDirectory(root, 0); 99 | root.close(); 100 | } 101 | 102 | return SDCardPresent; 103 | } 104 | 105 | 106 | void printDirectory(File dir, int numTabs) { 107 | 108 | 109 | debugPort->println("Print SD Directory"); 110 | while (true) { 111 | 112 | File entry = dir.openNextFile(); 113 | 114 | if (! entry) { 115 | 116 | // no more files 117 | 118 | break; 119 | 120 | } 121 | 122 | for (uint8_t i = 0; i < numTabs; i++) { 123 | 124 | debugPort->print('\t'); 125 | 126 | } 127 | 128 | debugPort->print(entry.name()); 129 | 130 | if (entry.isDirectory()) { 131 | 132 | debugPort->println("/"); 133 | 134 | printDirectory(entry, numTabs + 1); 135 | 136 | } else { 137 | 138 | // files have sizes, directories do not 139 | 140 | debugPort->print("\t\t"); 141 | 142 | debugPort->println(entry.size(), DEC); 143 | 144 | } 145 | 146 | entry.close(); 147 | 148 | } 149 | } 150 | 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /ESP32/configFIle.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by ArduinoGetStarted.com 3 | * 4 | * This example code is in the public domain 5 | * 6 | * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-read-config-from-sd-card 7 | */ 8 | 9 | bool SD_available(const __FlashStringHelper *key) { 10 | char value_string[VALUE_MAX_LENGTH]; 11 | int value_length = SD_findKey(key, value_string); 12 | return value_length > 0; 13 | } 14 | 15 | int SD_findInt(const __FlashStringHelper *key) { 16 | char value_string[VALUE_MAX_LENGTH]; 17 | int value_length = SD_findKey(key, value_string); 18 | return HELPER_ascii2Int(value_string, value_length); 19 | } 20 | 21 | float SD_findFloat(const __FlashStringHelper *key) { 22 | char value_string[VALUE_MAX_LENGTH]; 23 | int value_length = SD_findKey(key, value_string); 24 | return HELPER_ascii2Float(value_string, value_length); 25 | } 26 | 27 | String SD_findString(const __FlashStringHelper *key) { 28 | char value_string[VALUE_MAX_LENGTH]; 29 | int value_length = SD_findKey(key, value_string); 30 | return HELPER_ascii2String(value_string, value_length); 31 | } 32 | 33 | int SD_findKey(const __FlashStringHelper *key, char *value) { 34 | File configFile = SD.open(FILE_NAME); 35 | 36 | if (!configFile) { 37 | Serial.print(F("SD Card: error on opening config ")); 38 | Serial.println(FILE_NAME); 39 | while(1){ 40 | 41 | } 42 | return 0; 43 | } 44 | 45 | char key_string[KEY_MAX_LENGTH]; 46 | char SD_buffer[KEY_MAX_LENGTH + VALUE_MAX_LENGTH + 1]; // 1 is = character 47 | int key_length = 0; 48 | int value_length = 0; 49 | 50 | // Flash string to string 51 | PGM_P keyPoiter; 52 | keyPoiter = reinterpret_cast(key); 53 | byte ch; 54 | do { 55 | ch = pgm_read_byte(keyPoiter++); 56 | if (ch != 0) 57 | key_string[key_length++] = ch; 58 | } while (ch != 0); 59 | 60 | // check line by line 61 | while (configFile.available()) { 62 | int buffer_length = configFile.readBytesUntil('\n', SD_buffer, 100); 63 | if (SD_buffer[buffer_length - 1] == '\r') 64 | buffer_length--; // trim the \r 65 | //Serial.println(SD_buffer); 66 | if (buffer_length > (key_length + 1)) { // 1 is = character 67 | if (memcmp(SD_buffer, key_string, key_length) == 0) { // equal 68 | 69 | if (SD_buffer[key_length] == '=') { 70 | value_length = buffer_length - key_length - 1; 71 | memcpy(value, SD_buffer + key_length + 1, value_length); 72 | break; 73 | } 74 | } 75 | } 76 | } 77 | 78 | configFile.close(); // close the file 79 | //Serial.println(value_length); 80 | return value_length; 81 | } 82 | 83 | uint32_t HELPER_ascii2Int(char *ascii, int length) { 84 | int sign = 1; 85 | int number = 0; 86 | 87 | for (int i = 0; i < length; i++) { 88 | char c = *(ascii + i); 89 | if (i == 0 && c == '-') 90 | sign = -1; 91 | else { 92 | if (c >= '0' && c <= '9') 93 | number = number * 10 + (c - '0'); 94 | } 95 | } 96 | 97 | return number * sign; 98 | } 99 | 100 | float HELPER_ascii2Float(char *ascii, int length) { 101 | int sign = 1; 102 | int decimalPlace = 0; 103 | float number = 0; 104 | float decimal = 0; 105 | 106 | for (int i = 0; i < length; i++) { 107 | char c = *(ascii + i); 108 | if (i == 0 && c == '-') 109 | sign = -1; 110 | else { 111 | if (c == '.') 112 | decimalPlace = 1; 113 | else if (c >= '0' && c <= '9') { 114 | if (!decimalPlace) 115 | number = number * 10 + (c - '0'); 116 | else { 117 | decimal += ((float)(c - '0') / pow(10.0, decimalPlace)); 118 | decimalPlace++; 119 | } 120 | } 121 | } 122 | } 123 | 124 | return (number + decimal) * sign; 125 | } 126 | 127 | String HELPER_ascii2String(char *ascii, int length) { 128 | String str; 129 | str.reserve(length); 130 | str = ""; 131 | 132 | for (int i = 0; i < length; i++) { 133 | char c = *(ascii + i); 134 | str += String(c); 135 | } 136 | 137 | return str; 138 | } -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/DownloadLatestFW/DownloadLatestFW.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "SD.h" 4 | 5 | #include "JustHTTPClient.h" 6 | #include "SDUpdate.h" 7 | #include "wifi_functions.h" 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | This sketch and included files Updates the wifinina firmware to the latest firmware 14 | according to your version of the WiFiNina library. 15 | Please adjust settings in arduino_secrets 16 | 17 | This is a very complicated example but it gives you alot of flexibility, for example I use it to Monitor 18 | my debug statements over a changeable debug port. E.g Serial to a computer, Serial1 to a bluetooth Serial Module 19 | (,or even (untested) logged to an sd card) 20 | 21 | This is just a crude working example to get you started. the included files are not fully tested 22 | but have worked well for me. Id anyone has a more elegant solution feel free to drop a suggestion or pull request 23 | https://github.com/winner10920/ESPSerialFlasher 24 | 25 | ***WARNING*** 26 | *Trying to flash with a non-working binary or interupting the process 27 | *mid-way will leave your wifi-module in a non functional state. 28 | *The only way to fix this (other than putting a proper binary on the sd card) 29 | *will be the the IDE WIFI Firmware updater tool 30 | *Having your board on an uninteruptible power supply is recommended for the 31 | *flashing process. 32 | 33 | */ 34 | 35 | char downloadUrl[128] ; 36 | 37 | void setup() { 38 | Serial.begin(115200); // Start communication With IDE to see whats going on, the below functions use "Serial" 39 | Serial1.begin(115200); 40 | delay(5000); // wait 5 seconds before atarting 41 | 42 | checkWifi(); //function onnwofi functions page to check wifi connection to APspecified in secrets 43 | WiFiClient client; //create instamce of wifi client to use with requesting patest firmware url and downloading 44 | debugPort->print("Current WiFiNina firmware: "); 45 | debugPort->println(WiFi.firmwareVersion()); //print firmware version 46 | //connect to arduino.cc to find out what the url of thr latest firmware according to library versionncurrently in use 47 | bool connected = client.connectSSL("downloads.arduino.cc", 443); 48 | if(connected) 49 | { 50 | long contentLength = HTTPGETRequest("downloads.arduino.cc","/arduino-fwuploader/boards/module_firmware_index.json", client ); 51 | if(contentLength > 0){ 52 | bool foundBoard = client.find("\"fqbn\": \"arduino:samd:nano_33_iot\","); 53 | if(foundBoard){ 54 | debugPort->println("found Board"); 55 | bool foundVersion = client.find("\"version\": \""WIFI_FIRMWARE_LATEST_VERSION"\","); 56 | //bool foundVersion = client.find("\"version\": \"1.4.6\","); //could looknfor specific version like this 57 | if(foundVersion){ 58 | debugPort->println("found Version"); 59 | bool foundUrl = client.find("\"url\": \""); 60 | if(foundUrl){ 61 | debugPort->println("found Url"); 62 | client.readBytesUntil('"',downloadUrl,sizeof(downloadUrl)); 63 | debugPort->println(downloadUrl); 64 | }//end found url 65 | }//end found version 66 | }//end found board 67 | }//end content length 68 | emptyRequestBuffer(client, false); //empties rest of the http body 69 | }//end if connected 70 | else debugPort->println("Failed to connect to arduino"); 71 | client.stop(); 72 | 73 | //connect to arduino.cc to download the binary file to SD card 74 | connected = client.connectSSL("downloads.arduino.cc", 443); 75 | if(connected) 76 | { 77 | long contentLength = HTTPOTARequest("downloads.arduino.cc",downloadUrl, client ); 78 | if(contentLength > 0){ 79 | if(downloadToSD(client, contentLength,"NINAFW1.BIN")){ 80 | emptyRequestBuffer(client, false); 81 | client.stop(); 82 | WiFi.end(); 83 | ESPFlasherInit(DEBUG, debugPort); //sets up communication to wifi module, prints Debug message to the debug port specified in secrets 84 | //ESPFlasherInit(DEBUG); //sets up communication to wifi module, sets printing debug statements to Serial if DEBUG is true 85 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 86 | ESPFlasherConnect(); //connects to wifi module 87 | ESPFlashBin("NINAFW1.BIN"); //flashes "NINAFW.BIN" binary file from SD card to wifi module 88 | 89 | }//end if succeasful download 90 | }//end content length 91 | }//end connected 92 | 93 | checkWifi(); //flash procedure done, time to reconnect to wifi 94 | debugPort->print("Current WiFiNina firmware: "); 95 | debugPort->println(WiFi.firmwareVersion()); //print firmware version 96 | 97 | } 98 | 99 | void loop() { 100 | // put your main code here, to run repeatedly: 101 | delay(60000); //check wifi again every minute 102 | checkWifi(); 103 | Serial.println("loop"); 104 | //debugPort->println(WiFi.firmwareVersion()); //print firmware version 105 | 106 | } 107 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/DownloadLatestFW/DownloadLatestFW.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "ESPSerialFlasher.h" 3 | #include "SD.h" 4 | 5 | #include "JustHTTPClient.h" 6 | #include "SDUpdate.h" 7 | #include "wifi_functions.h" 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | This sketch and included files Updates the wifinina firmware to the latest firmware 14 | according to your version of the WiFiNina library. 15 | Please adjust settings in arduino_secrets 16 | 17 | This is a very complicated example but it gives you alot of flexibility, for example I use it to Monitor 18 | my debug statements over a changeable debug port. E.g Serial to a computer, Serial1 to a bluetooth Serial Module 19 | (,or even (untested) logged to an sd card) 20 | 21 | This is just a crude working example to get you started. the included files are not fully tested 22 | but have worked well for me. Id anyone has a more elegant solution feel free to drop a suggestion or pull request 23 | https://github.com/winner10920/ESPSerialFlasher 24 | 25 | ***WARNING*** 26 | *Trying to flash with a non-working binary or interupting the process 27 | *mid-way will leave your wifi-module in a non functional state. 28 | *The only way to fix this (other than putting a proper binary on the sd card) 29 | *will be the the IDE WIFI Firmware updater tool 30 | *Having your board on an uninteruptible power supply is recommended for the 31 | *flashing process. 32 | 33 | */ 34 | 35 | char downloadUrl[128] ; 36 | 37 | void setup() { 38 | Serial.begin(115200); // Start communication With IDE to see whats going on, the below functions use "Serial" 39 | Serial1.begin(115200); 40 | delay(5000); // wait 5 seconds before atarting 41 | 42 | checkWifi(); //function onnwofi functions page to check wifi connection to APspecified in secrets 43 | WiFiClient client; //create instamce of wifi client to use with requesting patest firmware url and downloading 44 | debugPort->print("Current WiFiNina firmware: "); 45 | debugPort->println(WiFi.firmwareVersion()); //print firmware version 46 | //connect to arduino.cc to find out what the url of thr latest firmware according to library versionncurrently in use 47 | bool connected = client.connectSSL("downloads.arduino.cc", 443); 48 | if(connected) 49 | { 50 | long contentLength = HTTPGETRequest("downloads.arduino.cc","/arduino-fwuploader/boards/module_firmware_index.json", client ); 51 | if(contentLength > 0){ 52 | bool foundBoard = client.find("\"fqbn\": \"arduino:samd:nano_33_iot\","); 53 | if(foundBoard){ 54 | debugPort->println("found Board"); 55 | bool foundVersion = client.find("\"version\": \""WIFI_FIRMWARE_LATEST_VERSION"\","); 56 | //bool foundVersion = client.find("\"version\": \"1.4.6\","); //could looknfor specific version like this 57 | if(foundVersion){ 58 | debugPort->println("found Version"); 59 | bool foundUrl = client.find("\"url\": \""); 60 | if(foundUrl){ 61 | debugPort->println("found Url"); 62 | client.readBytesUntil('"',downloadUrl,sizeof(downloadUrl)); 63 | debugPort->println(downloadUrl); 64 | }//end found url 65 | }//end found version 66 | }//end found board 67 | }//end content length 68 | emptyRequestBuffer(client, false); //empties rest of the http body 69 | }//end if connected 70 | else debugPort->println("Failed to connect to arduino"); 71 | client.stop(); 72 | 73 | //connect to arduino.cc to download the binary file to SD card 74 | connected = client.connectSSL("downloads.arduino.cc", 443); 75 | if(connected) 76 | { 77 | long contentLength = HTTPOTARequest("downloads.arduino.cc",downloadUrl, client ); 78 | if(contentLength > 0){ 79 | if(downloadToSD(client, contentLength,"NINAFW1.BIN")){ 80 | emptyRequestBuffer(client, false); 81 | client.stop(); 82 | WiFi.end(); 83 | ESPFlasherInit(DEBUG, debugPort); //sets up communication to wifi module, prints Debug message to the debug port specified in secrets 84 | //ESPFlasherInit(DEBUG); //sets up communication to wifi module, sets printing debug statements to Serial if DEBUG is true 85 | //ESPFlasherInit(); //sets up communication to wifi module, no debug messages 86 | ESPFlasherConnect(); //connects to wifi module 87 | ESPFlashBin("NINAFW1.BIN"); //flashes "NINAFW.BIN" binary file from SD card to wifi module 88 | 89 | }//end if succeasful download 90 | }//end content length 91 | }//end connected 92 | 93 | checkWifi(); //flash procedure done, time to reconnect to wifi 94 | debugPort->print("Current WiFiNina firmware: "); 95 | debugPort->println(WiFi.firmwareVersion()); //print firmware version 96 | 97 | } 98 | 99 | void loop() { 100 | // put your main code here, to run repeatedly: 101 | delay(60000); //check wifi again every minute 102 | checkWifi(); 103 | Serial.println("loop"); 104 | //debugPort->println(WiFi.firmwareVersion()); //print firmware version 105 | 106 | } 107 | -------------------------------------------------------------------------------- /ESP8266/sdcard.ino: -------------------------------------------------------------------------------- 1 | 2 | //HSPI MOSI=13, MISO=12, CLK=14, CS=25 3 | //VSPI MOSI=23, MISO=19, CLK=18, CS=25 4 | 5 | void getFileNames() { 6 | Serial.println("Looking for files"); 7 | File root; 8 | root = SD.open("/"); 9 | while (true) { 10 | 11 | File entry = root.openNextFile(); 12 | if (! entry) { 13 | // no more files 14 | break; 15 | } 16 | char *pointerTobootloaderKey = strstr(entry.name(), bootloaderKey);//go find keyword 17 | if (pointerTobootloaderKey != NULL) { 18 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 19 | if (pointerToHiddenFile == NULL) {//good not hidden file 20 | Serial.print("Found Bootloader File: "); 21 | //strncpy(bootloaderName, entry.name(), sizeof(bootloaderName)); 22 | strcpy(bootloaderName, "/"); 23 | strcat(bootloaderName, entry.name()); 24 | Serial.println(bootloaderName); 25 | } 26 | } 27 | char *pointerTobootKey = strstr(entry.name(), bootKey);//go find keyword 28 | if (pointerTobootKey != NULL) { 29 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 30 | if (pointerToHiddenFile == NULL) {//good not hidden file 31 | Serial.print("Found Boot File: "); 32 | //strncpy(bootName, entry.name(), sizeof(bootName)); 33 | strcpy(bootName, "/"); 34 | strcat(bootName, entry.name()); 35 | Serial.println(bootName); 36 | } 37 | } 38 | char *pointerToPartitionsKey = strstr(entry.name(), partitionsKey);//go find keyword 39 | if (pointerToPartitionsKey != NULL) { 40 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 41 | if (pointerToHiddenFile == NULL) {//good not hidden file 42 | Serial.print("Found Partitions File: "); 43 | // strncpy(partitionsName, entry.name(), sizeof(partitionsName)); 44 | strcpy(partitionsName, "/"); 45 | strcat(partitionsName, entry.name()); 46 | Serial.println(partitionsName); 47 | } 48 | } 49 | char *pointerToFirmwareKey = strstr(entry.name(), firmwareKey);//go find keyword 50 | if (pointerToFirmwareKey != NULL) { 51 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 52 | if (pointerToHiddenFile == NULL) {//good not hidden file 53 | Serial.print("Found Firmware File: "); 54 | // strncpy(firmwareName, entry.name(), sizeof(firmwareName)); 55 | strcpy(firmwareName, "/"); 56 | strcat(firmwareName, entry.name()); 57 | Serial.println(firmwareName); 58 | } 59 | } 60 | char *pointerToFirmwareSecondKey = strstr(entry.name(), firmwareSecondKey);//go find keyword 61 | if (pointerToFirmwareSecondKey != NULL) { 62 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 63 | if (pointerToHiddenFile == NULL) {//good not hidden file 64 | Serial.print("Found Firmware File: "); 65 | //strncpy(firmwareName, entry.name(), sizeof(firmwareName)); 66 | strcpy(firmwareName, "/"); 67 | strcat(firmwareName, entry.name()); 68 | Serial.println(firmwareName); 69 | } 70 | } 71 | 72 | char *pointerToSPIFFSKey = strstr(entry.name(), SPIFFSKey);//go find keyword 73 | if (pointerToSPIFFSKey != NULL) { 74 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 75 | if (pointerToHiddenFile == NULL) {//good not hidden file 76 | Serial.print("Found SPIFFS File: "); 77 | //strncpy(spiffsName, entry.name(), sizeof(spiffsName)); 78 | strcpy(spiffsName, "/"); 79 | strcat(spiffsName, entry.name()); 80 | Serial.println(spiffsName); 81 | flashSPIFFS = true; 82 | } 83 | } 84 | 85 | Serial.println(entry.name()); 86 | // if (entry.isDirectory()) { 87 | // Serial.println("/"); 88 | // //printDirectory(entry, numTabs + 1); 89 | // } else { 90 | // // files have sizes, directories do not 91 | // Serial.print("\t\t"); 92 | // Serial.println(entry.size(), DEC); 93 | // } 94 | entry.close(); 95 | } 96 | } 97 | 98 | 99 | void initSDcard() { 100 | //spiSD.begin(14, 12, 13, SD_CS); //SCK,MISO,MOSI,SS //HSPI1 101 | spiSD.begin(18, 19, 23, SD_CS_pin); //SCK,MISO,MOSI,SS //HSPI1 102 | while (!SD.begin( SD_CS_pin, spiSD )) 103 | { 104 | Serial.println("Card Mount Failed"); 105 | delay(1000); 106 | } 107 | 108 | 109 | uint8_t cardType = SD.cardType(); 110 | 111 | if (cardType == CARD_NONE) { 112 | Serial.println("No SD card attached"); 113 | return; 114 | } 115 | Serial.print("SD Card Type: "); 116 | if (cardType == CARD_MMC) { 117 | Serial.println("MMC"); 118 | } else if (cardType == CARD_SD) { 119 | Serial.println("SDSC"); 120 | } else if (cardType == CARD_SDHC) { 121 | Serial.println("SDHC"); 122 | } else { 123 | Serial.println("UNKNOWN"); 124 | } 125 | 126 | uint64_t cardSize = SD.cardSize() / (1024 * 1024); 127 | Serial.printf("SD Card Size: %lluMB\n", cardSize); 128 | 129 | getFileNames(); 130 | 131 | // if (bootName[0] == NULL || bootloaderName[0] == NULL || partitionsName[0] == NULL || firmwareName[0] == NULL) { 132 | // Serial.println("ERROR - not all files found!!!"); 133 | // while (1) { 134 | // } 135 | 136 | // } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/serial_comm_prv.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | #define STATUS_FAILURE 1 26 | #define STATUS_SUCCESS 0 27 | 28 | #define READ_DIRECTION 1 29 | #define WRITE_DIRECTION 0 30 | 31 | #define MD5_SIZE 32 32 | 33 | typedef enum __attribute__((packed)) 34 | { 35 | FLASH_BEGIN = 0x02, 36 | FLASH_DATA = 0x03, 37 | FLASH_END = 0x04, 38 | MEM_BEGIN = 0x05, 39 | MEM_END = 0x06, 40 | MEM_DATA = 0x07, 41 | SYNC = 0x08, 42 | WRITE_REG = 0x09, 43 | READ_REG = 0x0a, 44 | 45 | SPI_SET_PARAMS = 0x0b, 46 | SPI_ATTACH = 0x0d, 47 | CHANGE_BAUDRATE = 0x0f, 48 | FLASH_DEFL_BEGIN = 0x10, 49 | FLASH_DEFL_DATA = 0x11, 50 | FLASH_DEFL_END = 0x12, 51 | SPI_FLASH_MD5 = 0x13, 52 | } command_t; 53 | 54 | typedef enum __attribute__((packed)) 55 | { 56 | RESPONSE_OK = 0x00, 57 | INVALID_COMMAND = 0x05, // parameters or length field is invalid 58 | COMMAND_FAILED = 0x06, // Failed to act on received message 59 | INVALID_CRC = 0x07, // Invalid CRC in message 60 | FLASH_WRITE_ERR = 0x08, // After writing a block of data to flash, the ROM loader reads the value back and the 8-bit CRC is compared to the data read from flash. If they don't match, this error is returned. 61 | FLASH_READ_ERR = 0x09, // SPI read failed 62 | READ_LENGTH_ERR = 0x0a, // SPI read request length is too long 63 | DEFLATE_ERROR = 0x0b, // ESP32 compressed uploads only 64 | } error_code_t; 65 | 66 | typedef struct __attribute__((packed)) 67 | { 68 | uint8_t direction; 69 | uint8_t command; // One of command_t 70 | uint16_t size; 71 | uint32_t checksum; 72 | } command_common_t; 73 | 74 | typedef struct __attribute__((packed)) 75 | { 76 | command_common_t common; 77 | uint32_t erase_size; 78 | uint32_t packet_count; 79 | uint32_t packet_size; 80 | uint32_t offset; 81 | uint32_t encrypted; 82 | } begin_command_t; 83 | 84 | typedef struct __attribute__((packed)) 85 | { 86 | command_common_t common; 87 | uint32_t data_size; 88 | uint32_t sequence_number; 89 | uint32_t zero_0; 90 | uint32_t zero_1; 91 | } data_command_t; 92 | 93 | typedef struct __attribute__((packed)) 94 | { 95 | command_common_t common; 96 | uint32_t stay_in_loader; 97 | } flash_end_command_t; 98 | 99 | typedef struct __attribute__((packed)) 100 | { 101 | command_common_t common; 102 | uint32_t stay_in_loader; 103 | uint32_t entry_point_address; 104 | } mem_end_command_t; 105 | 106 | typedef struct __attribute__((packed)) 107 | { 108 | command_common_t common; 109 | uint8_t sync_sequence[36]; 110 | } sync_command_t; 111 | 112 | typedef struct __attribute__((packed)) 113 | { 114 | command_common_t common; 115 | uint32_t address; 116 | uint32_t value; 117 | uint32_t mask; 118 | uint32_t delay_us; 119 | } write_reg_command_t; 120 | 121 | typedef struct __attribute__((packed)) 122 | { 123 | command_common_t common; 124 | uint32_t address; 125 | } read_reg_command_t; 126 | 127 | typedef struct __attribute__((packed)) 128 | { 129 | command_common_t common; 130 | uint32_t configuration; 131 | uint32_t zero; // ESP32 ROM only 132 | } spi_attach_command_t; 133 | 134 | typedef struct __attribute__((packed)) 135 | { 136 | command_common_t common; 137 | uint32_t new_baudrate; 138 | uint32_t old_baudrate; 139 | } change_baudrate_command_t; 140 | 141 | typedef struct __attribute__((packed)) 142 | { 143 | command_common_t common; 144 | 145 | } eraseAllCommad_t; 146 | 147 | typedef struct __attribute__((packed)) 148 | { 149 | command_common_t common; 150 | uint32_t address; 151 | uint32_t size; 152 | uint32_t reserved_0; 153 | uint32_t reserved_1; 154 | } spi_flash_md5_command_t; 155 | 156 | typedef struct __attribute__((packed)) 157 | { 158 | uint8_t direction; 159 | uint8_t command; // One of command_t 160 | uint16_t size; 161 | uint32_t value; 162 | } common_response_t; 163 | 164 | typedef struct __attribute__((packed)) 165 | { 166 | uint8_t failed; 167 | uint8_t error; 168 | } response_status_t; 169 | 170 | typedef struct __attribute__((packed)) 171 | { 172 | common_response_t common; 173 | response_status_t status; 174 | } response_t; 175 | 176 | typedef struct __attribute__((packed)) 177 | { 178 | common_response_t common; 179 | uint8_t md5[MD5_SIZE]; // ROM only 180 | response_status_t status; 181 | } rom_md5_response_t; 182 | 183 | typedef struct __attribute__((packed)) 184 | { 185 | command_common_t common; 186 | uint32_t id; 187 | uint32_t total_size; 188 | uint32_t block_size; 189 | uint32_t sector_size; 190 | uint32_t page_size; 191 | uint32_t status_mask; 192 | } write_spi_command_t; 193 | 194 | 195 | #ifdef __cplusplus 196 | } 197 | #endif 198 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/serial_comm_prv.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | #define STATUS_FAILURE 1 26 | #define STATUS_SUCCESS 0 27 | 28 | #define READ_DIRECTION 1 29 | #define WRITE_DIRECTION 0 30 | 31 | #define MD5_SIZE 32 32 | 33 | typedef enum __attribute__((packed)) 34 | { 35 | FLASH_BEGIN = 0x02, 36 | FLASH_DATA = 0x03, 37 | FLASH_END = 0x04, 38 | MEM_BEGIN = 0x05, 39 | MEM_END = 0x06, 40 | MEM_DATA = 0x07, 41 | SYNC = 0x08, 42 | WRITE_REG = 0x09, 43 | READ_REG = 0x0a, 44 | 45 | SPI_SET_PARAMS = 0x0b, 46 | SPI_ATTACH = 0x0d, 47 | CHANGE_BAUDRATE = 0x0f, 48 | FLASH_DEFL_BEGIN = 0x10, 49 | FLASH_DEFL_DATA = 0x11, 50 | FLASH_DEFL_END = 0x12, 51 | SPI_FLASH_MD5 = 0x13, 52 | } command_t; 53 | 54 | typedef enum __attribute__((packed)) 55 | { 56 | RESPONSE_OK = 0x00, 57 | INVALID_COMMAND = 0x05, // parameters or length field is invalid 58 | COMMAND_FAILED = 0x06, // Failed to act on received message 59 | INVALID_CRC = 0x07, // Invalid CRC in message 60 | FLASH_WRITE_ERR = 0x08, // After writing a block of data to flash, the ROM loader reads the value back and the 8-bit CRC is compared to the data read from flash. If they don't match, this error is returned. 61 | FLASH_READ_ERR = 0x09, // SPI read failed 62 | READ_LENGTH_ERR = 0x0a, // SPI read request length is too long 63 | DEFLATE_ERROR = 0x0b, // ESP32 compressed uploads only 64 | } error_code_t; 65 | 66 | typedef struct __attribute__((packed)) 67 | { 68 | uint8_t direction; 69 | uint8_t command; // One of command_t 70 | uint16_t size; 71 | uint32_t checksum; 72 | } command_common_t; 73 | 74 | typedef struct __attribute__((packed)) 75 | { 76 | command_common_t common; 77 | uint32_t erase_size; 78 | uint32_t packet_count; 79 | uint32_t packet_size; 80 | uint32_t offset; 81 | uint32_t encrypted; 82 | } begin_command_t; 83 | 84 | typedef struct __attribute__((packed)) 85 | { 86 | command_common_t common; 87 | uint32_t data_size; 88 | uint32_t sequence_number; 89 | uint32_t zero_0; 90 | uint32_t zero_1; 91 | } data_command_t; 92 | 93 | typedef struct __attribute__((packed)) 94 | { 95 | command_common_t common; 96 | uint32_t stay_in_loader; 97 | } flash_end_command_t; 98 | 99 | typedef struct __attribute__((packed)) 100 | { 101 | command_common_t common; 102 | uint32_t stay_in_loader; 103 | uint32_t entry_point_address; 104 | } mem_end_command_t; 105 | 106 | typedef struct __attribute__((packed)) 107 | { 108 | command_common_t common; 109 | uint8_t sync_sequence[36]; 110 | } sync_command_t; 111 | 112 | typedef struct __attribute__((packed)) 113 | { 114 | command_common_t common; 115 | uint32_t address; 116 | uint32_t value; 117 | uint32_t mask; 118 | uint32_t delay_us; 119 | } write_reg_command_t; 120 | 121 | typedef struct __attribute__((packed)) 122 | { 123 | command_common_t common; 124 | uint32_t address; 125 | } read_reg_command_t; 126 | 127 | typedef struct __attribute__((packed)) 128 | { 129 | command_common_t common; 130 | uint32_t configuration; 131 | uint32_t zero; // ESP32 ROM only 132 | } spi_attach_command_t; 133 | 134 | typedef struct __attribute__((packed)) 135 | { 136 | command_common_t common; 137 | uint32_t new_baudrate; 138 | uint32_t old_baudrate; 139 | } change_baudrate_command_t; 140 | 141 | typedef struct __attribute__((packed)) 142 | { 143 | command_common_t common; 144 | 145 | } eraseAllCommad_t; 146 | 147 | typedef struct __attribute__((packed)) 148 | { 149 | command_common_t common; 150 | uint32_t address; 151 | uint32_t size; 152 | uint32_t reserved_0; 153 | uint32_t reserved_1; 154 | } spi_flash_md5_command_t; 155 | 156 | typedef struct __attribute__((packed)) 157 | { 158 | uint8_t direction; 159 | uint8_t command; // One of command_t 160 | uint16_t size; 161 | uint32_t value; 162 | } common_response_t; 163 | 164 | typedef struct __attribute__((packed)) 165 | { 166 | uint8_t failed; 167 | uint8_t error; 168 | } response_status_t; 169 | 170 | typedef struct __attribute__((packed)) 171 | { 172 | common_response_t common; 173 | response_status_t status; 174 | } response_t; 175 | 176 | typedef struct __attribute__((packed)) 177 | { 178 | common_response_t common; 179 | uint8_t md5[MD5_SIZE]; // ROM only 180 | response_status_t status; 181 | } rom_md5_response_t; 182 | 183 | typedef struct __attribute__((packed)) 184 | { 185 | command_common_t common; 186 | uint32_t id; 187 | uint32_t total_size; 188 | uint32_t block_size; 189 | uint32_t sector_size; 190 | uint32_t page_size; 191 | uint32_t status_mask; 192 | } write_spi_command_t; 193 | 194 | 195 | #ifdef __cplusplus 196 | } 197 | #endif 198 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | rjfedor@hotmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | rjfedor@hotmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/examples/DownloadLatestFW/JustHTTPClient.h: -------------------------------------------------------------------------------- 1 | #ifndef _JUSTHTTP_ 2 | #define _JUSTHTTP_ 3 | #include "arduino_secrets.h" 4 | 5 | 6 | 7 | 8 | const byte GET_METHOD = 1; 9 | const byte POST_METHOD = 2; 10 | const byte OTA_METHOD = 3; 11 | 12 | long HTTPGETRequest(const char* host, const char* path, Stream &client ); 13 | long HTTPPOSTRequest(const char* host, const char* path, const char* postData, Stream &client ); 14 | long HTTPOTARequest(const char* host, const char* path, Stream &client ); 15 | 16 | long HTTPRequest(byte method, const char* host, const char* path, const char* postData, Stream &client ); 17 | void emptyRequestBuffer(Stream &client , bool print = true); 18 | 19 | 20 | 21 | long HTTPRequest(byte method, const char* host, const char* path, const char* postData, Stream &client ){ 22 | char pathHeader[] = "%s %s HTTP/1.1"; 23 | char requestHeader[128]; 24 | char postContentHeader[64]; 25 | 26 | emptyRequestBuffer(client); 27 | 28 | 29 | if((method == GET_METHOD) || (method == OTA_METHOD)){ 30 | snprintf(requestHeader, sizeof(requestHeader), pathHeader, "GET", path); 31 | } 32 | else if(method == POST_METHOD) { 33 | snprintf(requestHeader, sizeof(requestHeader), pathHeader,"POST", path); 34 | char INSERT_LENGTH[] = "Content-Length: %i"; 35 | snprintf(postContentHeader,sizeof(postContentHeader),INSERT_LENGTH,strlen(postData)); 36 | } 37 | else return -2; 38 | 39 | char INSERT_HOST[] = "Host: %s"; 40 | char hostHeader[64]; 41 | sprintf(hostHeader,INSERT_HOST,host); 42 | 43 | char INSERT_USER_AGENT[] = "User-Agent: %s "; 44 | char UserAgentHeader[sizeof(INSERT_USER_AGENT)+sizeof(DEVICE)+2]; 45 | snprintf(UserAgentHeader, sizeof(UserAgentHeader), INSERT_USER_AGENT, DEVICE); 46 | 47 | client.println(requestHeader); 48 | client.println(hostHeader); 49 | client.println(UserAgentHeader); 50 | client.println("Connection: keep-alive"); 51 | if(DEBUG){ 52 | debugPort->println(requestHeader); 53 | debugPort->println(hostHeader); 54 | debugPort->println(UserAgentHeader); 55 | debugPort->println("Connection: keep-alive"); 56 | 57 | } 58 | 59 | if((method == GET_METHOD) || (method == OTA_METHOD)){ 60 | client.println(); 61 | if(DEBUG) debugPort->println(); 62 | } else 63 | if(method == POST_METHOD){ 64 | client.println("Content-Type: application/x-www-form-urlencoded"); 65 | client.println(postContentHeader); 66 | client.println(); 67 | client.print(postData); 68 | if(DEBUG){ 69 | debugPort->println("Content-Type: application/x-www-form-urlencoded"); 70 | debugPort->println(postContentHeader); 71 | debugPort->println(); 72 | debugPort->print(postData); 73 | } 74 | } 75 | 76 | 77 | 78 | // handle response 79 | boolean eoh = false; 80 | bool foundHTTP = false; 81 | int statusCode = 0; 82 | bool foundContentLength = false; 83 | char contentType[64]; 84 | int contentTypeCount = 0; 85 | bool binaryFileFound = 0; 86 | bool jsonFileFound = 0; 87 | bool otherFileFound = 0; 88 | long contentLength = -1; 89 | String searchBuffer; 90 | unsigned long ResponseDelayTimer = millis(); 91 | 92 | while((millis() - ResponseDelayTimer < HTTPResponseTime) || client.available()){ 93 | if(!eoh){ 94 | if(!foundHTTP) foundHTTP = client.find("HTTP/1.1 "); 95 | else if(!statusCode) statusCode = client.parseInt(); 96 | if(statusCode){ 97 | searchBuffer = client.readStringUntil(':'); 98 | if(DEBUG) debugPort->println(searchBuffer); 99 | if(searchBuffer.equals("Content-Length") ) 100 | { 101 | char c = client.peek(); if(c == ' '){client.read();} 102 | contentLength = client.parseInt(SKIP_NONE); 103 | c = client.peek(); 104 | while((c == '\r') || (c == '\r')){ client.read();c = client.peek();} 105 | } 106 | else 107 | if(searchBuffer.equals("Content-Type")) 108 | { 109 | char c = client.peek(); if(c == ' '){client.read();} 110 | contentTypeCount = client.readBytesUntil('\r',contentType,sizeof(contentType)); contentType[contentTypeCount] = '\0'; 111 | if(strcmp(contentType,"application/octet-stream") ==0) binaryFileFound = true; else 112 | if(strcmp(contentType,"application/json") ==0) jsonFileFound = true; else 113 | otherFileFound= true; 114 | client.read(); 115 | } 116 | else 117 | client.readStringUntil('\n'); 118 | char c = client.peek(); 119 | if(c == '\r'){eoh = client.find("\n");} 120 | 121 | 122 | }// end eoh 123 | if(eoh) break; 124 | } 125 | }// end while avaible 126 | if(DEBUG ){ 127 | debugPort->println("found end of header"); 128 | debugPort->println(); 129 | debugPort->print("foundHTTP: ");debugPort->println(foundHTTP); 130 | debugPort->print("statusCode: ");debugPort->println(statusCode); 131 | debugPort->print("foundContentLength: ");debugPort->println(contentLength); 132 | debugPort->print("contentTypeCount: ");debugPort->println(contentTypeCount); 133 | debugPort->print("contentType: ");debugPort->println(contentType); 134 | debugPort->print("binaryFileFound: ");debugPort->println(binaryFileFound); 135 | debugPort->print("jsonFileFound: ");debugPort->println(jsonFileFound); 136 | debugPort->print("otherFileFound: ");debugPort->println(otherFileFound); 137 | debugPort->print("found end-of-header: ");debugPort->println(eoh); 138 | debugPort->println(); 139 | } 140 | 141 | if((method == OTA_METHOD) && (!binaryFileFound)) contentLength = -2; 142 | 143 | return contentLength; 144 | } 145 | 146 | 147 | 148 | 149 | long HTTPGETRequest(const char* host, const char* path, Stream &client){ 150 | 151 | long contentLength = HTTPRequest( GET_METHOD, host, path, "",client); 152 | 153 | return contentLength; 154 | } 155 | 156 | 157 | long HTTPPOSTRequest(const char* host, const char* path, const char* postData, Stream &client){ 158 | 159 | long contentLength = HTTPRequest( POST_METHOD, host, path, postData,client); 160 | 161 | return contentLength; 162 | } 163 | 164 | long HTTPOTARequest(const char* host, const char* path, Stream &client){ 165 | 166 | long contentLength = HTTPRequest( OTA_METHOD, host, path, "",client ); 167 | 168 | return contentLength; 169 | 170 | 171 | } 172 | 173 | 174 | 175 | void emptyRequestBuffer(Stream &client, bool print){ 176 | unsigned long emptyBufferTime = millis() + 250; 177 | while( client.available() || (emptyBufferTime > millis())) 178 | { 179 | if(client.available()) 180 | { 181 | if(DEBUG && print) debugPort->write(client.read()); 182 | else client.read(); 183 | } 184 | } 185 | } 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/examples/DownloadLatestFW/JustHTTPClient.h: -------------------------------------------------------------------------------- 1 | #ifndef _JUSTHTTP_ 2 | #define _JUSTHTTP_ 3 | #include "arduino_secrets.h" 4 | 5 | 6 | 7 | 8 | const byte GET_METHOD = 1; 9 | const byte POST_METHOD = 2; 10 | const byte OTA_METHOD = 3; 11 | 12 | long HTTPGETRequest(const char* host, const char* path, Stream &client ); 13 | long HTTPPOSTRequest(const char* host, const char* path, const char* postData, Stream &client ); 14 | long HTTPOTARequest(const char* host, const char* path, Stream &client ); 15 | 16 | long HTTPRequest(byte method, const char* host, const char* path, const char* postData, Stream &client ); 17 | void emptyRequestBuffer(Stream &client , bool print = true); 18 | 19 | 20 | 21 | long HTTPRequest(byte method, const char* host, const char* path, const char* postData, Stream &client ){ 22 | char pathHeader[] = "%s %s HTTP/1.1"; 23 | char requestHeader[128]; 24 | char postContentHeader[64]; 25 | 26 | emptyRequestBuffer(client); 27 | 28 | 29 | if((method == GET_METHOD) || (method == OTA_METHOD)){ 30 | snprintf(requestHeader, sizeof(requestHeader), pathHeader, "GET", path); 31 | } 32 | else if(method == POST_METHOD) { 33 | snprintf(requestHeader, sizeof(requestHeader), pathHeader,"POST", path); 34 | char INSERT_LENGTH[] = "Content-Length: %i"; 35 | snprintf(postContentHeader,sizeof(postContentHeader),INSERT_LENGTH,strlen(postData)); 36 | } 37 | else return -2; 38 | 39 | char INSERT_HOST[] = "Host: %s"; 40 | char hostHeader[64]; 41 | sprintf(hostHeader,INSERT_HOST,host); 42 | 43 | char INSERT_USER_AGENT[] = "User-Agent: %s "; 44 | char UserAgentHeader[sizeof(INSERT_USER_AGENT)+sizeof(DEVICE)+2]; 45 | snprintf(UserAgentHeader, sizeof(UserAgentHeader), INSERT_USER_AGENT, DEVICE); 46 | 47 | client.println(requestHeader); 48 | client.println(hostHeader); 49 | client.println(UserAgentHeader); 50 | client.println("Connection: keep-alive"); 51 | if(DEBUG){ 52 | debugPort->println(requestHeader); 53 | debugPort->println(hostHeader); 54 | debugPort->println(UserAgentHeader); 55 | debugPort->println("Connection: keep-alive"); 56 | 57 | } 58 | 59 | if((method == GET_METHOD) || (method == OTA_METHOD)){ 60 | client.println(); 61 | if(DEBUG) debugPort->println(); 62 | } else 63 | if(method == POST_METHOD){ 64 | client.println("Content-Type: application/x-www-form-urlencoded"); 65 | client.println(postContentHeader); 66 | client.println(); 67 | client.print(postData); 68 | if(DEBUG){ 69 | debugPort->println("Content-Type: application/x-www-form-urlencoded"); 70 | debugPort->println(postContentHeader); 71 | debugPort->println(); 72 | debugPort->print(postData); 73 | } 74 | } 75 | 76 | 77 | 78 | // handle response 79 | boolean eoh = false; 80 | bool foundHTTP = false; 81 | int statusCode = 0; 82 | bool foundContentLength = false; 83 | char contentType[64]; 84 | int contentTypeCount = 0; 85 | bool binaryFileFound = 0; 86 | bool jsonFileFound = 0; 87 | bool otherFileFound = 0; 88 | long contentLength = -1; 89 | String searchBuffer; 90 | unsigned long ResponseDelayTimer = millis(); 91 | 92 | while((millis() - ResponseDelayTimer < HTTPResponseTime) || client.available()){ 93 | if(!eoh){ 94 | if(!foundHTTP) foundHTTP = client.find("HTTP/1.1 "); 95 | else if(!statusCode) statusCode = client.parseInt(); 96 | if(statusCode){ 97 | searchBuffer = client.readStringUntil(':'); 98 | if(DEBUG) debugPort->println(searchBuffer); 99 | if(searchBuffer.equals("Content-Length") ) 100 | { 101 | char c = client.peek(); if(c == ' '){client.read();} 102 | contentLength = client.parseInt(SKIP_NONE); 103 | c = client.peek(); 104 | while((c == '\r') || (c == '\r')){ client.read();c = client.peek();} 105 | } 106 | else 107 | if(searchBuffer.equals("Content-Type")) 108 | { 109 | char c = client.peek(); if(c == ' '){client.read();} 110 | contentTypeCount = client.readBytesUntil('\r',contentType,sizeof(contentType)); contentType[contentTypeCount] = '\0'; 111 | if(strcmp(contentType,"application/octet-stream") ==0) binaryFileFound = true; else 112 | if(strcmp(contentType,"application/json") ==0) jsonFileFound = true; else 113 | otherFileFound= true; 114 | client.read(); 115 | } 116 | else 117 | client.readStringUntil('\n'); 118 | char c = client.peek(); 119 | if(c == '\r'){eoh = client.find("\n");} 120 | 121 | 122 | }// end eoh 123 | if(eoh) break; 124 | } 125 | }// end while avaible 126 | if(DEBUG ){ 127 | debugPort->println("found end of header"); 128 | debugPort->println(); 129 | debugPort->print("foundHTTP: ");debugPort->println(foundHTTP); 130 | debugPort->print("statusCode: ");debugPort->println(statusCode); 131 | debugPort->print("foundContentLength: ");debugPort->println(contentLength); 132 | debugPort->print("contentTypeCount: ");debugPort->println(contentTypeCount); 133 | debugPort->print("contentType: ");debugPort->println(contentType); 134 | debugPort->print("binaryFileFound: ");debugPort->println(binaryFileFound); 135 | debugPort->print("jsonFileFound: ");debugPort->println(jsonFileFound); 136 | debugPort->print("otherFileFound: ");debugPort->println(otherFileFound); 137 | debugPort->print("found end-of-header: ");debugPort->println(eoh); 138 | debugPort->println(); 139 | } 140 | 141 | if((method == OTA_METHOD) && (!binaryFileFound)) contentLength = -2; 142 | 143 | return contentLength; 144 | } 145 | 146 | 147 | 148 | 149 | long HTTPGETRequest(const char* host, const char* path, Stream &client){ 150 | 151 | long contentLength = HTTPRequest( GET_METHOD, host, path, "",client); 152 | 153 | return contentLength; 154 | } 155 | 156 | 157 | long HTTPPOSTRequest(const char* host, const char* path, const char* postData, Stream &client){ 158 | 159 | long contentLength = HTTPRequest( POST_METHOD, host, path, postData,client); 160 | 161 | return contentLength; 162 | } 163 | 164 | long HTTPOTARequest(const char* host, const char* path, Stream &client){ 165 | 166 | long contentLength = HTTPRequest( OTA_METHOD, host, path, "",client ); 167 | 168 | return contentLength; 169 | 170 | 171 | } 172 | 173 | 174 | 175 | void emptyRequestBuffer(Stream &client, bool print){ 176 | unsigned long emptyBufferTime = millis() + 250; 177 | while( client.available() || (emptyBufferTime > millis())) 178 | { 179 | if(client.available()) 180 | { 181 | if(DEBUG && print) debugPort->write(client.read()); 182 | else client.read(); 183 | } 184 | } 185 | } 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /ESP32/SDcard.ino: -------------------------------------------------------------------------------- 1 | 2 | //HSPI MOSI=13, MISO=12, CLK=14, CS=25 3 | //VSPI MOSI=23, MISO=19, CLK=18, CS=25 4 | 5 | void getFileNames() { 6 | Serial.println("Looking for files"); 7 | File root; 8 | root = SD.open("/"); 9 | while (true) { 10 | 11 | File entry = root.openNextFile(); 12 | if (!entry) { 13 | // no more files 14 | break; 15 | } 16 | char *pointerTobootloaderKey = strstr(entry.name(), bootloaderKey); //go find keyword 17 | if (pointerTobootloaderKey != NULL) { 18 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 19 | if (pointerToHiddenFile == NULL) { //good not hidden file 20 | Serial.print("Found Bootloader File: "); 21 | strcpy(bootloaderName, "/"); 22 | strcat(bootloaderName, entry.name()); 23 | //strncpy(bootloaderName, entry.name(), sizeof(bootloaderName)); 24 | Serial.println(bootloaderName); 25 | } 26 | } 27 | char *pointerTobootKey = strstr(entry.name(), bootKey); //go find keyword 28 | if (pointerTobootKey != NULL) { 29 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 30 | if (pointerToHiddenFile == NULL) { //good not hidden file 31 | Serial.print("Found Boot File: "); 32 | strcpy(bootName, "/"); 33 | strcat(bootName, entry.name()); 34 | //strncpy(bootName, entry.name(), sizeof(bootName)); 35 | Serial.println(bootName); 36 | } 37 | } 38 | char *pointerToPartitionsKey = strstr(entry.name(), partitionsKey); //go find keyword 39 | if (pointerToPartitionsKey != NULL) { 40 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 41 | if (pointerToHiddenFile == NULL) { //good not hidden file 42 | Serial.print("Found Partitions File: "); 43 | strcpy(partitionsName, "/"); 44 | strcat(partitionsName, entry.name()); 45 | //strncpy(partitionsName, entry.name(), sizeof(partitionsName)); 46 | Serial.println(partitionsName); 47 | } 48 | } 49 | char *pointerToFirmwareKey = strstr(entry.name(), firmwareKey); //go find keyword 50 | if (pointerToFirmwareKey != NULL) { 51 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 52 | if (pointerToHiddenFile == NULL) { //good not hidden file 53 | Serial.print("Found Firmware File: "); 54 | strcpy(firmwareName, "/"); 55 | strcat(firmwareName, entry.name()); 56 | //strncpy(firmwareName, entry.name(), sizeof(firmwareName)); 57 | Serial.println(firmwareName); 58 | } 59 | } 60 | char *pointerToFirmwareSecondKey = strstr(entry.name(), firmwareSecondKey); //go find keyword 61 | if (pointerToFirmwareSecondKey != NULL) { 62 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 63 | if (pointerToHiddenFile == NULL) { //good not hidden file 64 | Serial.print("Found Firmware File: "); 65 | strcpy(firmwareName, "/"); 66 | strcat(firmwareName, entry.name()); 67 | //strncpy(firmwareName, entry.name(), sizeof(firmwareName)); 68 | Serial.println(firmwareName); 69 | } 70 | } 71 | 72 | char *pointerToSPIFFSKey = strstr(entry.name(), SPIFFSKey); //go find keyword 73 | if (pointerToSPIFFSKey != NULL) { 74 | char *pointerToHiddenFile = strstr(entry.name(), hiddenFileKey); 75 | if (pointerToHiddenFile == NULL) { //good not hidden file 76 | Serial.print("Found SPIFFS File: "); 77 | strcpy(spiffsName, "/"); 78 | strcat(spiffsName, entry.name()); 79 | //strncpy(spiffsName, entry.name(), sizeof(spiffsName)); 80 | Serial.println(spiffsName); 81 | flashSPIFFS = true; 82 | } 83 | } 84 | 85 | Serial.println(entry.name()); 86 | // if (entry.isDirectory()) { 87 | // Serial.println(" / "); 88 | // //printDirectory(entry, numTabs + 1); 89 | // } else { 90 | // // files have sizes, directories do not 91 | // Serial.print("\t\t"); 92 | // Serial.println(entry.size(), DEC); 93 | // } 94 | entry.close(); 95 | } 96 | } 97 | 98 | 99 | void initSDcard() { 100 | //spiSD.begin(14, 12, 13, SD_CS); //SCK,MISO,MOSI,SS //HSPI1 101 | spiSD.begin(18, 19, 23, SD_CS_pin); //SCK,MISO,MOSI,SS //HSPI1 102 | while (!SD.begin(SD_CS_pin, spiSD)) { 103 | Serial.println("Card Mount Failed"); 104 | delay(1000); 105 | } 106 | 107 | 108 | uint8_t cardType = SD.cardType(); 109 | 110 | if (cardType == CARD_NONE) { 111 | Serial.println("No SD card attached"); 112 | return; 113 | } 114 | Serial.print("SD Card Type: "); 115 | if (cardType == CARD_MMC) { 116 | Serial.println("MMC"); 117 | } else if (cardType == CARD_SD) { 118 | Serial.println("SDSC"); 119 | } else if (cardType == CARD_SDHC) { 120 | Serial.println("SDHC"); 121 | } else { 122 | Serial.println("UNKNOWN"); 123 | } 124 | 125 | 126 | String bootNameOffsetStr = SD_findString(F("bootNameOffset")); 127 | String bootloaderNameOffsetStr = SD_findString(F("bootloaderNameOffset")); 128 | String partitionsNameOffsetStr = SD_findString(F("partitionsNameOffset")); 129 | String firmwareNameOffsetStr = SD_findString(F("firmwareNameOffset")); 130 | String spiffsNameOffsetStr = SD_findString(F("spiffsNameOffset")); 131 | 132 | 133 | /* default 134 | bootNameOffset=0xe000 135 | bootloaderNameOffset=0x1000 136 | partitionsNameOffset=0x8000 137 | firmwareNameOffset=0x10000 138 | spiffsNameOffset=0x3D0000 139 | */ 140 | 141 | char *bootNameOffsetchar = const_cast(bootNameOffsetStr.c_str()); 142 | bootNameOffset = strtoul(bootNameOffsetchar, NULL, 0); 143 | 144 | char *bootloaderNameOffsetchar = const_cast(bootloaderNameOffsetStr.c_str()); 145 | bootloaderNameOffset = strtoul(bootloaderNameOffsetchar, NULL, 0); 146 | 147 | char *partitionsNameOffsetchar = const_cast(partitionsNameOffsetStr.c_str()); 148 | partitionsNameOffset = strtoul(partitionsNameOffsetchar, NULL, 0); 149 | 150 | char *firmwareNameOffsetchar = const_cast(firmwareNameOffsetStr.c_str()); 151 | firmwareNameOffset = strtoul(firmwareNameOffsetchar, NULL, 0); 152 | 153 | char *spiffsNameOffsetchar = const_cast(spiffsNameOffsetStr.c_str()); 154 | spiffsNameOffset = strtoul(spiffsNameOffsetchar, NULL, 0); 155 | 156 | 157 | Serial.printf("%s -> 0x%.2x bootNameOffset\n", bootNameOffsetStr, bootNameOffset); 158 | Serial.printf("%s -> 0x%.2x bootloaderNameOffset\n", bootloaderNameOffsetStr, bootloaderNameOffset); 159 | Serial.printf("%s -> 0x%.2x partitionsNameOffset\n", partitionsNameOffsetStr, partitionsNameOffset); 160 | Serial.printf("%s -> 0x%.2x firmwareNameOffset\n", firmwareNameOffsetStr, firmwareNameOffset); 161 | Serial.printf("%s -> 0x%.2x spiffsNameOffset\n", spiffsNameOffsetStr, spiffsNameOffset); 162 | 163 | 164 | 165 | 166 | 167 | 168 | // uint64_t cardSize = SD.cardSize() / (1024 * 1024); 169 | // Serial.printf("SD Card Size: % lluMB\n", cardSize); 170 | 171 | getFileNames(); 172 | 173 | if (bootName[0] == NULL || bootloaderName[0] == NULL || partitionsName[0] == NULL || firmwareName[0] == NULL) { 174 | Serial.println("ERROR - not all files found!!!"); 175 | while (1) { 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/esp_targets.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #include "esp_targets.h" 17 | #include 18 | 19 | typedef esp_loader_error_t (*read_spi_config_t)(uint32_t efuse_base, uint32_t *spi_config); 20 | 21 | typedef struct { 22 | target_registers_t regs; 23 | uint32_t efuse_base; 24 | uint32_t chip_magic_value; 25 | read_spi_config_t read_spi_config; 26 | } esp_target_t; 27 | 28 | // This ROM address has a different value on each chip model 29 | #define CHIP_DETECT_MAGIC_REG_ADDR 0x40001000 30 | 31 | #define ESP8266_SPI_REG_BASE 0x60000200 32 | #define ESP32S2_SPI_REG_BASE 0x3f402000 33 | #define ESP32C3_SPI_REG_BASE 0x60002000 34 | #define ESP32S3_SPI_REG_BASE 0x60002000 35 | #define ESP32_SPI_REG_BASE 0x3ff42000 36 | #define ESP32S3_SPI_REG_BASE 0x60002000 37 | 38 | 39 | 40 | static esp_loader_error_t spi_config_esp32(uint32_t efuse_base, uint32_t *spi_config); 41 | static esp_loader_error_t spi_config_esp32xx(uint32_t efuse_base, uint32_t *spi_config); 42 | 43 | static const esp_target_t esp_target[ESP_MAX_CHIP] = { 44 | 45 | // ESP8266 46 | { 47 | .regs = { 48 | .cmd = ESP8266_SPI_REG_BASE + 0x00, 49 | .usr = ESP8266_SPI_REG_BASE + 0x1c, 50 | .usr1 = ESP8266_SPI_REG_BASE + 0x20, 51 | .usr2 = ESP8266_SPI_REG_BASE + 0x24, 52 | .w0 = ESP8266_SPI_REG_BASE + 0x40, 53 | .mosi_dlen = 0, 54 | .miso_dlen = 0, 55 | }, 56 | .efuse_base = 0, // Not used 57 | .chip_magic_value = 0xfff0c101, 58 | .read_spi_config = NULL, // Not used 59 | }, 60 | 61 | // ESP32 62 | { 63 | .regs = { 64 | .cmd = ESP32_SPI_REG_BASE + 0x00, 65 | .usr = ESP32_SPI_REG_BASE + 0x1c, 66 | .usr1 = ESP32_SPI_REG_BASE + 0x20, 67 | .usr2 = ESP32_SPI_REG_BASE + 0x24, 68 | .w0 = ESP32_SPI_REG_BASE + 0x80, 69 | .mosi_dlen = ESP32_SPI_REG_BASE + 0x28, 70 | .miso_dlen = ESP32_SPI_REG_BASE + 0x2c, 71 | }, 72 | .efuse_base = 0x3ff5A000, 73 | .chip_magic_value = 0x00f01d83, 74 | .read_spi_config = spi_config_esp32, 75 | }, 76 | 77 | // ESP32S2 78 | { 79 | .regs = { 80 | .cmd = ESP32S2_SPI_REG_BASE + 0x00, 81 | .usr = ESP32S2_SPI_REG_BASE + 0x18, 82 | .usr1 = ESP32S2_SPI_REG_BASE + 0x1c, 83 | .usr2 = ESP32S2_SPI_REG_BASE + 0x20, 84 | .w0 = ESP32S2_SPI_REG_BASE + 0x58, 85 | .mosi_dlen = ESP32S2_SPI_REG_BASE + 0x24, 86 | .miso_dlen = ESP32S2_SPI_REG_BASE + 0x28, 87 | }, 88 | .efuse_base = 0x3f41A000, 89 | .chip_magic_value = 0x000007c6, 90 | .read_spi_config = spi_config_esp32xx, 91 | }, 92 | 93 | // ESP32C3 94 | { 95 | .regs = { 96 | .cmd = ESP32C3_SPI_REG_BASE + 0x00, 97 | .usr = ESP32C3_SPI_REG_BASE + 0x18, 98 | .usr1 = ESP32C3_SPI_REG_BASE + 0x1c, 99 | .usr2 = ESP32C3_SPI_REG_BASE + 0x20, 100 | .w0 = ESP32C3_SPI_REG_BASE + 0x58, 101 | .mosi_dlen = ESP32C3_SPI_REG_BASE + 0x24, 102 | .miso_dlen = ESP32C3_SPI_REG_BASE + 0x28, 103 | }, 104 | .efuse_base = 0x60008800, 105 | .chip_magic_value = 0x1b31506f,//was 0x6921506f 106 | .read_spi_config = spi_config_esp32xx, 107 | }, 108 | 109 | // ESP32S3 110 | { 111 | .regs = { 112 | .cmd = ESP32C3_SPI_REG_BASE + 0x00, 113 | .usr = ESP32C3_SPI_REG_BASE + 0x18, 114 | .usr1 = ESP32C3_SPI_REG_BASE + 0x1c, 115 | .usr2 = ESP32C3_SPI_REG_BASE + 0x20, 116 | .w0 = ESP32C3_SPI_REG_BASE + 0x58, 117 | .mosi_dlen = ESP32C3_SPI_REG_BASE + 0x24, 118 | .miso_dlen = ESP32C3_SPI_REG_BASE + 0x28, 119 | }, 120 | .efuse_base = 0x60007000, 121 | .chip_magic_value = 0x00000009, 122 | .read_spi_config = spi_config_esp32xx, // ! 123 | }, 124 | }; 125 | 126 | const target_registers_t *get_esp_target_data(target_chip_t chip) 127 | { 128 | return (target_registers_t *)&esp_target[chip]; 129 | } 130 | 131 | esp_loader_error_t loader_detect_chip(target_chip_t *target_chip, const target_registers_t **target_data) 132 | { 133 | uint32_t magic_value; 134 | RETURN_ON_ERROR( esp_loader_read_register(CHIP_DETECT_MAGIC_REG_ADDR, &magic_value) ); 135 | 136 | for (int chip = 0; chip < ESP_MAX_CHIP; chip++) { 137 | if (magic_value == esp_target[chip].chip_magic_value) { 138 | *target_chip = (target_chip_t)chip; 139 | *target_data = (target_registers_t *)&esp_target[chip]; 140 | return ESP_LOADER_SUCCESS; 141 | } 142 | } 143 | 144 | return ESP_LOADER_ERROR_INVALID_TARGET; 145 | } 146 | 147 | esp_loader_error_t loader_read_spi_config(target_chip_t target_chip, uint32_t *spi_config) 148 | { 149 | const esp_target_t *target = &esp_target[target_chip]; 150 | return target->read_spi_config(target->efuse_base, spi_config); 151 | } 152 | 153 | static inline uint32_t efuse_word_addr(uint32_t efuse_base, uint32_t n) 154 | { 155 | return efuse_base + (n * 4); 156 | } 157 | 158 | // 30->GPIO32 | 31->GPIO33 159 | static inline uint8_t adjust_pin_number(uint8_t num) 160 | { 161 | return (num >= 30) ? num + 2 : num; 162 | } 163 | 164 | 165 | static esp_loader_error_t spi_config_esp32(uint32_t efuse_base, uint32_t *spi_config) 166 | { 167 | *spi_config = 0; 168 | 169 | uint32_t reg5, reg3; 170 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 5), ®5) ); 171 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 3), ®3) ); 172 | 173 | uint32_t pins = reg5 & 0xfffff; 174 | 175 | if (pins == 0 || pins == 0xfffff) { 176 | return ESP_LOADER_SUCCESS; 177 | } 178 | 179 | uint8_t clk = adjust_pin_number( (pins >> 0) & 0x1f ); 180 | uint8_t q = adjust_pin_number( (pins >> 5) & 0x1f ); 181 | uint8_t d = adjust_pin_number( (pins >> 10) & 0x1f ); 182 | uint8_t cs = adjust_pin_number( (pins >> 15) & 0x1f ); 183 | uint8_t hd = adjust_pin_number( (reg3 >> 4) & 0x1f ); 184 | 185 | if (clk == cs || clk == d || clk == q || q == cs || q == d || q == d) { 186 | return ESP_LOADER_SUCCESS; 187 | } 188 | 189 | *spi_config = (hd << 24) | (cs << 18) | (d << 12) | (q << 6) | clk; 190 | 191 | return ESP_LOADER_SUCCESS; 192 | } 193 | 194 | // Applies for esp32s2, esp32c3 and esp32c3 195 | static esp_loader_error_t spi_config_esp32xx(uint32_t efuse_base, uint32_t *spi_config) 196 | { 197 | *spi_config = 0; 198 | 199 | uint32_t reg1, reg2; 200 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 18), ®1) ); 201 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 19), ®2) ); 202 | 203 | uint32_t pins = ((reg1 >> 16) | ((reg2 & 0xfffff) << 16)) & 0x3fffffff; 204 | 205 | if (pins == 0 || pins == 0xffffffff) { 206 | return ESP_LOADER_SUCCESS; 207 | } 208 | 209 | *spi_config = pins; 210 | return ESP_LOADER_SUCCESS; 211 | } -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/esp_targets.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #include "esp_targets.h" 17 | #include 18 | 19 | typedef esp_loader_error_t (*read_spi_config_t)(uint32_t efuse_base, uint32_t *spi_config); 20 | 21 | typedef struct { 22 | target_registers_t regs; 23 | uint32_t efuse_base; 24 | uint32_t chip_magic_value; 25 | read_spi_config_t read_spi_config; 26 | } esp_target_t; 27 | 28 | // This ROM address has a different value on each chip model 29 | #define CHIP_DETECT_MAGIC_REG_ADDR 0x40001000 30 | 31 | #define ESP8266_SPI_REG_BASE 0x60000200 32 | #define ESP32S2_SPI_REG_BASE 0x3f402000 33 | #define ESP32C3_SPI_REG_BASE 0x60002000 34 | #define ESP32S3_SPI_REG_BASE 0x60002000 35 | #define ESP32_SPI_REG_BASE 0x3ff42000 36 | #define ESP32S3_SPI_REG_BASE 0x60002000 37 | 38 | 39 | 40 | static esp_loader_error_t spi_config_esp32(uint32_t efuse_base, uint32_t *spi_config); 41 | static esp_loader_error_t spi_config_esp32xx(uint32_t efuse_base, uint32_t *spi_config); 42 | 43 | static const esp_target_t esp_target[ESP_MAX_CHIP] = { 44 | 45 | // ESP8266 46 | { 47 | .regs = { 48 | .cmd = ESP8266_SPI_REG_BASE + 0x00, 49 | .usr = ESP8266_SPI_REG_BASE + 0x1c, 50 | .usr1 = ESP8266_SPI_REG_BASE + 0x20, 51 | .usr2 = ESP8266_SPI_REG_BASE + 0x24, 52 | .w0 = ESP8266_SPI_REG_BASE + 0x40, 53 | .mosi_dlen = 0, 54 | .miso_dlen = 0, 55 | }, 56 | .efuse_base = 0, // Not used 57 | .chip_magic_value = 0xfff0c101, 58 | .read_spi_config = NULL, // Not used 59 | }, 60 | 61 | // ESP32 62 | { 63 | .regs = { 64 | .cmd = ESP32_SPI_REG_BASE + 0x00, 65 | .usr = ESP32_SPI_REG_BASE + 0x1c, 66 | .usr1 = ESP32_SPI_REG_BASE + 0x20, 67 | .usr2 = ESP32_SPI_REG_BASE + 0x24, 68 | .w0 = ESP32_SPI_REG_BASE + 0x80, 69 | .mosi_dlen = ESP32_SPI_REG_BASE + 0x28, 70 | .miso_dlen = ESP32_SPI_REG_BASE + 0x2c, 71 | }, 72 | .efuse_base = 0x3ff5A000, 73 | .chip_magic_value = 0x00f01d83, 74 | .read_spi_config = spi_config_esp32, 75 | }, 76 | 77 | // ESP32S2 78 | { 79 | .regs = { 80 | .cmd = ESP32S2_SPI_REG_BASE + 0x00, 81 | .usr = ESP32S2_SPI_REG_BASE + 0x18, 82 | .usr1 = ESP32S2_SPI_REG_BASE + 0x1c, 83 | .usr2 = ESP32S2_SPI_REG_BASE + 0x20, 84 | .w0 = ESP32S2_SPI_REG_BASE + 0x58, 85 | .mosi_dlen = ESP32S2_SPI_REG_BASE + 0x24, 86 | .miso_dlen = ESP32S2_SPI_REG_BASE + 0x28, 87 | }, 88 | .efuse_base = 0x3f41A000, 89 | .chip_magic_value = 0x000007c6, 90 | .read_spi_config = spi_config_esp32xx, 91 | }, 92 | 93 | // ESP32C3 94 | { 95 | .regs = { 96 | .cmd = ESP32C3_SPI_REG_BASE + 0x00, 97 | .usr = ESP32C3_SPI_REG_BASE + 0x18, 98 | .usr1 = ESP32C3_SPI_REG_BASE + 0x1c, 99 | .usr2 = ESP32C3_SPI_REG_BASE + 0x20, 100 | .w0 = ESP32C3_SPI_REG_BASE + 0x58, 101 | .mosi_dlen = ESP32C3_SPI_REG_BASE + 0x24, 102 | .miso_dlen = ESP32C3_SPI_REG_BASE + 0x28, 103 | }, 104 | .efuse_base = 0x60008800, 105 | .chip_magic_value = 0x1b31506f,//was 0x6921506f 106 | .read_spi_config = spi_config_esp32xx, 107 | }, 108 | 109 | // ESP32S3 110 | { 111 | .regs = { 112 | .cmd = ESP32C3_SPI_REG_BASE + 0x00, 113 | .usr = ESP32C3_SPI_REG_BASE + 0x18, 114 | .usr1 = ESP32C3_SPI_REG_BASE + 0x1c, 115 | .usr2 = ESP32C3_SPI_REG_BASE + 0x20, 116 | .w0 = ESP32C3_SPI_REG_BASE + 0x58, 117 | .mosi_dlen = ESP32C3_SPI_REG_BASE + 0x24, 118 | .miso_dlen = ESP32C3_SPI_REG_BASE + 0x28, 119 | }, 120 | .efuse_base = 0x60007000, 121 | .chip_magic_value = 0x00000009, 122 | .read_spi_config = spi_config_esp32xx, // ! 123 | }, 124 | }; 125 | 126 | const target_registers_t *get_esp_target_data(target_chip_t chip) 127 | { 128 | return (target_registers_t *)&esp_target[chip]; 129 | } 130 | 131 | esp_loader_error_t loader_detect_chip(target_chip_t *target_chip, const target_registers_t **target_data) 132 | { 133 | uint32_t magic_value; 134 | RETURN_ON_ERROR( esp_loader_read_register(CHIP_DETECT_MAGIC_REG_ADDR, &magic_value) ); 135 | 136 | for (int chip = 0; chip < ESP_MAX_CHIP; chip++) { 137 | if (magic_value == esp_target[chip].chip_magic_value) { 138 | *target_chip = (target_chip_t)chip; 139 | *target_data = (target_registers_t *)&esp_target[chip]; 140 | return ESP_LOADER_SUCCESS; 141 | } 142 | } 143 | 144 | return ESP_LOADER_ERROR_INVALID_TARGET; 145 | } 146 | 147 | esp_loader_error_t loader_read_spi_config(target_chip_t target_chip, uint32_t *spi_config) 148 | { 149 | const esp_target_t *target = &esp_target[target_chip]; 150 | return target->read_spi_config(target->efuse_base, spi_config); 151 | } 152 | 153 | static inline uint32_t efuse_word_addr(uint32_t efuse_base, uint32_t n) 154 | { 155 | return efuse_base + (n * 4); 156 | } 157 | 158 | // 30->GPIO32 | 31->GPIO33 159 | static inline uint8_t adjust_pin_number(uint8_t num) 160 | { 161 | return (num >= 30) ? num + 2 : num; 162 | } 163 | 164 | 165 | static esp_loader_error_t spi_config_esp32(uint32_t efuse_base, uint32_t *spi_config) 166 | { 167 | *spi_config = 0; 168 | 169 | uint32_t reg5, reg3; 170 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 5), ®5) ); 171 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 3), ®3) ); 172 | 173 | uint32_t pins = reg5 & 0xfffff; 174 | 175 | if (pins == 0 || pins == 0xfffff) { 176 | return ESP_LOADER_SUCCESS; 177 | } 178 | 179 | uint8_t clk = adjust_pin_number( (pins >> 0) & 0x1f ); 180 | uint8_t q = adjust_pin_number( (pins >> 5) & 0x1f ); 181 | uint8_t d = adjust_pin_number( (pins >> 10) & 0x1f ); 182 | uint8_t cs = adjust_pin_number( (pins >> 15) & 0x1f ); 183 | uint8_t hd = adjust_pin_number( (reg3 >> 4) & 0x1f ); 184 | 185 | if (clk == cs || clk == d || clk == q || q == cs || q == d || q == d) { 186 | return ESP_LOADER_SUCCESS; 187 | } 188 | 189 | *spi_config = (hd << 24) | (cs << 18) | (d << 12) | (q << 6) | clk; 190 | 191 | return ESP_LOADER_SUCCESS; 192 | } 193 | 194 | // Applies for esp32s2, esp32c3 and esp32c3 195 | static esp_loader_error_t spi_config_esp32xx(uint32_t efuse_base, uint32_t *spi_config) 196 | { 197 | *spi_config = 0; 198 | 199 | uint32_t reg1, reg2; 200 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 18), ®1) ); 201 | RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 19), ®2) ); 202 | 203 | uint32_t pins = ((reg1 >> 16) | ((reg2 & 0xfffff) << 16)) & 0x3fffffff; 204 | 205 | if (pins == 0 || pins == 0xffffffff) { 206 | return ESP_LOADER_SUCCESS; 207 | } 208 | 209 | *spi_config = pins; 210 | return ESP_LOADER_SUCCESS; 211 | } -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/esp_loader.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | #define MD5_ENABLED false 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | 26 | #ifndef MAX 27 | #define MAX(a, b) ((a) > (b)) ? (a) : (b) 28 | #endif 29 | 30 | #ifndef MIN 31 | #define MIN(a, b) ((a) < (b)) ? (a) : (b) 32 | #endif 33 | 34 | 35 | 36 | /** 37 | * Macro which can be used to check the error code, 38 | * and return in case the code is not ESP_LOADER_SUCCESS. 39 | */ 40 | #define RETURN_ON_ERROR(x) do { \ 41 | esp_loader_error_t _err_ = (x); \ 42 | if (_err_ != ESP_LOADER_SUCCESS) { \ 43 | return _err_; \ 44 | } \ 45 | } while(0) 46 | 47 | /** 48 | * @brief Error codes 49 | */ 50 | typedef enum { 51 | ESP_LOADER_SUCCESS, /*!< Success */ 52 | ESP_LOADER_ERROR_FAIL, /*!< Unspecified error */ 53 | ESP_LOADER_ERROR_TIMEOUT, /*!< Timeout elapsed */ 54 | ESP_LOADER_ERROR_IMAGE_SIZE, /*!< Image size to flash is larger than flash size */ 55 | ESP_LOADER_ERROR_INVALID_MD5, /*!< Computed and received MD5 does not match */ 56 | ESP_LOADER_ERROR_INVALID_PARAM, /*!< Invalid parameter passed to function */ 57 | ESP_LOADER_ERROR_INVALID_TARGET, /*!< Connected target is invalid */ 58 | ESP_LOADER_ERROR_UNSUPPORTED_CHIP, /*!< Attached chip is not supported */ 59 | ESP_LOADER_ERROR_UNSUPPORTED_FUNC, /*!< Function is not supported on attached target */ 60 | ESP_LOADER_ERROR_INVALID_RESPONSE /*!< Internal error */ 61 | } esp_loader_error_t; 62 | 63 | /** 64 | * @brief Supported targets 65 | */ 66 | typedef enum { 67 | ESP8266_CHIP = 0, 68 | ESP32_CHIP = 1, 69 | ESP32S2_CHIP = 2, 70 | ESP32C3_CHIP = 3, 71 | ESP32S3_CHIP = 4, 72 | ESP_MAX_CHIP = 5, 73 | ESP_UNKNOWN_CHIP = 5 74 | } target_chip_t; 75 | 76 | /** 77 | * @brief SPI pin configuration arguments 78 | */ 79 | typedef union { 80 | struct { 81 | uint32_t pin_clk: 6; 82 | uint32_t pin_q: 6; 83 | uint32_t pin_d: 6; 84 | uint32_t pin_cs: 6; 85 | uint32_t pin_hd: 6; 86 | uint32_t zero: 2; 87 | }; 88 | uint32_t val; 89 | } esp_loader_spi_config_t; 90 | 91 | /** 92 | * @brief Connection arguments 93 | */ 94 | typedef struct { 95 | uint32_t sync_timeout; /*!< Maximum time to wait for response from serial interface. */ 96 | int32_t trials; /*!< Number of trials to connect to target. If greater than 1, 97 | 100 millisecond delay is inserted after each try. */ 98 | } esp_loader_connect_args_t; 99 | 100 | #define ESP_LOADER_CONNECT_DEFAULT() { \ 101 | .sync_timeout = 100, \ 102 | .trials = 10, \ 103 | } 104 | 105 | /** 106 | * @brief Connects to the target 107 | * 108 | * @param connect_args[in] Timing parameters to be used for connecting to target. 109 | * 110 | * @return 111 | * - ESP_LOADER_SUCCESS Success 112 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 113 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 114 | */ 115 | esp_loader_error_t esp_loader_connect(esp_loader_connect_args_t *connect_args); 116 | 117 | /** 118 | * @brief Returns attached target chip. 119 | * 120 | * @warning This function can only be called after connection with target 121 | * has been successfully established by calling esp_loader_connect(). 122 | * 123 | * @return One of target_chip_t 124 | */ 125 | target_chip_t esp_loader_get_target(void); 126 | 127 | /** 128 | * @brief Initiates flash operation 129 | * 130 | * @param offset[in] Address from which flash operation will be performed. 131 | * @param image_size[in] Size of the whole binary to be loaded into flash. 132 | * @param block_size[in] Size of buffer used in subsequent calls to esp_loader_flash_write. 133 | * 134 | * @note image_size is size of the whole image, whereas, block_size is chunk of data sent 135 | * to the target, each time esp_loader_flash_write function is called. 136 | * 137 | * @return 138 | * - ESP_LOADER_SUCCESS Success 139 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 140 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 141 | */ 142 | esp_loader_error_t esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size); 143 | 144 | /** 145 | * @brief Writes supplied data to target's flash memory. 146 | * 147 | * @param payload[in] Data to be flashed into target's memory. 148 | * @param size[in] Size of payload in bytes. 149 | * 150 | * @note size must not be greater that block_size supplied to previously called 151 | * esp_loader_flash_start function. If size is less than block_size, 152 | * remaining bytes of payload buffer will be padded with 0xff. 153 | * Therefore, size of payload buffer has to be equal or greater than block_size. 154 | * 155 | * @return 156 | * - ESP_LOADER_SUCCESS Success 157 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 158 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 159 | */ 160 | esp_loader_error_t esp_loader_flash_write(void *payload, uint32_t size); 161 | 162 | /** 163 | * @brief Ends flash operation. 164 | * 165 | * @param reboot[in] reboot the target if true. 166 | * 167 | * @return 168 | * - ESP_LOADER_SUCCESS Success 169 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 170 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 171 | */ 172 | esp_loader_error_t esp_loader_flash_finish(bool reboot); 173 | 174 | /** 175 | * @brief Writes register. 176 | * 177 | * @param address[in] Address of register. 178 | * @param reg_value[in] New register value. 179 | * 180 | * @return 181 | * - ESP_LOADER_SUCCESS Success 182 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 183 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 184 | */ 185 | esp_loader_error_t esp_loader_write_register(uint32_t address, uint32_t reg_value); 186 | 187 | /** 188 | * @brief Reads register. 189 | * 190 | * @param address[in] Address of register. 191 | * @param reg_value[out] Register value. 192 | * 193 | * @return 194 | * - ESP_LOADER_SUCCESS Success 195 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 196 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 197 | */ 198 | esp_loader_error_t esp_loader_read_register(uint32_t address, uint32_t *reg_value); 199 | 200 | /** 201 | * @brief Change baud rate. 202 | * 203 | * @note Baud rate has to be also adjusted accordingly on host MCU, as 204 | * target's baud rate is changed upon return from this function. 205 | * 206 | * @param baudrate[in] new baud rate to be set. 207 | * 208 | * @return 209 | * - ESP_LOADER_SUCCESS Success 210 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 211 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 212 | * - ESP_LOADER_ERROR_UNSUPPORTED_FUNC Unsupported on the target 213 | */ 214 | esp_loader_error_t esp_loader_change_baudrate(uint32_t baudrate); 215 | 216 | /** 217 | * @brief Verify target's flash integrity by checking MD5. 218 | * MD5 checksum is computed from data pushed to target's memory by calling 219 | * esp_loader_flash_write() function and compared against target's MD5. 220 | * Target computes checksum based on offset and image_size passed to 221 | * esp_loader_flash_start() function. 222 | * 223 | * @note This function is only available if MD5_ENABLED is set. 224 | * 225 | * @return 226 | * - ESP_LOADER_SUCCESS Success 227 | * - ESP_LOADER_ERROR_INVALID_MD5 MD5 does not match 228 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 229 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 230 | * - ESP_LOADER_ERROR_UNSUPPORTED_FUNC Unsupported on the target 231 | */ 232 | esp_loader_error_t loader_eraseAllFlash_cmd(); 233 | 234 | #if MD5_ENABLED 235 | esp_loader_error_t esp_loader_flash_verify(void); 236 | #endif 237 | /** 238 | * @brief Toggles reset pin. 239 | */ 240 | void esp_loader_reset_target(void); 241 | 242 | 243 | 244 | #ifdef __cplusplus 245 | } 246 | #endif 247 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/esp_loader.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2020 Espressif Systems (Shanghai) PTE LTD 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | #define MD5_ENABLED false 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | 26 | #ifndef MAX 27 | #define MAX(a, b) ((a) > (b)) ? (a) : (b) 28 | #endif 29 | 30 | #ifndef MIN 31 | #define MIN(a, b) ((a) < (b)) ? (a) : (b) 32 | #endif 33 | 34 | 35 | 36 | /** 37 | * Macro which can be used to check the error code, 38 | * and return in case the code is not ESP_LOADER_SUCCESS. 39 | */ 40 | #define RETURN_ON_ERROR(x) do { \ 41 | esp_loader_error_t _err_ = (x); \ 42 | if (_err_ != ESP_LOADER_SUCCESS) { \ 43 | return _err_; \ 44 | } \ 45 | } while(0) 46 | 47 | /** 48 | * @brief Error codes 49 | */ 50 | typedef enum { 51 | ESP_LOADER_SUCCESS, /*!< Success */ 52 | ESP_LOADER_ERROR_FAIL, /*!< Unspecified error */ 53 | ESP_LOADER_ERROR_TIMEOUT, /*!< Timeout elapsed */ 54 | ESP_LOADER_ERROR_IMAGE_SIZE, /*!< Image size to flash is larger than flash size */ 55 | ESP_LOADER_ERROR_INVALID_MD5, /*!< Computed and received MD5 does not match */ 56 | ESP_LOADER_ERROR_INVALID_PARAM, /*!< Invalid parameter passed to function */ 57 | ESP_LOADER_ERROR_INVALID_TARGET, /*!< Connected target is invalid */ 58 | ESP_LOADER_ERROR_UNSUPPORTED_CHIP, /*!< Attached chip is not supported */ 59 | ESP_LOADER_ERROR_UNSUPPORTED_FUNC, /*!< Function is not supported on attached target */ 60 | ESP_LOADER_ERROR_INVALID_RESPONSE /*!< Internal error */ 61 | } esp_loader_error_t; 62 | 63 | /** 64 | * @brief Supported targets 65 | */ 66 | typedef enum { 67 | ESP8266_CHIP = 0, 68 | ESP32_CHIP = 1, 69 | ESP32S2_CHIP = 2, 70 | ESP32C3_CHIP = 3, 71 | ESP32S3_CHIP = 4, 72 | ESP_MAX_CHIP = 5, 73 | ESP_UNKNOWN_CHIP = 5 74 | } target_chip_t; 75 | 76 | /** 77 | * @brief SPI pin configuration arguments 78 | */ 79 | typedef union { 80 | struct { 81 | uint32_t pin_clk: 6; 82 | uint32_t pin_q: 6; 83 | uint32_t pin_d: 6; 84 | uint32_t pin_cs: 6; 85 | uint32_t pin_hd: 6; 86 | uint32_t zero: 2; 87 | }; 88 | uint32_t val; 89 | } esp_loader_spi_config_t; 90 | 91 | /** 92 | * @brief Connection arguments 93 | */ 94 | typedef struct { 95 | uint32_t sync_timeout; /*!< Maximum time to wait for response from serial interface. */ 96 | int32_t trials; /*!< Number of trials to connect to target. If greater than 1, 97 | 100 millisecond delay is inserted after each try. */ 98 | } esp_loader_connect_args_t; 99 | 100 | #define ESP_LOADER_CONNECT_DEFAULT() { \ 101 | .sync_timeout = 100, \ 102 | .trials = 10, \ 103 | } 104 | 105 | /** 106 | * @brief Connects to the target 107 | * 108 | * @param connect_args[in] Timing parameters to be used for connecting to target. 109 | * 110 | * @return 111 | * - ESP_LOADER_SUCCESS Success 112 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 113 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 114 | */ 115 | esp_loader_error_t esp_loader_connect(esp_loader_connect_args_t *connect_args); 116 | 117 | /** 118 | * @brief Returns attached target chip. 119 | * 120 | * @warning This function can only be called after connection with target 121 | * has been successfully established by calling esp_loader_connect(). 122 | * 123 | * @return One of target_chip_t 124 | */ 125 | target_chip_t esp_loader_get_target(void); 126 | 127 | /** 128 | * @brief Initiates flash operation 129 | * 130 | * @param offset[in] Address from which flash operation will be performed. 131 | * @param image_size[in] Size of the whole binary to be loaded into flash. 132 | * @param block_size[in] Size of buffer used in subsequent calls to esp_loader_flash_write. 133 | * 134 | * @note image_size is size of the whole image, whereas, block_size is chunk of data sent 135 | * to the target, each time esp_loader_flash_write function is called. 136 | * 137 | * @return 138 | * - ESP_LOADER_SUCCESS Success 139 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 140 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 141 | */ 142 | esp_loader_error_t esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size); 143 | 144 | /** 145 | * @brief Writes supplied data to target's flash memory. 146 | * 147 | * @param payload[in] Data to be flashed into target's memory. 148 | * @param size[in] Size of payload in bytes. 149 | * 150 | * @note size must not be greater that block_size supplied to previously called 151 | * esp_loader_flash_start function. If size is less than block_size, 152 | * remaining bytes of payload buffer will be padded with 0xff. 153 | * Therefore, size of payload buffer has to be equal or greater than block_size. 154 | * 155 | * @return 156 | * - ESP_LOADER_SUCCESS Success 157 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 158 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 159 | */ 160 | esp_loader_error_t esp_loader_flash_write(void *payload, uint32_t size); 161 | 162 | /** 163 | * @brief Ends flash operation. 164 | * 165 | * @param reboot[in] reboot the target if true. 166 | * 167 | * @return 168 | * - ESP_LOADER_SUCCESS Success 169 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 170 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 171 | */ 172 | esp_loader_error_t esp_loader_flash_finish(bool reboot); 173 | 174 | /** 175 | * @brief Writes register. 176 | * 177 | * @param address[in] Address of register. 178 | * @param reg_value[in] New register value. 179 | * 180 | * @return 181 | * - ESP_LOADER_SUCCESS Success 182 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 183 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 184 | */ 185 | esp_loader_error_t esp_loader_write_register(uint32_t address, uint32_t reg_value); 186 | 187 | /** 188 | * @brief Reads register. 189 | * 190 | * @param address[in] Address of register. 191 | * @param reg_value[out] Register value. 192 | * 193 | * @return 194 | * - ESP_LOADER_SUCCESS Success 195 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 196 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 197 | */ 198 | esp_loader_error_t esp_loader_read_register(uint32_t address, uint32_t *reg_value); 199 | 200 | /** 201 | * @brief Change baud rate. 202 | * 203 | * @note Baud rate has to be also adjusted accordingly on host MCU, as 204 | * target's baud rate is changed upon return from this function. 205 | * 206 | * @param baudrate[in] new baud rate to be set. 207 | * 208 | * @return 209 | * - ESP_LOADER_SUCCESS Success 210 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 211 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 212 | * - ESP_LOADER_ERROR_UNSUPPORTED_FUNC Unsupported on the target 213 | */ 214 | esp_loader_error_t esp_loader_change_baudrate(uint32_t baudrate); 215 | 216 | /** 217 | * @brief Verify target's flash integrity by checking MD5. 218 | * MD5 checksum is computed from data pushed to target's memory by calling 219 | * esp_loader_flash_write() function and compared against target's MD5. 220 | * Target computes checksum based on offset and image_size passed to 221 | * esp_loader_flash_start() function. 222 | * 223 | * @note This function is only available if MD5_ENABLED is set. 224 | * 225 | * @return 226 | * - ESP_LOADER_SUCCESS Success 227 | * - ESP_LOADER_ERROR_INVALID_MD5 MD5 does not match 228 | * - ESP_LOADER_ERROR_TIMEOUT Timeout 229 | * - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error 230 | * - ESP_LOADER_ERROR_UNSUPPORTED_FUNC Unsupported on the target 231 | */ 232 | esp_loader_error_t loader_eraseAllFlash_cmd(); 233 | 234 | #if MD5_ENABLED 235 | esp_loader_error_t esp_loader_flash_verify(void); 236 | #endif 237 | /** 238 | * @brief Toggles reset pin. 239 | */ 240 | void esp_loader_reset_target(void); 241 | 242 | 243 | 244 | #ifdef __cplusplus 245 | } 246 | #endif 247 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/src/md5_hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MD5 hash implementation and interface functions 3 | * Copyright (c) 2003-2005, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | 10 | #include "md5_hash.h" 11 | #include 12 | #include 13 | 14 | 15 | static void MD5Transform(uint32_t buf[4], uint32_t const in[16]); 16 | 17 | 18 | /* ===== start - public domain MD5 implementation ===== */ 19 | /* 20 | * This code implements the MD5 message-digest algorithm. 21 | * The algorithm is due to Ron Rivest. This code was 22 | * written by Colin Plumb in 1993, no copyright is claimed. 23 | * This code is in the public domain; do with it what you wish. 24 | * 25 | * Equivalent code is available from RSA Data Security, Inc. 26 | * This code has been tested against that, and is equivalent, 27 | * except that you don't need to include two pages of legalese 28 | * with every copy. 29 | * 30 | * To compute the message digest of a chunk of bytes, declare an 31 | * MD5Context structure, pass it to MD5Init, call MD5Update as 32 | * needed on buffers full of bytes, and then call MD5Final, which 33 | * will fill a supplied 16-byte array with the digest. 34 | */ 35 | 36 | #ifndef WORDS_BIGENDIAN 37 | #define byteReverse(buf, len) /* Nothing */ 38 | #else 39 | /* 40 | * Note: this code is harmless on little-endian machines. 41 | */ 42 | static void byteReverse(unsigned char *buf, unsigned longs) 43 | { 44 | uint32_t t; 45 | do { 46 | t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | 47 | ((unsigned) buf[1] << 8 | buf[0]); 48 | *(uint32_t *) buf = t; 49 | buf += 4; 50 | } while (--longs); 51 | } 52 | #endif 53 | 54 | /* 55 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 56 | * initialization constants. 57 | */ 58 | void MD5InitESP(struct MD5Context *ctx) 59 | { 60 | ctx->buf[0] = 0x67452301; 61 | ctx->buf[1] = 0xefcdab89; 62 | ctx->buf[2] = 0x98badcfe; 63 | ctx->buf[3] = 0x10325476; 64 | 65 | ctx->bits[0] = 0; 66 | ctx->bits[1] = 0; 67 | } 68 | 69 | /* 70 | * Update context to reflect the concatenation of another buffer full 71 | * of bytes. 72 | */ 73 | void MD5UpdateESP(struct MD5Context *ctx, unsigned char const *buf, unsigned len) 74 | { 75 | uint32_t t; 76 | 77 | /* Update bitcount */ 78 | 79 | t = ctx->bits[0]; 80 | if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) { 81 | ctx->bits[1]++; /* Carry from low to high */ 82 | } 83 | ctx->bits[1] += len >> 29; 84 | 85 | t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 86 | 87 | /* Handle any leading odd-sized chunks */ 88 | 89 | if (t) { 90 | unsigned char *p = (unsigned char *) ctx->in + t; 91 | 92 | t = 64 - t; 93 | if (len < t) { 94 | memcpy(p, buf, len); 95 | return; 96 | } 97 | memcpy(p, buf, t); 98 | byteReverse(ctx->in, 16); 99 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 100 | buf += t; 101 | len -= t; 102 | } 103 | /* Process data in 64-byte chunks */ 104 | 105 | while (len >= 64) { 106 | memcpy(ctx->in, buf, 64); 107 | byteReverse(ctx->in, 16); 108 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 109 | buf += 64; 110 | len -= 64; 111 | } 112 | 113 | /* Handle any remaining bytes of data. */ 114 | 115 | memcpy(ctx->in, buf, len); 116 | } 117 | 118 | /* 119 | * Final wrapup - pad to 64-byte boundary with the bit pattern 120 | * 1 0* (64-bit count of bits processed, MSB-first) 121 | */ 122 | void MD5FinalESP(unsigned char digest[16], struct MD5Context *ctx) 123 | { 124 | unsigned count; 125 | unsigned char *p; 126 | 127 | /* Compute number of bytes mod 64 */ 128 | count = (ctx->bits[0] >> 3) & 0x3F; 129 | 130 | /* Set the first char of padding to 0x80. This is safe since there is 131 | always at least one byte free */ 132 | p = ctx->in + count; 133 | *p++ = 0x80; 134 | 135 | /* Bytes of padding needed to make 64 bytes */ 136 | count = 64 - 1 - count; 137 | 138 | /* Pad out to 56 mod 64 */ 139 | if (count < 8) { 140 | /* Two lots of padding: Pad the first block to 64 bytes */ 141 | memset(p, 0, count); 142 | byteReverse(ctx->in, 16); 143 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 144 | 145 | /* Now fill the next block with 56 bytes */ 146 | memset(ctx->in, 0, 56); 147 | } else { 148 | /* Pad block to 56 bytes */ 149 | memset(p, 0, count - 8); 150 | } 151 | byteReverse(ctx->in, 14); 152 | 153 | /* Append length in bits and transform */ 154 | ((uint32_t *) ctx->in)[14] = ctx->bits[0]; 155 | ((uint32_t *) ctx->in)[15] = ctx->bits[1]; 156 | 157 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 158 | byteReverse((unsigned char *) ctx->buf, 4); 159 | memcpy(digest, ctx->buf, 16); 160 | memset(ctx, 0, sizeof(struct MD5Context)); /* In case it's sensitive */ 161 | } 162 | 163 | /* The four core functions - F1 is optimized somewhat */ 164 | 165 | /* #define F1(x, y, z) (x & y | ~x & z) */ 166 | #define F1(x, y, z) (z ^ (x & (y ^ z))) 167 | #define F2(x, y, z) F1(z, x, y) 168 | #define F3(x, y, z) (x ^ y ^ z) 169 | #define F4(x, y, z) (y ^ (x | ~z)) 170 | 171 | /* This is the central step in the MD5 algorithm. */ 172 | #define MD5STEP(f, w, x, y, z, data, s) \ 173 | ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) 174 | 175 | /* 176 | * The core of the MD5 algorithm, this alters an existing MD5 hash to 177 | * reflect the addition of 16 longwords of new data. MD5Update blocks 178 | * the data and converts bytes into longwords for this routine. 179 | */ 180 | static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) 181 | { 182 | register uint32_t a, b, c, d; 183 | 184 | a = buf[0]; 185 | b = buf[1]; 186 | c = buf[2]; 187 | d = buf[3]; 188 | 189 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 190 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 191 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 192 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 193 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 194 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 195 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 196 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 197 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 198 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 199 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 200 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 201 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 202 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 203 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 204 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 205 | 206 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 207 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 208 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 209 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 210 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 211 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 212 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 213 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 214 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 215 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 216 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 217 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 218 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 219 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 220 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 221 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 222 | 223 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 224 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 225 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 226 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 227 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 228 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 229 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 230 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 231 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 232 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 233 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 234 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 235 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 236 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 237 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 238 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 239 | 240 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 241 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 242 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 243 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 244 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 245 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 246 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 247 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 248 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 249 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 250 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 251 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 252 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 253 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 254 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 255 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 256 | 257 | buf[0] += a; 258 | buf[1] += b; 259 | buf[2] += c; 260 | buf[3] += d; 261 | } 262 | /* ===== end - public domain MD5 implementation ===== */ 263 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/src/md5_hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MD5 hash implementation and interface functions 3 | * Copyright (c) 2003-2005, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | 10 | #include "md5_hash.h" 11 | #include 12 | #include 13 | 14 | 15 | static void MD5Transform(uint32_t buf[4], uint32_t const in[16]); 16 | 17 | 18 | /* ===== start - public domain MD5 implementation ===== */ 19 | /* 20 | * This code implements the MD5 message-digest algorithm. 21 | * The algorithm is due to Ron Rivest. This code was 22 | * written by Colin Plumb in 1993, no copyright is claimed. 23 | * This code is in the public domain; do with it what you wish. 24 | * 25 | * Equivalent code is available from RSA Data Security, Inc. 26 | * This code has been tested against that, and is equivalent, 27 | * except that you don't need to include two pages of legalese 28 | * with every copy. 29 | * 30 | * To compute the message digest of a chunk of bytes, declare an 31 | * MD5Context structure, pass it to MD5Init, call MD5Update as 32 | * needed on buffers full of bytes, and then call MD5Final, which 33 | * will fill a supplied 16-byte array with the digest. 34 | */ 35 | 36 | #ifndef WORDS_BIGENDIAN 37 | #define byteReverse(buf, len) /* Nothing */ 38 | #else 39 | /* 40 | * Note: this code is harmless on little-endian machines. 41 | */ 42 | static void byteReverse(unsigned char *buf, unsigned longs) 43 | { 44 | uint32_t t; 45 | do { 46 | t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | 47 | ((unsigned) buf[1] << 8 | buf[0]); 48 | *(uint32_t *) buf = t; 49 | buf += 4; 50 | } while (--longs); 51 | } 52 | #endif 53 | 54 | /* 55 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 56 | * initialization constants. 57 | */ 58 | void MD5InitESP(struct MD5Context *ctx) 59 | { 60 | ctx->buf[0] = 0x67452301; 61 | ctx->buf[1] = 0xefcdab89; 62 | ctx->buf[2] = 0x98badcfe; 63 | ctx->buf[3] = 0x10325476; 64 | 65 | ctx->bits[0] = 0; 66 | ctx->bits[1] = 0; 67 | } 68 | 69 | /* 70 | * Update context to reflect the concatenation of another buffer full 71 | * of bytes. 72 | */ 73 | void MD5UpdateESP(struct MD5Context *ctx, unsigned char const *buf, unsigned len) 74 | { 75 | uint32_t t; 76 | 77 | /* Update bitcount */ 78 | 79 | t = ctx->bits[0]; 80 | if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) { 81 | ctx->bits[1]++; /* Carry from low to high */ 82 | } 83 | ctx->bits[1] += len >> 29; 84 | 85 | t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 86 | 87 | /* Handle any leading odd-sized chunks */ 88 | 89 | if (t) { 90 | unsigned char *p = (unsigned char *) ctx->in + t; 91 | 92 | t = 64 - t; 93 | if (len < t) { 94 | memcpy(p, buf, len); 95 | return; 96 | } 97 | memcpy(p, buf, t); 98 | byteReverse(ctx->in, 16); 99 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 100 | buf += t; 101 | len -= t; 102 | } 103 | /* Process data in 64-byte chunks */ 104 | 105 | while (len >= 64) { 106 | memcpy(ctx->in, buf, 64); 107 | byteReverse(ctx->in, 16); 108 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 109 | buf += 64; 110 | len -= 64; 111 | } 112 | 113 | /* Handle any remaining bytes of data. */ 114 | 115 | memcpy(ctx->in, buf, len); 116 | } 117 | 118 | /* 119 | * Final wrapup - pad to 64-byte boundary with the bit pattern 120 | * 1 0* (64-bit count of bits processed, MSB-first) 121 | */ 122 | void MD5FinalESP(unsigned char digest[16], struct MD5Context *ctx) 123 | { 124 | unsigned count; 125 | unsigned char *p; 126 | 127 | /* Compute number of bytes mod 64 */ 128 | count = (ctx->bits[0] >> 3) & 0x3F; 129 | 130 | /* Set the first char of padding to 0x80. This is safe since there is 131 | always at least one byte free */ 132 | p = ctx->in + count; 133 | *p++ = 0x80; 134 | 135 | /* Bytes of padding needed to make 64 bytes */ 136 | count = 64 - 1 - count; 137 | 138 | /* Pad out to 56 mod 64 */ 139 | if (count < 8) { 140 | /* Two lots of padding: Pad the first block to 64 bytes */ 141 | memset(p, 0, count); 142 | byteReverse(ctx->in, 16); 143 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 144 | 145 | /* Now fill the next block with 56 bytes */ 146 | memset(ctx->in, 0, 56); 147 | } else { 148 | /* Pad block to 56 bytes */ 149 | memset(p, 0, count - 8); 150 | } 151 | byteReverse(ctx->in, 14); 152 | 153 | /* Append length in bits and transform */ 154 | ((uint32_t *) ctx->in)[14] = ctx->bits[0]; 155 | ((uint32_t *) ctx->in)[15] = ctx->bits[1]; 156 | 157 | MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in); 158 | byteReverse((unsigned char *) ctx->buf, 4); 159 | memcpy(digest, ctx->buf, 16); 160 | memset(ctx, 0, sizeof(struct MD5Context)); /* In case it's sensitive */ 161 | } 162 | 163 | /* The four core functions - F1 is optimized somewhat */ 164 | 165 | /* #define F1(x, y, z) (x & y | ~x & z) */ 166 | #define F1(x, y, z) (z ^ (x & (y ^ z))) 167 | #define F2(x, y, z) F1(z, x, y) 168 | #define F3(x, y, z) (x ^ y ^ z) 169 | #define F4(x, y, z) (y ^ (x | ~z)) 170 | 171 | /* This is the central step in the MD5 algorithm. */ 172 | #define MD5STEP(f, w, x, y, z, data, s) \ 173 | ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) 174 | 175 | /* 176 | * The core of the MD5 algorithm, this alters an existing MD5 hash to 177 | * reflect the addition of 16 longwords of new data. MD5Update blocks 178 | * the data and converts bytes into longwords for this routine. 179 | */ 180 | static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) 181 | { 182 | register uint32_t a, b, c, d; 183 | 184 | a = buf[0]; 185 | b = buf[1]; 186 | c = buf[2]; 187 | d = buf[3]; 188 | 189 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 190 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 191 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 192 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 193 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 194 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 195 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 196 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 197 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 198 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 199 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 200 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 201 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 202 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 203 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 204 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 205 | 206 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 207 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 208 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 209 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 210 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 211 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 212 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 213 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 214 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 215 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 216 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 217 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 218 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 219 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 220 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 221 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 222 | 223 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 224 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 225 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 226 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 227 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 228 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 229 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 230 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 231 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 232 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 233 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 234 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 235 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 236 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 237 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 238 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 239 | 240 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 241 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 242 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 243 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 244 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 245 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 246 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 247 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 248 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 249 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 250 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 251 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 252 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 253 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 254 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 255 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 256 | 257 | buf[0] += a; 258 | buf[1] += b; 259 | buf[2] += c; 260 | buf[3] += d; 261 | } 262 | /* ===== end - public domain MD5 implementation ===== */ 263 | -------------------------------------------------------------------------------- /ESP32/src/ESPSerialFlasher/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /ESP8266/src/ESPSerialFlasher/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------