Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32-PICO-D4 - Error: flash chip not supported #7

Closed
tobymurray opened this issue Oct 1, 2020 · 17 comments
Closed

ESP32-PICO-D4 - Error: flash chip not supported #7

tobymurray opened this issue Oct 1, 2020 · 17 comments

Comments

@tobymurray
Copy link

I have an ESP32-PICO-D4 with 4MB of flash, I believe something like (but potentially not exactly) this: https://www.aliexpress.com/item/4000473398801.html

I'm following along the xtensa-rust-quickstart, and rying to use cargo-espflash from Crates.io got me some unexpected errors:

$ cargo espflash --chip esp32 --example esp32 --target xtensa-esp32-none-elf --speed 460800 --features="xtensa-lx-rt/lx6,xtensa-lx/lx6" /dev/ttyUSB0
thread 'main' panicked at 'Unable to parse command-line arguments: unused arguments left: --target, --speed, --features=xtensa-lx-rt/lx6,xtensa-lx/lx6', /home/toby/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-espflash-0.1.1/src/main.rs:13:29
stack backtrace:
   0: rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::result::unwrap_failed
   3: cargo_espflash::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Installing from this repo directly (via cargo install --git https://github.com/esp-rs/espflash/ cargo-espflash) seems to have gone better, but I get "flash chip not supported":

cargo espflash --chip esp32 --example esp32 --speed 460800 --features="xtensa-lx-rt/lx6,xtensa-lx/lx6,esp32-hal" /dev/ttyUSB0
   Compiling xtensa-quickstart v0.1.0 (/home/toby/git/esp32/xtensa-rust-quickstart)
    Finished dev [unoptimized + debuginfo] target(s) in 0.66s
Error: flash chip not supported

Is this a limitation of the library currently, or potentially a bug? Whatever the solution, this may ultimately fix MabezDev/xtensa-rust-quickstart#30

@tobymurray
Copy link
Author

As a sanity check that I have switched to an ESP-WROOM-32 and was successfully able to flash with the same command

@icewind1991
Copy link
Member

Can you try with the latest master, which should give you the detected flash id in the error message

@tobymurray
Copy link
Author

Tried with ad983cb:

Error: flash chip not supported, flash id: 0xff

@ubergeek801
Copy link
Contributor

Greetings,
I have the V4 version of this board (several of them actually) and am experiencing the same issue. As suggested above, I built from master (commit 0242407) and see the same result as tobymurray:

Error: flash chip not supported, flash id: 0xff

@ubergeek801
Copy link
Contributor

For what it's worth, I repeated the test using an Adafruit "FTDI Friend" USB-UART bridge, with the same results--although I didn't really expect the bridge to make a difference.

I've been comparing the espflash source with esptool.py on which it appears to be loosely based, although I am by no means fluent in either Rust or Python. While I've found some minor differences, so far none of them have proven to be material. I'll do a little more digging...

@icewind1991
Copy link
Member

The solution here will probably be to add a --flash-size parameter so we dont have to rely on auto detection for chips whose flash doesn't reply with a sensible flash id

@tobymurray
Copy link
Author

That sounds like a reasonable fallback so that the tool can still be used if auto detection fails. Idea being look at the specific device you're using and pass the flash size (e.g. for the board I'm using, it'd be 4 MB)?

@ubergeek801
Copy link
Contributor

It should be noted that the same device is detected without fail by esptool.py. But that utility also appears to push some stub to the ESP32 before detection. Is it using its own bootloader?

Anyway, I added some logging which is not terribly useful (and my apologies that it logs decimal values in arrays, but I'm just getting started with Rust).

When reading the flash ID:

reading register 0x3FF42080
read [1, 10, 4, 0, 255, 255, 255, 0, 0, 0, 0, 0]
response=Some(CommandResponse { resp: 1, return_op: 10, return_length: 4, value: 16777215, status: 0, error: 0 })
= 0xFFFFFF
read [1, 9, 4, 0, 255, 255, 255, 0, 0, 0, 0, 0]
response=Some(CommandResponse { resp: 1, return_op: 9, return_length: 4, value: 16777215, status: 0, error: 0 })
read [1, 9, 4, 0, 255, 255, 255, 0, 0, 0, 0, 0]
response=Some(CommandResponse { resp: 1, return_op: 9, return_length: 4, value: 16777215, status: 0, error: 0 })
flash_id=0xFFFFFF
size_id= 0xFF

Now, I hacked the code to accept 0xFF as the ID for the 4MB chip, just to see what would happen. Unfortunately, it wasn't very interesting:

read [1, 13, 4, 0, 255, 255, 255, 0, 0, 0, 0, 0]
response=Some(CommandResponse { resp: 1, return_op: 13, return_length: 4, value: 16777215, status: 0, error: 0 })
Error: IO error while using serial port: Operation timed out
caused by: Operation timed out

It seems that either 0x00FFFFFF is a popular return value, or something else is amiss. I suspect the latter, but I haven't much in the way of proof. But I think we can safely assume that forcing a particular flash size, while a useful capability in general, isn't going to help with this particular device.

@ubergeek801
Copy link
Contributor

Doing a little more digging, I stumbled onto something:

espressif/esptool#459

To summarize, an esptool.py user observed the same behavior (a 0xFFFFFF ID followed by a timeout) when using the --no-stub option with a PICO-D4. The explanation was thus:

You're right that ESP32s with custom efuse SPI flash pin mappings (such as the PICO-D4 has) are not currently supported unless the stub is used. The SPI flash pins aren't configured properly by the UART bootloader in ROM.

It would be possible (but fiddly) for us to add support by having esptool write the relevant registers directly. However another option will be to detect this case and produce a clear error message asking to enable the stub.

So I guess the Rust esptool has the same options: use the stub (it doesn't currently do so unless I'm horribly mistaken?), or "write the relevant registers directly," whatever that means exactly.

If there's a preferred approach, I'm happy to try implementing it, or at least help out somehow if I can.

@ubergeek801
Copy link
Contributor

Actually it seems that there is a third, less troublesome option. A later comment in that thread makes the cryptic suggestion:

esptool.py --no-stub --chip=esp32 --port COM17 flash_id --spi-connection=6,17,8,11,16

As a test, I hardcoded a parameter to the SpiAttach command, compiled espflash once again, et voilà!

$ espflash --board-info /dev/ttyUSB0
Chip type: Esp32
Flash size: Flash4MB

So I would suggest that the solution is to implement the same --spi-connection parameter as supported by esptool.py. I'm happy to start working on a PR to do so.

@icewind1991
Copy link
Member

Thanks for the research!

it might be doable to try the different spi parameters automatically when the flash detect returns FF and keep things fully automatic

@ubergeek801
Copy link
Contributor

I'm not sure how many variations exist in the wild, but I could certainly start by implementing something that works for the PICO-D4. This would probably require checking additional registers to distinguish the PICO from other ESP32 variations; I've noticed that esptool.py and esptool don't use the same detection methods, so I could borrow more logic from the former to make this work.

@ubergeek801
Copy link
Contributor

Seems that my recollection of esptool.py logic was faulty; the detection was for various incarnations of ESP32 (e.g. ESP32-S2) rather than device variants. So PR #13 doesn't perform any additional detection trickery but merely behaves as @icewind1991 suggests.

@icewind1991
Copy link
Member

@ubergeek801 can you verify that things are still working after merging 821cb2b

@ubergeek801
Copy link
Contributor

I like your version better; it's certainly cleaner.

However, there's a subtle issue when enabling/attaching to flash. The default all-zero parameter must be encoded as five bytes, or the command times out. (It's also possible that any parameters with leading and/or trailing zeroes also need an additional byte, but I have no way of knowing.)

In other words, instead of this:

self.connection.command(Command::SpiAttach as u8, &spi_params.to_le_bytes()[..], 0)?;

We need something like this:

if spi_params == 0 {
    self.connection.command(Command::SpiAttach as u8, &[0; 5][..], 0)?;
} else {
    self.connection.command(Command::SpiAttach as u8, &spi_params.to_le_bytes()[..], 0)?;
}

(Note that &[0; 5][..] appears in the original (pre-PR) code.)

@icewind1991
Copy link
Member

I noticed the difference in numbers of 0's send to, but it didn't seem to make a difference in my own testing. I've fixed it now

@ubergeek801
Copy link
Contributor

Detection seems to work perfectly now. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants