Git Product home page Git Product logo

esptool-js's Introduction

Javascript implementation of esptool

This repository contains a Javascript implementation of esptool, a serial flasher utility for Espressif chips. esptool-js is based on Web Serial API and works in Google Chrome and Microsoft Edge version 89 or later browsers and Google Chrome on Android version 61 or later via the web-serial-polyfill compatibility layer.

NOTE: Unlike the Python-based esptool, esptool-js doesn't implement generation of binary images out of ELF files, and doesn't include companion tools similar to espefuse.py and espsecure.py.

Usage

CDN

https://unpkg.com/esptool-js/lib/index.js or https://unpkg.com/esptool-js/bundle.js to use the single bundle JavaScript file.

NPM

npm install --save esptool-js

Yarn

yarn add --save esptool-js

Check an example project here.

Nightly builds for ESPTOOL-JS

Define port filters for device using WebSerial

const portFilters: { usbVendorId?: number | undefined, usbProductId?: number | undefined }[] = [];
const device = await navigator.serial.requestPort({ filters: portFilters });

Inject a Terminal to use with esptool-js

// You can use any JavaScript compatible terminal by wrapping it in a helper object like this:
let espLoaderTerminal = {
  clean() {
    // Implement the clean function call for your terminal here.
  },
  writeLine(data) {
    // Implement the writeLine function call for your terminal here.
  },
  write(data) {
    // Implement the write function call for your terminal here.
  },
};

You can pass this terminal object to ESPLoader constructor as shown in the examples projects.

Live demo

Visit https://espressif.github.io/esptool-js/ to see this tool in action.

Testing it locally

npm install
npm run build
cd examples/typescript
npm install
npm run dev # Run local sever with example code

Then open http://localhost:1234 in a Chrome browser. The npm run build step builds the lib used in the example examples/typescript/index.html. Update this reference as described in Usage section.

Test from Pull Request artifact

If you are testing the main branch or any Pull Request (PR) artifact you can follow these steps:

  1. Get the esptool-js-<version>.tgz where <version> is the current version and download it.
  2. Add the following line to your project's package.json dependencies
"dependencies": {
  "esptool-js": "file:../path/to/esptool-js-<version>.tgz"
}
  1. Use the package like import "esptool-js/lib/index.js" when added in package.json as shown before.

License

The code in this repository is Copyright (c) 2023 Espressif Systems (Shanghai) Co. Ltd. It is licensed under Apache 2.0 license, as described in LICENSE file.

esptool-js's People

Contributors

adwait-esp avatar ameyinamdar avatar balloob avatar brianignacio5 avatar domagojk avatar dumbaspl avatar espressif-bot avatar igrr avatar jason2866 avatar lan-hekary avatar leoyan avatar linkedupbits avatar liux-pro avatar pkendall64 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esptool-js's Issues

Failed to upload stub when flashing ESP32-S2 via built-in USB_OTG

Uploading to the same ESP32-S2 via a CP2102 works okay, but with the built-in USB_OTG in download mode, fails as follows:

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x303a ProductID 0x2
Connecting..._connect_attempt default_reset false

Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

.Sync
538052359

Chip Magic 7c6
Detecting chip type... ESP32-S2
Chip is ESP32-S2
Features: Wi-Fi,ADC and temperature sensor calibration in BLK2 of efuse
Crystal is 40MHz
MAC: 7c:df:a1:0f:4d:6e
Uploading stub...
mem_begin 4316 1 6144 40028000
check_command enter RAM download mode
check_command write to target RAM
Error: Timeout

Chip type not detected

Testing on EDGE Version 102.0.1245.44, with both an ESP8266 and ESP32 board with both local and the hosted version - The chip type is not detected and returns a value of null.
image

Provide Support For All SerialOptions While Opening Port Of Device (Web Serial API)

Currently, only baudRate is supported by the connect method of Transport Class. However, the following options can also be passed when opening the port of the device. For more details, refer to this link:

  • dataBits: The number of data bits per frame (either 7 or 8).
  • stopBits: The number of stop bits at the end of a frame (either 1 or 2).
  • bufferSize: The parity mode (either "none", "even", or "odd").
  • parity: The size of the read and write buffer that should be created (must be less than 16MB).
  • flowControl: The flow control mode (either "none" or "hardware").

It will be beneficial for devices like ExpressLink, which has specific serial options configurations while opening the port.

Timeout uploading stub on ESP32-S2

I was testing out a few boards. Most are working great, but I'm having an issue with it timing out when uploading the stub on the ESP32-S2. I tried multiple times and at 115200 and 921600.

This was tested with an Adafruit MagTag and the combined.bin file in https://github.com/adafruit/tinyuf2/releases for the board.

Here's the error:
Screen Shot 2023-03-02 at 4 34 44 PM

Here's the Console:
Screen Shot 2023-03-02 at 4 43 53 PM

Thanks.

Decide on the testing strategy

There are a few options for setting up tests for esptool-js:

  1. Unit tests with a mocked serial port, similar to the ones in https://github.com/espressif/esp-serial-flasher/blob/a61f7449d7d3c4e63e5188c398b6ea1b1d35a002/test/test.cpp#L183-L239.
    • ➕ these tests should be very reliable
    • ➕ contributors can run the tests locally
    • ➖ these tests check only what was envisioned by the test author, which is good for detecting regressions but not so good at finding unknown problems
    • ➖ writing them usually requires some understanding of the underlying protocol
  2. Integration test against an emulator (such as QEMU), similar to https://github.com/espressif/esp-serial-flasher/blob/a61f7449d7d3c4e63e5188c398b6ea1b1d35a002/test/run_test.sh.
    • ➕ requires no understanding of the protocol (so e.g. I could write such a test)
    • ➕ contributors can run the tests locally (although less easy than the unit tests)
    • ➖ involves communication between processes, could be flaky
    • ➖ only the ESP32 chip is emulated in QEMU now
  3. Integration test against hardware, similar to https://github.com/espressif/esptool/blob/3f3d88a82477848b8fd055e73de33937aeb896e6/test/test_esptool.py#L349
    • ➕ requires no understanding of the protocol
    • ➕ checks against real hardware, which means a pretty good level of assurance
    • ➕ can run tests with chips which we don't have an emulator for
    • ➖ involves real hardware and a self-hosted CI runner, can be flaky for many reasons
    • ➖ extra maintenance cost for the self-hosted runner
    • ➖ tests running in PRs from forks might require approval to run
    • ➖ running such tests locally might be more tricky (need to manually test on multiple chips)

Unwanted debugging messages in the latest version

After the typescript rewrite, there are some additional debugging messages in the "terminal":

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x303a ProductID 0x1001
Connecting..._connect_attempt default_reset false

Sync
Sync err Error: Timeout

.Sync
538052359

Chip Magic 9
Detecting chip type... ESP32-S3
Chip is ESP32-S3
Features: Wi-Fi,BLE
Crystal is 40MHz
MAC: 7c:df:a1:e8:12:58
Uploading stub...
mem_begin 4820 1 6144 40378000
check_command enter RAM download mode
check_command write to target RAM
mem_begin 4 1 6144 3fcb2bf4
check_command enter RAM download mode
check_command write to target RAM
Running stub...
check_command leave RAM download mode
Stub running...
Changing baudrate to 921600
0
Changed

Task is to review them and hide behind some "enable debugging" option.

The tool is freezing on "Leaving..." message

I'm writing bin file to esp8266 using esploader.write_flash
The console says "Leaving..." and nothing happens then.
In debug mode the last message is: "Debug: check_command leave Flash mode".
Despite this, the firmware works as expected after I press rst button on the dev board.

ESP8266/8285 Support

Is there any chance of getting ESP8266/8285 support added to this code base?

I have started adding support and have it reading doing the initial negotiation and feature detection, but after it uploads the stub, it's not getting the OHAI response back.

https://github.com/pkendall64/esptool-js/tree/esp8266

I created the stub code by decoding the one in esptool.py 3.0.
And just base64 the data and gzip -9 | base64 the text segment.

Any help appreciated.

Move reset code into own function

The reset code to reset a device is a useful standalone feature. I would like to avoid copying it around to my own projects. Would it be ok to extract it to a standalone function in its own file?

esptool-js/src/esploader.ts

Lines 289 to 322 in 99bcaf0

if (this.transport.get_pid() === this.USB_JTAG_SERIAL_PID) {
// Custom reset sequence, which is required when the device
// is connecting via its USB-JTAG-Serial peripheral
await this.transport.setRTS(false);
await this.transport.setDTR(false);
await this._sleep(100);
await this.transport.setDTR(true);
await this.transport.setRTS(false);
await this._sleep(100);
await this.transport.setRTS(true);
await this.transport.setDTR(false);
await this.transport.setRTS(true);
await this._sleep(100);
await this.transport.setRTS(false);
await this.transport.setDTR(false);
} else {
await this.transport.setDTR(false);
await this.transport.setRTS(true);
await this._sleep(100);
if (esp32r0_delay) {
//await this._sleep(1200);
await this._sleep(2000);
}
await this.transport.setDTR(true);
await this.transport.setRTS(false);
if (esp32r0_delay) {
//await this._sleep(400);
}
await this._sleep(50);
await this.transport.setDTR(false);
}

ESP32-S3 over USB doesn't connect

I was able to flash a dev board successfully (ESP32-S3-DevkitC-1) using the example page provided as a baseline "okay, that worked". I was curious if a ESP32-S3-Eye dev board would also work since the latter uses USB rather than the typical UART interface.

On the S3-Eye board, it wasn't able to get past "Connecting......".

Is communicating over USB in scope for esptool-js? I'm curious if this is a bug or if this simply isn't intended to work yet (or ever).

Upload of bin to esp32 DOIT DEVKIT doesn't work as expected

Hello, I am having trouble with the flashing process of specific board esp32 DOIT DEVKIT. Even with the upload process getting to 100%, the program flashed does not run even after resseting the board. The .bin file is attached as a zip and is a blink code (D2 turning on and off every second). I even tried flashing in different addresses 0x0 and 0x1000. Thank you for the attention.

Captura de tela 2023-02-17 121915
firmware.zip

Live Demo no longer working

In commit c34c8c7, index.ts was changed to use .textContent when reading the offset and file data. Since both the offset and file elements are html input elements with no textContent, the demo no longer works. It should be using .value and .data instead.

Relevant lines:

const offset = parseInt(offSetObj.textContent);

fileArray.push({ data: fileObj.textContent, address: offset });

Add a devcontainer

To simplify the set-up of developer environment, we could add a devcontainer file to the repository.

Flash error with ESP32-C3 via USB_SERIAL_JTAG: Timeout

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x303a ProductID 0x1001
Connecting....
Detecting chip type... ESP32-C3
Chip is ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: 84:f7:03:a0:ee:ec
Uploading stub...
Running stub...
Error: Timeout
Compressed 2209028 bytes to 1330626...

Screenshot from Chrome Console
Bildschirmfoto 2022-08-11 um 11 00 55

@balloob fyi

Compatibiity With Electron

Hi,
Does anyone have an example project of being able to flash an ESP32 using esptool-js from an Electron app?

I'm currently getting this error.

Error: TypeError: Cannot read properties of undefined (reading 'get_info')
    at new ESPLoader (esploader.js:124:1)
    at HTMLButtonElement.<anonymous> (renderer.js:73:27)
// renderer.js

const { SerialPort } = require('serialport');
const requireESM = require('esm')(module);
const esptool = requireESM('esptool-js');
const fs = require('fs');
const axios = require('axios');

const dropdown = document.getElementById('serial-dropdown');
const status = document.getElementById('status');

let selectedPort;

function updateStatus(text) {
    status.innerHTML = text;
}

// Consts
const REMOTE_FIRMWARE_URL = "";
const REMOTE_BOOTLOADER_URL = "";
const REMOTE_PARTITIONS_URL = "";

async function listSerialPorts() {
    try {
        const ports = await SerialPort.list();
        
        // Clear the dropdown
        dropdown.innerHTML = '';

        if (ports.length > 0) {
            selectedPort = ports[0].path;
        }
        ports.forEach(port => {
            const option = document.createElement('option');
            option.value = port.path;
            option.text = port.path + (port.manufacturer ? ` (${port.manufacturer})` : '');
            dropdown.appendChild(option);
        });
    } catch (error) {
        console.error('Error listing serial ports:', error);
    }
}

listSerialPorts();

dropdown.addEventListener('change', (e) => {
    console.log(`Selected serial port: ${e.target.value}`);
    selectedPort = e.target.value;
});

document.getElementById('refreshButton').addEventListener('click', async () => {
    listSerialPorts();
});

// Flashing
async function downloadFile(url, outputPath) {
    const response = await axios({
        method: 'get',
        url: url,
        responseType: 'arraybuffer'
    });
    fs.writeFileSync(outputPath, new Uint8Array(response.data));
}

document.getElementById('flashButton').addEventListener('click', async () => {
    updateStatus('Flashing...');
    try {
        const espLoader = new esptool.ESPLoader({
            port: selectedPort,
            chip: 'esp32',
            logLevel: 'debug'
        });
        
        updateStatus('Erasing flash...');

        // Erase the flash first.
        await espLoader.eraseFlash();

        updateStatus('Downloading files...');

        // Download the necessary files
        await downloadFile(REMOTE_FIRMWARE_URL, './tempFirmware.bin');
        await downloadFile(REMOTE_BOOTLOADER_URL, './tempBootloader.bin');
        await downloadFile(REMOTE_PARTITIONS_URL, './tempPartitions.bin');

        updateStatus('Flashing bootloader...');

        // Flash the bootloader.
        const bootloader = await espLoader.readFirmware('./tempBootloader.bin');
        await espLoader.flashFirmware(bootloader, 0x10000);

        updateStatus('Flashing firmware...');

        // Flash the firmware.
        const firmware = await espLoader.readFirmware('./tempFirmware.bin');
        await espLoader.flashFirmware(firmware, 0x1000);

        updateStatus('Flashing partition...');

        // Flash the partitions.
        const partitions = await espLoader.readPartitions('./tempPartitions.bin');
        await espLoader.flashPartitions(partitions, 0x8000);

        await espLoader.close();

        updateStatus('Cleanup...');

        // Clean up the temporary files
        fs.unlinkSync('./tempFirmware.bin');
        fs.unlinkSync('./tempBootloader.bin');
        fs.unlinkSync('./tempPartitions.bin');

        console.log('Flashing complete');
        updateStatus('Flashing completed successfully!');
    } catch (error) {
        console.error('Error:', error);
        updateStatus(error.toString());
    }
});

Using this tool to burn MicroPython firmware on ESP8266 always fails

I use https://espressif.github.io/esptool-js/ to burn MicroPython firmware, version
[v1.21.0 (2023-10-05) .bin](http://www.micropython.org/resources/firmware /ESP8266_GENERIC-20231005-v1.21.0.bin),
the programming can work normally, but the chip cannot run normally after burning. So far, I have also tried to use esptool.py to burn this firmware. Using esptool.py to burn the same firmware is It can run normally, but burning using esptool.js tool does not work. Hope the author can solve this problem?

Problem with most current (11.2.0.167) CP210X driver on Windows 10

On Windows 10 systems using the latest (11.2.0.167) CP210X driver I can not connect to ESP32 devices with a Silicon Labs CP2102 or CP2104 USB to UART bridge. I receive Error: Timeout
PlatformIO or the Arduino IDE can connect and flash without issues. When downgrading the driver to version 6.7.4.261, esptool-js works as expected.

Connect ESP32-S2 built-in USB_CDC Error: Timeout

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x303a ProductID 0x2
Connecting.........._
Detecting chip type... ESP32-S2
Chip is ESP32-S2
Features: Wi-Fi
Crystal is 40MHz
MAC: 68:67:25:2d:f4:0c
Uploading stub...
Error: Timeout

ESP32-C3: "app image at 0x10000 has invalid magic byte" if the app image flashed at first

Module

ESP32-C3-WROOM-02

Issue

  • Use esptool.py to flash ESP32-C3, it works after the module is reseted.
  • Use https://espressif.github.io/esptool-js/ to flash same images with the address the order:(0x0, 0x8000, 0xe000, 0x10000), it works after the module is reseted.
  • Use https://espressif.github.io/esptool-js/ to flash same images with the address the order:(0x0, 0x10000, 0x8000, 0xe000 ), it cannot works after the module is reseted.
  • the error is "esp_image: image at 0x10000 has invalid magic byte"

Esptool-js Failed Log

  • Flash(Adress: 0x0,0x10000, 0x8000, 0xe000 ) log in the Console:
esptool.js v0.1-dev
Serial port WebSerial VendorID 0x10c4 ProductID 0xea60
Connecting....
Detecting chip type... ESP32-C3
Chip is ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: 7c:df:a1:bc:37:ac
Uploading stub...
Running stub...
Stub running...
Changing baudrate to 921600
Changed
Compressed 19844 bytes to 12011...
Writing at 0x0... (100%)
Wrote 19844 bytes (12011 compressed) at 0x0 in 0.46 seconds.
Hash of data verified.
Compressed 583300 bytes to 321867...
Writing at 0x10000... (5%)
Writing at 0x14000... (10%)
Writing at 0x18000... (15%)
Writing at 0x1c000... (20%)
Writing at 0x20000... (25%)
Writing at 0x24000... (30%)
Writing at 0x28000... (35%)
Writing at 0x2c000... (40%)
Writing at 0x30000... (45%)
Writing at 0x34000... (50%)
Writing at 0x38000... (55%)
Writing at 0x3c000... (60%)
Writing at 0x40000... (65%)
Writing at 0x44000... (70%)
Writing at 0x48000... (75%)
Writing at 0x4c000... (80%)
Writing at 0x50000... (85%)
Writing at 0x54000... (90%)
Writing at 0x58000... (95%)
Writing at 0x5c000... (100%)
Wrote 583300 bytes (321867 compressed) at 0x10000 in 9.144 seconds.
Hash of data verified.
Compressed 3076 bytes to 128...
Writing at 0x8000... (100%)
Wrote 3076 bytes (128 compressed) at 0x8000 in 0.059 seconds.
Hash of data verified.
Compressed 8196 bytes to 30...
Writing at 0xe000... (100%)
Wrote 8196 bytes (30 compressed) at 0xe000 in 0.145 seconds.
Hash of data verified.
Leaving...
  • The output after the module restarted:
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x403d1546
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd6100,len:0x16b8
load:0x403ce000,len:0x930
load:0x403d0000,len:0x2d40
entry 0x403ce000
I (35) boot: ESP-IDF v4.4-dirty 2nd stage bootloader
I (35) boot: compile time 15:17:18
I (35) boot: chip revision: 3
I (37) boot.esp32c3: SPI Speed      : 80MHz
I (42) boot.esp32c3: SPI Mode       : DIO
I (47) boot.esp32c3: SPI Flash Size : 4MB
I (51) boot: Enabling RNG early entropy source...
I (57) boot: Partition Table:
I (60) boot: ## Label            Usage          Type ST Offset   Length
I (68) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (75) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (82) boot:  2 app0             OTA app          00 10 00010000 00140000
I (90) boot:  3 app1             OTA app          00 11 00150000 00140000
I (97) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (105) boot: End of partition table
I (109) boot: No factory image, trying OTA 0
E (114) esp_image: image at 0x10000 has invalid magic byte (nothing flashed here?)
E (122) boot: OTA app partition slot 0 is not bootable
E (128) esp_image: image at 0x150000 has invalid magic byte (nothing flashed here?)
E (136) boot: OTA app partition slot 1 is not bootable
E (142) boot: No bootable app partitions in the partition table

Esptool-js Success Log

  • Flash(Adress: 0x0, 0x8000, 0xe000, 0x10000) log in the Console:
Detecting chip type... ESP32-C3
Chip is ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: 7c:df:a1:bc:37:ac
Uploading stub...
Running stub...
Stub running...
Changing baudrate to 921600
Changed
Compressed 19844 bytes to 12011...
Writing at 0x0... (100%)
Wrote 19844 bytes (12011 compressed) at 0x0 in 0.449 seconds.
Hash of data verified.
Compressed 3076 bytes to 128...
Writing at 0x8000... (100%)
Wrote 3076 bytes (128 compressed) at 0x8000 in 0.056 seconds.
Hash of data verified.
Compressed 8196 bytes to 30...
Writing at 0xe000... (100%)
Wrote 8196 bytes (30 compressed) at 0xe000 in 0.145 seconds.
Hash of data verified.
Compressed 583300 bytes to 321867...
Writing at 0x10000... (5%)
Writing at 0x14000... (10%)
Writing at 0x18000... (15%)
Writing at 0x1c000... (20%)
Writing at 0x20000... (25%)
Writing at 0x24000... (30%)
Writing at 0x28000... (35%)
Writing at 0x2c000... (40%)
Writing at 0x30000... (45%)
Writing at 0x34000... (50%)
Writing at 0x38000... (55%)
Writing at 0x3c000... (60%)
Writing at 0x40000... (65%)
Writing at 0x44000... (70%)
Writing at 0x48000... (75%)
Writing at 0x4c000... (80%)
Writing at 0x50000... (85%)
Writing at 0x54000... (90%)
Writing at 0x58000... (95%)
Writing at 0x5c000... (100%)
Wrote 583300 bytes (321867 compressed) at 0x10000 in 9.012 seconds.
Hash of data verified.

Esptool.py Log

  • Flash info:
esptool.py esp32c3 -p /dev/cu.SLAB_USBtoUART -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 4MB 0x0 bootloader/bootloader.bin 0x10000 bbScale.bin 0x8000 partition_table/partition-table.bin 0xe000 ota_data_initial.bin
esptool.py v3.2-dev
Serial port /dev/cu.SLAB_USBtoUART
Connecting...
Chip is ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: 7c:df:a1:bc:37:ac
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00004fff...
Flash will be erased from 0x00010000 to 0x0009efff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Compressed 19840 bytes to 12006...
Writing at 0x00000000... (100 %)
Wrote 19840 bytes (12006 compressed) at 0x00000000 in 0.6 seconds (effective 268.6 kbit/s)...
Hash of data verified.
Compressed 583296 bytes to 321864...
Writing at 0x00010000... (5 %)
Writing at 0x0001a238... (10 %)
Writing at 0x00024900... (15 %)
Writing at 0x0002adb0... (20 %)
Writing at 0x00031669... (25 %)
Writing at 0x00038c5e... (30 %)
Writing at 0x0003ff69... (35 %)
Writing at 0x00046f36... (40 %)
Writing at 0x0004e094... (45 %)
Writing at 0x0005502e... (50 %)
Writing at 0x0005bf9e... (55 %)
Writing at 0x00062ac3... (60 %)
Writing at 0x00069d9e... (65 %)
Writing at 0x000718f7... (70 %)
Writing at 0x000781de... (75 %)
Writing at 0x0007e8f5... (80 %)
Writing at 0x000851f0... (85 %)
Writing at 0x0008b180... (90 %)
Writing at 0x00092b02... (95 %)
Writing at 0x00099d34... (100 %)
Wrote 583296 bytes (321864 compressed) at 0x00010000 in 9.5 seconds (effective 490.0 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 128...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (128 compressed) at 0x00008000 in 0.1 seconds (effective 401.4 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 31...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (31 compressed) at 0x0000e000 in 0.1 seconds (effective 565.2 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
Done
  • The output after the module restarted:
mac$ idf.py monitor
Executing action: monitor
Serial port /dev/cu.usbserial-1420
/dev/cu.usbserial-1420 failed to connect: [Errno 16] could not open port /dev/cu.usbserial-1420: [Errno 16] Resource busy: '/dev/cu.usbserial-1420'
Serial port /dev/cu.SLAB_USBtoUART
Connecting.........
Detecting chip type... ESP32-C3

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd6100,len:0x16b8
load:0x403ce000,len:0x930
load:0x403d0000,len:0x2d40
entry 0x403ce000
I (30) boot: ESP-IDF v4.4-dirty 2nd stage bootloader
I (30) boot: compile time 15:17:18
I (30) boot: chip revision: 3
I (32) boot.esp32c3: SPI Speed      : 80MHz
I (37) boot.esp32c3: SPI Mode       : DIO
I (42) boot.esp32c3: SPI Flash Size : 4MB
I (46) boot: Enabling RNG early entropy source...
I (52) boot: Partition Table:
I (55) boot: ## Label            Usage          Type ST Offset   Length
I (63) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (70) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (78) boot:  2 app0             OTA app          00 10 00010000 00140000
I (85) boot:  3 app1             OTA app          00 11 00150000 00140000
I (93) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (100) boot: End of partition table

It takes 3-5 minutes to decide that a connection cannot be established

ESPLoader is initialized by calling main_fn. This function calls detect_chip, which in turn calls connect which triggers the connection sequence.

If a device requires the BOOT mode to be held down to start flashing, the connection will fail. Currently it takes 4-5 minutes on my machine before it raises the error Failed to connect with the device. This seems too long.

The default attempts number for connect is set to 7. This means that 7 times it tries the following:

  • Calls connect_attempt with esp32r0_delay set to false
  • Calls connect_attempt with esp32r0_delay set to true

main_fn allows passing in a mode that is passed down to connect_attempt. It is defined as type string, it defaults to default_reset. It can be set to no_reset to skip resetting the device inside connect_attempt. The resetting takes quite some time, with hardcoded sleeps. If esp32r0_delay is true, there is a call to sleep 2 seconds!

Because our connection runs connect_attempt twice for each attempt, we are trying to attempt to connect 14 times. That's already twice as many as the Python tool does by default.

Below a screenshot of the console logs. This is not a full single attempt (out of 7), as it cuts off the 2nd call to connect_attempt with esp32r0_delay set to true. The screenshot already spans 26 seconds. It has another 6 full attempts to go!

CleanShot 2023-02-02 at 23 05 48

Looking at esptool, it also resets between every attempt, but it uses different reset strategies that leverage different delays https://github.com/espressif/esptool/blob/master/esptool/loader.py#L567. The strategies are defined at https://github.com/espressif/esptool/blob/master/esptool/reset.py#L61. By default the sleep delay between RTS setting is 0.05 and 0.55 for a 2nd reset attempt. There are also calls to 0.1 and 0.2s sleeps. There definitely is never a 2s sleep 👀 Also there is no reference to what esp32r0_delay is, it's not in the Python tool.

Summary:

  • What is esp32r0_delay?
  • Why are we doing two connection attempts for each attempt, doubling the number of attempts what esptool does?
  • Are there ways we can speed this up further?

Flash a binary from Arduino IDE?

Should this work to upload a binary from the Arduino IDE using the ESP32 / Arduino framework? It doesn't for me.

I have this sketch:

void setup() {
  Serial.begin(115200);
  Serial.println("\nsetup");
}

void loop() {
  Serial.println("loop");
  delay(1000);
}

I use menu option "Sketch -> Export compiled Binary" to show the .bin file, which I've attached here.

Use the Live demo link and connect to my local board, choose the binary file, and click program. It all seems to flash ok, screen shot:

image

but then the board seems to be borked and wont reset and nothing comes up in a serial monitor or terminal.

Changing baud rate causes timeout

We use esptool-js to power ESP Web Tools. When it starts installing using esploader, it passes an existing port. The port has been opened, used to query improv, and then closed.

ESPLoader will, as part of main_fn(), call await this.change_baud();. This command is causing the connection to timeout and make the connection unusable.

The fix for ESP Web Tools is to apply a patch to the installed node module to comment out the changing of the baud rate. When done, everything works fine.

I've been looking into the code trying to understand what's going on:

  • ESPLoader takes baudrate and rom_baudrate param. Second one defaults to 115200
  • main_fn() calls detect_chip()
  • detect_chip() calls connect()
  • connect() calls transport.connect(this.rom_baudrate)
  • transport.connect() opens the port at the requested baud rate and stores it as transport.baudrate
  • ESPLoader detects chip, runs stub.
  • ESPloader calls change_baud.
  • change_baud sends a packet. Then disconnects and opens again.

Question: would it be possible to skip changing the baud if this.baudrate == this.rom_baudrate ?

Can't upload .bin to 0x00010000 ESP32

When I use ArduinoIDE, all works correctly:

Compressed 940304 bytes to 602887...

Writing at 0x00010000... (2 %)
Writing at 0x000197fd... (5 %)
Writing at 0x0002591d... (8 %)
Writing at 0x0002ef7e... (10 %)
Writing at 0x0003e65a... (13 %)
Writing at 0x0004402c... (16 %)
Writing at 0x0004972b... (18 %)
Writing at 0x0004f616... (21 %)
Writing at 0x00055243... (24 %)
Writing at 0x0005a931... (27 %)
Writing at 0x0005ffed... (29 %)
Writing at 0x000652b4... (32 %)
Writing at 0x0006a626... (35 %)
Writing at 0x0006f83d... (37 %)
Writing at 0x00074b1b... (40 %)
Writing at 0x00079ebf... (43 %)
Writing at 0x0007f100... (45 %)
Writing at 0x00084429... (48 %)
Writing at 0x000894c8... (51 %)
Writing at 0x0008e874... (54 %)
Writing at 0x0009465e... (56 %)
Writing at 0x00099b05... (59 %)
Writing at 0x0009ed9f... (62 %)
Writing at 0x000a42b7... (64 %)
Writing at 0x000a94b2... (67 %)
Writing at 0x000ae91e... (70 %)
Writing at 0x000b3e98... (72 %)
Writing at 0x000b948f... (75 %)
Writing at 0x000bec93... (78 %)
Writing at 0x000c4a5f... (81 %)
Writing at 0x000ca397... (83 %)
Writing at 0x000d298c... (86 %)
Writing at 0x000db638... (89 %)
Writing at 0x000e095b... (91 %)
Writing at 0x000e625b... (94 %)
Writing at 0x000eb97b... (97 %)
Writing at 0x000f0e03... (100 %)

When I use esptool-js:

Compressed 940308 bytes to 602890...
Writing at 0x10000... (2%)
Writing at 0x14000... (5%)
Writing at 0x18000... (8%)
Writing at 0x1c000... (10%)
Writing at 0x20000... (13%)
Writing at 0x24000... (16%)
Writing at 0x28000... (18%)
Writing at 0x2c000... (21%)
Writing at 0x30000... (24%)
Writing at 0x34000... (27%)
Writing at 0x38000... (29%)
Writing at 0x3c000... (32%)
Writing at 0x40000... (35%)
Writing at 0x44000... (37%)
Writing at 0x48000... (40%)
Writing at 0x4c000... (43%)
Writing at 0x50000... (45%)
Writing at 0x54000... (48%)
Writing at 0x58000... (51%)
Writing at 0x5c000... (54%)
Writing at 0x60000... (56%)
Writing at 0x64000... (59%)
Writing at 0x68000... (62%)
Writing at 0x6c000... (64%)
Writing at 0x70000... (67%)
Writing at 0x74000... (70%)
Writing at 0x78000... (72%)
Writing at 0x7c000... (75%)
Writing at 0x80000... (78%)
Writing at 0x84000... (81%)
Writing at 0x88000... (83%)
Writing at 0x8c000... (86%)
Writing at 0x90000... (89%)
Writing at 0x94000... (91%)
Writing at 0x98000... (94%)
Writing at 0x9c000... (97%)
Writing at 0xa0000... (100%)

In .py writing starts from 0x00010000 in .js - 0x10000.

Looks like something wrong with int to address convert.
image

image

Please advice, thanks.

Flash error with ESP32-S3: Timeout

Appears to be the same with S2 and C3 ... there is a timeout error when trying to flash the chip.

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x303a ProductID 0x1001
Connecting....
Detecting chip type... ESP32-S3
Chip is ESP32-S3
Features: Wi-Fi,BLE
Crystal is 40MHz
MAC: f4:12:fa:44:1b:fc
Uploading stub...
Running stub...
Stub running...
Changing baudrate to 460800
Changed
Erasing flash (this may take a while)...
Chip erase completed successfully in 1.082s
Compressed 4420676 bytes to 124923...
Writing at 0x0... (12%)
Writing at 0x4000... (25%)
Writing at 0x8000... (37%)
Error: Timeout

Separate environment specific bindings and make esptool-js usable from Node.js environment

I want to use the tool from a Node.js application to flash firmware to an ESP32.

Even though the app is used from a desktop environment, I do not want to rely on the python esptool, because, it is an external dependency, which complicates distribution and limits the possibility of the application being ported to a web app in the future.

To make this possible, I propose two changes:

  1. split the webserial Transport into two classes implementing a simple abstraction layer around the serial port and new Transport implementing packet parsing etc.
  2. change the package configuration, so that it can be imported using node.js module resolution.

This will not require extensive changes and will make it easy to write bindings for other serial port implementations (such as node serialport. It will also make it easier to port the application to completely different connection types (such as RFC 2217).

Breaking changes to the API will be required.

I have hacked an ugly version, which works both in both node.js and as a web app. I've used it as a proof of concept in my app, however, I have not made any changes to the API yet (leading to code duplication in the Transport code). I also do not have much (mostly none) experience with JavaScript/TypeScript build systems and module resolution, for which reason the changes in package configuration are especially ugly (and change things, which probably can be fixed in some other way).

I also do not want to rely on modified/own implementation of the esptool, as it would mean giving up official support and more work in the future.

If the proposed changes are accepted, I will be happy to implement the first suggested change. On the other hand, I do not have the skills to implement the second change, so I would be happy if someone else could do it or guide me through the process.

Make esptool-js available on Android device.

The website https://caniuse.com/?search=webusb indicates that Web USB is available on Android devices. However, it's noted that Web Serial is currently not available on Android, as shown on https://caniuse.com/?search=serial.

To address this limitation, the project at https://github.com/google/web-serial-polyfill has developed a polyfill that enables Web Serial functionality alongside Web USB. This enhancement allows Android devices to access Web Serial capabilities.

I conducted a test by opening the following demonstration on my Android phone: https://googlechromelabs.github.io/serial-terminal/?polyfill. During the test, I successfully connected an ESP32s3 device to my Android phone. This resulted in the display of booting logs from the ESP32 on my Google Chrome browser on Android.

Considering this, I am curious whether the esptool-js project will consider making their tool available for use on Android devices. This expansion could further contribute to the accessibility and functionality of the tool.

Enable strict mode for TypeScript

Maintenance issue. Now that we're using TypeScript, it would be great to enable strict: true in tsconfig.json. It currently generates a bunch of warnings that are potentially bugs.

❯ tsc
src/esploader.ts:30:7 - error TS2322: Type 'null' is not assignable to type 'ROM'.

30       return null;
         ~~~~~~~~~~~~

src/esploader.ts:100:5 - error TS2322: Type 'null' is not assignable to type 'ROM'.

100     this.chip = null;
        ~~~~~~~~~

src/esploader.ts:180:16 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'string'.

180       this.log(e);
                   ~

src/esploader.ts:328:18 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'string'.

328         this.log(e);
                     ~

src/esploader.ts:344:18 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'string'.

344         this.log(error);
                     ~~~~~

src/esploader.ts:766:16 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'string'.

766       this.log(e);
                   ~

src/esploader.ts:992:53 - error TS2454: Variable 'calcmd5' is used before being assigned.

992         if (new String(res).valueOf() != new String(calcmd5).valueOf()) {
                                                        ~~~~~~~

src/esploader.ts:993:36 - error TS2454: Variable 'calcmd5' is used before being assigned.

993           this.log("File  md5: " + calcmd5);
                                       ~~~~~~~

src/webserial.ts:130:20 - error TS2531: Object is possibly 'null'.

130     const reader = this.device.readable.getReader();
                       ~~~~~~~~~~~~~~~~~~~~


Found 9 errors in 2 files.

Errors  Files
     8  src/esploader.ts:30
     1  src/webserial.ts:130

Error when trying to connect to esp32 device (Sync Errror:Timeout)

Errors in console:

index.js:112 Error: Timeout
at ei.read (bundle.js:2:65884)
at async ti.command (bundle.js:2:49127)
at async ti.read_reg (bundle.js:2:49475)
at async ti.connect (bundle.js:2:51399)
at async ti.detect_chip (bundle.js:2:52198)
at async ti.main_fn (bundle.js:2:60077)
at async connectButton.onclick (index.js:107:12)

Errors in output:

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x1a86 ProductID 0x7523
Connecting..._connect_attempt default_reset false

Sync
Sync err Error: Timeout

.Sync
538052359

Error: Timeout

Time out when trying to flash spiffs.bin for an ESP32

Hello, I am trying to flash the spiffs part of a project with this tool.
From pio in verbose mode, the command line executed is :
```--chip esp32 --port "“COM18”" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_size detect 2686976 .pio/build/routeur_solaire/spiffs.bin`````

Seems the offset adress is 2686976 = 0x290000.

When trying with esptool-js got a timeout error...

image

Maybe I am wrong somewhere, but is-it a bug ?

Missing version in package.json

The package.json file is very bare bones here and doesn't even have a version number.

version is a required field

Yarn refuses to install packages that do not have a version number specified and just throws a error Can't add "esptool-js": invalid package version undefined.

Can I use transport for sending string commands over serial?

I am trying to send a command using Transport but I am stuck...

Without esptool-js, I was able to send those commands like this:

function send(command: string) {
    const encoder = new TextEncoder();
    const dataArrayBuffer = encoder.encode(command);
    const writer = this.serialPort.writable.getWriter();
    await writer.write(dataArrayBuffer);
    writer.releaseLock();
}

but this no longer works after ESPLoader is synced so I tried using Transporter:

function send(command: string) {
    const encoder = new TextEncoder();
    const dataArrayBuffer = encoder.encode(command);
    await this.transport.write(dataArrayBuffer);
}

However, I got no response... Could someone help me out?

Bug: connection error after typescript rewrite

Hi there! I wanted to try this tool and after I tested it online it worked correctly:

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x1a86 ProductID 0x7523
Connecting....
Detecting chip type... ESP32
Chip is ESP32-D0WDQ6 (revision 1)
Features: Wi-Fi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 40:91:51:a5:d8:14
Uploading stub...
Running stub...
Stub running...
Changing baudrate to 115200
Changed

but when I tried it locally, I got this:

esptool.js v0.1-dev
Serial port WebSerial VendorID 0x1a86 ProductID 0x7523
Connecting..._connect_attempt default_reset false

Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

.Sync
Sync err Error: Timeout

._connect_attempt default_reset true

Sync
Sync err Error: Timeout

_Sync
Sync err Error: Timeout

_Sync
Sync err Error: Timeout

So I tried checking out to a commit which is on gh-pages (the one before first attempt to re write in typescript) and it worked again!

It looks like there may have been a bug introduced in that commit 😬 Unfortunately, I am not familiar enough with the codebase to determine the cause. So, I wanted to bring this to your attention in case it helps with troubleshooting.

Still, this looks promising, keep up the good work! 🙂

Issue with ESP32-S3 and Baudrate 115200

Many people use this tool to flash their nerdminers, as it seems that some people, myself included, are unable to do so anymore. Specifically, with the Lilygo ESP32-S3, at a baud rate of 115200, it stops at "Stub running..."

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.