Skip to content

Commit bc08c88

Browse files
committed
esp32: Add new port to Espressif ESP32 SoC.
This commit is a combination of 216 commits from the initial stages of development of this port, up to and including the point where the code was moved to the ports/esp32 directory. These commits were mostly concerned with setting up the build system and getting a reliable port working with basic features. The following is a digest of the original commits in their original order (most recent listed first), grouped where possible per author. The list is here to give credit for the work and provide some level of traceability and accountability. For the full history of development please consult the original repository. All code is MIT licensed and the relevant copyright holders are listed in the comment-header of each file. Damien George <[email protected]> esp32: Update to latest ESP IDF. esp32: Update module symlinks now that code lives under the ports dir. esp32: Update to compile with new ports/esp32 directory structure. esp32: Move it to the ports/ directory. esp32/machine_uart: Don't save baudrate but compute it instead. esp32/modsocket: Add socket.readinto() method. esp32/modesp: Add esp.gpio_matrix_in and esp.gpio_matrix_out functions. esp32/machine_uart: Wait for all data to be tx'd before changing config. NyxCode <[email protected]> esp32: Add note to README.md about updating the submodules of ESP IDF. Anthony Briggs <[email protected]> esp32: Update README.md installation and flashing instructions. Javier Candeira <[email protected]> esp32: Raise error when setting input-only pin to output. With help from Adrian Smith ([email protected]) Javier Candeira <[email protected]> esp32: Replace exception raising with corresponding mp_raise_XXX funcs. Tisham Dhar <[email protected]> esp32: Add some specific notes about building on Windows using WSL. Ben Gamari <[email protected]> esp32: Provide machine.Signal class. Damien George <[email protected]> esp32/modnetwork: Implement AP version of network.isconnected(). Eric Poulsen <[email protected]> esp32/README.md: Add note about btree submodule initialization. Damien George <[email protected]> esp32: Make firmware.bin start at 0x1000 to allow flash size autodetect. esp32: Changes to follow latest version of upstream uPy. esp32/Makefile: Separate ESP-specific inc dirs to avoid header clashes. esp32: Enable "btree" database module. esp32: Update to latest ESP IDF. Roosted7 <[email protected]> esp32: Update to latest ESP-IDF. Alex King <[email protected]> esp32/machine_timer: Add support for esp32 hardware timer. Code lineage: Timer() is based loosely on the version in esp8266, although the implementation is differs significantly because of the change in the underlying platform. Damien George <[email protected]> esp32/machine_uart: Increase UART TX buffer size to 64. esp32/modules: Update dht symlink. esp32/mpconfigport.h: Enable utimeq module, needed for uasyncio. esp32: Changes to follow latest version of upstream uPy. esp32: Update to latest ESP-IDF. esp32/machine_uart: Add uart.any() method. esp32/machine_uart: Uninstall the UART driver before installing it. Thomas Roos <[email protected]> esp32: Update to latest ESP-IDF. Eric Poulsen <[email protected]> esp32/modsocket: Make read/write return None when in non-blocking mode. esp32/modsocket.c: Fix send/sendto/write for non-blocking sockets. Odd Stråbø <[email protected]> esp32: Initial working implementation of machine.UART. Code lineage (as seen by previous commits): I copied the ESP8266 code, renamed pyb -> machine, and used esp-idf as a reference while implementing minimal functionality. I provide all of my changes under the MIT license. Odd Stråbø <[email protected]> esp32/machine_uart: Rename pyb to machine. esp32: Copy machine_uart.c from esp8266 port. Damien George <[email protected]> esp32/moduos: Add uos.ilistdir() function. esp32: Mount filesystem at the root of the VFS, following esp8266. Andy Valencia <[email protected]> esp32: Add hardware SHA1/SHA256 support via mbedtls API. Code lineage: a copy of extmod/moduhashlib with the API invocation details edited. Total derivative work. Andy Valencia <[email protected]> esp32: Add PWM support via machine.PWM class. Code lineage: I started by copying the esp8266 machine_pwm.c. I used information from the ESP32 Technical Reference Manual, the esp-idf documentation, and the SDK's sample ledc example code (but I did not copy that code, just studied it to understand the SDK's API for PWM). So aside from the code copied from the esp8266 PWM support, everything else you see is just new code I wrote. I wasn't an employee of anybody when I wrote it, and I wrote it with the understanding and intention that it's simply a derivative work of the existing micropython code. I freely and willingly contribute it to the project and intend that it not change the legal status of the micropython code base in any way, even if it is included in that base in whole or part. Damien George <[email protected]> esp32/modules: Add symlinks for upysh and upip. Eric Poulsen <[email protected]> esp32/modmachine: Add unique_id() function to machine module. Damien George <[email protected]> esp32: Change dac_out_voltage to dac_output_voltage for new IDF API. esp32: Update esp32.custom_common.ld to align with changes in ESP IDF. Eric Poulsen <[email protected]> esp32: Update to latest ESP IDF. Damien George <[email protected]> esp32/modsocket: When resolving IP addr handle the case of host=''. esp32: Update to latest ESP IDF. Eric Poulsen <[email protected]> esp32/Makefile: Change default FLASH_MODE to dio for WROOM-32 module. esp32: Move FAT FS to start at 0x200000 and increase size to 2MiB. Damien George <[email protected]> esp32: Remove enable_irq/disable_irq and use ATOMIC_SECTION instead. esp32/mpconfigport.h: Provide ATOMIC_SECTION macros. esp32/main: Restart the MCU if there is a failed NLR jump. Daniel Campora <[email protected]> esp32: Enable threading; be sure to exit GIL when a thread will block. esp32: Trace the registers when doing a gc collect. Also make it thread ready. esp32: Add threading implementation, disabled for the time being. Damien George <[email protected]> esp32: Update to latest ESP IDF. esp32/uart: Use high-level function to install UART0 RX ISR handler. esp32/Makefile: Make FreeRTOS private include dir really private. Eric Poulsen <[email protected]> esp32: Add support for hardware SPI peripheral (block 1 and 2). Sergio Conde Gómez <[email protected]> esp32/modules/inisetup.py: Mount filesystem at /flash like ESP8266 Damien George <[email protected]> esp32: Convert to use core-provided KeyboardInterrupt exception. esp32: Pump the event loop while waiting for rx-chr or delay_ms. esp32: Implement Pin.irq() using "soft" scheduled interrupts. esp32: Update to latest ESP IDF version. Eric Poulsen <[email protected]> esp32/README: Add troubleshooting section to the end. tyggerjai <[email protected]> esp32: Add support for WS2812 and APA106 RGB LEDs. Damien George <[email protected]> esp32: Add makeimg.py script to build full firmware; use it in Makefile. esp32/modsocket: Make socket.read return when socket closes. esp32/modsocket: Initialise the timeout on an accepted socket. esp32/mphalport: Provide proper implementations of disable_/enable_irq. esp32/modmachine: Add disable_irq/enable_irq functions. Nick Moore <[email protected]> esp32/modsocket.c: add comment explaining timeout behaviour esp32/modsocket.c: clean up send methods for retries too esp32/modsocket.c: sockets always nonblocking, accept timeout in modsocket esp32: Update to latest ESP IDF version. esp32/modsocket.c: remove MSG_PEEK workaround on select ioctl. esp32/modsocket.c: Initialize tcp when modsocket loads. Damien George <[email protected]> esp32/main: Bump heap size from 64k to 96k. esp32/modutime: Add time.time() function. esp32/modsocket: Convert lwip errnos to uPy ones. esp32/modules: Provide symlink to ds18x20 module. esp32: Add support for onewire protocol via OneWire module. esp32: Add support for DHT11 and DHT22 sensors. esp32/mphalport: Improve delay and ticks functions. esp32: Update to latest ESP IDF. esp32/modules: Provide symlink to urequests from micropython-lib. esp32: Populate sys.path. Nick Moore <[email protected]> esp32/machine_dac.c: implement DAC pins as well esp32/machine_adc.c: also machine.ADC esp32/machine_touchpad.c: add support for touchpad Damien George <[email protected]> esp32/README: Add hint about using GNUmakefile on case-insensitive FS. esp32/mpconfigport.h: Enable maximum speed software SPI. esp32: Provide improved version of mp_hal_delay_us_fast. esp32/mpconfigport.h: Enable MICROPY_PY_BUILTINS_POW3 option. esp32: Update to latest ESP IDF. esp32: Convert to use new oofatfs library and generic VFS sub-system. esp32: Enable help('modules') to list builtin modules. esp32: Convert to use new builtin help function. Aaron Kelly <[email protected]> esp32/README: Add comment about ESP-IDF version Damien George <[email protected]> esp32: Consistently use size_t instead of mp_uint_t. esp32: Change "Micro Python" to "MicroPython" in license comments. esp32/Makefile: Use -C argument to git instead of cd'ing. esp32/help: Add section to help about using the network module. esp32/README: Add section about configuring and using an ESP32 board. esp32/README: Remove paragraph about buggy toolchain, it's now fixed. esp32/modnetwork: Change network init logging from info to debug. esp32/modnetwork: Don't start AP automatically when init'ing wifi. esp32/modsocket: Implement socket.setsockopt, to support SO_REUSEADDR. esp32: Update to latest ESP IDF. esp32/sdkconfig.h: Remove unused CONFIG_ESPTOOLPY_xxx config settings. esp32/modsocket: Add support for DGRAM and RAW, and sendto/recvfrom. esp32/modsocket: Fix return value of "port" in socket.accept. esp32/modsocket: Make socket.recv take exactly 2 args. esp32: Enable ussl module, using mbedtls component from ESP IDF. esp32/modsocket: Rename "socket" module to "usocket". esp32/sdkconfig: Increase max number of open sockets from 4 to 8. esp32/modsocket: Add error checking for creating and closing sockets. esp32/modsocket: Use _r (re-entrant) versions of LWIP socket API funcs. esp32/modsocket: Raise an exception if socket.connect did not succeed. esp32/modsocket: Make socket.accept return a tuple: (client, addr). esp32/modsocket: Use m_new_obj_with_finaliser instead of calloc. esp32/Makefile: Add check for IDF version, and warn if not supported. esp32/esp32.custom_common.ld: Update to follow changes in IDF. esp32: Update to latest ESP IDF. nubcore <[email protected]> esp32: add #define CONFIG_ESP32_WIFI_RX_BUFFER_NUM 25 Nick Moore <[email protected]> esp32/modsocket.c: add in sendall and makefile methods lvgl#10 esp32/modsocket.c: fixups for lvgl#10 esp32/modsocket.c: fix copyright, socket_recv gets param and exception esp32/modnetwork.c: fix copyright, network.active param to bool Damien George <[email protected]> esp32/modnetwork: Implement wlan.isconnected() method. esp32/modnetwork: Add initial implementation of wlan.config(). esp32/modnetwork: Simplify event_handler messages. Nick Moore <[email protected]> esp32/modsocket.c: support for ioctl, settimeout, setblocking, getaddrinfo Damien George <[email protected]> esp32/README: Add comment about FLASH_MODE being dio. esp32: Update to latest ESP IDF. esp32/modnetwork: Remove unnecessary indirection variable for scan list. esp32/modnetwork: Check that STA is active before trying to scan. esp32/mphalport: Replace portTICK_RATE_MS with portTICK_PERIOD_MS. esp32/README: Add comment about using $(HOME) in makefile. esp32/modnetwork: Use memset instead of bzero, the latter is deprecated. esp32/modnetwork: Improve error handling when STA is connecting to AP. esp32/Makefile: Use tab instead of spaces, and use shorter variable. Nick Moore <[email protected]> esp32/modsocket.c: AF_*, SOCK_* and IPPROTO_* constants esp32/modsocket.c: socket.settimeout implementation Damien George <[email protected]> esp32/Makefile: Update to latest ESP IDF. Nick Moore <[email protected]> esp32/modsocket.c: use mp streams for sockets esp32: network.WLAN.ifconfig based on esp8266 version esp32: Fix up exception handling esp32: sketchy modsocket ... revisit this once modnetwork is sorted esp32: First cut at modnetwork, manually rebased from prev. version Damien George <[email protected]> esp32/help: Update help text. esp32: Add info about Microbric Pty Ltd being the sponsor of this port. esp32: Add README.md file. esp32/mpconfigport.h: Add weak links to many of the builtin modules. esp32: Enable soft implementation of machine.SPI class. esp32/Makefile: Simplify APP_LD_ARGS by using OBJ variable. esp32/Makefile: Reorganise Makefile and add some comments. esp32/Makefile: Clean up CFLAGS for ESP IDF components. esp32/Makefile: Tidy up names of ESP IDF components, to match dir name. esp32/Makefile: Define and use ESPCOMP variable. esp32: Update to latest ESP IDF. esp32/main: Enable filesystem support. esp32: Use custom ld script to ensure correct code get placed in iram. esp32: Update to latest ESP IDF. esp32/main: Pin the uPy task to core 0. esp32: Update to use latest ESP IDF. esp32: Disable boot-up scripts, spi_flash_erase_sector no longer works. esp32: Add scripts to init and mount filesystem. esp32: Enable frozen bytecode, with scripts stored in "modules/" dir. esp32/modesp: Increase flash_user_start position to 1Mbyte. esp32/Makefile: Add "erase" target for convenient erasure. esp32/sdkconfig: Reorder config settings to put common things together. esp32/sdkconfig: Change to use single core only. esp32: Add esp module. esp32/uart.c: Make sure uart ISR handler is all in iram. esp32/main.c: Use ESP_TASK_PRIO_MIN + 1 for mp_task's priority. esp32/Makefile: Use only bare-minimum flags when compiling .S files. esp32/Makefile: Rename "firmware" to "application". esp32: Update ESP IDF version. esp32/Makefile: Add declarations to build bootloader and partitions. esp32/Makefile: When deploying, write the application last. esp32/Makefile: Use $(INC) variable instead of listing include dirs. esp32/Makefile: Use locally built versions of freertos and newlib libs. esp32: Add low-level uart handler with ISR and ringbuf for stdin. esp32: Add machine.idle() function. esp32: Add machine.I2C class. esp32: Enable machine.time_pulse_us. esp32: Add initial implementation of machine.Pin class. esp32: Prepare main.c for using xTaskCreateStatic. esp32: Clean up mphalport.h. esp32: Add initial uos module. esp32: Clean up mpconfigport.h, enable more features. esp32: Use new reset function. esp32: Update to latest ESP IDF. esp32: Add idf-version target to Makefile, to track IDF commit. esp32: Initial port to ESP32.
1 parent f1c9e77 commit bc08c88

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+6463
-0
lines changed

ports/esp32/Makefile

+719
Large diffs are not rendered by default.

ports/esp32/README.md

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
MicroPython port to the ESP32
2+
=============================
3+
4+
This is an experimental port of MicroPython to the Espressif ESP32
5+
microcontroller. It uses the ESP-IDF framework and MicroPython runs as
6+
a task under FreeRTOS.
7+
8+
Supported features include:
9+
- REPL (Python prompt) over UART0.
10+
- 16k stack for the MicroPython task and 64k Python heap.
11+
- Many of MicroPython's features are enabled: unicode, arbitrary-precision
12+
integers, single-precision floats, complex numbers, frozen bytecode, as
13+
well as many of the internal modules.
14+
- Internal filesystem using the flash (currently 256k in size).
15+
- The machine module with basic GPIO and bit-banging I2C, SPI support.
16+
17+
Development of this ESP32 port was sponsored in part by Microbric Pty Ltd.
18+
19+
Setting up the toolchain and ESP-IDF
20+
------------------------------------
21+
22+
There are two main components that are needed to build the firmware:
23+
- the Xtensa cross-compiler that targets the CPU in the ESP32 (this is
24+
different to the compiler used by the ESP8266)
25+
- the Espressif IDF (IoT development framework, aka SDK)
26+
27+
Instructions for setting up both of these components are provided by the
28+
ESP-IDF itself, which is found at https://github.com/espressif/esp-idf .
29+
Follow the guide "Setting Up ESP-IDF", for Windows, Mac or Linux. You
30+
only need to perform up to "Step 2" of the guide, by which stage you
31+
should have installed the cross-compile and cloned the ESP-IDF repository.
32+
33+
If you are on a Windows machine then the
34+
[Windows Subsystem for Linux](https://msdn.microsoft.com/en-au/commandline/wsl/install_guide)
35+
is the most efficient way to install the ESP32 toolchain and build the project.
36+
If you use WSL then follow the
37+
[Linux guidelines](http://esp-idf.readthedocs.io/en/latest/get-started/linux-setup.html)
38+
for the ESP-IDF instead of the Windows ones.
39+
40+
Be advised that the ESP-IDF is still undergoing changes and only some
41+
versions are supported. To find which build is compatible refer to the line
42+
in the makefile containing the following:
43+
```
44+
ESPIDF_SUPHASH := <Current supported ESP-IDF commit hash>
45+
```
46+
After finishing "Step 2" you can roll back your current build of
47+
the ESP-IDF (and update the submodules accordingly) using:
48+
```
49+
$ git checkout <Current supported ESP-IDF commit hash>
50+
$ git submodule update --recursive
51+
```
52+
Note that you will get a warning when building the code if the ESP-IDF
53+
version is incorrect.
54+
55+
The Espressif ESP-IDF instructions above only install pyserial for Python 2,
56+
so if you're running Python 3 or a non-system Python you'll also need to
57+
install `pyserial` (or `esptool`) so that the Makefile can flash the board
58+
and set parameters:
59+
```bash
60+
$ pip install pyserial
61+
```
62+
63+
Once everything is set up you should have a functioning toolchain with
64+
prefix xtensa-esp32-elf- (or otherwise if you configured it differently)
65+
as well as a copy of the ESP-IDF repository.
66+
67+
You then need to set the `ESPIDF` environment/makefile variable to point to
68+
the root of the ESP-IDF repository. You can set the variable in your PATH,
69+
or at the command line when calling make, or in your own custom `makefile`.
70+
The last option is recommended as it allows you to easily configure other
71+
variables for the build. In that case, create a new file in the esp32
72+
directory called `makefile` and add the following lines to that file:
73+
```
74+
ESPIDF = <path to root of esp-idf repository>
75+
#PORT = /dev/ttyUSB0
76+
#FLASH_MODE = qio
77+
#FLASH_SIZE = 4MB
78+
#CROSS_COMPILE = xtensa-esp32-elf-
79+
80+
include Makefile
81+
```
82+
Be sure to enter the correct path to your local copy of the IDF repository
83+
(and use `$(HOME)`, not tilde, to reference your home directory).
84+
If your filesystem is case-insensitive then you'll need to use `GNUmakefile`
85+
instead of `makefile`.
86+
If the Xtensa cross-compiler is not in your path you can use the
87+
`CROSS_COMPILE` variable to set its location. Other options of interest
88+
are `PORT` for the serial port of your esp32 module, and `FLASH_MODE`
89+
(which may need to be `dio` for some modules)
90+
and `FLASH_SIZE`. See the Makefile for further information.
91+
92+
Building the firmware
93+
---------------------
94+
95+
The MicroPython cross-compiler must be built to pre-compile some of the
96+
built-in scripts to bytecode. This can be done by (from the root of
97+
this repository):
98+
```bash
99+
$ make -C mpy-cross
100+
```
101+
102+
The ESP32 port has a dependency on Berkeley DB, which is an external
103+
dependency (git submodule). You'll need to have git initialize that
104+
module using the commands:
105+
```bash
106+
$ git submodule init lib/berkeley-db-1.xx
107+
$ git submodule update
108+
```
109+
110+
Then to build MicroPython for the ESP32 run:
111+
```bash
112+
$ cd ports/esp32
113+
$ make
114+
```
115+
This will produce binary firmware images in the `build/` subdirectory
116+
(three of them: bootloader.bin, partitions.bin and application.bin).
117+
118+
To flash the firmware you must have your ESP32 module in the bootloader
119+
mode and connected to a serial port on your PC. Refer to the documentation
120+
for your particular ESP32 module for how to do this. The serial port and
121+
flash settings are set in the `Makefile`, and can be overridden in your
122+
local `makefile`; see above for more details.
123+
124+
You will also need to have user permissions to access the /dev/ttyUSB0 device.
125+
On Linux, you can enable this by adding your user to the `dialout` group,
126+
and rebooting or logging out and in again.
127+
```bash
128+
$ sudo adduser <username> dialout
129+
```
130+
131+
If you are installing MicroPython to your module for the first time, or
132+
after installing any other firmware, you should first erase the flash
133+
completely:
134+
```bash
135+
$ make erase
136+
```
137+
138+
To flash the MicroPython firmware to your ESP32 use:
139+
```bash
140+
$ make deploy
141+
```
142+
This will use the `esptool.py` script (provided by ESP-IDF) to download the
143+
binary images.
144+
145+
Getting a Python prompt
146+
-----------------------
147+
148+
You can get a prompt via the serial port, via UART0, which is the same UART
149+
that is used for programming the firmware. The baudrate for the REPL is
150+
115200 and you can use a command such as:
151+
```bash
152+
$ picocom -b 115200 /dev/ttyUSB0
153+
```
154+
155+
Configuring the WiFi and using the board
156+
----------------------------------------
157+
158+
The ESP32 port is designed to be (almost) equivalent to the ESP8266 in
159+
terms of the modules and user-facing API. There are some small differences,
160+
notably that the ESP32 does not automatically connect to the last access
161+
point when booting up. But for the most part the documentation and tutorials
162+
for the ESP8266 should apply to the ESP32 (at least for the components that
163+
are implemented).
164+
165+
See http://docs.micropython.org/en/latest/esp8266/esp8266/quickref.html for
166+
a quick reference, and http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/intro.html
167+
for a tutorial.
168+
169+
The following function can be used to connect to a WiFi access point (you can
170+
either pass in your own SSID and password, or change the defaults so you can
171+
quickly call `wlan_connect()` and it just works):
172+
```python
173+
def wlan_connect(ssid='MYSSID', password='MYPASS'):
174+
import network
175+
wlan = network.WLAN(network.STA_IF)
176+
if not wlan.active() or not wlan.isconnected():
177+
wlan.active(True)
178+
print('connecting to:', ssid)
179+
wlan.connect(ssid, password)
180+
while not wlan.isconnected():
181+
pass
182+
print('network config:', wlan.ifconfig())
183+
```
184+
185+
Note that some boards require you to configure the WiFi antenna before using
186+
the WiFi. On Pycom boards like the LoPy and WiPy 2.0 you need to execute the
187+
following code to select the internal antenna (best to put this line in your
188+
boot.py file):
189+
```python
190+
import machine
191+
antenna = machine.Pin(16, machine.Pin.OUT, value=0)
192+
```
193+
194+
Troubleshooting
195+
---------------
196+
197+
* Continuous reboots after programming: Ensure FLASH_MODE is correct for your
198+
board (e.g. ESP-WROOM-32 should be DIO). Then perform a `make clean`, rebuild,
199+
redeploy.

0 commit comments

Comments
 (0)