Monday 21 March 2016

Updating the firmware on the Pimoroni ESP8266 pHAT

Pimoroni recently released their ESP8266 pHAT for the Raspberry Pi and while there is plenty of information on the ESP8266 board itself there is much less about how it is connected to the Pi.  Richard Hayler has a post about getting started with the pHAT but it doesn't go beyond the basics.  I've explored the board a little more and have managed to write firmware to the device from the Pi which I will document here.

Richard has shown how to get started which I will only cover briefly here.  They are:
  • Create a new Rasbian 'Jessie' image.
  • Do updates.
  • Do upgrade.
  • Install Minicom.
  • Edit /boot/cmdline.txt to remove the reference to console=ttyAMA0
  • Power down and attach the pHAT.
  • Power back up and connect to the ESP8266 over serial using Minicom.
For convenience I wrote a quick shell script to start up MinicomOpen a new file called 'term' in your favourite text editor and type:

#!/bin/bash
minicom -b 115200 -o -D /dev/ttyAMA0


Save the file and exit and the make it executable by typing:

chmod +x term

from a command prompt.  You can now run it with:

 ./term

Now you should be able to communicate using the AT commands as Richard outlined.  Don't forget that you need to press CTRL+j after hitting return.  So far, so much the same but we need a way to reset the ESP8266 and put it into 'flash' mode.  There is not much documentation on the pHAT but a few minutes with a multimeter showed me that the 'reset' pin on the ESP8266 is connected to GPIO 17 on the Pi and GPIO #0 on the ESP8266 is connected to GPIO 27 on the Pi.  This allows the ESP8266 to be both hardware reset and put into programming mode.  The latest 'Jessie' version of Raspbian has the handy gpiozero Python module installed and we can use this to toggle the GPIO lines with a simple Python script.  Open your editor or, if you prefer, Idle for Python 3 and enter the following code:

#!/usr/bin/env python3
from gpiozero import OutputDevice
from time import sleep

# reset on pin 17, active low
rst = OutputDevice(17, False)

rst.on()
sleep(0.5)
rst.off()
rst.close()


then save it at 'reset.py'.  Make sure you have Minicom open and connected to the ESP8266 so that you can see that the script is working. You can test it from within Idle or make it executable before running it from the command line:

chmod +x reset.py
./reset.py

You should see lots of rubbish scroll by in Minicon before seeing 'ready' and allowing you to type AT commands again.  What the script above does is to define pin 17 as an output called 'rst' which is 'active' low.  ie it is normally high but when it is turned 'on' it goes low.  First the pin is turned 'on' (goes low), then we wait for half a second and turn the pin 'off' again (goes high).  This will reset the ESP8266 and restart the firmware.  We now have a handy way of resetting the device.

The next task is to put it into programming mode.  To do this GPIO #0 on the ESP8266 has to be sent low while we do the reset.  Here is the script to do this:

 #!/usr/bin/env python3
from gpiozero import OutputDevice
from time import sleep

# reset on pin 17, active low
rst = OutputDevice(17, False)
# flash mode select on pin 27, active low
flash = OutputDevice(27, False)

flash.on()
sleep(0.5)
rst.on()
sleep(0.5)
rst.off()
sleep(0.5)
flash.off()
rst.close()
flash.close()


This script defines a second pin (GPIO 27) as 'flash'.  As you can see we turn 'flash' 'on' before doing the reset.  Then we turn it off (remember that these pins are set as active low and so 'on' means going low).  Save the script as 'flash.py' and then make it executable before running it:

chmod +x flash.py
./flash.py

When this script is run you should see the while LED on the pHAT flash briefly and this time Minicom will no longer come back to being ready and you can't type commands.  We are in programming mode.  We can get back into the normal mode of operation by simply running the 'reset.py' script.

Next we need a tool to access the device in programming mode.  There is a platform independent tool on GitHub which is handily also written in Python.  There is loads of information on the tool which includes a manual for all the commands.  We can download it to the Pi using wget and then make it execuatable:

wget https://raw.githubusercontent.com/themadinventor/esptool/master/esptool.py
chmod +x esptool.py

Now we put the ESP8266 into programming mode and test the tool to see that we have a connection.  Make sure you close Minicom first so that it doesn't conflict:

./flash.py
./esptool.py -p /dev/ttyAMA0 read_mac

Hopefully you should see a message like the following:

Connecting...
MAC: 5c:cf:7f:12:72:e7


and the MAC address for the WiFi chip will be displayed.  Another useful command tells us the device id for the flash chip in the device:

./esptool.py -p /dev/ttyAMA0 flash_id
Connecting...
Manufacturer: e0
Device: 4016


As you can see the numbers returned are pretty opaque but another GitHub project has a list of many of them.  The chip in my device is 32 Mbits in size, ie 4 MBytes.

Now we need some firmware to flash.  Of the many pages of resources for the ESP8266, this is one of the most useful.  For this test I'm going to update to the latest official firmware from Espressif. Espressif's board is difficult to navigate and much of it is in Chinese but the latest firmware is posted on their announcement page.  You want to go to 'latest release' Then click the download link for the 'Non-OS SDK' and on that page scroll past the notes and comments to where the file is attached (I said it was complicated, and the exact location might change.)  As I write this, version 1.5.2 is the current file.  Also useful is the current AT commands document.  Besides the command list it also shows which files should be flashed into which locations for different flash sizes.  The firmware is a zip file that contains all source code as well as the binaries.  I unzipped this file on a PC and just moved the 'bin' folder over to the Pi.  Then using the document above I worked out which file I had to flash to which location and then used this command to write them:

./esptool.py -p /dev/ttyAMA0 write_flash 0x7e000 bin/blank.bin 0x3fe000 bin/blank.bin 0x3fc000 bin/esp_init_data_default.bin 0x00000 bin/boot_v1.5.bin 0x01000 bin/at/512+512/user1.1024.new.2.bin

and after 40 seconds I had this:

Connecting...
Erasing flash...
Took 0.09s to erase flash block
Wrote 4096 bytes at 0x0007e000 in 0.4 seconds (84.2 kbit/s)...
Erasing flash...
Took 0.08s to erase flash block
Wrote 4096 bytes at 0x003fe000 in 0.4 seconds (84.7 kbit/s)...
Erasing flash...
Took 0.08s to erase flash block
Wrote 1024 bytes at 0x003fc000 in 0.1 seconds (84.4 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Wrote 4096 bytes at 0x00000000 in 0.4 seconds (81.5 kbit/s)...
Erasing flash...
Took 1.66s to erase flash block
Wrote 397312 bytes at 0x00001000 in 39.4 seconds (80.7 kbit/s)...

Leaving...


All that remaind was to use the reset command to boot the new firmware, connect with Minicom and check the version:

AT+GMR
AT version:0.60.0.0(Jan 29 2016 15:10:17)
SDK version:1.5.2(80914727)
compile time:Jan 29 2016 19:07:08
OK


and we have flashed new firmware!  
 

4 comments:

  1. great tutorial, shame i got lost at Espressif and what firmware to get, if i try uploading the firmware in the pimoroni directory i get error espflash Invalid head of packet ('\x04')

    ReplyDelete
  2. Thank you. I agree that the Espressif site is difficult to navigate. As of today (20th July) there is a new version of the firmware - ver 2.0.0 and the current direct link to the file is bbs.espressif.com/download/file.php?id=1613 but I'm not sure how long that will remain true. I've also not had a chance to test this version either. Good luck with it.

    ReplyDelete
  3. Thank you so much, Paul, for saving me a load of time! I've worked through the above and now have new firmware running on my ESP8266! :-). I was using a PiMod3 as the host, so I needed to jump through a bunch of hoops to get the serial port working, as the mod3 changed all the serial port workings. But that's all done now and I'm working nicely. I'm using miniterm.py as the terminal, as this has the CR/LF sequence already as default, so no "Ctrl-J" nonsense :-).

    I've bought a bunch of these 8266 modules from china (ebay specials) in the hope of configuring them as cheap wifi ports for zeros (keeping the USB port free) so I now plan to follow the instructions in the following link:

    "https://hackaday.io/project/9300-esp-12f-raspberry-pi-gpio-sdio-wifi"

    I don't suppose you've tried this, have you? Clearly you can't do this with an unmodified phat (or can you? are the correct GPIO lines attached?)

    Doug

    ReplyDelete
  4. Hi,

    Have you ever tried to flash ESP easy (http://www.letscontrolit.com/wiki/index.php/ESPEasy) on the ESP8266 pHAT ? I had no luck - Flashing completes but afterwards ESp is stuck with INIT : Incorrect PID or version!
    RESET: Reboot count: 4
    RESET: To many reset attempts
    Entered Rescue mode!

    The AT firmware flashes without problem. I also have tried out esp link from jeelabs with success. You can use this to get a wifi console to the pi zero. You just need to renable serial in raspi-config after flashing.

    TIA,

    gadget

    ReplyDelete