---
# System prepended metadata

title: ESP8266 Firmware Update
tags: [Computer Network, esp8266, wifi]

---


This article aims to describe how to program AT firmware to ESP8266 modules .

## Introduction
The ESP8266 Wi-Fi module has become popular for adding wireless capabilities to a wide variety of eletronic hardware projects. A key feature that facilitates this integration is the AT firmware.

### What is AT firmware
The AT firmware is a default program preloaded on many ESP8266 modules. It enables the module to interpret and execute AT commands received via a serial interface (UART). This setup allows the ESP8266 to function as a Wi-Fi modem, offloading network tasks from the main microcontroller.

### AT Commands and Their Role
AT commands are textual instructions that control the behavior of ESP8266. They cover a range of functions like device attribute setup, wifi station setup, access-point lookup / join, and managing TCP/IP connection.

In this article, only a few commands are applied for verification after AT firmware update.


## Source of AT Firmware

- [ESP Non-OS SDK](https://github.com/espressif/ESP8266_NONOS_SDK/tree/master)
  - it provides handy pre-built firmware binary for flashing to your ESP module
  - deprecated and no longer maintained (lastest supported version: 1.7.6)
- [ESP RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK)
  - based on FreeRTOS, it provides low-level system features integrated with AT firmware and custom application.
  - Users need to download the source project, add their own application code, then build binaries from source. I have not tried this yet (TODO)
  - recommended and maintained by espressif dev team since version 2.x

In this article I use ESP Non-OS SDK because AT firmware is the only thing I need

## Pin Wiring
The wiring is tested with my ESP-01S and ESP-12S modules.

### Wiring via USB-to-TTL Adapter
- use USB-to-TTL adapter cable to interface ESP8266 module with host PC that runs binary-flashing tool.
- I use `PL2303HXD` , the adapter operates at `3.3v` and `20mA to 25mA` current. Avoid using 5V logic levels, as they can damage the ESP module

---

The table below shows common pin wirings with USB-TTL serial cable 
| ESP8266 | USB-TTL serial cable |
|----|---|
| `Tx`   | `Rx` |
| `Rx`   | `Tx` |
| `VDD`  | `3V3` |
| `GND`  | `GND` |

> Note If your USB-to-TTL cable cannot supply appropriate operating voltage or current required by ESP8266 module, please switch to other reliable power source, For example you can utilize pins `3V3` or `GND` from a development board.

The table below shows essential pin wirings with extra reliable power source, in my case I use `3V3` and `GND` pinout on STM32 board.

| ESP8266        | STM32 board |
| -------------- | --------------------------------------------------------------------------- |
| `CH_PD` (`EN`) | `3V3`, always pulling HIGH                                                  |
| `RST`          | `3V3`, always pulling HIGH as   reset deassertion |


### Wiring GPIO0 - Boot Mode Seletion
| pull state | other devices | mode |
|-------|------|-----|
| `LOW` | `GND` of any power supply | programming mode |
| `HIGH` | `3.3V` of any power supply | Boot-from-flash mode |

- Programmable mode : to flash firmware to target ESP8266 board
- Boot-from-flash mode : after flashing the firmware, it is necessary to pull `HIGH` to GPIO0 for booting from internal flash (normal mode) then start sending AT commands

### Wiring GPIO2 and GPIO15
- This highly depends on your ESP board manufacturer, they might modify default state of some input pins of ESP chip during integration.
- Typically , to successully switch to specific boot mode, GPIO2 should be always pulled HIGH and GPIO15 pulled LOW as stated in many ESP8266 documentation.
- In my ESP-12s module, it is not necessary to pull GPIO2 and GPIO15 to LOW / HIGH state, they can be floating. (maybe the manufcturer handled this internally ?)


### Power supply consideration
- ESP-01S and ESP-12S modules operate within a voltage range of `3.0V` to `3.6V`, with `3.3V` being typical.
- ESP-12S draws current that ranges from `170mA` to `20uA` depending on different opearations.
- USB cable `PL2303HXD` supplies just enough voltage and current to my ESP modules **only** for flashing binaries and testing few simple AT commands in boot-from-flash mode ; for the AT commands that provide more advanced network features e.g. network packet transmission, they are beyond the scope of this article and won't be tested at here.
- It is essential to check power consumption parameters for the ESP module and USB-to-TTL cable (acceptable ranges of voltages and current) in your project

### Manually Reseting ESP module to Set Boot Mode
Before using any firmware-flashing tool, it is important to perform hardware reset along with desired GPIO0 state, to ensure correct [boot mode](#Wiring-GPIO0---Boot-Mode-Seletion) in ESP module.

I use power-on reset to set boot mode by manually connecting `VCC` pin of both ends (ESP module and USB-to-TTL adapter cable) , manual reset is not efficient but works without extra button setup.


## Firmware-Flashing Tool
I use python-based [`esptool`](https://docs.espressif.com/projects/esptool/en/latest/esp8266/index.html) to write firmware binaries  to flash memory in ESP8266 modules


### Firmware components to Flash
Be sure that AT-firmware binares (from  ESP-NONOS-SQK) has to be programmed to valid memory address ranges.
  - for `1MB` flash, choose binaries under `bin/at/512+512` in ESP non-OS SDK ; for flash size ` >= 2MB` , choose binaries under `bin/at/1024+1024`

> Note the size of programmable flash memory on your ESP module depends on the manufacturers. In my case , it is 1MB flash in ESP-01s, 4MB flash in ESP-12s


### Operations with `esptool`
#### Check hardware attributes of ESP module
such as flash size or MAC address.

```shell!
esptool.py --port /dev/ttyUSB0 --chip esp8266 --baud 115200  flash_id
```

`/dev/ttyUSB0` indicates to device name of my Linux host environment.

#### Start flashing to ESP module
Below is command exmaple which programs AT fireware v1.7.6 (from ESP non-OS SDK) to ESP-12s module.

```python!
esptool.py --port /dev/ttyUSB0 \
    --chip esp8266 --baud 115200 --before default_reset \
    --after hard_reset  write_flash -z --flash_mode dio \
    --flash_freq 40m --flash_size 4MB  \
    0x0     ./boot_v1.7.bin \
    0x1000  ./at/1024+1024/user1.2048.new.5.bin \
    0x1fc000  ./esp_init_data_default_v08.bin \
    0xfe000   ./blank.bin  \
    0x1fe000  ./blank.bin 
```

> **Note**
> In `ESP Non-OS SDK`, boot loader started at address `0x0` should jump to AT-firmware started at address `0x1000` after runtime execution ; The binaries for AT firmware and bootloader from `ESP-RTOS-SDK` does not seem to work in similar way
> 
> (TODO, figure out how to use the ESP-RTOS-SDK)


If the binary files are written successfully , you should see the response below

```
esptool.py v4.8.1
Serial port /dev/ttyUSB0
Connecting...
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: ec:fa:bc:9c:d7:bf
Stub is already running. No upload is necessary.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00000fff...
Flash will be erased from 0x00001000 to 0x0006dfff...
Flash will be erased from 0x001fc000 to 0x001fcfff...
Flash will be erased from 0x000fe000 to 0x000fefff...
Flash will be erased from 0x001fe000 to 0x001fefff...
Flash params set to 0x0240
Compressed 4080 bytes to 2936...
Wrote 4080 bytes (2936 compressed) at 0x00000000 in 0.3 seconds (effective 107.9 kbit/s)...
Hash of data verified.
Compressed 446196 bytes to 310900...
Wrote 446196 bytes (310900 compressed) at 0x00001000 in 27.9 seconds (effective 127.8 kbit/s)...
Hash of data verified.
Compressed 128 bytes to 75...
Wrote 128 bytes (75 compressed) at 0x001fc000 in 0.0 seconds (effective 27.2 kbit/s)...
Hash of data verified.
Compressed 4096 bytes to 26...
Wrote 4096 bytes (26 compressed) at 0x000fe000 in 0.0 seconds (effective 829.5 kbit/s)...
Hash of data verified.
Compressed 4096 bytes to 26...
Wrote 4096 bytes (26 compressed) at 0x001fe000 in 0.0 seconds (effective 690.4 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
```

### Verification After Flashing
Use any communication tools (e.g. `minicom`) which connects to the port to the USB-to-TTL serial cable, transmit AT commands in the tool console with valid baud rate (determined by your module's vendor, typically `115200`). Below is my test result in `minicom` console :

```shell!
AT

OK
AT+GMR
AT version:1.7.6.0(Jan 24 2022 08:56:02)
SDK version:3.0.6-dev(072755c)
compile time:Jun 17 2024 07:37:40
Bin version(Wroom 02):1.7.6
OK
AT+SLEEP?
+SLEEP:2

OK

AT+UART_CUR?
+UART_CUR:115273,8,1,0,1
OK
AT+CWMODE_CUR?
+CWMODE_CUR:2

OK
```


## Reference
- [`esptool.py` binary-flashing tool for ESP wifi module](https://docs.espressif.com/projects/esptool/en/latest/esp8266/index.html)
- [ESP-12s specification from Ai-Thinker](https://docs.ai-thinker.com/_media/esp-12s_specification_v1.0.pdf)
- [Installing the AT Firmware on an ESP-01S](https://www.sigmdel.ca/michel/ha/esp8266/ESP01_AT_Firmware_en.html)
- [Restoring the AT firmware on the ESP8266 - Robert Oostenveld’s blog](https://robertoostenveld.nl/esp8266-at-firmware/)
- [ESP8266 01 overview and flashing instructions](https://github.com/jandelgado/NodeMCU/wiki/ESP8266-01-overview-and-flashing-instructions)
- [How to Flash ESP-01 Firmware to the Improved SDK v2.0.0](https://www.allaboutcircuits.com/projects/flashing-the-ESP-01-firmware-to-SDK-v2.0.0-is-easier-now/)
- [NodeMCU Flashing the firmware](https://nodemcu.readthedocs.io/en/master/flash/)
- [TTL-232R-RPi Debug Cable for Raspberry Pi Datasheet](https://ftdichip.com/wp-content/uploads/2020/08/DS_TTL-232R_RPi.pdf)
- [c USB-to-Serial Controller Datasheet v1.4.4](https://www.prolific.com.tw/UserFiles/files/ds_pl2303HXD_v1_4_4.pdf)
