Skip to content

WIP: esp32: Add support to build using IDF cmake, with MicroPython as a cmake component #6473

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

Closed
wants to merge 10 commits into from
34 changes: 10 additions & 24 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -268,39 +268,25 @@ jobs:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32-

# esp32 w/ESP-IDFv3 port
# esp32 port
- stage: test
name: "esp32 ESP-IDFv3 port build"
name: "esp32 port build"
install:
- sudo apt-get install python3-pip
- sudo pip3 install 'pyparsing<2.4'
- curl -L https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz | tar zxf -
- cmake --version
- curl -L https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp-2020r2-linux-amd64.tar.gz | tar zxf -
- export PATH=$(pwd)/xtensa-esp32-elf/bin:$PATH
- git clone https://github.com/espressif/esp-idf.git
- git -C esp-idf checkout v4.1
- git -C esp-idf submodule update --init
- export IDF_PATH=$(pwd)/esp-idf
script:
- make ${MAKEOPTS} -C mpy-cross
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V3 :=" ports/esp32/Makefile | cut -d " " -f 3)
- git -C esp-idf submodule update --init components/json/cJSON components/esp32/lib components/esptool_py/esptool components/expat/expat components/lwip/lwip components/mbedtls/mbedtls components/micro-ecc/micro-ecc components/nghttp/nghttp2 components/nimble components/bt
- make ${MAKEOPTS} -C ports/esp32 submodules
- make ${MAKEOPTS} -C ports/esp32

# esp32 w/ESP-IDFv4 port
- stage: test
name: "esp32 ESP-IDFv4 port build"
install:
- sudo apt-get install python3-pip
- sudo pip3 install 'pyparsing<2.4'
- curl -L https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp-2019r2-linux-amd64.tar.gz | tar zxf -
- export PATH=$(pwd)/xtensa-esp32-elf/bin:$PATH
- git clone https://github.com/espressif/esp-idf.git
- export IDF_PATH=$(pwd)/esp-idf
- sudo pip3 install setuptools
- sudo pip3 install -r $IDF_PATH/requirements.txt
script:
- make ${MAKEOPTS} -C mpy-cross
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V4 :=" ports/esp32/Makefile | cut -d " " -f 3)
- git -C esp-idf submodule update --init components/bt/controller/lib components/bt/host/nimble/nimble components/esp_wifi/lib_esp32 components/esptool_py/esptool components/lwip/lwip components/mbedtls/mbedtls
- make ${MAKEOPTS} -C ports/esp32 submodules
- make ${MAKEOPTS} -C ports/esp32
- (mkdir build && cd build && cmake -D PYTHON=python3 ../ports/esp32)
- make ${MAKEOPTS} -C build

# esp8266 port
- stage: test
Expand Down
42 changes: 42 additions & 0 deletions extmod/extmod.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# CMake fragment for MicroPython extmod component

set(MPY_EXTMOD_DIR "${MPY_DIR}/extmod")
set(OOFATFS_DIR "${MPY_DIR}/lib/oofatfs")

set(SOURCE_EXTMOD
${MPY_EXTMOD_DIR}/machine_i2c.c
${MPY_EXTMOD_DIR}/machine_mem.c
${MPY_EXTMOD_DIR}/machine_pulse.c
${MPY_EXTMOD_DIR}/machine_signal.c
${MPY_EXTMOD_DIR}/machine_spi.c
${MPY_EXTMOD_DIR}/modbtree.c
${MPY_EXTMOD_DIR}/modframebuf.c
${MPY_EXTMOD_DIR}/moduasyncio.c
${MPY_EXTMOD_DIR}/modubinascii.c
${MPY_EXTMOD_DIR}/moducryptolib.c
${MPY_EXTMOD_DIR}/moductypes.c
${MPY_EXTMOD_DIR}/moduhashlib.c
${MPY_EXTMOD_DIR}/moduheapq.c
${MPY_EXTMOD_DIR}/modujson.c
${MPY_EXTMOD_DIR}/modurandom.c
${MPY_EXTMOD_DIR}/modure.c
${MPY_EXTMOD_DIR}/moduselect.c
${MPY_EXTMOD_DIR}/modussl_axtls.c
${MPY_EXTMOD_DIR}/modussl_mbedtls.c
${MPY_EXTMOD_DIR}/modutimeq.c
${MPY_EXTMOD_DIR}/moduwebsocket.c
${MPY_EXTMOD_DIR}/moduzlib.c
${MPY_EXTMOD_DIR}/modwebrepl.c
${MPY_EXTMOD_DIR}/uos_dupterm.c
${MPY_EXTMOD_DIR}/utime_mphal.c
${MPY_EXTMOD_DIR}/vfs.c
${MPY_EXTMOD_DIR}/vfs_blockdev.c
${MPY_EXTMOD_DIR}/vfs_fat.c
${MPY_EXTMOD_DIR}/vfs_fat_diskio.c
${MPY_EXTMOD_DIR}/vfs_fat_file.c
${MPY_EXTMOD_DIR}/vfs_lfs.c
${MPY_EXTMOD_DIR}/vfs_posix.c
${MPY_EXTMOD_DIR}/vfs_posix_file.c
${MPY_EXTMOD_DIR}/vfs_reader.c
${MPY_EXTMOD_DIR}/virtpin.c
)
5 changes: 5 additions & 0 deletions ports/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.5)
set(SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig)
set(SDKCONFIG_DEFAULTS boards/sdkconfig.base)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(micropython)
5 changes: 5 additions & 0 deletions ports/esp32/boards/sdkconfig.base
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ CONFIG_PPP_SUPPORT=y
CONFIG_PPP_PAP_SUPPORT=y
CONFIG_PPP_CHAP_SUPPORT=y
CONFIG_ULP_COPROC_ENABLED=y

# For cmake build
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
2 changes: 1 addition & 1 deletion ports/esp32/esp32_rmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ STATIC mp_obj_t esp32_rmt_write_pulses(size_t n_args, const mp_obj_t *pos_args,
mp_obj_t pulses = args[1].u_obj;
mp_uint_t start = args[2].u_int;

if (start < 0 || start > 1) {
if (start > 1) {
mp_raise_ValueError(MP_ERROR_TEXT("start must be 0 or 1"));
}

Expand Down
24 changes: 13 additions & 11 deletions ports/esp32/machine_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include "py/mperrno.h"
#include "modmachine.h"

#define UART_LINE_INV_MASK (0xff)

typedef struct _machine_uart_obj_t {
mp_obj_base_t base;
uart_port_t uart_num;
Expand Down Expand Up @@ -68,28 +70,28 @@ STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
if (self->invert) {
mp_printf(print, ", invert=");
uint32_t invert_mask = self->invert;
if (invert_mask & UART_INVERSE_TXD) {
if (invert_mask & UART_SIGNAL_TXD_INV) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with esp-idf pre-4.1? Or is the idea to deprecate the use of older esp-idf versions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get that far, I just wanted to get something working and get feedback (will add WIP to the PR title).

We can continue to support older IDF versions if it's not difficult, but I'd rather just support the latest (easier to test, etc).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NP, I just wanted to flag it.

mp_printf(print, "INV_TX");
invert_mask &= ~UART_INVERSE_TXD;
invert_mask &= ~UART_SIGNAL_TXD_INV;
if (invert_mask) {
mp_printf(print, "|");
}
}
if (invert_mask & UART_INVERSE_RXD) {
if (invert_mask & UART_SIGNAL_RXD_INV) {
mp_printf(print, "INV_RX");
invert_mask &= ~UART_INVERSE_RXD;
invert_mask &= ~UART_SIGNAL_RXD_INV;
if (invert_mask) {
mp_printf(print, "|");
}
}
if (invert_mask & UART_INVERSE_RTS) {
if (invert_mask & UART_SIGNAL_RTS_INV) {
mp_printf(print, "INV_RTS");
invert_mask &= ~UART_INVERSE_RTS;
invert_mask &= ~UART_SIGNAL_RTS_INV;
if (invert_mask) {
mp_printf(print, "|");
}
}
if (invert_mask & UART_INVERSE_CTS) {
if (invert_mask & UART_SIGNAL_CTS_INV) {
mp_printf(print, "INV_CTS");
}
}
Expand Down Expand Up @@ -380,10 +382,10 @@ STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },

{ MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERSE_TXD) },
{ MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERSE_RXD) },
{ MP_ROM_QSTR(MP_QSTR_INV_RTS), MP_ROM_INT(UART_INVERSE_RTS) },
{ MP_ROM_QSTR(MP_QSTR_INV_CTS), MP_ROM_INT(UART_INVERSE_CTS) },
{ MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_SIGNAL_TXD_INV) },
{ MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_SIGNAL_RXD_INV) },
{ MP_ROM_QSTR(MP_QSTR_INV_RTS), MP_ROM_INT(UART_SIGNAL_RTS_INV) },
{ MP_ROM_QSTR(MP_QSTR_INV_CTS), MP_ROM_INT(UART_SIGNAL_CTS_INV) },
};

STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
Expand Down
123 changes: 123 additions & 0 deletions ports/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Set location of base MicroPython directory, and this port's directory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this file have to be in a subdirectory? (I know nothing about cmake)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Or at least I couldn't work out how to put it in ports/esp32/ directly...

get_filename_component(MPY_DIR ${PROJECT_DIR}/../.. ABSOLUTE)
set(MPY_PORT_DIR ${PROJECT_DIR})
set(MPY_BOARD_DIR ${PROJECT_DIR}/boards/GENERIC)

# Include core source components.
include(${MPY_DIR}/py/py.cmake)
include(${MPY_DIR}/extmod/extmod.cmake)

set(SOURCE_EXTMOD_EXTRA
${MPY_DIR}/extmod/modonewire.c
)

set(SOURCE_LIB
${MPY_DIR}/lib/littlefs/lfs1.c
${MPY_DIR}/lib/littlefs/lfs1_util.c
${MPY_DIR}/lib/littlefs/lfs2.c
${MPY_DIR}/lib/littlefs/lfs2_util.c
${MPY_DIR}/lib/mbedtls_errors/mp_mbedtls_errors.c
${MPY_DIR}/lib/mp-readline/readline.c
${MPY_DIR}/lib/netutils/netutils.c
${MPY_DIR}/lib/oofatfs/ff.c
${MPY_DIR}/lib/oofatfs/ffunicode.c
${MPY_DIR}/lib/timeutils/timeutils.c
${MPY_DIR}/lib/utils/interrupt_char.c
${MPY_DIR}/lib/utils/stdout_helpers.c
${MPY_DIR}/lib/utils/sys_stdio_mphal.c
${MPY_DIR}/lib/utils/pyexec.c
)

set(SOURCE_DRIVERS
${MPY_DIR}/drivers/bus/softspi.c
${MPY_DIR}/drivers/dht/dht.c
)

set(SOURCE_PORT
${PROJECT_DIR}/main.c
${PROJECT_DIR}/uart.c
${PROJECT_DIR}/gccollect.c
${PROJECT_DIR}/mphalport.c
${PROJECT_DIR}/fatfs_port.c
${PROJECT_DIR}/help.c
${PROJECT_DIR}/modutime.c
${PROJECT_DIR}/moduos.c
${PROJECT_DIR}/machine_timer.c
${PROJECT_DIR}/machine_pin.c
${PROJECT_DIR}/machine_touchpad.c
${PROJECT_DIR}/machine_adc.c
${PROJECT_DIR}/machine_dac.c
${PROJECT_DIR}/machine_i2c.c
${PROJECT_DIR}/machine_pwm.c
${PROJECT_DIR}/machine_uart.c
${PROJECT_DIR}/modmachine.c
${PROJECT_DIR}/modnetwork.c
${PROJECT_DIR}/network_lan.c
${PROJECT_DIR}/network_ppp.c
${PROJECT_DIR}/mpnimbleport.c
${PROJECT_DIR}/modsocket.c
${PROJECT_DIR}/modesp.c
${PROJECT_DIR}/esp32_partition.c
${PROJECT_DIR}/esp32_rmt.c
${PROJECT_DIR}/esp32_ulp.c
${PROJECT_DIR}/modesp32.c
${PROJECT_DIR}/espneopixel.c
${PROJECT_DIR}/machine_hw_spi.c
${PROJECT_DIR}/machine_wdt.c
${PROJECT_DIR}/mpthreadport.c
${PROJECT_DIR}/machine_rtc.c
${PROJECT_DIR}/machine_sdcard.c
)

set(SOURCE_QSTR
${SOURCE_PY}
${SOURCE_EXTMOD}
${SOURCE_EXTMOD_EXTRA}
${SOURCE_LIB}
${SOURCE_PORT}
)

# Register the main IDF component.
idf_component_register(
SRCS
${SOURCE_PY}
${SOURCE_EXTMOD}
${SOURCE_EXTMOD_EXTRA}
${SOURCE_LIB}
${SOURCE_DRIVERS}
${SOURCE_PORT}
INCLUDE_DIRS
${MPY_DIR}
${MPY_PORT_DIR}
${MPY_BOARD_DIR}
${CMAKE_BINARY_DIR}
REQUIRES
soc nvs_flash ulp sdmmc mdns app_update lwip
)

# Define mpy-cross flags and frozen manifest
set(MPY_CROSS_FLAGS -march=xtensawin)
set(FROZEN_MANIFEST ${PROJECT_DIR}/boards/manifest.py)

# Include the main MicroPython cmake rules.
set(MICROPYTHON_TARGET ${COMPONENT_TARGET})
include(${MPY_DIR}/py/mkrules.cmake)

# Set compile options for this port.
target_compile_options(${MICROPYTHON_TARGET} PUBLIC
-DMICROPY_ESP_IDF_4=1
-DMICROPY_VFS_FAT=1
-DMICROPY_VFS_LFS2=1
-DFFCONF_H=\"${OOFATFS_DIR}/ffconf.h\"
-DLFS1_NO_MALLOC -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR -DLFS1_NO_ASSERT
-DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT
)

# Disable some warnings to keep the build output clean.
target_compile_options(${MICROPYTHON_TARGET} PUBLIC
-Wno-clobbered
-Wno-deprecated-declarations
-Wno-implicit-fallthrough
-Wno-missing-field-initializers
-Wno-override-init
)
7 changes: 3 additions & 4 deletions ports/esp32/modnetwork.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
#include "esp_wifi.h"
#include "esp_log.h"
#include "lwip/dns.h"
#include "tcpip_adapter.h"
#include "mdns.h"

#if !MICROPY_ESP_IDF_4
Expand Down Expand Up @@ -491,7 +490,7 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
tcpip_adapter_ip_info_t info;
tcpip_adapter_dns_info_t dns_info;
tcpip_adapter_get_ip_info(self->if_id, &info);
tcpip_adapter_get_dns_info(self->if_id, TCPIP_ADAPTER_DNS_MAIN, &dns_info);
tcpip_adapter_get_dns_info(self->if_id, ESP_NETIF_DNS_MAIN, &dns_info);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compat with older esp-idf?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but easy to make it compat.

if (n_args == 1) {
// get
mp_obj_t tuple[4] = {
Expand Down Expand Up @@ -526,14 +525,14 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
_esp_exceptions(e);
}
ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(self->if_id, &info));
ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(self->if_id, TCPIP_ADAPTER_DNS_MAIN, &dns_info));
ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(self->if_id, ESP_NETIF_DNS_MAIN, &dns_info));
} else if (self->if_id == WIFI_IF_AP) {
esp_err_t e = tcpip_adapter_dhcps_stop(WIFI_IF_AP);
if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) {
_esp_exceptions(e);
}
ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(WIFI_IF_AP, &info));
ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(WIFI_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info));
ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(WIFI_IF_AP, ESP_NETIF_DNS_MAIN, &dns_info));
ESP_EXCEPTIONS(tcpip_adapter_dhcps_start(WIFI_IF_AP));
}
} else {
Expand Down
3 changes: 1 addition & 2 deletions ports/esp32/modsocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
#include "py/stream.h"
#include "py/mperrno.h"
#include "lib/netutils/netutils.h"
#include "tcpip_adapter.h"
#include "mdns.h"
#include "modnetwork.h"

Expand Down Expand Up @@ -181,7 +180,7 @@ static int _socket_getaddrinfo3(const char *nodename, const char *servname,
memcpy(nodename_no_local, nodename, nodename_len - local_len);
nodename_no_local[nodename_len - local_len] = '\0';

struct ip4_addr addr = {0};
esp_ip4_addr_t addr = {0};
esp_err_t err = mdns_query_a(nodename_no_local, MDNS_QUERY_TIMEOUT_MS, &addr);
if (err != ESP_OK) {
if (err == ESP_ERR_NOT_FOUND) {
Expand Down
1 change: 1 addition & 0 deletions ports/esp32/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <stdio.h>

#include "driver/uart.h"
#include "soc/uart_periph.h"

#include "py/runtime.h"
#include "py/mphal.h"
Expand Down
Loading