Compare commits

..

134 commits

Author SHA1 Message Date
Tyeth Gundry
c6f2a0cc4c
Update library.properties - bump version to 1.14.2 2025-08-05 13:32:43 +01:00
Ha Thach
b138cd1ba1
Merge pull request #29 from adafruit/brain-240mhz
Support running brain with rp2350 also support both F_CPU 120Mhz or 240Mhz
2025-07-30 21:38:04 +07:00
hathach
5b4034b0f9
add rp2350 to brain ci build 2025-07-30 21:17:17 +07:00
hathach
0332ed1117
support running rp2350 as testbed brain. Correct nop cycle for both rp2040 and rp2350 (higher IPC). Support both running with 120Mhz and 240Mhz 2025-07-30 21:09:27 +07:00
ladyada
6bfd594148 let run on RP2350 2025-07-29 13:44:15 -04:00
hathach
ab3624e73b
error if F_CPU is not 240Mhz due to pio-usb hanndshake timing issue when working with rp2350 bootrom.
support neopixel with 240Mhz
2025-07-29 21:10:15 +07:00
Tyeth Gundry
2b71fa7422
Update library.properties - 1.14.1 2025-06-26 15:03:33 +01:00
ladyada
6d16513e79 add feather m0's built in neopix 2025-06-22 13:40:48 -04:00
Tyeth Gundry
8045dd5c78
Update library.properties - bump to 1.14.0 2025-03-11 21:21:50 +00:00
Ha Thach
0b408468ce
Merge pull request #28 from adafruit/support-program-rp2350
support programming rp2350
2025-03-07 11:15:37 +07:00
hathach
759bdeb282
support programming rp2350, add a new example to program metro rp2350 from firmware.h
rename program_rp2040_uf2.ino to program_rp2_from_sdcard.ino
change include SdFat.h to SdFat_Adafruit_Fork.h
2025-03-05 16:47:56 +07:00
Tyeth Gundry
1130b8c29d
Update library.properties - bump version to 1.13.2 2024-11-27 15:35:24 +00:00
Limor "Ladyada" Fried
45816d8d0a
Merge pull request #27 from mikeysklar/master
qtpy esp32s3 with psram name fix
2024-11-22 19:15:07 -05:00
Mikey Sklar
d75faf6081 qtpy esp32s3 with psram name fix
Incorrect board name being used for Qt Py ESP32-S3 with 2MB PSRAM.

was:
ARDUINO_ADAFRUIT_QTPY_ESP32S3

correct boards.txt name:
ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2
2024-11-22 15:18:57 -08:00
Tyeth Gundry
d48670064b
Update library.properties - bump version to 1.13.1 2024-07-23 15:57:58 +01:00
Tyeth Gundry
4125a29235
Merge pull request #26 from adafruit/2024-07-23-formatting
ESP32BootRom.cpp: format ifdefs
2024-07-23 15:57:27 +01:00
Tyeth Gundry
7657c315e3 ESP32BootRom.cpp: format ifdefs 2024-07-23 15:43:57 +01:00
Tyeth Gundry
64fc7e33c9
Update library.properties - bump version to 1.13.0 2024-07-23 15:06:02 +01:00
ladyada
cd2ecc5b76 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2024-07-17 17:40:52 -04:00
ladyada
bbc2afadf4 add swj_clock argument, error setting for analog tests, and some ifdefs for ESP32 programming modes 2024-07-17 17:40:04 -04:00
Tyeth Gundry
e0d3b19e47
Update library.properties - bump version to 1.12.2 2024-07-09 11:21:22 +01:00
Ha Thach
4fb2c089bc
Merge pull request #25 from adafruit/support-c6 2024-07-05 16:26:54 +07:00
hathach
1805552376
add test for c6 programmin via cdc but not working yet due to usb host. 2024-07-05 15:21:21 +07:00
hathach
948b602102
add support for c6 programming stub + chip detect. Tested with uart programming 2024-07-05 14:32:14 +07:00
ladyada
00ea80fce2 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2024-04-10 11:06:46 -04:00
ladyada
f3f79e1384 reading is slow so give some feedback so they know its working! 2024-04-10 11:06:39 -04:00
Tyeth Gundry
0de33c2804 Clean up old formatting (pre-commit) 2024-04-09 17:47:43 +00:00
ladyada
228169cbe5 add blink 2024-04-06 10:27:00 -04:00
ladyada
d37a36ff29 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2024-01-09 15:07:21 -05:00
Tyeth Gundry
d02093a1b1
Update library.properties - bump version to 1.12.0 2024-01-09 15:43:57 +00:00
Ha Thach
f13cdaa159
Merge pull request #24 from adafruit/add-8266-binary
Add 8266 binary
2024-01-09 15:51:13 +07:00
hathach
87f1fa0d9d rename example program_esp32_cdc/uart to simply program_esp_cdc/uart
since esp8266 is also supported
2024-01-09 13:00:23 +07:00
hathach
28fda00cce add 8266 blinky to program_esp32_cdc 2024-01-09 12:57:30 +07:00
ladyada
991d04d7a6 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2024-01-08 14:16:23 -05:00
Ha Thach
38c0a286f5
Merge pull request #23 from adafruit/add-verify-arg-dap_programFlash
Add verify arg dap_programFlash(), add new dap_readFlash()
2024-01-03 20:23:09 +07:00
ladyada
293c7f8be2 more correct msg 2023-12-28 14:17:48 -05:00
hathach
dc494b2be1 add do_verify and do_crc32 2023-12-29 02:02:43 +07:00
hathach
4b29b6a223 add Brain::dap_readFlash(), add read_nrf52840_to_sdcard example 2023-12-28 22:04:57 +07:00
hathach
26be867d87 add optional do_verify to Brain.dap_programFlash(), default to true
duplicate program nrf52840 to program rnf52840_from_sdcard
2023-12-28 21:27:13 +07:00
ladyada
0bd60196b2 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2023-10-20 23:39:13 -04:00
ladyada
e47a9febec dont halt on bad ID read 2023-10-20 23:39:07 -04:00
Tyeth Gundry
c5216f28cd
Update library.properties - bump version to 1.11.0 2023-10-17 14:52:14 +01:00
Ha Thach
8ffa1d6ff9
Merge pull request #22 from adafruit/refactor-program-esp32
Refactor programming esp32 out of Brain
2023-10-13 09:59:26 +07:00
hathach
fcf8557dd0 replace all printf() to make it compatible with arduino avr and samd core 2023-10-13 00:05:38 +07:00
hathach
0daa066f41 fix ci build with avr core 2023-10-12 23:40:30 +07:00
hathach
9a1477f407 add esp32_programFlashDefl() with File32 from SD card
- upgrade tool/esp_compress.py with --sd option to generate metadata for
use with files on sdcard
- add new program_esp32_uart_from_sdcard that tested on metro m4 (and
pyportal)
2023-10-12 23:24:29 +07:00
hathach
c25bc452fd refactor: move esp32 program function from Brain to TestBed
also move targetResetPin to TestBed
2023-10-11 11:02:19 +07:00
hathach
31c20caf2c
add ESP32_NATIVE_USB setting to make it clear which usb we are dealing with 2023-07-23 13:29:04 +07:00
hathach
d379e56c4f
default program_cdc to S3 2023-07-23 13:23:02 +07:00
Eva Herrada
6e53893034
Bumped to 1.10.0 2023-07-18 15:39:52 -04:00
Ha Thach
4b31541dc4
Merge pull request #21 from adafruit/add-usbh-hub-test
Add usbh hub test
2023-07-10 22:03:05 +07:00
hathach
3930a02dac
use ARM_MATH_CM0PLUS as adafruit samd indicator 2023-07-10 17:19:37 +07:00
hathach
db9ba914b4
fix ci: arduino samd does not have printf, enable esp32bootrom for adafruit samd21 only 2023-07-10 16:56:03 +07:00
hathach
f6aee1c29a
fix clang 2023-07-10 16:18:15 +07:00
hathach
b4249f1614
add usbh hub test example 2023-07-10 16:10:54 +07:00
lady ada
c90c7cd375 qwiic is on second port 2023-06-28 13:11:42 -04:00
lady ada
b65bd1fd88 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2023-06-11 13:00:31 -04:00
lady ada
6f3b5e73f6 small tweaks 2023-06-11 13:00:02 -04:00
Eva Herrada
782efbfe5a
Bump to 1.9.0 2023-05-30 12:32:46 -04:00
Ha Thach
c3e647b801
Merge pull request #20 from adafruit/add-featherV2-ch9102f
add support for programming esp via serial host with usb-to-uart chip like ch9102f
2023-05-05 16:52:31 +07:00
hathach
2e5afb8b32 update esp32 to be compatible with M4 and/or board without tinyusb 2023-05-05 16:40:15 +07:00
hathach
ce1d1ec7b0 rebase and fix clang 2023-05-05 16:27:13 +07:00
hathach
5ad6ac8fb6 update doc wiring 2023-05-05 16:26:49 +07:00
hathach
b77e95352f add support for programming esp via serial host with usb-to-uart chip e.g ch9102f
- update program_esp32_cdc.ino to support ch9102f
- add flashing binaries for feather esp32 v2 blinky
2023-05-05 16:26:49 +07:00
lady ada
31792680b3 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2023-04-21 13:11:39 -04:00
lady ada
0cf64c14cf retry fewer times 2023-04-21 13:10:49 -04:00
Ha Thach
92764d6ef1
Merge pull request #19 from adafruit/add-esp8266
Add esp8266
2023-04-19 17:15:41 +07:00
hathach
fbe4f207c8 clang, pre-commit skip ino files 2023-04-19 17:03:26 +07:00
hathach
689440a95f change default binaries back to metro s2 2023-04-19 16:49:54 +07:00
hathach
0f8bf4c029 wrap up support for esp8266, testing with speed aroudn 120KB/s 2023-04-19 16:49:23 +07:00
hathach
3417e50633 fix timing delay for esp8266 which is slow to be ready for each new command
also retry 3 times for each command before failed
2023-04-19 16:18:22 +07:00
hathach
bfbcf9b7c6 update all commands to use new sendCommandGetResponse() also slight change signature from int to bool 2023-04-19 13:23:22 +07:00
hathach
03823d562f irmpve esp bootrom to support esp8266
- 8266 rom has status len = 2 (as opposed to esp32 with 4), which is
used to detect 8266 in early (before chip detect)
- small delay each sync attempt to better sync
- small delay before sending command for 8266 rom since it takes longer
to ready receiving (possibly due to flexible baud 74800bps and 115200bps
- able to upload stub, and flashing with baud rate = 115200 with 8266
- add sendCommandGetResponse() to centrally manage failed and retry with
commands
2023-04-19 12:48:15 +07:00
hathach
17575513c3 add esp8266 stub 2023-04-18 11:36:09 +07:00
hathach
0b6ce61c5b clean up 2023-04-18 09:05:16 +07:00
Ha Thach
91f6f7cc72
Merge pull request #18 from adafruit/fix-neopixel-color
fine tune and fix neopixel incorrect color
2023-04-14 10:56:50 +07:00
hathach
984926b7d8 clang 2023-04-14 10:46:41 +07:00
hathach
f7ea00b74b fine tune and fix neopixel incorrect color 2023-04-14 10:42:56 +07:00
Eva Herrada
d19c9f6e4d
Bump to 1.8.2 2023-04-03 15:45:27 -04:00
lady ada
6e013b1c11 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2023-03-22 11:22:36 -04:00
lady ada
829d921b35 fix tone() on esp32s2, allow esp32 programming via M4 host 2023-03-22 11:22:30 -04:00
Limor "Ladyada" Fried
30d2ead4cb
Merge pull request #17 from adafruit/fix-s3-reset
Fix s3 reset
2023-03-22 11:19:39 -04:00
hathach
98ca14c68f
use safer walkaround, idleOtherCore() can accidentally idle core0 when executed in core1 2023-03-22 16:38:52 +07:00
hathach
e631a58b30
add pre-commit with clang, trailing spaces, and codespell 2023-03-22 16:21:00 +07:00
hathach
d4a945f967
add walkround for reset S3 2023-03-22 16:20:10 +07:00
hathach
41eae0f21a esp23 bootrom begin() return chip_detect id 2023-03-22 16:04:46 +07:00
Eva Herrada
b5a2854854
Bump to 1.8.1 2023-03-14 15:44:51 -04:00
lady ada
387a95c819 add some debug and semaphore for LCD 2023-03-07 14:28:51 -05:00
lady ada
8c7ba727e5 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2023-03-06 18:56:06 -05:00
Eva Herrada
e02f558ca8
Bump to 1.8.0 2023-03-02 16:18:09 -05:00
lady ada
76e28d0e6d Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2023-02-24 18:02:50 -05:00
Ha Thach
fd4ecd9b87
Merge pull request #16 from adafruit/add-metro-bin
added metro binaries for program cdc
2023-02-24 21:17:50 +07:00
hathach
dfca31499c
clang 2023-02-24 21:05:56 +07:00
hathach
2df3903e52
update binaries for cdc 2023-02-24 21:01:24 +07:00
hathach
68a73923f5
update esp binaries 2023-02-24 20:59:22 +07:00
hathach
94910676de
added metro binaries for program cdc 2023-02-24 18:33:01 +07:00
lady ada
4fa35fbbc7 Merge branch 'master' of github.com:adafruit/Adafruit_TestBed 2023-02-23 22:44:28 -05:00
lady ada
cfd5014475 add debug timing 2023-02-23 22:44:22 -05:00
Ha Thach
62ffc063d3
Merge pull request #15 from adafruit/brain-esp32-s2-s3
Brain esp32 s2 s3
2023-02-23 16:34:31 +07:00
hathach
108db070d7
fix warnings 2023-02-23 12:41:58 +07:00
hathach
05c4ca3e10
more clang 2023-02-23 12:14:52 +07:00
hathach
30e01cd273
clang 2023-02-23 12:13:02 +07:00
hathach
6d727217b7
wrap up 2023-02-23 12:11:22 +07:00
hathach
fd3acf6fe3
stub + compresssion work well with s2 and s3 with decent 56KB/s 2023-02-23 12:04:00 +07:00
hathach
125166afde
fix read escape issue 2023-02-23 10:24:51 +07:00
hathach
5bcbd821b2
use stub for esp32s2, work well
speed is increase from 25 to 38 kB
2023-02-23 09:16:24 +07:00
Ha Thach
6fb3ea8bc7
Merge pull request #14 from adafruit/brain-esp-compression
Brain esp compression
2023-02-22 10:45:55 +07:00
hathach
b7bd917be0
run clang before test 2023-02-22 10:26:06 +07:00
hathach
b183a5b31b
improve serial write(), write in chunk up to escape code instead of 1 by 1 2023-02-22 10:25:06 +07:00
hathach
2e8e572dca
check md5 before flashing 2023-02-21 21:59:32 +07:00
hathach
039fb89810
clang 2023-02-21 21:28:46 +07:00
hathach
33d8bb52d3
rename esp32_stub_loader_t 2023-02-21 21:18:22 +07:00
hathach
1bb697f951
clang 2023-02-21 21:12:11 +07:00
hathach
eabef3a42a
esp32_programFlashDefl() work well with on-board flash 2023-02-21 20:13:35 +07:00
hathach
6e930676c1
implemented flash deflate 2023-02-21 19:43:03 +07:00
hathach
58c6faceb7
adding esp_compress.py, add intial zip program, rename sd based example to program_esp32_uart_uncompressed 2023-02-21 17:30:53 +07:00
hathach
008240300b
improve readSLIP() 2023-02-21 11:38:19 +07:00
hathach
0a3dabfc2f
improve stub hanlding 2023-02-21 10:40:11 +07:00
hathach
6d649f4812
clean up 2023-02-21 10:28:27 +07:00
Ha Thach
cfd77f443e
Merge pull request #13 from adafruit/brain-esp32-stub-loader
Brain esp32 stub loader
2023-02-20 22:45:32 +07:00
hathach
4325321100
fix clang 2023-02-20 22:36:22 +07:00
hathach
566cb691bb
fix typo 2023-02-20 22:22:55 +07:00
hathach
a9e5d3ed88
Merge branch 'master' into brain-esp32-stub-loader 2023-02-20 21:59:02 +07:00
hathach
81b139c124
clang 2023-02-20 21:44:39 +07:00
hathach
4a1cf8ecde
fix ci 2023-02-20 21:31:05 +07:00
hathach
3de56de16b
more enhance 2023-02-20 21:29:03 +07:00
hathach
fcf3f29586
detect SUPPORTS_ENCRYPTED_FLASH by chip detect. fix s2/s3 upload
though s2/s3 upload isn't stable enough.
2023-02-20 20:06:42 +07:00
hathach
442a5d3744
everything works well with stub 2023-02-20 18:18:41 +07:00
hathach
70197ab53b
improve dataMem() 2023-02-20 18:09:12 +07:00
hathach
564de5050d
enhance command() for dataFlash() 2023-02-20 18:05:54 +07:00
hathach
e4623a8095
update syncStub() 2023-02-20 16:38:37 +07:00
hathach
9855be25fe
flashing with stub working 2023-02-20 16:27:57 +07:00
lady ada
09fd788cbb clang 2023-02-18 15:02:06 -05:00
lady ada
69a55bde9e dont compile for AVRs, fix essp to esp 2023-02-18 11:18:09 -05:00
82 changed files with 358021 additions and 1221 deletions

View file

@ -17,7 +17,12 @@ jobs:
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: actions/checkout@v3
- name: Run pre-commit
uses: pre-commit/action@v3.0.0
- uses: actions/checkout@v3
with:
repository: adafruit/ci-arduino
@ -26,12 +31,12 @@ jobs:
- name: pre-install
run: bash ci/actions_install.sh
- name: test platforms
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
- name: clang
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
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.idea
.pio

25
.pre-commit-config.yaml Normal file
View 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]

View file

@ -1,7 +1,7 @@
// Testing basic peripherals on Brain
// required for Host MSC block device
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// required for USB host
#include "pio_usb.h"

View file

@ -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");
}
}

View file

@ -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");
}
}

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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);
}
}

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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");
}
}

View file

@ -6,7 +6,7 @@
// - Brain's USB host to Target USB
// required for Host MSC block device
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// required for USB host
#include "pio_usb.h"
@ -17,11 +17,7 @@
#include "Adafruit_TestBed_Brains.h"
// RP2040 Boot VID/PID
#define BOOT_VID 0x2e8a
#define BOOT_PID 0x0003
// file path on SDCard to prograom
// file path on SDCard to program
#define TEST_FILE_PATH "nrf/feather_nrf52840/bleblink.bin"
// DAP interface for nRF5x
@ -66,8 +62,10 @@ void setup() {
// 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);
size_t copied_bytes = Brain.dap_programFlash(TEST_FILE_PATH, 0, true, false);
ms = millis() - ms;
print_speed(copied_bytes, ms);
@ -110,9 +108,7 @@ void tuh_mount_cb (uint8_t dev_addr)
uint16_t vid, pid;
tuh_vid_pid_get(dev_addr, &vid, &pid);
if ( !(vid == BOOT_VID && pid == BOOT_PID) ) {
Brain.LCD_printf(1, "UnkDev %04x:%04x", vid, pid);
}
Brain.LCD_printf("USBID %04x:%04x", vid, pid);
}
/// Invoked when device is unmounted (bus reset/unplugged)

View file

@ -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");
}
}

Binary file not shown.

File diff suppressed because it is too large Load diff

View 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);
}
}

View file

@ -6,7 +6,7 @@
// - Brain's USB host to RP2040 USB interface
// required for Host MSC block device
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// required for USB host
#include "pio_usb.h"
@ -60,11 +60,6 @@ void print_speed(size_t count, uint32_t ms) {
}
void setup() {
// For debugging tinyusb
if (CFG_TUSB_DEBUG) {
Serial1.begin(115200);
}
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("Tester Brains: UF2 copy from SD to USBH FS test!");
@ -75,7 +70,7 @@ void setup() {
// prepare SD Card
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
while (!is_usbfs_mounted) delay(10);
@ -84,7 +79,7 @@ void setup() {
Serial.println("Copying from SD to USBHFS: " UF2_FILE_PATH);
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);
@ -93,6 +88,7 @@ void setup() {
}
void loop() {
Serial.flush();
}
//--------------------------------------------------------------------+
@ -108,7 +104,7 @@ void setup1() {
Brain.LCD_printf(1, "No USB Device");
// 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

View file

@ -6,7 +6,7 @@
// - Brain's USB host to Target USB
// required for Host MSC block device
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// required for USB host
#include "pio_usb.h"

View file

@ -6,7 +6,7 @@
// - Brain's USB host to Target USB
// required for Host MSC block device
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// required for USB host
#include "pio_usb.h"

View file

@ -6,7 +6,7 @@
// - Brain's USB host to Target USB
// required for Host MSC block device
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// required for USB host
#include "pio_usb.h"

View file

@ -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");
}
}

View 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) {
}
}

View file

@ -2,7 +2,7 @@
// to LCD. Also determine if device support MSC or HID
// required for Host MSC block device
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// required for USB host
#include "pio_usb.h"
@ -13,6 +13,11 @@
// CDC Host object
Adafruit_USBH_CDC SerialHost;
enum {
COLOR_NO_DEV = 0x00000ff,
COLOR_MOUNTED = 0x00ff00,
};
//--------------------------------------------------------------------+
// Setup and Loop on Core0
//--------------------------------------------------------------------+
@ -57,9 +62,10 @@ void setup1() {
// Init Brain USB Host
Brain.usbh_begin();
Brain.setColor(COLOR_NO_DEV);
// 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");
@ -89,8 +95,8 @@ void tuh_mount_cb (uint8_t daddr)
tuh_vid_pid_get(daddr, &vid, &pid);
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(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)
{
Serial.printf("Device removed, address = %d\r\n", daddr);
Brain.setColor(COLOR_NO_DEV);
Brain.LCD_printf(0, "No USB attached");
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);
}
}

View file

@ -7,9 +7,10 @@ extern Adafruit_TestBed TB;
#if defined(ARDUINO_ARCH_RP2040) \
|| defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) \
|| 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_SAM_DUE)
|| defined(ARDUINO_SAM_DUE) \
|| defined(ARDUINO_ARCH_RENESAS_UNO)
#define SECONDARY_I2C_PORT &Wire1
#endif
@ -25,7 +26,7 @@ void setup() {
#if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3) || \
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_N4R2) || \
defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
// ESP32 is kinda odd in that secondary ports must be manually
// assigned their pins with setPins()!

View 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,
},
};

View file

@ -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() {
}

View file

@ -1,5 +1,5 @@
name=Adafruit TestBed
version=1.7.0
version=1.14.2
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=Adafruit's internal test bed code library

View file

@ -1,10 +1,25 @@
#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) {
#if defined(ADAFRUIT_METRO_M0_EXPRESS)
neopixelPin = 40;
neopixelNum = 1;
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
neopixelPin = 8;
neopixelNum = 1;
#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);
}
if (targetResetPin >= 0) {
pinMode(targetResetPin, OUTPUT);
digitalWrite(targetResetPin, HIGH);
}
#if defined(__AVR__)
analogRef = 5.0;
#elif defined(ARDUINO_ARCH_RP2040)
@ -150,6 +170,23 @@ void Adafruit_TestBed::targetPowerCycle(uint16_t off_time) {
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
@ -160,7 +197,7 @@ void Adafruit_TestBed::targetPowerCycle(uint16_t off_time) {
/**************************************************************************/
float Adafruit_TestBed::readAnalogVoltage(uint16_t pin, float multiplier) {
float a = analogRead(pin);
theSerial->println(a);
// theSerial->println(a);
#if defined(ARDUINO_ARCH_ESP32) && !defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3)
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 multiplier If there's a resistor divider, put the inverse here
@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
*/
/**************************************************************************/
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);
theSerial->print(name);
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(value);
theSerial->print(" V)...");
if (abs(voltage - value) > (value / 10.0)) {
if (abs(voltage - value) > (value * error / 100.0)) {
theSerial->println("Failed");
return false;
}
theSerial->println(F("OK within 10%"));
theSerial->print(F("OK within "));
theSerial->print(error);
theSerial->println("%");
return true;
}
@ -380,7 +421,8 @@ void Adafruit_TestBed::beep(uint32_t freq, uint32_t duration) {
if (piezoPin < 0)
return;
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);
#else
// suppress compiler warns
@ -413,4 +455,203 @@ void Adafruit_TestBed::beepNblink(void) {
#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;

View file

@ -5,6 +5,9 @@
#include "Arduino.h"
#include "Wire.h"
#include "ESP32BootROM.h"
#include "SdFat_Adafruit_Fork.h"
#define RED 0xFF0000
#define YELLOW 0xFFFF00
#define GREEN 0x00FF00
@ -13,6 +16,14 @@
#define PURPLE 0xFF00FF
#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
@ -33,9 +44,11 @@ public:
void targetPower(bool on);
void targetPowerCycle(uint16_t off_time = 10);
void targetReset(uint32_t reset_ms = 20);
float readAnalogVoltage(uint16_t pin, float multiplier = 1);
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);
@ -46,10 +59,29 @@ public:
void beep(uint32_t freq, uint32_t duration);
void beepNblink(void);
void blink(void);
uint32_t timestamp(void);
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
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
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
uint8_t neopixelNum = 0; ///< How many neopixels are on board, if any
Adafruit_NeoPixel *pixels =
@ -70,6 +104,15 @@ public:
private:
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

View file

@ -22,9 +22,9 @@
* THE SOFTWARE.
*/
#ifdef ARDUINO_RASPBERRY_PI_PICO
#ifdef ARDUINO_ARCH_RP2040
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
#include "pio_usb.h"
#include "Adafruit_DAP.h"
@ -34,8 +34,16 @@
#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;
volatile bool LCD_semaphore = false;
// Simple and low code CRC calculation (copied from PicoOTA)
class BrainCRC32 {
public:
@ -88,12 +96,11 @@ Adafruit_TestBed_Brains::Adafruit_TestBed_Brains() {
_usbh_dp_pin = 20; // USB Host D+
_vbus_en_pin = 22; // USB Host VBus enable
_target_rst = 27;
targetResetPin = 27;
_target_swdio = 2;
_target_swdclk = 3;
dap = NULL;
esp32boot = NULL;
}
void Adafruit_TestBed_Brains::begin(void) {
@ -105,8 +112,8 @@ void Adafruit_TestBed_Brains::begin(void) {
neopixelNum = 1;
pinMode(neopixelPin, OUTPUT);
pinMode(_target_rst, OUTPUT);
digitalWrite(_target_rst, HIGH);
pinMode(targetResetPin, OUTPUT);
digitalWrite(targetResetPin, HIGH);
pinMode(_sd_detect_pin, INPUT_PULLUP);
pinMode(_vbus_en_pin, OUTPUT);
@ -128,20 +135,13 @@ void Adafruit_TestBed_Brains::begin(void) {
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
//--------------------------------------------------------------------+
void Adafruit_TestBed_Brains::rp2040_targetResetBootRom(int bootsel_pin,
uint32_t reset_ms) {
void Adafruit_TestBed_Brains::rp2_targetResetBootRom(int bootsel_pin,
uint32_t reset_ms) {
pinMode(bootsel_pin, OUTPUT);
digitalWrite(bootsel_pin, LOW);
targetReset(reset_ms);
@ -152,7 +152,41 @@ void Adafruit_TestBed_Brains::rp2040_targetResetBootRom(int bootsel_pin,
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);
if (!fsrc) {
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;
const char *dst_name = "FIRMWARE.UF2";
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;
return dap->begin(_target_swdclk, _target_swdio, _target_rst,
return dap->begin(_target_swdclk, _target_swdio, targetResetPin,
dap_err_hanlder);
}
bool Adafruit_TestBed_Brains::dap_connect(void) {
bool Adafruit_TestBed_Brains::dap_connect(uint32_t swj_clock) {
if (!dap) {
return false;
}
LCD_printf("Connecting...");
if (!dap->targetConnect()) {
if (!dap->targetConnect(swj_clock)) {
return false;
}
@ -239,10 +272,6 @@ bool Adafruit_TestBed_Brains::dap_connect(void) {
LCD_printf(0, "Unknown MCU");
LCD_printf(1, "ID = %08X", dsu_did);
while (1) {
delay(1);
}
return false;
}
@ -251,9 +280,9 @@ bool Adafruit_TestBed_Brains::dap_connect(void) {
? (dap->target_device.flash_size / dap->target_device.n_pages)
: 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);
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,
page_size);
@ -272,9 +301,9 @@ bool Adafruit_TestBed_Brains::dap_unprotectBoot(void) {
return false;
}
LCD_printf("Unlock chip...");
Serial.println("Unlock chip...");
bool ret = dap->unprotectBoot();
LCD_printf(ret ? "OK" : "Failed");
Serial.println(ret ? "OK" : "Failed");
return ret;
}
@ -283,9 +312,9 @@ bool Adafruit_TestBed_Brains::dap_protectBoot(void) {
return false;
}
LCD_printf("Lock chip...");
Serial.println("Lock chip...");
bool ret = dap->protectBoot();
LCD_printf(ret ? "OK" : "Failed");
Serial.println(ret ? "OK" : "Failed");
return ret;
}
@ -306,14 +335,15 @@ bool Adafruit_TestBed_Brains::dap_eraseChip(void) {
dap->erase();
ms = millis() - ms;
LCD_printf("done in %.02fs", ms / 1000.0F);
LCD_printf("Erased in %.02fs", ms / 1000.0F);
}
return true;
}
size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
uint32_t addr) {
uint32_t addr, bool do_verify,
bool do_crc32) {
if (!dap) {
return 0;
}
@ -356,7 +386,8 @@ size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
return 0;
}
LCD_printf("Programming..");
LCD_printf("Programming...");
uint32_t ms = millis();
BrainCRC32 crc32;
dap->program_start(addr, fsize);
@ -364,22 +395,42 @@ size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
uint32_t addr_tmp = addr;
while (fsrc.available()) {
memset(buf, 0xff, bufsize); // empty it out
uint32_t rd_count = fsrc.read(buf, bufsize);
setLED(HIGH);
dap->programBlock(addr_tmp, buf, bufsize);
crc32.add(buf, rd_count);
setLED(LOW);
// don't verify each write if we use crc32
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;
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()) {
LCD_printf("CRC Failed");
Serial.printf("CRC mismtached: %08X != %08X\n", crc32.get(), target_crc);
if (do_crc32) {
ms = millis();
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 {
LCD_printf("Done!");
}
@ -390,112 +441,47 @@ size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath,
return fsize;
}
//--------------------------------------------------------------------+
// ESP32 Target
//--------------------------------------------------------------------+
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) {
size_t Adafruit_TestBed_Brains::dap_readFlash(const char *fpath, uint32_t addr,
size_t size) {
if (!dap) {
return 0;
}
enum { MAX_PAYLOAD_SIZE = 1024 };
uint8_t *buf = (uint8_t *)malloc(MAX_PAYLOAD_SIZE);
size_t bufsize = 4096;
uint8_t *buf = (uint8_t *)malloc(bufsize);
if (!buf) {
LCD_printf_error("No memory %u\n", MAX_PAYLOAD_SIZE);
return 0;
}
File32 fsrc = SD.open(fpath);
File32 fsrc = SD.open(fpath, O_CREAT | O_WRONLY);
if (!fsrc) {
Serial.printf("SD: cannot open file: %s\r\n", fpath);
return 0;
}
uint32_t fsize = fsrc.fileSize();
uint32_t total_count = 0;
if (!esp32boot->beginFlash(addr, fsize, MAX_PAYLOAD_SIZE)) {
LCD_printf_error("beginFlash failed!");
} else {
LCD_printf("#Packets %u", fsize / MAX_PAYLOAD_SIZE);
LCD_printf("Reading...");
MD5Builder md5;
md5.begin();
size_t remain = size;
while (remain) {
uint32_t count = min(remain, bufsize);
//------------- Flashing -------------//
while (fsrc.available()) {
memset(buf, 0xff, MAX_PAYLOAD_SIZE); // empty it out
uint32_t rd_count = fsrc.read(buf, MAX_PAYLOAD_SIZE);
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;
setLED(HIGH);
if (!dap->dap_read_block(addr, buf, (int)count)) {
Serial.printf("Failed to read block at %08lX\n", addr);
break;
}
Serial.println();
setLED(LOW);
//------------- MD5 verification -------------//
md5.calculate();
Serial.printf("md5 = %s\r\n", md5.toString().c_str());
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();
}
fsrc.write(buf, count);
LCD_printf("%d remaining", remain);
addr += count;
remain -= count;
}
free(buf);
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
//--------------------------------------------------------------------+
#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
// 1 us -> 120 nop
// full frame, 1.25 us -> 150 nop
// - T1H 0,76 us -> 91 nop
// - T0H 0,36 us -> 43 nop
#define _NOP_COUNT(n) NOP##n
#define NOP_COUNT(n) _NOP_COUNT(n)
void __no_inline_not_in_flash_func(Adafruit_TestBed_Brains::setColor)(
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 *ptr, *end, p, bitMask;
@ -548,65 +743,107 @@ void Adafruit_TestBed_Brains::setColor(uint32_t color) {
p = *ptr++;
bitMask = 0x80;
// 800 KHz
for (;;) {
// wait for previous frame to finish
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) {
// T1H 0,76 us -> 91 nop
// T1H 0.8 us = 96 nop (without overhead)
sio_hw->gpio_set = pinMask;
asm("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; 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_COUNT(T1H_CYCLE);
#if F_CPU == 240000000L
NOP_COUNT(T1H_CYCLE);
#endif
// 150 - 91 = 59 nop
// T1L 0.45 = 54 - 10 (ifelse) - 5 (overhead) = 44 nop
sio_hw->gpio_clr = pinMask;
asm("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_COUNT(T1L_CYCLE);
#if F_CPU == 240000000L
NOP_COUNT(T1L_CYCLE);
#endif
} else {
// T0H 0,36 us -> 43 nop
// T0H 0.4 us = 48 cycles
sio_hw->gpio_set = pinMask;
asm("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_COUNT(T0H_CYCLE);
#if F_CPU == 240000000L
NOP_COUNT(T0H_CYCLE);
#endif
// 150 - 43 = 107 nop
// T0L 0.85 us = 102 - 10 (ifelse) - 5 (overhead) = 87 nop
sio_hw->gpio_clr = pinMask;
asm("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; 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_COUNT(T0L_CYCLE);
#if F_CPU == 240000000L
NOP_COUNT(T0L_CYCLE);
#endif
}
// if a full byte is sent, next to another byte
if (0 == (bitMask >>= 1)) {
if (ptr >= end)
if (bitMask >>= 1) {
// not full byte, shift to next bit
NOP_COUNT(LOOP_OVERHEAD_CYCLE);
} else {
// probably take 10 nops
// if a full byte is sent, next to another byte
if (ptr >= end) {
break;
}
p = *ptr++;
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]) {
// wait for semaphore to release
while (LCD_semaphore)
yield();
LCD_semaphore = true;
// fill the rest with spaces
memset(linebuf + strlen(linebuf), ' ', 16 - strlen(linebuf));
linebuf[16] = 0;
@ -618,6 +855,7 @@ void Adafruit_TestBed_Brains::lcd_write(uint8_t linenum, char linebuf[17]) {
Serial.flush();
_lcd_line = 1 - linenum;
LCD_semaphore = false;
}
#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,
const char *errmsg2) {
setColor(0xFF0000);
LCD_printf(0, errmsg1);
if (errmsg1) {
LCD_printf(0, errmsg1);
}
if (errmsg2) {
LCD_printf(1, errmsg2);
}
@ -673,16 +913,14 @@ void Adafruit_TestBed_Brains::usbh_setVBus(bool en) {
bool Adafruit_TestBed_Brains::usbh_begin(void) {
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %u, PIO USB require CPU clock must be "
"multiple of 120 Mhz\r\n",
cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU "
"Speed \r\n",
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be "
"multiple of 12 Mhz\r\n",
cpu_hz);
Serial.println("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed");
while (1) {
delay(1);
}

View file

@ -1,18 +1,16 @@
#ifndef 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 "SdFat.h"
#include <LiquidCrystal.h>
#include "Adafruit_DAP.h"
#include "Adafruit_TinyUSB.h"
#include "ESP32BootROM.h"
#include "MD5Builder.h"
/**************************************************************************/
/*!
@brief A helper class for making RP2040 "Tester Brains"
@ -51,24 +49,31 @@ public:
bool usbh_mountFS(uint8_t dev_addr);
bool usbh_umountFS(uint8_t dev_addr);
// Target
void targetReset(uint32_t reset_ms = 20);
//--------------------------------------------------------------------+1
// RP2 (rp2040 and rp2350) Target
//--------------------------------------------------------------------+
// RP2040 Target
//--------------------------------------------------------------------+
// reset rp2040 target to Boot ROM
void rp2040_targetResetBootRom(int bootsel_pin = 28, uint32_t reset_ms = 20);
// reset rp2 target to Boot ROM
void rp2_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)
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
//--------------------------------------------------------------------+
bool dap_begin(Adafruit_DAP *dp);
bool dap_connect(void);
bool dap_connect(uint32_t swj_clock = 50);
void dap_disconnect(void);
bool dap_unprotectBoot(void);
@ -78,18 +83,12 @@ public:
// program dap target with file from SDCard
// 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);
//--------------------------------------------------------------------+
// ESP32 Target
//--------------------------------------------------------------------+
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);
// read dap target flash to file on SDCard
size_t dap_readFlash(const char *fpath, uint32_t addr, size_t size);
//--------------------------------------------------------------------+
// Public Variables
@ -109,9 +108,6 @@ public:
// Dap
Adafruit_DAP *dap;
// ESP32 ROM
ESP32BootROMClass *esp32boot;
private:
bool _inited;
uint8_t _lcd_line;
@ -121,7 +117,6 @@ private:
int _vbus_en_pin;
int _usbh_dp_pin;
int _target_rst;
int _target_swdio;
int _target_swdclk;

File diff suppressed because it is too large Load diff

View file

@ -18,54 +18,103 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ESP32_BOOTROM_H
#define ESP32_BOOTROM_H
#include <Arduino.h>
#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 {
public:
// supportsEncryptedFlash must be set to
// - false for ESP32 (default)
// - true for later chips such as S2, S3, H2, C3
ESP32BootROMClass(HardwareSerial &hwSerial, int gpio0Pin, int resetnPin,
bool supportsEncryptedFlash = false);
ESP32BootROMClass(HardwareSerial &hwSerial, int gpio0Pin = -1,
int resetnPin = -1);
int begin(unsigned long baudrate);
// return chip detect magic if success, otherwise 0
uint32_t begin(unsigned long baudrate);
void end();
bool read_reg(uint32_t regAddr, uint32_t *regValue, uint32_t timeout_ms=ESP32_DEFAULT_TIMEOUT);
bool read_MAC(uint8_t mac[6]);
bool isRunningStub(void);
uint32_t getFlashWriteSize(void);
int beginFlash(uint32_t offset, uint32_t size, uint32_t chunkSize);
int dataFlash(const void *data, uint32_t length);
int endFlash(uint32_t reboot);
int md5Flash(uint32_t offset, uint32_t size, uint8_t *result);
// High Level commands
bool read_reg(uint32_t regAddr, uint32_t *regValue,
uint32_t timeout_ms = ESP32_DEFAULT_TIMEOUT);
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:
int sync();
int changeBaudrate(unsigned long baudrate);
int spiAttach();
void init();
void resetBootloader(void);
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);
int response(uint8_t opcode, uint32_t timeout_ms, void *body = NULL, uint16_t maxlen = 4);
// Command and Response
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 dataMem(const void *data, uint32_t length);
bool endMem(uint32_t entry);
// only needed for ESP32
bool uploadStub(void);
bool syncStub(void);
// read and write packets
uint16_t readBytes(void *buf, uint16_t length, uint32_t timeout_ms);
bool readSLIP(uint32_t timeout_ms);
void writeEscapedBytes(const uint8_t *data, uint16_t length);
private:
HardwareSerial *_serial;
int _gpio0Pin;
int _resetnPin;
bool _supports_encrypted_flash;
bool _stub_running;
bool _rom_8266_running;
uint32_t _chip_detect;
uint32_t _flashSequenceNumber;
uint32_t _chunkSize;
};
#endif

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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
View 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

File diff suppressed because one or more lines are too long

45
tools/file2carray.py Normal file
View 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())