ESP8266 Bootloader Modes and GPIO state on Startup
The ESP8266 is an extremely cheap wifi module with a fairly capable processor on board. Recently, it’s exploded on the hobbyist scene due to its low cost. Even better, there’s a high level development platform available (NodeMCU) which runs eLua code making programming quick and simple.
We’ve been using the ESP-07 module in a lot of our projects recently which breaks out nine of the on-board GPIO pins. Although the pin pitch is a non-standard 2mm, breakout boards are available and the smaller size is useful for PCB projects.
Documentation for the ESP8266 is fairly sparse, at least in any official format, but there is a large amount of discussion in various places, most notably the ESP8266 forum. One of the stumbling blocks we encountered was that on startup, the module can enter a number of bootloader modes depending on GPIO pin states. This means that if you want to use any of those pins, you have to be quite careful.
Flashing the NodeMCU firmware
To flash NodeMCU (or any other firmware) you’ll need to connect the following pins:
- GPIO 0: LOW
- GPIO 2: HIGH
- GPIO 15: LOW
If, like us, you’re using the ESP-07 and you need to flash a lot of them, it’s fairly simple to make a jig with Pogo Pins where you can clamp the module during flashing.
You can generally find pre-built versions of NodeMCU around github but if your application uses a lot of memory, you’d do well to remove some of the unneeded modules in user_modules.h and rebuild the binary.
The bootloader can go into a number of modes depending on the state of GPIOs 0, 2 and 15. The two useful modes are the UART download mode (for flashing new firmware) and the flash startup mode (which boots from flash).
|GPIO 0||GPIO 2||GPIO 15|
|UART Download Mode (Programming)||0||1||0|
|Flash Startup (Normal)||1||1||0|
GPIO state on startup
When choosing GPIO pins to use, it’s best to avoid GPIO 0, 2 and 15 unless absolutely necessary. If you do end up using them, you’ll need pullups / pulldowns to ensure the correct bootloader mode. You should also be aware of the fact that GPIO 0 is driven as an output during startup (at least with NodeMCU).
Here’s what we found: 40ms after startup, the GPIO0 line is driven with a signal at around 350 Hz for around 100 ms. So make sure you don’t rely on GPIO0 being stable for the first ~200 ms after startup.