Compare commits
134 commits
brain-esp3
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6f2a0cc4c | ||
|
|
b138cd1ba1 | ||
|
|
5b4034b0f9 | ||
|
|
0332ed1117 | ||
|
|
6bfd594148 | ||
|
|
ab3624e73b | ||
|
|
2b71fa7422 | ||
|
|
6d16513e79 | ||
|
|
8045dd5c78 | ||
|
|
0b408468ce | ||
|
|
759bdeb282 | ||
|
|
1130b8c29d | ||
|
|
45816d8d0a | ||
|
|
d75faf6081 | ||
|
|
d48670064b | ||
|
|
4125a29235 | ||
|
|
7657c315e3 | ||
|
|
64fc7e33c9 | ||
|
|
cd2ecc5b76 | ||
|
|
bbc2afadf4 | ||
|
|
e0d3b19e47 | ||
|
|
4fb2c089bc | ||
|
|
1805552376 | ||
|
|
948b602102 | ||
|
|
00ea80fce2 | ||
|
|
f3f79e1384 | ||
|
|
0de33c2804 | ||
|
|
228169cbe5 | ||
|
|
d37a36ff29 | ||
|
|
d02093a1b1 | ||
|
|
f13cdaa159 | ||
|
|
87f1fa0d9d | ||
|
|
28fda00cce | ||
|
|
991d04d7a6 | ||
|
|
38c0a286f5 | ||
|
|
293c7f8be2 | ||
|
|
dc494b2be1 | ||
|
|
4b29b6a223 | ||
|
|
26be867d87 | ||
|
|
0bd60196b2 | ||
|
|
e47a9febec | ||
|
|
c5216f28cd | ||
|
|
8ffa1d6ff9 | ||
|
|
fcf8557dd0 | ||
|
|
0daa066f41 | ||
|
|
9a1477f407 | ||
|
|
c25bc452fd | ||
|
|
31c20caf2c | ||
|
|
d379e56c4f | ||
|
|
6e53893034 | ||
|
|
4b31541dc4 | ||
|
|
3930a02dac | ||
|
|
db9ba914b4 | ||
|
|
f6aee1c29a | ||
|
|
b4249f1614 | ||
|
|
c90c7cd375 | ||
|
|
b65bd1fd88 | ||
|
|
6f3b5e73f6 | ||
|
|
782efbfe5a | ||
|
|
c3e647b801 | ||
|
|
2e5afb8b32 | ||
|
|
ce1d1ec7b0 | ||
|
|
5ad6ac8fb6 | ||
|
|
b77e95352f | ||
|
|
31792680b3 | ||
|
|
0cf64c14cf | ||
|
|
92764d6ef1 | ||
|
|
fbe4f207c8 | ||
|
|
689440a95f | ||
|
|
0f8bf4c029 | ||
|
|
3417e50633 | ||
|
|
bfbcf9b7c6 | ||
|
|
03823d562f | ||
|
|
17575513c3 | ||
|
|
0b6ce61c5b | ||
|
|
91f6f7cc72 | ||
|
|
984926b7d8 | ||
|
|
f7ea00b74b | ||
|
|
d19c9f6e4d | ||
|
|
6e013b1c11 | ||
|
|
829d921b35 | ||
|
|
30d2ead4cb | ||
|
|
98ca14c68f | ||
|
|
e631a58b30 | ||
|
|
d4a945f967 | ||
|
|
41eae0f21a | ||
|
|
b5a2854854 | ||
|
|
387a95c819 | ||
|
|
8c7ba727e5 | ||
|
|
e02f558ca8 | ||
|
|
76e28d0e6d | ||
|
|
fd4ecd9b87 | ||
|
|
dfca31499c | ||
|
|
2df3903e52 | ||
|
|
68a73923f5 | ||
|
|
94910676de | ||
|
|
4fa35fbbc7 | ||
|
|
cfd5014475 | ||
|
|
62ffc063d3 | ||
|
|
108db070d7 | ||
|
|
05c4ca3e10 | ||
|
|
30e01cd273 | ||
|
|
6d727217b7 | ||
|
|
fd3acf6fe3 | ||
|
|
125166afde | ||
|
|
5bcbd821b2 | ||
|
|
6fb3ea8bc7 | ||
|
|
b7bd917be0 | ||
|
|
b183a5b31b | ||
|
|
2e8e572dca | ||
|
|
039fb89810 | ||
|
|
33d8bb52d3 | ||
|
|
1bb697f951 | ||
|
|
eabef3a42a | ||
|
|
6e930676c1 | ||
|
|
58c6faceb7 | ||
|
|
008240300b | ||
|
|
0a3dabfc2f | ||
|
|
6d649f4812 | ||
|
|
cfd77f443e | ||
|
|
4325321100 | ||
|
|
566cb691bb | ||
|
|
a9e5d3ed88 | ||
|
|
81b139c124 | ||
|
|
4a1cf8ecde | ||
|
|
3de56de16b | ||
|
|
fcf3f29586 | ||
|
|
442a5d3744 | ||
|
|
70197ab53b | ||
|
|
564de5050d | ||
|
|
e4623a8095 | ||
|
|
9855be25fe | ||
|
|
09fd788cbb | ||
|
|
69a55bde9e |
82 changed files with 358021 additions and 1221 deletions
11
.github/workflows/githubci.yml
vendored
11
.github/workflows/githubci.yml
vendored
|
|
@ -17,7 +17,12 @@ jobs:
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Run pre-commit
|
||||||
|
uses: pre-commit/action@v3.0.0
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: adafruit/ci-arduino
|
repository: adafruit/ci-arduino
|
||||||
|
|
@ -26,12 +31,12 @@ jobs:
|
||||||
- name: pre-install
|
- name: pre-install
|
||||||
run: bash ci/actions_install.sh
|
run: bash ci/actions_install.sh
|
||||||
|
|
||||||
- name: test platforms
|
|
||||||
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
|
|
||||||
|
|
||||||
- name: clang
|
- name: clang
|
||||||
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
|
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
|
||||||
|
|
||||||
|
- name: test platforms
|
||||||
|
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
|
||||||
|
|
||||||
- name: doxygen
|
- name: doxygen
|
||||||
env:
|
env:
|
||||||
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
|
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
|
||||||
|
|
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
.idea
|
||||||
|
.pio
|
||||||
25
.pre-commit-config.yaml
Normal file
25
.pre-commit-config.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.4.0
|
||||||
|
hooks:
|
||||||
|
- id: check-yaml
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: v15.0.7
|
||||||
|
hooks:
|
||||||
|
- id: clang-format
|
||||||
|
exclude: ^(examples/.*.ino)
|
||||||
|
types_or: [c++, c, header]
|
||||||
|
|
||||||
|
- repo: https://github.com/codespell-project/codespell
|
||||||
|
rev: v2.2.4
|
||||||
|
hooks:
|
||||||
|
- id: codespell
|
||||||
|
exclude: ^(tools/esp_stub.py)
|
||||||
|
args: [-w]
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Testing basic peripherals on Brain
|
// Testing basic peripherals on Brain
|
||||||
|
|
||||||
// required for Host MSC block device
|
// required for Host MSC block device
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
// required for USB host
|
// required for USB host
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
|
||||||
|
|
@ -1,186 +0,0 @@
|
||||||
// This sketch program ESP32 by flashing bin file from SD Card
|
|
||||||
// Hardware wiring:
|
|
||||||
// - Brain GPIO28 <-> ESP32 IO0
|
|
||||||
// - Brain Reset <-> ESP32 Enable
|
|
||||||
// - Brain TX/RX <-> ESP32 RX/TX
|
|
||||||
|
|
||||||
// required for Host MSC block device
|
|
||||||
#include "SdFat.h"
|
|
||||||
|
|
||||||
// required for USB host
|
|
||||||
#include "pio_usb.h"
|
|
||||||
#include "Adafruit_TinyUSB.h"
|
|
||||||
|
|
||||||
#include "Adafruit_TestBed_Brains.h"
|
|
||||||
|
|
||||||
#define ESP32_RESET 27
|
|
||||||
#define ESP32_IO0 28
|
|
||||||
|
|
||||||
// false for ESP32 (default)
|
|
||||||
// true for later chips such as S2, S3, H2, C3
|
|
||||||
#define ESP32_SUPPORTS_ENCRYPTED_FLASH true
|
|
||||||
|
|
||||||
//#define ESP32_BAUDRATE 921600
|
|
||||||
#define ESP32_BAUDRATE 115200
|
|
||||||
|
|
||||||
// CDC Host object
|
|
||||||
Adafruit_USBH_CDC SerialHost;
|
|
||||||
|
|
||||||
// Defined an boot rom object that use UART Serial1
|
|
||||||
ESP32BootROMClass ESP32BootROM(SerialHost, ESP32_IO0, ESP32_RESET, ESP32_SUPPORTS_ENCRYPTED_FLASH);
|
|
||||||
|
|
||||||
// Bin files on SDCard to program
|
|
||||||
// These files can be found in raspi-tester (or compiled from Arduino sketch)
|
|
||||||
#define BIN_FEATHER_ESP32S2 0
|
|
||||||
#define BIN_FEATHER_ESP32S3 1
|
|
||||||
|
|
||||||
#define BIN_FILES BIN_FEATHER_ESP32S3 // select which bins to flash either Feather ESP32 S2 or S3
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t addr;
|
|
||||||
const char* fpath;
|
|
||||||
} bin_files [] =
|
|
||||||
{
|
|
||||||
#if BIN_FILES == BIN_FEATHER_ESP32S2
|
|
||||||
{ 0x1000 , "esp32s2/PID5000/esp32s2_feather_test.ino.bootloader.bin" },
|
|
||||||
{ 0x8000 , "esp32s2/PID5000/esp32s2_feather_test.ino.partitions.bin" },
|
|
||||||
{ 0xe000 , "esp32s2/PID5000/boot_app0.bin" },
|
|
||||||
{ 0x10000 , "esp32s2/PID5000/esp32s2_feather_test.ino.bin" },
|
|
||||||
{ 0x2d0000, "esp32s2/PID5000/tinyuf2.bin" },
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BIN_FILES == BIN_FEATHER_ESP32S3
|
|
||||||
{ 0x0000 , "esp32s3/PID5477/esp32s3_feather_test.ino.bootloader.bin" },
|
|
||||||
{ 0x8000 , "esp32s3/PID5477/esp32s3_feather_test.ino.partitions.bin" },
|
|
||||||
{ 0xe000 , "esp32s3/PID5477/boot_app0.bin" },
|
|
||||||
{ 0x10000 , "esp32s3/PID5477/esp32s3_feather_test.ino.bin" },
|
|
||||||
{ 0x2d0000, "esp32s3/PID5477/tinyuf2.bin" },
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
BIN_FILES_COUNT = sizeof(bin_files)/sizeof(bin_files[0])
|
|
||||||
};
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Setup and Loop on Core0
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void prepare_sd(void) {
|
|
||||||
if (!Brain.SD_detected()) {
|
|
||||||
Brain.LCD_printf(0, "No SD Card");
|
|
||||||
while ( !Brain.SD_detected() ) delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !Brain.SD_begin(SD_SCK_MHZ(16)) ) {
|
|
||||||
Brain.LCD_printf(0, "SD init failed");
|
|
||||||
while(1) delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
Brain.LCD_printf(0, "SD mounted");
|
|
||||||
|
|
||||||
// Print out file on SD if Serial is connected
|
|
||||||
if (Serial) {
|
|
||||||
Serial.println();
|
|
||||||
Serial.println("SD Contents:");
|
|
||||||
Serial.printf("Card size = %0.1f GB\n", 0.000000512 * Brain.SD.card()->sectorCount());
|
|
||||||
Brain.SD.ls(LS_R | LS_DATE | LS_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_speed(size_t count, uint32_t ms) {
|
|
||||||
Brain.LCD_printf(0, "%.01fKB %.01fs", count/1000.0F, ms / 1000.0F);
|
|
||||||
|
|
||||||
Serial.printf("Completed %u bytes in %.02f seconds.\r\n", count, ms / 1000.0F);
|
|
||||||
Serial.printf("Speed : %.02f KB/s\r\n", (count / 1000.0F) / (ms / 1000.0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
while (!Serial) delay(10);
|
|
||||||
Serial.println("Tester Brains: Programming ESP32 with UART!");
|
|
||||||
|
|
||||||
// sync: wait for Brain.begin() called in core1 before accessing SD or other peripherals
|
|
||||||
while (!Brain.inited()) delay(10);
|
|
||||||
|
|
||||||
// prepare SD Card
|
|
||||||
prepare_sd();
|
|
||||||
|
|
||||||
while ( !Brain.esp32_begin(&ESP32BootROM, ESP32_BAUDRATE) ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writing bin files
|
|
||||||
size_t total_bytes = 0;
|
|
||||||
uint32_t ms = millis();
|
|
||||||
for(size_t i=0; i<BIN_FILES_COUNT; i++) {
|
|
||||||
Brain.LCD_printf("Flashing file %u", i);
|
|
||||||
size_t wr_count = Brain.essp32_programFlash(bin_files[i].fpath, bin_files[i].addr);
|
|
||||||
total_bytes += wr_count;
|
|
||||||
if (!wr_count) {
|
|
||||||
Brain.LCD_printf_error("Failed to flash");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print_speed(total_bytes, millis() - ms);
|
|
||||||
|
|
||||||
Brain.esp32_end();
|
|
||||||
|
|
||||||
// reset ESP32 to run new firmware
|
|
||||||
Brain.targetReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Setup and Loop on Core1
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// call usbh_begin() here to make pio usb background task run on core1
|
|
||||||
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
|
||||||
void setup1() {
|
|
||||||
Brain.begin();
|
|
||||||
Brain.usbh_begin();
|
|
||||||
|
|
||||||
// Since we only support 1 CDC interface with Tester (also CFG_TUH_CDC = 1)
|
|
||||||
// the index will always be 0 for SerialHost
|
|
||||||
// SerialHost.setInterfaceIndex(0);
|
|
||||||
SerialHost.begin(115200);
|
|
||||||
|
|
||||||
Brain.LCD_printf(0, "No USB attached");
|
|
||||||
Brain.LCD_printf(1, "Plug your device");
|
|
||||||
}
|
|
||||||
|
|
||||||
// core1's loop: process usb host task on core1
|
|
||||||
void loop1() {
|
|
||||||
Brain.USBHost.task();
|
|
||||||
|
|
||||||
// periodically flush SerialHost if connected
|
|
||||||
if ( SerialHost && SerialHost.connected() ) {
|
|
||||||
SerialHost.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// TinyUSB Host callbacks
|
|
||||||
// Note: running in the same core where Brain.USBHost.task() is called
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
// Invoked when device is mounted (configured)
|
|
||||||
void tuh_mount_cb (uint8_t daddr)
|
|
||||||
{
|
|
||||||
uint16_t vid, pid;
|
|
||||||
tuh_vid_pid_get(daddr, &vid, &pid);
|
|
||||||
|
|
||||||
Serial.printf("Device attached, address = %d\r\n", daddr);
|
|
||||||
Brain.LCD_printf("USBID %04x:%04x", vid, pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Invoked when device is unmounted (bus reset/unplugged)
|
|
||||||
void tuh_umount_cb(uint8_t dev_addr)
|
|
||||||
{
|
|
||||||
(void) dev_addr;
|
|
||||||
Brain.LCD_printf(1, "No USB Device");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
// This sketch program ESP32 by flashing bin file from SD Card
|
|
||||||
// Hardware wiring:
|
|
||||||
// - Brain GPIO28 <-> ESP32 IO0
|
|
||||||
// - Brain Reset <-> ESP32 Enable
|
|
||||||
// - Brain TX/RX <-> ESP32 RX/TX
|
|
||||||
|
|
||||||
// required for Host MSC block device
|
|
||||||
#include "SdFat.h"
|
|
||||||
|
|
||||||
// required for USB host
|
|
||||||
#include "pio_usb.h"
|
|
||||||
#include "Adafruit_TinyUSB.h"
|
|
||||||
|
|
||||||
#include "Adafruit_TestBed_Brains.h"
|
|
||||||
|
|
||||||
#define ESP32_RESET 27
|
|
||||||
#define ESP32_IO0 28
|
|
||||||
|
|
||||||
// false for ESP32 (default)
|
|
||||||
// true for later chips such as S2, S3, H2, C3
|
|
||||||
#define ESP32_SUPPORTS_ENCRYPTED_FLASH false
|
|
||||||
|
|
||||||
#define ESP32_BAUDRATE 921600
|
|
||||||
// #define ESP32_BAUDRATE 115200
|
|
||||||
|
|
||||||
// Bin files on SDCard to program
|
|
||||||
// These files can be generated by any of Arduino sketches
|
|
||||||
// The example use WiFiAccessPoint sketch, which we can verify its running image
|
|
||||||
// by simply scan for existence of ssid "YourAP"
|
|
||||||
struct {
|
|
||||||
uint32_t addr;
|
|
||||||
const char* fpath;
|
|
||||||
} bin_files [] = {
|
|
||||||
{ 0x1000 , "esp32/WiFiAccessPoint/WiFiAccessPoint.ino.bootloader.bin" },
|
|
||||||
{ 0x8000 , "esp32/WiFiAccessPoint/WiFiAccessPoint.ino.partitions.bin" },
|
|
||||||
{ 0xe000 , "esp32/WiFiAccessPoint/boot_app0.bin" },
|
|
||||||
{ 0x10000 , "esp32/WiFiAccessPoint/WiFiAccessPoint.ino.bin" },
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
BIN_FILES_COUNT = sizeof(bin_files)/sizeof(bin_files[0])
|
|
||||||
};
|
|
||||||
|
|
||||||
// Defined an boot rom object that use UART Serial1
|
|
||||||
ESP32BootROMClass ESP32BootROM(Serial1, ESP32_IO0, ESP32_RESET, ESP32_SUPPORTS_ENCRYPTED_FLASH);
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Setup and Loop on Core0
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
void prepare_sd(void) {
|
|
||||||
if (!Brain.SD_detected()) {
|
|
||||||
Brain.LCD_printf(0, "No SD Card");
|
|
||||||
while ( !Brain.SD_detected() ) delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !Brain.SD_begin(SD_SCK_MHZ(16)) ) {
|
|
||||||
Brain.LCD_printf(0, "SD init failed");
|
|
||||||
while(1) delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
Brain.LCD_printf(0, "SD mounted");
|
|
||||||
|
|
||||||
// Print out file on SD if Serial is connected
|
|
||||||
if (Serial) {
|
|
||||||
Serial.println();
|
|
||||||
Serial.println("SD Contents:");
|
|
||||||
Serial.printf("Card size = %0.1f GB\n", 0.000000512 * Brain.SD.card()->sectorCount());
|
|
||||||
Brain.SD.ls(LS_R | LS_DATE | LS_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_speed(size_t count, uint32_t ms) {
|
|
||||||
Brain.LCD_printf(0, "%.01fKB %.01fs", count/1000.0F, ms / 1000.0F);
|
|
||||||
|
|
||||||
Serial.printf("Completed %u bytes in %.02f seconds.\r\n", count, ms / 1000.0F);
|
|
||||||
Serial.printf("Speed : %.02f KB/s\r\n", (count / 1000.0F) / (ms / 1000.0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
while (!Serial) delay(10);
|
|
||||||
Serial.println("Tester Brains: Programming ESP32 with UART!");
|
|
||||||
|
|
||||||
// sync: wait for Brain.begin() called in core1 before accessing SD or other peripherals
|
|
||||||
while (!Brain.inited()) delay(10);
|
|
||||||
|
|
||||||
// prepare SD Card
|
|
||||||
prepare_sd();
|
|
||||||
|
|
||||||
while ( !Brain.esp32_begin(&ESP32BootROM, ESP32_BAUDRATE) ) {
|
|
||||||
// retry syncing
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writing bin files
|
|
||||||
size_t total_bytes = 0;
|
|
||||||
uint32_t ms = millis();
|
|
||||||
for(size_t i=0; i<BIN_FILES_COUNT; i++) {
|
|
||||||
Brain.LCD_printf("Flashing file %u", i);
|
|
||||||
size_t wr_count = Brain.essp32_programFlash(bin_files[i].fpath, bin_files[i].addr);
|
|
||||||
total_bytes += wr_count;
|
|
||||||
if (!wr_count) {
|
|
||||||
Brain.LCD_printf_error("Failed to flash");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print_speed(total_bytes, millis() - ms);
|
|
||||||
|
|
||||||
Brain.esp32_end();
|
|
||||||
|
|
||||||
// reset ESP32 to run new firmware
|
|
||||||
Brain.targetReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// Setup and Loop on Core1
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// call usbh_begin() here to make pio usb background task run on core1
|
|
||||||
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
|
||||||
void setup1() {
|
|
||||||
Brain.begin();
|
|
||||||
Brain.usbh_begin();
|
|
||||||
|
|
||||||
Brain.LCD_printf(1, "No USB Device");
|
|
||||||
}
|
|
||||||
|
|
||||||
// core1's loop: process usb host task on core1
|
|
||||||
void loop1() {
|
|
||||||
Brain.USBHost.task();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// TinyUSB Host callbacks
|
|
||||||
// Note: running in the same core where Brain.USBHost.task() is called
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
// Invoked when device is mounted (configured)
|
|
||||||
void tuh_mount_cb (uint8_t dev_addr)
|
|
||||||
{
|
|
||||||
(void) dev_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Invoked when device is unmounted (bus reset/unplugged)
|
|
||||||
void tuh_umount_cb(uint8_t dev_addr)
|
|
||||||
{
|
|
||||||
(void) dev_addr;
|
|
||||||
Brain.LCD_printf(1, "No USB Device");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
151
examples/Brain/program_esp_cdc/esp_binaries.h
Normal file
151
examples/Brain/program_esp_cdc/esp_binaries.h
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP_BINARIES_H_
|
||||||
|
#define ESP_BINARIES_H_
|
||||||
|
|
||||||
|
// Configuration: select which bins to flash
|
||||||
|
#define BIN_FILES BIN_C6_BLINK_IO8
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// LIST OF BINARIES
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#define BIN_ESP32_NINA_1_7_4 0 // nina 1.7.4
|
||||||
|
#define BIN_ESP32_WIFI_AP_SKETCH 1 // esp32 AP with ssdi "YourAP"
|
||||||
|
#define BIN_FEATHER_ESP32_V2_BLINKY 2 // Feather esp32 v2 blinky sketch
|
||||||
|
|
||||||
|
#define BIN_FEATHER_S2 10 // Feather esp32s2 factory firmware
|
||||||
|
#define BIN_FEATHER_S3 11 // Feather esp32s3 factory firmware
|
||||||
|
#define BIN_METRO_S2 12 // Metro esp32s2 factory firmware
|
||||||
|
|
||||||
|
#define BIN_DEVKIT_S2 20 // Espressif s2 devkit
|
||||||
|
#define BIN_DEVKIT_S3 21 // Espressif s3 devkit
|
||||||
|
|
||||||
|
#define BIN_FEATHER_8266_BLINKY 30 // Feather esp8266 blinky sketch
|
||||||
|
|
||||||
|
#define BIN_C6_BLINK_IO8 40 // Blink sketch for C6 with LED on IO8
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Binaries include
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#if BIN_FILES == BIN_ESP32_WIFI_AP_SKETCH
|
||||||
|
#include "esp_binaries/wifi_ap_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_ESP32_V2_BLINKY
|
||||||
|
#include "esp_binaries/feather_esp32_v2_blinky_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_NINA_1_7_4
|
||||||
|
#include "esp_binaries/nina_1_7_4_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S2
|
||||||
|
#include "esp_binaries/feather_esp32s2_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_METRO_S2
|
||||||
|
#include "esp_binaries/metro_esp32s2_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S3
|
||||||
|
#include "esp_binaries/feather_esp32s3_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S2
|
||||||
|
#include "esp_binaries/esp32s2_devkit_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S3
|
||||||
|
#include "esp_binaries/esp32s3_devkit_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_8266_BLINKY
|
||||||
|
#include "esp_binaries/feather_esp8266_blinky.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_C6_BLINK_IO8
|
||||||
|
#include "esp_binaries/c6_blink_io8.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Please select BIN_FILES in esp_binaries.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t addr;
|
||||||
|
esp32_zipfile_t const *zfile;
|
||||||
|
} bin_files[] = {
|
||||||
|
#if BIN_FILES == BIN_NINA_1_7_4
|
||||||
|
{0x00000, &NINA_W102_1_7_4},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_ESP32_V2_BLINKY
|
||||||
|
{0x1000, &feather_esp32v2_blinky_bootloader},
|
||||||
|
{0x8000, &feather_esp32v2_blinky_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &feather_esp32v2_blinky},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S2
|
||||||
|
{0x1000, &esp32s2_feather_test_ino_bootloader},
|
||||||
|
{0x8000, &esp32s2_feather_test_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &esp32s2_feather_test_ino},
|
||||||
|
{0x2d0000, &tinyuf2},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_METRO_S2
|
||||||
|
{0x1000, &selftest_ino_bootloader},
|
||||||
|
{0x8000, &selftest_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &selftest_ino},
|
||||||
|
{0x2d0000, &tinyuf2},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S3
|
||||||
|
{0x0000, &esp32s3_feather_test_ino_bootloader},
|
||||||
|
{0x8000, &esp32s3_feather_test_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &esp32s3_feather_test_ino},
|
||||||
|
{0x2d0000, &tinyuf2},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S2
|
||||||
|
{0x1000, &Blink_ino_bootloader},
|
||||||
|
{0x8000, &Blink_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &Blink_ino},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S3
|
||||||
|
{0x0000, &Blink_ino_bootloader},
|
||||||
|
{0x8000, &Blink_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &Blink_ino},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_8266_BLINKY
|
||||||
|
{0x0000, &Blink_ino},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_C6_BLINK_IO8
|
||||||
|
{0x00000, &c6_blink_io8_bootloader},
|
||||||
|
{0x8000, &c6_blink_io8_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &c6_blink_io8},
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Please select BIN_FILES in esp_binaries.h"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { BIN_FILES_COUNT = sizeof(bin_files) / sizeof(bin_files[0]) };
|
||||||
|
|
||||||
|
#endif
|
||||||
10840
examples/Brain/program_esp_cdc/esp_binaries/c6_blink_io8.h
Normal file
10840
examples/Brain/program_esp_cdc/esp_binaries/c6_blink_io8.h
Normal file
File diff suppressed because it is too large
Load diff
11085
examples/Brain/program_esp_cdc/esp_binaries/esp32s2_devkit_binaries.h
Normal file
11085
examples/Brain/program_esp_cdc/esp_binaries/esp32s2_devkit_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
12317
examples/Brain/program_esp_cdc/esp_binaries/esp32s3_devkit_binaries.h
Normal file
12317
examples/Brain/program_esp_cdc/esp_binaries/esp32s3_devkit_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
23271
examples/Brain/program_esp_cdc/esp_binaries/feather_esp32s2_binaries.h
Normal file
23271
examples/Brain/program_esp_cdc/esp_binaries/feather_esp32s2_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
23344
examples/Brain/program_esp_cdc/esp_binaries/feather_esp32s3_binaries.h
Normal file
23344
examples/Brain/program_esp_cdc/esp_binaries/feather_esp32s3_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
16347
examples/Brain/program_esp_cdc/esp_binaries/feather_esp8266_blinky.h
Normal file
16347
examples/Brain/program_esp_cdc/esp_binaries/feather_esp8266_blinky.h
Normal file
File diff suppressed because it is too large
Load diff
22156
examples/Brain/program_esp_cdc/esp_binaries/metro_esp32s2_binaries.h
Normal file
22156
examples/Brain/program_esp_cdc/esp_binaries/metro_esp32s2_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
181
examples/Brain/program_esp_cdc/program_esp_cdc.ino
Normal file
181
examples/Brain/program_esp_cdc/program_esp_cdc.ino
Normal file
|
|
@ -0,0 +1,181 @@
|
||||||
|
// This sketch program ESP32 by flashing bin file via Serial Host.
|
||||||
|
// Hardware wiring is a bit different between S2/S3 and ESP32 + USB-to-UART chip
|
||||||
|
// For S2/S3 with native USB
|
||||||
|
// - Brain GPIO28 <-> ESP32 IO0
|
||||||
|
// - Brain Reset <-> ESP32 Enable
|
||||||
|
// - Brain USB Host <-> ESP32 native usb
|
||||||
|
// For ESP32 with USB-to-UART chip
|
||||||
|
// - Brain USB Host <-> ESP32 native usb
|
||||||
|
// - There is no need to connect IO0/Reset since we will use DTR/RTS to reset ESP32
|
||||||
|
|
||||||
|
// required for Host MSC block device
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
|
// required for USB host
|
||||||
|
#include "pio_usb.h"
|
||||||
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
|
#include "Adafruit_TestBed_Brains.h"
|
||||||
|
|
||||||
|
// Change BIN_FILES in esp_binaries.h header to select which binaries to flash
|
||||||
|
// bin_files[] is defined accordingly
|
||||||
|
#include "esp_binaries.h"
|
||||||
|
|
||||||
|
// 1 if programming ESP32-S2/S3 via native USB
|
||||||
|
// 0 if programming ESP32/8266 via USB-to-UART chip such as FTDI/CP210x/CH9102f
|
||||||
|
#define ESP32_NATIVE_USB 1
|
||||||
|
|
||||||
|
#define ESP32_RESET 27
|
||||||
|
#define ESP32_IO0 28
|
||||||
|
|
||||||
|
// Note: baudrate does not matter if programming S2/S3 native USB
|
||||||
|
// But does matter if programming ESP32/8266 via USB-to-UART chip
|
||||||
|
#define ESP32_BAUDRATE (115200*8)
|
||||||
|
|
||||||
|
// CDC Host object
|
||||||
|
Adafruit_USBH_CDC SerialHost;
|
||||||
|
|
||||||
|
#if ESP32_NATIVE_USB
|
||||||
|
// Declare BootROM with IO0 and Reset will use GPIO for bootloader reset
|
||||||
|
// This is typically for programming ESP32-S2/S3 via native USB
|
||||||
|
ESP32BootROMClass ESP32BootROM(SerialHost, ESP32_IO0, ESP32_RESET);
|
||||||
|
#else
|
||||||
|
// Defined an boot rom object that use SerialHost
|
||||||
|
// Declare BootROM without IO0 and Reset will use SerialHost.setDtrRts() for bootloader reset
|
||||||
|
// This is for programming ESP32/8266 via USB-to-UART chip such as FTDI/CP210x/CH9102f
|
||||||
|
ESP32BootROMClass ESP32BootROM(SerialHost);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core0
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void print_speed(size_t count, uint32_t ms) {
|
||||||
|
float count_k = count / 1000.0F;
|
||||||
|
float sec = ms / 1000.0F;
|
||||||
|
float speed = count_k / sec;
|
||||||
|
Brain.LCD_printf(0, "%.01fKB %.01fs", count_k, sec);
|
||||||
|
Brain.LCD_printf(1, "Spd: %.01f KB/s", speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset using DTR/RTS
|
||||||
|
void reset_with_dtr_rts(uint32_t ms) {
|
||||||
|
SerialHost.setDtrRts(false, true);
|
||||||
|
delay(ms);
|
||||||
|
SerialHost.setDtrRts(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(10);
|
||||||
|
Serial.println("Tester Brains: Programming ESP32 with SerialHost!");
|
||||||
|
|
||||||
|
// sync: wait for Brain.begin() called in core1 before accessing SD or other peripherals
|
||||||
|
while (!Brain.inited()) delay(10);
|
||||||
|
|
||||||
|
while (!Brain.esp32_begin(&ESP32BootROM, ESP32_BAUDRATE)) {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writing bin files
|
||||||
|
size_t total_bytes = 0;
|
||||||
|
uint32_t ms = millis();
|
||||||
|
for (size_t i = 0; i < BIN_FILES_COUNT; i++) {
|
||||||
|
Brain.LCD_printf("Flashing file %u", i);
|
||||||
|
Serial.printf("File %s\r\n", bin_files[i].zfile->name);
|
||||||
|
size_t wr_count = Brain.esp32_programFlashDefl(bin_files[i].zfile, bin_files[i].addr);
|
||||||
|
total_bytes += wr_count;
|
||||||
|
if (!wr_count) {
|
||||||
|
Brain.LCD_printf_error("Failed to flash");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_speed(total_bytes, millis() - ms);
|
||||||
|
|
||||||
|
Brain.esp32_end();
|
||||||
|
|
||||||
|
// reset ESP32 to run new firmware
|
||||||
|
Brain.targetReset(); // reset using Reset pin GPIO27
|
||||||
|
|
||||||
|
// Reset using DTR if GPIO27 is not connected
|
||||||
|
reset_with_dtr_rts(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core1
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// call usbh_begin() here to make pio usb background task run on core1
|
||||||
|
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
||||||
|
void setup1() {
|
||||||
|
Brain.begin();
|
||||||
|
Brain.usbh_begin();
|
||||||
|
|
||||||
|
// Since we only support 1 CDC interface with Tester (also CFG_TUH_CDC = 1)
|
||||||
|
// the index will always be 0 for SerialHost
|
||||||
|
SerialHost.begin(115200);
|
||||||
|
|
||||||
|
Brain.LCD_printf(0, "No USB attached");
|
||||||
|
Brain.LCD_printf(1, "Plug your device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// core1's loop: process usb host task on core1
|
||||||
|
void loop1() {
|
||||||
|
if (Brain.esp32_s3_inReset()) {
|
||||||
|
// Note: S3 has an USB-OTG errata
|
||||||
|
// https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf
|
||||||
|
// which is walkarounded by idf/arduino-esp32 to always mux JTAG to USB for
|
||||||
|
// uploading and/or power on. Afterwards USB-OTG will be set up if selected
|
||||||
|
// so. However rp2040 USBH is running too fast and can actually retrieve
|
||||||
|
// device/configuration descriptor of JTAG before the OTG is fully setup.
|
||||||
|
// We delay a bit here
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Brain.esp32_s3_clearReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
Brain.USBHost.task();
|
||||||
|
|
||||||
|
// periodically flush SerialHost if connected
|
||||||
|
if (SerialHost && SerialHost.connected()) {
|
||||||
|
SerialHost.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB Host callbacks
|
||||||
|
// Note: running in the same core where Brain.USBHost.task() is called
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Invoked when device is mounted (configured)
|
||||||
|
void tuh_mount_cb(uint8_t daddr) {
|
||||||
|
uint16_t vid, pid;
|
||||||
|
tuh_vid_pid_get(daddr, &vid, &pid);
|
||||||
|
|
||||||
|
Serial.printf("Device attached, address = %d\r\n", daddr);
|
||||||
|
Brain.LCD_printf("USBID %04x:%04x", vid, pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
void tuh_umount_cb(uint8_t dev_addr) {
|
||||||
|
(void) dev_addr;
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with CDC interface is mounted
|
||||||
|
// idx is index of cdc interface in the internal pool.
|
||||||
|
void tuh_cdc_mount_cb(uint8_t idx) {
|
||||||
|
// bind SerialHost object to this interface index
|
||||||
|
SerialHost.mount(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with CDC interface is unmounted
|
||||||
|
void tuh_cdc_umount_cb(uint8_t idx) {
|
||||||
|
// unbind SerialHost if this interface is unmounted
|
||||||
|
SerialHost.umount(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
142
examples/Brain/program_esp_uart/esp_binaries.h
Normal file
142
examples/Brain/program_esp_uart/esp_binaries.h
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Ha Thach (tinyusb.org) for Adafruit Industries
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP_BINARIES_H_
|
||||||
|
#define ESP_BINARIES_H_
|
||||||
|
|
||||||
|
// Configuration: select which bins to flash
|
||||||
|
#define BIN_FILES BIN_C6_BLINK_IO8
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// LIST OF BINARIES
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#define BIN_ESP32_NINA_1_7_4 0 // nina 1.7.4
|
||||||
|
#define BIN_ESP32_WIFI_AP_SKETCH 1 // esp32 AP with ssdi "YourAP"
|
||||||
|
|
||||||
|
#define BIN_FEATHER_S2 10 // Feather esp32s2 factory firmware
|
||||||
|
#define BIN_FEATHER_S3 11 // Feather esp32s3 factory firmware
|
||||||
|
#define BIN_METRO_S2 12 // Metro esp32s2 factory firmware
|
||||||
|
|
||||||
|
#define BIN_DEVKIT_S2 20 // Espressif s2 devkit
|
||||||
|
#define BIN_DEVKIT_S3 21 // Espressif s3 devkit
|
||||||
|
|
||||||
|
#define BIN_ESP8266 30 // Espressif esp8266
|
||||||
|
|
||||||
|
#define BIN_C6_BLINK_IO8 40 // Blink sketch for C6 with LED on IO8
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Binaries include
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#if BIN_FILES == BIN_ESP32_WIFI_AP_SKETCH
|
||||||
|
#include "esp_binaries/wifi_ap_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_NINA_1_7_4
|
||||||
|
#include "esp_binaries/nina_1_7_4_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S2
|
||||||
|
#include "esp_binaries/feather_esp32s2_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_METRO_S2
|
||||||
|
#include "esp_binaries/metro_esp32s2_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S3
|
||||||
|
#include "esp_binaries/feather_esp32s3_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S2
|
||||||
|
#include "esp_binaries/esp32s2_devkit_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S3
|
||||||
|
#include "esp_binaries/esp32s3_devkit_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_ESP8266
|
||||||
|
#include "esp_binaries/esp8266_binaries.h"
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_C6_BLINK_IO8
|
||||||
|
#include "esp_binaries/c6_blink_io8.h"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Please select BIN_FILES in esp_binaries.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t addr;
|
||||||
|
esp32_zipfile_t const *zfile;
|
||||||
|
} bin_files[] = {
|
||||||
|
#if BIN_FILES == BIN_NINA_1_7_4
|
||||||
|
{0x00000, &NINA_W102_1_7_4},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S2
|
||||||
|
{0x1000, &esp32s2_feather_test_ino_bootloader},
|
||||||
|
{0x8000, &esp32s2_feather_test_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &esp32s2_feather_test_ino},
|
||||||
|
{0x2d0000, &tinyuf2},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_METRO_S2
|
||||||
|
{0x1000, &selftest_ino_bootloader},
|
||||||
|
{0x8000, &selftest_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &selftest_ino},
|
||||||
|
{0x2d0000, &tinyuf2},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_FEATHER_S3
|
||||||
|
{0x0000, &esp32s3_feather_test_ino_bootloader},
|
||||||
|
{0x8000, &esp32s3_feather_test_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &esp32s3_feather_test_ino},
|
||||||
|
{0x2d0000, &tinyuf2},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S2
|
||||||
|
{0x1000, &Blink_ino_bootloader},
|
||||||
|
{0x8000, &Blink_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &Blink_ino},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_DEVKIT_S3
|
||||||
|
{0x0000, &Blink_ino_bootloader},
|
||||||
|
{0x8000, &Blink_ino_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &Blink_ino},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_ESP8266
|
||||||
|
{0x00000, &esp8266_blink_io0},
|
||||||
|
|
||||||
|
#elif BIN_FILES == BIN_C6_BLINK_IO8
|
||||||
|
{0x00000, &c6_blink_io8_bootloader},
|
||||||
|
{0x8000, &c6_blink_io8_partitions},
|
||||||
|
{0xe000, &boot_app0},
|
||||||
|
{0x10000, &c6_blink_io8},
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Please select BIN_FILES in esp_binaries.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { BIN_FILES_COUNT = sizeof(bin_files) / sizeof(bin_files[0]) };
|
||||||
|
|
||||||
|
#endif
|
||||||
10840
examples/Brain/program_esp_uart/esp_binaries/c6_blink_io8.h
Normal file
10840
examples/Brain/program_esp_uart/esp_binaries/c6_blink_io8.h
Normal file
File diff suppressed because it is too large
Load diff
11085
examples/Brain/program_esp_uart/esp_binaries/esp32s2_devkit_binaries.h
Normal file
11085
examples/Brain/program_esp_uart/esp_binaries/esp32s2_devkit_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
12317
examples/Brain/program_esp_uart/esp_binaries/esp32s3_devkit_binaries.h
Normal file
12317
examples/Brain/program_esp_uart/esp_binaries/esp32s3_devkit_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
16344
examples/Brain/program_esp_uart/esp_binaries/esp8266_binaries.h
Normal file
16344
examples/Brain/program_esp_uart/esp_binaries/esp8266_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
23271
examples/Brain/program_esp_uart/esp_binaries/feather_esp32s2_binaries.h
Normal file
23271
examples/Brain/program_esp_uart/esp_binaries/feather_esp32s2_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
23344
examples/Brain/program_esp_uart/esp_binaries/feather_esp32s3_binaries.h
Normal file
23344
examples/Brain/program_esp_uart/esp_binaries/feather_esp32s3_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
22156
examples/Brain/program_esp_uart/esp_binaries/metro_esp32s2_binaries.h
Normal file
22156
examples/Brain/program_esp_uart/esp_binaries/metro_esp32s2_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
52833
examples/Brain/program_esp_uart/esp_binaries/nina_1_7_4_binaries.h
Normal file
52833
examples/Brain/program_esp_uart/esp_binaries/nina_1_7_4_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
40424
examples/Brain/program_esp_uart/esp_binaries/wifi_ap_binaries.h
Normal file
40424
examples/Brain/program_esp_uart/esp_binaries/wifi_ap_binaries.h
Normal file
File diff suppressed because it is too large
Load diff
134
examples/Brain/program_esp_uart/program_esp_uart.ino
Normal file
134
examples/Brain/program_esp_uart/program_esp_uart.ino
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
// This sketch program ESP32 by flashing bin file from on-flash (with .h header)
|
||||||
|
// Supported/tested ESP MCU are: ESP32, ESP32-S2, ESP32-S3, ESP8266
|
||||||
|
// Hardware wiring:
|
||||||
|
// - Brain GPIO28 <-> ESP32 IO0
|
||||||
|
// - Brain Reset <-> ESP32 Enable
|
||||||
|
// - Brain TX/RX <-> ESP32 RX/TX
|
||||||
|
|
||||||
|
// required for Host MSC block device
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
|
// required for USB host
|
||||||
|
#include "pio_usb.h"
|
||||||
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
|
#include "Adafruit_TestBed_Brains.h"
|
||||||
|
|
||||||
|
// Change BIN_FILES in esp_binaries.h header to select which binaries to flash
|
||||||
|
// bin_files[] is defined accordingly
|
||||||
|
#include "esp_binaries.h"
|
||||||
|
|
||||||
|
#define ESP32_RESET 27
|
||||||
|
#define ESP32_IO0 28
|
||||||
|
|
||||||
|
#define ESP32_BAUDRATE 2000000
|
||||||
|
//#define ESP32_BAUDRATE 1500000
|
||||||
|
//#define ESP32_BAUDRATE 921600
|
||||||
|
//#define ESP32_BAUDRATE 115200
|
||||||
|
|
||||||
|
|
||||||
|
// Defined an boot rom object that use UART Serial1
|
||||||
|
ESP32BootROMClass ESP32BootROM(Serial1, ESP32_IO0, ESP32_RESET);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core0
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void print_speed(size_t count, uint32_t ms) {
|
||||||
|
float count_k = count / 1000.0F;
|
||||||
|
float sec = ms / 1000.0F;
|
||||||
|
float speed = count_k / sec;
|
||||||
|
Brain.LCD_printf(0, "%.01fKB %.01fs", count_k, sec);
|
||||||
|
Brain.LCD_printf(1, "Spd: %.01f KB/s", speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(10);
|
||||||
|
Serial.println("Tester Brains: Programming ESP with UART!");
|
||||||
|
|
||||||
|
// sync: wait for Brain.begin() called in core1 before accessing SD or other peripherals
|
||||||
|
while (!Brain.inited()) delay(10);
|
||||||
|
while (!Brain.esp32_begin(&ESP32BootROM, ESP32_BAUDRATE)) {
|
||||||
|
// retry syncing
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writing bin files
|
||||||
|
size_t total_bytes = 0;
|
||||||
|
uint32_t ms = millis();
|
||||||
|
for (size_t i = 0; i < BIN_FILES_COUNT; i++) {
|
||||||
|
Brain.LCD_printf(0, "Flashing file %u", i);
|
||||||
|
Serial.printf("File: %s\r\n", bin_files[i].zfile->name);
|
||||||
|
size_t wr_count = Brain.esp32_programFlashDefl(bin_files[i].zfile, bin_files[i].addr);
|
||||||
|
total_bytes += wr_count;
|
||||||
|
if (!wr_count) {
|
||||||
|
Brain.LCD_printf_error("Failed to flash");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print_speed(total_bytes, millis() - ms);
|
||||||
|
|
||||||
|
Brain.esp32_end();
|
||||||
|
|
||||||
|
// reset ESP32 to run new firmware
|
||||||
|
Brain.targetReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core1
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// call usbh_begin() here to make pio usb background task run on core1
|
||||||
|
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
||||||
|
void setup1() {
|
||||||
|
Brain.begin();
|
||||||
|
Brain.usbh_begin();
|
||||||
|
|
||||||
|
Brain.LCD_printf(0, "No USB attached");
|
||||||
|
Brain.LCD_printf(1, "Plug your device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// core1's loop: process usb host task on core1
|
||||||
|
void loop1() {
|
||||||
|
if (Brain.esp32_s3_inReset()) {
|
||||||
|
// Note: S3 has an USB-OTG errata
|
||||||
|
// https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf
|
||||||
|
// which is walkarounded by idf/arduino-esp32 to always mux JTAG to USB for
|
||||||
|
// uploading and/or power on. Afterwards USB-OTG will be set up if selected
|
||||||
|
// so. However rp2040 USBH is running too fast and can actually retrieve
|
||||||
|
// device/configuration descriptor of JTAG before the OTG is fully setup.
|
||||||
|
// We delay a bit here
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
Brain.esp32_s3_clearReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
Brain.USBHost.task();
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB Host callbacks
|
||||||
|
// Note: running in the same core where Brain.USBHost.task() is called
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Invoked when device is mounted (configured)
|
||||||
|
void tuh_mount_cb(uint8_t daddr) {
|
||||||
|
uint16_t vid, pid;
|
||||||
|
tuh_vid_pid_get(daddr, &vid, &pid);
|
||||||
|
|
||||||
|
Serial.printf("Device attached, address = %d\r\n", daddr);
|
||||||
|
Brain.LCD_printf("USBID %04x:%04x", vid, pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
void tuh_umount_cb(uint8_t dev_addr) {
|
||||||
|
(void) dev_addr;
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// - Brain's USB host to Target USB
|
// - Brain's USB host to Target USB
|
||||||
|
|
||||||
// required for Host MSC block device
|
// required for Host MSC block device
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
// required for USB host
|
// required for USB host
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
@ -17,11 +17,7 @@
|
||||||
|
|
||||||
#include "Adafruit_TestBed_Brains.h"
|
#include "Adafruit_TestBed_Brains.h"
|
||||||
|
|
||||||
// RP2040 Boot VID/PID
|
// file path on SDCard to program
|
||||||
#define BOOT_VID 0x2e8a
|
|
||||||
#define BOOT_PID 0x0003
|
|
||||||
|
|
||||||
// file path on SDCard to prograom
|
|
||||||
#define TEST_FILE_PATH "nrf/feather_nrf52840/bleblink.bin"
|
#define TEST_FILE_PATH "nrf/feather_nrf52840/bleblink.bin"
|
||||||
|
|
||||||
// DAP interface for nRF5x
|
// DAP interface for nRF5x
|
||||||
|
|
@ -66,8 +62,10 @@ void setup() {
|
||||||
// erase chip before programming
|
// erase chip before programming
|
||||||
Brain.dap_eraseChip();
|
Brain.dap_eraseChip();
|
||||||
|
|
||||||
|
// for nrf52840 don't use crc32 as it is not supported.
|
||||||
|
// Note: verify is with reading back increase programming time by 2x
|
||||||
uint32_t ms = millis();
|
uint32_t ms = millis();
|
||||||
size_t copied_bytes = Brain.dap_programFlash(TEST_FILE_PATH, 0);
|
size_t copied_bytes = Brain.dap_programFlash(TEST_FILE_PATH, 0, true, false);
|
||||||
ms = millis() - ms;
|
ms = millis() - ms;
|
||||||
print_speed(copied_bytes, ms);
|
print_speed(copied_bytes, ms);
|
||||||
|
|
||||||
|
|
@ -110,9 +108,7 @@ void tuh_mount_cb (uint8_t dev_addr)
|
||||||
uint16_t vid, pid;
|
uint16_t vid, pid;
|
||||||
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||||
|
|
||||||
if ( !(vid == BOOT_VID && pid == BOOT_PID) ) {
|
Brain.LCD_printf("USBID %04x:%04x", vid, pid);
|
||||||
Brain.LCD_printf(1, "UnkDev %04x:%04x", vid, pid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invoked when device is unmounted (bus reset/unplugged)
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
|
|
||||||
BIN
examples/Brain/program_nrf52840_from_sdcard/bleblink.bin
Normal file
BIN
examples/Brain/program_nrf52840_from_sdcard/bleblink.bin
Normal file
Binary file not shown.
|
|
@ -0,0 +1,121 @@
|
||||||
|
// This sketch program SAMD with bin file from SDCard using Adafruit_DAP
|
||||||
|
// Hardware wiring:
|
||||||
|
// - Brain's header Reset <-> Target Reset
|
||||||
|
// - Brain's header SWDIO <-> Target SWDIO
|
||||||
|
// - Brain's header SWCLK <-> Target SWCLK
|
||||||
|
// - Brain's USB host to Target USB
|
||||||
|
|
||||||
|
// required for Host MSC block device
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
|
// required for USB host
|
||||||
|
#include "pio_usb.h"
|
||||||
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
|
// required for DAP programming
|
||||||
|
#include "Adafruit_DAP.h"
|
||||||
|
|
||||||
|
#include "Adafruit_TestBed_Brains.h"
|
||||||
|
|
||||||
|
// file path on SDCard to program
|
||||||
|
#define TEST_FILE_PATH "nrf/feather_nrf52840/bleblink.bin"
|
||||||
|
|
||||||
|
// DAP interface for nRF5x
|
||||||
|
Adafruit_DAP_nRF5x dap;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core0
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void print_speed(size_t count, uint32_t ms) {
|
||||||
|
Brain.LCD_printf(0, "%.01fKB in %.01fs", count/1000.0F, ms / 1000.0F);
|
||||||
|
|
||||||
|
Serial.printf("Completed %u bytes in %.02f seconds.\r\n", count, ms / 1000.0F);
|
||||||
|
Serial.printf("Speed : %.02f KB/s\r\n", (count / 1000.0F) / (ms / 1000.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(10);
|
||||||
|
Serial.println("Tester Brains: nRF52840 programming !");
|
||||||
|
|
||||||
|
// sync: wait for Brain.usbh_begin() called in core1 before accessing SD or other peripherals
|
||||||
|
while (!Brain.usbh_inited()) delay(10);
|
||||||
|
|
||||||
|
Brain.SD_begin(SD_SCK_MHZ(16));
|
||||||
|
|
||||||
|
// Print out file on SD if Serial is connected
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("SD Contents:");
|
||||||
|
Serial.printf("Card size = %0.1f GB\n", 0.000000512 * Brain.SD.card()->sectorCount());
|
||||||
|
Brain.SD.ls(LS_R | LS_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Brain.targetReset();
|
||||||
|
|
||||||
|
Brain.dap_begin(&dap);
|
||||||
|
Brain.dap_connect();
|
||||||
|
|
||||||
|
Brain.dap_unprotectBoot();
|
||||||
|
|
||||||
|
// erase chip before programming
|
||||||
|
Brain.dap_eraseChip();
|
||||||
|
|
||||||
|
// for nrf52840 don't use crc32 as it is not supported.
|
||||||
|
// Note: verify is with reading back increase programming time by 2x
|
||||||
|
uint32_t ms = millis();
|
||||||
|
size_t copied_bytes = Brain.dap_programFlash(TEST_FILE_PATH, 0, true, false);
|
||||||
|
ms = millis() - ms;
|
||||||
|
print_speed(copied_bytes, ms);
|
||||||
|
|
||||||
|
Brain.dap_protectBoot();
|
||||||
|
Brain.dap_disconnect();
|
||||||
|
|
||||||
|
Brain.targetReset();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core1
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// call usbh_begin() here to make pio usb background task run on core1
|
||||||
|
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
||||||
|
void setup1() {
|
||||||
|
Brain.begin();
|
||||||
|
Brain.usbh_begin();
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// core1's loop: process usb host task on core1
|
||||||
|
void loop1() {
|
||||||
|
Brain.USBHost.task();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB Host callbacks
|
||||||
|
// Note: running in the same core where Brain.USBHost.task() is called
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Invoked when device is mounted (configured)
|
||||||
|
void tuh_mount_cb (uint8_t dev_addr)
|
||||||
|
{
|
||||||
|
uint16_t vid, pid;
|
||||||
|
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||||
|
|
||||||
|
Brain.LCD_printf("USBID %04x:%04x", vid, pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
void tuh_umount_cb(uint8_t dev_addr)
|
||||||
|
{
|
||||||
|
(void) dev_addr;
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2
Normal file
BIN
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2
Normal file
Binary file not shown.
7043
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2.h
Normal file
7043
examples/Brain/program_rp2/metro_rp2350_cdc_msc.uf2.h
Normal file
File diff suppressed because it is too large
Load diff
135
examples/Brain/program_rp2/program_rp2.ino
Normal file
135
examples/Brain/program_rp2/program_rp2.ino
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
// This sketch program rp2040 by copying UF2 file from SDCard to
|
||||||
|
// rp2040 bootrom
|
||||||
|
// Hardware wiring:
|
||||||
|
// - Brain's Target GPIO28 to RP2 bootsel
|
||||||
|
// - Brain's Target Reset to RP2 Reset
|
||||||
|
// - Brain's USB host to RP2040 USB interface
|
||||||
|
|
||||||
|
// required for Host MSC block device
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
|
// required for USB host
|
||||||
|
#include "pio_usb.h"
|
||||||
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
|
#include "Adafruit_TestBed_Brains.h"
|
||||||
|
|
||||||
|
// firmware.h is converted using tools/file2carray.py e.g
|
||||||
|
// python tools/file2carray.py cdc_msc.uf2
|
||||||
|
// above command will generate cdc_msc.uf2.h with bindata, bindata_len
|
||||||
|
#include "metro_rp2350_cdc_msc.uf2.h"
|
||||||
|
|
||||||
|
// RP2040 Boot VID/PID
|
||||||
|
#define BOOT_VID 0x2e8a
|
||||||
|
#define BOOT_PID_RP2040 0x0003
|
||||||
|
#define BOOT_PID_RP2350 0x000f
|
||||||
|
|
||||||
|
// If USB filesystem is mounted
|
||||||
|
volatile bool is_usbfs_mounted = false;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core0
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void print_speed(size_t count, uint32_t ms) {
|
||||||
|
Brain.LCD_printf(0, "%.01fKB %.01fs", count/1000.0F, ms / 1000.0F);
|
||||||
|
|
||||||
|
Serial.printf("Completed %u bytes in %.02f seconds.\r\n", count, ms / 1000.0F);
|
||||||
|
Serial.printf("Speed : %.02f KB/s\r\n", (count / 1000.0F) / (ms / 1000.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(10);
|
||||||
|
Serial.println("Program RP2 by copy UF2 from Internal Flash to Bootloader!");
|
||||||
|
|
||||||
|
// sync: wait for Brain.begin() called in core1 before accessing SD or other peripherals
|
||||||
|
while (!Brain.inited()) delay(10);
|
||||||
|
|
||||||
|
// wait for USB filesystem is mounted. USB host bit-banging and task is
|
||||||
|
// processed on core1
|
||||||
|
while (!is_usbfs_mounted) delay(10);
|
||||||
|
|
||||||
|
// Copy UF2 file
|
||||||
|
Brain.LCD_printf(0, "Copying firmware");
|
||||||
|
Serial.println("Copying UF2 from Flash to USBHFS");
|
||||||
|
|
||||||
|
uint32_t ms = millis();
|
||||||
|
size_t copied_bytes = Brain.rp2_programUF2(bindata, bindata_len);
|
||||||
|
print_speed(copied_bytes, millis() - ms);
|
||||||
|
|
||||||
|
// wait for rp2040 boot rom to reset
|
||||||
|
// while (is_usbfs_mounted) delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Serial.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core1
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// call usbh_begin() here to make pio usb background task run on core1
|
||||||
|
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
||||||
|
void setup1() {
|
||||||
|
Brain.begin();
|
||||||
|
Brain.usbh_begin();
|
||||||
|
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
|
||||||
|
// reset rp2040 target into Boot Rom, default bootsel = 28, reset duration = 10 ms
|
||||||
|
Brain.rp2_targetResetBootRom();
|
||||||
|
}
|
||||||
|
|
||||||
|
// core1's loop: process usb host task on core1
|
||||||
|
void loop1() {
|
||||||
|
Brain.USBHost.task();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB Host callbacks
|
||||||
|
// Note: running in the same core where Brain.USBHost.task() is called
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
bool is_rp2_bootloader(uint16_t vid, uint16_t pid) {
|
||||||
|
return (vid == BOOT_VID && (pid == BOOT_PID_RP2040 || pid == BOOT_PID_RP2350));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Invoked when device is mounted (configured)
|
||||||
|
void tuh_mount_cb(uint8_t dev_addr) {
|
||||||
|
uint16_t vid, pid;
|
||||||
|
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||||
|
|
||||||
|
if (!is_rp2_bootloader(vid, pid)) {
|
||||||
|
Brain.LCD_printf(1, "UnkDev %04x:%04x", vid, pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
void tuh_umount_cb(uint8_t dev_addr) {
|
||||||
|
(void)dev_addr;
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with MassStorage interface is mounted
|
||||||
|
void tuh_msc_mount_cb(uint8_t dev_addr) {
|
||||||
|
uint16_t vid, pid;
|
||||||
|
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||||
|
|
||||||
|
if (is_rp2_bootloader(vid, pid)) {
|
||||||
|
is_usbfs_mounted = Brain.usbh_mountFS(dev_addr);
|
||||||
|
if (is_usbfs_mounted) {
|
||||||
|
uint16_t rp2variant = (pid == BOOT_PID_RP2040 ? 2040 : 2350);
|
||||||
|
Brain.LCD_printf(1, "RP%u Bootldr", rp2variant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with MassStorage interface is unmounted
|
||||||
|
void tuh_msc_umount_cb(uint8_t dev_addr) {
|
||||||
|
is_usbfs_mounted = false;
|
||||||
|
Brain.usbh_umountFS(dev_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// - Brain's USB host to RP2040 USB interface
|
// - Brain's USB host to RP2040 USB interface
|
||||||
|
|
||||||
// required for Host MSC block device
|
// required for Host MSC block device
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
// required for USB host
|
// required for USB host
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
@ -60,11 +60,6 @@ void print_speed(size_t count, uint32_t ms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// For debugging tinyusb
|
|
||||||
if (CFG_TUSB_DEBUG) {
|
|
||||||
Serial1.begin(115200);
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
while (!Serial) delay(10);
|
while (!Serial) delay(10);
|
||||||
Serial.println("Tester Brains: UF2 copy from SD to USBH FS test!");
|
Serial.println("Tester Brains: UF2 copy from SD to USBH FS test!");
|
||||||
|
|
@ -75,7 +70,7 @@ void setup() {
|
||||||
// prepare SD Card
|
// prepare SD Card
|
||||||
prepare_sd();
|
prepare_sd();
|
||||||
|
|
||||||
// wait for USB filesytem is mounted. USB host bit-banging and task is
|
// wait for USB filesystem is mounted. USB host bit-banging and task is
|
||||||
// processed on core1
|
// processed on core1
|
||||||
while (!is_usbfs_mounted) delay(10);
|
while (!is_usbfs_mounted) delay(10);
|
||||||
|
|
||||||
|
|
@ -84,7 +79,7 @@ void setup() {
|
||||||
Serial.println("Copying from SD to USBHFS: " UF2_FILE_PATH);
|
Serial.println("Copying from SD to USBHFS: " UF2_FILE_PATH);
|
||||||
|
|
||||||
uint32_t ms = millis();
|
uint32_t ms = millis();
|
||||||
size_t copied_bytes = Brain.rp2040_programUF2(UF2_FILE_PATH);
|
size_t copied_bytes = Brain.rp2_programUF2(UF2_FILE_PATH);
|
||||||
|
|
||||||
print_speed(copied_bytes, millis() - ms);
|
print_speed(copied_bytes, millis() - ms);
|
||||||
|
|
||||||
|
|
@ -93,6 +88,7 @@ void setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
Serial.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
@ -108,7 +104,7 @@ void setup1() {
|
||||||
Brain.LCD_printf(1, "No USB Device");
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
|
||||||
// reset rp2040 target into Boot Rom, default bootsel = 28, reset duration = 10 ms
|
// reset rp2040 target into Boot Rom, default bootsel = 28, reset duration = 10 ms
|
||||||
Brain.rp2040_targetResetBootRom();
|
Brain.rp2_targetResetBootRom();
|
||||||
}
|
}
|
||||||
|
|
||||||
// core1's loop: process usb host task on core1
|
// core1's loop: process usb host task on core1
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// - Brain's USB host to Target USB
|
// - Brain's USB host to Target USB
|
||||||
|
|
||||||
// required for Host MSC block device
|
// required for Host MSC block device
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
// required for USB host
|
// required for USB host
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// - Brain's USB host to Target USB
|
// - Brain's USB host to Target USB
|
||||||
|
|
||||||
// required for Host MSC block device
|
// required for Host MSC block device
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
// required for USB host
|
// required for USB host
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// - Brain's USB host to Target USB
|
// - Brain's USB host to Target USB
|
||||||
|
|
||||||
// required for Host MSC block device
|
// required for Host MSC block device
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
// required for USB host
|
// required for USB host
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
// This sketch program SAMD with bin file from SDCard using Adafruit_DAP
|
||||||
|
// Hardware wiring:
|
||||||
|
// - Brain's header Reset <-> Target Reset
|
||||||
|
// - Brain's header SWDIO <-> Target SWDIO
|
||||||
|
// - Brain's header SWCLK <-> Target SWCLK
|
||||||
|
// - Brain's USB host to Target USB
|
||||||
|
|
||||||
|
// required for Host MSC block device
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
|
// required for USB host
|
||||||
|
#include "pio_usb.h"
|
||||||
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
|
// required for DAP programming
|
||||||
|
#include "Adafruit_DAP.h"
|
||||||
|
|
||||||
|
#include "Adafruit_TestBed_Brains.h"
|
||||||
|
|
||||||
|
// file path on SDCard to hold nrf52840 binary
|
||||||
|
#define READ_FILE_PATH "nrf/readback.bin"
|
||||||
|
#define READ_SIZE (1024u*1024u) // 1 MB
|
||||||
|
|
||||||
|
// DAP interface for nRF5x
|
||||||
|
Adafruit_DAP_nRF5x dap;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core0
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void print_speed(size_t count, uint32_t ms) {
|
||||||
|
Brain.LCD_printf(0, "%.01fKB in %.01fs", count/1000.0F, ms / 1000.0F);
|
||||||
|
|
||||||
|
Serial.printf("Completed %u bytes in %.02f seconds.\r\n", count, ms / 1000.0F);
|
||||||
|
Serial.printf("Speed : %.02f KB/s\r\n", (count / 1000.0F) / (ms / 1000.0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(10);
|
||||||
|
Serial.println("Tester Brains: Reading nRF52840 to SD Card!");
|
||||||
|
|
||||||
|
// sync: wait for Brain.usbh_begin() called in core1 before accessing SD or other peripherals
|
||||||
|
while (!Brain.usbh_inited()) delay(10);
|
||||||
|
|
||||||
|
Brain.SD_begin(SD_SCK_MHZ(16));
|
||||||
|
|
||||||
|
// Print out file on SD if Serial is connected
|
||||||
|
if (Serial) {
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("SD Contents:");
|
||||||
|
Serial.printf("Card size = %0.1f GB\n", 0.000000512 * Brain.SD.card()->sectorCount());
|
||||||
|
Brain.SD.ls(LS_R | LS_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Brain.targetReset();
|
||||||
|
Brain.dap_begin(&dap);
|
||||||
|
Brain.dap_connect();
|
||||||
|
|
||||||
|
uint32_t ms = millis();
|
||||||
|
size_t nbytes = Brain.dap_readFlash(READ_FILE_PATH, 0, READ_SIZE);
|
||||||
|
ms = millis() - ms;
|
||||||
|
print_speed(nbytes, ms);
|
||||||
|
|
||||||
|
Brain.dap_disconnect();
|
||||||
|
Brain.targetReset();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core1
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// call usbh_begin() here to make pio usb background task run on core1
|
||||||
|
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
||||||
|
void setup1() {
|
||||||
|
Brain.begin();
|
||||||
|
Brain.usbh_begin();
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// core1's loop: process usb host task on core1
|
||||||
|
void loop1() {
|
||||||
|
Brain.USBHost.task();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB Host callbacks
|
||||||
|
// Note: running in the same core where Brain.USBHost.task() is called
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Invoked when device is mounted (configured)
|
||||||
|
void tuh_mount_cb (uint8_t dev_addr)
|
||||||
|
{
|
||||||
|
uint16_t vid, pid;
|
||||||
|
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||||
|
|
||||||
|
Brain.LCD_printf("USBID %04x:%04x", vid, pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
void tuh_umount_cb(uint8_t dev_addr)
|
||||||
|
{
|
||||||
|
(void) dev_addr;
|
||||||
|
Brain.LCD_printf(1, "No USB Device");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
115
examples/Brain/usbh_hub_test/usbh_hub_test.ino
Normal file
115
examples/Brain/usbh_hub_test/usbh_hub_test.ino
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
// Testing USB host hardware on Brain by printing out VID/PID of attached device
|
||||||
|
// to LCD. Also determine if device support MSC or HID
|
||||||
|
|
||||||
|
// required for Host MSC block device
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
|
// required for USB host
|
||||||
|
#include "pio_usb.h"
|
||||||
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
|
#include "Adafruit_TestBed_Brains.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t vid;
|
||||||
|
uint16_t pid;
|
||||||
|
bool mounted;
|
||||||
|
} dev_info_t;
|
||||||
|
|
||||||
|
// CFG_TUH_DEVICE_MAX is defined by tusb_config header
|
||||||
|
dev_info_t dev_info[CFG_TUH_DEVICE_MAX] = { 0 };
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core0
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Scan and print VID/PID
|
||||||
|
uint8_t dev_count = 0;
|
||||||
|
for(uint8_t daddr=1; daddr < CFG_TUH_DEVICE_MAX+1; daddr++) {
|
||||||
|
dev_info_t const* dev = &dev_info[daddr-1];
|
||||||
|
|
||||||
|
if ( dev->mounted ) {
|
||||||
|
dev_count++;
|
||||||
|
Brain.LCD_printf("[%u] %04X:%04X", daddr, dev->vid, dev->pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dev_count == 0 ) {
|
||||||
|
Brain.LCD_printf(0, "No USB attached");
|
||||||
|
Brain.LCD_printf(1, "Plug your device");
|
||||||
|
}else {
|
||||||
|
Brain.LCD_printf("Devices num: %u", dev_count);
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Setup and Loop on Core1
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// call usbh_begin() hrere to make pio usb background task run on core1
|
||||||
|
// NOTE: Brain.begin() should be called here as well to prevent race condition
|
||||||
|
void setup1() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
// while (!Serial) delay(10);
|
||||||
|
|
||||||
|
Serial.println("Tester Brains USB Host test!");
|
||||||
|
|
||||||
|
// Init Brain peripherals
|
||||||
|
Brain.begin();
|
||||||
|
|
||||||
|
// Init Brain USB Host
|
||||||
|
Brain.usbh_begin();
|
||||||
|
|
||||||
|
Brain.LCD_printf(0, "No USB attached");
|
||||||
|
Brain.LCD_printf(1, "Plug your device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// core1's loop: process usb host task on core1
|
||||||
|
void loop1()
|
||||||
|
{
|
||||||
|
Brain.USBHost.task();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// TinyUSB Host callbacks
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Invoked when device is mounted (configured)
|
||||||
|
void tuh_mount_cb (uint8_t daddr)
|
||||||
|
{
|
||||||
|
dev_info_t* dev = &dev_info[daddr-1];
|
||||||
|
dev->mounted = true;
|
||||||
|
|
||||||
|
tuh_vid_pid_get(daddr, &dev->vid, &dev->pid);
|
||||||
|
|
||||||
|
Serial.printf("Device attached, address = %d\r\n", daddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when device is unmounted (bus reset/unplugged)
|
||||||
|
void tuh_umount_cb(uint8_t daddr)
|
||||||
|
{
|
||||||
|
dev_info_t* dev = &dev_info[daddr-1];
|
||||||
|
dev->mounted = false;
|
||||||
|
|
||||||
|
Serial.printf("Device removed, address = %d\r\n", daddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with CDC interface is mounted
|
||||||
|
// idx is index of cdc interface in the internal pool.
|
||||||
|
void tuh_cdc_mount_cb(uint8_t idx) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with CDC interface is unmounted
|
||||||
|
void tuh_cdc_umount_cb(uint8_t idx) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
0
examples/Brain/usbh_test/.pico_rp2350_tinyusb.test.only
Normal file
0
examples/Brain/usbh_test/.pico_rp2350_tinyusb.test.only
Normal file
|
|
@ -2,7 +2,7 @@
|
||||||
// to LCD. Also determine if device support MSC or HID
|
// to LCD. Also determine if device support MSC or HID
|
||||||
|
|
||||||
// required for Host MSC block device
|
// required for Host MSC block device
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
// required for USB host
|
// required for USB host
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
@ -13,6 +13,11 @@
|
||||||
// CDC Host object
|
// CDC Host object
|
||||||
Adafruit_USBH_CDC SerialHost;
|
Adafruit_USBH_CDC SerialHost;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
COLOR_NO_DEV = 0x00000ff,
|
||||||
|
COLOR_MOUNTED = 0x00ff00,
|
||||||
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Setup and Loop on Core0
|
// Setup and Loop on Core0
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
@ -57,9 +62,10 @@ void setup1() {
|
||||||
// Init Brain USB Host
|
// Init Brain USB Host
|
||||||
Brain.usbh_begin();
|
Brain.usbh_begin();
|
||||||
|
|
||||||
|
Brain.setColor(COLOR_NO_DEV);
|
||||||
|
|
||||||
// Since we only support 1 CDC interface with Tester (also CFG_TUH_CDC = 1)
|
// Since we only support 1 CDC interface with Tester (also CFG_TUH_CDC = 1)
|
||||||
// the index will always be 0 for SerialHost
|
// the index will always be 0 for SerialHost
|
||||||
// SerialHost.setInterfaceIndex(0);
|
|
||||||
SerialHost.begin(115200);
|
SerialHost.begin(115200);
|
||||||
|
|
||||||
Brain.LCD_printf(0, "No USB attached");
|
Brain.LCD_printf(0, "No USB attached");
|
||||||
|
|
@ -89,8 +95,8 @@ void tuh_mount_cb (uint8_t daddr)
|
||||||
tuh_vid_pid_get(daddr, &vid, &pid);
|
tuh_vid_pid_get(daddr, &vid, &pid);
|
||||||
|
|
||||||
Serial.printf("Device attached, address = %d\r\n", daddr);
|
Serial.printf("Device attached, address = %d\r\n", daddr);
|
||||||
|
Brain.setColor(COLOR_MOUNTED);
|
||||||
Brain.LCD_printf(0, "USBID %04x:%04x", vid, pid);
|
Brain.LCD_printf(0, "USBID %04x:%04x", vid, pid);
|
||||||
|
|
||||||
Brain.LCD_printf(1, "MS %u HID %u CDC %u", tuh_msc_mounted(daddr), tuh_hid_instance_count(daddr), SerialHost.mounted());
|
Brain.LCD_printf(1, "MS %u HID %u CDC %u", tuh_msc_mounted(daddr), tuh_hid_instance_count(daddr), SerialHost.mounted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,9 +104,22 @@ void tuh_mount_cb (uint8_t daddr)
|
||||||
void tuh_umount_cb(uint8_t daddr)
|
void tuh_umount_cb(uint8_t daddr)
|
||||||
{
|
{
|
||||||
Serial.printf("Device removed, address = %d\r\n", daddr);
|
Serial.printf("Device removed, address = %d\r\n", daddr);
|
||||||
|
Brain.setColor(COLOR_NO_DEV);
|
||||||
Brain.LCD_printf(0, "No USB attached");
|
Brain.LCD_printf(0, "No USB attached");
|
||||||
Brain.LCD_printf(1, "Plug your device");
|
Brain.LCD_printf(1, "Plug your device");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with CDC interface is mounted
|
||||||
|
// idx is index of cdc interface in the internal pool.
|
||||||
|
void tuh_cdc_mount_cb(uint8_t idx) {
|
||||||
|
// bind SerialHost object to this interface index
|
||||||
|
SerialHost.mount(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when a device with CDC interface is unmounted
|
||||||
|
void tuh_cdc_umount_cb(uint8_t idx) {
|
||||||
|
// unbind SerialHost if this interface is unmounted
|
||||||
|
SerialHost.umount(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ extern Adafruit_TestBed TB;
|
||||||
#if defined(ARDUINO_ARCH_RP2040) \
|
#if defined(ARDUINO_ARCH_RP2040) \
|
||||||
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) \
|
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) \
|
||||||
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) \
|
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) \
|
||||||
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3) \
|
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) \
|
||||||
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) \
|
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) \
|
||||||
|| defined(ARDUINO_SAM_DUE)
|
|| defined(ARDUINO_SAM_DUE) \
|
||||||
|
|| defined(ARDUINO_ARCH_RENESAS_UNO)
|
||||||
#define SECONDARY_I2C_PORT &Wire1
|
#define SECONDARY_I2C_PORT &Wire1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -25,7 +26,7 @@ void setup() {
|
||||||
|
|
||||||
#if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \
|
#if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \
|
||||||
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \
|
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \
|
||||||
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3) || \
|
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) || \
|
||||||
defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
|
defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
|
||||||
// ESP32 is kinda odd in that secondary ports must be manually
|
// ESP32 is kinda odd in that secondary ports must be manually
|
||||||
// assigned their pins with setPins()!
|
// assigned their pins with setPins()!
|
||||||
|
|
|
||||||
BIN
examples/program_esp32_uart_from_sdcard/NINA_W102-1.7.5.bin.gz
Normal file
BIN
examples/program_esp32_uart_from_sdcard/NINA_W102-1.7.5.bin.gz
Normal file
Binary file not shown.
30
examples/program_esp32_uart_from_sdcard/esp_binaries.h
Normal file
30
examples/program_esp32_uart_from_sdcard/esp_binaries.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Generated by tools/esp_compress.py
|
||||||
|
#define ESP_BINARIES_COUNT (1)
|
||||||
|
|
||||||
|
// const esp32_zipfile_t NINA_W102_1_7_5
|
||||||
|
|
||||||
|
const esp32_zipfile_t NINA_W102_1_7_5 = {
|
||||||
|
.name = "NINA_W102-1.7.5.bin.gz",
|
||||||
|
.data = NULL,
|
||||||
|
.compressed_len = 634996,
|
||||||
|
.uncompressed_len = 1160192,
|
||||||
|
.md5 =
|
||||||
|
{
|
||||||
|
0x07,
|
||||||
|
0x7c,
|
||||||
|
0xec,
|
||||||
|
0x6d,
|
||||||
|
0xaa,
|
||||||
|
0x68,
|
||||||
|
0x13,
|
||||||
|
0xc5,
|
||||||
|
0xa4,
|
||||||
|
0x68,
|
||||||
|
0x0f,
|
||||||
|
0x45,
|
||||||
|
0xc9,
|
||||||
|
0xd8,
|
||||||
|
0x77,
|
||||||
|
0x6b,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
/* This sketch run on SAMD21/SAMD51 to program ESP32 by flashing bin file from SD Card
|
||||||
|
* Supported/tested ESP MCU are: ESP32, ESP32-S2, ESP32-S3, ESP8266
|
||||||
|
* Hardware wiring:
|
||||||
|
* - TB D2 <-> ESP32 IO0
|
||||||
|
* - TB D3 <-> ESP32 Enable
|
||||||
|
* - TB TX/RX <-> ESP32 RX/TX
|
||||||
|
*
|
||||||
|
* How to run this example:
|
||||||
|
* 0. Define ESP32_RESET, ESP32_IO0, SD_CS, SD_DETECT in this sketch according to your hardware setup
|
||||||
|
* 1. Generate compressed binary and its metadata (len, md5 etc..) by running:
|
||||||
|
* python3 tools/esp_compress.py --sd <directory_of_bin_files>
|
||||||
|
* For example: python tools/esp_compress.py --sd .
|
||||||
|
* 2. .bin.gz (e.g NINA_W102-1.7.5.bin.gz) and esp_binaries.h will be generated in the same directory
|
||||||
|
* 3. Copy esp_binaries.h to this example directory
|
||||||
|
* 4. Copy .bin.gz files to SD Card within BIN_DIR (defined in this sketch)
|
||||||
|
* 5. Insert SD Card to board
|
||||||
|
* 6. Upload this sketch to board
|
||||||
|
*
|
||||||
|
* Note: for convenience, this example included generated 'NINA_W102-1.7.5.bin.gz' and 'esp_binaries.h'
|
||||||
|
* from https://github.com/adafruit/nina-fw/releases/tag/1.7.5 in this example directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
|
// #include "Adafruit_TinyUSB.h"
|
||||||
|
#include "Adafruit_TestBed.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Hardware Configuration
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// These are defined in airlift-capable board such PyPortal, PyBadge, etc.
|
||||||
|
#if defined(ESP32_GPIO0) && defined(ESP32_RESETN)
|
||||||
|
#define ESP32_RESET ESP32_RESETN
|
||||||
|
#define ESP32_IO0 ESP32_GPIO0
|
||||||
|
#else
|
||||||
|
#define ESP32_RESET 2
|
||||||
|
#define ESP32_IO0 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ARDUINO_PYPORTAL_M4)
|
||||||
|
#define SD_CS 32
|
||||||
|
#define SD_DETECT 33
|
||||||
|
#else
|
||||||
|
#define SD_CS 4
|
||||||
|
#define SD_DETECT 5 // optional
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ESP32_BAUDRATE 2000000
|
||||||
|
//#define ESP32_BAUDRATE 1500000
|
||||||
|
//#define ESP32_BAUDRATE 921600
|
||||||
|
//#define ESP32_BAUDRATE 115200
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Binaries and Path
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
#define BIN_DIR "/" // SD card's directory that contains bin files
|
||||||
|
#include "esp_binaries.h"
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t addr;
|
||||||
|
esp32_zipfile_t const *zfile;
|
||||||
|
} bin_files[] = {
|
||||||
|
{0x00000, &NINA_W102_1_7_5}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { BIN_FILES_COUNT = sizeof(bin_files) / sizeof(bin_files[0]) };
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Defined an boot rom object that use UART Serial1
|
||||||
|
ESP32BootROMClass ESP32BootROM(Serial1, ESP32_IO0, ESP32_RESET);
|
||||||
|
|
||||||
|
SdFat SD;
|
||||||
|
File32 fbin;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Implementation
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
void print_speed(size_t count, uint32_t ms) {
|
||||||
|
float count_k = count / 1000.0F;
|
||||||
|
float sec = ms / 1000.0F;
|
||||||
|
float speed = count_k / sec;
|
||||||
|
|
||||||
|
Serial.print(count_k); Serial.print("KB "); Serial.print(sec); Serial.println("s");
|
||||||
|
Serial.print("Spd: "); Serial.print(speed); Serial.println(" KB/s");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(10);
|
||||||
|
Serial.println("TestBed: Programming ESP32 with UART!");
|
||||||
|
|
||||||
|
#ifdef SD_DETECT
|
||||||
|
pinMode(SD_DETECT, INPUT_PULLUP);
|
||||||
|
if (digitalRead(SD_DETECT) == LOW) {
|
||||||
|
Serial.println("SD Card not inserted");
|
||||||
|
while (1) delay(10);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!SD.begin(SD_CS, SD_SCK_MHZ(12))) {
|
||||||
|
Serial.println("SD Card init failed");
|
||||||
|
while (1) delay(10);
|
||||||
|
}
|
||||||
|
Serial.println("SD Card init OK");
|
||||||
|
|
||||||
|
TB.begin();
|
||||||
|
while ( !TB.esp32_begin(&ESP32BootROM, ESP32_BAUDRATE) ) {
|
||||||
|
// retry syncing
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writing bin files
|
||||||
|
size_t total_bytes = 0;
|
||||||
|
uint32_t ms = millis();
|
||||||
|
for(size_t i=0; i<BIN_FILES_COUNT; i++) {
|
||||||
|
Serial.printf("Flashing file %u\r\n", i);
|
||||||
|
Serial.printf("File: %s\r\n", bin_files[i].zfile->name);
|
||||||
|
|
||||||
|
char bin_path[128] = BIN_DIR;
|
||||||
|
strcat(bin_path, bin_files[i].zfile->name);
|
||||||
|
|
||||||
|
fbin.open(&SD, bin_path);
|
||||||
|
if (!fbin) {
|
||||||
|
Serial.printf("Failed to open file %s\r\n", bin_files[i].zfile->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wr_count = TB.esp32_programFlashDefl(bin_files[i].zfile, bin_files[i].addr, &fbin);
|
||||||
|
total_bytes += wr_count;
|
||||||
|
if (!wr_count) {
|
||||||
|
Serial.printf("Failed to flash");
|
||||||
|
}
|
||||||
|
|
||||||
|
fbin.close();
|
||||||
|
}
|
||||||
|
print_speed(total_bytes, millis() - ms);
|
||||||
|
|
||||||
|
TB.esp32_end();
|
||||||
|
|
||||||
|
// reset ESP32 to run new firmware
|
||||||
|
TB.targetReset();
|
||||||
|
}
|
||||||
|
void loop() {
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name=Adafruit TestBed
|
name=Adafruit TestBed
|
||||||
version=1.7.0
|
version=1.14.2
|
||||||
author=Adafruit
|
author=Adafruit
|
||||||
maintainer=Adafruit <info@adafruit.com>
|
maintainer=Adafruit <info@adafruit.com>
|
||||||
sentence=Adafruit's internal test bed code library
|
sentence=Adafruit's internal test bed code library
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,25 @@
|
||||||
#include "Adafruit_TestBed.h"
|
#include "Adafruit_TestBed.h"
|
||||||
|
|
||||||
|
// change to 1 to skip pre-flash md5 check for testing
|
||||||
|
#define SKIP_PRE_FLASH_MD5_CHECK 0
|
||||||
|
|
||||||
|
static inline uint32_t div_ceil(uint32_t v, uint32_t d) {
|
||||||
|
return (v + d - 1) / d;
|
||||||
|
}
|
||||||
|
|
||||||
Adafruit_TestBed::Adafruit_TestBed(void) {
|
Adafruit_TestBed::Adafruit_TestBed(void) {
|
||||||
#if defined(ADAFRUIT_METRO_M0_EXPRESS)
|
#if defined(ADAFRUIT_METRO_M0_EXPRESS)
|
||||||
neopixelPin = 40;
|
neopixelPin = 40;
|
||||||
neopixelNum = 1;
|
neopixelNum = 1;
|
||||||
|
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
|
||||||
|
neopixelPin = 8;
|
||||||
|
neopixelNum = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
esp32boot = NULL;
|
||||||
|
_esp32_flash_defl = false;
|
||||||
|
_esp32_chip_detect = 0;
|
||||||
|
_esp32s3_in_reset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
@ -33,6 +48,11 @@ void Adafruit_TestBed::begin(void) {
|
||||||
digitalWrite(ledPin, LOW);
|
digitalWrite(ledPin, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (targetResetPin >= 0) {
|
||||||
|
pinMode(targetResetPin, OUTPUT);
|
||||||
|
digitalWrite(targetResetPin, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__AVR__)
|
#if defined(__AVR__)
|
||||||
analogRef = 5.0;
|
analogRef = 5.0;
|
||||||
#elif defined(ARDUINO_ARCH_RP2040)
|
#elif defined(ARDUINO_ARCH_RP2040)
|
||||||
|
|
@ -150,6 +170,23 @@ void Adafruit_TestBed::targetPowerCycle(uint16_t off_time) {
|
||||||
targetPower(1);
|
targetPower(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Adafruit_TestBed::targetReset(uint32_t reset_ms) {
|
||||||
|
digitalWrite(targetResetPin, LOW);
|
||||||
|
delay(reset_ms);
|
||||||
|
digitalWrite(targetResetPin, HIGH);
|
||||||
|
|
||||||
|
// Note: S3 has an USB-OTG errata
|
||||||
|
// https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf
|
||||||
|
// which is walkarounded by idf/arduino-esp32 to always mux JTAG to USB for
|
||||||
|
// uploading and/or power on. Afterwards USB-OTG will be set up if selected
|
||||||
|
// so. However rp2040 USBH is running too fast and can actually retrieve
|
||||||
|
// device/configuration descriptor of JTAG before the OTG is fully setup.
|
||||||
|
// Mark this for application usage
|
||||||
|
if (_esp32_chip_detect == CHIP_DETECT_MAGIC_ESP32S3) {
|
||||||
|
_esp32s3_in_reset = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Read the ADC on a pin and convert it to a voltage
|
@brief Read the ADC on a pin and convert it to a voltage
|
||||||
|
|
@ -160,7 +197,7 @@ void Adafruit_TestBed::targetPowerCycle(uint16_t off_time) {
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
float Adafruit_TestBed::readAnalogVoltage(uint16_t pin, float multiplier) {
|
float Adafruit_TestBed::readAnalogVoltage(uint16_t pin, float multiplier) {
|
||||||
float a = analogRead(pin);
|
float a = analogRead(pin);
|
||||||
theSerial->println(a);
|
// theSerial->println(a);
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3)
|
#if defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3)
|
||||||
if (a > 3000) {
|
if (a > 3000) {
|
||||||
|
|
@ -184,11 +221,13 @@ float Adafruit_TestBed::readAnalogVoltage(uint16_t pin, float multiplier) {
|
||||||
@param name Human readable name for the pin
|
@param name Human readable name for the pin
|
||||||
@param multiplier If there's a resistor divider, put the inverse here
|
@param multiplier If there's a resistor divider, put the inverse here
|
||||||
@param value What voltage the pin should be
|
@param value What voltage the pin should be
|
||||||
|
@param error Percent of error permitted (10 is 10%)
|
||||||
@return True if the pin voltage is within 10% of target
|
@return True if the pin voltage is within 10% of target
|
||||||
*/
|
*/
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
bool Adafruit_TestBed::testAnalogVoltage(uint16_t pin, const char *name,
|
bool Adafruit_TestBed::testAnalogVoltage(uint16_t pin, const char *name,
|
||||||
float multiplier, float value) {
|
float multiplier, float value,
|
||||||
|
uint8_t error) {
|
||||||
float voltage = readAnalogVoltage(pin, multiplier);
|
float voltage = readAnalogVoltage(pin, multiplier);
|
||||||
theSerial->print(name);
|
theSerial->print(name);
|
||||||
theSerial->print(F(" output voltage: "));
|
theSerial->print(F(" output voltage: "));
|
||||||
|
|
@ -196,11 +235,13 @@ bool Adafruit_TestBed::testAnalogVoltage(uint16_t pin, const char *name,
|
||||||
theSerial->print(F(" V (should be "));
|
theSerial->print(F(" V (should be "));
|
||||||
theSerial->print(value);
|
theSerial->print(value);
|
||||||
theSerial->print(" V)...");
|
theSerial->print(" V)...");
|
||||||
if (abs(voltage - value) > (value / 10.0)) {
|
if (abs(voltage - value) > (value * error / 100.0)) {
|
||||||
theSerial->println("Failed");
|
theSerial->println("Failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
theSerial->println(F("OK within 10%"));
|
theSerial->print(F("OK within "));
|
||||||
|
theSerial->print(error);
|
||||||
|
theSerial->println("%");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +421,8 @@ void Adafruit_TestBed::beep(uint32_t freq, uint32_t duration) {
|
||||||
if (piezoPin < 0)
|
if (piezoPin < 0)
|
||||||
return;
|
return;
|
||||||
pinMode(piezoPin, OUTPUT);
|
pinMode(piezoPin, OUTPUT);
|
||||||
#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_SAM_DUE)
|
#if !defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_SAM_DUE) && \
|
||||||
|
!defined(ARDUINO_METRO_ESP32S2)
|
||||||
tone(piezoPin, freq, duration);
|
tone(piezoPin, freq, duration);
|
||||||
#else
|
#else
|
||||||
// suppress compiler warns
|
// suppress compiler warns
|
||||||
|
|
@ -413,4 +455,203 @@ void Adafruit_TestBed::beepNblink(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief light the LED for 500ms, if defined
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
void Adafruit_TestBed::blink(void) {
|
||||||
|
if (ledPin >= 0) {
|
||||||
|
pinMode(ledPin, OUTPUT);
|
||||||
|
digitalWrite(ledPin, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
if (ledPin >= 0) {
|
||||||
|
digitalWrite(ledPin, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// ESP32 Target
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
bool Adafruit_TestBed::esp32_begin(ESP32BootROMClass *bootrom,
|
||||||
|
uint32_t baudrate) {
|
||||||
|
esp32boot = bootrom;
|
||||||
|
|
||||||
|
Serial.println("Syncing ESP32");
|
||||||
|
_esp32_chip_detect = esp32boot->begin(baudrate);
|
||||||
|
|
||||||
|
if (_esp32_chip_detect) {
|
||||||
|
setColor(0xFFFFFF);
|
||||||
|
Serial.println("Synced OK");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Serial.println("Sync failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Adafruit_TestBed::esp32_end(bool reset_esp) {
|
||||||
|
if (esp32boot->isRunningStub()) {
|
||||||
|
// skip sending flash_finish to ROM loader here,
|
||||||
|
// as it causes the loader to exit and run user code
|
||||||
|
esp32boot->beginFlash(0, 0, esp32boot->getFlashWriteSize());
|
||||||
|
|
||||||
|
if (_esp32_flash_defl) {
|
||||||
|
esp32boot->endFlashDefl(reset_esp);
|
||||||
|
} else {
|
||||||
|
esp32boot->endFlash(reset_esp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp32boot->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Adafruit_TestBed::esp32_s3_inReset(void) { return _esp32s3_in_reset; }
|
||||||
|
|
||||||
|
void Adafruit_TestBed::esp32_s3_clearReset(void) { _esp32s3_in_reset = false; }
|
||||||
|
|
||||||
|
static void print_buf(uint8_t const *buf, size_t len) {
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
Serial.print(buf[i], HEX);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
Adafruit_TestBed::_esp32_programFlashDefl_impl(const esp32_zipfile_t *zfile,
|
||||||
|
uint32_t addr, File32 *fsrc) {
|
||||||
|
if (!esp32boot) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if MD5 matches to skip this file
|
||||||
|
uint8_t esp_md5[16];
|
||||||
|
|
||||||
|
#if !SKIP_PRE_FLASH_MD5_CHECK
|
||||||
|
esp32boot->md5Flash(addr, zfile->uncompressed_len, esp_md5);
|
||||||
|
Serial.print("Flash MD5: ");
|
||||||
|
print_buf(esp_md5, 16);
|
||||||
|
if (0 == memcmp(zfile->md5, esp_md5, 16)) {
|
||||||
|
Serial.println("MD5 matched");
|
||||||
|
return zfile->uncompressed_len;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Write Size is different depending on ROM (1K) or Stub (16KB)
|
||||||
|
uint32_t const block_size = esp32boot->getFlashWriteSize();
|
||||||
|
|
||||||
|
uint8_t *buf = NULL;
|
||||||
|
bool const use_sdcard = (fsrc != NULL);
|
||||||
|
|
||||||
|
if (use_sdcard) {
|
||||||
|
buf = (uint8_t *)malloc(block_size);
|
||||||
|
if (!buf) {
|
||||||
|
Serial.print("No memory ");
|
||||||
|
Serial.println(block_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("Compressed ");
|
||||||
|
Serial.print(zfile->uncompressed_len);
|
||||||
|
Serial.print(" bytes to ");
|
||||||
|
Serial.println(zfile->compressed_len);
|
||||||
|
|
||||||
|
if (!esp32boot->beginFlashDefl(addr, zfile->uncompressed_len,
|
||||||
|
zfile->compressed_len)) {
|
||||||
|
Serial.println("beginFlash failed!");
|
||||||
|
if (buf) {
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_esp32_flash_defl = true;
|
||||||
|
|
||||||
|
//------------- Flashing -------------//
|
||||||
|
uint32_t written = 0;
|
||||||
|
|
||||||
|
uint32_t const block_num = div_ceil(zfile->compressed_len, block_size);
|
||||||
|
for (uint32_t i = 0; i < block_num; i++) {
|
||||||
|
setLED(HIGH);
|
||||||
|
// Serial.print("Pckt %lu/%lu", i + 1, block_num);
|
||||||
|
Serial.print("Packet ");
|
||||||
|
Serial.print(i + 1);
|
||||||
|
Serial.print("/");
|
||||||
|
Serial.println(block_num);
|
||||||
|
|
||||||
|
uint32_t const remain = zfile->compressed_len - written;
|
||||||
|
uint32_t const wr_count = (remain < block_size) ? remain : block_size;
|
||||||
|
|
||||||
|
uint8_t const *data;
|
||||||
|
if (!use_sdcard) {
|
||||||
|
// file contents is stored in internal flash (e.g rp2040)
|
||||||
|
data = zfile->data + written;
|
||||||
|
} else {
|
||||||
|
// file contents is stored in sdcard
|
||||||
|
memset(buf, 0xff, block_size); // empty it out
|
||||||
|
if (wr_count != fsrc->read(buf, wr_count)) {
|
||||||
|
Serial.println("File contents does not matched with compressed_len");
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: flash deflat does not need padding
|
||||||
|
if (!esp32boot->dataFlashDefl(data, wr_count)) {
|
||||||
|
Serial.println("Failed to flash");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
written += wr_count;
|
||||||
|
setLED(LOW);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
// Stub only writes each block to flash after 'ack'ing the receive,
|
||||||
|
// so do a final dummy operation which will not be 'ack'ed
|
||||||
|
// until the last block has actually been written out to flash
|
||||||
|
if (esp32boot->isRunningStub()) {
|
||||||
|
Serial.println("Dummy read chip detect after final block");
|
||||||
|
(void)esp32boot->read_chip_detect();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------- MD5 verification -------------//
|
||||||
|
Serial.println("Verifying MD5");
|
||||||
|
esp32boot->md5Flash(addr, zfile->uncompressed_len, esp_md5);
|
||||||
|
|
||||||
|
if (0 == memcmp(zfile->md5, esp_md5, 16)) {
|
||||||
|
Serial.println("MD5 matched");
|
||||||
|
} else {
|
||||||
|
Serial.println("MD5 mismatched!!");
|
||||||
|
|
||||||
|
Serial.print("File: ");
|
||||||
|
print_buf(zfile->md5, 16);
|
||||||
|
|
||||||
|
Serial.print("ESP : ");
|
||||||
|
print_buf(esp_md5, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return zfile->uncompressed_len;
|
||||||
|
}
|
||||||
|
size_t Adafruit_TestBed::esp32_programFlashDefl(const esp32_zipfile_t *zfile,
|
||||||
|
uint32_t addr) {
|
||||||
|
return _esp32_programFlashDefl_impl(zfile, addr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Adafruit_TestBed::esp32_programFlashDefl(const esp32_zipfile_t *zfile,
|
||||||
|
uint32_t addr, File32 *fsrc) {
|
||||||
|
return _esp32_programFlashDefl_impl(zfile, addr, fsrc);
|
||||||
|
}
|
||||||
|
|
||||||
Adafruit_TestBed TB;
|
Adafruit_TestBed TB;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
|
|
||||||
|
#include "ESP32BootROM.h"
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
#define RED 0xFF0000
|
#define RED 0xFF0000
|
||||||
#define YELLOW 0xFFFF00
|
#define YELLOW 0xFFFF00
|
||||||
#define GREEN 0x00FF00
|
#define GREEN 0x00FF00
|
||||||
|
|
@ -13,6 +16,14 @@
|
||||||
#define PURPLE 0xFF00FF
|
#define PURPLE 0xFF00FF
|
||||||
#define WHITE 0xFFFFFF
|
#define WHITE 0xFFFFFF
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
const uint8_t *data;
|
||||||
|
const uint32_t compressed_len;
|
||||||
|
const uint32_t uncompressed_len;
|
||||||
|
const uint8_t md5[16];
|
||||||
|
} esp32_zipfile_t;
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief A helper class for making test beds and functions. Lots of handy lil
|
@brief A helper class for making test beds and functions. Lots of handy lil
|
||||||
|
|
@ -33,9 +44,11 @@ public:
|
||||||
void targetPower(bool on);
|
void targetPower(bool on);
|
||||||
void targetPowerCycle(uint16_t off_time = 10);
|
void targetPowerCycle(uint16_t off_time = 10);
|
||||||
|
|
||||||
|
void targetReset(uint32_t reset_ms = 20);
|
||||||
|
|
||||||
float readAnalogVoltage(uint16_t pin, float multiplier = 1);
|
float readAnalogVoltage(uint16_t pin, float multiplier = 1);
|
||||||
bool testAnalogVoltage(uint16_t pin, const char *name, float multiplier,
|
bool testAnalogVoltage(uint16_t pin, const char *name, float multiplier,
|
||||||
float value);
|
float value, uint8_t error = 10);
|
||||||
|
|
||||||
bool testpins(uint8_t a, uint8_t b, uint8_t *allpins, uint8_t num_allpins);
|
bool testpins(uint8_t a, uint8_t b, uint8_t *allpins, uint8_t num_allpins);
|
||||||
|
|
||||||
|
|
@ -46,10 +59,29 @@ public:
|
||||||
|
|
||||||
void beep(uint32_t freq, uint32_t duration);
|
void beep(uint32_t freq, uint32_t duration);
|
||||||
void beepNblink(void);
|
void beepNblink(void);
|
||||||
|
void blink(void);
|
||||||
|
|
||||||
uint32_t timestamp(void);
|
uint32_t timestamp(void);
|
||||||
void printTimeTaken(bool restamp = false);
|
void printTimeTaken(bool restamp = false);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// ESP32 Target
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
bool esp32_begin(ESP32BootROMClass *bootrom, uint32_t baudrate);
|
||||||
|
void esp32_end(bool reset_esp = false);
|
||||||
|
|
||||||
|
// program esp32 target with compressed data stored in internal flash
|
||||||
|
size_t esp32_programFlashDefl(const esp32_zipfile_t *zfile, uint32_t addr);
|
||||||
|
|
||||||
|
// program esp32 target with compressed file from SDCard
|
||||||
|
size_t esp32_programFlashDefl(const esp32_zipfile_t *zfile, uint32_t addr,
|
||||||
|
File32 *fsrc);
|
||||||
|
|
||||||
|
bool esp32_s3_inReset(void);
|
||||||
|
void esp32_s3_clearReset(void);
|
||||||
|
|
||||||
|
ESP32BootROMClass *esp32boot; // ESP32 ROM
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
TwoWire *theWire = &Wire; ///< The I2C port used in scanning
|
TwoWire *theWire = &Wire; ///< The I2C port used in scanning
|
||||||
Stream *theSerial = &Serial; ///< The Serial port used for debugging
|
Stream *theSerial = &Serial; ///< The Serial port used for debugging
|
||||||
|
|
@ -60,6 +92,8 @@ public:
|
||||||
int16_t targetPowerPin = -1; ///< Set to a target power pin if used
|
int16_t targetPowerPin = -1; ///< Set to a target power pin if used
|
||||||
bool targetPowerPolarity = HIGH; ///< What to set the power pin to, for ON
|
bool targetPowerPolarity = HIGH; ///< What to set the power pin to, for ON
|
||||||
|
|
||||||
|
int targetResetPin = -1; ///< Set to target reset pin if used
|
||||||
|
|
||||||
int16_t neopixelPin = -1; ///< The neopixel connected pin if any
|
int16_t neopixelPin = -1; ///< The neopixel connected pin if any
|
||||||
uint8_t neopixelNum = 0; ///< How many neopixels are on board, if any
|
uint8_t neopixelNum = 0; ///< How many neopixels are on board, if any
|
||||||
Adafruit_NeoPixel *pixels =
|
Adafruit_NeoPixel *pixels =
|
||||||
|
|
@ -70,6 +104,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t millis_timestamp = 0; ///< A general purpose timestamp
|
uint32_t millis_timestamp = 0; ///< A general purpose timestamp
|
||||||
|
|
||||||
|
bool _esp32_flash_defl;
|
||||||
|
uint32_t _esp32_chip_detect;
|
||||||
|
bool _esp32s3_in_reset;
|
||||||
|
|
||||||
|
size_t _esp32_programFlashDefl_impl(const esp32_zipfile_t *zfile,
|
||||||
|
uint32_t addr, File32 *fsrc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Adafruit_TestBed TB;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ARDUINO_RASPBERRY_PI_PICO
|
#ifdef ARDUINO_ARCH_RP2040
|
||||||
|
|
||||||
#include "SdFat.h"
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
#include "pio_usb.h"
|
#include "pio_usb.h"
|
||||||
|
|
||||||
#include "Adafruit_DAP.h"
|
#include "Adafruit_DAP.h"
|
||||||
|
|
@ -34,8 +34,16 @@
|
||||||
|
|
||||||
#define USBHOST_RHPORT 1
|
#define USBHOST_RHPORT 1
|
||||||
|
|
||||||
|
// Workaround force F_CPU to 240MHz for programming RP2350 due to handshake
|
||||||
|
// timeout
|
||||||
|
#if F_CPU != 120000000L && F_CPU != 240000000L
|
||||||
|
#error "F_CPU must be set to either 120Mhz or 240Mhz for pio-usb host"
|
||||||
|
#endif
|
||||||
|
|
||||||
Adafruit_TestBed_Brains Brain;
|
Adafruit_TestBed_Brains Brain;
|
||||||
|
|
||||||
|
volatile bool LCD_semaphore = false;
|
||||||
|
|
||||||
// Simple and low code CRC calculation (copied from PicoOTA)
|
// Simple and low code CRC calculation (copied from PicoOTA)
|
||||||
class BrainCRC32 {
|
class BrainCRC32 {
|
||||||
public:
|
public:
|
||||||
|
|
@ -88,12 +96,11 @@ Adafruit_TestBed_Brains::Adafruit_TestBed_Brains() {
|
||||||
_usbh_dp_pin = 20; // USB Host D+
|
_usbh_dp_pin = 20; // USB Host D+
|
||||||
_vbus_en_pin = 22; // USB Host VBus enable
|
_vbus_en_pin = 22; // USB Host VBus enable
|
||||||
|
|
||||||
_target_rst = 27;
|
targetResetPin = 27;
|
||||||
_target_swdio = 2;
|
_target_swdio = 2;
|
||||||
_target_swdclk = 3;
|
_target_swdclk = 3;
|
||||||
|
|
||||||
dap = NULL;
|
dap = NULL;
|
||||||
esp32boot = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Adafruit_TestBed_Brains::begin(void) {
|
void Adafruit_TestBed_Brains::begin(void) {
|
||||||
|
|
@ -105,8 +112,8 @@ void Adafruit_TestBed_Brains::begin(void) {
|
||||||
neopixelNum = 1;
|
neopixelNum = 1;
|
||||||
pinMode(neopixelPin, OUTPUT);
|
pinMode(neopixelPin, OUTPUT);
|
||||||
|
|
||||||
pinMode(_target_rst, OUTPUT);
|
pinMode(targetResetPin, OUTPUT);
|
||||||
digitalWrite(_target_rst, HIGH);
|
digitalWrite(targetResetPin, HIGH);
|
||||||
|
|
||||||
pinMode(_sd_detect_pin, INPUT_PULLUP);
|
pinMode(_sd_detect_pin, INPUT_PULLUP);
|
||||||
pinMode(_vbus_en_pin, OUTPUT);
|
pinMode(_vbus_en_pin, OUTPUT);
|
||||||
|
|
@ -128,20 +135,13 @@ void Adafruit_TestBed_Brains::begin(void) {
|
||||||
|
|
||||||
bool Adafruit_TestBed_Brains::inited(void) { return _inited; }
|
bool Adafruit_TestBed_Brains::inited(void) { return _inited; }
|
||||||
|
|
||||||
void Adafruit_TestBed_Brains::targetReset(uint32_t reset_ms) {
|
|
||||||
digitalWrite(_target_rst, LOW);
|
|
||||||
delay(reset_ms);
|
|
||||||
digitalWrite(_target_rst, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// RP2040 Target
|
// RP2040 Target
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
void Adafruit_TestBed_Brains::rp2040_targetResetBootRom(int bootsel_pin,
|
void Adafruit_TestBed_Brains::rp2_targetResetBootRom(int bootsel_pin,
|
||||||
uint32_t reset_ms) {
|
uint32_t reset_ms) {
|
||||||
pinMode(bootsel_pin, OUTPUT);
|
pinMode(bootsel_pin, OUTPUT);
|
||||||
|
|
||||||
digitalWrite(bootsel_pin, LOW);
|
digitalWrite(bootsel_pin, LOW);
|
||||||
|
|
||||||
targetReset(reset_ms);
|
targetReset(reset_ms);
|
||||||
|
|
@ -152,7 +152,41 @@ void Adafruit_TestBed_Brains::rp2040_targetResetBootRom(int bootsel_pin,
|
||||||
pinMode(bootsel_pin, INPUT);
|
pinMode(bootsel_pin, INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Adafruit_TestBed_Brains::rp2040_programUF2(const char *fpath) {
|
size_t Adafruit_TestBed_Brains::rp2_programUF2(const uint8_t *buffer,
|
||||||
|
size_t bufsize) {
|
||||||
|
size_t copied_bytes = 0;
|
||||||
|
const char *dst_name = "FIRMWARE.UF2";
|
||||||
|
File32 fdst = USBH_FS.open(dst_name, O_WRONLY | O_CREAT);
|
||||||
|
|
||||||
|
if (!fdst) {
|
||||||
|
Serial.printf("USBH_FS: cannot create file: %s\r\n", dst_name);
|
||||||
|
} else {
|
||||||
|
while (copied_bytes < bufsize) {
|
||||||
|
size_t count = bufsize - copied_bytes;
|
||||||
|
if (count > 4096) {
|
||||||
|
count = 4096; // write 1 sector each
|
||||||
|
}
|
||||||
|
|
||||||
|
setLED(HIGH);
|
||||||
|
size_t wr_count = fdst.write(buffer, count);
|
||||||
|
setLED(LOW);
|
||||||
|
|
||||||
|
buffer += wr_count;
|
||||||
|
copied_bytes += wr_count;
|
||||||
|
|
||||||
|
if (wr_count != count) {
|
||||||
|
Serial.println("USBH_FS: Failed to write file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fdst.close();
|
||||||
|
|
||||||
|
return copied_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Adafruit_TestBed_Brains::rp2_programUF2(const char *fpath) {
|
||||||
File32 fsrc = SD.open(fpath);
|
File32 fsrc = SD.open(fpath);
|
||||||
if (!fsrc) {
|
if (!fsrc) {
|
||||||
Serial.printf("SD: cannot open file: %s\r\n", fpath);
|
Serial.printf("SD: cannot open file: %s\r\n", fpath);
|
||||||
|
|
@ -160,7 +194,6 @@ size_t Adafruit_TestBed_Brains::rp2040_programUF2(const char *fpath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t copied_bytes = 0;
|
size_t copied_bytes = 0;
|
||||||
|
|
||||||
const char *dst_name = "FIRMWARE.UF2";
|
const char *dst_name = "FIRMWARE.UF2";
|
||||||
File32 fdst = USBH_FS.open(dst_name, O_WRONLY | O_CREAT);
|
File32 fdst = USBH_FS.open(dst_name, O_WRONLY | O_CREAT);
|
||||||
|
|
||||||
|
|
@ -219,17 +252,17 @@ bool Adafruit_TestBed_Brains::dap_begin(Adafruit_DAP *dp) {
|
||||||
|
|
||||||
dap = dp;
|
dap = dp;
|
||||||
|
|
||||||
return dap->begin(_target_swdclk, _target_swdio, _target_rst,
|
return dap->begin(_target_swdclk, _target_swdio, targetResetPin,
|
||||||
dap_err_hanlder);
|
dap_err_hanlder);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Adafruit_TestBed_Brains::dap_connect(void) {
|
bool Adafruit_TestBed_Brains::dap_connect(uint32_t swj_clock) {
|
||||||
if (!dap) {
|
if (!dap) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LCD_printf("Connecting...");
|
LCD_printf("Connecting...");
|
||||||
if (!dap->targetConnect()) {
|
if (!dap->targetConnect(swj_clock)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,10 +272,6 @@ bool Adafruit_TestBed_Brains::dap_connect(void) {
|
||||||
LCD_printf(0, "Unknown MCU");
|
LCD_printf(0, "Unknown MCU");
|
||||||
LCD_printf(1, "ID = %08X", dsu_did);
|
LCD_printf(1, "ID = %08X", dsu_did);
|
||||||
|
|
||||||
while (1) {
|
|
||||||
delay(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,9 +280,9 @@ bool Adafruit_TestBed_Brains::dap_connect(void) {
|
||||||
? (dap->target_device.flash_size / dap->target_device.n_pages)
|
? (dap->target_device.flash_size / dap->target_device.n_pages)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
Serial.printf("Found Target: %s, ID = %08X\n", dap->target_device.name,
|
Serial.printf("Found Target: %s, ID = %08lX\n", dap->target_device.name,
|
||||||
dsu_did);
|
dsu_did);
|
||||||
Serial.printf("Flash size: %u, Page Num: %u, Page Size: %u\n",
|
Serial.printf("Flash size: %lu, Page Num: %lu, Page Size: %lu\n",
|
||||||
dap->target_device.flash_size, dap->target_device.n_pages,
|
dap->target_device.flash_size, dap->target_device.n_pages,
|
||||||
page_size);
|
page_size);
|
||||||
|
|
||||||
|
|
@ -272,9 +301,9 @@ bool Adafruit_TestBed_Brains::dap_unprotectBoot(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LCD_printf("Unlock chip...");
|
Serial.println("Unlock chip...");
|
||||||
bool ret = dap->unprotectBoot();
|
bool ret = dap->unprotectBoot();
|
||||||
LCD_printf(ret ? "OK" : "Failed");
|
Serial.println(ret ? "OK" : "Failed");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,9 +312,9 @@ bool Adafruit_TestBed_Brains::dap_protectBoot(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LCD_printf("Lock chip...");
|
Serial.println("Lock chip...");
|
||||||
bool ret = dap->protectBoot();
|
bool ret = dap->protectBoot();
|
||||||
LCD_printf(ret ? "OK" : "Failed");
|
Serial.println(ret ? "OK" : "Failed");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,14 +335,15 @@ bool Adafruit_TestBed_Brains::dap_eraseChip(void) {
|
||||||
dap->erase();
|
dap->erase();
|
||||||
|
|
||||||
ms = millis() - ms;
|
ms = millis() - ms;
|
||||||
LCD_printf("done in %.02fs", ms / 1000.0F);
|
LCD_printf("Erased in %.02fs", ms / 1000.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
|
size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
|
||||||
uint32_t addr) {
|
uint32_t addr, bool do_verify,
|
||||||
|
bool do_crc32) {
|
||||||
if (!dap) {
|
if (!dap) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -356,7 +386,8 @@ size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LCD_printf("Programming..");
|
LCD_printf("Programming...");
|
||||||
|
uint32_t ms = millis();
|
||||||
|
|
||||||
BrainCRC32 crc32;
|
BrainCRC32 crc32;
|
||||||
dap->program_start(addr, fsize);
|
dap->program_start(addr, fsize);
|
||||||
|
|
@ -364,22 +395,42 @@ size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
|
||||||
uint32_t addr_tmp = addr;
|
uint32_t addr_tmp = addr;
|
||||||
while (fsrc.available()) {
|
while (fsrc.available()) {
|
||||||
memset(buf, 0xff, bufsize); // empty it out
|
memset(buf, 0xff, bufsize); // empty it out
|
||||||
|
|
||||||
uint32_t rd_count = fsrc.read(buf, bufsize);
|
uint32_t rd_count = fsrc.read(buf, bufsize);
|
||||||
|
|
||||||
setLED(HIGH);
|
setLED(HIGH);
|
||||||
dap->programBlock(addr_tmp, buf, bufsize);
|
|
||||||
crc32.add(buf, rd_count);
|
// don't verify each write if we use crc32
|
||||||
setLED(LOW);
|
if (!dap->programFlash(addr_tmp, buf, bufsize, !do_crc32 && do_verify)) {
|
||||||
|
Serial.printf("Failed to program block at %08lX\n", addr_tmp);
|
||||||
|
free(buf);
|
||||||
|
fsrc.close();
|
||||||
|
return addr_tmp - addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_crc32) {
|
||||||
|
crc32.add(buf, rd_count);
|
||||||
|
}
|
||||||
|
|
||||||
addr_tmp += bufsize;
|
addr_tmp += bufsize;
|
||||||
|
|
||||||
|
setLED(LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t target_crc = dap->computeFlashCRC32(addr, fsize);
|
Serial.printf("Programming end, t = %lu ms\r\n", millis(), millis() - ms);
|
||||||
|
|
||||||
if (target_crc != crc32.get()) {
|
if (do_crc32) {
|
||||||
LCD_printf("CRC Failed");
|
ms = millis();
|
||||||
Serial.printf("CRC mismtached: %08X != %08X\n", crc32.get(), target_crc);
|
Serial.printf("CRC32 start\r\n", ms);
|
||||||
|
uint32_t target_crc = dap->computeFlashCRC32(addr, fsize);
|
||||||
|
Serial.printf("CRC32 end, t = %lu ms\r\n", millis(), millis() - ms);
|
||||||
|
|
||||||
|
if (target_crc != crc32.get()) {
|
||||||
|
LCD_printf("CRC Failed");
|
||||||
|
Serial.printf("CRC mismtached: %08lX != %08lX\n", crc32.get(),
|
||||||
|
target_crc);
|
||||||
|
} else {
|
||||||
|
LCD_printf("Done!");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LCD_printf("Done!");
|
LCD_printf("Done!");
|
||||||
}
|
}
|
||||||
|
|
@ -390,112 +441,47 @@ size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
|
||||||
return fsize;
|
return fsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
size_t Adafruit_TestBed_Brains::dap_readFlash(const char *fpath, uint32_t addr,
|
||||||
// ESP32 Target
|
size_t size) {
|
||||||
//--------------------------------------------------------------------+
|
if (!dap) {
|
||||||
|
|
||||||
bool Adafruit_TestBed_Brains::esp32_begin(ESP32BootROMClass *bootrom,
|
|
||||||
uint32_t baudrate) {
|
|
||||||
esp32boot = bootrom;
|
|
||||||
|
|
||||||
LCD_printf("Syncing ESP32");
|
|
||||||
bool ret = esp32boot->begin(baudrate);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
LCD_printf("Synced OK");
|
|
||||||
} else {
|
|
||||||
LCD_printf_error("Sync failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Adafruit_TestBed_Brains::esp32_end(void) {
|
|
||||||
esp32boot->endFlash(false);
|
|
||||||
esp32boot->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Adafruit_TestBed_Brains::essp32_programFlash(const char *fpath,
|
|
||||||
uint32_t addr) {
|
|
||||||
if (!esp32boot) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum { MAX_PAYLOAD_SIZE = 1024 };
|
size_t bufsize = 4096;
|
||||||
|
uint8_t *buf = (uint8_t *)malloc(bufsize);
|
||||||
uint8_t *buf = (uint8_t *)malloc(MAX_PAYLOAD_SIZE);
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
LCD_printf_error("No memory %u\n", MAX_PAYLOAD_SIZE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
File32 fsrc = SD.open(fpath);
|
File32 fsrc = SD.open(fpath, O_CREAT | O_WRONLY);
|
||||||
if (!fsrc) {
|
if (!fsrc) {
|
||||||
Serial.printf("SD: cannot open file: %s\r\n", fpath);
|
Serial.printf("SD: cannot open file: %s\r\n", fpath);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint32_t fsize = fsrc.fileSize();
|
|
||||||
uint32_t total_count = 0;
|
|
||||||
|
|
||||||
if (!esp32boot->beginFlash(addr, fsize, MAX_PAYLOAD_SIZE)) {
|
LCD_printf("Reading...");
|
||||||
LCD_printf_error("beginFlash failed!");
|
|
||||||
} else {
|
|
||||||
LCD_printf("#Packets %u", fsize / MAX_PAYLOAD_SIZE);
|
|
||||||
|
|
||||||
MD5Builder md5;
|
size_t remain = size;
|
||||||
md5.begin();
|
while (remain) {
|
||||||
|
uint32_t count = min(remain, bufsize);
|
||||||
|
|
||||||
//------------- Flashing -------------//
|
setLED(HIGH);
|
||||||
while (fsrc.available()) {
|
if (!dap->dap_read_block(addr, buf, (int)count)) {
|
||||||
memset(buf, 0xff, MAX_PAYLOAD_SIZE); // empty it out
|
Serial.printf("Failed to read block at %08lX\n", addr);
|
||||||
uint32_t rd_count = fsrc.read(buf, MAX_PAYLOAD_SIZE);
|
break;
|
||||||
|
|
||||||
setLED(HIGH);
|
|
||||||
Serial.printf("#");
|
|
||||||
if (!esp32boot->dataFlash(buf, MAX_PAYLOAD_SIZE)) {
|
|
||||||
LCD_printf_error("Failed to flash");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
setLED(LOW);
|
|
||||||
|
|
||||||
md5.add(buf, rd_count);
|
|
||||||
total_count += rd_count;
|
|
||||||
}
|
}
|
||||||
Serial.println();
|
setLED(LOW);
|
||||||
|
|
||||||
//------------- MD5 verification -------------//
|
fsrc.write(buf, count);
|
||||||
md5.calculate();
|
LCD_printf("%d remaining", remain);
|
||||||
Serial.printf("md5 = %s\r\n", md5.toString().c_str());
|
addr += count;
|
||||||
|
remain -= count;
|
||||||
uint8_t file_md5[16];
|
|
||||||
md5.getBytes(file_md5);
|
|
||||||
|
|
||||||
uint8_t esp_md5[16];
|
|
||||||
esp32boot->md5Flash(addr, fsize, esp_md5);
|
|
||||||
|
|
||||||
if (0 == memcmp(file_md5, esp_md5, 16)) {
|
|
||||||
LCD_printf("MD5 matched");
|
|
||||||
} else {
|
|
||||||
LCD_printf_error("MD5 mismatched!!");
|
|
||||||
|
|
||||||
Serial.printf("File: ");
|
|
||||||
for (size_t i = 0; i < 16; i++) {
|
|
||||||
Serial.printf("%02X ", file_md5[i]);
|
|
||||||
}
|
|
||||||
Serial.println();
|
|
||||||
|
|
||||||
Serial.printf("ESP : ");
|
|
||||||
for (size_t i = 0; i < 16; i++) {
|
|
||||||
Serial.printf("%02X ", esp_md5[i]);
|
|
||||||
}
|
|
||||||
Serial.println();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
|
||||||
fsrc.close();
|
fsrc.close();
|
||||||
|
LCD_printf("Done!");
|
||||||
|
|
||||||
return total_count;
|
return size - remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
@ -528,16 +514,225 @@ bool Adafruit_TestBed_Brains::SD_begin(uint32_t max_clock) {
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// LCD
|
// LCD
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
#define NOP1 __asm volatile("nop");
|
||||||
|
#define NOP2 NOP1 NOP1
|
||||||
|
#define NOP3 NOP2 NOP1
|
||||||
|
#define NOP4 NOP2 NOP2
|
||||||
|
#define NOP5 NOP4 NOP1
|
||||||
|
#define NOP6 NOP4 NOP2
|
||||||
|
#define NOP7 NOP4 NOP3
|
||||||
|
#define NOP8 NOP4 NOP4
|
||||||
|
#define NOP9 NOP8 NOP1
|
||||||
|
#define NOP10 NOP8 NOP2
|
||||||
|
#define NOP11 NOP8 NOP3
|
||||||
|
#define NOP12 NOP8 NOP4
|
||||||
|
#define NOP13 NOP8 NOP5
|
||||||
|
#define NOP14 NOP8 NOP6
|
||||||
|
#define NOP15 NOP8 NOP7
|
||||||
|
#define NOP16 NOP8 NOP8
|
||||||
|
#define NOP17 NOP16 NOP1
|
||||||
|
#define NOP18 NOP16 NOP2
|
||||||
|
#define NOP19 NOP16 NOP3
|
||||||
|
#define NOP20 NOP16 NOP4
|
||||||
|
#define NOP21 NOP16 NOP5
|
||||||
|
#define NOP22 NOP16 NOP6
|
||||||
|
#define NOP23 NOP16 NOP7
|
||||||
|
#define NOP24 NOP16 NOP8
|
||||||
|
#define NOP25 NOP16 NOP9
|
||||||
|
#define NOP26 NOP16 NOP10
|
||||||
|
#define NOP27 NOP16 NOP11
|
||||||
|
#define NOP28 NOP16 NOP12
|
||||||
|
#define NOP29 NOP16 NOP13
|
||||||
|
#define NOP30 NOP16 NOP14
|
||||||
|
#define NOP31 NOP16 NOP15
|
||||||
|
#define NOP32 NOP16 NOP16
|
||||||
|
#define NOP33 NOP32 NOP1
|
||||||
|
#define NOP34 NOP32 NOP2
|
||||||
|
#define NOP35 NOP32 NOP3
|
||||||
|
#define NOP36 NOP32 NOP4
|
||||||
|
#define NOP37 NOP32 NOP5
|
||||||
|
#define NOP38 NOP32 NOP6
|
||||||
|
#define NOP39 NOP32 NOP7
|
||||||
|
#define NOP40 NOP32 NOP8
|
||||||
|
#define NOP41 NOP32 NOP9
|
||||||
|
#define NOP42 NOP32 NOP10
|
||||||
|
#define NOP43 NOP32 NOP11
|
||||||
|
#define NOP44 NOP32 NOP12
|
||||||
|
#define NOP45 NOP32 NOP13
|
||||||
|
#define NOP46 NOP32 NOP14
|
||||||
|
#define NOP47 NOP32 NOP15
|
||||||
|
#define NOP48 NOP32 NOP16
|
||||||
|
#define NOP49 NOP48 NOP1
|
||||||
|
#define NOP50 NOP48 NOP2
|
||||||
|
#define NOP51 NOP48 NOP3
|
||||||
|
#define NOP52 NOP48 NOP4
|
||||||
|
#define NOP53 NOP48 NOP5
|
||||||
|
#define NOP54 NOP48 NOP6
|
||||||
|
#define NOP55 NOP48 NOP7
|
||||||
|
#define NOP56 NOP48 NOP8
|
||||||
|
#define NOP57 NOP48 NOP9
|
||||||
|
#define NOP58 NOP48 NOP10
|
||||||
|
#define NOP59 NOP48 NOP11
|
||||||
|
#define NOP60 NOP48 NOP12
|
||||||
|
#define NOP61 NOP48 NOP13
|
||||||
|
#define NOP62 NOP48 NOP14
|
||||||
|
#define NOP63 NOP48 NOP15
|
||||||
|
#define NOP64 NOP48 NOP16
|
||||||
|
#define NOP65 NOP64 NOP1
|
||||||
|
#define NOP66 NOP64 NOP2
|
||||||
|
#define NOP67 NOP64 NOP3
|
||||||
|
#define NOP68 NOP64 NOP4
|
||||||
|
#define NOP69 NOP64 NOP5
|
||||||
|
#define NOP70 NOP64 NOP6
|
||||||
|
#define NOP71 NOP64 NOP7
|
||||||
|
#define NOP72 NOP64 NOP8
|
||||||
|
#define NOP73 NOP64 NOP9
|
||||||
|
#define NOP74 NOP64 NOP10
|
||||||
|
#define NOP75 NOP64 NOP11
|
||||||
|
#define NOP76 NOP64 NOP12
|
||||||
|
#define NOP77 NOP64 NOP13
|
||||||
|
#define NOP78 NOP64 NOP14
|
||||||
|
#define NOP79 NOP64 NOP15
|
||||||
|
#define NOP80 NOP64 NOP16
|
||||||
|
#define NOP81 NOP80 NOP1
|
||||||
|
#define NOP82 NOP80 NOP2
|
||||||
|
#define NOP83 NOP80 NOP3
|
||||||
|
#define NOP84 NOP80 NOP4
|
||||||
|
#define NOP85 NOP80 NOP5
|
||||||
|
#define NOP86 NOP80 NOP6
|
||||||
|
#define NOP87 NOP80 NOP7
|
||||||
|
#define NOP88 NOP80 NOP8
|
||||||
|
#define NOP89 NOP80 NOP9
|
||||||
|
#define NOP90 NOP80 NOP10
|
||||||
|
#define NOP91 NOP80 NOP11
|
||||||
|
#define NOP92 NOP80 NOP12
|
||||||
|
#define NOP93 NOP80 NOP13
|
||||||
|
#define NOP94 NOP80 NOP14
|
||||||
|
#define NOP95 NOP80 NOP15
|
||||||
|
#define NOP96 NOP80 NOP16
|
||||||
|
#define NOP97 NOP96 NOP1
|
||||||
|
#define NOP98 NOP96 NOP2
|
||||||
|
#define NOP99 NOP96 NOP3
|
||||||
|
#define NOP100 NOP96 NOP4
|
||||||
|
#define NOP101 NOP100 NOP1
|
||||||
|
#define NOP102 NOP100 NOP2
|
||||||
|
#define NOP103 NOP100 NOP3
|
||||||
|
#define NOP104 NOP100 NOP4
|
||||||
|
#define NOP105 NOP100 NOP5
|
||||||
|
#define NOP106 NOP100 NOP6
|
||||||
|
#define NOP107 NOP100 NOP7
|
||||||
|
#define NOP108 NOP100 NOP8
|
||||||
|
#define NOP109 NOP100 NOP9
|
||||||
|
#define NOP110 NOP100 NOP10
|
||||||
|
#define NOP111 NOP100 NOP11
|
||||||
|
#define NOP112 NOP100 NOP12
|
||||||
|
#define NOP113 NOP100 NOP13
|
||||||
|
#define NOP114 NOP100 NOP14
|
||||||
|
#define NOP115 NOP100 NOP15
|
||||||
|
#define NOP116 NOP100 NOP16
|
||||||
|
#define NOP117 NOP116 NOP1
|
||||||
|
#define NOP118 NOP116 NOP2
|
||||||
|
#define NOP119 NOP116 NOP3
|
||||||
|
#define NOP120 NOP116 NOP4
|
||||||
|
#define NOP121 NOP116 NOP5
|
||||||
|
#define NOP122 NOP116 NOP6
|
||||||
|
#define NOP123 NOP116 NOP7
|
||||||
|
#define NOP124 NOP116 NOP8
|
||||||
|
#define NOP125 NOP116 NOP9
|
||||||
|
#define NOP126 NOP116 NOP10
|
||||||
|
#define NOP127 NOP116 NOP11
|
||||||
|
#define NOP128 NOP116 NOP12
|
||||||
|
#define NOP129 NOP128 NOP1
|
||||||
|
#define NOP130 NOP128 NOP2
|
||||||
|
#define NOP131 NOP128 NOP3
|
||||||
|
#define NOP132 NOP128 NOP4
|
||||||
|
#define NOP133 NOP128 NOP5
|
||||||
|
#define NOP134 NOP128 NOP6
|
||||||
|
#define NOP135 NOP128 NOP7
|
||||||
|
#define NOP136 NOP128 NOP8
|
||||||
|
#define NOP137 NOP128 NOP9
|
||||||
|
#define NOP138 NOP128 NOP10
|
||||||
|
#define NOP139 NOP128 NOP11
|
||||||
|
#define NOP140 NOP128 NOP12
|
||||||
|
#define NOP141 NOP128 NOP13
|
||||||
|
#define NOP142 NOP128 NOP14
|
||||||
|
#define NOP143 NOP128 NOP15
|
||||||
|
#define NOP144 NOP128 NOP16
|
||||||
|
#define NOP145 NOP144 NOP1
|
||||||
|
#define NOP146 NOP144 NOP2
|
||||||
|
#define NOP147 NOP144 NOP3
|
||||||
|
#define NOP148 NOP144 NOP4
|
||||||
|
#define NOP149 NOP144 NOP5
|
||||||
|
#define NOP150 NOP144 NOP6
|
||||||
|
#define NOP151 NOP144 NOP7
|
||||||
|
#define NOP152 NOP144 NOP8
|
||||||
|
#define NOP153 NOP144 NOP9
|
||||||
|
#define NOP154 NOP144 NOP10
|
||||||
|
#define NOP155 NOP144 NOP11
|
||||||
|
#define NOP156 NOP144 NOP12
|
||||||
|
#define NOP157 NOP144 NOP13
|
||||||
|
#define NOP158 NOP144 NOP14
|
||||||
|
#define NOP159 NOP144 NOP15
|
||||||
|
#define NOP160 NOP144 NOP16
|
||||||
|
#define NOP161 NOP160 NOP1
|
||||||
|
#define NOP162 NOP160 NOP2
|
||||||
|
#define NOP163 NOP160 NOP3
|
||||||
|
#define NOP164 NOP160 NOP4
|
||||||
|
#define NOP165 NOP160 NOP5
|
||||||
|
#define NOP166 NOP160 NOP6
|
||||||
|
#define NOP167 NOP160 NOP7
|
||||||
|
#define NOP168 NOP160 NOP8
|
||||||
|
#define NOP169 NOP160 NOP9
|
||||||
|
#define NOP170 NOP160 NOP10
|
||||||
|
#define NOP171 NOP160 NOP11
|
||||||
|
#define NOP172 NOP160 NOP12
|
||||||
|
#define NOP173 NOP160 NOP13
|
||||||
|
#define NOP174 NOP160 NOP14
|
||||||
|
#define NOP175 NOP160 NOP15
|
||||||
|
#define NOP176 NOP160 NOP16
|
||||||
|
#define NOP177 NOP176 NOP1
|
||||||
|
#define NOP178 NOP176 NOP2
|
||||||
|
#define NOP179 NOP176 NOP3
|
||||||
|
#define NOP180 NOP176 NOP4
|
||||||
|
#define NOP181 NOP176 NOP5
|
||||||
|
#define NOP182 NOP176 NOP6
|
||||||
|
#define NOP183 NOP176 NOP7
|
||||||
|
#define NOP184 NOP176 NOP8
|
||||||
|
#define NOP185 NOP176 NOP9
|
||||||
|
#define NOP186 NOP176 NOP10
|
||||||
|
#define NOP187 NOP176 NOP11
|
||||||
|
#define NOP188 NOP176 NOP12
|
||||||
|
#define NOP189 NOP176 NOP13
|
||||||
|
#define NOP190 NOP176 NOP14
|
||||||
|
#define NOP191 NOP176 NOP15
|
||||||
|
#define NOP192 NOP176 NOP16
|
||||||
|
#define NOP193 NOP192 NOP1
|
||||||
|
#define NOP194 NOP192 NOP2
|
||||||
|
#define NOP195 NOP192 NOP3
|
||||||
|
#define NOP196 NOP192 NOP4
|
||||||
|
#define NOP197 NOP192 NOP5
|
||||||
|
#define NOP198 NOP192 NOP6
|
||||||
|
#define NOP199 NOP192 NOP7
|
||||||
|
#define NOP200 NOP192 NOP8
|
||||||
|
|
||||||
// 1s = 1.000.000 us --> 120.000.000 nop
|
#define _NOP_COUNT(n) NOP##n
|
||||||
// 1 us -> 120 nop
|
#define NOP_COUNT(n) _NOP_COUNT(n)
|
||||||
// full frame, 1.25 us -> 150 nop
|
|
||||||
// - T1H 0,76 us -> 91 nop
|
void __no_inline_not_in_flash_func(Adafruit_TestBed_Brains::setColor)(
|
||||||
// - T0H 0,36 us -> 43 nop
|
uint32_t color) {
|
||||||
|
static uint32_t end_us = 0;
|
||||||
|
static uint32_t last_color = 0x123456;
|
||||||
|
|
||||||
|
if (last_color == color) {
|
||||||
|
// no need to update
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_color = color;
|
||||||
|
|
||||||
|
uint8_t r = (uint8_t)(color >> 16); // red
|
||||||
|
uint8_t g = (uint8_t)(color >> 8); // green
|
||||||
|
uint8_t b = (uint8_t)color; // blue
|
||||||
|
|
||||||
void Adafruit_TestBed_Brains::setColor(uint32_t color) {
|
|
||||||
uint8_t r = (uint8_t)(color >> 16), g = (uint8_t)(color >> 8),
|
|
||||||
b = (uint8_t)color;
|
|
||||||
uint8_t buf[3] = {r, g, b};
|
uint8_t buf[3] = {r, g, b};
|
||||||
|
|
||||||
uint8_t *ptr, *end, p, bitMask;
|
uint8_t *ptr, *end, p, bitMask;
|
||||||
|
|
@ -548,65 +743,107 @@ void Adafruit_TestBed_Brains::setColor(uint32_t color) {
|
||||||
p = *ptr++;
|
p = *ptr++;
|
||||||
bitMask = 0x80;
|
bitMask = 0x80;
|
||||||
|
|
||||||
// 800 KHz
|
// wait for previous frame to finish
|
||||||
for (;;) {
|
enum { FRAME_TIME_US = 300 };
|
||||||
|
|
||||||
|
uint32_t now = end_us;
|
||||||
|
while (now - end_us < FRAME_TIME_US) {
|
||||||
|
now = micros();
|
||||||
|
if (now < end_us) {
|
||||||
|
// micros() overflow
|
||||||
|
end_us = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t const isr_context = save_and_disable_interrupts();
|
||||||
|
|
||||||
|
/* Neopixel is 800 KHz, 1T = 1.25 us = 150 nop (120Mhz), 300 nop (240Mhz)
|
||||||
|
- T1H = 0.8 us, T1L = 0.45 us
|
||||||
|
- T0H = 0.4 us, T0L = 0.85 us
|
||||||
|
If F_CPU is 120 MHz: 120 nop = 1us -> 1 nop = 8.33 ns
|
||||||
|
- T1H = 0.8 us = 96 nop, T1L = 0.45 us = 54 nop
|
||||||
|
- T0H = 0.4 us = 48 nop, T0L = 0.85 us = 102 nop
|
||||||
|
If F_CPU is 240 MHz: 240 nop = 1us -> 1 nop = 4.17 ns
|
||||||
|
- T1H = 0.8 us = 192 nop, T1L = 0.45 us = 108 nop
|
||||||
|
- T0H = 0.4 us = 96 nop, T0L = 0.85 us = 204 nop
|
||||||
|
Due to overhead the number of NOP is actually smaller, also M33 run faster
|
||||||
|
(higher IPC) therefore these are hand tuned,
|
||||||
|
*/
|
||||||
|
#if defined(ARDUINO_RASPBERRY_PI_PICO)
|
||||||
|
// value for rp2040 at 120MHz
|
||||||
|
#define T1H_CYCLE 90
|
||||||
|
#define T1L_CYCLE 39
|
||||||
|
#define T0H_CYCLE 42
|
||||||
|
#define T0L_CYCLE 84
|
||||||
|
#define LOOP_OVERHEAD_CYCLE 10 // overhead for if/else and loop
|
||||||
|
#elif defined(ARDUINO_RASPBERRY_PI_PICO_2)
|
||||||
|
// value for rp2350 at 120MHz
|
||||||
|
#define T1H_CYCLE 190
|
||||||
|
#define T1L_CYCLE 90
|
||||||
|
#define T0H_CYCLE 88
|
||||||
|
#define T0L_CYCLE 180
|
||||||
|
#define LOOP_OVERHEAD_CYCLE 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (1) {
|
||||||
if (p & bitMask) {
|
if (p & bitMask) {
|
||||||
// T1H 0,76 us -> 91 nop
|
// T1H 0.8 us = 96 nop (without overhead)
|
||||||
sio_hw->gpio_set = pinMask;
|
sio_hw->gpio_set = pinMask;
|
||||||
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T1H_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#if F_CPU == 240000000L
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T1H_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#endif
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop;");
|
|
||||||
|
|
||||||
// 150 - 91 = 59 nop
|
// T1L 0.45 = 54 - 10 (ifelse) - 5 (overhead) = 44 nop
|
||||||
sio_hw->gpio_clr = pinMask;
|
sio_hw->gpio_clr = pinMask;
|
||||||
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T1L_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#if F_CPU == 240000000L
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T1L_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#endif
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop;");
|
|
||||||
} else {
|
} else {
|
||||||
// T0H 0,36 us -> 43 nop
|
// T0H 0.4 us = 48 cycles
|
||||||
sio_hw->gpio_set = pinMask;
|
sio_hw->gpio_set = pinMask;
|
||||||
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T0H_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#if F_CPU == 240000000L
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T0H_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#endif
|
||||||
"nop; nop; nop;");
|
|
||||||
|
|
||||||
// 150 - 43 = 107 nop
|
// T0L 0.85 us = 102 - 10 (ifelse) - 5 (overhead) = 87 nop
|
||||||
sio_hw->gpio_clr = pinMask;
|
sio_hw->gpio_clr = pinMask;
|
||||||
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T0L_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#if F_CPU == 240000000L
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
NOP_COUNT(T0L_CYCLE);
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
#endif
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
|
|
||||||
"nop; nop; nop; nop; nop; nop; nop;");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a full byte is sent, next to another byte
|
if (bitMask >>= 1) {
|
||||||
if (0 == (bitMask >>= 1)) {
|
// not full byte, shift to next bit
|
||||||
if (ptr >= end)
|
NOP_COUNT(LOOP_OVERHEAD_CYCLE);
|
||||||
|
} else {
|
||||||
|
// probably take 10 nops
|
||||||
|
// if a full byte is sent, next to another byte
|
||||||
|
if (ptr >= end) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
p = *ptr++;
|
p = *ptr++;
|
||||||
bitMask = 0x80;
|
bitMask = 0x80;
|
||||||
}
|
}
|
||||||
|
#if F_CPU == 240000000L
|
||||||
|
NOP_COUNT(LOOP_OVERHEAD_CYCLE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore_interrupts(isr_context);
|
||||||
|
|
||||||
|
end_us = micros();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Adafruit_TestBed_Brains::lcd_write(uint8_t linenum, char linebuf[17]) {
|
void Adafruit_TestBed_Brains::lcd_write(uint8_t linenum, char linebuf[17]) {
|
||||||
|
// wait for semaphore to release
|
||||||
|
while (LCD_semaphore)
|
||||||
|
yield();
|
||||||
|
LCD_semaphore = true;
|
||||||
// fill the rest with spaces
|
// fill the rest with spaces
|
||||||
memset(linebuf + strlen(linebuf), ' ', 16 - strlen(linebuf));
|
memset(linebuf + strlen(linebuf), ' ', 16 - strlen(linebuf));
|
||||||
linebuf[16] = 0;
|
linebuf[16] = 0;
|
||||||
|
|
@ -618,6 +855,7 @@ void Adafruit_TestBed_Brains::lcd_write(uint8_t linenum, char linebuf[17]) {
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
|
|
||||||
_lcd_line = 1 - linenum;
|
_lcd_line = 1 - linenum;
|
||||||
|
LCD_semaphore = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _LCD_PRINTF(_line, _format) \
|
#define _LCD_PRINTF(_line, _format) \
|
||||||
|
|
@ -656,7 +894,9 @@ void Adafruit_TestBed_Brains::LCD_info(const char *msg1, const char *msg2) {
|
||||||
void Adafruit_TestBed_Brains::LCD_error(const char *errmsg1,
|
void Adafruit_TestBed_Brains::LCD_error(const char *errmsg1,
|
||||||
const char *errmsg2) {
|
const char *errmsg2) {
|
||||||
setColor(0xFF0000);
|
setColor(0xFF0000);
|
||||||
LCD_printf(0, errmsg1);
|
if (errmsg1) {
|
||||||
|
LCD_printf(0, errmsg1);
|
||||||
|
}
|
||||||
if (errmsg2) {
|
if (errmsg2) {
|
||||||
LCD_printf(1, errmsg2);
|
LCD_printf(1, errmsg2);
|
||||||
}
|
}
|
||||||
|
|
@ -673,16 +913,14 @@ void Adafruit_TestBed_Brains::usbh_setVBus(bool en) {
|
||||||
bool Adafruit_TestBed_Brains::usbh_begin(void) {
|
bool Adafruit_TestBed_Brains::usbh_begin(void) {
|
||||||
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
|
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
|
||||||
uint32_t cpu_hz = clock_get_hz(clk_sys);
|
uint32_t cpu_hz = clock_get_hz(clk_sys);
|
||||||
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
|
if (cpu_hz % 12000000UL) {
|
||||||
while (!Serial) {
|
while (!Serial) {
|
||||||
delay(10); // wait for native usb
|
delay(10); // wait for native usb
|
||||||
}
|
}
|
||||||
Serial.printf("Error: CPU Clock = %u, PIO USB require CPU clock must be "
|
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be "
|
||||||
"multiple of 120 Mhz\r\n",
|
"multiple of 12 Mhz\r\n",
|
||||||
cpu_hz);
|
|
||||||
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU "
|
|
||||||
"Speed \r\n",
|
|
||||||
cpu_hz);
|
cpu_hz);
|
||||||
|
Serial.println("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed");
|
||||||
while (1) {
|
while (1) {
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
#ifndef ADAFRUIT_TESTBED_BRAINS_H
|
#ifndef ADAFRUIT_TESTBED_BRAINS_H
|
||||||
#define ADAFRUIT_TESTBED_BRAINS_H
|
#define ADAFRUIT_TESTBED_BRAINS_H
|
||||||
|
|
||||||
#ifdef ARDUINO_RASPBERRY_PI_PICO
|
#ifdef ARDUINO_ARCH_RP2040
|
||||||
|
|
||||||
|
#include "SdFat_Adafruit_Fork.h"
|
||||||
|
|
||||||
#include "Adafruit_TestBed.h"
|
#include "Adafruit_TestBed.h"
|
||||||
#include "SdFat.h"
|
|
||||||
#include <LiquidCrystal.h>
|
#include <LiquidCrystal.h>
|
||||||
|
|
||||||
#include "Adafruit_DAP.h"
|
#include "Adafruit_DAP.h"
|
||||||
#include "Adafruit_TinyUSB.h"
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
#include "ESP32BootROM.h"
|
|
||||||
#include "MD5Builder.h"
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief A helper class for making RP2040 "Tester Brains"
|
@brief A helper class for making RP2040 "Tester Brains"
|
||||||
|
|
@ -51,24 +49,31 @@ public:
|
||||||
bool usbh_mountFS(uint8_t dev_addr);
|
bool usbh_mountFS(uint8_t dev_addr);
|
||||||
bool usbh_umountFS(uint8_t dev_addr);
|
bool usbh_umountFS(uint8_t dev_addr);
|
||||||
|
|
||||||
// Target
|
//--------------------------------------------------------------------+1
|
||||||
void targetReset(uint32_t reset_ms = 20);
|
// RP2 (rp2040 and rp2350) Target
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// RP2040 Target
|
// reset rp2 target to Boot ROM
|
||||||
//--------------------------------------------------------------------+
|
void rp2_targetResetBootRom(int bootsel_pin = 28, uint32_t reset_ms = 20);
|
||||||
// reset rp2040 target to Boot ROM
|
|
||||||
void rp2040_targetResetBootRom(int bootsel_pin = 28, uint32_t reset_ms = 20);
|
|
||||||
|
|
||||||
// program rp2040 target by copying UF2 file from SDCard
|
// program rp2 target by copying UF2 file stored in flash
|
||||||
|
size_t rp2_programUF2(const uint8_t *buffer, size_t bufsize);
|
||||||
|
|
||||||
|
// program rp2 target by copying UF2 file from SDCard
|
||||||
// return number of copied bytes (typically uf2 file size)
|
// return number of copied bytes (typically uf2 file size)
|
||||||
size_t rp2040_programUF2(const char *fpath);
|
size_t rp2_programUF2(const char *fpath);
|
||||||
|
|
||||||
|
// backward compatibility
|
||||||
|
void rp2040_targetResetBootRom(int bootsel_pin = 28, uint32_t reset_ms = 20) {
|
||||||
|
rp2_targetResetBootRom(bootsel_pin, reset_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t rp2040_programUF2(const char *fpath) { return rp2_programUF2(fpath); }
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// DAP (samd21/51, nrf5x, stm32f4 etc..) Target
|
// DAP (samd21/51, nrf5x, stm32f4 etc..) Target
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool dap_begin(Adafruit_DAP *dp);
|
bool dap_begin(Adafruit_DAP *dp);
|
||||||
bool dap_connect(void);
|
bool dap_connect(uint32_t swj_clock = 50);
|
||||||
void dap_disconnect(void);
|
void dap_disconnect(void);
|
||||||
|
|
||||||
bool dap_unprotectBoot(void);
|
bool dap_unprotectBoot(void);
|
||||||
|
|
@ -78,18 +83,12 @@ public:
|
||||||
|
|
||||||
// program dap target with file from SDCard
|
// program dap target with file from SDCard
|
||||||
// return number of programmed bytes
|
// return number of programmed bytes
|
||||||
size_t dap_programFlash(const char *fpath, uint32_t addr);
|
// Note: if do_crc32 is false, we will verify each write by reading back
|
||||||
|
size_t dap_programFlash(const char *fpath, uint32_t addr,
|
||||||
|
bool do_verify = true, bool do_crc32 = true);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
// read dap target flash to file on SDCard
|
||||||
// ESP32 Target
|
size_t dap_readFlash(const char *fpath, uint32_t addr, size_t size);
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
bool esp32_begin(ESP32BootROMClass *bootrom, uint32_t baudrate);
|
|
||||||
void esp32_end(void);
|
|
||||||
|
|
||||||
// program esp32 target with file from SDCard
|
|
||||||
// return number of programmed bytes
|
|
||||||
size_t essp32_programFlash(const char *fpath, uint32_t addr);
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Public Variables
|
// Public Variables
|
||||||
|
|
@ -109,9 +108,6 @@ public:
|
||||||
// Dap
|
// Dap
|
||||||
Adafruit_DAP *dap;
|
Adafruit_DAP *dap;
|
||||||
|
|
||||||
// ESP32 ROM
|
|
||||||
ESP32BootROMClass *esp32boot;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _inited;
|
bool _inited;
|
||||||
uint8_t _lcd_line;
|
uint8_t _lcd_line;
|
||||||
|
|
@ -121,7 +117,6 @@ private:
|
||||||
int _vbus_en_pin;
|
int _vbus_en_pin;
|
||||||
int _usbh_dp_pin;
|
int _usbh_dp_pin;
|
||||||
|
|
||||||
int _target_rst;
|
|
||||||
int _target_swdio;
|
int _target_swdio;
|
||||||
int _target_swdclk;
|
int _target_swdclk;
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -18,54 +18,103 @@
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
#ifndef ESP32_BOOTROM_H
|
||||||
|
#define ESP32_BOOTROM_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#define ESP32_DEFAULT_TIMEOUT 3000
|
#define ESP32_DEFAULT_TIMEOUT 3000
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CHIP_DETECT_MAGIC_ESP32 = 0x00F01D83,
|
||||||
|
CHIP_DETECT_MAGIC_ESP32S2 = 0x000007C6,
|
||||||
|
CHIP_DETECT_MAGIC_ESP32S3 = 0x9,
|
||||||
|
CHIP_DETECT_MAGIC_ESP8266 = 0xFFF0C101,
|
||||||
|
CHIP_DETECT_MAGIC_ESP32C6 = 0x2CE0806F,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t chip_detect;
|
||||||
|
uint32_t entry;
|
||||||
|
uint32_t text_start;
|
||||||
|
uint32_t text_length;
|
||||||
|
const uint8_t *text;
|
||||||
|
uint32_t data_start;
|
||||||
|
uint32_t data_length;
|
||||||
|
const uint8_t *data;
|
||||||
|
const char *chip_name;
|
||||||
|
} esp32_stub_loader_t;
|
||||||
|
|
||||||
class ESP32BootROMClass {
|
class ESP32BootROMClass {
|
||||||
public:
|
public:
|
||||||
// supportsEncryptedFlash must be set to
|
ESP32BootROMClass(HardwareSerial &hwSerial, int gpio0Pin = -1,
|
||||||
// - false for ESP32 (default)
|
int resetnPin = -1);
|
||||||
// - true for later chips such as S2, S3, H2, C3
|
|
||||||
ESP32BootROMClass(HardwareSerial &hwSerial, int gpio0Pin, int resetnPin,
|
|
||||||
bool supportsEncryptedFlash = false);
|
|
||||||
|
|
||||||
int begin(unsigned long baudrate);
|
// return chip detect magic if success, otherwise 0
|
||||||
|
uint32_t begin(unsigned long baudrate);
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
bool read_reg(uint32_t regAddr, uint32_t *regValue, uint32_t timeout_ms=ESP32_DEFAULT_TIMEOUT);
|
bool isRunningStub(void);
|
||||||
bool read_MAC(uint8_t mac[6]);
|
uint32_t getFlashWriteSize(void);
|
||||||
|
|
||||||
int beginFlash(uint32_t offset, uint32_t size, uint32_t chunkSize);
|
// High Level commands
|
||||||
int dataFlash(const void *data, uint32_t length);
|
bool read_reg(uint32_t regAddr, uint32_t *regValue,
|
||||||
int endFlash(uint32_t reboot);
|
uint32_t timeout_ms = ESP32_DEFAULT_TIMEOUT);
|
||||||
int md5Flash(uint32_t offset, uint32_t size, uint8_t *result);
|
bool read_MAC(uint8_t mac[6]);
|
||||||
|
uint32_t read_chip_detect(void);
|
||||||
|
|
||||||
|
// uncompressed
|
||||||
|
bool beginFlash(uint32_t offset, uint32_t size, uint32_t chunkSize);
|
||||||
|
bool dataFlash(const void *data, uint32_t length);
|
||||||
|
bool endFlash(uint32_t reboot);
|
||||||
|
|
||||||
|
// compressed
|
||||||
|
bool beginFlashDefl(uint32_t offset, uint32_t size, uint32_t zip_size);
|
||||||
|
bool dataFlashDefl(const void *data, uint32_t len);
|
||||||
|
bool endFlashDefl(uint32_t reboot);
|
||||||
|
|
||||||
|
bool md5Flash(uint32_t offset, uint32_t size, uint8_t *result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int sync();
|
void init();
|
||||||
int changeBaudrate(unsigned long baudrate);
|
void resetBootloader(void);
|
||||||
int spiAttach();
|
bool sync();
|
||||||
|
bool uploadStub(const esp32_stub_loader_t *stub);
|
||||||
|
bool syncStub(uint32_t timeout_ms);
|
||||||
|
|
||||||
void command(uint8_t opcode, const void *data, uint16_t length);
|
// Command and Response
|
||||||
int response(uint8_t opcode, uint32_t timeout_ms, void *body = NULL, uint16_t maxlen = 4);
|
void command(uint8_t opcode, const void *data, uint16_t length,
|
||||||
|
const void *data2 = NULL, uint16_t len2 = 0);
|
||||||
|
int response(uint8_t opcode, uint32_t timeout_ms, void *body = NULL);
|
||||||
|
|
||||||
void writeEscapedBytes(const uint8_t *data, uint16_t length);
|
bool sendCommandGetResponse(uint8_t opcode, const void *data, uint16_t length,
|
||||||
|
const void *data2 = NULL, uint16_t len2 = 0,
|
||||||
|
uint32_t timeout_ms = ESP32_DEFAULT_TIMEOUT,
|
||||||
|
void *body = NULL);
|
||||||
|
|
||||||
|
// High Level commands
|
||||||
|
bool changeBaudrate(uint32_t baudrate);
|
||||||
|
bool spiAttach();
|
||||||
|
|
||||||
bool beginMem(uint32_t offset, uint32_t size, uint32_t chunkSize);
|
bool beginMem(uint32_t offset, uint32_t size, uint32_t chunkSize);
|
||||||
bool dataMem(const void *data, uint32_t length);
|
bool dataMem(const void *data, uint32_t length);
|
||||||
bool endMem(uint32_t entry);
|
bool endMem(uint32_t entry);
|
||||||
|
|
||||||
// only needed for ESP32
|
// read and write packets
|
||||||
bool uploadStub(void);
|
uint16_t readBytes(void *buf, uint16_t length, uint32_t timeout_ms);
|
||||||
bool syncStub(void);
|
bool readSLIP(uint32_t timeout_ms);
|
||||||
|
void writeEscapedBytes(const uint8_t *data, uint16_t length);
|
||||||
|
|
||||||
private:
|
|
||||||
HardwareSerial *_serial;
|
HardwareSerial *_serial;
|
||||||
int _gpio0Pin;
|
int _gpio0Pin;
|
||||||
int _resetnPin;
|
int _resetnPin;
|
||||||
|
|
||||||
bool _supports_encrypted_flash;
|
bool _supports_encrypted_flash;
|
||||||
|
bool _stub_running;
|
||||||
|
bool _rom_8266_running;
|
||||||
|
uint32_t _chip_detect;
|
||||||
|
|
||||||
uint32_t _flashSequenceNumber;
|
uint32_t _flashSequenceNumber;
|
||||||
uint32_t _chunkSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
91
src/stub.py
91
src/stub.py
|
|
@ -1,91 +0,0 @@
|
||||||
import base64
|
|
||||||
import string
|
|
||||||
from samba.dcerpc.dcerpc import payload
|
|
||||||
|
|
||||||
'''
|
|
||||||
stub = {
|
|
||||||
"entry": 1074521560,
|
|
||||||
"text": "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",
|
|
||||||
"text_start": 1074520064,
|
|
||||||
"data": "GOv8P9jnC0Bx6AtA8+wLQO3oC0CP6AtA7egLQEnpC0AG6gtAeOoLQCHqC0CB5wtAo+kLQPjpC0Bn6QtAmuoLQI7pC0Ca6gtAXegLQLPoC0Dt6AtASekLQHfoC0BM6wtAs+wLQKXmC0DX7AtApeYLQKXmC0Cl5gtApeYLQKXmC0Cl5gtApeYLQKXmC0Dz6gtApeYLQM3rC0Cz7AtA",
|
|
||||||
"data_start": 1073605544
|
|
||||||
}
|
|
||||||
'''
|
|
||||||
|
|
||||||
# from esptool.py v4.4
|
|
||||||
stub = {
|
|
||||||
"entry": 1074521516,
|
|
||||||
"text": "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",
|
|
||||||
"text_start": 1074520064,
|
|
||||||
"data": "CMD8Pw==",
|
|
||||||
"data_start": 1073605544
|
|
||||||
}
|
|
||||||
|
|
||||||
def print_array(payload):
|
|
||||||
i = 0;
|
|
||||||
for x in payload:
|
|
||||||
if i == 0:
|
|
||||||
print(" ", end='')
|
|
||||||
print("0x%02x, " % x, end="")
|
|
||||||
i += 1
|
|
||||||
if i == 16:
|
|
||||||
i = 0
|
|
||||||
print("")
|
|
||||||
print()
|
|
||||||
print("};");
|
|
||||||
print()
|
|
||||||
|
|
||||||
data = base64.b64decode(stub["data"])
|
|
||||||
text = base64.b64decode(stub["text"])
|
|
||||||
|
|
||||||
print("const uint32_t stub_esp32_entry = 0x%08x;" % stub["entry"])
|
|
||||||
print()
|
|
||||||
|
|
||||||
print("const uint32_t stub_esp32_text_start = 0x%08x;" % stub["text_start"])
|
|
||||||
print("const uint32_t stub_esp32_text_length = %d;" % len(text))
|
|
||||||
print()
|
|
||||||
|
|
||||||
print("const uint32_t stub_esp32_data_start = 0x%08x;" % stub["data_start"])
|
|
||||||
print("const uint32_t stub_esp32_data_length = %d;" % len(data))
|
|
||||||
print()
|
|
||||||
|
|
||||||
print ("const uint8_t stub_esp32_data[%d] = {" % len(data))
|
|
||||||
print_array(data)
|
|
||||||
|
|
||||||
print ("const uint8_t stub_esp32_text[%d] = {" % len(text))
|
|
||||||
print_array(text)
|
|
||||||
|
|
||||||
# For comparing with esptool.py --trace data
|
|
||||||
'''
|
|
||||||
def hexify(s, uppercase=True):
|
|
||||||
format_str = "%02X" if uppercase else "%02x"
|
|
||||||
return "".join(format_str % c for c in s)
|
|
||||||
|
|
||||||
def HexFormatter(_s):
|
|
||||||
if len(_s) > 16:
|
|
||||||
result = ""
|
|
||||||
s = _s
|
|
||||||
while len(s) > 0:
|
|
||||||
line = s[:16]
|
|
||||||
ascii_line = "".join(
|
|
||||||
c
|
|
||||||
if (
|
|
||||||
c == " "
|
|
||||||
or (c in string.printable and c not in string.whitespace)
|
|
||||||
)
|
|
||||||
else "."
|
|
||||||
for c in line.decode("ascii", "replace")
|
|
||||||
)
|
|
||||||
s = s[16:]
|
|
||||||
result += "\n %-16s %-16s | %s" % (
|
|
||||||
hexify(line[:8], False),
|
|
||||||
hexify(line[8:], False),
|
|
||||||
ascii_line,
|
|
||||||
)
|
|
||||||
return result
|
|
||||||
else:
|
|
||||||
return hexify(_s, False)
|
|
||||||
|
|
||||||
text = base64.b64decode(stub["text"])
|
|
||||||
print(HexFormatter(text))
|
|
||||||
'''
|
|
||||||
2234
src/stub_esp.h
Normal file
2234
src/stub_esp.h
Normal file
File diff suppressed because it is too large
Load diff
230
src/stub_esp32.h
230
src/stub_esp32.h
|
|
@ -1,230 +0,0 @@
|
||||||
const uint32_t stub_esp32_entry = 0x400be5ac;
|
|
||||||
|
|
||||||
const uint32_t stub_esp32_text_start = 0x400be000;
|
|
||||||
const uint32_t stub_esp32_text_length = 3432;
|
|
||||||
|
|
||||||
const uint32_t stub_esp32_data_start = 0x3ffdeba8;
|
|
||||||
const uint32_t stub_esp32_data_length = 4;
|
|
||||||
|
|
||||||
const uint8_t stub_esp32_data[4] = {
|
|
||||||
0x08, 0xc0, 0xfc, 0x3f,
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t stub_esp32_text[3432] = {
|
|
||||||
0x08, 0x00, 0xf4, 0x3f, 0x1c, 0x00, 0xf4, 0x3f, 0x00, 0x00, 0xf4, 0x3f, 0xa4, 0xeb, 0xfd, 0x3f,
|
|
||||||
0x10, 0x00, 0xf4, 0x3f, 0x36, 0x41, 0x00, 0x21, 0xfa, 0xff, 0xc0, 0x20, 0x00, 0x38, 0x02, 0x41,
|
|
||||||
0xf9, 0xff, 0xc0, 0x20, 0x00, 0x28, 0x04, 0x20, 0x20, 0x74, 0x9c, 0xe2, 0x06, 0x05, 0x00, 0x00,
|
|
||||||
0x00, 0x41, 0xf5, 0xff, 0x81, 0xf6, 0xff, 0xc0, 0x20, 0x00, 0xa8, 0x04, 0x88, 0x08, 0xa0, 0xa0,
|
|
||||||
0x74, 0xe0, 0x08, 0x00, 0x0b, 0x22, 0x66, 0x02, 0xe7, 0x86, 0xf4, 0xff, 0x21, 0xf1, 0xff, 0xc0,
|
|
||||||
0x20, 0x00, 0x39, 0x02, 0x1d, 0xf0, 0x00, 0x00, 0xf8, 0x20, 0xf4, 0x3f, 0xf8, 0x30, 0xf4, 0x3f,
|
|
||||||
0x36, 0x41, 0x00, 0x91, 0xfd, 0xff, 0xc0, 0x20, 0x00, 0x88, 0x09, 0x80, 0x80, 0x24, 0x56, 0x48,
|
|
||||||
0xff, 0x91, 0xfa, 0xff, 0xc0, 0x20, 0x00, 0x88, 0x09, 0x80, 0x80, 0x24, 0x56, 0x48, 0xff, 0x1d,
|
|
||||||
0xf0, 0x00, 0x00, 0x00, 0x10, 0x20, 0xf4, 0x3f, 0x00, 0x20, 0xf4, 0x3f, 0x00, 0x00, 0x00, 0x08,
|
|
||||||
0x36, 0x41, 0x00, 0xe5, 0xfc, 0xff, 0x21, 0xfb, 0xff, 0x0c, 0x08, 0xc0, 0x20, 0x00, 0x89, 0x02,
|
|
||||||
0x91, 0xfb, 0xff, 0x81, 0xf9, 0xff, 0xc0, 0x20, 0x00, 0x92, 0x68, 0x00, 0xc0, 0x20, 0x00, 0x98,
|
|
||||||
0x08, 0x56, 0x79, 0xff, 0xc0, 0x20, 0x00, 0x88, 0x02, 0x7c, 0xf2, 0x80, 0x22, 0x30, 0x20, 0x20,
|
|
||||||
0x04, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x36, 0x41, 0x00, 0x65, 0xfc, 0xff, 0x16, 0x9a,
|
|
||||||
0xff, 0x81, 0xed, 0xff, 0x91, 0xfc, 0xff, 0xc0, 0x20, 0x00, 0x99, 0x08, 0xc0, 0x20, 0x00, 0x98,
|
|
||||||
0x08, 0x56, 0x79, 0xff, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x98, 0xc0, 0xfd, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x04, 0x20, 0xf4, 0x3f, 0x36, 0x41, 0x00, 0x21,
|
|
||||||
0xfc, 0xff, 0x38, 0x42, 0x16, 0x23, 0x06, 0xa5, 0xf8, 0xff, 0x16, 0xca, 0x05, 0x88, 0x42, 0x0c,
|
|
||||||
0xf9, 0x0c, 0x03, 0x87, 0xa9, 0x0c, 0x88, 0x22, 0x90, 0x88, 0x10, 0x0c, 0x19, 0x80, 0x39, 0x83,
|
|
||||||
0x30, 0x30, 0x74, 0x65, 0xfa, 0xff, 0xa5, 0xf3, 0xff, 0x88, 0x22, 0x91, 0xf2, 0xff, 0x40, 0x88,
|
|
||||||
0x11, 0x87, 0x39, 0x1f, 0x91, 0xed, 0xff, 0xcc, 0x13, 0x91, 0xec, 0xff, 0xa1, 0xef, 0xff, 0xc0,
|
|
||||||
0x20, 0x00, 0x89, 0x0a, 0x81, 0xd1, 0xff, 0xc0, 0x20, 0x00, 0x99, 0x08, 0xc0, 0x20, 0x00, 0x98,
|
|
||||||
0x08, 0x56, 0x79, 0xff, 0x1c, 0x09, 0x0c, 0x18, 0x30, 0x89, 0x93, 0x3d, 0x08, 0x88, 0x42, 0x30,
|
|
||||||
0x88, 0xc0, 0x89, 0x42, 0x88, 0x22, 0x3a, 0x38, 0x39, 0x22, 0x1d, 0xf0, 0x90, 0xc0, 0xfd, 0x3f,
|
|
||||||
0x08, 0x40, 0xfd, 0x3f, 0x80, 0x80, 0x00, 0x00, 0x84, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
|
||||||
0x48, 0x80, 0xfd, 0x3f, 0x94, 0xc0, 0xfd, 0x3f, 0x36, 0x41, 0x00, 0xb1, 0xf8, 0xff, 0x20, 0xa0,
|
|
||||||
0x74, 0xa5, 0xb7, 0x00, 0x96, 0xea, 0x05, 0x81, 0xf6, 0xff, 0x91, 0xf6, 0xff, 0xa0, 0xa0, 0x74,
|
|
||||||
0x90, 0x98, 0x80, 0xc0, 0x20, 0x00, 0xb2, 0x29, 0x00, 0x91, 0xf3, 0xff, 0x90, 0x88, 0x80, 0xc0,
|
|
||||||
0x20, 0x00, 0x92, 0x18, 0x00, 0x90, 0x90, 0xf4, 0x1b, 0xc9, 0xc0, 0xc0, 0xf4, 0xc0, 0x20, 0x00,
|
|
||||||
0xc2, 0x58, 0x00, 0x9a, 0x9b, 0xc0, 0x20, 0x00, 0xa2, 0x49, 0x00, 0xc0, 0x20, 0x00, 0x92, 0x18,
|
|
||||||
0x00, 0x81, 0xea, 0xff, 0x90, 0x90, 0xf4, 0x80, 0x80, 0xf4, 0x87, 0x99, 0x46, 0x81, 0xe4, 0xff,
|
|
||||||
0x91, 0xe5, 0xff, 0xa1, 0xe8, 0xff, 0x9a, 0x98, 0xc0, 0x20, 0x00, 0xc8, 0x09, 0xb1, 0xe4, 0xff,
|
|
||||||
0x87, 0x9c, 0x19, 0x46, 0x02, 0x00, 0x7c, 0xe8, 0x87, 0x1a, 0xe1, 0x46, 0x09, 0x00, 0x00, 0x00,
|
|
||||||
0xc0, 0x20, 0x00, 0x89, 0x0a, 0xc0, 0x20, 0x00, 0xb9, 0x09, 0x46, 0x02, 0x00, 0xc0, 0x20, 0x00,
|
|
||||||
0xb9, 0x0a, 0xc0, 0x20, 0x00, 0x89, 0x09, 0x91, 0xd8, 0xff, 0x9a, 0x88, 0x0c, 0x09, 0xc0, 0x20,
|
|
||||||
0x00, 0x92, 0x58, 0x00, 0x1d, 0xf0, 0x00, 0x00, 0x50, 0x2d, 0x06, 0x40, 0x36, 0x41, 0x00, 0x41,
|
|
||||||
0xb0, 0xff, 0x58, 0x34, 0x50, 0x33, 0x63, 0x16, 0xf3, 0x03, 0x58, 0x14, 0x5a, 0x53, 0x50, 0x5c,
|
|
||||||
0x41, 0x86, 0x00, 0x00, 0x65, 0xeb, 0xff, 0x88, 0x44, 0xa6, 0x18, 0x04, 0x88, 0x24, 0x87, 0xa5,
|
|
||||||
0xf2, 0xe5, 0xe3, 0xff, 0x16, 0x9a, 0xff, 0xa8, 0x14, 0xcd, 0x03, 0xbd, 0x02, 0x81, 0xf2, 0xff,
|
|
||||||
0xe0, 0x08, 0x00, 0xa0, 0xa0, 0x74, 0x8c, 0x3a, 0x22, 0xa0, 0xc4, 0x29, 0x54, 0x28, 0x14, 0x3a,
|
|
||||||
0x22, 0x29, 0x14, 0x28, 0x34, 0x30, 0x32, 0xc0, 0x39, 0x34, 0x1d, 0xf0, 0x08, 0x20, 0xf4, 0x3f,
|
|
||||||
0x00, 0x00, 0x40, 0x00, 0x70, 0xe2, 0xfa, 0x3f, 0x48, 0x24, 0x06, 0x40, 0xf0, 0x22, 0x06, 0x40,
|
|
||||||
0x36, 0x61, 0x00, 0xe5, 0xdc, 0xff, 0xad, 0x01, 0x81, 0xfc, 0xff, 0xe0, 0x08, 0x00, 0x3d, 0x0a,
|
|
||||||
0x0c, 0x12, 0xec, 0xea, 0x88, 0x01, 0x92, 0xa2, 0x00, 0x90, 0x88, 0x10, 0x89, 0x01, 0xa5, 0xe1,
|
|
||||||
0xff, 0x91, 0xf2, 0xff, 0xa1, 0xf3, 0xff, 0xc0, 0x20, 0x00, 0x88, 0x09, 0xa0, 0x88, 0x20, 0xc0,
|
|
||||||
0x20, 0x00, 0x82, 0x69, 0x00, 0xb2, 0x21, 0x00, 0xa1, 0xef, 0xff, 0x81, 0xf0, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0xa0, 0x23, 0x83, 0x1d, 0xf0, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x36, 0x41, 0x00, 0x81,
|
|
||||||
0x84, 0xff, 0x92, 0xa0, 0x01, 0x92, 0x48, 0x00, 0x30, 0x9c, 0x41, 0x92, 0x68, 0x02, 0x91, 0xfa,
|
|
||||||
0xff, 0x32, 0x68, 0x01, 0x29, 0x38, 0x30, 0x30, 0xb4, 0x9a, 0x22, 0x2a, 0x33, 0x30, 0x3c, 0x41,
|
|
||||||
0x0c, 0x02, 0x29, 0x58, 0x39, 0x48, 0xa5, 0xf8, 0xff, 0x2d, 0x0a, 0x8c, 0x1a, 0x22, 0xa0, 0xc5,
|
|
||||||
0x1d, 0xf0, 0x00, 0x00, 0x2c, 0x92, 0x00, 0x40, 0x36, 0x41, 0x00, 0x82, 0xa0, 0xc0, 0xad, 0x02,
|
|
||||||
0x87, 0x92, 0x0e, 0xa2, 0xa0, 0xdb, 0x81, 0xfb, 0xff, 0xe0, 0x08, 0x00, 0xa2, 0xa0, 0xdc, 0x86,
|
|
||||||
0x03, 0x00, 0x82, 0xa0, 0xdb, 0x87, 0x92, 0x08, 0x81, 0xf7, 0xff, 0xe0, 0x08, 0x00, 0xa2, 0xa0,
|
|
||||||
0xdd, 0x81, 0xf4, 0xff, 0xe0, 0x08, 0x00, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, 0x3a,
|
|
||||||
0x32, 0x06, 0x02, 0x00, 0x00, 0xa2, 0x02, 0x00, 0x1b, 0x22, 0xe5, 0xfb, 0xff, 0x37, 0x92, 0xf4,
|
|
||||||
0x1d, 0xf0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x7c, 0xda, 0x05, 0x40,
|
|
||||||
0xd8, 0x2e, 0x06, 0x40, 0x9c, 0xda, 0x05, 0x40, 0x1c, 0xdb, 0x05, 0x40, 0x36, 0x21, 0x21, 0xa2,
|
|
||||||
0xd1, 0x10, 0x81, 0xfa, 0xff, 0xe0, 0x08, 0x00, 0x86, 0x0a, 0x00, 0x00, 0x00, 0x51, 0xf5, 0xff,
|
|
||||||
0xbd, 0x01, 0x50, 0x43, 0x63, 0xcd, 0x04, 0xad, 0x02, 0x81, 0xf5, 0xff, 0xe0, 0x08, 0x00, 0xa0,
|
|
||||||
0xa0, 0x74, 0xfc, 0x2a, 0xcd, 0x04, 0xbd, 0x01, 0xa2, 0xd1, 0x10, 0x81, 0xf2, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0x4a, 0x22, 0x40, 0x33, 0xc0, 0x56, 0x33, 0xfd, 0xa1, 0xeb, 0xff, 0xb2, 0xd1, 0x10, 0x1a,
|
|
||||||
0xaa, 0x81, 0xed, 0xff, 0xe0, 0x08, 0x00, 0xa1, 0xe8, 0xff, 0x1c, 0x0b, 0x1a, 0xaa, 0xe5, 0xf7,
|
|
||||||
0xff, 0x2d, 0x03, 0x06, 0x01, 0x00, 0x00, 0x00, 0x22, 0xa0, 0x63, 0x1d, 0xf0, 0x00, 0x00, 0x00,
|
|
||||||
0x36, 0x41, 0x00, 0xa2, 0xa0, 0xc0, 0x81, 0xcb, 0xff, 0xe0, 0x08, 0x00, 0x1d, 0xf0, 0x00, 0x00,
|
|
||||||
0x6c, 0x10, 0x00, 0x00, 0x68, 0x10, 0x00, 0x00, 0x70, 0x10, 0x00, 0x00, 0x74, 0x10, 0x00, 0x00,
|
|
||||||
0x78, 0x10, 0x00, 0x00, 0xfc, 0x67, 0x00, 0x40, 0xd0, 0x92, 0x00, 0x40, 0x08, 0x68, 0x00, 0x40,
|
|
||||||
0x36, 0x41, 0x21, 0x61, 0xf9, 0xff, 0x81, 0xf9, 0xff, 0x1a, 0x66, 0x49, 0x06, 0x1a, 0x88, 0x62,
|
|
||||||
0xd1, 0x10, 0x0c, 0x04, 0x2c, 0x0a, 0x59, 0x08, 0x42, 0x66, 0x1a, 0x81, 0xf6, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0x51, 0xf1, 0xff, 0x81, 0xcc, 0xff, 0x1a, 0x55, 0x58, 0x05, 0x57, 0xb8, 0x02, 0x06, 0x38,
|
|
||||||
0x00, 0xad, 0x06, 0x81, 0xca, 0xff, 0xe0, 0x08, 0x00, 0x81, 0xed, 0xff, 0x71, 0xe9, 0xff, 0x1a,
|
|
||||||
0x88, 0x7a, 0x51, 0x59, 0x08, 0x46, 0x26, 0x00, 0x81, 0xe8, 0xff, 0x40, 0x73, 0xc0, 0x1a, 0x88,
|
|
||||||
0x88, 0x08, 0xbd, 0x01, 0x70, 0x78, 0x63, 0xcd, 0x07, 0xad, 0x02, 0x81, 0xc1, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0xa0, 0xa0, 0x74, 0x8c, 0xca, 0x71, 0xdf, 0xff, 0x0c, 0x05, 0x52, 0x66, 0x16, 0x7a, 0x71,
|
|
||||||
0x06, 0x0d, 0x00, 0x00, 0xa5, 0xf5, 0xff, 0x70, 0xb7, 0x20, 0xad, 0x01, 0xe5, 0xeb, 0xff, 0x25,
|
|
||||||
0xf5, 0xff, 0xcd, 0x07, 0x10, 0xb1, 0x20, 0x60, 0xa6, 0x20, 0x81, 0xb6, 0xff, 0xe0, 0x08, 0x00,
|
|
||||||
0x7a, 0x22, 0x7a, 0x44, 0x37, 0xb4, 0xce, 0x81, 0xd5, 0xff, 0x50, 0x74, 0xc0, 0x1a, 0x88, 0x88,
|
|
||||||
0x08, 0x87, 0x37, 0xa3, 0x86, 0xef, 0xff, 0x00, 0x0c, 0x0a, 0xa2, 0x46, 0x6c, 0x81, 0xd0, 0xff,
|
|
||||||
0x1a, 0x88, 0xa2, 0x28, 0x00, 0x81, 0xd0, 0xff, 0xe0, 0x08, 0x00, 0x56, 0xea, 0xfe, 0xb1, 0xa6,
|
|
||||||
0xff, 0xa2, 0x06, 0x6c, 0x1a, 0xbb, 0x65, 0x83, 0x00, 0xf7, 0xea, 0x0c, 0xf6, 0x45, 0x09, 0x5a,
|
|
||||||
0xb7, 0xa2, 0x4b, 0x00, 0x1b, 0x55, 0x86, 0xf3, 0xff, 0xb2, 0xaf, 0xfe, 0xb7, 0x9a, 0xc8, 0x66,
|
|
||||||
0x45, 0x08, 0x52, 0x26, 0x1a, 0x37, 0xb5, 0x02, 0x57, 0xb4, 0xa8, 0xa1, 0x9b, 0xff, 0x60, 0xb6,
|
|
||||||
0x20, 0x10, 0xaa, 0x80, 0x81, 0x9d, 0xff, 0xe0, 0x08, 0x00, 0x65, 0xed, 0xff, 0xa1, 0x96, 0xff,
|
|
||||||
0x1c, 0x0b, 0x1a, 0xaa, 0x65, 0xe3, 0xff, 0xa5, 0xec, 0xff, 0x2c, 0x0a, 0x81, 0xbc, 0xff, 0xe0,
|
|
||||||
0x08, 0x00, 0x1d, 0xf0, 0x00, 0xc0, 0xfc, 0x3f, 0x4f, 0x48, 0x41, 0x49, 0xa8, 0xeb, 0xfd, 0x3f,
|
|
||||||
0x88, 0xe1, 0x0b, 0x40, 0x14, 0xe0, 0x0b, 0x40, 0x0c, 0x00, 0xf4, 0x3f, 0x38, 0x40, 0xf4, 0x3f,
|
|
||||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8c, 0x80, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00,
|
|
||||||
0x00, 0x40, 0x00, 0x00, 0x00, 0xc0, 0xfc, 0x3f, 0x04, 0xc0, 0xfc, 0x3f, 0x10, 0x27, 0x00, 0x00,
|
|
||||||
0x14, 0x00, 0xf4, 0x3f, 0xf0, 0xff, 0xff, 0x00, 0xa8, 0xeb, 0xfd, 0x3f, 0x08, 0xc0, 0xfc, 0x3f,
|
|
||||||
0xb0, 0xc0, 0xfd, 0x3f, 0x7c, 0x68, 0x00, 0x40, 0xec, 0x67, 0x00, 0x40, 0x58, 0x86, 0x00, 0x40,
|
|
||||||
0x6c, 0x2a, 0x06, 0x40, 0x38, 0x32, 0x06, 0x40, 0x14, 0x2c, 0x06, 0x40, 0xcc, 0x2c, 0x06, 0x40,
|
|
||||||
0x4c, 0x2c, 0x06, 0x40, 0x34, 0x85, 0x00, 0x40, 0xcc, 0x90, 0x00, 0x40, 0x78, 0x2e, 0x06, 0x40,
|
|
||||||
0x30, 0xef, 0x05, 0x40, 0x58, 0x92, 0x00, 0x40, 0x4c, 0x82, 0x00, 0x40, 0x36, 0xc1, 0x00, 0x21,
|
|
||||||
0xde, 0xff, 0x0c, 0x0a, 0x22, 0x61, 0x08, 0x42, 0xa0, 0x00, 0x81, 0xee, 0xff, 0xe0, 0x08, 0x00,
|
|
||||||
0x21, 0xd9, 0xff, 0x31, 0xda, 0xff, 0x06, 0x01, 0x00, 0x42, 0x62, 0x00, 0x4b, 0x22, 0x37, 0x32,
|
|
||||||
0xf7, 0xe5, 0xe0, 0xff, 0x0c, 0x4b, 0xa2, 0xc1, 0x20, 0x25, 0xd7, 0xff, 0x25, 0xe0, 0xff, 0x31,
|
|
||||||
0xe4, 0xfe, 0x21, 0xe4, 0xfe, 0x41, 0xd2, 0xff, 0x2a, 0x23, 0xc0, 0x20, 0x00, 0x39, 0x02, 0xb1,
|
|
||||||
0xd1, 0xff, 0x21, 0x86, 0xfe, 0x0c, 0x0c, 0x0c, 0x5a, 0x49, 0x02, 0x81, 0xdf, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0x41, 0xcd, 0xff, 0x52, 0xa1, 0x01, 0xc0, 0x20, 0x00, 0x28, 0x04, 0x2c, 0x0a, 0x50, 0x22,
|
|
||||||
0x20, 0xc0, 0x20, 0x00, 0x29, 0x04, 0x81, 0x7d, 0xff, 0xe0, 0x08, 0x00, 0x81, 0xd8, 0xff, 0xe0,
|
|
||||||
0x08, 0x00, 0x21, 0xc6, 0xff, 0xc0, 0x20, 0x00, 0x28, 0x02, 0xcc, 0xba, 0x1c, 0xc4, 0x40, 0x22,
|
|
||||||
0x10, 0x22, 0xc2, 0xf8, 0x0c, 0x14, 0x20, 0xa4, 0x83, 0x0c, 0x0b, 0x81, 0xd1, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0xf1, 0xbf, 0xff, 0xd1, 0x48, 0xff, 0xc1, 0xbf, 0xff, 0xb1, 0xa8, 0xfe, 0xe2, 0xa1, 0x00,
|
|
||||||
0x0c, 0x0a, 0x81, 0xcc, 0xff, 0xe0, 0x08, 0x00, 0x21, 0xbc, 0xff, 0x41, 0xa5, 0xfe, 0x2a, 0x33,
|
|
||||||
0x62, 0xd4, 0x2b, 0x0c, 0x02, 0xc0, 0x20, 0x00, 0x48, 0x03, 0x16, 0x74, 0xff, 0xc0, 0x20, 0x00,
|
|
||||||
0x58, 0x03, 0x0c, 0x14, 0xc0, 0x20, 0x00, 0x29, 0x03, 0x42, 0x41, 0x10, 0x42, 0x05, 0x01, 0x0c,
|
|
||||||
0x27, 0x42, 0x41, 0x11, 0x72, 0x51, 0x09, 0x29, 0x51, 0x26, 0x94, 0x07, 0x1c, 0x37, 0x77, 0x14,
|
|
||||||
0x1e, 0x06, 0x08, 0x00, 0x42, 0x05, 0x03, 0x72, 0x05, 0x02, 0x80, 0x44, 0x11, 0x70, 0x44, 0x20,
|
|
||||||
0x66, 0x44, 0x11, 0x48, 0x25, 0xc0, 0x20, 0x00, 0x48, 0x04, 0x49, 0x51, 0x46, 0x01, 0x00, 0x00,
|
|
||||||
0x1c, 0x24, 0x42, 0x51, 0x09, 0xa5, 0xd2, 0xff, 0x0c, 0x8b, 0xa2, 0xc1, 0x10, 0xe5, 0xc8, 0xff,
|
|
||||||
0x42, 0x05, 0x03, 0x72, 0x05, 0x02, 0x80, 0x44, 0x11, 0x70, 0x44, 0x20, 0x71, 0xa0, 0xff, 0x70,
|
|
||||||
0x70, 0xf4, 0x47, 0xb7, 0x12, 0xa2, 0xa0, 0xc0, 0xe5, 0xc3, 0xff, 0xa2, 0xa0, 0xee, 0xa5, 0xc3,
|
|
||||||
0xff, 0xe5, 0xcf, 0xff, 0x46, 0xdf, 0xff, 0x00, 0x72, 0x05, 0x01, 0x0c, 0xd9, 0x97, 0x97, 0x02,
|
|
||||||
0x86, 0xaf, 0x00, 0x77, 0x39, 0x56, 0x66, 0x67, 0x02, 0x06, 0xe8, 0x00, 0xf6, 0x77, 0x20, 0x66,
|
|
||||||
0x37, 0x02, 0xc6, 0x81, 0x00, 0xf6, 0x47, 0x08, 0x66, 0x27, 0x02, 0x46, 0x67, 0x00, 0x06, 0x28,
|
|
||||||
0x00, 0x66, 0x47, 0x02, 0x46, 0x95, 0x00, 0x66, 0x57, 0x02, 0x06, 0xc4, 0x00, 0x46, 0x24, 0x00,
|
|
||||||
0x0c, 0x99, 0x97, 0x97, 0x02, 0xc6, 0xa7, 0x00, 0x77, 0x39, 0x10, 0x66, 0x77, 0x02, 0xc6, 0xc5,
|
|
||||||
0x00, 0x66, 0x87, 0x02, 0x86, 0x20, 0x00, 0xc6, 0x1d, 0x00, 0x00, 0x00, 0x66, 0x97, 0x02, 0x46,
|
|
||||||
0xb7, 0x00, 0x0c, 0xb9, 0x97, 0x97, 0x02, 0x46, 0x90, 0x00, 0x06, 0x19, 0x00, 0x1c, 0x39, 0x97,
|
|
||||||
0x97, 0x02, 0x06, 0x50, 0x00, 0x77, 0x39, 0x2a, 0x66, 0xb7, 0x02, 0xc6, 0x5d, 0x00, 0x1c, 0x09,
|
|
||||||
0x77, 0x39, 0x0c, 0x0c, 0xf9, 0xed, 0x02, 0x97, 0x97, 0x02, 0x86, 0x44, 0x00, 0xc6, 0x10, 0x00,
|
|
||||||
0x1c, 0x19, 0x97, 0x97, 0x02, 0x06, 0x65, 0x00, 0x1c, 0x24, 0x47, 0x97, 0x02, 0x06, 0x7b, 0x00,
|
|
||||||
0x86, 0x0b, 0x00, 0x92, 0xa0, 0xd2, 0x97, 0x97, 0x02, 0xc6, 0x40, 0x00, 0x77, 0x39, 0x10, 0x92,
|
|
||||||
0xa0, 0xd0, 0x97, 0x17, 0x5b, 0x92, 0xa0, 0xd1, 0x97, 0x17, 0x69, 0xc6, 0x04, 0x00, 0x00, 0x00,
|
|
||||||
0x92, 0xa0, 0xd3, 0x97, 0x97, 0x02, 0x86, 0x57, 0x01, 0x92, 0xa0, 0xd4, 0x97, 0x97, 0x02, 0x86,
|
|
||||||
0x56, 0x00, 0xed, 0x02, 0x72, 0xa0, 0xff, 0x46, 0xc0, 0x00, 0x2c, 0x49, 0xed, 0x02, 0x72, 0xa0,
|
|
||||||
0xc0, 0x97, 0x14, 0x02, 0x06, 0xbd, 0x00, 0x29, 0x51, 0x42, 0xa0, 0x07, 0x20, 0xa2, 0x20, 0xa5,
|
|
||||||
0xb4, 0xff, 0x20, 0xa2, 0x20, 0x25, 0xb4, 0xff, 0x65, 0xc0, 0xff, 0x65, 0xc0, 0xff, 0xb2, 0xa0,
|
|
||||||
0x08, 0xa2, 0xc1, 0x10, 0x0b, 0x44, 0x65, 0xb6, 0xff, 0x56, 0xf4, 0xfd, 0x46, 0x26, 0x00, 0x00,
|
|
||||||
0x00, 0x0c, 0x17, 0x56, 0x34, 0x2c, 0x81, 0x64, 0xff, 0xe0, 0x08, 0x00, 0xa0, 0x74, 0x83, 0xc6,
|
|
||||||
0xad, 0x00, 0x00, 0x00, 0x00, 0x26, 0x84, 0x04, 0x0c, 0x17, 0x06, 0xab, 0x00, 0x42, 0x25, 0x02,
|
|
||||||
0x72, 0x25, 0x03, 0x70, 0x94, 0x20, 0x90, 0x90, 0xb4, 0x56, 0xb9, 0xfe, 0x25, 0xa7, 0xff, 0x70,
|
|
||||||
0x44, 0x80, 0x9c, 0x1a, 0x06, 0xf8, 0xff, 0x00, 0xa0, 0xac, 0x41, 0x81, 0x58, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0x56, 0x3a, 0xfd, 0x72, 0xd7, 0xf0, 0x70, 0xa4, 0xc0, 0xcc, 0x27, 0x06, 0x81, 0x00, 0x00,
|
|
||||||
0xa0, 0x80, 0xf4, 0x56, 0x18, 0xfe, 0x46, 0x04, 0x00, 0xa0, 0xa0, 0xf5, 0x81, 0x51, 0xff, 0xe0,
|
|
||||||
0x08, 0x00, 0x56, 0x2a, 0xfb, 0x81, 0x3b, 0xff, 0x80, 0x77, 0xc0, 0x91, 0x3a, 0xff, 0x70, 0xa4,
|
|
||||||
0xc0, 0x77, 0x39, 0xe4, 0xc6, 0x03, 0x00, 0x00, 0xa0, 0xac, 0x41, 0x81, 0x48, 0xff, 0xe0, 0x08,
|
|
||||||
0x00, 0x56, 0x3a, 0xf9, 0x72, 0xd7, 0xf0, 0x70, 0xa4, 0xc0, 0x56, 0xa7, 0xfe, 0xc6, 0x70, 0x00,
|
|
||||||
0x72, 0xa0, 0xc0, 0x26, 0x84, 0x02, 0x86, 0x8c, 0x00, 0xed, 0x02, 0x0c, 0x07, 0xc6, 0x8a, 0x00,
|
|
||||||
0x26, 0xb4, 0xf5, 0xc6, 0x63, 0x00, 0x72, 0xa0, 0x01, 0x26, 0xb4, 0x02, 0x86, 0x86, 0x00, 0xb2,
|
|
||||||
0x25, 0x03, 0xa2, 0x25, 0x02, 0x65, 0xad, 0xff, 0x06, 0x09, 0x00, 0x00, 0x72, 0xa0, 0x01, 0x26,
|
|
||||||
0xb4, 0x02, 0x06, 0x81, 0x00, 0x91, 0x26, 0xff, 0x42, 0x25, 0x04, 0x20, 0xe2, 0x20, 0x72, 0xa0,
|
|
||||||
0xc2, 0x47, 0xb9, 0x02, 0x06, 0x7d, 0x00, 0xb8, 0x55, 0xa8, 0x25, 0x0c, 0x17, 0xe5, 0xa0, 0xff,
|
|
||||||
0xa0, 0x72, 0x83, 0xc6, 0x78, 0x00, 0x0c, 0x19, 0x66, 0xb4, 0x2c, 0x48, 0x45, 0xa1, 0x1c, 0xff,
|
|
||||||
0xed, 0x02, 0x72, 0xa0, 0xc2, 0x47, 0xba, 0x02, 0x06, 0x74, 0x00, 0x78, 0x35, 0xb8, 0x55, 0xa8,
|
|
||||||
0x25, 0x70, 0x74, 0x82, 0x99, 0xe1, 0x65, 0x9e, 0xff, 0x41, 0xfd, 0xfd, 0x98, 0xe1, 0x29, 0x64,
|
|
||||||
0x42, 0xd4, 0x2b, 0x79, 0x24, 0xa0, 0x92, 0x83, 0x7d, 0x09, 0x06, 0x6b, 0x00, 0x91, 0xf8, 0xfd,
|
|
||||||
0xed, 0x02, 0xa2, 0x09, 0x00, 0x72, 0xa0, 0xc6, 0x16, 0x0a, 0x1a, 0x78, 0x59, 0x98, 0x25, 0x42,
|
|
||||||
0xc4, 0xf0, 0x40, 0x99, 0xc0, 0xa2, 0xa0, 0xc0, 0x90, 0x7a, 0x93, 0x0c, 0x0a, 0x92, 0xa0, 0xef,
|
|
||||||
0x86, 0x02, 0x00, 0x00, 0xaa, 0xb5, 0xb2, 0x0b, 0x18, 0x1b, 0xaa, 0xb0, 0x99, 0x30, 0x47, 0x2a,
|
|
||||||
0xf2, 0xa2, 0x05, 0x05, 0x42, 0x05, 0x04, 0x80, 0xaa, 0x11, 0x40, 0xaa, 0x20, 0x42, 0x05, 0x06,
|
|
||||||
0xed, 0x02, 0x00, 0x44, 0x11, 0xa0, 0xa4, 0x20, 0x42, 0x05, 0x07, 0x80, 0x44, 0x01, 0xa0, 0x44,
|
|
||||||
0x20, 0x40, 0x99, 0xc0, 0x42, 0xa0, 0xc1, 0x90, 0x74, 0x93, 0x86, 0x53, 0x00, 0x41, 0xe0, 0xfd,
|
|
||||||
0xed, 0x02, 0x92, 0x04, 0x00, 0x72, 0xa0, 0xc6, 0x16, 0x09, 0x14, 0x98, 0x34, 0x72, 0xa0, 0xc8,
|
|
||||||
0x56, 0x89, 0x13, 0x92, 0x44, 0x00, 0x78, 0x54, 0x06, 0x4c, 0x00, 0x00, 0x1c, 0x89, 0xed, 0x02,
|
|
||||||
0x0c, 0x17, 0x97, 0x14, 0x02, 0xc6, 0x48, 0x00, 0xe8, 0x65, 0xf8, 0x75, 0xd8, 0x55, 0xc8, 0x45,
|
|
||||||
0xb8, 0x35, 0xa8, 0x25, 0x81, 0xf8, 0xfe, 0xe0, 0x08, 0x00, 0xed, 0x0a, 0xa0, 0x72, 0x83, 0x46,
|
|
||||||
0x42, 0x00, 0x0c, 0x17, 0x26, 0x44, 0x02, 0xc6, 0x3f, 0x00, 0xa8, 0x25, 0xbd, 0x02, 0x81, 0xf0,
|
|
||||||
0xfe, 0xe0, 0x08, 0x00, 0x06, 0x1f, 0x00, 0x00, 0x40, 0xa0, 0x34, 0xed, 0x02, 0x72, 0xa0, 0xc0,
|
|
||||||
0x56, 0x8a, 0x0e, 0x40, 0xb4, 0x41, 0x8b, 0x95, 0x4d, 0x0a, 0x7c, 0xfc, 0x86, 0x0e, 0x00, 0x00,
|
|
||||||
0xa8, 0x39, 0x99, 0xe1, 0xb9, 0xc1, 0xc9, 0xd1, 0x81, 0xeb, 0xfe, 0xe0, 0x08, 0x00, 0x98, 0xe1,
|
|
||||||
0xb8, 0xc1, 0x78, 0x29, 0xa8, 0x19, 0xd8, 0x09, 0xa0, 0xa7, 0x10, 0xc2, 0x21, 0x0d, 0x26, 0x07,
|
|
||||||
0x0e, 0xc0, 0x20, 0x00, 0xe2, 0x2d, 0x00, 0x70, 0x7c, 0x30, 0xe0, 0x77, 0x10, 0x70, 0xaa, 0x20,
|
|
||||||
0xc0, 0x20, 0x00, 0xa9, 0x0d, 0x1b, 0x44, 0x92, 0xc9, 0x10, 0xb7, 0x34, 0xc2, 0x06, 0x9a, 0xff,
|
|
||||||
0x66, 0x44, 0x02, 0x86, 0x98, 0xff, 0xed, 0x02, 0x72, 0xa0, 0xc0, 0x46, 0x23, 0x00, 0x0c, 0x17,
|
|
||||||
0x26, 0xb4, 0x02, 0xc6, 0x20, 0x00, 0x41, 0xc7, 0xfe, 0x98, 0x55, 0x78, 0x25, 0x99, 0x04, 0x41,
|
|
||||||
0xc6, 0xfe, 0x79, 0x04, 0x7d, 0x02, 0x06, 0x1c, 0x00, 0xb1, 0xc2, 0xfe, 0x0c, 0x17, 0xc8, 0x0b,
|
|
||||||
0x42, 0xc4, 0xf0, 0x9d, 0x02, 0x40, 0x97, 0x93, 0xc0, 0x72, 0x93, 0x70, 0x99, 0x10, 0xed, 0x02,
|
|
||||||
0x72, 0xa0, 0xc6, 0x56, 0x59, 0x05, 0x81, 0xbc, 0xfe, 0x72, 0xa0, 0xc9, 0xd8, 0x08, 0x47, 0x3d,
|
|
||||||
0x4a, 0x40, 0xa0, 0x14, 0x72, 0xa0, 0xc0, 0x56, 0x1a, 0x04, 0x7d, 0x0a, 0x0c, 0x1f, 0x46, 0x02,
|
|
||||||
0x00, 0x7a, 0x95, 0x98, 0x69, 0x4b, 0x77, 0x99, 0x0a, 0x9d, 0x0f, 0x70, 0xed, 0xc0, 0x7a, 0xac,
|
|
||||||
0x47, 0x37, 0xed, 0x16, 0x29, 0xdf, 0xa9, 0x0b, 0xe9, 0x08, 0xc6, 0x7a, 0xff, 0x0c, 0x17, 0x66,
|
|
||||||
0x84, 0x17, 0x41, 0xad, 0xfe, 0x78, 0x04, 0x8c, 0x17, 0x72, 0xa0, 0xc8, 0x29, 0x04, 0x0c, 0x1a,
|
|
||||||
0x41, 0xa9, 0xfe, 0x70, 0xa2, 0x83, 0x29, 0x04, 0x7d, 0x0a, 0xed, 0x02, 0x70, 0xa0, 0x74, 0xe2,
|
|
||||||
0x61, 0x0c, 0x65, 0x85, 0xff, 0xe2, 0x21, 0x0c, 0xe0, 0xa0, 0x74, 0xe5, 0x84, 0xff, 0x25, 0x91,
|
|
||||||
0xff, 0x56, 0x07, 0xb9, 0x42, 0x05, 0x01, 0x72, 0xa0, 0x0f, 0x77, 0x14, 0x40, 0x47, 0x37, 0x14,
|
|
||||||
0x66, 0x44, 0x02, 0x46, 0x79, 0x00, 0x66, 0x64, 0x02, 0xc6, 0x7f, 0x00, 0x26, 0x34, 0x02, 0x86,
|
|
||||||
0xdc, 0xfe, 0x86, 0x1f, 0x00, 0x1c, 0x27, 0x77, 0x94, 0x02, 0x86, 0x73, 0x00, 0x47, 0x37, 0x0b,
|
|
||||||
0x1c, 0x17, 0x77, 0x94, 0x02, 0x06, 0x3a, 0x00, 0x46, 0xd6, 0xfe, 0x00, 0x72, 0xa0, 0xd2, 0x77,
|
|
||||||
0x14, 0x4f, 0x72, 0xa0, 0xd4, 0x77, 0x14, 0x73, 0x46, 0xd2, 0xfe, 0x00, 0x00, 0x00, 0x98, 0x35,
|
|
||||||
0xa1, 0x8f, 0xfe, 0x58, 0x25, 0x99, 0xe1, 0x81, 0x9b, 0xfe, 0xe0, 0x08, 0x00, 0x41, 0x8c, 0xfe,
|
|
||||||
0x81, 0x8d, 0xfe, 0xc0, 0x20, 0x00, 0x48, 0x04, 0x98, 0xe1, 0x40, 0x74, 0x35, 0xc0, 0x44, 0x11,
|
|
||||||
0x80, 0x44, 0x10, 0x40, 0x47, 0x20, 0x90, 0x44, 0x82, 0xad, 0x02, 0x50, 0xb4, 0xc2, 0x81, 0x92,
|
|
||||||
0xfe, 0xe0, 0x08, 0x00, 0xa2, 0xa3, 0xe8, 0x81, 0x8f, 0xfe, 0xe0, 0x08, 0x00, 0x06, 0xc1, 0xfe,
|
|
||||||
0x00, 0x00, 0xd2, 0x25, 0x05, 0xc2, 0x25, 0x04, 0xb2, 0x25, 0x03, 0xa8, 0x25, 0x25, 0x8a, 0xff,
|
|
||||||
0x46, 0xbc, 0xfe, 0x00, 0xb2, 0x05, 0x03, 0x42, 0x05, 0x02, 0x80, 0xbb, 0x11, 0x40, 0xbb, 0x20,
|
|
||||||
0xb2, 0xcb, 0xf0, 0xa2, 0xc5, 0x18, 0x65, 0x6a, 0xff, 0x06, 0xb6, 0xfe, 0x42, 0x05, 0x03, 0x72,
|
|
||||||
0x05, 0x02, 0x80, 0x44, 0x11, 0x70, 0x44, 0x20, 0x71, 0x56, 0xfd, 0x42, 0xc4, 0xf0, 0x98, 0x37,
|
|
||||||
0x90, 0x44, 0x63, 0x16, 0xe4, 0xab, 0x98, 0x17, 0x9a, 0x94, 0x90, 0x9c, 0x41, 0x06, 0x02, 0x00,
|
|
||||||
0x92, 0x61, 0x0e, 0xa5, 0x54, 0xff, 0x92, 0x21, 0x0e, 0xa2, 0x27, 0x04, 0xa6, 0x1a, 0x04, 0xa8,
|
|
||||||
0x27, 0xa7, 0xa9, 0xeb, 0xa5, 0x4c, 0xff, 0x16, 0x9a, 0xff, 0xa2, 0x27, 0x01, 0x40, 0xc4, 0x20,
|
|
||||||
0xb2, 0xc5, 0x18, 0x81, 0x72, 0xfe, 0xe0, 0x08, 0x00, 0x16, 0x4a, 0x00, 0x82, 0xa0, 0xc4, 0x89,
|
|
||||||
0x57, 0x88, 0x17, 0x4a, 0x88, 0x89, 0x17, 0x88, 0x37, 0x40, 0x48, 0xc0, 0x49, 0x37, 0xc6, 0x9c,
|
|
||||||
0xfe, 0x82, 0x05, 0x03, 0x72, 0x05, 0x02, 0x80, 0x88, 0x11, 0x70, 0x88, 0x20, 0x42, 0xc5, 0x18,
|
|
||||||
0x82, 0xc8, 0xf0, 0x0c, 0x15, 0x06, 0x20, 0x00, 0x00, 0x91, 0x57, 0xfe, 0x71, 0x59, 0xfd, 0x58,
|
|
||||||
0x09, 0x89, 0x71, 0x50, 0x77, 0xc0, 0x79, 0x61, 0x78, 0x26, 0x0c, 0x1a, 0x77, 0xb8, 0x01, 0x0c,
|
|
||||||
0x3a, 0x89, 0xd1, 0x99, 0xe1, 0xa9, 0xc1, 0x65, 0x4d, 0xff, 0xa8, 0xc1, 0x71, 0x50, 0xfe, 0xa9,
|
|
||||||
0x01, 0xa1, 0x4f, 0xfe, 0xed, 0x05, 0xbd, 0x04, 0xf2, 0xc1, 0x18, 0xdd, 0x07, 0xc2, 0xc1, 0x1c,
|
|
||||||
0x81, 0x58, 0xfe, 0xe0, 0x08, 0x00, 0x5d, 0x0a, 0xb8, 0x26, 0xa8, 0x71, 0x88, 0xd1, 0x98, 0xe1,
|
|
||||||
0xa0, 0xbb, 0xc0, 0xb9, 0x26, 0xa0, 0x88, 0xc0, 0xb8, 0x09, 0xaa, 0x44, 0xa8, 0x61, 0x0c, 0x1e,
|
|
||||||
0xaa, 0xbb, 0xad, 0x02, 0x50, 0xae, 0x83, 0xb9, 0x09, 0xa0, 0xa0, 0x74, 0x70, 0xbb, 0xc0, 0xcc,
|
|
||||||
0x7a, 0xd2, 0xdb, 0x80, 0xd0, 0xae, 0x83, 0x16, 0xea, 0x00, 0xad, 0x07, 0x89, 0xd1, 0x99, 0xe1,
|
|
||||||
0xa5, 0x5a, 0xff, 0x98, 0xe1, 0x88, 0xd1, 0x79, 0x09, 0x91, 0x19, 0xfd, 0x78, 0x39, 0x8c, 0xa8,
|
|
||||||
0x50, 0x9f, 0x31, 0x50, 0x99, 0xc0, 0xd6, 0x29, 0x00, 0x56, 0xc7, 0xf6, 0xd6, 0xa5, 0x00, 0x51,
|
|
||||||
0x14, 0xfd, 0x42, 0xa0, 0xc7, 0x49, 0x55, 0x46, 0x00, 0x00, 0x8c, 0x35, 0x9c, 0x07, 0xc6, 0x6c,
|
|
||||||
0xfe, 0x16, 0x07, 0x9b, 0x81, 0x0f, 0xfd, 0x42, 0xa0, 0xc8, 0x49, 0x58, 0x46, 0x69, 0xfe, 0x00,
|
|
||||||
0x91, 0x0c, 0xfd, 0x42, 0xa0, 0xc9, 0x49, 0x59, 0x46, 0x66, 0xfe, 0x00, 0x48, 0x25, 0x56, 0x34,
|
|
||||||
0x99, 0xad, 0x02, 0x81, 0x34, 0xfe, 0xe0, 0x08, 0x00, 0xa1, 0x20, 0xfe, 0x81, 0x2e, 0xfe, 0xe0,
|
|
||||||
0x08, 0x00, 0x81, 0x31, 0xfe, 0xe0, 0x08, 0x00, 0x46, 0x5e, 0xfe, 0x00, 0x48, 0x35, 0x16, 0x34,
|
|
||||||
0x97, 0xad, 0x02, 0x81, 0x2c, 0xfe, 0xe0, 0x08, 0x00, 0xa2, 0xa3, 0xe8, 0x81, 0x26, 0xfe, 0xe0,
|
|
||||||
0x08, 0x00, 0xe0, 0x04, 0x00, 0x06, 0x57, 0xfe, 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x41, 0x00, 0x9d,
|
|
||||||
0x02, 0x82, 0xa0, 0xc0, 0x28, 0x03, 0x87, 0x99, 0x0f, 0xcc, 0x32, 0x0c, 0x12, 0x86, 0x07, 0x00,
|
|
||||||
0x0c, 0x02, 0x29, 0x03, 0x7c, 0xe2, 0x86, 0x0e, 0x00, 0x26, 0x12, 0x07, 0x26, 0x22, 0x16, 0x86,
|
|
||||||
0x03, 0x00, 0x00, 0x00, 0x82, 0xa0, 0xdb, 0x80, 0x29, 0x23, 0x87, 0x99, 0x26, 0x0c, 0x22, 0x29,
|
|
||||||
0x03, 0x7c, 0xf2, 0x46, 0x07, 0x00, 0x22, 0xa0, 0xdc, 0x27, 0x99, 0x08, 0x0c, 0x12, 0x29, 0x03,
|
|
||||||
0x2d, 0x08, 0x86, 0x03, 0x00, 0x82, 0xa0, 0xdd, 0x7c, 0xf2, 0x87, 0x99, 0x06, 0x0c, 0x12, 0x29,
|
|
||||||
0x03, 0x22, 0xa0, 0xdb, 0x1d, 0xf0, 0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
81
tools/esp_compress.py
Normal file
81
tools/esp_compress.py
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
import zlib
|
||||||
|
import hashlib
|
||||||
|
from pathlib import Path
|
||||||
|
import click
|
||||||
|
|
||||||
|
def print_carray(f, payload):
|
||||||
|
while len(payload) > 0:
|
||||||
|
f.write('\n ')
|
||||||
|
f.write(', '.join('0x{:02x}'.format(x) for x in payload[0:16]))
|
||||||
|
f.write(',')
|
||||||
|
payload = payload[16:]
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.argument('dpath', type=click.Path(exists=True), default='.')
|
||||||
|
@click.option('--sd', is_flag=True, default=False, help='Generate header for using with SDCard')
|
||||||
|
def main(dpath, sd):
|
||||||
|
"""
|
||||||
|
This script takes a directory path (default is current directory) and
|
||||||
|
create compressed .bin.gz file along 'esp_binaries.h' containing metadata in esp32_zipfile_t struct.
|
||||||
|
Which can be used to program ESP32 with TestBed or Brain.
|
||||||
|
If '--sd' option is specified, it will skip generating C array data for gz file.
|
||||||
|
"""
|
||||||
|
output_header = 'esp_binaries.h'
|
||||||
|
with open(output_header, 'w') as fc:
|
||||||
|
# print typedef struct
|
||||||
|
fc.write('// Generated by tools/esp_compress.py\n')
|
||||||
|
file_list = sorted(Path(dpath).glob('*.bin'))
|
||||||
|
fc.write(f'#define ESP_BINARIES_COUNT ({len(file_list)})\n\n')
|
||||||
|
|
||||||
|
# print list of struct first
|
||||||
|
for fname in file_list:
|
||||||
|
var = fname.stem
|
||||||
|
var = var.replace('.', '_')
|
||||||
|
var = var.replace('-', '_')
|
||||||
|
fc.write(f'// const esp32_zipfile_t {var}\n')
|
||||||
|
fc.write('\n')
|
||||||
|
|
||||||
|
for fname in file_list:
|
||||||
|
with open(fname, 'rb') as fi:
|
||||||
|
image = fi.read()
|
||||||
|
zimage = zlib.compress(image, 9)
|
||||||
|
fzname = fname.with_suffix('.bin.gz')
|
||||||
|
md5 = hashlib.md5(image)
|
||||||
|
|
||||||
|
# write .gz file
|
||||||
|
with open(fzname, 'wb') as fz:
|
||||||
|
fz.write(zimage)
|
||||||
|
|
||||||
|
# write to c header file
|
||||||
|
var = fname.stem
|
||||||
|
var = var.replace('.', '_')
|
||||||
|
var = var.replace('-', '_')
|
||||||
|
|
||||||
|
# bin gz contents
|
||||||
|
if not sd:
|
||||||
|
fc.write(f'const uint8_t _{var}_gz[{len(zimage)}] = {{')
|
||||||
|
print_carray(fc, zimage)
|
||||||
|
fc.write('};\n\n')
|
||||||
|
|
||||||
|
fc.write(f'const esp32_zipfile_t {var} = {{\n')
|
||||||
|
fc.write(f' .name = "{fzname}",\n')
|
||||||
|
if sd:
|
||||||
|
fc.write(f' .data = NULL,\n')
|
||||||
|
else:
|
||||||
|
fc.write(f' .data = _{var}_gz,\n')
|
||||||
|
fc.write(f' .compressed_len = {len(zimage)},\n')
|
||||||
|
fc.write(f' .uncompressed_len = {len(image)},\n')
|
||||||
|
fc.write(' .md5 = {')
|
||||||
|
print_carray(fc, md5.digest())
|
||||||
|
fc.write(' },\n')
|
||||||
|
fc.write('};\n')
|
||||||
|
fc.write('\n')
|
||||||
|
|
||||||
|
deflation = 100*(1-len(zimage)/len(image))
|
||||||
|
print(f"Compressed {var}: {len(image)} to {len(zimage)} bytes, deflation: {deflation:.2f}%")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
104
tools/esp_stub.py
Normal file
104
tools/esp_stub.py
Normal file
File diff suppressed because one or more lines are too long
45
tools/file2carray.py
Normal file
45
tools/file2carray.py
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import random
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
from multiprocessing import Pool
|
||||||
|
from weakref import finalize
|
||||||
|
|
||||||
|
|
||||||
|
def print_carray(f, payload):
|
||||||
|
while len(payload) > 0:
|
||||||
|
f.write('\n ')
|
||||||
|
f.write(', '.join('0x{:02x}'.format(x) for x in payload[0:16]))
|
||||||
|
f.write(',')
|
||||||
|
payload = payload[16:]
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Convert binary files to C array format')
|
||||||
|
parser.add_argument('files', nargs='+', help='Binary files to convert')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
files = args.files
|
||||||
|
for fin_name in files:
|
||||||
|
if not os.path.isfile(fin_name):
|
||||||
|
print(f"File {fin_name} does not exist")
|
||||||
|
continue
|
||||||
|
|
||||||
|
with open(fin_name, 'rb') as fin:
|
||||||
|
contents = fin.read()
|
||||||
|
fout_name = fin_name + '.h'
|
||||||
|
with open(fout_name, 'w') as fout:
|
||||||
|
print(f"Converting {fin_name} to {fout_name}")
|
||||||
|
fout.write(f'const size_t bindata_len = {len(contents)};\n')
|
||||||
|
fout.write(f'const uint8_t bindata[] __attribute__((aligned(16))) = {{')
|
||||||
|
print_carray(fout, contents)
|
||||||
|
fout.write('};\n')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
Loading…
Reference in a new issue