Clean up and remove unused files

pull/311/head
Melissa LeBlanc-Williams 3 months ago
parent a97608a07d
commit f96b54bddd

@ -1,26 +0,0 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- run: npm ci
- run: script/build
- run: npm exec -- prettier --check src

@ -37,12 +37,6 @@ jobs:
run: npm install -g yarn
- name: yarn install
run: yarn install
- name: Compile TypeScript
run: |
set -e
rm -rf dist
NODE_ENV=production npm exec -- tsc
NODE_ENV=production npm exec -- rollup -c
- name: Commit Distribution Files
uses: stefanzweifel/git-auto-commit-action@v5
if: startswith(github.repository, 'adafruit/')

@ -1 +0,0 @@
src/stubs

@ -1,22 +0,0 @@
# Adafruit WebSerial ESPTool
JavaScript package to install firmware on ESP devices via the browser using WebSerial.
## Used by
- [Adafruit WipperSnapper](https://learn.adafruit.com/quickstart-adafruit-io-wippersnapper)
- [Adafruit CircuitPython Installer](https://circuitpython.org/downloads)
## Local development
- Clone this repository.
- Install dependencies with `npm`
- Run `script/develop`
- Open http://localhost:5004/
## Origin
This project was originally written by [Melissa LeBlanc-Williams](https://github.com/makermelissa). [Nabu Casa](https://www.nabucasa.com) ported the code over to TypeScript and in March 2022 took over maintenance from Adafruit. In July 2022, the Nabucasa stopped maintaining the project in favor of an official, but very early release of Espressif's [esptool-js](https://github.com/espressif/esptool-js/). Due to the instability of the tool, Adafruit updated their fork with Nabucasa's changes in November 2022 and took over maintenance once again.
A live copy of the tool is hosted here: https://adafruit.github.io/Adafruit_WebSerial_ESPTool/

193
dist/const.d.ts vendored

@ -1,193 +0,0 @@
export interface Logger {
log(msg: string, ...args: any[]): void;
error(msg: string, ...args: any[]): void;
debug(msg: string, ...args: any[]): void;
}
export declare const baudRates: number[];
export declare const FLASH_SIZES: {
"512KB": number;
"256KB": number;
"1MB": number;
"2MB": number;
"4MB": number;
"2MB-c1": number;
"4MB-c1": number;
"8MB": number;
"16MB": number;
};
export declare const ESP32_FLASH_SIZES: {
"1MB": number;
"2MB": number;
"4MB": number;
"8MB": number;
"16MB": number;
"32MB": number;
"64MB": number;
"128MB": number;
};
interface FlashSize {
[key: number]: string;
}
export declare const DETECTED_FLASH_SIZES: FlashSize;
export declare const FLASH_WRITE_SIZE = 1024;
export declare const STUB_FLASH_WRITE_SIZE = 16384;
export declare const FLASH_SECTOR_SIZE = 4096;
export declare const ESP_ROM_BAUD = 115200;
export declare const USB_JTAG_SERIAL_PID = 4097;
export declare const ESP8266_SPI_REG_BASE = 1610613248;
export declare const ESP8266_BASEFUSEADDR = 1072693328;
export declare const ESP8266_MACFUSEADDR = 1072693328;
export declare const ESP8266_SPI_USR_OFFS = 28;
export declare const ESP8266_SPI_USR1_OFFS = 32;
export declare const ESP8266_SPI_USR2_OFFS = 36;
export declare const ESP8266_SPI_MOSI_DLEN_OFFS = -1;
export declare const ESP8266_SPI_MISO_DLEN_OFFS = -1;
export declare const ESP8266_SPI_W0_OFFS = 64;
export declare const ESP8266_UART_DATE_REG_ADDR = 1610612856;
export declare const ESP8266_BOOTLOADER_FLASH_OFFSET = 0;
export declare const ESP32_SPI_REG_BASE = 1072963584;
export declare const ESP32_BASEFUSEADDR = 1073061888;
export declare const ESP32_MACFUSEADDR = 1073061888;
export declare const ESP32_SPI_USR_OFFS = 28;
export declare const ESP32_SPI_USR1_OFFS = 32;
export declare const ESP32_SPI_USR2_OFFS = 36;
export declare const ESP32_SPI_MOSI_DLEN_OFFS = 40;
export declare const ESP32_SPI_MISO_DLEN_OFFS = 44;
export declare const ESP32_SPI_W0_OFFS = 128;
export declare const ESP32_UART_DATE_REG_ADDR = 1610612856;
export declare const ESP32_BOOTLOADER_FLASH_OFFSET = 4096;
export declare const ESP32S2_SPI_REG_BASE = 1061167104;
export declare const ESP32S2_BASEFUSEADDR = 1061265408;
export declare const ESP32S2_MACFUSEADDR = 1061265476;
export declare const ESP32S2_SPI_USR_OFFS = 24;
export declare const ESP32S2_SPI_USR1_OFFS = 28;
export declare const ESP32S2_SPI_USR2_OFFS = 32;
export declare const ESP32S2_SPI_MOSI_DLEN_OFFS = 36;
export declare const ESP32S2_SPI_MISO_DLEN_OFFS = 40;
export declare const ESP32S2_SPI_W0_OFFS = 88;
export declare const ESP32S2_UART_DATE_REG_ADDR = 1610612856;
export declare const ESP32S2_BOOTLOADER_FLASH_OFFSET = 4096;
export declare const ESP32S3_SPI_REG_BASE = 1610620928;
export declare const ESP32S3_BASEFUSEADDR = 1610641408;
export declare const ESP32S3_MACFUSEADDR: number;
export declare const ESP32S3_SPI_USR_OFFS = 24;
export declare const ESP32S3_SPI_USR1_OFFS = 28;
export declare const ESP32S3_SPI_USR2_OFFS = 32;
export declare const ESP32S3_SPI_MOSI_DLEN_OFFS = 36;
export declare const ESP32S3_SPI_MISO_DLEN_OFFS = 40;
export declare const ESP32S3_SPI_W0_OFFS = 88;
export declare const ESP32S3_UART_DATE_REG_ADDR = 1610612864;
export declare const ESP32S3_BOOTLOADER_FLASH_OFFSET = 0;
export declare const ESP32C2_SPI_REG_BASE = 1610620928;
export declare const ESP32C2_BASEFUSEADDR = 1610647552;
export declare const ESP32C2_MACFUSEADDR: number;
export declare const ESP32C2_SPI_USR_OFFS = 24;
export declare const ESP32C2_SPI_USR1_OFFS = 28;
export declare const ESP32C2_SPI_USR2_OFFS = 32;
export declare const ESP32C2_SPI_MOSI_DLEN_OFFS = 36;
export declare const ESP32C2_SPI_MISO_DLEN_OFFS = 40;
export declare const ESP32C2_SPI_W0_OFFS = 88;
export declare const ESP32C2_UART_DATE_REG_ADDR = 1610612860;
export declare const ESP32C2_BOOTLOADER_FLASH_OFFSET = 0;
export declare const ESP32C3_SPI_REG_BASE = 1610620928;
export declare const ESP32C3_BASEFUSEADDR = 1610647552;
export declare const ESP32C3_MACFUSEADDR: number;
export declare const ESP32C3_SPI_USR_OFFS = 24;
export declare const ESP32C3_SPI_USR1_OFFS = 28;
export declare const ESP32C3_SPI_USR2_OFFS = 32;
export declare const ESP32C3_SPI_MOSI_DLEN_OFFS = 36;
export declare const ESP32C3_SPI_MISO_DLEN_OFFS = 40;
export declare const ESP32C3_SPI_W0_OFFS = 88;
export declare const ESP32C3_UART_DATE_REG_ADDR = 1610612860;
export declare const ESP32C3_BOOTLOADER_FLASH_OFFSET = 0;
export declare const ESP32C6_SPI_REG_BASE = 1610625024;
export declare const ESP32C6_BASEFUSEADDR = 1611335680;
export declare const ESP32C6_MACFUSEADDR: number;
export declare const ESP32C6_SPI_USR_OFFS = 24;
export declare const ESP32C6_SPI_USR1_OFFS = 28;
export declare const ESP32C6_SPI_USR2_OFFS = 32;
export declare const ESP32C6_SPI_MOSI_DLEN_OFFS = 36;
export declare const ESP32C6_SPI_MISO_DLEN_OFFS = 40;
export declare const ESP32C6_SPI_W0_OFFS = 88;
export declare const ESP32C6_UART_DATE_REG_ADDR = 1610612860;
export declare const ESP32C6_BOOTLOADER_FLASH_OFFSET = 0;
export declare const ESP32H2_SPI_REG_BASE = 1610620928;
export declare const ESP32H2_BASEFUSEADDR = 1610719232;
export declare const ESP32H2_MACFUSEADDR: number;
export declare const ESP32H2_SPI_USR_OFFS = 24;
export declare const ESP32H2_SPI_USR1_OFFS = 28;
export declare const ESP32H2_SPI_USR2_OFFS = 32;
export declare const ESP32H2_SPI_MOSI_DLEN_OFFS = 36;
export declare const ESP32H2_SPI_MISO_DLEN_OFFS = 40;
export declare const ESP32H2_SPI_W0_OFFS = 88;
export declare const ESP32H2_UART_DATE_REG_ADDR = 1610612860;
export declare const ESP32H2_BOOTLOADER_FLASH_OFFSET = 0;
export interface SpiFlashAddresses {
regBase: number;
baseFuse: number;
macFuse: number;
usrOffs: number;
usr1Offs: number;
usr2Offs: number;
mosiDlenOffs: number;
misoDlenOffs: number;
w0Offs: number;
uartDateReg: number;
flashOffs: number;
}
export declare const SYNC_PACKET: number[];
export declare const CHIP_DETECT_MAGIC_REG_ADDR = 1073745920;
export declare const CHIP_FAMILY_ESP8266 = 33382;
export declare const CHIP_FAMILY_ESP32 = 50;
export declare const CHIP_FAMILY_ESP32S2 = 12882;
export declare const CHIP_FAMILY_ESP32S3 = 12883;
export declare const CHIP_FAMILY_ESP32C2 = 12994;
export declare const CHIP_FAMILY_ESP32C3 = 12995;
export declare const CHIP_FAMILY_ESP32C6 = 12998;
export declare const CHIP_FAMILY_ESP32H2 = 12914;
export type ChipFamily = typeof CHIP_FAMILY_ESP8266 | typeof CHIP_FAMILY_ESP32 | typeof CHIP_FAMILY_ESP32S2 | typeof CHIP_FAMILY_ESP32S3 | typeof CHIP_FAMILY_ESP32C2 | typeof CHIP_FAMILY_ESP32C3 | typeof CHIP_FAMILY_ESP32C6 | typeof CHIP_FAMILY_ESP32H2;
interface ChipInfo {
[magicValue: number]: {
name: string;
family: ChipFamily;
};
}
export declare const CHIP_DETECT_MAGIC_VALUES: ChipInfo;
export declare const ESP_FLASH_BEGIN = 2;
export declare const ESP_FLASH_DATA = 3;
export declare const ESP_FLASH_END = 4;
export declare const ESP_MEM_BEGIN = 5;
export declare const ESP_MEM_END = 6;
export declare const ESP_MEM_DATA = 7;
export declare const ESP_SYNC = 8;
export declare const ESP_WRITE_REG = 9;
export declare const ESP_READ_REG = 10;
export declare const ESP_ERASE_FLASH = 208;
export declare const ESP_ERASE_REGION = 209;
export declare const ESP_SPI_SET_PARAMS = 11;
export declare const ESP_SPI_ATTACH = 13;
export declare const ESP_CHANGE_BAUDRATE = 15;
export declare const ESP_SPI_FLASH_MD5 = 19;
export declare const ESP_CHECKSUM_MAGIC = 239;
export declare const ESP_FLASH_DEFL_BEGIN = 16;
export declare const ESP_FLASH_DEFL_DATA = 17;
export declare const ESP_FLASH_DEFL_END = 18;
export declare const ROM_INVALID_RECV_MSG = 5;
export declare const USB_RAM_BLOCK = 2048;
export declare const ESP_RAM_BLOCK = 6144;
export declare const DEFAULT_TIMEOUT = 3000;
export declare const CHIP_ERASE_TIMEOUT = 600000;
export declare const MAX_TIMEOUT: number;
export declare const SYNC_TIMEOUT = 100;
export declare const ERASE_REGION_TIMEOUT_PER_MB = 30000;
export declare const MEM_END_ROM_TIMEOUT = 500;
/**
* @name timeoutPerMb
* Scales timeouts which are size-specific
*/
export declare const timeoutPerMb: (secondsPerMb: number, sizeBytes: number) => number;
export declare const getSpiFlashAddresses: (chipFamily: ChipFamily) => SpiFlashAddresses;
export declare class SlipReadError extends Error {
constructor(message: string);
}
export {};

331
dist/const.js vendored

@ -1,331 +0,0 @@
import { toByteArray } from "./util";
export const baudRates = [
115200, 128000, 153600, 230400, 460800, 921600, 1500000, 2000000,
];
export const FLASH_SIZES = {
"512KB": 0x00,
"256KB": 0x10,
"1MB": 0x20,
"2MB": 0x30,
"4MB": 0x40,
"2MB-c1": 0x50,
"4MB-c1": 0x60,
"8MB": 0x80,
"16MB": 0x90,
};
export const ESP32_FLASH_SIZES = {
"1MB": 0x00,
"2MB": 0x10,
"4MB": 0x20,
"8MB": 0x30,
"16MB": 0x40,
"32MB": 0x50,
"64MB": 0x60,
"128MB": 0x70,
};
export const DETECTED_FLASH_SIZES = {
0x12: "256KB",
0x13: "512KB",
0x14: "1MB",
0x15: "2MB",
0x16: "4MB",
0x17: "8MB",
0x18: "16MB",
0x19: "32MB",
0x1a: "64MB",
};
export const FLASH_WRITE_SIZE = 0x400;
export const STUB_FLASH_WRITE_SIZE = 0x4000;
export const FLASH_SECTOR_SIZE = 0x1000; // Flash sector size, minimum unit of erase.
export const ESP_ROM_BAUD = 115200;
export const USB_JTAG_SERIAL_PID = 0x1001;
export const ESP8266_SPI_REG_BASE = 0x60000200;
export const ESP8266_BASEFUSEADDR = 0x3ff00050;
export const ESP8266_MACFUSEADDR = 0x3ff00050;
export const ESP8266_SPI_USR_OFFS = 0x1c;
export const ESP8266_SPI_USR1_OFFS = 0x20;
export const ESP8266_SPI_USR2_OFFS = 0x24;
export const ESP8266_SPI_MOSI_DLEN_OFFS = -1;
export const ESP8266_SPI_MISO_DLEN_OFFS = -1;
export const ESP8266_SPI_W0_OFFS = 0x40;
export const ESP8266_UART_DATE_REG_ADDR = 0x60000078;
export const ESP8266_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32_SPI_REG_BASE = 0x3ff42000;
export const ESP32_BASEFUSEADDR = 0x3ff5a000;
export const ESP32_MACFUSEADDR = 0x3ff5a000;
export const ESP32_SPI_USR_OFFS = 0x1c;
export const ESP32_SPI_USR1_OFFS = 0x20;
export const ESP32_SPI_USR2_OFFS = 0x24;
export const ESP32_SPI_MOSI_DLEN_OFFS = 0x28;
export const ESP32_SPI_MISO_DLEN_OFFS = 0x2c;
export const ESP32_SPI_W0_OFFS = 0x80;
export const ESP32_UART_DATE_REG_ADDR = 0x60000078;
export const ESP32_BOOTLOADER_FLASH_OFFSET = 0x1000;
export const ESP32S2_SPI_REG_BASE = 0x3f402000;
export const ESP32S2_BASEFUSEADDR = 0x3f41a000;
export const ESP32S2_MACFUSEADDR = 0x3f41a044;
export const ESP32S2_SPI_USR_OFFS = 0x18;
export const ESP32S2_SPI_USR1_OFFS = 0x1c;
export const ESP32S2_SPI_USR2_OFFS = 0x20;
export const ESP32S2_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32S2_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32S2_SPI_W0_OFFS = 0x58;
export const ESP32S2_UART_DATE_REG_ADDR = 0x60000078;
export const ESP32S2_BOOTLOADER_FLASH_OFFSET = 0x1000;
export const ESP32S3_SPI_REG_BASE = 0x60002000;
export const ESP32S3_BASEFUSEADDR = 0x60007000;
export const ESP32S3_MACFUSEADDR = 0x60007000 + 0x044;
export const ESP32S3_SPI_USR_OFFS = 0x18;
export const ESP32S3_SPI_USR1_OFFS = 0x1c;
export const ESP32S3_SPI_USR2_OFFS = 0x20;
export const ESP32S3_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32S3_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32S3_SPI_W0_OFFS = 0x58;
export const ESP32S3_UART_DATE_REG_ADDR = 0x60000080;
export const ESP32S3_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32C2_SPI_REG_BASE = 0x60002000;
export const ESP32C2_BASEFUSEADDR = 0x60008800;
export const ESP32C2_MACFUSEADDR = 0x60008800 + 0x044;
export const ESP32C2_SPI_USR_OFFS = 0x18;
export const ESP32C2_SPI_USR1_OFFS = 0x1c;
export const ESP32C2_SPI_USR2_OFFS = 0x20;
export const ESP32C2_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32C2_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32C2_SPI_W0_OFFS = 0x58;
export const ESP32C2_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32C2_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32C3_SPI_REG_BASE = 0x60002000;
export const ESP32C3_BASEFUSEADDR = 0x60008800;
export const ESP32C3_MACFUSEADDR = 0x60008800 + 0x044;
export const ESP32C3_SPI_USR_OFFS = 0x18;
export const ESP32C3_SPI_USR1_OFFS = 0x1c;
export const ESP32C3_SPI_USR2_OFFS = 0x20;
export const ESP32C3_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32C3_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32C3_SPI_W0_OFFS = 0x58;
export const ESP32C3_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32C3_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32C6_SPI_REG_BASE = 0x60003000;
export const ESP32C6_BASEFUSEADDR = 0x600b0800;
export const ESP32C6_MACFUSEADDR = 0x600b0800 + 0x044;
export const ESP32C6_SPI_USR_OFFS = 0x18;
export const ESP32C6_SPI_USR1_OFFS = 0x1c;
export const ESP32C6_SPI_USR2_OFFS = 0x20;
export const ESP32C6_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32C6_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32C6_SPI_W0_OFFS = 0x58;
export const ESP32C6_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32C6_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32H2_SPI_REG_BASE = 0x60002000;
export const ESP32H2_BASEFUSEADDR = 0x6001a000;
export const ESP32H2_MACFUSEADDR = 0x6001a000 + 0x044;
export const ESP32H2_SPI_USR_OFFS = 0x18;
export const ESP32H2_SPI_USR1_OFFS = 0x1c;
export const ESP32H2_SPI_USR2_OFFS = 0x20;
export const ESP32H2_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32H2_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32H2_SPI_W0_OFFS = 0x58;
export const ESP32H2_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32H2_BOOTLOADER_FLASH_OFFSET = 0x0;
export const SYNC_PACKET = toByteArray("\x07\x07\x12 UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU");
export const CHIP_DETECT_MAGIC_REG_ADDR = 0x40001000;
// These values for the families are made up; nothing that esptool uses.
export const CHIP_FAMILY_ESP8266 = 0x8266;
export const CHIP_FAMILY_ESP32 = 0x32;
export const CHIP_FAMILY_ESP32S2 = 0x3252;
export const CHIP_FAMILY_ESP32S3 = 0x3253;
export const CHIP_FAMILY_ESP32C2 = 0x32c2;
export const CHIP_FAMILY_ESP32C3 = 0x32c3;
export const CHIP_FAMILY_ESP32C6 = 0x32c6;
export const CHIP_FAMILY_ESP32H2 = 0x3272;
export const CHIP_DETECT_MAGIC_VALUES = {
0xfff0c101: { name: "ESP8266", family: CHIP_FAMILY_ESP8266 },
0x00f01d83: { name: "ESP32", family: CHIP_FAMILY_ESP32 },
0x000007c6: { name: "ESP32-S2", family: CHIP_FAMILY_ESP32S2 },
0x9: { name: "ESP32-S3", family: CHIP_FAMILY_ESP32S3 },
0xeb004136: { name: "ESP32-S3(beta2)", family: CHIP_FAMILY_ESP32S3 },
0x6f51306f: { name: "ESP32-C2", family: CHIP_FAMILY_ESP32C2 },
0x7c41a06f: { name: "ESP32-C2", family: CHIP_FAMILY_ESP32C2 },
0x6921506f: { name: "ESP32-C3", family: CHIP_FAMILY_ESP32C3 },
0x1b31506f: { name: "ESP32-C3", family: CHIP_FAMILY_ESP32C3 },
0xd7b73e80: { name: "ESP32-H2", family: CHIP_FAMILY_ESP32H2 },
0x0da1806f: { name: "ESP32-C6(beta)", family: CHIP_FAMILY_ESP32C6 },
0x2ce0806f: { name: "ESP32-C6", family: CHIP_FAMILY_ESP32C6 },
};
// Commands supported by ESP8266 ROM bootloader
export const ESP_FLASH_BEGIN = 0x02;
export const ESP_FLASH_DATA = 0x03;
export const ESP_FLASH_END = 0x04;
export const ESP_MEM_BEGIN = 0x05;
export const ESP_MEM_END = 0x06;
export const ESP_MEM_DATA = 0x07;
export const ESP_SYNC = 0x08;
export const ESP_WRITE_REG = 0x09;
export const ESP_READ_REG = 0x0a;
export const ESP_ERASE_FLASH = 0xd0;
export const ESP_ERASE_REGION = 0xd1;
export const ESP_SPI_SET_PARAMS = 0x0b;
export const ESP_SPI_ATTACH = 0x0d;
export const ESP_CHANGE_BAUDRATE = 0x0f;
export const ESP_SPI_FLASH_MD5 = 0x13;
export const ESP_CHECKSUM_MAGIC = 0xef;
export const ESP_FLASH_DEFL_BEGIN = 0x10;
export const ESP_FLASH_DEFL_DATA = 0x11;
export const ESP_FLASH_DEFL_END = 0x12;
export const ROM_INVALID_RECV_MSG = 0x05;
export const USB_RAM_BLOCK = 0x800;
export const ESP_RAM_BLOCK = 0x1800;
// Timeouts
export const DEFAULT_TIMEOUT = 3000;
export const CHIP_ERASE_TIMEOUT = 600000; // timeout for full chip erase in ms
export const MAX_TIMEOUT = CHIP_ERASE_TIMEOUT * 2; // longest any command can run in ms
export const SYNC_TIMEOUT = 100; // timeout for syncing with bootloader in ms
export const ERASE_REGION_TIMEOUT_PER_MB = 30000; // timeout (per megabyte) for erasing a region in ms
export const MEM_END_ROM_TIMEOUT = 500;
/**
* @name timeoutPerMb
* Scales timeouts which are size-specific
*/
export const timeoutPerMb = (secondsPerMb, sizeBytes) => {
let result = Math.floor(secondsPerMb * (sizeBytes / 0x1e6));
if (result < DEFAULT_TIMEOUT) {
return DEFAULT_TIMEOUT;
}
return result;
};
export const getSpiFlashAddresses = (chipFamily) => {
switch (chipFamily) {
case CHIP_FAMILY_ESP32:
return {
regBase: ESP32_SPI_REG_BASE,
baseFuse: ESP32_BASEFUSEADDR,
macFuse: ESP32_MACFUSEADDR,
usrOffs: ESP32_SPI_USR_OFFS,
usr1Offs: ESP32_SPI_USR1_OFFS,
usr2Offs: ESP32_SPI_USR2_OFFS,
mosiDlenOffs: ESP32_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32_SPI_W0_OFFS,
uartDateReg: ESP32_UART_DATE_REG_ADDR,
flashOffs: ESP32_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32S2:
return {
regBase: ESP32S2_SPI_REG_BASE,
baseFuse: ESP32S2_BASEFUSEADDR,
macFuse: ESP32S2_MACFUSEADDR,
usrOffs: ESP32S2_SPI_USR_OFFS,
usr1Offs: ESP32S2_SPI_USR1_OFFS,
usr2Offs: ESP32S2_SPI_USR2_OFFS,
mosiDlenOffs: ESP32S2_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32S2_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32S2_SPI_W0_OFFS,
uartDateReg: ESP32S2_UART_DATE_REG_ADDR,
flashOffs: ESP32S2_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32S3:
return {
regBase: ESP32S3_SPI_REG_BASE,
usrOffs: ESP32S3_SPI_USR_OFFS,
baseFuse: ESP32S3_BASEFUSEADDR,
macFuse: ESP32S3_MACFUSEADDR,
usr1Offs: ESP32S3_SPI_USR1_OFFS,
usr2Offs: ESP32S3_SPI_USR2_OFFS,
mosiDlenOffs: ESP32S3_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32S3_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32S3_SPI_W0_OFFS,
uartDateReg: ESP32S3_UART_DATE_REG_ADDR,
flashOffs: ESP32S3_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP8266:
return {
regBase: ESP8266_SPI_REG_BASE,
usrOffs: ESP8266_SPI_USR_OFFS,
baseFuse: ESP8266_BASEFUSEADDR,
macFuse: ESP8266_MACFUSEADDR,
usr1Offs: ESP8266_SPI_USR1_OFFS,
usr2Offs: ESP8266_SPI_USR2_OFFS,
mosiDlenOffs: ESP8266_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP8266_SPI_MISO_DLEN_OFFS,
w0Offs: ESP8266_SPI_W0_OFFS,
uartDateReg: ESP8266_UART_DATE_REG_ADDR,
flashOffs: ESP8266_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32C2:
return {
regBase: ESP32C2_SPI_REG_BASE,
baseFuse: ESP32C2_BASEFUSEADDR,
macFuse: ESP32C2_MACFUSEADDR,
usrOffs: ESP32C2_SPI_USR_OFFS,
usr1Offs: ESP32C2_SPI_USR1_OFFS,
usr2Offs: ESP32C2_SPI_USR2_OFFS,
mosiDlenOffs: ESP32C2_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32C2_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32C2_SPI_W0_OFFS,
uartDateReg: ESP32C2_UART_DATE_REG_ADDR,
flashOffs: ESP32C2_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32C3:
return {
regBase: ESP32C3_SPI_REG_BASE,
baseFuse: ESP32C3_BASEFUSEADDR,
macFuse: ESP32C3_MACFUSEADDR,
usrOffs: ESP32C3_SPI_USR_OFFS,
usr1Offs: ESP32C3_SPI_USR1_OFFS,
usr2Offs: ESP32C3_SPI_USR2_OFFS,
mosiDlenOffs: ESP32C3_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32C3_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32C3_SPI_W0_OFFS,
uartDateReg: ESP32C3_UART_DATE_REG_ADDR,
flashOffs: ESP32C3_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32C6:
return {
regBase: ESP32C6_SPI_REG_BASE,
baseFuse: ESP32C6_BASEFUSEADDR,
macFuse: ESP32C6_MACFUSEADDR,
usrOffs: ESP32C6_SPI_USR_OFFS,
usr1Offs: ESP32C6_SPI_USR1_OFFS,
usr2Offs: ESP32C6_SPI_USR2_OFFS,
mosiDlenOffs: ESP32C6_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32C6_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32C6_SPI_W0_OFFS,
uartDateReg: ESP32C6_UART_DATE_REG_ADDR,
flashOffs: ESP32C6_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32H2:
return {
regBase: ESP32H2_SPI_REG_BASE,
baseFuse: ESP32H2_BASEFUSEADDR,
macFuse: ESP32H2_MACFUSEADDR,
usrOffs: ESP32H2_SPI_USR_OFFS,
usr1Offs: ESP32H2_SPI_USR1_OFFS,
usr2Offs: ESP32H2_SPI_USR2_OFFS,
mosiDlenOffs: ESP32H2_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32H2_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32H2_SPI_W0_OFFS,
uartDateReg: ESP32H2_UART_DATE_REG_ADDR,
flashOffs: ESP32H2_BOOTLOADER_FLASH_OFFSET,
};
default:
return {
regBase: -1,
baseFuse: -1,
macFuse: -1,
usrOffs: -1,
usr1Offs: -1,
usr2Offs: -1,
mosiDlenOffs: -1,
misoDlenOffs: -1,
w0Offs: -1,
uartDateReg: -1,
flashOffs: -1,
};
}
};
export class SlipReadError extends Error {
constructor(message) {
super(message);
this.name = "SlipReadError";
}
}

165
dist/esp_loader.d.ts vendored

@ -1,165 +0,0 @@
import { Logger, ChipFamily, SpiFlashAddresses } from "./const";
export declare class ESPLoader extends EventTarget {
port: SerialPort;
logger: Logger;
private _parent?;
chipFamily: ChipFamily;
chipName: string | null;
_efuses: any[];
_flashsize: number;
debug: boolean;
IS_STUB: boolean;
connected: boolean;
flashSize: string | null;
__inputBuffer?: number[];
private _reader?;
constructor(port: SerialPort, logger: Logger, _parent?: ESPLoader | undefined);
private get _inputBuffer();
initialize(): Promise<void>;
/**
* @name readLoop
* Reads data from the input stream and places it in the inputBuffer
*/
readLoop(): Promise<void>;
sleep(ms?: number): Promise<unknown>;
state_DTR: boolean;
setRTS(state: boolean): Promise<void>;
setDTR(state: boolean): Promise<void>;
hardReset(bootloader?: boolean): Promise<void>;
/**
* @name macAddr
* The MAC address burned into the OTP memory of the ESP chip
*/
macAddr(): any[];
readRegister(reg: number): Promise<number>;
/**
* @name checkCommand
* Send a command packet, check that the command succeeded and
* return a tuple with the value and data.
* See the ESP Serial Protocol for more details on what value/data are
*/
checkCommand(opcode: number, buffer: number[], checksum?: number, timeout?: number): Promise<[number, number[]]>;
/**
* @name sendCommand
* Send a slip-encoded, checksummed command over the UART,
* does not check response
*/
sendCommand(opcode: number, buffer: number[], checksum?: number): Promise<void>;
/**
* @name readPacket
* Generator to read SLIP packets from a serial port.
* Yields one full SLIP packet at a time, raises exception on timeout or invalid data.
* Designed to avoid too many calls to serial.read(1), which can bog
* down on slow systems.
*/
readPacket(timeout: number): Promise<number[]>;
/**
* @name getResponse
* Read response data and decodes the slip packet, then parses
* out the value/data and returns as a tuple of (value, data) where
* each is a list of bytes
*/
getResponse(opcode: number, timeout?: number): Promise<[number, number[]]>;
/**
* @name checksum
* Calculate checksum of a blob, as it is defined by the ROM
*/
checksum(data: number[], state?: number): number;
setBaudrate(baud: number): Promise<void>;
reconfigurePort(baud: number): Promise<void>;
/**
* @name sync
* Put into ROM bootload mode & attempt to synchronize with the
* ESP ROM bootloader, we will retry a few times
*/
sync(): Promise<boolean>;
/**
* @name _sync
* Perform a soft-sync using AT sync packets, does not perform
* any hardware resetting
*/
_sync(): Promise<boolean>;
/**
* @name getFlashWriteSize
* Get the Flash write size based on the chip
*/
getFlashWriteSize(): 1024 | 16384;
/**
* @name flashData
* Program a full, uncompressed binary file into SPI Flash at
* a given offset. If an ESP32 and md5 string is passed in, will also
* verify memory. ESP8266 does not have checksum memory verification in
* ROM
*/
flashData(binaryData: ArrayBuffer, updateProgress: (bytesWritten: number, totalBytes: number) => void, offset?: number, compress?: boolean): Promise<void>;
/**
* @name flashBlock
* Send one block of data to program into SPI Flash memory
*/
flashBlock(data: number[], seq: number, timeout?: number): Promise<void>;
flashDeflBlock(data: number[], seq: number, timeout?: number): Promise<void>;
/**
* @name flashBegin
* Prepare for flashing by attaching SPI chip and erasing the
* number of blocks requred.
*/
flashBegin(size?: number, offset?: number, encrypted?: boolean): Promise<number>;
/**
* @name flashDeflBegin
*
*/
flashDeflBegin(size?: number, compressedSize?: number, offset?: number, encrypted?: boolean): Promise<number>;
flashFinish(): Promise<void>;
flashDeflFinish(): Promise<void>;
getBootloaderOffset(): number;
flashId(): Promise<number>;
getChipFamily(): ChipFamily;
writeRegister(address: number, value: number, mask?: number, delayUs?: number, delayAfterUs?: number): Promise<void>;
setDataLengths(spiAddresses: SpiFlashAddresses, mosiBits: number, misoBits: number): Promise<void>;
waitDone(spiCmdReg: number, spiCmdUsr: number): Promise<void>;
runSpiFlashCommand(spiflashCommand: number, data: number[], readBits?: number): Promise<number>;
detectFlashSize(): Promise<void>;
/**
* @name getEraseSize
* Calculate an erase size given a specific size in bytes.
* Provides a workaround for the bootloader erase bug on ESP8266.
*/
getEraseSize(offset: number, size: number): number;
/**
* @name memBegin (592)
* Start downloading an application image to RAM
*/
memBegin(size: number, blocks: number, blocksize: number, offset: number): Promise<[number, number[]]>;
/**
* @name memBlock (609)
* Send a block of an image to RAM
*/
memBlock(data: number[], seq: number): Promise<[number, number[]]>;
/**
* @name memFinish (615)
* Leave download mode and run the application
*
* Sending ESP_MEM_END usually sends a correct response back, however sometimes
* (with ROM loader) the executed code may reset the UART or change the baud rate
* before the transmit FIFO is empty. So in these cases we set a short timeout and
* ignore errors.
*/
memFinish(entrypoint?: number): Promise<[number, number[]]>;
runStub(): Promise<EspStubLoader>;
writeToStream(data: number[]): Promise<void>;
disconnect(): Promise<void>;
}
declare class EspStubLoader extends ESPLoader {
IS_STUB: boolean;
/**
* @name memBegin (592)
* Start downloading an application image to RAM
*/
memBegin(size: number, blocks: number, blocksize: number, offset: number): Promise<any>;
/**
* @name getEraseSize
* depending on flash chip model the erase may take this long (maybe longer!)
*/
eraseFlash(): Promise<void>;
}
export {};

949
dist/esp_loader.js vendored

@ -1,949 +0,0 @@
import { CHIP_FAMILY_ESP32, CHIP_FAMILY_ESP32S2, CHIP_FAMILY_ESP32S3, CHIP_FAMILY_ESP32C2, CHIP_FAMILY_ESP32C3, CHIP_FAMILY_ESP32C6, CHIP_FAMILY_ESP32H2, CHIP_FAMILY_ESP8266, MAX_TIMEOUT, DEFAULT_TIMEOUT, ERASE_REGION_TIMEOUT_PER_MB, ESP_CHANGE_BAUDRATE, ESP_CHECKSUM_MAGIC, ESP_FLASH_BEGIN, ESP_FLASH_DATA, ESP_FLASH_END, ESP_MEM_BEGIN, ESP_MEM_DATA, ESP_MEM_END, ESP_READ_REG, ESP_WRITE_REG, ESP_SPI_ATTACH, ESP_SYNC, FLASH_SECTOR_SIZE, FLASH_WRITE_SIZE, STUB_FLASH_WRITE_SIZE, MEM_END_ROM_TIMEOUT, ROM_INVALID_RECV_MSG, SYNC_PACKET, SYNC_TIMEOUT, USB_RAM_BLOCK, ESP_ERASE_FLASH, CHIP_ERASE_TIMEOUT, timeoutPerMb, ESP_ROM_BAUD, USB_JTAG_SERIAL_PID, ESP_FLASH_DEFL_BEGIN, ESP_FLASH_DEFL_DATA, ESP_FLASH_DEFL_END, getSpiFlashAddresses, DETECTED_FLASH_SIZES, CHIP_DETECT_MAGIC_REG_ADDR, CHIP_DETECT_MAGIC_VALUES, SlipReadError, } from "./const";
import { getStubCode } from "./stubs";
import { hexFormatter, sleep, slipEncode, toHex } from "./util";
// @ts-ignore
import { deflate } from "pako/dist/pako.esm.mjs";
import { pack, unpack } from "./struct";
export class ESPLoader extends EventTarget {
constructor(port, logger, _parent) {
super();
this.port = port;
this.logger = logger;
this._parent = _parent;
this.chipName = null;
this._efuses = new Array(4).fill(0);
this._flashsize = 4 * 1024 * 1024;
this.debug = false;
this.IS_STUB = false;
this.connected = true;
this.flashSize = null;
this.state_DTR = false;
}
get _inputBuffer() {
return this._parent ? this._parent._inputBuffer : this.__inputBuffer;
}
async initialize() {
await this.hardReset(true);
if (!this._parent) {
this.__inputBuffer = [];
// Don't await this promise so it doesn't block rest of method.
this.readLoop();
}
await this.sync();
// Determine chip family and name
let chipMagicValue = await this.readRegister(CHIP_DETECT_MAGIC_REG_ADDR);
let chip = CHIP_DETECT_MAGIC_VALUES[chipMagicValue >>> 0];
if (chip === undefined) {
throw new Error(`Unknown Chip: Hex: ${toHex(chipMagicValue >>> 0, 8).toLowerCase()} Number: ${chipMagicValue}`);
}
this.chipName = chip.name;
this.chipFamily = chip.family;
// Read the OTP data for this chip and store into this.efuses array
let FlAddr = getSpiFlashAddresses(this.getChipFamily());
let AddrMAC = FlAddr.macFuse;
for (let i = 0; i < 4; i++) {
this._efuses[i] = await this.readRegister(AddrMAC + 4 * i);
}
this.logger.log(`Chip type ${this.chipName}`);
//this.logger.log("FLASHID");
}
/**
* @name readLoop
* Reads data from the input stream and places it in the inputBuffer
*/
async readLoop() {
if (this.debug) {
this.logger.debug("Starting read loop");
}
this._reader = this.port.readable.getReader();
try {
while (true) {
const { value, done } = await this._reader.read();
if (done) {
this._reader.releaseLock();
break;
}
if (!value || value.length === 0) {
continue;
}
this._inputBuffer.push(...Array.from(value));
}
}
catch (err) {
console.error("Read loop got disconnected");
}
// Disconnected!
this.connected = false;
this.dispatchEvent(new Event("disconnect"));
this.logger.debug("Finished read loop");
}
sleep(ms = 100) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async setRTS(state) {
await this.port.setSignals({ requestToSend: state });
// # Work-around for adapters on Windows using the usbser.sys driver:
// # generate a dummy change to DTR so that the set-control-line-state
// # request is sent with the updated RTS state and the same DTR state
// Referenced to esptool.py
await this.setDTR(this.state_DTR);
}
async setDTR(state) {
this.state_DTR = state;
await this.port.setSignals({ dataTerminalReady: state });
}
async hardReset(bootloader = false) {
// Passthrough mode defaults to "off"
// Passthrough checkbox is "on" will prevent a controller reset
const noResetCheckbox = document.getElementById("noReset");
const noReset = noResetCheckbox ? noResetCheckbox.checked : false;
if (noReset) {
return; // Skip reset if noReset is true
}
if (bootloader) {
// enter flash mode
if (this.port.getInfo().usbProductId === USB_JTAG_SERIAL_PID) {
// esp32c3 esp32s3 etc. build-in USB serial.
// when connect to computer direct via usb, using following signals
// to enter flash mode automatically.
await this.setDTR(false);
await this.setRTS(false);
await this.sleep(100);
await this.setDTR(true);
await this.setRTS(false);
await this.sleep(100);
await this.setRTS(true);
await this.setDTR(false);
await this.setRTS(true);
await this.sleep(100);
await this.setDTR(false);
await this.setRTS(false);
}
else {
// otherwise, esp chip should be connected to computer via usb-serial
// bridge chip like ch340, CP2102 etc.
// use normal way to enter flash mode.
await this.setDTR(false);
await this.setRTS(true);
await this.sleep(100);
await this.setDTR(true);
await this.setRTS(false);
await this.sleep(50);
await this.setDTR(false);
}
}
else {
// just reset
await this.setRTS(true); // EN->LOW
await this.sleep(100);
await this.setRTS(false);
}
await new Promise((resolve) => setTimeout(resolve, 1000));
}
/**
* @name macAddr
* The MAC address burned into the OTP memory of the ESP chip
*/
macAddr() {
let macAddr = new Array(6).fill(0);
let mac0 = this._efuses[0];
let mac1 = this._efuses[1];
let mac2 = this._efuses[2];
let mac3 = this._efuses[3];
let oui;
if (this.chipFamily == CHIP_FAMILY_ESP8266) {
if (mac3 != 0) {
oui = [(mac3 >> 16) & 0xff, (mac3 >> 8) & 0xff, mac3 & 0xff];
}
else if (((mac1 >> 16) & 0xff) == 0) {
oui = [0x18, 0xfe, 0x34];
}
else if (((mac1 >> 16) & 0xff) == 1) {
oui = [0xac, 0xd0, 0x74];
}
else {
throw new Error("Couldnt determine OUI");
}
macAddr[0] = oui[0];
macAddr[1] = oui[1];
macAddr[2] = oui[2];
macAddr[3] = (mac1 >> 8) & 0xff;
macAddr[4] = mac1 & 0xff;
macAddr[5] = (mac0 >> 24) & 0xff;
}
else if (this.chipFamily == CHIP_FAMILY_ESP32) {
macAddr[0] = (mac2 >> 8) & 0xff;
macAddr[1] = mac2 & 0xff;
macAddr[2] = (mac1 >> 24) & 0xff;
macAddr[3] = (mac1 >> 16) & 0xff;
macAddr[4] = (mac1 >> 8) & 0xff;
macAddr[5] = mac1 & 0xff;
}
else if (this.chipFamily == CHIP_FAMILY_ESP32S2 ||
this.chipFamily == CHIP_FAMILY_ESP32S3 ||
this.chipFamily == CHIP_FAMILY_ESP32C2 ||
this.chipFamily == CHIP_FAMILY_ESP32C3 ||
this.chipFamily == CHIP_FAMILY_ESP32C6 ||
this.chipFamily == CHIP_FAMILY_ESP32H2) {
macAddr[0] = (mac1 >> 8) & 0xff;
macAddr[1] = mac1 & 0xff;
macAddr[2] = (mac0 >> 24) & 0xff;
macAddr[3] = (mac0 >> 16) & 0xff;
macAddr[4] = (mac0 >> 8) & 0xff;
macAddr[5] = mac0 & 0xff;
}
else {
throw new Error("Unknown chip family");
}
return macAddr;
}
async readRegister(reg) {
if (this.debug) {
this.logger.debug("Reading from Register " + toHex(reg, 8));
}
let packet = pack("<I", reg);
await this.sendCommand(ESP_READ_REG, packet);
let [val, _data] = await this.getResponse(ESP_READ_REG);
return val;
}
/**
* @name checkCommand
* Send a command packet, check that the command succeeded and
* return a tuple with the value and data.
* See the ESP Serial Protocol for more details on what value/data are
*/
async checkCommand(opcode, buffer, checksum = 0, timeout = DEFAULT_TIMEOUT) {
timeout = Math.min(timeout, MAX_TIMEOUT);
await this.sendCommand(opcode, buffer, checksum);
let [value, data] = await this.getResponse(opcode, timeout);
if (data === null) {
throw new Error("Didn't get enough status bytes");
}
let statusLen = 0;
if (this.IS_STUB || this.chipFamily == CHIP_FAMILY_ESP8266) {
statusLen = 2;
}
else if ([
CHIP_FAMILY_ESP32,
CHIP_FAMILY_ESP32S2,
CHIP_FAMILY_ESP32S3,
CHIP_FAMILY_ESP32C2,
CHIP_FAMILY_ESP32C3,
CHIP_FAMILY_ESP32C6,
CHIP_FAMILY_ESP32H2,
].includes(this.chipFamily)) {
statusLen = 4;
}
else {
if ([2, 4].includes(data.length)) {
statusLen = data.length;
}
}
if (data.length < statusLen) {
throw new Error("Didn't get enough status bytes");
}
let status = data.slice(-statusLen, data.length);
data = data.slice(0, -statusLen);
if (this.debug) {
this.logger.debug("status", status);
this.logger.debug("value", value);
this.logger.debug("data", data);
}
if (status[0] == 1) {
if (status[1] == ROM_INVALID_RECV_MSG) {
throw new Error("Invalid (unsupported) command " + toHex(opcode));
}
else {
throw new Error("Command failure error code " + toHex(status[1]));
}
}
return [value, data];
}
/**
* @name sendCommand
* Send a slip-encoded, checksummed command over the UART,
* does not check response
*/
async sendCommand(opcode, buffer, checksum = 0) {
let packet = slipEncode([
...pack("<BBHI", 0x00, opcode, buffer.length, checksum),
...buffer,
]);
if (this.debug) {
this.logger.debug(`Writing ${packet.length} byte${packet.length == 1 ? "" : "s"}:`, packet);
}
await this.writeToStream(packet);
}
/**
* @name readPacket
* Generator to read SLIP packets from a serial port.
* Yields one full SLIP packet at a time, raises exception on timeout or invalid data.
* Designed to avoid too many calls to serial.read(1), which can bog
* down on slow systems.
*/
async readPacket(timeout) {
let partialPacket = null;
let inEscape = false;
let readBytes = [];
while (true) {
let stamp = Date.now();
readBytes = [];
while (Date.now() - stamp < timeout) {
if (this._inputBuffer.length > 0) {
readBytes.push(this._inputBuffer.shift());
break;
}
else {
await sleep(10);
}
}
if (readBytes.length == 0) {
let waitingFor = partialPacket === null ? "header" : "content";
throw new SlipReadError("Timed out waiting for packet " + waitingFor);
}
if (this.debug)
this.logger.debug("Read " + readBytes.length + " bytes: " + hexFormatter(readBytes));
for (let b of readBytes) {
if (partialPacket === null) {
// waiting for packet header
if (b == 0xc0) {
partialPacket = [];
}
else {
if (this.debug) {
this.logger.debug("Read invalid data: " + hexFormatter(readBytes));
this.logger.debug("Remaining data in serial buffer: " +
hexFormatter(this._inputBuffer));
}
throw new SlipReadError("Invalid head of packet (" + toHex(b) + ")");
}
}
else if (inEscape) {
// part-way through escape sequence
inEscape = false;
if (b == 0xdc) {
partialPacket.push(0xc0);
}
else if (b == 0xdd) {
partialPacket.push(0xdb);
}
else {
if (this.debug) {
this.logger.debug("Read invalid data: " + hexFormatter(readBytes));
this.logger.debug("Remaining data in serial buffer: " +
hexFormatter(this._inputBuffer));
}
throw new SlipReadError("Invalid SLIP escape (0xdb, " + toHex(b) + ")");
}
}
else if (b == 0xdb) {
// start of escape sequence
inEscape = true;
}
else if (b == 0xc0) {
// end of packet
if (this.debug)
this.logger.debug("Received full packet: " + hexFormatter(partialPacket));
return partialPacket;
}
else {
// normal byte in packet
partialPacket.push(b);
}
}
}
throw new SlipReadError("Invalid state");
}
/**
* @name getResponse
* Read response data and decodes the slip packet, then parses
* out the value/data and returns as a tuple of (value, data) where
* each is a list of bytes
*/
async getResponse(opcode, timeout = DEFAULT_TIMEOUT) {
for (let i = 0; i < 100; i++) {
const packet = await this.readPacket(timeout);
if (packet.length < 8) {
continue;
}
const [resp, opRet, _lenRet, val] = unpack("<BBHI", packet.slice(0, 8));
if (resp != 1) {
continue;
}
const data = packet.slice(8);
if (opcode == null || opRet == opcode) {
return [val, data];
}
if (data[0] != 0 && data[1] == ROM_INVALID_RECV_MSG) {
this._inputBuffer.length = 0;
throw new Error(`Invalid (unsupported) command ${toHex(opcode)}`);
}
}
throw "Response doesn't match request";
}
/**
* @name checksum
* Calculate checksum of a blob, as it is defined by the ROM
*/
checksum(data, state = ESP_CHECKSUM_MAGIC) {
for (let b of data) {
state ^= b;
}
return state;
}
async setBaudrate(baud) {
if (this.chipFamily == CHIP_FAMILY_ESP8266) {
throw new Error("Changing baud rate is not supported on the ESP8266");
}
this.logger.log("Attempting to change baud rate to " + baud + "...");
try {
// Send ESP_ROM_BAUD(115200) as the old one if running STUB otherwise 0
let buffer = pack("<II", baud, this.IS_STUB ? ESP_ROM_BAUD : 0);
await this.checkCommand(ESP_CHANGE_BAUDRATE, buffer);
}
catch (e) {
console.error(e);
throw new Error(`Unable to change the baud rate to ${baud}: No response from set baud rate command.`);
}
if (this._parent) {
await this._parent.reconfigurePort(baud);
}
else {
await this.reconfigurePort(baud);
}
}
async reconfigurePort(baud) {
var _a;
try {
// SerialPort does not allow to be reconfigured while open so we close and re-open
// reader.cancel() causes the Promise returned by the read() operation running on
// the readLoop to return immediately with { value: undefined, done: true } and thus
// breaking the loop and exiting readLoop();
await ((_a = this._reader) === null || _a === void 0 ? void 0 : _a.cancel());
await this.port.close();
// Reopen Port
await this.port.open({ baudRate: baud });
// Restart Readloop
this.readLoop();
this.logger.log(`Changed baud rate to ${baud}`);
}
catch (e) {
console.error(e);
throw new Error(`Unable to change the baud rate to ${baud}: ${e}`);
}
}
/**
* @name sync
* Put into ROM bootload mode & attempt to synchronize with the
* ESP ROM bootloader, we will retry a few times
*/
async sync() {
for (let i = 0; i < 5; i++) {
this._inputBuffer.length = 0;
let response = await this._sync();
if (response) {
await sleep(100);
return true;
}
await sleep(100);
}
throw new Error("Couldn't sync to ESP. Try resetting.");
}
/**
* @name _sync
* Perform a soft-sync using AT sync packets, does not perform
* any hardware resetting
*/
async _sync() {
await this.sendCommand(ESP_SYNC, SYNC_PACKET);
for (let i = 0; i < 8; i++) {
try {
let [_reply, data] = await this.getResponse(ESP_SYNC, SYNC_TIMEOUT);
if (data.length > 1 && data[0] == 0 && data[1] == 0) {
return true;
}
}
catch (err) {
// If read packet fails.
}
}
return false;
}
/**
* @name getFlashWriteSize
* Get the Flash write size based on the chip
*/
getFlashWriteSize() {
if (this.IS_STUB) {
return STUB_FLASH_WRITE_SIZE;
}
return FLASH_WRITE_SIZE;
}
/**
* @name flashData
* Program a full, uncompressed binary file into SPI Flash at
* a given offset. If an ESP32 and md5 string is passed in, will also
* verify memory. ESP8266 does not have checksum memory verification in
* ROM
*/
async flashData(binaryData, updateProgress, offset = 0, compress = false) {
if (binaryData.byteLength >= 8) {
// unpack the (potential) image header
var header = Array.from(new Uint8Array(binaryData, 0, 4));
let headerMagic = header[0];
let headerFlashMode = header[2];
let headerFlashSizeFreq = header[3];
this.logger.log(`Image header, Magic=${toHex(headerMagic)}, FlashMode=${toHex(headerFlashMode)}, FlashSizeFreq=${toHex(headerFlashSizeFreq)}`);
}
let uncompressedFilesize = binaryData.byteLength;
let compressedFilesize = 0;
let dataToFlash;
let timeout = DEFAULT_TIMEOUT;
if (compress) {
dataToFlash = deflate(new Uint8Array(binaryData), {
level: 9,
}).buffer;
compressedFilesize = dataToFlash.byteLength;
this.logger.log(`Writing data with filesize: ${uncompressedFilesize}. Compressed Size: ${compressedFilesize}`);
timeout = await this.flashDeflBegin(uncompressedFilesize, compressedFilesize, offset);
}
else {
this.logger.log(`Writing data with filesize: ${uncompressedFilesize}`);
dataToFlash = binaryData;
await this.flashBegin(uncompressedFilesize, offset);
}
let block = [];
let seq = 0;
let written = 0;
let position = 0;
let stamp = Date.now();
let flashWriteSize = this.getFlashWriteSize();
let filesize = compress ? compressedFilesize : uncompressedFilesize;
while (filesize - position > 0) {
if (this.debug) {
this.logger.log(`Writing at ${toHex(offset + seq * flashWriteSize, 8)} `);
}
if (filesize - position >= flashWriteSize) {
block = Array.from(new Uint8Array(dataToFlash, position, flashWriteSize));
}
else {
// Pad the last block only if we are sending uncompressed data.
block = Array.from(new Uint8Array(dataToFlash, position, filesize - position));
if (!compress) {
block = block.concat(new Array(flashWriteSize - block.length).fill(0xff));
}
}
if (compress) {
await this.flashDeflBlock(block, seq, timeout);
}
else {
await this.flashBlock(block, seq);
}
seq += 1;
// If using compression we update the progress with the proportional size of the block taking into account the compression ratio.
// This way we report progress on the uncompressed size
written += compress
? Math.round((block.length * uncompressedFilesize) / compressedFilesize)
: block.length;
position += flashWriteSize;
updateProgress(Math.min(written, uncompressedFilesize), uncompressedFilesize);
}
this.logger.log("Took " + (Date.now() - stamp) + "ms to write " + filesize + " bytes");
// Only send flashF finish if running the stub because ir causes the ROM to exit and run user code
if (this.IS_STUB) {
await this.flashBegin(0, 0);
if (compress) {
await this.flashDeflFinish();
}
else {
await this.flashFinish();
}
}
}
/**
* @name flashBlock
* Send one block of data to program into SPI Flash memory
*/
async flashBlock(data, seq, timeout = DEFAULT_TIMEOUT) {
await this.checkCommand(ESP_FLASH_DATA, pack("<IIII", data.length, seq, 0, 0).concat(data), this.checksum(data), timeout);
}
async flashDeflBlock(data, seq, timeout = DEFAULT_TIMEOUT) {
await this.checkCommand(ESP_FLASH_DEFL_DATA, pack("<IIII", data.length, seq, 0, 0).concat(data), this.checksum(data), timeout);
}
/**
* @name flashBegin
* Prepare for flashing by attaching SPI chip and erasing the
* number of blocks requred.
*/
async flashBegin(size = 0, offset = 0, encrypted = false) {
let eraseSize;
let buffer;
let flashWriteSize = this.getFlashWriteSize();
if (!this.IS_STUB &&
[
CHIP_FAMILY_ESP32,
CHIP_FAMILY_ESP32S2,
CHIP_FAMILY_ESP32S3,
CHIP_FAMILY_ESP32C2,
CHIP_FAMILY_ESP32C3,
CHIP_FAMILY_ESP32C6,
CHIP_FAMILY_ESP32H2,
].includes(this.chipFamily)) {
await this.checkCommand(ESP_SPI_ATTACH, new Array(8).fill(0));
}
let numBlocks = Math.floor((size + flashWriteSize - 1) / flashWriteSize);
if (this.chipFamily == CHIP_FAMILY_ESP8266) {
eraseSize = this.getEraseSize(offset, size);
}
else {
eraseSize = size;
}
let timeout;
if (this.IS_STUB) {
timeout = DEFAULT_TIMEOUT;
}
else {
timeout = timeoutPerMb(ERASE_REGION_TIMEOUT_PER_MB, size);
}
let stamp = Date.now();
buffer = pack("<IIII", eraseSize, numBlocks, flashWriteSize, offset);
if (this.chipFamily == CHIP_FAMILY_ESP32 ||
this.chipFamily == CHIP_FAMILY_ESP32S2 ||
this.chipFamily == CHIP_FAMILY_ESP32S3 ||
this.chipFamily == CHIP_FAMILY_ESP32C2 ||
this.chipFamily == CHIP_FAMILY_ESP32C3 ||
this.chipFamily == CHIP_FAMILY_ESP32C6 ||
this.chipFamily == CHIP_FAMILY_ESP32H2) {
buffer = buffer.concat(pack("<I", encrypted ? 1 : 0));
}
this.logger.log("Erase size " +
eraseSize +
", blocks " +
numBlocks +
", block size " +
toHex(flashWriteSize, 4) +
", offset " +
toHex(offset, 4) +
", encrypted " +
(encrypted ? "yes" : "no"));
await this.checkCommand(ESP_FLASH_BEGIN, buffer, 0, timeout);
if (size != 0 && !this.IS_STUB) {
this.logger.log("Took " + (Date.now() - stamp) + "ms to erase " + numBlocks + " bytes");
}
return numBlocks;
}
/**
* @name flashDeflBegin
*
*/
async flashDeflBegin(size = 0, compressedSize = 0, offset = 0, encrypted = false) {
// Start downloading compressed data to Flash (performs an erase)
// Returns number of blocks to write.
let flashWriteSize = this.getFlashWriteSize();
let numBlocks = Math.floor((compressedSize + flashWriteSize - 1) / flashWriteSize);
let eraseBlocks = Math.floor((size + flashWriteSize - 1) / flashWriteSize);
let writeSize = 0;
let timeout = 0;
let buffer;
if (this.IS_STUB) {
writeSize = size; // stub expects number of bytes here, manages erasing internally
timeout = timeoutPerMb(ERASE_REGION_TIMEOUT_PER_MB, writeSize); // ROM performs the erase up front
}
else {
writeSize = eraseBlocks * flashWriteSize; // ROM expects rounded up to erase block size
timeout = DEFAULT_TIMEOUT;
}
buffer = pack("<IIII", writeSize, numBlocks, flashWriteSize, offset);
await this.checkCommand(ESP_FLASH_DEFL_BEGIN, buffer, 0, timeout);
return timeout;
}
async flashFinish() {
let buffer = pack("<I", 1);
await this.checkCommand(ESP_FLASH_END, buffer);
}
async flashDeflFinish() {
let buffer = pack("<I", 1);
await this.checkCommand(ESP_FLASH_DEFL_END, buffer);
}
getBootloaderOffset() {
let bootFlashOffs = getSpiFlashAddresses(this.getChipFamily());
let BootldrFlashOffs = bootFlashOffs.flashOffs;
return BootldrFlashOffs;
}
async flashId() {
let SPIFLASH_RDID = 0x9f;
let result = await this.runSpiFlashCommand(SPIFLASH_RDID, [], 24);
return result;
}
getChipFamily() {
return this._parent ? this._parent.chipFamily : this.chipFamily;
}
async writeRegister(address, value, mask = 0xffffffff, delayUs = 0, delayAfterUs = 0) {
let buffer = pack("<IIII", address, value, mask, delayUs);
if (delayAfterUs > 0) {
// add a dummy write to a date register as an excuse to have a delay
buffer.concat(pack("<IIII", getSpiFlashAddresses(this.getChipFamily()).uartDateReg, 0, 0, delayAfterUs));
}
await this.checkCommand(ESP_WRITE_REG, buffer);
}
async setDataLengths(spiAddresses, mosiBits, misoBits) {
if (spiAddresses.mosiDlenOffs != -1) {
// ESP32/32S2/32S3/32C3 has a more sophisticated way to set up "user" commands
let SPI_MOSI_DLEN_REG = spiAddresses.regBase + spiAddresses.mosiDlenOffs;
let SPI_MISO_DLEN_REG = spiAddresses.regBase + spiAddresses.misoDlenOffs;
if (mosiBits > 0) {
await this.writeRegister(SPI_MOSI_DLEN_REG, mosiBits - 1);
}
if (misoBits > 0) {
await this.writeRegister(SPI_MISO_DLEN_REG, misoBits - 1);
}
}
else {
let SPI_DATA_LEN_REG = spiAddresses.regBase + spiAddresses.usr1Offs;
let SPI_MOSI_BITLEN_S = 17;
let SPI_MISO_BITLEN_S = 8;
let mosiMask = mosiBits == 0 ? 0 : mosiBits - 1;
let misoMask = misoBits == 0 ? 0 : misoBits - 1;
let value = (misoMask << SPI_MISO_BITLEN_S) | (mosiMask << SPI_MOSI_BITLEN_S);
await this.writeRegister(SPI_DATA_LEN_REG, value);
}
}
async waitDone(spiCmdReg, spiCmdUsr) {
for (let i = 0; i < 10; i++) {
let cmdValue = await this.readRegister(spiCmdReg);
if ((cmdValue & spiCmdUsr) == 0) {
return;
}
}
throw Error("SPI command did not complete in time");
}
async runSpiFlashCommand(spiflashCommand, data, readBits = 0) {
// Run an arbitrary SPI flash command.
// This function uses the "USR_COMMAND" functionality in the ESP
// SPI hardware, rather than the precanned commands supported by
// hardware. So the value of spiflash_command is an actual command
// byte, sent over the wire.
// After writing command byte, writes 'data' to MOSI and then
// reads back 'read_bits' of reply on MISO. Result is a number.
// SPI_USR register flags
let SPI_USR_COMMAND = 1 << 31;
let SPI_USR_MISO = 1 << 28;
let SPI_USR_MOSI = 1 << 27;
// SPI registers, base address differs ESP32* vs 8266
let spiAddresses = getSpiFlashAddresses(this.getChipFamily());
let base = spiAddresses.regBase;
let SPI_CMD_REG = base;
let SPI_USR_REG = base + spiAddresses.usrOffs;
let SPI_USR2_REG = base + spiAddresses.usr2Offs;
let SPI_W0_REG = base + spiAddresses.w0Offs;
// SPI peripheral "command" bitmasks for SPI_CMD_REG
let SPI_CMD_USR = 1 << 18;
// shift values
let SPI_USR2_COMMAND_LEN_SHIFT = 28;
if (readBits > 32) {
throw new Error("Reading more than 32 bits back from a SPI flash operation is unsupported");
}
if (data.length > 64) {
throw new Error("Writing more than 64 bytes of data with one SPI command is unsupported");
}
let dataBits = data.length * 8;
let oldSpiUsr = await this.readRegister(SPI_USR_REG);
let oldSpiUsr2 = await this.readRegister(SPI_USR2_REG);
let flags = SPI_USR_COMMAND;
if (readBits > 0) {
flags |= SPI_USR_MISO;
}
if (dataBits > 0) {
flags |= SPI_USR_MOSI;
}
await this.setDataLengths(spiAddresses, dataBits, readBits);
await this.writeRegister(SPI_USR_REG, flags);
await this.writeRegister(SPI_USR2_REG, (7 << SPI_USR2_COMMAND_LEN_SHIFT) | spiflashCommand);
if (dataBits == 0) {
await this.writeRegister(SPI_W0_REG, 0); // clear data register before we read it
}
else {
data.concat(new Array(data.length % 4).fill(0x00)); // pad to 32-bit multiple
let words = unpack("I".repeat(Math.floor(data.length / 4)), data);
let nextReg = SPI_W0_REG;
this.logger.debug(`Words Length: ${words.length}`);
for (const word of words) {
this.logger.debug(`Writing word ${toHex(word)} to register offset ${toHex(nextReg)}`);
await this.writeRegister(nextReg, word);
nextReg += 4;
}
}
await this.writeRegister(SPI_CMD_REG, SPI_CMD_USR);
await this.waitDone(SPI_CMD_REG, SPI_CMD_USR);
let status = await this.readRegister(SPI_W0_REG);
// restore some SPI controller registers
await this.writeRegister(SPI_USR_REG, oldSpiUsr);
await this.writeRegister(SPI_USR2_REG, oldSpiUsr2);
return status;
}
async detectFlashSize() {
this.logger.log("Detecting Flash Size");
let flashId = await this.flashId();
let manufacturer = flashId & 0xff;
let flashIdLowbyte = (flashId >> 16) & 0xff;
this.logger.log(`FlashId: ${toHex(flashId)}`);
this.logger.log(`Flash Manufacturer: ${manufacturer.toString(16)}`);
this.logger.log(`Flash Device: ${((flashId >> 8) & 0xff).toString(16)}${flashIdLowbyte.toString(16)}`);
this.flashSize = DETECTED_FLASH_SIZES[flashIdLowbyte];
this.logger.log(`Auto-detected Flash size: ${this.flashSize}`);
}
/**
* @name getEraseSize
* Calculate an erase size given a specific size in bytes.
* Provides a workaround for the bootloader erase bug on ESP8266.
*/
getEraseSize(offset, size) {
let sectorsPerBlock = 16;
let sectorSize = FLASH_SECTOR_SIZE;
let numSectors = Math.floor((size + sectorSize - 1) / sectorSize);
let startSector = Math.floor(offset / sectorSize);
let headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
if (numSectors < headSectors) {
headSectors = numSectors;
}
if (numSectors < 2 * headSectors) {
return Math.floor(((numSectors + 1) / 2) * sectorSize);
}
return (numSectors - headSectors) * sectorSize;
}
/**
* @name memBegin (592)
* Start downloading an application image to RAM
*/
async memBegin(size, blocks, blocksize, offset) {
return await this.checkCommand(ESP_MEM_BEGIN, pack("<IIII", size, blocks, blocksize, offset));
}
/**
* @name memBlock (609)
* Send a block of an image to RAM
*/
async memBlock(data, seq) {
return await this.checkCommand(ESP_MEM_DATA, pack("<IIII", data.length, seq, 0, 0).concat(data), this.checksum(data));
}
/**
* @name memFinish (615)
* Leave download mode and run the application
*
* Sending ESP_MEM_END usually sends a correct response back, however sometimes
* (with ROM loader) the executed code may reset the UART or change the baud rate
* before the transmit FIFO is empty. So in these cases we set a short timeout and
* ignore errors.
*/
async memFinish(entrypoint = 0) {
let timeout = this.IS_STUB ? DEFAULT_TIMEOUT : MEM_END_ROM_TIMEOUT;
let data = pack("<II", entrypoint == 0 ? 1 : 0, entrypoint);
return await this.checkCommand(ESP_MEM_END, data, 0, timeout);
}
async runStub() {
const stub = await getStubCode(this.chipFamily);
// We're transferring over USB, right?
let ramBlock = USB_RAM_BLOCK;
// Upload
this.logger.log("Uploading stub...");
for (let field of ["text", "data"]) {
if (Object.keys(stub).includes(field)) {
let offset = stub[field + "_start"];
let length = stub[field].length;
let blocks = Math.floor((length + ramBlock - 1) / ramBlock);
await this.memBegin(length, blocks, ramBlock, offset);
for (let seq of Array(blocks).keys()) {
let fromOffs = seq * ramBlock;
let toOffs = fromOffs + ramBlock;
if (toOffs > length) {
toOffs = length;
}
await this.memBlock(stub[field].slice(fromOffs, toOffs), seq);
}
}
}
this.logger.log("Running stub...");
await this.memFinish(stub["entry"]);
let pChar;
const p = await this.readPacket(500);
pChar = String.fromCharCode(...p);
if (pChar != "OHAI") {
throw new Error("Failed to start stub. Unexpected response: " + pChar);
}
this.logger.log("Stub is now running...");
const espStubLoader = new EspStubLoader(this.port, this.logger, this);
// Try to autodetect the flash size as soon as the stub is running.
await espStubLoader.detectFlashSize();
return espStubLoader;
}
async writeToStream(data) {
const writer = this.port.writable.getWriter();
await writer.write(new Uint8Array(data));
try {
writer.releaseLock();
}
catch (err) {
console.error("Ignoring release lock error", err);
}
}
async disconnect() {
if (this._parent) {
await this._parent.disconnect();
return;
}
await this.port.writable.getWriter().close();
await new Promise((resolve) => {
if (!this._reader) {
resolve(undefined);
}
this.addEventListener("disconnect", resolve, { once: true });
this._reader.cancel();
});
this.connected = false;
}
}
class EspStubLoader extends ESPLoader {
constructor() {
super(...arguments);
/*
The Stubloader has commands that run on the uploaded Stub Code in RAM
rather than built in commands.
*/
this.IS_STUB = true;
}
/**
* @name memBegin (592)
* Start downloading an application image to RAM
*/
async memBegin(size, blocks, blocksize, offset) {
let stub = await getStubCode(this.chipFamily);
let load_start = offset;
let load_end = offset + size;
console.log(load_start, load_end);
console.log(stub.data_start, stub.data.length, stub.text_start, stub.text.length);
for (let [start, end] of [
[stub.data_start, stub.data_start + stub.data.length],
[stub.text_start, stub.text_start + stub.text.length],
]) {
if (load_start < end && load_end > start) {
throw new Error("Software loader is resident at " +
toHex(start, 8) +
"-" +
toHex(end, 8) +
". " +
"Can't load binary at overlapping address range " +
toHex(load_start, 8) +
"-" +
toHex(load_end, 8) +
". " +
"Try changing the binary loading address.");
}
}
}
/**
* @name getEraseSize
* depending on flash chip model the erase may take this long (maybe longer!)
*/
async eraseFlash() {
await this.checkCommand(ESP_ERASE_FLASH, [], 0, CHIP_ERASE_TIMEOUT);
}
}

6
dist/index.d.ts vendored

@ -1,6 +0,0 @@
import { Logger } from "./const";
import { ESPLoader } from "./esp_loader";
export type { Logger } from "./const";
export { ESPLoader } from "./esp_loader";
export { CHIP_FAMILY_ESP32, CHIP_FAMILY_ESP32S2, CHIP_FAMILY_ESP32S3, CHIP_FAMILY_ESP8266, CHIP_FAMILY_ESP32C3, CHIP_FAMILY_ESP32C6, CHIP_FAMILY_ESP32H2, } from "./const";
export declare const connect: (logger: Logger) => Promise<ESPLoader>;

12
dist/index.js vendored

@ -1,12 +0,0 @@
import { ESP_ROM_BAUD } from "./const";
import { ESPLoader } from "./esp_loader";
export { ESPLoader } from "./esp_loader";
export { CHIP_FAMILY_ESP32, CHIP_FAMILY_ESP32S2, CHIP_FAMILY_ESP32S3, CHIP_FAMILY_ESP8266, CHIP_FAMILY_ESP32C3, CHIP_FAMILY_ESP32C6, CHIP_FAMILY_ESP32H2, } from "./const";
export const connect = async (logger) => {
// - Request a port and open a connection.
const port = await navigator.serial.requestPort();
logger.log("Connecting...");
await port.open({ baudRate: ESP_ROM_BAUD });
logger.log("Connected successfully.");
return new ESPLoader(port, logger);
};

2
dist/struct.d.ts vendored

@ -1,2 +0,0 @@
export declare const pack: (format: string, ...data: number[]) => number[];
export declare const unpack: (format: string, bytes: number[]) => number[];

105
dist/struct.js vendored

@ -1,105 +0,0 @@
const lut = {
b: { u: DataView.prototype.getInt8, p: DataView.prototype.setInt8, bytes: 1 },
B: {
u: DataView.prototype.getUint8,
p: DataView.prototype.setUint8,
bytes: 1,
},
h: {
u: DataView.prototype.getInt16,
p: DataView.prototype.setInt16,
bytes: 2,
},
H: {
u: DataView.prototype.getUint16,
p: DataView.prototype.setUint16,
bytes: 2,
},
i: {
u: DataView.prototype.getInt32,
p: DataView.prototype.setInt32,
bytes: 4,
},
I: {
u: DataView.prototype.getUint32,
p: DataView.prototype.setUint32,
bytes: 4,
},
q: {
// @ts-ignore
u: DataView.prototype.getInt64,
// @ts-ignore
p: DataView.prototype.setInt64,
bytes: 8,
},
Q: {
// @ts-ignore
u: DataView.prototype.getUint64,
// @ts-ignore
p: DataView.prototype.setUint64,
bytes: 8,
},
};
export const pack = (format, ...data) => {
let pointer = 0;
if (format.replace(/[<>]/, "").length != data.length) {
throw "Pack format to Argument count mismatch";
}
let bytes = [];
let littleEndian = true;
for (let i = 0; i < format.length; i++) {
if (format[i] == "<") {
littleEndian = true;
}
else if (format[i] == ">") {
littleEndian = false;
}
else {
pushBytes(format[i], data[pointer]);
pointer++;
}
}
function pushBytes(formatChar, value) {
if (!(formatChar in lut)) {
throw "Unhandled character '" + formatChar + "' in pack format";
}
let dataSize = lut[formatChar].bytes;
let view = new DataView(new ArrayBuffer(dataSize));
let dataViewFn = lut[formatChar].p.bind(view);
dataViewFn(0, value, littleEndian);
for (let i = 0; i < dataSize; i++) {
bytes.push(view.getUint8(i));
}
}
return bytes;
};
export const unpack = (format, bytes) => {
let pointer = 0;
let data = [];
let littleEndian = true;
for (let c of format) {
if (c == "<") {
littleEndian = true;
}
else if (c == ">") {
littleEndian = false;
}
else {
pushData(c);
}
}
function pushData(formatChar) {
if (!(formatChar in lut)) {
throw "Unhandled character '" + formatChar + "' in unpack format";
}
let dataSize = lut[formatChar].bytes;
let view = new DataView(new ArrayBuffer(dataSize));
for (let i = 0; i < dataSize; i++) {
view.setUint8(i, bytes[pointer + i] & 0xff);
}
let dataViewFn = lut[formatChar].u.bind(view);
data.push(dataViewFn(0, littleEndian));
pointer += dataSize;
}
return data;
};

@ -1,7 +0,0 @@
{
"entry": 1074521560,
"text": "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",
"text_start": 1074520064,
"data": "GOv8P9jnC0Bx6AtA8+wLQO3oC0CP6AtA7egLQEnpC0AG6gtAeOoLQCHqC0CB5wtAo+kLQPjpC0Bn6QtAmuoLQI7pC0Ca6gtAXegLQLPoC0Dt6AtASekLQHfoC0BM6wtAs+wLQKXmC0DX7AtApeYLQKXmC0Cl5gtApeYLQKXmC0Cl5gtApeYLQKXmC0Dz6gtApeYLQM3rC0Cz7AtA",
"data_start": 1073605544
}

@ -1,7 +0,0 @@
{
"entry": 1077413304,
"text": "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",
"text_start": 1077411840,
"data": "GGvKP+AIOEAsCThAhAk4QCgKOECUCjhAQgo4QKgHOEDkCThAJAo4QJgJOEBYBzhAzAk4QFgHOEC6CDhA/gg4QCwJOECECThAzAg4QBIIOEBCCDhAyAg4QOYMOEAsCThArAs4QJoMOECkBjhAxAw4QKQGOECkBjhApAY4QKQGOECkBjhApAY4QKQGOECkBjhASAs4QKQGOEDICzhAmgw4QA==",
"data_start": 1070295976
}

File diff suppressed because one or more lines are too long

@ -1,7 +0,0 @@
{
"entry": 1082132112,
"text": "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",
"text_start": 1082130432,
"data": "HCuEQEIKgECSCoBA6gqAQI4LgED6C4BAqAuAQA4JgEBKC4BAiguAQP4KgEC+CIBAMguAQL4IgEAcCoBAYgqAQJIKgEDqCoBALgqAQHIJgECiCYBAKgqAQEwOgECSCoBAEg2AQAQOgED+B4BALA6AQP4HgED+B4BA/geAQP4HgED+B4BA/geAQP4HgED+B4BArgyAQP4HgEAwDYBABA6AQA==",
"data_start": 1082469292
}

@ -1,7 +0,0 @@
{
"entry": 1082132112,
"text": "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",
"text_start": 1082130432,
"data": "HCuDQEIKgECSCoBA6gqAQI4LgED6C4BAqAuAQA4JgEBKC4BAiguAQP4KgEC+CIBAMguAQL4IgEAcCoBAYgqAQJIKgEDqCoBALgqAQHIJgECiCYBAKgqAQEwOgECSCoBAEg2AQAQOgED+B4BALA6AQP4HgED+B4BA/geAQP4HgED+B4BA/geAQP4HgED+B4BArgyAQP4HgEAwDYBABA6AQA==",
"data_start": 1082403756
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,10 +0,0 @@
import { ChipFamily } from "../const";
interface Stub {
text: number[];
data: number[];
text_start: number;
entry: number;
data_start: number;
}
export declare const getStubCode: (chipFamily: ChipFamily) => Promise<Stub>;
export {};

@ -1,35 +0,0 @@
import { CHIP_FAMILY_ESP32, CHIP_FAMILY_ESP32S2, CHIP_FAMILY_ESP32S3, CHIP_FAMILY_ESP8266, CHIP_FAMILY_ESP32C2, CHIP_FAMILY_ESP32C3, CHIP_FAMILY_ESP32C6, CHIP_FAMILY_ESP32H2 } from "../const";
import { toByteArray } from "../util";
export const getStubCode = async (chipFamily) => {
let stubcode;
if (chipFamily == CHIP_FAMILY_ESP32) {
stubcode = await import("./esp32.json");
}
else if (chipFamily == CHIP_FAMILY_ESP32S2) {
stubcode = await import("./esp32s2.json");
}
else if (chipFamily == CHIP_FAMILY_ESP32S3) {
stubcode = await import("./esp32s3.json");
}
else if (chipFamily == CHIP_FAMILY_ESP8266) {
stubcode = await import("./esp8266.json");
}
else if (chipFamily == CHIP_FAMILY_ESP32C2) {
stubcode = await import("./esp32c2.json");
}
else if (chipFamily == CHIP_FAMILY_ESP32C3) {
stubcode = await import("./esp32c3.json");
}
else if (chipFamily == CHIP_FAMILY_ESP32C6) {
stubcode = await import("./esp32c6.json");
}
else if (chipFamily == CHIP_FAMILY_ESP32H2) {
stubcode = await import("./esp32h2.json");
}
// Base64 decode the text and data
return {
...stubcode,
text: toByteArray(atob(stubcode.text)),
data: toByteArray(atob(stubcode.data)),
};
};

14
dist/util.d.ts vendored

@ -1,14 +0,0 @@
/**
* @name slipEncode
* Take an array buffer and return back a new array where
* 0xdb is replaced with 0xdb 0xdd and 0xc0 is replaced with 0xdb 0xdc
*/
export declare const slipEncode: (buffer: number[]) => number[];
/**
* @name toByteArray
* Convert a string to a byte array
*/
export declare const toByteArray: (str: string) => number[];
export declare const hexFormatter: (bytes: number[]) => string;
export declare const toHex: (value: number, size?: number) => string;
export declare const sleep: (ms: number) => Promise<unknown>;

46
dist/util.js vendored

@ -1,46 +0,0 @@
/**
* @name slipEncode
* Take an array buffer and return back a new array where
* 0xdb is replaced with 0xdb 0xdd and 0xc0 is replaced with 0xdb 0xdc
*/
export const slipEncode = (buffer) => {
let encoded = [0xc0];
for (let byte of buffer) {
if (byte == 0xdb) {
encoded = encoded.concat([0xdb, 0xdd]);
}
else if (byte == 0xc0) {
encoded = encoded.concat([0xdb, 0xdc]);
}
else {
encoded.push(byte);
}
}
encoded.push(0xc0);
return encoded;
};
/**
* @name toByteArray
* Convert a string to a byte array
*/
export const toByteArray = (str) => {
let byteArray = [];
for (let i = 0; i < str.length; i++) {
let charcode = str.charCodeAt(i);
if (charcode <= 0xff) {
byteArray.push(charcode);
}
}
return byteArray;
};
export const hexFormatter = (bytes) => "[" + bytes.map((value) => toHex(value)).join(", ") + "]";
export const toHex = (value, size = 2) => {
let hex = value.toString(16).toUpperCase();
if (hex.startsWith("-")) {
return "-0x" + hex.substring(1).padStart(size, "0");
}
else {
return "0x" + hex.padStart(size, "0");
}
};
export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

8203
dist/web/index.js vendored

File diff suppressed because it is too large Load Diff

@ -32,16 +32,6 @@
class="alternate"
disabled
/>
<!-- import the webpage's javascript file -->
<!--<script module>
window.esptoolPackage = import(
// In development we import locally.
window.location.hostname === "localhost"
? "/dist/web/index.js"
: "https://cdn.jsdelivr.net/gh/adafruit/Adafruit_WebSerial_ESPTool@latest/dist/web/index.js"
);
</script>-->
<script type="module" src="js/script.js" defer></script>
</head>
<body>

@ -1,4 +1,3 @@
import { ESPLoader, Transport } from "https://unpkg.com/esptool-js/bundle.js";
const baudRates = [921600, 115200, 230400, 460800];
@ -246,22 +245,6 @@ async function clickErase() {
* Click handler for the program button.
*/
async function clickProgram() {
const readUploadedFileAsArrayBuffer = (inputFile) => {
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onerror = () => {
reader.abort();
reject(new DOMException("Problem parsing input file."));
};
reader.onload = () => {
resolve(reader.result);
};
reader.readAsArrayBuffer(inputFile);
});
};
const readUploadedFileAsBinaryString = (inputFile) => {
const reader = new FileReader();

@ -1,148 +0,0 @@
/**
* @name toByteArray
* Convert a string to a byte array
*/
function toByteArray(str) {
let byteArray = [];
for (let i = 0; i < str.length; i++) {
let charcode = str.charCodeAt(i);
if (charcode <= 0xFF) {
byteArray.push(charcode);
}
}
return byteArray;
}
function fromByteArray(byteArray) {
return String.fromCharCode.apply(String, byteArray);
}
function crc32(data, value=0) {
if (data instanceof Array) {
data = fromByteArray(data);
}
let table = [];
for(let entry, c = 0; c < 256; c++) {
entry = c;
for(let k = 0; k < 8; k++) {
entry = 1 & entry ? 3988292384^entry >>> 1 : entry >>> 1;
}
table[c] = entry;
}
let n = -1 - value;
for(let t = 0; t < data.length; t++) {
n = n >>> 8^table[255 & (n^data.charCodeAt(t))];
}
return (-1 ^ n) >>> 0;
}
function zipLongest() {
var args = [].slice.call(arguments);
var longest = args.reduce(function(a,b){
return a.length > b.length ? a : b
}, []);
return longest.map(function(_,i){
return args.map(function(array){return array[i]})
});
}
class struct {
static lut = {
"b": {u: DataView.prototype.getInt8, p: DataView.prototype.setInt8, bytes: 1},
"B": {u: DataView.prototype.getUint8, p: DataView.prototype.setUint8, bytes: 1},
"h": {u: DataView.prototype.getInt16, p: DataView.prototype.setInt16, bytes: 2},
"H": {u: DataView.prototype.getUint16, p: DataView.prototype.setUint16, bytes: 2},
"i": {u: DataView.prototype.getInt32, p: DataView.prototype.setInt32, bytes: 4},
"I": {u: DataView.prototype.getUint32, p: DataView.prototype.setUint32, bytes: 4},
"q": {u: DataView.prototype.getInt64, p: DataView.prototype.setInt64, bytes: 8},
"Q": {u: DataView.prototype.getUint64, p: DataView.prototype.setUint64, bytes: 8},
}
static pack(...args) {
let format = args[0];
let pointer = 0;
let data = args.slice(1);
if (format.replace(/[<>]/, '').length != data.length) {
throw("Pack format to Argument count mismatch");
return;
}
let bytes = [];
let littleEndian = true;
for (let i = 0; i < format.length; i++) {
if (format[i] == "<") {
littleEndian = true;
} else if (format[i] == ">") {
littleEndian = false;
} else {
pushBytes(format[i], data[pointer]);
pointer++;
}
}
function pushBytes(formatChar, value) {
if (!(formatChar in struct.lut)) {
throw("Unhandled character '" + formatChar + "' in pack format");
}
let dataSize = struct.lut[formatChar].bytes;
let view = new DataView(new ArrayBuffer(dataSize));
let dataViewFn = struct.lut[formatChar].p.bind(view);
dataViewFn(0, value, littleEndian);
for (let i = 0; i < dataSize; i++) {
bytes.push(view.getUint8(i));
}
}
return bytes;
};
static unpack(format, bytes) {
let pointer = 0;
let data = [];
let littleEndian = true;
for (let c of format) {
if (c == "<") {
littleEndian = true;
} else if (c == ">") {
littleEndian = false;
} else {
pushData(c);
}
}
function pushData(formatChar) {
if (!(formatChar in struct.lut)) {
throw("Unhandled character '" + formatChar + "' in unpack format");
}
let dataSize = struct.lut[formatChar].bytes;
let view = new DataView(new ArrayBuffer(dataSize));
for (let i = 0; i < dataSize; i++) {
view.setUint8(i, bytes[pointer + i] & 0xFF);
}
let dataViewFn = struct.lut[formatChar].u.bind(view);
data.push(dataViewFn(0, littleEndian));
pointer += dataSize;
}
return data;
};
static calcsize(format) {
let size = 0;
for (let i = 0; i < format.length; i++) {
if (format[i] != "<" && format[i] != ">") {
size += struct.lut[format[i]].bytes;
}
}
return size;
}
}
function* makeFileIterator(content) {
for (let line of content.split(/\r?\n/)) {
yield line.trim();
}
return '';
}

1751
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,37 +0,0 @@
{
"name": "@adafruit/adafruit-webserial-esptool",
"version": "6.0.0",
"description": "Flash ESP devices using WebSerial",
"main": "dist/index.js",
"repository": {
"type": "git",
"url": "git://github.com/adafruit/Adafruit_WebSerial_ESPTool.git"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"author": "Melissa LeBlanc-Williams",
"license": "MIT",
"type": "module",
"scripts": {
"prepublishOnly": "script/build"
},
"devDependencies": {
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.1",
"@types/pako": "^2.0.3",
"@types/w3c-web-serial": "^1.0.7",
"prettier": "^3.3.3",
"rollup": "^4.25.0",
"serve": "^14.2.4",
"typescript": "^5.6.3"
},
"dependencies": {
"@types/node": "^22.9.0",
"esptool-js": "^0.4.7",
"pako": "^2.1.0",
"tslib": "^2.8.1"
}
}

@ -1,27 +0,0 @@
import { nodeResolve } from "@rollup/plugin-node-resolve";
import json from "@rollup/plugin-json";
import terser from "@rollup/plugin-terser";
const config = {
input: "dist/index.js",
output: {
dir: "dist/web",
format: "module",
},
// preserveEntrySignatures: false,
plugins: [nodeResolve(), json()],
};
if (process.env.NODE_ENV === "production") {
config.plugins.push(
terser({
ecma: 2019,
toplevel: true,
output: {
comments: false,
},
})
);
}
export default config;

@ -1,8 +0,0 @@
# Stop on errors
set -e
cd "$(dirname "$0")/.."
rm -rf dist
NODE_ENV=production npm exec -- tsc
NODE_ENV=production npm exec -- rollup -c

@ -1,17 +1,17 @@
# Stop on errors
set -e
cd "$(dirname "$0")/.."
#cd "$(dirname "$0")/.."
rm -rf dist
#rm -rf dist
# Quit all background tasks when script exits
trap "kill 0" EXIT
# Run tsc once as rollup expects those files
npm exec -- tsc || true
npm exec -- rollup -c
#npm exec -- tsc || true
#npm exec -- rollup -c
npm exec -- tsc --watch &
#npm exec -- tsc --watch &
npm exec -- serve -p 5004 &
wait

@ -1,398 +0,0 @@
import { toByteArray } from "./util";
export interface Logger {
log(msg: string, ...args: any[]): void;
error(msg: string, ...args: any[]): void;
debug(msg: string, ...args: any[]): void;
}
export const baudRates = [
115200, 128000, 153600, 230400, 460800, 921600, 1500000, 2000000,
];
export const FLASH_SIZES = {
"512KB": 0x00,
"256KB": 0x10,
"1MB": 0x20,
"2MB": 0x30,
"4MB": 0x40,
"2MB-c1": 0x50,
"4MB-c1": 0x60,
"8MB": 0x80,
"16MB": 0x90,
};
export const ESP32_FLASH_SIZES = {
"1MB": 0x00,
"2MB": 0x10,
"4MB": 0x20,
"8MB": 0x30,
"16MB": 0x40,
"32MB": 0x50,
"64MB": 0x60,
"128MB": 0x70,
};
interface FlashSize {
[key: number]: string;
}
export const DETECTED_FLASH_SIZES: FlashSize = {
0x12: "256KB",
0x13: "512KB",
0x14: "1MB",
0x15: "2MB",
0x16: "4MB",
0x17: "8MB",
0x18: "16MB",
0x19: "32MB",
0x1a: "64MB",
};
export const FLASH_WRITE_SIZE = 0x400;
export const STUB_FLASH_WRITE_SIZE = 0x4000;
export const FLASH_SECTOR_SIZE = 0x1000; // Flash sector size, minimum unit of erase.
export const ESP_ROM_BAUD = 115200;
export const USB_JTAG_SERIAL_PID = 0x1001;
export const ESP8266_SPI_REG_BASE = 0x60000200;
export const ESP8266_BASEFUSEADDR = 0x3ff00050;
export const ESP8266_MACFUSEADDR = 0x3ff00050;
export const ESP8266_SPI_USR_OFFS = 0x1c;
export const ESP8266_SPI_USR1_OFFS = 0x20;
export const ESP8266_SPI_USR2_OFFS = 0x24;
export const ESP8266_SPI_MOSI_DLEN_OFFS = -1;
export const ESP8266_SPI_MISO_DLEN_OFFS = -1;
export const ESP8266_SPI_W0_OFFS = 0x40;
export const ESP8266_UART_DATE_REG_ADDR = 0x60000078;
export const ESP8266_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32_SPI_REG_BASE = 0x3ff42000;
export const ESP32_BASEFUSEADDR = 0x3ff5a000;
export const ESP32_MACFUSEADDR = 0x3ff5a000;
export const ESP32_SPI_USR_OFFS = 0x1c;
export const ESP32_SPI_USR1_OFFS = 0x20;
export const ESP32_SPI_USR2_OFFS = 0x24;
export const ESP32_SPI_MOSI_DLEN_OFFS = 0x28;
export const ESP32_SPI_MISO_DLEN_OFFS = 0x2c;
export const ESP32_SPI_W0_OFFS = 0x80;
export const ESP32_UART_DATE_REG_ADDR = 0x60000078;
export const ESP32_BOOTLOADER_FLASH_OFFSET = 0x1000;
export const ESP32S2_SPI_REG_BASE = 0x3f402000;
export const ESP32S2_BASEFUSEADDR = 0x3f41a000;
export const ESP32S2_MACFUSEADDR = 0x3f41a044;
export const ESP32S2_SPI_USR_OFFS = 0x18;
export const ESP32S2_SPI_USR1_OFFS = 0x1c;
export const ESP32S2_SPI_USR2_OFFS = 0x20;
export const ESP32S2_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32S2_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32S2_SPI_W0_OFFS = 0x58;
export const ESP32S2_UART_DATE_REG_ADDR = 0x60000078;
export const ESP32S2_BOOTLOADER_FLASH_OFFSET = 0x1000;
export const ESP32S3_SPI_REG_BASE = 0x60002000;
export const ESP32S3_BASEFUSEADDR = 0x60007000;
export const ESP32S3_MACFUSEADDR = 0x60007000 + 0x044;
export const ESP32S3_SPI_USR_OFFS = 0x18;
export const ESP32S3_SPI_USR1_OFFS = 0x1c;
export const ESP32S3_SPI_USR2_OFFS = 0x20;
export const ESP32S3_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32S3_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32S3_SPI_W0_OFFS = 0x58;
export const ESP32S3_UART_DATE_REG_ADDR = 0x60000080;
export const ESP32S3_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32C2_SPI_REG_BASE = 0x60002000;
export const ESP32C2_BASEFUSEADDR = 0x60008800;
export const ESP32C2_MACFUSEADDR = 0x60008800 + 0x044;
export const ESP32C2_SPI_USR_OFFS = 0x18;
export const ESP32C2_SPI_USR1_OFFS = 0x1c;
export const ESP32C2_SPI_USR2_OFFS = 0x20;
export const ESP32C2_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32C2_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32C2_SPI_W0_OFFS = 0x58;
export const ESP32C2_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32C2_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32C3_SPI_REG_BASE = 0x60002000;
export const ESP32C3_BASEFUSEADDR = 0x60008800;
export const ESP32C3_MACFUSEADDR = 0x60008800 + 0x044;
export const ESP32C3_SPI_USR_OFFS = 0x18;
export const ESP32C3_SPI_USR1_OFFS = 0x1c;
export const ESP32C3_SPI_USR2_OFFS = 0x20;
export const ESP32C3_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32C3_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32C3_SPI_W0_OFFS = 0x58;
export const ESP32C3_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32C3_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32C6_SPI_REG_BASE = 0x60003000;
export const ESP32C6_BASEFUSEADDR = 0x600b0800;
export const ESP32C6_MACFUSEADDR = 0x600b0800 + 0x044;
export const ESP32C6_SPI_USR_OFFS = 0x18;
export const ESP32C6_SPI_USR1_OFFS = 0x1c;
export const ESP32C6_SPI_USR2_OFFS = 0x20;
export const ESP32C6_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32C6_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32C6_SPI_W0_OFFS = 0x58;
export const ESP32C6_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32C6_BOOTLOADER_FLASH_OFFSET = 0x0;
export const ESP32H2_SPI_REG_BASE = 0x60002000;
export const ESP32H2_BASEFUSEADDR = 0x6001a000;
export const ESP32H2_MACFUSEADDR = 0x6001a000 + 0x044;
export const ESP32H2_SPI_USR_OFFS = 0x18;
export const ESP32H2_SPI_USR1_OFFS = 0x1c;
export const ESP32H2_SPI_USR2_OFFS = 0x20;
export const ESP32H2_SPI_MOSI_DLEN_OFFS = 0x24;
export const ESP32H2_SPI_MISO_DLEN_OFFS = 0x28;
export const ESP32H2_SPI_W0_OFFS = 0x58;
export const ESP32H2_UART_DATE_REG_ADDR = 0x6000007c;
export const ESP32H2_BOOTLOADER_FLASH_OFFSET = 0x0;
export interface SpiFlashAddresses {
regBase: number;
baseFuse: number;
macFuse: number;
usrOffs: number;
usr1Offs: number;
usr2Offs: number;
mosiDlenOffs: number;
misoDlenOffs: number;
w0Offs: number;
uartDateReg: number;
flashOffs: number;
}
export const SYNC_PACKET = toByteArray(
"\x07\x07\x12 UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
);
export const CHIP_DETECT_MAGIC_REG_ADDR = 0x40001000;
// These values for the families are made up; nothing that esptool uses.
export const CHIP_FAMILY_ESP8266 = 0x8266;
export const CHIP_FAMILY_ESP32 = 0x32;
export const CHIP_FAMILY_ESP32S2 = 0x3252;
export const CHIP_FAMILY_ESP32S3 = 0x3253;
export const CHIP_FAMILY_ESP32C2 = 0x32c2;
export const CHIP_FAMILY_ESP32C3 = 0x32c3;
export const CHIP_FAMILY_ESP32C6 = 0x32c6;
export const CHIP_FAMILY_ESP32H2 = 0x3272;
export type ChipFamily =
| typeof CHIP_FAMILY_ESP8266
| typeof CHIP_FAMILY_ESP32
| typeof CHIP_FAMILY_ESP32S2
| typeof CHIP_FAMILY_ESP32S3
| typeof CHIP_FAMILY_ESP32C2
| typeof CHIP_FAMILY_ESP32C3
| typeof CHIP_FAMILY_ESP32C6
| typeof CHIP_FAMILY_ESP32H2;
interface ChipInfo {
[magicValue: number]: {
name: string;
family: ChipFamily;
};
}
export const CHIP_DETECT_MAGIC_VALUES: ChipInfo = {
0xfff0c101: { name: "ESP8266", family: CHIP_FAMILY_ESP8266 },
0x00f01d83: { name: "ESP32", family: CHIP_FAMILY_ESP32 },
0x000007c6: { name: "ESP32-S2", family: CHIP_FAMILY_ESP32S2 },
0x9: { name: "ESP32-S3", family: CHIP_FAMILY_ESP32S3 },
0xeb004136: { name: "ESP32-S3(beta2)", family: CHIP_FAMILY_ESP32S3 },
0x6f51306f: { name: "ESP32-C2", family: CHIP_FAMILY_ESP32C2 },
0x7c41a06f: { name: "ESP32-C2", family: CHIP_FAMILY_ESP32C2 },
0x6921506f: { name: "ESP32-C3", family: CHIP_FAMILY_ESP32C3 },
0x1b31506f: { name: "ESP32-C3", family: CHIP_FAMILY_ESP32C3 },
0xd7b73e80: { name: "ESP32-H2", family: CHIP_FAMILY_ESP32H2 },
0x0da1806f: { name: "ESP32-C6(beta)", family: CHIP_FAMILY_ESP32C6 },
0x2ce0806f: { name: "ESP32-C6", family: CHIP_FAMILY_ESP32C6 },
};
// Commands supported by ESP8266 ROM bootloader
export const ESP_FLASH_BEGIN = 0x02;
export const ESP_FLASH_DATA = 0x03;
export const ESP_FLASH_END = 0x04;
export const ESP_MEM_BEGIN = 0x05;
export const ESP_MEM_END = 0x06;
export const ESP_MEM_DATA = 0x07;
export const ESP_SYNC = 0x08;
export const ESP_WRITE_REG = 0x09;
export const ESP_READ_REG = 0x0a;
export const ESP_ERASE_FLASH = 0xd0;
export const ESP_ERASE_REGION = 0xd1;
export const ESP_SPI_SET_PARAMS = 0x0b;
export const ESP_SPI_ATTACH = 0x0d;
export const ESP_CHANGE_BAUDRATE = 0x0f;
export const ESP_SPI_FLASH_MD5 = 0x13;
export const ESP_CHECKSUM_MAGIC = 0xef;
export const ESP_FLASH_DEFL_BEGIN = 0x10;
export const ESP_FLASH_DEFL_DATA = 0x11;
export const ESP_FLASH_DEFL_END = 0x12;
export const ROM_INVALID_RECV_MSG = 0x05;
export const USB_RAM_BLOCK = 0x800;
export const ESP_RAM_BLOCK = 0x1800;
// Timeouts
export const DEFAULT_TIMEOUT = 3000;
export const CHIP_ERASE_TIMEOUT = 600000; // timeout for full chip erase in ms
export const MAX_TIMEOUT = CHIP_ERASE_TIMEOUT * 2; // longest any command can run in ms
export const SYNC_TIMEOUT = 100; // timeout for syncing with bootloader in ms
export const ERASE_REGION_TIMEOUT_PER_MB = 30000; // timeout (per megabyte) for erasing a region in ms
export const MEM_END_ROM_TIMEOUT = 500;
/**
* @name timeoutPerMb
* Scales timeouts which are size-specific
*/
export const timeoutPerMb = (secondsPerMb: number, sizeBytes: number) => {
let result = Math.floor(secondsPerMb * (sizeBytes / 0x1e6));
if (result < DEFAULT_TIMEOUT) {
return DEFAULT_TIMEOUT;
}
return result;
};
export const getSpiFlashAddresses = (
chipFamily: ChipFamily,
): SpiFlashAddresses => {
switch (chipFamily) {
case CHIP_FAMILY_ESP32:
return {
regBase: ESP32_SPI_REG_BASE,
baseFuse: ESP32_BASEFUSEADDR,
macFuse: ESP32_MACFUSEADDR,
usrOffs: ESP32_SPI_USR_OFFS,
usr1Offs: ESP32_SPI_USR1_OFFS,
usr2Offs: ESP32_SPI_USR2_OFFS,
mosiDlenOffs: ESP32_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32_SPI_W0_OFFS,
uartDateReg: ESP32_UART_DATE_REG_ADDR,
flashOffs: ESP32_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32S2:
return {
regBase: ESP32S2_SPI_REG_BASE,
baseFuse: ESP32S2_BASEFUSEADDR,
macFuse: ESP32S2_MACFUSEADDR,
usrOffs: ESP32S2_SPI_USR_OFFS,
usr1Offs: ESP32S2_SPI_USR1_OFFS,
usr2Offs: ESP32S2_SPI_USR2_OFFS,
mosiDlenOffs: ESP32S2_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32S2_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32S2_SPI_W0_OFFS,
uartDateReg: ESP32S2_UART_DATE_REG_ADDR,
flashOffs: ESP32S2_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32S3:
return {
regBase: ESP32S3_SPI_REG_BASE,
usrOffs: ESP32S3_SPI_USR_OFFS,
baseFuse: ESP32S3_BASEFUSEADDR,
macFuse: ESP32S3_MACFUSEADDR,
usr1Offs: ESP32S3_SPI_USR1_OFFS,
usr2Offs: ESP32S3_SPI_USR2_OFFS,
mosiDlenOffs: ESP32S3_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32S3_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32S3_SPI_W0_OFFS,
uartDateReg: ESP32S3_UART_DATE_REG_ADDR,
flashOffs: ESP32S3_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP8266:
return {
regBase: ESP8266_SPI_REG_BASE,
usrOffs: ESP8266_SPI_USR_OFFS,
baseFuse: ESP8266_BASEFUSEADDR,
macFuse: ESP8266_MACFUSEADDR,
usr1Offs: ESP8266_SPI_USR1_OFFS,
usr2Offs: ESP8266_SPI_USR2_OFFS,
mosiDlenOffs: ESP8266_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP8266_SPI_MISO_DLEN_OFFS,
w0Offs: ESP8266_SPI_W0_OFFS,
uartDateReg: ESP8266_UART_DATE_REG_ADDR,
flashOffs: ESP8266_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32C2:
return {
regBase: ESP32C2_SPI_REG_BASE,
baseFuse: ESP32C2_BASEFUSEADDR,
macFuse: ESP32C2_MACFUSEADDR,
usrOffs: ESP32C2_SPI_USR_OFFS,
usr1Offs: ESP32C2_SPI_USR1_OFFS,
usr2Offs: ESP32C2_SPI_USR2_OFFS,
mosiDlenOffs: ESP32C2_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32C2_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32C2_SPI_W0_OFFS,
uartDateReg: ESP32C2_UART_DATE_REG_ADDR,
flashOffs: ESP32C2_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32C3:
return {
regBase: ESP32C3_SPI_REG_BASE,
baseFuse: ESP32C3_BASEFUSEADDR,
macFuse: ESP32C3_MACFUSEADDR,
usrOffs: ESP32C3_SPI_USR_OFFS,
usr1Offs: ESP32C3_SPI_USR1_OFFS,
usr2Offs: ESP32C3_SPI_USR2_OFFS,
mosiDlenOffs: ESP32C3_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32C3_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32C3_SPI_W0_OFFS,
uartDateReg: ESP32C3_UART_DATE_REG_ADDR,
flashOffs: ESP32C3_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32C6:
return {
regBase: ESP32C6_SPI_REG_BASE,
baseFuse: ESP32C6_BASEFUSEADDR,
macFuse: ESP32C6_MACFUSEADDR,
usrOffs: ESP32C6_SPI_USR_OFFS,
usr1Offs: ESP32C6_SPI_USR1_OFFS,
usr2Offs: ESP32C6_SPI_USR2_OFFS,
mosiDlenOffs: ESP32C6_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32C6_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32C6_SPI_W0_OFFS,
uartDateReg: ESP32C6_UART_DATE_REG_ADDR,
flashOffs: ESP32C6_BOOTLOADER_FLASH_OFFSET,
};
case CHIP_FAMILY_ESP32H2:
return {
regBase: ESP32H2_SPI_REG_BASE,
baseFuse: ESP32H2_BASEFUSEADDR,
macFuse: ESP32H2_MACFUSEADDR,
usrOffs: ESP32H2_SPI_USR_OFFS,
usr1Offs: ESP32H2_SPI_USR1_OFFS,
usr2Offs: ESP32H2_SPI_USR2_OFFS,
mosiDlenOffs: ESP32H2_SPI_MOSI_DLEN_OFFS,
misoDlenOffs: ESP32H2_SPI_MISO_DLEN_OFFS,
w0Offs: ESP32H2_SPI_W0_OFFS,
uartDateReg: ESP32H2_UART_DATE_REG_ADDR,
flashOffs: ESP32H2_BOOTLOADER_FLASH_OFFSET,
};
default:
return {
regBase: -1,
baseFuse: -1,
macFuse: -1,
usrOffs: -1,
usr1Offs: -1,
usr2Offs: -1,
mosiDlenOffs: -1,
misoDlenOffs: -1,
w0Offs: -1,
uartDateReg: -1,
flashOffs: -1,
};
}
};
export class SlipReadError extends Error {
constructor(message: string) {
super(message);
this.name = "SlipReadError";
}
}

File diff suppressed because it is too large Load Diff

@ -1,27 +0,0 @@
import { ESP_ROM_BAUD, Logger } from "./const";
import { ESPLoader } from "./esp_loader";
export type { Logger } from "./const";
export { ESPLoader } from "./esp_loader";
export {
CHIP_FAMILY_ESP32,
CHIP_FAMILY_ESP32S2,
CHIP_FAMILY_ESP32S3,
CHIP_FAMILY_ESP8266,
CHIP_FAMILY_ESP32C3,
CHIP_FAMILY_ESP32C6,
CHIP_FAMILY_ESP32H2,
} from "./const";
export const connect = async (logger: Logger) => {
// - Request a port and open a connection.
const port = await navigator.serial.requestPort();
logger.log("Connecting...");
await port.open({ baudRate: ESP_ROM_BAUD });
logger.log("Connected successfully.");
return new ESPLoader(port, logger);
};

@ -1,115 +0,0 @@
interface DataType {
[key: string]: {
u: Function;
p: Function;
bytes: number;
};
}
const lut: DataType = {
b: { u: DataView.prototype.getInt8, p: DataView.prototype.setInt8, bytes: 1 },
B: {
u: DataView.prototype.getUint8,
p: DataView.prototype.setUint8,
bytes: 1,
},
h: {
u: DataView.prototype.getInt16,
p: DataView.prototype.setInt16,
bytes: 2,
},
H: {
u: DataView.prototype.getUint16,
p: DataView.prototype.setUint16,
bytes: 2,
},
i: {
u: DataView.prototype.getInt32,
p: DataView.prototype.setInt32,
bytes: 4,
},
I: {
u: DataView.prototype.getUint32,
p: DataView.prototype.setUint32,
bytes: 4,
},
q: {
// @ts-ignore
u: DataView.prototype.getInt64,
// @ts-ignore
p: DataView.prototype.setInt64,
bytes: 8,
},
Q: {
// @ts-ignore
u: DataView.prototype.getUint64,
// @ts-ignore
p: DataView.prototype.setUint64,
bytes: 8,
},
};
export const pack = (format: string, ...data: number[]) => {
let pointer = 0;
if (format.replace(/[<>]/, "").length != data.length) {
throw "Pack format to Argument count mismatch";
}
let bytes: number[] = [];
let littleEndian = true;
for (let i = 0; i < format.length; i++) {
if (format[i] == "<") {
littleEndian = true;
} else if (format[i] == ">") {
littleEndian = false;
} else {
pushBytes(format[i], data[pointer]);
pointer++;
}
}
function pushBytes(formatChar: string, value: number) {
if (!(formatChar in lut)) {
throw "Unhandled character '" + formatChar + "' in pack format";
}
let dataSize = lut[formatChar].bytes;
let view = new DataView(new ArrayBuffer(dataSize));
let dataViewFn = lut[formatChar].p.bind(view);
dataViewFn(0, value, littleEndian);
for (let i = 0; i < dataSize; i++) {
bytes.push(view.getUint8(i));
}
}
return bytes;
};
export const unpack = (format: string, bytes: number[]) => {
let pointer = 0;
let data: number[] = [];
let littleEndian = true;
for (let c of format) {
if (c == "<") {
littleEndian = true;
} else if (c == ">") {
littleEndian = false;
} else {
pushData(c);
}
}
function pushData(formatChar: string) {
if (!(formatChar in lut)) {
throw "Unhandled character '" + formatChar + "' in unpack format";
}
let dataSize = lut[formatChar].bytes;
let view = new DataView(new ArrayBuffer(dataSize));
for (let i = 0; i < dataSize; i++) {
view.setUint8(i, bytes[pointer + i] & 0xff);
}
let dataViewFn = lut[formatChar].u.bind(view);
data.push(dataViewFn(0, littleEndian));
pointer += dataSize;
}
return data;
};

@ -1,7 +0,0 @@
{
"entry": 1074521560,
"text": "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",
"text_start": 1074520064,
"data": "GOv8P9jnC0Bx6AtA8+wLQO3oC0CP6AtA7egLQEnpC0AG6gtAeOoLQCHqC0CB5wtAo+kLQPjpC0Bn6QtAmuoLQI7pC0Ca6gtAXegLQLPoC0Dt6AtASekLQHfoC0BM6wtAs+wLQKXmC0DX7AtApeYLQKXmC0Cl5gtApeYLQKXmC0Cl5gtApeYLQKXmC0Dz6gtApeYLQM3rC0Cz7AtA",
"data_start": 1073605544
}

@ -1,7 +0,0 @@
{
"entry": 1077413304,
"text": "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",
"text_start": 1077411840,
"data": "GGvKP+AIOEAsCThAhAk4QCgKOECUCjhAQgo4QKgHOEDkCThAJAo4QJgJOEBYBzhAzAk4QFgHOEC6CDhA/gg4QCwJOECECThAzAg4QBIIOEBCCDhAyAg4QOYMOEAsCThArAs4QJoMOECkBjhAxAw4QKQGOECkBjhApAY4QKQGOECkBjhApAY4QKQGOECkBjhASAs4QKQGOEDICzhAmgw4QA==",
"data_start": 1070295976
}

File diff suppressed because one or more lines are too long

@ -1,7 +0,0 @@
{
"entry": 1082132112,
"text": "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",
"text_start": 1082130432,
"data": "HCuEQEIKgECSCoBA6gqAQI4LgED6C4BAqAuAQA4JgEBKC4BAiguAQP4KgEC+CIBAMguAQL4IgEAcCoBAYgqAQJIKgEDqCoBALgqAQHIJgECiCYBAKgqAQEwOgECSCoBAEg2AQAQOgED+B4BALA6AQP4HgED+B4BA/geAQP4HgED+B4BA/geAQP4HgED+B4BArgyAQP4HgEAwDYBABA6AQA==",
"data_start": 1082469292
}

@ -1,7 +0,0 @@
{
"entry": 1082132112,
"text": "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",
"text_start": 1082130432,
"data": "HCuDQEIKgECSCoBA6gqAQI4LgED6C4BAqAuAQA4JgEBKC4BAiguAQP4KgEC+CIBAMguAQL4IgEAcCoBAYgqAQJIKgEDqCoBALgqAQHIJgECiCYBAKgqAQEwOgECSCoBAEg2AQAQOgED+B4BALA6AQP4HgED+B4BA/geAQP4HgED+B4BA/geAQP4HgED+B4BArgyAQP4HgEAwDYBABA6AQA==",
"data_start": 1082403756
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,57 +0,0 @@
import {
ChipFamily,
CHIP_FAMILY_ESP32,
CHIP_FAMILY_ESP32S2,
CHIP_FAMILY_ESP32S3,
CHIP_FAMILY_ESP8266,
CHIP_FAMILY_ESP32C2,
CHIP_FAMILY_ESP32C3,
CHIP_FAMILY_ESP32C6,
CHIP_FAMILY_ESP32H2
} from "../const";
import { toByteArray } from "../util";
interface LoadedStub {
text: string;
data: string;
text_start: number;
entry: number;
data_start: number;
}
interface Stub {
text: number[];
data: number[];
text_start: number;
entry: number;
data_start: number;
}
export const getStubCode = async (chipFamily: ChipFamily): Promise<Stub> => {
let stubcode!: LoadedStub;
if (chipFamily == CHIP_FAMILY_ESP32) {
stubcode = await import("./esp32.json");
} else if (chipFamily == CHIP_FAMILY_ESP32S2) {
stubcode = await import("./esp32s2.json");
} else if (chipFamily == CHIP_FAMILY_ESP32S3) {
stubcode = await import("./esp32s3.json");
} else if (chipFamily == CHIP_FAMILY_ESP8266) {
stubcode = await import("./esp8266.json");
} else if (chipFamily == CHIP_FAMILY_ESP32C2) {
stubcode = await import("./esp32c2.json");
} else if (chipFamily == CHIP_FAMILY_ESP32C3) {
stubcode = await import("./esp32c3.json");
} else if (chipFamily == CHIP_FAMILY_ESP32C6) {
stubcode = await import("./esp32c6.json");
} else if (chipFamily == CHIP_FAMILY_ESP32H2) {
stubcode = await import("./esp32h2.json");
}
// Base64 decode the text and data
return {
...stubcode,
text: toByteArray(atob(stubcode.text)),
data: toByteArray(atob(stubcode.data)),
};
};

@ -1,49 +0,0 @@
/**
* @name slipEncode
* Take an array buffer and return back a new array where
* 0xdb is replaced with 0xdb 0xdd and 0xc0 is replaced with 0xdb 0xdc
*/
export const slipEncode = (buffer: number[]): number[] => {
let encoded = [0xc0];
for (let byte of buffer) {
if (byte == 0xdb) {
encoded = encoded.concat([0xdb, 0xdd]);
} else if (byte == 0xc0) {
encoded = encoded.concat([0xdb, 0xdc]);
} else {
encoded.push(byte);
}
}
encoded.push(0xc0);
return encoded;
};
/**
* @name toByteArray
* Convert a string to a byte array
*/
export const toByteArray = (str: string): number[] => {
let byteArray: number[] = [];
for (let i = 0; i < str.length; i++) {
let charcode = str.charCodeAt(i);
if (charcode <= 0xff) {
byteArray.push(charcode);
}
}
return byteArray;
};
export const hexFormatter = (bytes: number[]) =>
"[" + bytes.map((value) => toHex(value)).join(", ") + "]";
export const toHex = (value: number, size = 2) => {
let hex = value.toString(16).toUpperCase();
if (hex.startsWith("-")) {
return "-0x" + hex.substring(1).padStart(size, "0");
} else {
return "0x" + hex.padStart(size, "0");
}
};
export const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));

@ -1,19 +0,0 @@
{
"compilerOptions": {
"lib": ["es2019", "dom"],
"target": "es2019",
"module": "es2020",
"moduleResolution": "node",
"resolveJsonModule": true,
"outDir": "dist",
"declaration": true,
"experimentalDecorators": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"importHelpers": true
},
"include": ["src/*"]
}
Loading…
Cancel
Save