diff --git a/README.md b/README.md
index f6f53b7a5f774e2267635f5a8752e908e386f129..9f18cba83d169c07928887a505996d6eafaf9126 100644
--- a/README.md
+++ b/README.md
@@ -18,17 +18,17 @@ Please transfer all .py files in python_payload/ for using the demo payload.
 
 ## How to install dependencies
 
-Pay attention to install version 4.4.5. Other versions (specifically 5.x) did not work. To be sure follow the generic instructions below.
+Pay attention to install version 5.1. To be sure follow the generic instructions below.
 
 ### Generic
 
-1. install esp-idf v4.4.5:
+1. install esp-idf v5.1:
 (copied from https://www.wemos.cc/en/latest/tutorials/others/build\_micropython\_esp32.html)
 ```
 $ cd ~
 $ git clone https://github.com/espressif/esp-idf.git
 $ cd esp-idf
-$ git checkout v4.4.5
+$ git checkout v5.1
 $ git submodule update --init --recursive
 
 $ cd esp-idf
diff --git a/components/bl00mbox/bl00mbox.c b/components/bl00mbox/bl00mbox.c
index 7fc6569b68c21c0d990d15b9e7d21626df81a826..8559cef7397fb652a969067516efb97202cedb74 100644
--- a/components/bl00mbox/bl00mbox.c
+++ b/components/bl00mbox/bl00mbox.c
@@ -20,7 +20,7 @@ static audio_source_t * _audio_sources = NULL;
 uint16_t bl00mbox_source_add(void * render_data, void * render_function){
     //construct audio source struct
     audio_source_t * src = malloc(sizeof(audio_source_t));
-    if(src == NULL) return;
+    if(src == NULL) return 0;
     src->render_data = render_data;
     src->render_function = render_function;
     src->next = NULL;
diff --git a/components/flow3r_bsp/CMakeLists.txt b/components/flow3r_bsp/CMakeLists.txt
index 9414a39ee6c382900b5d0204e23c8be4feb341fb..241f4533cc7d7d63a0442d89dd2bc4178f09fcde 100644
--- a/components/flow3r_bsp/CMakeLists.txt
+++ b/components/flow3r_bsp/CMakeLists.txt
@@ -13,4 +13,7 @@ idf_component_register(
 		flow3r_bsp_spio.c
     INCLUDE_DIRS
 		.
+    REQUIRES
+		driver
+		vfs
 )
diff --git a/components/flow3r_bsp/flow3r_bsp.h b/components/flow3r_bsp/flow3r_bsp.h
index def81e768bbe91854ad0b4c8ec5f97ec6d8696a8..2b807720c3decc30f8540038fdd4243e95531f9e 100644
--- a/components/flow3r_bsp/flow3r_bsp.h
+++ b/components/flow3r_bsp/flow3r_bsp.h
@@ -34,7 +34,7 @@ void flow3r_bsp_display_set_backlight(uint8_t percent);
 #define FLOW3R_BSP_DISPLAY_HEIGHT 240
 
 // Badge hardware generation name, human-readable.
-const char *flow3r_bsp_hw_name;
+extern const char *flow3r_bsp_hw_name;
 
 #define FLOW3R_BSP_AUDIO_SAMPLE_RATE 48000
 #define FLOW3R_BSP_AUDIO_DMA_BUFFER_SIZE 64
diff --git a/components/flow3r_bsp/flow3r_bsp_i2c.c b/components/flow3r_bsp/flow3r_bsp_i2c.c
index 576a2beb60bf915b6f73e17d50cb2ff5bae54b6a..50354cb0d8ea6d1a01f3aaa7365070df4834bf42 100644
--- a/components/flow3r_bsp/flow3r_bsp_i2c.c
+++ b/components/flow3r_bsp/flow3r_bsp_i2c.c
@@ -108,7 +108,7 @@ void flow3r_bsp_i2c_scan(void) {
 		i2c_master_start(cmd);
         i2c_master_write_byte(cmd, (i << 1) | I2C_MASTER_WRITE, 1);
 		i2c_master_stop(cmd);
-		esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 100 / portTICK_RATE_MS);
+		esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 100 / portTICK_PERIOD_MS);
         i2c_cmd_link_delete(cmd);
 		if (ret == ESP_OK) {
 			ESP_LOGI(TAG, "Scan: detected %02x", i);
diff --git a/components/micropython/CMakeLists.txt b/components/micropython/CMakeLists.txt
index 9ab7329ac039acc85a4f54cdea044e18d8dd064b..ce77a29e5c3e625544ba5345a90945a4bd8f2f6c 100644
--- a/components/micropython/CMakeLists.txt
+++ b/components/micropython/CMakeLists.txt
@@ -42,7 +42,6 @@ set(MICROPY_SOURCE_LIB
     ${MICROPY_DIR}/lib/littlefs/lfs1_util.c
     ${MICROPY_DIR}/lib/littlefs/lfs2.c
     ${MICROPY_DIR}/lib/littlefs/lfs2_util.c
-    ${MICROPY_DIR}/lib/mbedtls_errors/mp_mbedtls_errors.c
     ${MICROPY_DIR}/lib/oofatfs/ff.c
     ${MICROPY_DIR}/lib/oofatfs/ffunicode.c
 )
@@ -55,23 +54,16 @@ set(MICROPY_SOURCE_DRIVERS
 set(MICROPY_SOURCE_PORT
     ${MICROPY_PORT_DIR}/main.c
     ${MICROPY_PORT_DIR}/uart.c
-    ${MICROPY_PORT_DIR}/usb.c
-    ${MICROPY_PORT_DIR}/usb_serial_jtag.c
     ${MICROPY_PORT_DIR}/gccollect.c
     ${MICROPY_PORT_DIR}/mphalport.c
     ${MICROPY_PORT_DIR}/fatfs_port.c
     ${MICROPY_PORT_DIR}/help.c
     ${MICROPY_PORT_DIR}/modutime.c
-    ${MICROPY_PORT_DIR}/machine_bitstream.c
-    ${MICROPY_PORT_DIR}/machine_timer.c
     ${MICROPY_PORT_DIR}/machine_pin.c
-    ${MICROPY_PORT_DIR}/machine_touchpad.c
+    ${MICROPY_PORT_DIR}/machine_timer.c
+    ${MICROPY_PORT_DIR}/machine_uart.c
     ${MICROPY_PORT_DIR}/machine_adc.c
     ${MICROPY_PORT_DIR}/machine_adcblock.c
-    ${MICROPY_PORT_DIR}/machine_dac.c
-    ${MICROPY_PORT_DIR}/machine_i2c.c
-    ${MICROPY_PORT_DIR}/machine_i2s.c
-    ${MICROPY_PORT_DIR}/machine_uart.c
     ${MICROPY_PORT_DIR}/modmachine.c
     ${MICROPY_PORT_DIR}/network_common.c
     ${MICROPY_PORT_DIR}/network_lan.c
@@ -79,17 +71,14 @@ set(MICROPY_SOURCE_PORT
     ${MICROPY_PORT_DIR}/network_wlan.c
     ${MICROPY_PORT_DIR}/mpnimbleport.c
     ${MICROPY_PORT_DIR}/modsocket.c
-    ${MICROPY_PORT_DIR}/modesp.c
     ${MICROPY_PORT_DIR}/esp32_nvs.c
     ${MICROPY_PORT_DIR}/esp32_partition.c
-    ${MICROPY_PORT_DIR}/esp32_rmt.c
     ${MICROPY_PORT_DIR}/esp32_ulp.c
     ${MICROPY_PORT_DIR}/modesp32.c
-    ${MICROPY_PORT_DIR}/machine_hw_spi.c
-    ${MICROPY_PORT_DIR}/machine_wdt.c
     ${MICROPY_PORT_DIR}/mpthreadport.c
     ${MICROPY_PORT_DIR}/machine_rtc.c
-    ${MICROPY_PORT_DIR}/machine_sdcard.c
+    ${MICROPY_PORT_DIR}/ppp_set_auth.c
+    ${MICROPY_PORT_DIR}/usb_serial_jtag.c
 )
 
 set(MICROPY_SOURCE_QSTR
@@ -112,32 +101,31 @@ set(IDF_COMPONENTS
     bootloader_support
     bt
     driver
-    esp_adc_cal
+    esp_adc
+    esp_app_format
     esp_common
     esp_eth
     esp_event
     esp_hw_support
     esp_ringbuf
     esp_rom
+    esp_partition
     esp_pm
     esp_wifi
     esp_system
     esp_timer
     esp_netif
-    esp32s3
+    esp_psram
     freertos
     hal
     heap
     log
     lwip
-    mbedtls
-    mdns
     newlib
     nvs_flash
     sdmmc
     soc
     spi_flash
-    tcpip_adapter
     ulp
     vfs
     xtensa
diff --git a/components/micropython/vendor/extmod/extmod.cmake b/components/micropython/vendor/extmod/extmod.cmake
index 0e5ed942260f07d0004a0545bee1fcf5f0b17acb..88b12841d67a0014a694a2ee57288c61212488d5 100644
--- a/components/micropython/vendor/extmod/extmod.cmake
+++ b/components/micropython/vendor/extmod/extmod.cmake
@@ -7,12 +7,8 @@ set(MICROPY_SOURCE_EXTMOD
     ${MICROPY_DIR}/shared/libc/abort_.c
     ${MICROPY_DIR}/shared/libc/printf.c
     ${MICROPY_EXTMOD_DIR}/machine_bitstream.c
-    ${MICROPY_EXTMOD_DIR}/machine_i2c.c
     ${MICROPY_EXTMOD_DIR}/machine_mem.c
-    ${MICROPY_EXTMOD_DIR}/machine_pulse.c
-    ${MICROPY_EXTMOD_DIR}/machine_pwm.c
     ${MICROPY_EXTMOD_DIR}/machine_signal.c
-    ${MICROPY_EXTMOD_DIR}/machine_spi.c
     ${MICROPY_EXTMOD_DIR}/modbluetooth.c
     ${MICROPY_EXTMOD_DIR}/modframebuf.c
     ${MICROPY_EXTMOD_DIR}/modlwip.c
@@ -22,7 +18,6 @@ set(MICROPY_SOURCE_EXTMOD
     ${MICROPY_EXTMOD_DIR}/modubinascii.c
     ${MICROPY_EXTMOD_DIR}/moducryptolib.c
     ${MICROPY_EXTMOD_DIR}/moductypes.c
-    ${MICROPY_EXTMOD_DIR}/moduhashlib.c
     ${MICROPY_EXTMOD_DIR}/moduheapq.c
     ${MICROPY_EXTMOD_DIR}/modujson.c
     ${MICROPY_EXTMOD_DIR}/moduos.c
diff --git a/components/micropython/vendor/extmod/extmod.mk b/components/micropython/vendor/extmod/extmod.mk
index 5aecedc2281b2e927d83428f76f8bb032fe6aa4a..7701d2b45a0dc7ae558389f10c18078505260dde 100644
--- a/components/micropython/vendor/extmod/extmod.mk
+++ b/components/micropython/vendor/extmod/extmod.mk
@@ -7,7 +7,6 @@ SRC_EXTMOD_C += \
 	extmod/machine_mem.c \
 	extmod/machine_pinbase.c \
 	extmod/machine_pulse.c \
-	extmod/machine_pwm.c \
 	extmod/machine_signal.c \
 	extmod/machine_spi.c \
 	extmod/machine_timer.c \
diff --git a/components/micropython/vendor/ports/esp32/CMakeLists.txt b/components/micropython/vendor/ports/esp32/CMakeLists.txt
index 274b16d796ce742e03e2a5649116605e627feb40..ae13faaf2b03011be90e4d5b217f77b1dc1a741c 100644
--- a/components/micropython/vendor/ports/esp32/CMakeLists.txt
+++ b/components/micropython/vendor/ports/esp32/CMakeLists.txt
@@ -18,16 +18,15 @@ if(NOT EXISTS ${MICROPY_BOARD_DIR}/mpconfigboard.cmake)
     message(FATAL_ERROR "Invalid MICROPY_BOARD specified: ${MICROPY_BOARD}")
 endif()
 
-# Include main IDF cmake file.
-include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-
 # Define the output sdkconfig so it goes in the build directory.
 set(SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig)
 
 # Save the manifest file set from the cmake command line.
 set(MICROPY_USER_FROZEN_MANIFEST ${MICROPY_FROZEN_MANIFEST})
 
-# Include board config; this is expected to set SDKCONFIG_DEFAULTS (among other options).
+# Include board config; this is expected to set (among other options):
+# - SDKCONFIG_DEFAULTS
+# - IDF_TARGET
 include(${MICROPY_BOARD_DIR}/mpconfigboard.cmake)
 
 # Set the frozen manifest file. Note if MICROPY_FROZEN_MANIFEST is set from the cmake
@@ -38,13 +37,6 @@ elseif (NOT MICROPY_FROZEN_MANIFEST)
     set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py)
 endif()
 
-# Add sdkconfig fragments that depend on the IDF version.
-if(IDF_VERSION_MAJOR EQUAL 4 AND IDF_VERSION_MINOR LESS 2)
-    set(SDKCONFIG_DEFAULTS ${SDKCONFIG_DEFAULTS} boards/sdkconfig.nimble_core0)
-else()
-    set(SDKCONFIG_DEFAULTS ${SDKCONFIG_DEFAULTS} boards/sdkconfig.nimble_core1)
-endif()
-
 # Concatenate all sdkconfig files into a combined one for the IDF to use.
 file(WRITE ${CMAKE_BINARY_DIR}/sdkconfig.combined.in "")
 foreach(SDKCONFIG_DEFAULT ${SDKCONFIG_DEFAULTS})
@@ -56,5 +48,11 @@ set(SDKCONFIG_DEFAULTS ${CMAKE_BINARY_DIR}/sdkconfig.combined)
 
 list(APPEND EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../badge23/components/")
 
+# Include main IDF cmake file.
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+
+# Set the location of the main component for the project (one per target).
+set(EXTRA_COMPONENT_DIRS main_${IDF_TARGET})
+
 # Define the project.
 project(micropython)
diff --git a/components/micropython/vendor/ports/esp32/README.md b/components/micropython/vendor/ports/esp32/README.md
index c37213b303109839e3b60bc7ff6ca5c536d3fe96..dc9e9f8b723ac3cb78d9c8c0e1797066ea277a93 100644
--- a/components/micropython/vendor/ports/esp32/README.md
+++ b/components/micropython/vendor/ports/esp32/README.md
@@ -22,13 +22,13 @@ Initial development of this ESP32 port was sponsored in part by Microbric Pty Lt
 Setting up ESP-IDF and the build environment
 --------------------------------------------
 
-MicroPython on ESP32 requires the Espressif IDF version 4 (IoT development
+MicroPython on ESP32 requires the Espressif IDF version 5 (IoT development
 framework, aka SDK).  The ESP-IDF includes the libraries and RTOS needed to
 manage the ESP32 microcontroller, as well as a way to manage the required
 build environment and toolchains needed to build the firmware.
 
 The ESP-IDF changes quickly and MicroPython only supports certain versions.
-Currently MicroPython supports v4.0.2, v4.1.1, v4.2.2, v4.3.2 and v4.4,
+Currently MicroPython supports v5.0.2,
 although other IDF v4 versions may also work.
 
 To install the ESP-IDF the full instructions can be found at the
@@ -47,10 +47,10 @@ The steps to take are summarised below.
 To check out a copy of the IDF use git clone:
 
 ```bash
-$ git clone -b v4.0.2 --recursive https://github.com/espressif/esp-idf.git
+$ git clone -b v5.0.2 --recursive https://github.com/espressif/esp-idf.git
 ```
 
-You can replace `v4.0.2` with `v4.2.2` or `v4.4` or any other supported version.
+You can replace `v5.0.2` with any other supported version.
 (You don't need a full recursive clone; see the `ci_esp32_setup` function in
 `tools/ci.sh` in this repository for more detailed set-up commands.)
 
@@ -59,7 +59,7 @@ MicroPython and update the submodules using:
 
 ```bash
 $ cd esp-idf
-$ git checkout v4.2
+$ git checkout v5.0.2
 $ git submodule update --init --recursive
 ```
 
@@ -75,11 +75,6 @@ $ source export.sh   # (or export.bat on Windows)
 The `install.sh` step only needs to be done once. You will need to source
 `export.sh` for every new session.
 
-**Note:** If you are building MicroPython for the ESP32-S2, ESP32-C3 or ESP32-S3,
-please ensure you are using the following required IDF versions:
-- ESP32-S3 currently requires `v4.4` or later.
-- ESP32-S2 and ESP32-C3 require `v4.3.1` or later.
-
 Building the firmware
 ---------------------
 
diff --git a/components/micropython/vendor/ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board
index 9373a522324db6c8e70aa1d38161e9ad4599892b..ea263cad9f4afbf1e8b55282ef4f83612d38c073 100644
--- a/components/micropython/vendor/ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/ESP32_S2_WROVER/sdkconfig.board
@@ -1,6 +1,5 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
diff --git a/components/micropython/vendor/ports/esp32/boards/GENERIC_C3_USB/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/GENERIC_C3_USB/sdkconfig.board
index f0cbad00e4617dd2ec0ba1a03b4e342e00e2db23..d9e7c7f61f620ca7a6ce61009e94c5a2133b3210 100644
--- a/components/micropython/vendor/ports/esp32/boards/GENERIC_C3_USB/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/GENERIC_C3_USB/sdkconfig.board
@@ -1,9 +1,7 @@
 CONFIG_ESP32C3_REV_MIN_3=y
-CONFIG_ESP32C3_REV_MIN=3
 CONFIG_ESP32C3_BROWNOUT_DET=y
 CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_7=
 CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_4=y
 CONFIG_ESP32C3_BROWNOUT_DET_LVL=4
 CONFIG_ESP_CONSOLE_UART_DEFAULT=
-CONFIG_ESP_CONSOLE_USB_CDC=
 CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
diff --git a/components/micropython/vendor/ports/esp32/boards/GENERIC_D2WD/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/GENERIC_D2WD/sdkconfig.board
index 07e208a09ae7b13ab612a867b1ae4d73a0a8a74f..7b4313b7deef1c3d4c294ee952cd21f069c536ff 100644
--- a/components/micropython/vendor/ports/esp32/boards/GENERIC_D2WD/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/GENERIC_D2WD/sdkconfig.board
@@ -1,6 +1,7 @@
 # Optimise using -Os to reduce size
 CONFIG_COMPILER_OPTIMIZATION_SIZE=y
 CONFIG_COMPILER_OPTIMIZATION_PERF=n
+CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
 
 CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
diff --git a/components/micropython/vendor/ports/esp32/boards/GENERIC_S3/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/GENERIC_S3/sdkconfig.board
index c9726d4232ed4a6b2867bc71bcc8900103c46087..7b9d932503e55f41cbd65d191be36cd0c02c8818 100644
--- a/components/micropython/vendor/ports/esp32/boards/GENERIC_S3/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/GENERIC_S3/sdkconfig.board
@@ -1,10 +1,7 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
-CONFIG_SPIRAM_MEMTEST=
-
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=
diff --git a/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board
index c9726d4232ed4a6b2867bc71bcc8900103c46087..7b9d932503e55f41cbd65d191be36cd0c02c8818 100644
--- a/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM/sdkconfig.board
@@ -1,10 +1,7 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
-CONFIG_SPIRAM_MEMTEST=
-
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=
diff --git a/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM_OCT/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM_OCT/sdkconfig.board
index c9726d4232ed4a6b2867bc71bcc8900103c46087..7b9d932503e55f41cbd65d191be36cd0c02c8818 100644
--- a/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM_OCT/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/GENERIC_S3_SPIRAM_OCT/sdkconfig.board
@@ -1,10 +1,7 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
-CONFIG_SPIRAM_MEMTEST=
-
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=
diff --git a/components/micropython/vendor/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake b/components/micropython/vendor/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake
index dcffe5f01e7a0bc751bb7370fc22da134de19f7c..2e1d799b93b1ca9bd445ef1fcd0d18f888fff693 100644
--- a/components/micropython/vendor/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake
+++ b/components/micropython/vendor/ports/esp32/boards/GENERIC_SPIRAM/mpconfigboard.cmake
@@ -2,5 +2,4 @@ set(SDKCONFIG_DEFAULTS
     boards/sdkconfig.base
     boards/sdkconfig.ble
     boards/sdkconfig.spiram
-    boards/GENERIC_SPIRAM/sdkconfig.board
 )
diff --git a/components/micropython/vendor/ports/esp32/boards/GENERIC_SPIRAM/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/GENERIC_SPIRAM/sdkconfig.board
deleted file mode 100644
index a2859acb5f90643466a61580cd5ca150c4e2764d..0000000000000000000000000000000000000000
--- a/components/micropython/vendor/ports/esp32/boards/GENERIC_SPIRAM/sdkconfig.board
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPIRAM increases the size of the firmware, use -Os to reduce it again to fit in iram
-CONFIG_COMPILER_OPTIMIZATION_SIZE=y
diff --git a/components/micropython/vendor/ports/esp32/boards/LOLIN_C3_MINI/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/LOLIN_C3_MINI/sdkconfig.board
index f0cbad00e4617dd2ec0ba1a03b4e342e00e2db23..d9e7c7f61f620ca7a6ce61009e94c5a2133b3210 100644
--- a/components/micropython/vendor/ports/esp32/boards/LOLIN_C3_MINI/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/LOLIN_C3_MINI/sdkconfig.board
@@ -1,9 +1,7 @@
 CONFIG_ESP32C3_REV_MIN_3=y
-CONFIG_ESP32C3_REV_MIN=3
 CONFIG_ESP32C3_BROWNOUT_DET=y
 CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_7=
 CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_4=y
 CONFIG_ESP32C3_BROWNOUT_DET_LVL=4
 CONFIG_ESP_CONSOLE_UART_DEFAULT=
-CONFIG_ESP_CONSOLE_USB_CDC=
 CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
diff --git a/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board
index ccda7bff68129b1044c912b1ecdc64cd8c6654d6..88bc9e72aca76215e1be295d078a18ca660f376c 100644
--- a/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board
@@ -1,15 +1,11 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
-CONFIG_SPIRAM_MEMTEST=
-
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
 CONFIG_PARTITION_TABLE_CUSTOM=y
 CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-16MiB.csv"
-#CONFIG_USB_AND_UART=y
 
 # LWIP
 CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS2"
diff --git a/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board
index 5e200451254637b6c32ef2ffe7a50cf4daa34f8e..a4a167de8a748063ae7955ce69708139f8f69287 100644
--- a/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board
@@ -1,10 +1,7 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
-CONFIG_SPIRAM_MEMTEST=
-
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_8MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
@@ -13,11 +10,9 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-16MiB.csv"
 
 CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS3"
 
-# CONFIG_TINYUSB_DESC_USE_ESPRESSIF_VID is not set
 CONFIG_TINYUSB_DESC_CUSTOM_VID=0x303A
-# CONFIG_TINYUSB_DESC_USE_DEFAULT_PID is not set
 CONFIG_TINYUSB_DESC_CUSTOM_PID=0x80D7
 CONFIG_TINYUSB_DESC_BCD_DEVICE=0x0100
 CONFIG_TINYUSB_DESC_MANUFACTURER_STRING="Unexpected Maker"
 CONFIG_TINYUSB_DESC_PRODUCT_STRING="FeatherS3"
-CONFIG_TINYUSB_DESC_SERIAL_STRING="_fs3_"
\ No newline at end of file
+CONFIG_TINYUSB_DESC_SERIAL_STRING="_fs3_"
diff --git a/components/micropython/vendor/ports/esp32/boards/UM_PROS3/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/UM_PROS3/sdkconfig.board
index 06b3a00a1c5a453f337966fe2d0f630be2ca14fa..74ca6df8f668654ce488f25fd1ffaa2e3b7b512c 100644
--- a/components/micropython/vendor/ports/esp32/boards/UM_PROS3/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/UM_PROS3/sdkconfig.board
@@ -1,10 +1,7 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
-CONFIG_SPIRAM_MEMTEST=
-
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_8MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
@@ -13,9 +10,7 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-16MiB.csv"
 
 CONFIG_LWIP_LOCAL_HOSTNAME="UMProS3"
 
-# CONFIG_TINYUSB_DESC_USE_ESPRESSIF_VID is not set
 CONFIG_TINYUSB_DESC_CUSTOM_VID=0x303A
-# CONFIG_TINYUSB_DESC_USE_DEFAULT_PID is not set
 CONFIG_TINYUSB_DESC_CUSTOM_PID=0x80D4
 CONFIG_TINYUSB_DESC_BCD_DEVICE=0x0100
 CONFIG_TINYUSB_DESC_MANUFACTURER_STRING="Unexpected Maker"
diff --git a/components/micropython/vendor/ports/esp32/boards/UM_TINYPICO/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/UM_TINYPICO/sdkconfig.board
index 8ed083e62d1a4ddc4bb2cb20677a65048269dc7e..766419c7f81a37871ac33c72f81b5b2423b2e601 100644
--- a/components/micropython/vendor/ports/esp32/boards/UM_TINYPICO/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/UM_TINYPICO/sdkconfig.board
@@ -3,6 +3,3 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
 CONFIG_SPIRAM_SPEED_80M=y
 CONFIG_ESP32_REV_MIN_1=y
 CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyPICO"
-
-# SPIRAM increases the size of the firmware, use -Os to reduce it again to fit in iram
-CONFIG_COMPILER_OPTIMIZATION_SIZE=y
diff --git a/components/micropython/vendor/ports/esp32/boards/UM_TINYS3/sdkconfig.board b/components/micropython/vendor/ports/esp32/boards/UM_TINYS3/sdkconfig.board
index 2b9ddbebe7b5de5eab15e4da31e3f92db85f4bde..0ac3c1f4cb157f3d56e9b8520f1e68fb5b8c90ce 100644
--- a/components/micropython/vendor/ports/esp32/boards/UM_TINYS3/sdkconfig.board
+++ b/components/micropython/vendor/ports/esp32/boards/UM_TINYS3/sdkconfig.board
@@ -1,10 +1,7 @@
 CONFIG_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
-CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
 CONFIG_ESPTOOLPY_AFTER_NORESET=y
 
-CONFIG_SPIRAM_MEMTEST=
-
 CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
 CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=
@@ -13,9 +10,7 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-8MiB.csv"
 
 CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyS3"
 
-# CONFIG_TINYUSB_DESC_USE_ESPRESSIF_VID is not set
 CONFIG_TINYUSB_DESC_CUSTOM_VID=0x303A
-# CONFIG_TINYUSB_DESC_USE_DEFAULT_PID is not set
 CONFIG_TINYUSB_DESC_CUSTOM_PID=0x80D1
 CONFIG_TINYUSB_DESC_BCD_DEVICE=0x0100
 CONFIG_TINYUSB_DESC_MANUFACTURER_STRING="Unexpected Maker"
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.240mhz b/components/micropython/vendor/ports/esp32/boards/sdkconfig.240mhz
index e36884009d1ed28f2b8e2f2f0cd1a771813b2474..c89a1ed2518991d33c081d555465d4839da44e6d 100644
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.240mhz
+++ b/components/micropython/vendor/ports/esp32/boards/sdkconfig.240mhz
@@ -1,5 +1,6 @@
 # MicroPython on ESP32, ESP IDF configuration with 240MHz CPU
-CONFIG_ESP32_DEFAULT_CPU_FREQ_80=
-CONFIG_ESP32_DEFAULT_CPU_FREQ_160=
-CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
-CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_40=
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.base b/components/micropython/vendor/ports/esp32/boards/sdkconfig.base
index 6b891aa006b1b190307702c4d4a951ea710880bc..a9e4454427a7d5b32d7ae50b2b8835d2fab84cae 100644
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.base
+++ b/components/micropython/vendor/ports/esp32/boards/sdkconfig.base
@@ -4,8 +4,6 @@
 CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
 
 # Compiler options: use -O2 and disable assertions to improve performance
-# (CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is for IDF 4.0.2)
-CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
 CONFIG_COMPILER_OPTIMIZATION_PERF=y
 CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
 
@@ -21,10 +19,14 @@ CONFIG_LOG_DEFAULT_LEVEL_INFO=n
 CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
 CONFIG_LOG_DEFAULT_LEVEL=1
 
-# ESP32-specific
+# Main XTAL Config
+# Only on: ESP32
+CONFIG_XTAL_FREQ_AUTO=y
+
+# ESP System Settings
+# Only on: ESP32, ESP32S3
 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=n
-CONFIG_ESP32_XTAL_FREQ_AUTO=y
 
 # Power Management
 CONFIG_PM_ENABLE=y
@@ -60,7 +62,17 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
 CONFIG_ESP32_WIFI_IRAM_OPT=n
 CONFIG_ESP32_WIFI_RX_IRAM_OPT=n
 
-# ADC calibration
+# Legacy ADC Calibration Configuration
+# Only on: ESP32
 CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y
 CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y
 CONFIG_ADC_CAL_LUT_ENABLE=y
+
+# UART Configuration
+CONFIG_UART_ISR_IN_IRAM=y
+
+# IDF 5 deprecated
+CONFIG_ADC_SUPPRESS_DEPRECATE_WARN=y
+CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN=y
+CONFIG_RMT_SUPPRESS_DEPRECATE_WARN=y
+CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.ble b/components/micropython/vendor/ports/esp32/boards/sdkconfig.ble
index 08d5e481f4993eb31b7022428c5bb21dd550d2ed..91ac3240ebee75022b122db7a878379630435eba 100644
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.ble
+++ b/components/micropython/vendor/ports/esp32/boards/sdkconfig.ble
@@ -1,9 +1,14 @@
-# Note this requires building with IDF 4.x
+CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR=y
 CONFIG_BT_ENABLED=y
-CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
-CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=
-CONFIG_BTDM_CTRL_MODE_BTDM=
-
 CONFIG_BT_NIMBLE_ENABLED=y
+CONFIG_BT_CONTROLLER_ENABLED=y
 
 CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
+
+# Put NimBLE on core 1, and for synchronisation
+# with the ringbuffer and scheduler MP needs to be on the same core.
+# MP on core 1 prevents interference with WiFi for time sensitive operations.
+# Only on: ESP32, ESP32S2, ESP32S3
+CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=n
+CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
+CONFIG_BT_NIMBLE_PINNED_TO_CORE=1
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.nimble_core0 b/components/micropython/vendor/ports/esp32/boards/sdkconfig.nimble_core0
deleted file mode 100644
index cacaff1197cb363b6425c57de73dd51ec2443e5c..0000000000000000000000000000000000000000
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.nimble_core0
+++ /dev/null
@@ -1,6 +0,0 @@
-# For IDF <4.2, we need NimBLE on core 0, and for synchronisation
-# with the ringbuffer and scheduler MP needs to be on the same core.
-# See https://github.com/micropython/micropython/issues/5489
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=n
-CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.nimble_core1 b/components/micropython/vendor/ports/esp32/boards/sdkconfig.nimble_core1
deleted file mode 100644
index 33653cc4b164c25285b3e703591da39d9c6aff1c..0000000000000000000000000000000000000000
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.nimble_core1
+++ /dev/null
@@ -1,6 +0,0 @@
-# For IDF >=4.2, we are able to put NimBLE on core 1, and for synchronisation
-# with the ringbuffer and scheduler MP needs to be on the same core.
-# MP on core 1 prevents interference with WiFi for time sensitive operations.
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=n
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
-CONFIG_BT_NIMBLE_PINNED_TO_CORE=1
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram b/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram
index 5b4ce118b890e67a4a15e1e20cdfbf889163a5de..74d35f7b4ad4a6f1447c778dbc2fc6f727ff18d4 100644
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram
+++ b/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram
@@ -1,6 +1,11 @@
 # MicroPython on ESP32, ESP IDF configuration with SPIRAM support
 
-CONFIG_ESP32_SPIRAM_SUPPORT=y
+CONFIG_SPIRAM=y
 CONFIG_SPIRAM_CACHE_WORKAROUND=y
 CONFIG_SPIRAM_IGNORE_NOTFOUND=y
-CONFIG_SPIRAM_USE_MEMMAP=y
+CONFIG_SPIRAM_USE_CAPS_ALLOC=y
+
+# SPIRAM increases the size of the firmware and overflows iram0_0_seg, due
+# to PSRAM bug workarounds.  Apply some options to reduce the firmware size.
+CONFIG_COMPILER_OPTIMIZATION_SIZE=y
+CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram_sx b/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram_sx
index ef24e90829e16295ed1a7275d5eafc83190afb42..fe388467800e24e84a4e135ca1a63ff49b375bb7 100644
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram_sx
+++ b/components/micropython/vendor/ports/esp32/boards/sdkconfig.spiram_sx
@@ -1,6 +1,4 @@
 # MicroPython on ESP32-S2 and ESP32-PAD1_subscript_3, ESP IDF configuration with SPIRAM support
-CONFIG_ESP32S2_SPIRAM_SUPPORT=y
-CONFIG_ESP32S3_SPIRAM_SUPPORT=y
 CONFIG_SPIRAM_MODE_QUAD=y
 CONFIG_SPIRAM_TYPE_AUTO=y
 CONFIG_DEFAULT_PSRAM_CLK_IO=30
@@ -9,7 +7,4 @@ CONFIG_SPIRAM_SPEED_80M=y
 CONFIG_SPIRAM=y
 CONFIG_SPIRAM_BOOT_INIT=y
 CONFIG_SPIRAM_IGNORE_NOTFOUND=y
-CONFIG_SPIRAM_USE_MEMMAP=y
-CONFIG_SPIRAM_MEMTEST=y
-CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
-CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
+CONFIG_SPIRAM_USE_CAPS_ALLOC=y
diff --git a/components/micropython/vendor/ports/esp32/boards/sdkconfig.usb b/components/micropython/vendor/ports/esp32/boards/sdkconfig.usb
index 657edbc58059bce00666ccdec644c89ff1251451..4090c710e62e6073f504b168d6dcc7d7c0b4a317 100644
--- a/components/micropython/vendor/ports/esp32/boards/sdkconfig.usb
+++ b/components/micropython/vendor/ports/esp32/boards/sdkconfig.usb
@@ -1,4 +1,4 @@
-CONFIG_USB_ENABLED=y
-CONFIG_USB_CDC_ENABLED=y
-CONFIG_USB_CDC_RX_BUFSIZE=256
-CONFIG_USB_CDC_TX_BUFSIZE=256
+CONFIG_USB_OTG_SUPPORTED=y
+CONFIG_TINYUSB_CDC_ENABLED=y
+CONFIG_TINYUSB_CDC_RX_BUFSIZE=256
+CONFIG_TINYUSB_CDC_TX_BUFSIZE=256
diff --git a/components/micropython/vendor/ports/esp32/esp32_rmt.c b/components/micropython/vendor/ports/esp32/esp32_rmt.c
index 78c8c8aceeffbf509faf9602c04d1d981143b5d7..621f8321c99b59746ffaa679b64c20287543c2b2 100644
--- a/components/micropython/vendor/ports/esp32/esp32_rmt.c
+++ b/components/micropython/vendor/ports/esp32/esp32_rmt.c
@@ -48,11 +48,7 @@
 // and carrier output.
 
 // Last available RMT channel that can transmit.
-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 0)
-#define RMT_LAST_TX_CHANNEL (RMT_CHANNEL_MAX - 1)
-#else
 #define RMT_LAST_TX_CHANNEL (SOC_RMT_TX_CANDIDATES_PER_GROUP - 1)
-#endif
 
 // Forward declaration
 extern const mp_obj_type_t esp32_rmt_type;
diff --git a/components/micropython/vendor/ports/esp32/gccollect.c b/components/micropython/vendor/ports/esp32/gccollect.c
index 403a3c7dfa0fb3b8d899dd2c9d3cb76081a83985..6fa287de28c0c493b9a25b82ddf14f75f7b3c5ea 100644
--- a/components/micropython/vendor/ports/esp32/gccollect.c
+++ b/components/micropython/vendor/ports/esp32/gccollect.c
@@ -34,7 +34,6 @@
 #include "py/gc.h"
 #include "py/mpthread.h"
 #include "gccollect.h"
-#include "soc/cpu.h"
 
 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 
@@ -50,7 +49,7 @@ static void gc_collect_inner(int level) {
 
     if (level == XCHAL_NUM_AREGS / 8) {
         // get the sp
-        volatile uint32_t sp = (uint32_t)get_sp();
+        volatile uint32_t sp = (uint32_t)esp_cpu_get_sp();
         gc_collect_root((void **)sp, ((mp_uint_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t));
         return;
     }
diff --git a/components/micropython/vendor/ports/esp32/machine_adcblock.h b/components/micropython/vendor/ports/esp32/machine_adcblock.h
index 0500726d7179152d2371bafeca9ae73ca5622b31..7c9249b072c18bc51d076529e8ab1bc5311d2024 100644
--- a/components/micropython/vendor/ports/esp32/machine_adcblock.h
+++ b/components/micropython/vendor/ports/esp32/machine_adcblock.h
@@ -3,6 +3,8 @@
 
 #include "esp_adc_cal.h"
 
+#define ADC_ATTEN_MAX SOC_ADC_ATTEN_NUM
+
 typedef struct _madcblock_obj_t {
     mp_obj_base_t base;
     adc_unit_t unit_id;
diff --git a/components/micropython/vendor/ports/esp32/machine_bitstream.c b/components/micropython/vendor/ports/esp32/machine_bitstream.c
deleted file mode 100644
index 4284b5f8baf7737334e22ba3a19045425ca5a0e2..0000000000000000000000000000000000000000
--- a/components/micropython/vendor/ports/esp32/machine_bitstream.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2021 Jim Mussared
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "py/mpconfig.h"
-#include "py/mphal.h"
-#include "modesp32.h"
-
-#if MICROPY_PY_MACHINE_BITSTREAM
-
-/******************************************************************************/
-// Bit-bang implementation
-
-#define NS_TICKS_OVERHEAD (6)
-
-// This is a translation of the cycle counter implementation in ports/stm32/machine_bitstream.c.
-STATIC void IRAM_ATTR machine_bitstream_high_low_bitbang(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) {
-    uint32_t pin_mask, gpio_reg_set, gpio_reg_clear;
-    #if !CONFIG_IDF_TARGET_ESP32C3
-    if (pin >= 32) {
-        pin_mask = 1 << (pin - 32);
-        gpio_reg_set = GPIO_OUT1_W1TS_REG;
-        gpio_reg_clear = GPIO_OUT1_W1TC_REG;
-    } else
-    #endif
-    {
-        pin_mask = 1 << pin;
-        gpio_reg_set = GPIO_OUT_W1TS_REG;
-        gpio_reg_clear = GPIO_OUT_W1TC_REG;
-    }
-
-    // Convert ns to cpu ticks [high_time_0, period_0, high_time_1, period_1].
-    uint32_t fcpu_mhz = ets_get_cpu_frequency();
-    for (size_t i = 0; i < 4; ++i) {
-        timing_ns[i] = fcpu_mhz * timing_ns[i] / 1000;
-        if (timing_ns[i] > NS_TICKS_OVERHEAD) {
-            timing_ns[i] -= NS_TICKS_OVERHEAD;
-        }
-        if (i % 2 == 1) {
-            // Convert low_time to period (i.e. add high_time).
-            timing_ns[i] += timing_ns[i - 1];
-        }
-    }
-
-    uint32_t irq_state = mp_hal_quiet_timing_enter();
-
-    for (size_t i = 0; i < len; ++i) {
-        uint8_t b = buf[i];
-        for (size_t j = 0; j < 8; ++j) {
-            GPIO_REG_WRITE(gpio_reg_set, pin_mask);
-            uint32_t start_ticks = mp_hal_ticks_cpu();
-            uint32_t *t = &timing_ns[b >> 6 & 2];
-            while (mp_hal_ticks_cpu() - start_ticks < t[0]) {
-                ;
-            }
-            GPIO_REG_WRITE(gpio_reg_clear, pin_mask);
-            b <<= 1;
-            while (mp_hal_ticks_cpu() - start_ticks < t[1]) {
-                ;
-            }
-        }
-    }
-
-    mp_hal_quiet_timing_exit(irq_state);
-}
-
-/******************************************************************************/
-// RMT implementation
-
-#include "driver/rmt.h"
-
-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0)
-// This convenience macro was not available in earlier IDF versions.
-#define RMT_DEFAULT_CONFIG_TX(gpio, channel_id)      \
-    {                                                \
-        .rmt_mode = RMT_MODE_TX,                     \
-        .channel = channel_id,                       \
-        .clk_div = 80,                               \
-        .gpio_num = gpio,                            \
-        .mem_block_num = 1,                          \
-        .tx_config = {                               \
-            .loop_en = false,                        \
-            .carrier_freq_hz = 38000,                \
-            .carrier_duty_percent = 33,              \
-            .carrier_level = RMT_CARRIER_LEVEL_HIGH, \
-            .carrier_en = false,                     \
-            .idle_level = RMT_IDLE_LEVEL_LOW,        \
-            .idle_output_en = true,                  \
-        }                                            \
-    }
-#endif
-
-// Logical 0 and 1 values (encoded as a rmt_item32_t).
-// The duration fields will be set later.
-STATIC rmt_item32_t bitstream_high_low_0 = {{{ 0, 1, 0, 0 }}};
-STATIC rmt_item32_t bitstream_high_low_1 = {{{ 0, 1, 0, 0 }}};
-
-// See https://github.com/espressif/esp-idf/blob/master/examples/common_components/led_strip/led_strip_rmt_ws2812.c
-// This is called automatically by the IDF during rmt_write_sample in order to
-// convert the byte stream to rmt_item32_t's.
-STATIC void IRAM_ATTR bitstream_high_low_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num) {
-    if (src == NULL || dest == NULL) {
-        *translated_size = 0;
-        *item_num = 0;
-        return;
-    }
-
-    size_t size = 0;
-    size_t num = 0;
-    uint8_t *psrc = (uint8_t *)src;
-    rmt_item32_t *pdest = dest;
-    while (size < src_size && num < wanted_num) {
-        for (int i = 0; i < 8; i++) {
-            // MSB first
-            if (*psrc & (1 << (7 - i))) {
-                pdest->val = bitstream_high_low_1.val;
-            } else {
-                pdest->val = bitstream_high_low_0.val;
-            }
-            num++;
-            pdest++;
-        }
-        size++;
-        psrc++;
-    }
-
-    *translated_size = size;
-    *item_num = num;
-}
-
-// Use the reserved RMT channel to stream high/low data on the specified pin.
-STATIC void machine_bitstream_high_low_rmt(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len, uint8_t channel_id) {
-    rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin, channel_id);
-
-    // Use 40MHz clock (although 2MHz would probably be sufficient).
-    config.clk_div = 2;
-
-    // Install the driver on this channel & pin.
-    check_esp_err(rmt_config(&config));
-    check_esp_err(rmt_driver_install_core1(config.channel));
-
-    // Get the tick rate in kHz (this will likely be 40000).
-    uint32_t counter_clk_khz = 0;
-    #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0)
-    uint8_t div_cnt;
-    check_esp_err(rmt_get_clk_div(config.channel, &div_cnt));
-    counter_clk_khz = APB_CLK_FREQ / div_cnt;
-    #else
-    check_esp_err(rmt_get_counter_clock(config.channel, &counter_clk_khz));
-    #endif
-
-    counter_clk_khz /= 1000;
-
-    // Convert nanoseconds to pulse duration.
-    bitstream_high_low_0.duration0 = (counter_clk_khz * timing_ns[0]) / 1e6;
-    bitstream_high_low_0.duration1 = (counter_clk_khz * timing_ns[1]) / 1e6;
-    bitstream_high_low_1.duration0 = (counter_clk_khz * timing_ns[2]) / 1e6;
-    bitstream_high_low_1.duration1 = (counter_clk_khz * timing_ns[3]) / 1e6;
-
-    // Install the bits->highlow translator.
-    rmt_translator_init(config.channel, bitstream_high_low_rmt_adapter);
-
-    // Stream the byte data using the translator.
-    check_esp_err(rmt_write_sample(config.channel, buf, len, true));
-
-    // Wait 50% longer than we expect (if every bit takes the maximum time).
-    uint32_t timeout_ms = (3 * len / 2) * (1 + (8 * MAX(timing_ns[0] + timing_ns[1], timing_ns[2] + timing_ns[3])) / 1000);
-    check_esp_err(rmt_wait_tx_done(config.channel, pdMS_TO_TICKS(timeout_ms)));
-
-    // Uninstall the driver.
-    check_esp_err(rmt_driver_uninstall(config.channel));
-
-    // Cancel RMT output to GPIO pin.
-    gpio_matrix_out(pin, SIG_GPIO_OUT_IDX, false, false);
-}
-
-/******************************************************************************/
-// Interface to machine.bitstream
-
-void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) {
-    if (esp32_rmt_bitstream_channel_id < 0) {
-        machine_bitstream_high_low_bitbang(pin, timing_ns, buf, len);
-    } else {
-        machine_bitstream_high_low_rmt(pin, timing_ns, buf, len, esp32_rmt_bitstream_channel_id);
-    }
-}
-
-#endif // MICROPY_PY_MACHINE_BITSTREAM
diff --git a/components/micropython/vendor/ports/esp32/machine_hw_spi.c b/components/micropython/vendor/ports/esp32/machine_hw_spi.c
index 36f8d3f06956a213aa10a0b760bcf2ea3a6af4b9..662d0e599419bc9d93f5eaec1311da7014472662 100644
--- a/components/micropython/vendor/ports/esp32/machine_hw_spi.c
+++ b/components/micropython/vendor/ports/esp32/machine_hw_spi.c
@@ -35,6 +35,8 @@
 #include "modmachine.h"
 
 #include "driver/spi_master.h"
+#include "soc/gpio_sig_map.h"
+#include "soc/spi_pins.h"
 
 // SPI mappings by device, naming used by IDF old/new
 // upython   | ESP32     | ESP32S2   | ESP32S3 | ESP32C3
@@ -57,9 +59,9 @@
 #define MICROPY_HW_SPI1_MOSI FSPI_IOMUX_PIN_NUM_MOSI
 #define MICROPY_HW_SPI1_MISO FSPI_IOMUX_PIN_NUM_MISO
 #else
-#define MICROPY_HW_SPI1_SCK HSPI_IOMUX_PIN_NUM_CLK
-#define MICROPY_HW_SPI1_MOSI HSPI_IOMUX_PIN_NUM_MOSI
-#define MICROPY_HW_SPI1_MISO HSPI_IOMUX_PIN_NUM_MISO
+#define MICROPY_HW_SPI1_SCK SPI2_IOMUX_PIN_NUM_CLK
+#define MICROPY_HW_SPI1_MOSI SPI2_IOMUX_PIN_NUM_MOSI
+#define MICROPY_HW_SPI1_MISO SPI2_IOMUX_PIN_NUM_MISO
 #endif
 #endif
 
@@ -67,9 +69,9 @@
 #ifndef MICROPY_HW_SPI2_SCK
 #if CONFIG_IDF_TARGET_ESP32
 // ESP32 has IO_MUX pins for VSPI/SPI3 lines, use them as defaults
-#define MICROPY_HW_SPI2_SCK VSPI_IOMUX_PIN_NUM_CLK      // pin 18
-#define MICROPY_HW_SPI2_MOSI VSPI_IOMUX_PIN_NUM_MOSI    // pin 23
-#define MICROPY_HW_SPI2_MISO VSPI_IOMUX_PIN_NUM_MISO    // pin 19
+#define MICROPY_HW_SPI2_SCK SPI3_IOMUX_PIN_NUM_CLK      // pin 18
+#define MICROPY_HW_SPI2_MOSI SPI3_IOMUX_PIN_NUM_MOSI    // pin 23
+#define MICROPY_HW_SPI2_MISO SPI3_IOMUX_PIN_NUM_MISO    // pin 19
 #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 // ESP32S2 and S3 uses GPIO matrix for SPI3 pins, no IO_MUX possible
 // Set defaults to the pins used by SPI2 in Octal mode
@@ -83,9 +85,9 @@
 #define MP_HW_SPI_MAX_XFER_BITS (MP_HW_SPI_MAX_XFER_BYTES * 8) // Has to be an even multiple of 8
 
 #if CONFIG_IDF_TARGET_ESP32C3
-#define HSPI_HOST SPI2_HOST
+#define SPI2_HOST SPI2_HOST
 #elif CONFIG_IDF_TARGET_ESP32S3
-#define HSPI_HOST SPI3_HOST
+#define SPI2_HOST SPI3_HOST
 #define FSPI_HOST SPI2_HOST
 #endif
 
@@ -122,7 +124,7 @@ STATIC const machine_hw_spi_default_pins_t machine_hw_spi_default_pins[2] = {
     #endif
 };
 
-// Static objects mapping to HSPI and VSPI hardware peripherals
+// Static objects mapping to SPI2 and SPI3 hardware peripherals
 STATIC machine_hw_spi_obj_t machine_hw_spi_obj[2];
 
 STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t *self) {
@@ -150,8 +152,8 @@ STATIC void machine_hw_spi_deinit_internal(machine_hw_spi_obj_t *self) {
 
     for (int i = 0; i < 3; i++) {
         if (pins[i] != -1) {
-            gpio_pad_select_gpio(pins[i]);
-            gpio_matrix_out(pins[i], SIG_GPIO_OUT_IDX, false, false);
+            esp_rom_gpio_pad_select_gpio(pins[i]);
+            esp_rom_gpio_connect_out_signal(pins[i], SIG_GPIO_OUT_IDX, false, false);
             gpio_set_direction(pins[i], GPIO_MODE_INPUT);
         }
     }
@@ -226,12 +228,12 @@ STATIC void machine_hw_spi_init_internal(
         changed = true;
     }
 
-    if (self->host != HSPI_HOST
+    if (self->host != SPI2_HOST
         #ifdef FSPI_HOST
         && self->host != FSPI_HOST
         #endif
-        #ifdef VSPI_HOST
-        && self->host != VSPI_HOST
+        #ifdef SPI3_HOST
+        && self->host != SPI3_HOST
         #endif
         ) {
         mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SPI(%d) doesn't exist"), self->host);
@@ -270,7 +272,7 @@ STATIC void machine_hw_spi_init_internal(
     #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
     dma_chan = SPI_DMA_CH_AUTO;
     #else
-    if (self->host == HSPI_HOST) {
+    if (self->host == SPI2_HOST) {
         dma_chan = 1;
     } else {
         dma_chan = 2;
@@ -483,7 +485,7 @@ mp_obj_t machine_hw_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
 
     machine_hw_spi_obj_t *self;
     const machine_hw_spi_default_pins_t *default_pins;
-    if (args[ARG_id].u_int == 1) { // SPI2_HOST which is FSPI_HOST on ESP32Sx, HSPI_HOST on others
+    if (args[ARG_id].u_int == 1) { // SPI2_HOST which is FSPI_HOST on ESP32Sx, SPI2_HOST on others
         self = &machine_hw_spi_obj[0];
         default_pins = &machine_hw_spi_default_pins[0];
     } else {
diff --git a/components/micropython/vendor/ports/esp32/machine_i2c.c b/components/micropython/vendor/ports/esp32/machine_i2c.c
index c805dab87ee241681d55828d429ad15276fbb278..4d645807abe64edfec84e6f3c21b9f4df77b3be8 100644
--- a/components/micropython/vendor/ports/esp32/machine_i2c.c
+++ b/components/micropython/vendor/ports/esp32/machine_i2c.c
@@ -31,13 +31,7 @@
 #include "modmachine.h"
 
 #include "driver/i2c.h"
-
-#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
 #include "hal/i2c_ll.h"
-#else
-#include "soc/i2c_reg.h"
-#define I2C_LL_MAX_TIMEOUT I2C_TIME_OUT_REG_V
-#endif
 
 #ifndef MICROPY_HW_I2C0_SCL
 #define MICROPY_HW_I2C0_SCL (GPIO_NUM_18)
@@ -125,7 +119,7 @@ int machine_hw_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t n, mp_
     }
 
     // TODO proper timeout
-    esp_err_t err = i2c_master_cmd_begin(self->port, cmd, 100 * (1 + data_len) / portTICK_RATE_MS);
+    esp_err_t err = i2c_master_cmd_begin(self->port, cmd, 100 * (1 + data_len) / portTICK_PERIOD_MS);
     i2c_cmd_link_delete(cmd);
 
     if (err == ESP_FAIL) {
diff --git a/components/micropython/vendor/ports/esp32/machine_i2s.c b/components/micropython/vendor/ports/esp32/machine_i2s.c
index ce1cb59849dc1ec5b3c079fbdd0acc76f186f33a..7cb18b706901ecad3931f0ae5bcc0e74c80e3b6b 100644
--- a/components/micropython/vendor/ports/esp32/machine_i2s.c
+++ b/components/micropython/vendor/ports/esp32/machine_i2s.c
@@ -148,7 +148,7 @@ STATIC const int8_t i2s_frame_map[NUM_I2S_USER_FORMATS][I2S_RX_FRAME_SIZE_IN_BYT
 };
 
 void machine_i2s_init0() {
-    for (i2s_port_t p = 0; p < I2S_NUM_MAX; p++) {
+    for (i2s_port_t p = 0; p < I2S_NUM_AUTO; p++) {
         MP_STATE_PORT(machine_i2s_obj)[p] = NULL;
     }
 }
@@ -269,15 +269,6 @@ STATIC uint32_t fill_appbuf_from_dma(machine_i2s_obj_t *self, mp_buffer_info_t *
             num_bytes_requested_from_dma,
             &num_bytes_received_from_dma,
             delay);
-
-        // the following is a workaround for a bug in ESP-IDF v4.4
-        // https://github.com/espressif/esp-idf/issues/8121
-        #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4)
-        if ((delay != portMAX_DELAY) && (ret == ESP_ERR_TIMEOUT)) {
-            ret = ESP_OK;
-        }
-        #endif
-
         check_esp_err(ret);
 
         // process the transform buffer one frame at a time.
@@ -334,15 +325,6 @@ STATIC size_t copy_appbuf_to_dma(machine_i2s_obj_t *self, mp_buffer_info_t *appb
     }
 
     esp_err_t ret = i2s_write(self->port, appbuf->buf, appbuf->len, &num_bytes_written, delay);
-
-    // the following is a workaround for a bug in ESP-IDF v4.4
-    // https://github.com/espressif/esp-idf/issues/8121
-    #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4)
-    if ((delay != portMAX_DELAY) && (ret == ESP_ERR_TIMEOUT)) {
-        ret = ESP_OK;
-    }
-    #endif
-
     check_esp_err(ret);
 
     if ((self->io_mode == UASYNCIO) && (num_bytes_written < appbuf->len)) {
@@ -467,10 +449,8 @@ STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args,
     i2s_config.use_apll = false;
     i2s_config.tx_desc_auto_clear = true;
     i2s_config.fixed_mclk = 0;
-    #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4)
-    i2s_config.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT;
+    i2s_config.mclk_multiple = I2S_MCLK_MULTIPLE_256;
     i2s_config.bits_per_chan = 0;
-    #endif
 
     // I2S queue size equals the number of DMA buffers
     check_esp_err(i2s_driver_install(self->port, &i2s_config, i2s_config.dma_buf_count, &self->i2s_event_queue));
@@ -487,9 +467,7 @@ STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args,
     #endif
 
     i2s_pin_config_t pin_config;
-    #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4)
     pin_config.mck_io_num = I2S_PIN_NO_CHANGE;
-    #endif
     pin_config.bck_io_num = self->sck;
     pin_config.ws_io_num = self->ws;
 
@@ -527,7 +505,7 @@ STATIC mp_obj_t machine_i2s_make_new(const mp_obj_type_t *type, size_t n_pos_arg
     mp_arg_check_num(n_pos_args, n_kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
     i2s_port_t port = mp_obj_get_int(args[0]);
-    if (port < 0 || port >= I2S_NUM_MAX) {
+    if (port < 0 || port >= I2S_NUM_AUTO) {
         mp_raise_ValueError(MP_ERROR_TEXT("invalid id"));
     }
 
@@ -841,6 +819,6 @@ MP_DEFINE_CONST_OBJ_TYPE(
     locals_dict, &machine_i2s_locals_dict
     );
 
-MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_MAX]);
+MP_REGISTER_ROOT_POINTER(struct _machine_i2s_obj_t *machine_i2s_obj[I2S_NUM_AUTO]);
 
 #endif // MICROPY_PY_MACHINE_I2S
diff --git a/components/micropython/vendor/ports/esp32/machine_pin.c b/components/micropython/vendor/ports/esp32/machine_pin.c
index f103b96963ce46de74d1015c8c02f90f778fde8c..5ea41701afe3cd96b5e00310ef034be7dff7a618 100644
--- a/components/micropython/vendor/ports/esp32/machine_pin.c
+++ b/components/micropython/vendor/ports/esp32/machine_pin.c
@@ -31,6 +31,7 @@
 
 #include "driver/gpio.h"
 #include "driver/rtc_io.h"
+#include "hal/gpio_ll.h"
 
 #include "py/runtime.h"
 #include "py/mphal.h"
@@ -92,11 +93,7 @@ STATIC const machine_pin_obj_t machine_pin_obj[GPIO_NUM_MAX] = {
     #endif
     {{&machine_pin_type}, GPIO_NUM_18},
     {{&machine_pin_type}, GPIO_NUM_19},
-    #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 2)
     {{&machine_pin_type}, GPIO_NUM_20},
-    #else
-    {{NULL}, -1},
-    #endif
     {{&machine_pin_type}, GPIO_NUM_21},
     {{&machine_pin_type}, GPIO_NUM_22},
     {{&machine_pin_type}, GPIO_NUM_23},
@@ -295,7 +292,7 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_
     #endif
 
     // configure the pin for gpio
-    gpio_pad_select_gpio(self->id);
+    esp_rom_gpio_pad_select_gpio(self->id);
 
     // set initial value (do this before configuring mode/pull)
     if (args[ARG_value].u_obj != MP_OBJ_NULL) {
@@ -423,7 +420,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
     enum { ARG_handler, ARG_trigger, ARG_wake };
     static const mp_arg_t allowed_args[] = {
         { MP_QSTR_handler, MP_ARG_OBJ, {.u_obj = mp_const_none} },
-        { MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_PIN_INTR_POSEDGE | GPIO_PIN_INTR_NEGEDGE} },
+        { MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_INTR_POSEDGE | GPIO_INTR_NEGEDGE} },
         { MP_QSTR_wake, MP_ARG_OBJ, {.u_obj = mp_const_none} },
     };
     machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
@@ -436,7 +433,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
         uint32_t trigger = args[ARG_trigger].u_int;
         mp_obj_t wake_obj = args[ARG_wake].u_obj;
 
-        if ((trigger == GPIO_PIN_INTR_LOLEVEL || trigger == GPIO_PIN_INTR_HILEVEL) && wake_obj != mp_const_none) {
+        if ((trigger == GPIO_INTR_LOW_LEVEL || trigger == GPIO_INTR_HIGH_LEVEL) && wake_obj != mp_const_none) {
             mp_int_t wake;
             if (mp_obj_get_int_maybe(wake_obj, &wake)) {
                 if (wake < 2 || wake > 7) {
@@ -460,7 +457,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
                 mp_raise_ValueError(MP_ERROR_TEXT("no resources"));
             }
 
-            machine_rtc_config.ext0_level = trigger == GPIO_PIN_INTR_LOLEVEL ? 0 : 1;
+            machine_rtc_config.ext0_level = trigger == GPIO_INTR_LOW_LEVEL ? 0 : 1;
             machine_rtc_config.ext0_wake_types = wake;
         } else {
             if (machine_rtc_config.ext0_pin == self->id) {
@@ -497,10 +494,10 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = {
     { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_INPUT_OUTPUT_OD) },
     { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULL_UP) },
     { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULL_DOWN) },
-    { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_PIN_INTR_POSEDGE) },
-    { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_PIN_INTR_NEGEDGE) },
-    { MP_ROM_QSTR(MP_QSTR_WAKE_LOW), MP_ROM_INT(GPIO_PIN_INTR_LOLEVEL) },
-    { MP_ROM_QSTR(MP_QSTR_WAKE_HIGH), MP_ROM_INT(GPIO_PIN_INTR_HILEVEL) },
+    { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_INTR_POSEDGE) },
+    { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_INTR_NEGEDGE) },
+    { MP_ROM_QSTR(MP_QSTR_WAKE_LOW), MP_ROM_INT(GPIO_INTR_LOW_LEVEL) },
+    { MP_ROM_QSTR(MP_QSTR_WAKE_HIGH), MP_ROM_INT(GPIO_INTR_HIGH_LEVEL) },
     { MP_ROM_QSTR(MP_QSTR_DRIVE_0), MP_ROM_INT(GPIO_DRIVE_CAP_0) },
     { MP_ROM_QSTR(MP_QSTR_DRIVE_1), MP_ROM_INT(GPIO_DRIVE_CAP_1) },
     { MP_ROM_QSTR(MP_QSTR_DRIVE_2), MP_ROM_INT(GPIO_DRIVE_CAP_2) },
@@ -573,11 +570,7 @@ STATIC const machine_pin_irq_obj_t machine_pin_irq_object[GPIO_NUM_MAX] = {
     #endif
     {{&machine_pin_irq_type}, GPIO_NUM_18},
     {{&machine_pin_irq_type}, GPIO_NUM_19},
-    #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 2)
     {{&machine_pin_irq_type}, GPIO_NUM_20},
-    #else
-    {{NULL}, -1},
-    #endif
     {{&machine_pin_irq_type}, GPIO_NUM_21},
     {{&machine_pin_irq_type}, GPIO_NUM_22},
     {{&machine_pin_irq_type}, GPIO_NUM_23},
diff --git a/components/micropython/vendor/ports/esp32/machine_pwm.c b/components/micropython/vendor/ports/esp32/machine_pwm.c
index 79e11d02784eaef04446b64decf6819de2858048..462d0fa79c7400f5678032d30430179825c86b51 100644
--- a/components/micropython/vendor/ports/esp32/machine_pwm.c
+++ b/components/micropython/vendor/ports/esp32/machine_pwm.c
@@ -34,6 +34,7 @@
 
 #include "driver/ledc.h"
 #include "esp_err.h"
+#include "soc/gpio_sig_map.h"
 
 #define PWM_DBG(...)
 // #define PWM_DBG(...) mp_printf(&mp_plat_print, __VA_ARGS__); mp_printf(&mp_plat_print, "\n");
@@ -164,13 +165,13 @@ STATIC void pwm_deinit(int channel_idx) {
             // Mark it unused, and tell the hardware to stop routing
             check_esp_err(ledc_stop(mode, channel, 0));
             // Disable ledc signal for the pin
-            // gpio_matrix_out(pin, SIG_GPIO_OUT_IDX, false, false);
+            // esp_rom_gpio_connect_out_signal(pin, SIG_GPIO_OUT_IDX, false, false);
             if (mode == LEDC_LOW_SPEED_MODE) {
-                gpio_matrix_out(pin, LEDC_LS_SIG_OUT0_IDX + channel, false, true);
+                esp_rom_gpio_connect_out_signal(pin, LEDC_LS_SIG_OUT0_IDX + channel, false, true);
             } else {
                 #if LEDC_SPEED_MODE_MAX > 1
                 #if CONFIG_IDF_TARGET_ESP32
-                gpio_matrix_out(pin, LEDC_HS_SIG_OUT0_IDX + channel, false, true);
+                esp_rom_gpio_connect_out_signal(pin, LEDC_HS_SIG_OUT0_IDX + channel, false, true);
                 #else
                 #error Add supported CONFIG_IDF_TARGET_ESP32_xxx
                 #endif
@@ -209,18 +210,13 @@ STATIC void configure_channel(machine_pwm_obj_t *self) {
 STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_config_t *timer) {
     if (freq != timer->freq_hz) {
         // Find the highest bit resolution for the requested frequency
-        unsigned int i = LEDC_APB_CLK_HZ; // 80 MHz
+        unsigned int i = APB_CLK_FREQ; // 80 MHz
         #if SOC_LEDC_SUPPORT_REF_TICK
         if (freq < EMPIRIC_FREQ) {
-            i = LEDC_REF_CLK_HZ; // 1 MHz
+            i = REF_CLK_FREQ; // 1 MHz
         }
         #endif
 
-        #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
-        // original code
-        i /= freq;
-        #else
-        // See https://github.com/espressif/esp-idf/issues/7722
         int divider = (i + freq / 2) / freq; // rounded
         if (divider == 0) {
             divider = 1;
@@ -230,7 +226,6 @@ STATIC void set_freq(machine_pwm_obj_t *self, unsigned int freq, ledc_timer_conf
             f = 1.0;
         }
         i = (unsigned int)roundf((float)i / f);
-        #endif
 
         unsigned int res = 0;
         for (; i > 1; i >>= 1) {
@@ -350,11 +345,11 @@ STATIC void set_duty_u16(machine_pwm_obj_t *self, int duty) {
     /*
     // Bug: Sometimes duty is not set right now.
     // Not a bug. It's a feature. The duty is applied at the beginning of the next signal period.
-    // Bug: It has been experimentally established that the duty is setted during 2 signal periods, but 1 period is expected.
+    // Bug: It has been experimentally established that the duty is set during 2 signal periods, but 1 period is expected.
     // See https://github.com/espressif/esp-idf/issues/7288
     if (duty != get_duty_u16(self)) {
         PWM_DBG("set_duty_u16(%u), get_duty_u16():%u, channel_duty:%d, duty_resolution:%d, freq_hz:%d", duty, get_duty_u16(self), channel_duty, timer.duty_resolution, timer.freq_hz);
-        ets_delay_us(2 * 1000000 / timer.freq_hz);
+        esp_rom_delay_us(2 * 1000000 / timer.freq_hz);
         if (duty != get_duty_u16(self)) {
             PWM_DBG("set_duty_u16(%u), get_duty_u16():%u, channel_duty:%d, duty_resolution:%d, freq_hz:%d", duty, get_duty_u16(self), channel_duty, timer.duty_resolution, timer.freq_hz);
         }
@@ -510,7 +505,7 @@ STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
         }
     }
     if ((freq <= 0) || (freq > 40000000)) {
-        mp_raise_ValueError(MP_ERROR_TEXT("freqency must be from 1Hz to 40MHz"));
+        mp_raise_ValueError(MP_ERROR_TEXT("frequency must be from 1Hz to 40MHz"));
     }
 
     int timer_idx;
@@ -607,7 +602,7 @@ STATIC void mp_machine_pwm_deinit(machine_pwm_obj_t *self) {
     self->duty_x = 0;
 }
 
-// Set's and get's methods of PWM class
+// Set and get methods of PWM class
 
 STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
     pwm_is_active(self);
@@ -617,7 +612,7 @@ STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
 STATIC void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) {
     pwm_is_active(self);
     if ((freq <= 0) || (freq > 40000000)) {
-        mp_raise_ValueError(MP_ERROR_TEXT("freqency must be from 1Hz to 40MHz"));
+        mp_raise_ValueError(MP_ERROR_TEXT("frequency must be from 1Hz to 40MHz"));
     }
     if (freq == timers[TIMER_IDX(self->mode, self->timer)].freq_hz) {
         return;
diff --git a/components/micropython/vendor/ports/esp32/machine_sdcard.c b/components/micropython/vendor/ports/esp32/machine_sdcard.c
index 12ba96bb89cb95e4f4d6a72912a02aea288d3a00..e0bb3d5a87b5d0e25626b9592156a90536837b4f 100644
--- a/components/micropython/vendor/ports/esp32/machine_sdcard.c
+++ b/components/micropython/vendor/ports/esp32/machine_sdcard.c
@@ -69,6 +69,68 @@ typedef struct _sdcard_obj_t {
 
 #define _SECTOR_SIZE(self) (self->card.csd.sector_size)
 
+// SPI bus default bus and device configuration.
+
+static const spi_bus_config_t spi_bus_defaults[2] = {
+    {
+        #if CONFIG_IDF_TARGET_ESP32
+        .miso_io_num = GPIO_NUM_19,
+        .mosi_io_num = GPIO_NUM_23,
+        .sclk_io_num = GPIO_NUM_18,
+        #else
+        .miso_io_num = GPIO_NUM_36,
+        .mosi_io_num = GPIO_NUM_35,
+        .sclk_io_num = GPIO_NUM_37,
+        #endif
+        .data2_io_num = GPIO_NUM_NC,
+        .data3_io_num = GPIO_NUM_NC,
+        .data4_io_num = GPIO_NUM_NC,
+        .data5_io_num = GPIO_NUM_NC,
+        .data6_io_num = GPIO_NUM_NC,
+        .data7_io_num = GPIO_NUM_NC,
+        .max_transfer_sz = 4000,
+        .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI,
+        .intr_flags = 0,
+    },
+    {
+        .miso_io_num = GPIO_NUM_2,
+        .mosi_io_num = GPIO_NUM_15,
+        .sclk_io_num = GPIO_NUM_14,
+        .data2_io_num = GPIO_NUM_NC,
+        .data3_io_num = GPIO_NUM_NC,
+        .data4_io_num = GPIO_NUM_NC,
+        .data5_io_num = GPIO_NUM_NC,
+        .data6_io_num = GPIO_NUM_NC,
+        .data7_io_num = GPIO_NUM_NC,
+        .max_transfer_sz = 4000,
+        .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI,
+        .intr_flags = 0,
+    },
+};
+
+#if CONFIG_IDF_TARGET_ESP32
+static const uint8_t spi_dma_channel_defaults[2] = {
+    2,
+    1,
+};
+#endif
+
+static const sdspi_device_config_t spi_dev_defaults[2] = {
+    {
+        #if CONFIG_IDF_TARGET_ESP32
+        .host_id = VSPI_HOST,
+        .gpio_cs = GPIO_NUM_5,
+        #else
+        .host_id = SPI3_HOST,
+        .gpio_cs = GPIO_NUM_34,
+        #endif
+        .gpio_cd = SDSPI_SLOT_NO_CD,
+        .gpio_wp = SDSPI_SLOT_NO_WP,
+        .gpio_int = SDSPI_SLOT_NO_INT,
+    },
+    SDSPI_DEVICE_CONFIG_DEFAULT(), // HSPI (ESP32) / SPI2 (ESP32S3)
+};
+
 STATIC gpio_num_t pin_or_int(const mp_obj_t arg) {
     if (mp_obj_is_small_int(arg)) {
         return MP_OBJ_SMALL_INT_VALUE(arg);
@@ -223,10 +285,11 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
     }
 
     if (is_spi) {
-        #if CONFIG_IDF_TARGET_ESP32S3
-        self->host.slot = slot_num ? SPI3_HOST : SPI2_HOST;
-        #else
+        // Needs to match spi_dev_defaults above.
+        #if CONFIG_IDF_TARGET_ESP32
         self->host.slot = slot_num ? HSPI_HOST : VSPI_HOST;
+        #else
+        self->host.slot = slot_num ? SPI2_HOST : SPI3_HOST;
         #endif
     }
 
@@ -237,46 +300,39 @@ STATIC mp_obj_t machine_sdcard_make_new(const mp_obj_type_t *type, size_t n_args
 
     if (is_spi) {
         // SPI interface
-        #if CONFIG_IDF_TARGET_ESP32S3
-        STATIC const sdspi_slot_config_t slot_defaults[2] = {
-            {
-                .gpio_miso = GPIO_NUM_36,
-                .gpio_mosi = GPIO_NUM_35,
-                .gpio_sck = GPIO_NUM_37,
-                .gpio_cs = GPIO_NUM_34,
-                .gpio_cd = SDSPI_SLOT_NO_CD,
-                .gpio_wp = SDSPI_SLOT_NO_WP,
-                .dma_channel = SPI_DMA_CH_AUTO
-            },
-            SDSPI_SLOT_CONFIG_DEFAULT()
-        };
+        DEBUG_printf("  Setting up SPI slot configuration");
+        spi_host_device_t spi_host_id = self->host.slot;
+        spi_bus_config_t bus_config = spi_bus_defaults[slot_num];
+        #if CONFIG_IDF_TARGET_ESP32
+        spi_dma_chan_t dma_channel = spi_dma_channel_defaults[slot_num];
         #else
-        STATIC const sdspi_slot_config_t slot_defaults[2] = {
-            {
-                .gpio_miso = GPIO_NUM_19,
-                .gpio_mosi = GPIO_NUM_23,
-                .gpio_sck = GPIO_NUM_18,
-                .gpio_cs = GPIO_NUM_5,
-                .gpio_cd = SDSPI_SLOT_NO_CD,
-                .gpio_wp = SDSPI_SLOT_NO_WP,
-                .dma_channel = 2
-            },
-            SDSPI_SLOT_CONFIG_DEFAULT()
-        };
+        spi_dma_chan_t dma_channel = SPI_DMA_CH_AUTO;
         #endif
+        sdspi_device_config_t dev_config = spi_dev_defaults[slot_num];
 
-        DEBUG_printf("  Setting up SPI slot configuration");
-        sdspi_slot_config_t slot_config = slot_defaults[slot_num];
+        SET_CONFIG_PIN(bus_config, miso_io_num, ARG_miso);
+        SET_CONFIG_PIN(bus_config, mosi_io_num, ARG_mosi);
+        SET_CONFIG_PIN(bus_config, sclk_io_num, ARG_sck);
 
-        SET_CONFIG_PIN(slot_config, gpio_cd, ARG_cd);
-        SET_CONFIG_PIN(slot_config, gpio_wp, ARG_wp);
-        SET_CONFIG_PIN(slot_config, gpio_miso, ARG_miso);
-        SET_CONFIG_PIN(slot_config, gpio_mosi, ARG_mosi);
-        SET_CONFIG_PIN(slot_config, gpio_sck, ARG_sck);
-        SET_CONFIG_PIN(slot_config, gpio_cs, ARG_cs);
+        SET_CONFIG_PIN(dev_config, gpio_cs, ARG_cs);
+        SET_CONFIG_PIN(dev_config, gpio_cd, ARG_cd);
+        SET_CONFIG_PIN(dev_config, gpio_wp, ARG_wp);
 
-        DEBUG_printf("  Calling init_slot()");
-        check_esp_err(sdspi_host_init_slot(self->host.slot, &slot_config));
+        DEBUG_printf("  Calling spi_bus_initialize()");
+        check_esp_err(spi_bus_initialize(spi_host_id, &bus_config, dma_channel));
+
+        DEBUG_printf("  Calling sdspi_host_init_device()");
+        sdspi_dev_handle_t sdspi_handle;
+        esp_err_t ret = sdspi_host_init_device(&dev_config, &sdspi_handle);
+        if (ret != ESP_OK) {
+            spi_bus_free(spi_host_id);
+            check_esp_err(ret);
+        }
+        if (self->host.slot != sdspi_handle) {
+            // MicroPython restriction: the SPI bus must be exclusively for the SD card.
+            spi_bus_free(spi_host_id);
+            mp_raise_ValueError(MP_ERROR_TEXT("SPI bus already in use"));
+        }
     } else {
         // SD/MMC interface
         DEBUG_printf("  Setting up SDMMC slot configuration");
@@ -322,12 +378,9 @@ STATIC mp_obj_t sd_deinit(mp_obj_t self_in) {
     DEBUG_printf("De-init host\n");
 
     if (self->flags & SDCARD_CARD_FLAGS_HOST_INIT_DONE) {
-        #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
         if (self->host.flags & SDMMC_HOST_FLAG_DEINIT_ARG) {
             self->host.deinit_p(self->host.slot);
-        } else
-        #endif
-        {
+        } else {
             self->host.deinit();
         }
         if (self->host.flags & SDMMC_HOST_FLAG_SPI) {
diff --git a/components/micropython/vendor/ports/esp32/machine_timer.c b/components/micropython/vendor/ports/esp32/machine_timer.c
index c66cb2a48d903370355da87272bbcc4d52f40a5d..5855cfb3e0b09c4bcd187b31f59b30f9ffd5465c 100644
--- a/components/micropython/vendor/ports/esp32/machine_timer.c
+++ b/components/micropython/vendor/ports/esp32/machine_timer.c
@@ -36,16 +36,13 @@
 #include "mphalport.h"
 
 #include "driver/timer.h"
-#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 1)
 #include "hal/timer_ll.h"
-#define HAVE_TIMER_LL (1)
-#endif
 
 #define TIMER_INTR_SEL TIMER_INTR_LEVEL
 #define TIMER_DIVIDER  8
 
 // TIMER_BASE_CLK is normally 80MHz. TIMER_DIVIDER ought to divide this exactly
-#define TIMER_SCALE    (TIMER_BASE_CLK / TIMER_DIVIDER)
+#define TIMER_SCALE    (APB_CLK_FREQ / TIMER_DIVIDER)
 
 #define TIMER_FLAGS    0
 
@@ -143,39 +140,14 @@ STATIC void machine_timer_isr(void *self_in) {
     machine_timer_obj_t *self = self_in;
     timg_dev_t *device = self->group ? &(TIMERG1) : &(TIMERG0);
 
-    #if HAVE_TIMER_LL
-
-    #if CONFIG_IDF_TARGET_ESP32 && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
-    device->hw_timer[self->index].update = 1;
-    #else
-    #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
     #if CONFIG_IDF_TARGET_ESP32S3
     device->hw_timer[self->index].update.tn_update = 1;
     #else
     device->hw_timer[self->index].update.tx_update = 1;
     #endif
-    #else
-    device->hw_timer[self->index].update.update = 1;
-    #endif
-    #endif
+
     timer_ll_clear_intr_status(device, self->index);
-    #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
-    timer_ll_set_alarm_enable(device, self->index, self->repeat);
-    #else
     timer_ll_set_alarm_value(device, self->index, self->repeat);
-    #endif
-
-    #else
-
-    device->hw_timer[self->index].update = 1;
-    if (self->index) {
-        device->int_clr_timers.t1 = 1;
-    } else {
-        device->int_clr_timers.t0 = 1;
-    }
-    device->hw_timer[self->index].config.alarm_en = self->repeat;
-
-    #endif
 
     mp_sched_schedule(self->callback, self);
     mp_hal_wake_main_task_from_isr();
diff --git a/components/micropython/vendor/ports/esp32/machine_uart.c b/components/micropython/vendor/ports/esp32/machine_uart.c
index 4cfa31b71de3b5ec87e1d65bf4b60879a2845742..7a2dc2b323e28b8f6c51fde87ae110da35a19b49 100644
--- a/components/micropython/vendor/ports/esp32/machine_uart.c
+++ b/components/micropython/vendor/ports/esp32/machine_uart.c
@@ -37,17 +37,17 @@
 #include "modmachine.h"
 #include "uart.h"
 
-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0)
-#define UART_INV_TX UART_INVERSE_TXD
-#define UART_INV_RX UART_INVERSE_RXD
-#define UART_INV_RTS UART_INVERSE_RTS
-#define UART_INV_CTS UART_INVERSE_CTS
+#if SOC_UART_SUPPORT_XTAL_CLK
+// Works independently of APB frequency, on ESP32C3, ESP32S3.
+#define UART_SOURCE_CLK UART_SCLK_XTAL
 #else
+#define UART_SOURCE_CLK UART_SCLK_DEFAULT
+#endif
+
 #define UART_INV_TX UART_SIGNAL_TXD_INV
 #define UART_INV_RX UART_SIGNAL_RXD_INV
 #define UART_INV_RTS UART_SIGNAL_RTS_INV
 #define UART_INV_CTS UART_SIGNAL_CTS_INV
-#endif
 
 #define UART_INV_MASK (UART_INV_TX | UART_INV_RX | UART_INV_RTS | UART_INV_CTS)
 
@@ -164,7 +164,8 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
         }
         uart_config_t uartcfg = {
             .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
-            .rx_flow_ctrl_thresh = 0
+            .rx_flow_ctrl_thresh = 0,
+            .source_clk = UART_SOURCE_CLK,
         };
         uint32_t baudrate;
         uart_get_baudrate(self->uart_num, &baudrate);
@@ -273,9 +274,7 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
         uint32_t char_time_ms = 12000 / baudrate + 1;
         uint32_t rx_timeout = self->timeout_char / char_time_ms;
         if (rx_timeout < 1) {
-            #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)
             uart_set_rx_full_threshold(self->uart_num, 1);
-            #endif
             uart_set_rx_timeout(self->uart_num, 1);
         } else {
             uart_set_rx_timeout(self->uart_num, rx_timeout);
@@ -317,7 +316,8 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
         .parity = UART_PARITY_DISABLE,
         .stop_bits = UART_STOP_BITS_1,
         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
-        .rx_flow_ctrl_thresh = 0
+        .rx_flow_ctrl_thresh = 0,
+        .source_clk = UART_SOURCE_CLK,
     };
 
     // create instance
diff --git a/components/micropython/vendor/ports/esp32/machine_wdt.c b/components/micropython/vendor/ports/esp32/machine_wdt.c
index 4ccf417b60999a1aa2425a232eb7cd4b77f4a59b..2cb6c518175eb2becf2e348b462b369b00ed9fc8 100644
--- a/components/micropython/vendor/ports/esp32/machine_wdt.c
+++ b/components/micropython/vendor/ports/esp32/machine_wdt.c
@@ -54,14 +54,16 @@ STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args
         mp_raise_ValueError(NULL);
     }
 
-    // Convert milliseconds to seconds (esp_task_wdt_init needs seconds)
-    args[ARG_timeout].u_int /= 1000;
-
     if (args[ARG_timeout].u_int <= 0) {
         mp_raise_ValueError(MP_ERROR_TEXT("WDT timeout too short"));
     }
 
-    mp_int_t rs_code = esp_task_wdt_init(args[ARG_timeout].u_int, true);
+    esp_task_wdt_config_t config = {
+        .timeout_ms = args[ARG_timeout].u_int,
+        .idle_core_mask = 0,
+        .trigger_panic = true,
+    };
+    mp_int_t rs_code = esp_task_wdt_reconfigure(&config);
     if (rs_code != ESP_OK) {
         mp_raise_OSError(rs_code);
     }
diff --git a/components/micropython/vendor/ports/esp32/main.c b/components/micropython/vendor/ports/esp32/main.c
index a2040c483019af13c3153dd36c5a12574a775397..acb6316f5752eb7cbc30ea4f180de3d0f6eb5442 100644
--- a/components/micropython/vendor/ports/esp32/main.c
+++ b/components/micropython/vendor/ports/esp32/main.c
@@ -35,16 +35,9 @@
 #include "esp_system.h"
 #include "nvs_flash.h"
 #include "esp_task.h"
-#include "soc/cpu.h"
+#include "esp_event.h"
 #include "esp_log.h"
-
-#if CONFIG_IDF_TARGET_ESP32
-#include "esp32/spiram.h"
-#elif CONFIG_IDF_TARGET_ESP32S2
-#include "esp32s2/spiram.h"
-#elif CONFIG_IDF_TARGET_ESP32S3
-#include "esp32s3/spiram.h"
-#endif
+#include "esp_psram.h"
 
 #include "py/stackctrl.h"
 #include "py/nlr.h"
@@ -84,7 +77,7 @@ int vprintf_null(const char *format, va_list ap) {
 }
 
 void mp_task(void *pvParameter) {
-    volatile uint32_t sp = (uint32_t)get_sp();
+    volatile uint32_t sp = (uint32_t)esp_cpu_get_sp();
     #if MICROPY_PY_THREAD
     mp_thread_init(pxTaskGetStackStart(NULL), MP_TASK_STACK_SIZE / sizeof(uintptr_t));
     #endif
@@ -98,50 +91,18 @@ void mp_task(void *pvParameter) {
     #endif
     machine_init();
 
-    size_t mp_task_heap_size;
-    void *mp_task_heap = NULL;
-
-    #if CONFIG_SPIRAM_USE_MALLOC
-    // SPIRAM is issued using MALLOC, fallback to normal allocation rules
-    mp_task_heap = NULL;
-    #elif CONFIG_ESP32_SPIRAM_SUPPORT
-    // Try to use the entire external SPIRAM directly for the heap
-    mp_task_heap = (void *)SOC_EXTRAM_DATA_LOW;
-    switch (esp_spiram_get_chip_size()) {
-        case ESP_SPIRAM_SIZE_16MBITS:
-            mp_task_heap_size = 2 * 1024 * 1024;
-            break;
-        case ESP_SPIRAM_SIZE_32MBITS:
-        case ESP_SPIRAM_SIZE_64MBITS:
-            mp_task_heap_size = 4 * 1024 * 1024;
-            break;
-        default:
-            // No SPIRAM, fallback to normal allocation
-            mp_task_heap = NULL;
-            break;
+    esp_err_t err = esp_event_loop_create_default();
+    if (err != ESP_OK) {
+        ESP_LOGE("esp_init", "can't create event loop: 0x%x\n", err);
     }
-    #elif CONFIG_ESP32S2_SPIRAM_SUPPORT || CONFIG_ESP32S3_SPIRAM_SUPPORT
-    // Try to use the entire external SPIRAM directly for the heap
-    size_t esp_spiram_size = esp_spiram_get_size();
-    if (esp_spiram_size > 0) {
-        mp_task_heap = (void *)SOC_EXTRAM_DATA_HIGH - esp_spiram_size;
-        mp_task_heap_size = esp_spiram_size;
-    }
-    #endif
 
-    if (mp_task_heap == NULL) {
-        // Allocate the uPy heap using malloc and get the largest available region,
-        // limiting to 1/2 total available memory to leave memory for the OS.
-        #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)
-        size_t heap_total = heap_caps_get_total_size(MALLOC_CAP_8BIT);
-        #else
-        multi_heap_info_t info;
-        heap_caps_get_info(&info, MALLOC_CAP_8BIT);
-        size_t heap_total = info.total_free_bytes + info.total_allocated_bytes;
-        #endif
-        mp_task_heap_size = MIN(heap_caps_get_largest_free_block(MALLOC_CAP_8BIT), heap_total / 2);
-        mp_task_heap = malloc(mp_task_heap_size);
-    }
+    // Allocate the uPy heap using malloc and get the largest available region,
+    // limiting to 1/2 total available memory to leave memory for the OS.
+    // When SPIRAM is enabled, this will allocate from SPIRAM.
+    uint32_t caps = MALLOC_CAP_8BIT;
+    size_t heap_total = heap_caps_get_total_size(caps);
+    size_t mp_task_heap_size = MIN(heap_caps_get_largest_free_block(caps), heap_total / 2);
+    void *mp_task_heap = heap_caps_malloc(mp_task_heap_size, caps);
 
 soft_reset:
     // initialise the stack pointer for the main thread
@@ -211,12 +172,11 @@ soft_reset_exit:
     mp_hal_stdout_tx_str("MPY: soft reboot\r\n");
 
     // deinitialise peripherals
-    machine_pwm_deinit_all();
     // TODO: machine_rmt_deinit_all();
     machine_pins_deinit();
     machine_deinit();
-    #if MICROPY_PY_USOCKET_EVENTS
-    usocket_events_deinit();
+    #if MICROPY_PY_SOCKET_EVENTS
+    socket_events_deinit();
     #endif
 
     mp_deinit();
diff --git a/components/micropython/vendor/ports/esp32/main/CMakeLists.txt b/components/micropython/vendor/ports/esp32/main/CMakeLists.txt
deleted file mode 100644
index 59592b3ae06dd3594b3a7669903b44291eb88219..0000000000000000000000000000000000000000
--- a/components/micropython/vendor/ports/esp32/main/CMakeLists.txt
+++ /dev/null
@@ -1,243 +0,0 @@
-# Set location of base MicroPython directory.
-if(NOT MICROPY_DIR)
-    get_filename_component(MICROPY_DIR ${PROJECT_DIR}/../.. ABSOLUTE)
-endif()
-
-# Include core source components.
-include(${MICROPY_DIR}/py/py.cmake)
-
-if(NOT CMAKE_BUILD_EARLY_EXPANSION)
-    # Enable extmod components that will be configured by extmod.cmake.
-    # A board may also have enabled additional components.
-    set(MICROPY_PY_BTREE ON)
-
-    include(${MICROPY_DIR}/py/usermod.cmake)
-    include(${MICROPY_DIR}/extmod/extmod.cmake)
-endif()
-
-set(MICROPY_QSTRDEFS_PORT
-    ${PROJECT_DIR}/qstrdefsport.h
-)
-
-set(BADGE23_LIB
-    ${PROJECT_DIR}/../../../badge23/apa102LEDStrip.c
-    ${PROJECT_DIR}/../../../badge23/audio.c
-    ${PROJECT_DIR}/../../../badge23/captouch.c
-    ${PROJECT_DIR}/../../../badge23/display.c
-    ${PROJECT_DIR}/../../../badge23/espan.c
-    ${PROJECT_DIR}/../../../badge23/leds.c
-    ${PROJECT_DIR}/../../../badge23/scope.c
-    ${PROJECT_DIR}/../../../badge23/synth.c
-    ${PROJECT_DIR}/../../../badge23/components/gc9a01/gc9a01.c
-)
-
-set(MICROPY_SOURCE_SHARED
-    ${MICROPY_DIR}/shared/readline/readline.c
-    ${MICROPY_DIR}/shared/netutils/netutils.c
-    ${MICROPY_DIR}/shared/timeutils/timeutils.c
-    ${MICROPY_DIR}/shared/runtime/interrupt_char.c
-    ${MICROPY_DIR}/shared/runtime/stdout_helpers.c
-    ${MICROPY_DIR}/shared/runtime/sys_stdio_mphal.c
-    ${MICROPY_DIR}/shared/runtime/pyexec.c
-)
-
-set(MICROPY_SOURCE_LIB
-    ${MICROPY_DIR}/lib/littlefs/lfs1.c
-    ${MICROPY_DIR}/lib/littlefs/lfs1_util.c
-    ${MICROPY_DIR}/lib/littlefs/lfs2.c
-    ${MICROPY_DIR}/lib/littlefs/lfs2_util.c
-    ${MICROPY_DIR}/lib/mbedtls_errors/mp_mbedtls_errors.c
-    ${MICROPY_DIR}/lib/oofatfs/ff.c
-    ${MICROPY_DIR}/lib/oofatfs/ffunicode.c
-)
-if(IDF_TARGET STREQUAL "esp32c3")
-    list(APPEND MICROPY_SOURCE_LIB ${MICROPY_DIR}/shared/runtime/gchelper_generic.c)
-endif()
-
-set(MICROPY_SOURCE_DRIVERS
-    ${MICROPY_DIR}/drivers/bus/softspi.c
-    ${MICROPY_DIR}/drivers/dht/dht.c
-)
-
-set(MICROPY_SOURCE_PORT
-    ${PROJECT_DIR}/badge23_mp_hardware.c
-    ${PROJECT_DIR}/badge23_mp_synth.c
-    ${PROJECT_DIR}/main.c
-    ${PROJECT_DIR}/uart.c
-    ${PROJECT_DIR}/usb.c
-    ${PROJECT_DIR}/usb_serial_jtag.c
-    ${PROJECT_DIR}/gccollect.c
-    ${PROJECT_DIR}/mphalport.c
-    ${PROJECT_DIR}/fatfs_port.c
-    ${PROJECT_DIR}/help.c
-    ${PROJECT_DIR}/modutime.c
-    ${PROJECT_DIR}/machine_bitstream.c
-    ${PROJECT_DIR}/machine_timer.c
-    ${PROJECT_DIR}/machine_pin.c
-    ${PROJECT_DIR}/machine_touchpad.c
-    ${PROJECT_DIR}/machine_adc.c
-    ${PROJECT_DIR}/machine_adcblock.c
-    ${PROJECT_DIR}/machine_dac.c
-    ${PROJECT_DIR}/machine_i2c.c
-    ${PROJECT_DIR}/machine_i2s.c
-    ${PROJECT_DIR}/machine_uart.c
-    ${PROJECT_DIR}/modmachine.c
-    ${PROJECT_DIR}/network_common.c
-    ${PROJECT_DIR}/network_lan.c
-    ${PROJECT_DIR}/network_ppp.c
-    ${PROJECT_DIR}/network_wlan.c
-    ${PROJECT_DIR}/mpnimbleport.c
-    ${PROJECT_DIR}/modsocket.c
-    ${PROJECT_DIR}/modesp.c
-    ${PROJECT_DIR}/esp32_nvs.c
-    ${PROJECT_DIR}/esp32_partition.c
-    ${PROJECT_DIR}/esp32_rmt.c
-    ${PROJECT_DIR}/esp32_ulp.c
-    ${PROJECT_DIR}/modesp32.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(MICROPY_SOURCE_QSTR
-    ${MICROPY_SOURCE_PY}
-    ${MICROPY_SOURCE_EXTMOD}
-    ${MICROPY_SOURCE_USERMOD}
-    ${MICROPY_SOURCE_SHARED}
-    ${MICROPY_SOURCE_LIB}
-    ${MICROPY_SOURCE_PORT}
-    ${MICROPY_SOURCE_BOARD}
-    ${BADGE23_LIB}
-)
-
-set(IDF_COMPONENTS
-    app_update
-    bootloader_support
-    bt
-    driver
-    esp_adc_cal
-    esp_common
-    esp_eth
-    esp_event
-    esp_ringbuf
-    esp_rom
-    esp_wifi
-    freertos
-    heap
-    log
-    lwip
-    mbedtls
-    mdns
-    newlib
-    nvs_flash
-    sdmmc
-    soc
-    spi_flash
-    tcpip_adapter
-    ulp
-    vfs
-    xtensa
-)
-
-if(IDF_VERSION_MINOR GREATER_EQUAL 1 OR IDF_VERSION_MAJOR GREATER_EQUAL 5)
-    list(APPEND IDF_COMPONENTS esp_netif)
-endif()
-
-if(IDF_VERSION_MINOR GREATER_EQUAL 2 OR IDF_VERSION_MAJOR GREATER_EQUAL 5)
-    list(APPEND IDF_COMPONENTS esp_system)
-    list(APPEND IDF_COMPONENTS esp_timer)
-endif()
-
-if(IDF_VERSION_MINOR GREATER_EQUAL 3 OR IDF_VERSION_MAJOR GREATER_EQUAL 5)
-    list(APPEND IDF_COMPONENTS esp_hw_support)
-    list(APPEND IDF_COMPONENTS esp_pm)
-    list(APPEND IDF_COMPONENTS hal)
-endif()
-
-if(IDF_TARGET STREQUAL "esp32")
-    list(APPEND IDF_COMPONENTS esp32)
-elseif(IDF_TARGET STREQUAL "esp32c3")
-    list(APPEND IDF_COMPONENTS esp32c3)
-    list(APPEND IDF_COMPONENTS riscv)
-elseif(IDF_TARGET STREQUAL "esp32s2")
-    list(APPEND IDF_COMPONENTS esp32s2)
-    list(APPEND IDF_COMPONENTS tinyusb)
-elseif(IDF_TARGET STREQUAL "esp32s3")
-    list(APPEND IDF_COMPONENTS esp32s3)
-    list(APPEND IDF_COMPONENTS tinyusb)
-endif()
-
-# Register the main IDF component.
-idf_component_register(
-    SRCS
-        ${MICROPY_SOURCE_PY}
-        ${MICROPY_SOURCE_EXTMOD}
-        ${MICROPY_SOURCE_SHARED}
-        ${MICROPY_SOURCE_LIB}
-        ${MICROPY_SOURCE_DRIVERS}
-        ${MICROPY_SOURCE_PORT}
-        ${MICROPY_SOURCE_BOARD}
-        ${BADGE23_LIB}
-    INCLUDE_DIRS
-        ${MICROPY_INC_CORE}
-        ${MICROPY_INC_USERMOD}
-        ${MICROPY_PORT_DIR}
-        ${MICROPY_BOARD_DIR}
-        ${CMAKE_BINARY_DIR}
-    REQUIRES
-        ${IDF_COMPONENTS}
-)
-
-# Set the MicroPython target as the current (main) IDF component target.
-set(MICROPY_TARGET ${COMPONENT_TARGET})
-
-# Define mpy-cross flags, for use with frozen code.
-set(MICROPY_CROSS_FLAGS -march=xtensawin)
-
-# Set compile options for this port.
-target_compile_definitions(${MICROPY_TARGET} PUBLIC
-    ${MICROPY_DEF_CORE}
-    MICROPY_ESP_IDF_4=1
-    MICROPY_VFS_FAT=1
-    MICROPY_VFS_LFS2=1
-    FFCONF_H=\"${MICROPY_OOFATFS_DIR}/ffconf.h\"
-    LFS1_NO_MALLOC LFS1_NO_DEBUG LFS1_NO_WARN LFS1_NO_ERROR LFS1_NO_ASSERT
-    LFS2_NO_MALLOC LFS2_NO_DEBUG LFS2_NO_WARN LFS2_NO_ERROR LFS2_NO_ASSERT
-)
-
-# Disable some warnings to keep the build output clean.
-target_compile_options(${MICROPY_TARGET} PUBLIC
-    -Wno-clobbered
-    -Wno-deprecated-declarations
-    -Wno-missing-field-initializers
-)
-
-# Additional include directories needed for private NimBLE headers.
-target_include_directories(${MICROPY_TARGET} PUBLIC
-    ${IDF_PATH}/components/bt/host/nimble/nimble
-)
-
-# Add additional extmod and usermod components.
-target_link_libraries(${MICROPY_TARGET} micropy_extmod_btree)
-target_link_libraries(${MICROPY_TARGET} usermod)
-
-# Collect all of the include directories and compile definitions for the IDF components.
-foreach(comp ${IDF_COMPONENTS})
-    micropy_gather_target_properties(__idf_${comp})
-endforeach()
-
-if(IDF_VERSION_MINOR GREATER_EQUAL 2 OR IDF_VERSION_MAJOR GREATER_EQUAL 5)
-    # These paths cannot currently be found by the IDF_COMPONENTS search loop above,
-    # so add them explicitly.
-    list(APPEND MICROPY_CPP_INC_EXTRA ${IDF_PATH}/components/soc/soc/${IDF_TARGET}/include)
-    list(APPEND MICROPY_CPP_INC_EXTRA ${IDF_PATH}/components/soc/soc/include)
-    if(IDF_VERSION_MINOR GREATER_EQUAL 3)
-        list(APPEND MICROPY_CPP_INC_EXTRA ${IDF_PATH}/components/tinyusb/additions/include)
-        list(APPEND MICROPY_CPP_INC_EXTRA ${IDF_PATH}/components/tinyusb/tinyusb/src)
-    endif()
-endif()
-
-# Include the main MicroPython cmake rules.
-include(${MICROPY_DIR}/py/mkrules.cmake)
diff --git a/components/micropython/vendor/ports/esp32/modesp.c b/components/micropython/vendor/ports/esp32/modesp.c
index f125b614bda95df99fa98084fabb7363e7d30f33..4726ce5874209deedf1cfc931f1531163b639b17 100644
--- a/components/micropython/vendor/ports/esp32/modesp.c
+++ b/components/micropython/vendor/ports/esp32/modesp.c
@@ -29,8 +29,8 @@
 
 #include <stdio.h>
 
+#include "esp_flash.h"
 #include "esp_log.h"
-#include "esp_spi_flash.h"
 
 #include "py/runtime.h"
 #include "py/mperrno.h"
@@ -53,33 +53,33 @@ STATIC mp_obj_t esp_osdebug(size_t n_args, const mp_obj_t *args) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_osdebug_obj, 1, 2, esp_osdebug);
 
-STATIC mp_obj_t esp_flash_read(mp_obj_t offset_in, mp_obj_t buf_in) {
+STATIC mp_obj_t esp_flash_read_(mp_obj_t offset_in, mp_obj_t buf_in) {
     mp_int_t offset = mp_obj_get_int(offset_in);
     mp_buffer_info_t bufinfo;
     mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
-    esp_err_t res = spi_flash_read(offset, bufinfo.buf, bufinfo.len);
+    esp_err_t res = esp_flash_read(NULL, bufinfo.buf, offset, bufinfo.len);
     if (res != ESP_OK) {
         mp_raise_OSError(MP_EIO);
     }
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_read_obj, esp_flash_read);
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_read_obj, esp_flash_read_);
 
-STATIC mp_obj_t esp_flash_write(mp_obj_t offset_in, mp_obj_t buf_in) {
+STATIC mp_obj_t esp_flash_write_(mp_obj_t offset_in, mp_obj_t buf_in) {
     mp_int_t offset = mp_obj_get_int(offset_in);
     mp_buffer_info_t bufinfo;
     mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
-    esp_err_t res = spi_flash_write(offset, bufinfo.buf, bufinfo.len);
+    esp_err_t res = esp_flash_write(NULL, bufinfo.buf, offset, bufinfo.len);
     if (res != ESP_OK) {
         mp_raise_OSError(MP_EIO);
     }
     return mp_const_none;
 }
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_write_obj, esp_flash_write);
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_write_obj, esp_flash_write_);
 
 STATIC mp_obj_t esp_flash_erase(mp_obj_t sector_in) {
     mp_int_t sector = mp_obj_get_int(sector_in);
-    esp_err_t res = spi_flash_erase_sector(sector);
+    esp_err_t res = esp_flash_erase_region(NULL, sector * 4096, 4096);
     if (res != ESP_OK) {
         mp_raise_OSError(MP_EIO);
     }
@@ -88,7 +88,9 @@ STATIC mp_obj_t esp_flash_erase(mp_obj_t sector_in) {
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_flash_erase_obj, esp_flash_erase);
 
 STATIC mp_obj_t esp_flash_size(void) {
-    return mp_obj_new_int_from_uint(spi_flash_get_chip_size());
+    uint32_t size;
+    esp_flash_get_size(NULL, &size);
+    return mp_obj_new_int_from_uint(size);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);
 
@@ -98,14 +100,14 @@ STATIC mp_obj_t esp_flash_user_start(void) {
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_user_start_obj, esp_flash_user_start);
 
 STATIC mp_obj_t esp_gpio_matrix_in(mp_obj_t pin, mp_obj_t sig, mp_obj_t inv) {
-    gpio_matrix_in(mp_obj_get_int(pin), mp_obj_get_int(sig), mp_obj_get_int(inv));
+    esp_rom_gpio_connect_in_signal(mp_obj_get_int(pin), mp_obj_get_int(sig), mp_obj_get_int(inv));
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_gpio_matrix_in_obj, esp_gpio_matrix_in);
 
 STATIC mp_obj_t esp_gpio_matrix_out(size_t n_args, const mp_obj_t *args) {
     (void)n_args;
-    gpio_matrix_out(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2]), mp_obj_get_int(args[3]));
+    esp_rom_gpio_connect_out_signal(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2]), mp_obj_get_int(args[3]));
     return mp_const_none;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_gpio_matrix_out_obj, 4, 4, esp_gpio_matrix_out);
diff --git a/components/micropython/vendor/ports/esp32/modesp32.c b/components/micropython/vendor/ports/esp32/modesp32.c
index 017db36e22adfc127fb2a5fa72c62cca9c178c82..0a9a2569e7153559ac83626a0014027c99fad580 100644
--- a/components/micropython/vendor/ports/esp32/modesp32.c
+++ b/components/micropython/vendor/ports/esp32/modesp32.c
@@ -31,7 +31,6 @@
 #include <sys/time.h>
 #include "soc/rtc_cntl_reg.h"
 #include "driver/gpio.h"
-#include "driver/adc.h"
 #include "esp_heap_caps.h"
 #include "multi_heap.h"
 
@@ -45,10 +44,8 @@
 #include "modesp32.h"
 
 // These private includes are needed for idf_heap_info.
-#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
 #define MULTI_HEAP_FREERTOS
 #include "../multi_heap_platform.h"
-#endif
 #include "../heap_private.h"
 
 STATIC mp_obj_t esp32_wake_on_touch(const mp_obj_t wake) {
@@ -161,9 +158,9 @@ STATIC mp_obj_t esp32_raw_temperature(void) {
     CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);
     SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP_FORCE);
     SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP);
-    ets_delay_us(100);
+    esp_rom_delay_us(100);
     SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);
-    ets_delay_us(5);
+    esp_rom_delay_us(5);
     int res = GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR3_REG, SENS_TSENS_OUT, SENS_TSENS_OUT_S);
 
     return mp_obj_new_int(res);
@@ -216,7 +213,6 @@ STATIC const mp_rom_map_elem_t esp32_module_globals_table[] = {
 
     { MP_ROM_QSTR(MP_QSTR_NVS), MP_ROM_PTR(&esp32_nvs_type) },
     { MP_ROM_QSTR(MP_QSTR_Partition), MP_ROM_PTR(&esp32_partition_type) },
-    { MP_ROM_QSTR(MP_QSTR_RMT), MP_ROM_PTR(&esp32_rmt_type) },
     #if CONFIG_IDF_TARGET_ESP32
     { MP_ROM_QSTR(MP_QSTR_ULP), MP_ROM_PTR(&esp32_ulp_type) },
     #endif
diff --git a/components/micropython/vendor/ports/esp32/modmachine.c b/components/micropython/vendor/ports/esp32/modmachine.c
index 37d4f424d421672b29db514e6206456061cbd3ef..6779a6bcfc3fb29a24880bf6016d3f65ceb0bf55 100644
--- a/components/micropython/vendor/ports/esp32/modmachine.c
+++ b/components/micropython/vendor/ports/esp32/modmachine.c
@@ -32,20 +32,10 @@
 
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
+#include "esp_mac.h"
 #include "esp_sleep.h"
 #include "esp_pm.h"
 
-#if CONFIG_IDF_TARGET_ESP32
-#include "esp32/rom/rtc.h"
-#include "esp32/clk.h"
-#elif CONFIG_IDF_TARGET_ESP32S2
-#include "esp32s2/rom/rtc.h"
-#include "esp32s2/clk.h"
-#elif CONFIG_IDF_TARGET_ESP32S3
-#include "esp32s3/rom/rtc.h"
-#include "esp32s3/clk.h"
-#endif
-
 #include "py/obj.h"
 #include "py/runtime.h"
 #include "shared/runtime/pyexec.h"
@@ -79,7 +69,7 @@ int esp_clk_cpu_freq(void);
 STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
     if (n_args == 0) {
         // get
-        return mp_obj_new_int(esp_clk_cpu_freq());
+        return mp_obj_new_int(esp_rom_get_cpu_ticks_per_us() * 1000000);
     } else {
         // set
         mp_int_t freq = mp_obj_get_int(args[0]) / 1000000;
@@ -110,7 +100,7 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
         if (ret != ESP_OK) {
             mp_raise_ValueError(NULL);
         }
-        while (esp_clk_cpu_freq() != freq * 1000000) {
+        while (esp_rom_get_cpu_ticks_per_us() != freq) {
             vTaskDelay(1);
         }
         return mp_const_none;
@@ -272,7 +262,7 @@ STATIC mp_obj_t machine_enable_irq(mp_obj_t state_in) {
 MP_DEFINE_CONST_FUN_OBJ_1(machine_enable_irq_obj, machine_enable_irq);
 
 STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
-    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
+    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_machine) },
 
     { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) },
     { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) },
@@ -290,42 +280,21 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
     { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) },
     { MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&machine_enable_irq_obj) },
 
-    #if MICROPY_PY_MACHINE_BITSTREAM
-    { MP_ROM_QSTR(MP_QSTR_bitstream), MP_ROM_PTR(&machine_bitstream_obj) },
-    #endif
-    #if MICROPY_PY_MACHINE_PULSE
-    { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) },
-    #endif
     { MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) },
 
     { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) },
-    { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) },
-    #if MICROPY_HW_ENABLE_SDCARD
-    { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&machine_sdcard_type) },
-    #endif
 
     // wake abilities
     { MP_ROM_QSTR(MP_QSTR_SLEEP), MP_ROM_INT(MACHINE_WAKE_SLEEP) },
     { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) },
     { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) },
     { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) },
-    #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
-    { MP_ROM_QSTR(MP_QSTR_TouchPad), MP_ROM_PTR(&machine_touchpad_type) },
-    #endif
     { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
     { MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adcblock_type) },
     #if MICROPY_PY_MACHINE_DAC
     { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) },
     #endif
-    { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) },
-    { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) },
-    #if MICROPY_PY_MACHINE_I2S
-    { MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) },
-    #endif
-    { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) },
     { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) },
-    { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },
-    { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) },
     { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
 
     // Reset reasons
diff --git a/components/micropython/vendor/ports/esp32/modnetwork.h b/components/micropython/vendor/ports/esp32/modnetwork.h
index 5f2767ac8d4fdd48b9c18b3d900f4cc033d43384..b1b3fc368a450f7f4ea279725de083d029469bb4 100644
--- a/components/micropython/vendor/ports/esp32/modnetwork.h
+++ b/components/micropython/vendor/ports/esp32/modnetwork.h
@@ -26,7 +26,7 @@
 #ifndef MICROPY_INCLUDED_ESP32_MODNETWORK_H
 #define MICROPY_INCLUDED_ESP32_MODNETWORK_H
 
-#include "esp_event.h"
+#include "esp_netif.h"
 
 enum { PHY_LAN8710, PHY_LAN8720, PHY_IP101, PHY_RTL8201, PHY_DP83848, PHY_KSZ8041, PHY_KSZ8081, PHY_KSZ8851SNL = 100, PHY_DM9051, PHY_W5500 };
 #define IS_SPI_PHY(NUM) (NUM >= 100)
@@ -40,10 +40,13 @@ enum {
     STAT_GOT_IP     = 1010,
 };
 
-typedef struct _wlan_if_obj_t {
+typedef struct _base_if_obj_t {
     mp_obj_base_t base;
-    int if_id;
-} wlan_if_obj_t;
+    esp_interface_t if_id;
+    esp_netif_t *netif;
+} base_if_obj_t;
+
+extern const mp_obj_type_t esp_network_wlan_type;
 
 MP_DECLARE_CONST_FUN_OBJ_0(esp_network_initialize_obj);
 MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_get_wlan_obj);
@@ -61,7 +64,7 @@ static inline void esp_exceptions(esp_err_t e) {
     }
 }
 
-void usocket_events_deinit(void);
-void network_wlan_event_handler(system_event_t *event);
+void socket_events_deinit(void);
+void esp_initialise_wifi(void);
 
 #endif
diff --git a/components/micropython/vendor/ports/esp32/modnetwork_globals.h b/components/micropython/vendor/ports/esp32/modnetwork_globals.h
index 72d1ff3afbbc9bb8fa130a1ca7baf9eaf86af3e1..2b6405a66c731182e7d1b36f2a26797d162da5a2 100644
--- a/components/micropython/vendor/ports/esp32/modnetwork_globals.h
+++ b/components/micropython/vendor/ports/esp32/modnetwork_globals.h
@@ -1,7 +1,7 @@
 { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&esp_network_initialize_obj) },
 
 #if MICROPY_PY_NETWORK_WLAN
-{ MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&esp_network_get_wlan_obj) },
+{ MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&esp_network_wlan_type) },
 #endif
 
 #if MICROPY_PY_NETWORK_LAN
@@ -27,9 +27,7 @@
 { MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_ENTERPRISE), MP_ROM_INT(WIFI_AUTH_WPA2_ENTERPRISE) },
 { MP_ROM_QSTR(MP_QSTR_AUTH_WPA3_PSK), MP_ROM_INT(WIFI_AUTH_WPA3_PSK) },
 { MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_WPA3_PSK), MP_ROM_INT(WIFI_AUTH_WPA2_WPA3_PSK) },
-#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(4, 3, 0)
 { MP_ROM_QSTR(MP_QSTR_AUTH_WAPI_PSK), MP_ROM_INT(WIFI_AUTH_WAPI_PSK) },
-#endif
 { MP_ROM_QSTR(MP_QSTR_AUTH_MAX), MP_ROM_INT(WIFI_AUTH_MAX) },
 #endif
 
@@ -39,14 +37,8 @@
 { MP_ROM_QSTR(MP_QSTR_PHY_IP101), MP_ROM_INT(PHY_IP101) },
 { MP_ROM_QSTR(MP_QSTR_PHY_RTL8201), MP_ROM_INT(PHY_RTL8201) },
 { MP_ROM_QSTR(MP_QSTR_PHY_DP83848), MP_ROM_INT(PHY_DP83848) },
-#if ESP_IDF_VERSION_MINOR >= 3
-// PHY_KSZ8041 is new in ESP-IDF v4.3
 { MP_ROM_QSTR(MP_QSTR_PHY_KSZ8041), MP_ROM_INT(PHY_KSZ8041) },
-#endif
-#if ESP_IDF_VERSION_MINOR >= 4
-// PHY_KSZ8081 is new in ESP-IDF v4.4
 { MP_ROM_QSTR(MP_QSTR_PHY_KSZ8081), MP_ROM_INT(PHY_KSZ8081) },
-#endif
 
 #if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
 { MP_ROM_QSTR(MP_QSTR_PHY_KSZ8851SNL), MP_ROM_INT(PHY_KSZ8851SNL) },
diff --git a/components/micropython/vendor/ports/esp32/modsocket.c b/components/micropython/vendor/ports/esp32/modsocket.c
index 9812eb347689cad4c004639072d98b310da69620..732d29fdd03be1827912fc722df207451d8be7fa 100644
--- a/components/micropython/vendor/ports/esp32/modsocket.c
+++ b/components/micropython/vendor/ports/esp32/modsocket.c
@@ -46,7 +46,6 @@
 #include "py/stream.h"
 #include "py/mperrno.h"
 #include "shared/netutils/netutils.h"
-#include "mdns.h"
 #include "modnetwork.h"
 
 #include "lwip/sockets.h"
@@ -56,8 +55,6 @@
 #include "esp_log.h"
 
 #define SOCKET_POLL_US (100000)
-#define MDNS_QUERY_TIMEOUT_MS (5000)
-#define MDNS_LOCAL_SUFFIX ".local"
 
 enum {
     SOCKET_STATE_NEW,
@@ -154,55 +151,6 @@ static inline void check_for_exceptions(void) {
 static int _socket_getaddrinfo3(const char *nodename, const char *servname,
     const struct addrinfo *hints, struct addrinfo **res) {
 
-    #if MICROPY_HW_ENABLE_MDNS_QUERIES
-    int nodename_len = strlen(nodename);
-    const int local_len = sizeof(MDNS_LOCAL_SUFFIX) - 1;
-    if (nodename_len > local_len
-        && strcasecmp(nodename + nodename_len - local_len, MDNS_LOCAL_SUFFIX) == 0) {
-        // mDNS query
-        char nodename_no_local[nodename_len - local_len + 1];
-        memcpy(nodename_no_local, nodename, nodename_len - local_len);
-        nodename_no_local[nodename_len - local_len] = '\0';
-
-        #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0)
-        struct ip4_addr addr = {0};
-        #else
-        esp_ip4_addr_t addr = {0};
-        #endif
-
-        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) {
-                *res = NULL;
-                return 0;
-            }
-            *res = NULL;
-            return err;
-        }
-
-        struct addrinfo *ai = memp_malloc(MEMP_NETDB);
-        if (ai == NULL) {
-            *res = NULL;
-            return EAI_MEMORY;
-        }
-        memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
-
-        struct sockaddr_in *sa = (struct sockaddr_in *)((uint8_t *)ai + sizeof(struct addrinfo));
-        inet_addr_from_ip4addr(&sa->sin_addr, &addr);
-        sa->sin_family = AF_INET;
-        sa->sin_len = sizeof(struct sockaddr_in);
-        sa->sin_port = lwip_htons((u16_t)atoi(servname));
-        ai->ai_family = AF_INET;
-        ai->ai_canonname = ((char *)sa + sizeof(struct sockaddr_storage));
-        memcpy(ai->ai_canonname, nodename, nodename_len + 1);
-        ai->ai_addrlen = sizeof(struct sockaddr_storage);
-        ai->ai_addr = (struct sockaddr *)sa;
-
-        *res = ai;
-        return 0;
-    }
-    #endif
-
     // Normal query
     return lwip_getaddrinfo(nodename, servname, hints, res);
 }
@@ -836,7 +784,7 @@ STATIC mp_obj_t esp_socket_initialize() {
     static int initialized = 0;
     if (!initialized) {
         ESP_LOGI("modsocket", "Initializing");
-        tcpip_adapter_init();
+        esp_netif_init();
         initialized = 1;
     }
     return mp_const_none;
diff --git a/components/micropython/vendor/ports/esp32/moduos.c b/components/micropython/vendor/ports/esp32/moduos.c
index bdfd19c5d20ad57dd00abe6a2f9313d7f8cb74a6..ecd0b524a37d28bc18177087be1bcdce95bb1ee3 100644
--- a/components/micropython/vendor/ports/esp32/moduos.c
+++ b/components/micropython/vendor/ports/esp32/moduos.c
@@ -32,6 +32,7 @@
 #include "py/runtime.h"
 #include "py/mphal.h"
 #include "extmod/misc.h"
+#include "esp_random.h"
 
 STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) {
     mp_int_t n = mp_obj_get_int(num);
diff --git a/components/micropython/vendor/ports/esp32/mpconfigport.h b/components/micropython/vendor/ports/esp32/mpconfigport.h
index 94daa2caa175dfa97a0188ac9872f93f947127c6..68cd933333b547a9ffcc4306adc72422bc3af2ff 100644
--- a/components/micropython/vendor/ports/esp32/mpconfigport.h
+++ b/components/micropython/vendor/ports/esp32/mpconfigport.h
@@ -7,8 +7,9 @@
 #include <stdint.h>
 #include <alloca.h>
 #include "esp_system.h"
+#include "esp_random.h"
 #include "freertos/FreeRTOS.h"
-#include "driver/i2s.h"
+#include "esp_wifi_types.h"
 
 #ifndef MICROPY_CONFIG_ROM_LEVEL
 #define MICROPY_CONFIG_ROM_LEVEL            (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
@@ -81,7 +82,7 @@
 #define MICROPY_PY_UTIMEQ                   (1)
 #define MICROPY_PY_UHASHLIB_SHA1            (1)
 #define MICROPY_PY_UHASHLIB_SHA256          (1)
-#define MICROPY_PY_UCRYPTOLIB               (1)
+#define MICROPY_PY_UCRYPTOLIB               (0)
 #define MICROPY_PY_URANDOM_SEED_INIT_FUNC   (esp_random())
 #define MICROPY_PY_UOS_INCLUDEFILE          "ports/esp32/moduos.c"
 #define MICROPY_PY_OS_DUPTERM               (1)
@@ -107,9 +108,6 @@
 #ifndef MICROPY_PY_MACHINE_DAC
 #define MICROPY_PY_MACHINE_DAC              (1)
 #endif
-#ifndef MICROPY_PY_MACHINE_I2S
-#define MICROPY_PY_MACHINE_I2S              (1)
-#endif
 #define MICROPY_PY_NETWORK (1)
 #ifndef MICROPY_PY_NETWORK_HOSTNAME_DEFAULT
 #if CONFIG_IDF_TARGET_ESP32
@@ -133,7 +131,7 @@
 #define MICROPY_HW_SOFTSPI_MIN_DELAY        (0)
 #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE     (ets_get_cpu_frequency() * 1000000 / 200) // roughly
 #define MICROPY_PY_USSL                     (1)
-#define MICROPY_SSL_MBEDTLS                 (1)
+#define MICROPY_SSL_MBEDTLS                 (0)
 #define MICROPY_PY_USSL_FINALISER           (1)
 #define MICROPY_PY_UWEBSOCKET               (1)
 #define MICROPY_PY_WEBREPL                  (1)
@@ -162,8 +160,8 @@ void *esp_native_code_commit(void *, size_t, void *);
 // the only disable interrupts on the current CPU.  To full manage exclusion
 // one should use portENTER_CRITICAL/portEXIT_CRITICAL instead.
 #include "freertos/FreeRTOS.h"
-#define MICROPY_BEGIN_ATOMIC_SECTION() portENTER_CRITICAL_NESTED()
-#define MICROPY_END_ATOMIC_SECTION(state) portEXIT_CRITICAL_NESTED(state)
+#define MICROPY_BEGIN_ATOMIC_SECTION() portSET_INTERRUPT_MASK_FROM_ISR()
+#define MICROPY_END_ATOMIC_SECTION(state) portCLEAR_INTERRUPT_MASK_FROM_ISR(state)
 
 #if MICROPY_PY_USOCKET_EVENTS
 #define MICROPY_PY_USOCKET_EVENTS_HANDLER extern void usocket_events_handler(void); usocket_events_handler();
@@ -219,11 +217,11 @@ typedef long mp_off_t;
 #endif
 
 #ifndef MICROPY_HW_ENABLE_MDNS_QUERIES
-#define MICROPY_HW_ENABLE_MDNS_QUERIES      (1)
+#define MICROPY_HW_ENABLE_MDNS_QUERIES      (0)
 #endif
 
 #ifndef MICROPY_HW_ENABLE_MDNS_RESPONDER
-#define MICROPY_HW_ENABLE_MDNS_RESPONDER    (1)
+#define MICROPY_HW_ENABLE_MDNS_RESPONDER    (0)
 #endif
 
 #ifndef MICROPY_BOARD_STARTUP
@@ -233,7 +231,7 @@ typedef long mp_off_t;
 void boardctrl_startup(void);
 
 #ifndef MICROPY_PY_NETWORK_LAN
-#if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 1) && (CONFIG_IDF_TARGET_ESP32 || (CONFIG_ETH_USE_SPI_ETHERNET && (CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL || CONFIG_ETH_SPI_ETHERNET_DM9051 || CONFIG_ETH_SPI_ETHERNET_W5500)))
+#if CONFIG_IDF_TARGET_ESP32 || (CONFIG_ETH_USE_SPI_ETHERNET && (CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL || CONFIG_ETH_SPI_ETHERNET_DM9051 || CONFIG_ETH_SPI_ETHERNET_W5500))
 #define MICROPY_PY_NETWORK_LAN              (1)
 #else
 #define MICROPY_PY_NETWORK_LAN              (0)
diff --git a/components/micropython/vendor/ports/esp32/mphalport.c b/components/micropython/vendor/ports/esp32/mphalport.c
index b187b422d50be0f1338a733b38ac77b157549ca9..ac179b429d0a1034894fd3f4df90744a9ee34104 100644
--- a/components/micropython/vendor/ports/esp32/mphalport.c
+++ b/components/micropython/vendor/ports/esp32/mphalport.c
@@ -29,9 +29,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/time.h>
+#include <unistd.h>
 
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
+#include "esp_timer.h"
 
 #include "py/obj.h"
 #include "py/objstr.h"
@@ -118,6 +120,7 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
     #if MICROPY_HW_ENABLE_UART_REPL
     uart_stdout_tx_strn(str, len);
     #endif
+
     if (release_gil) {
         MP_THREAD_GIL_ENTER();
     }
diff --git a/components/micropython/vendor/ports/esp32/mphalport.h b/components/micropython/vendor/ports/esp32/mphalport.h
index 672fa306f5dcacee0814d7e7041e2a0c750e910b..e5316bb0bdd1331a6e2344b0c92c796c2c2eaca1 100644
--- a/components/micropython/vendor/ports/esp32/mphalport.h
+++ b/components/micropython/vendor/ports/esp32/mphalport.h
@@ -46,10 +46,8 @@
 // See https://github.com/micropython/micropython/issues/5489 for history
 #if CONFIG_FREERTOS_UNICORE
 #define MP_TASK_COREID (0)
-#elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
-#define MP_TASK_COREID (1)
 #else
-#define MP_TASK_COREID (0)
+#define MP_TASK_COREID (1)
 #endif
 
 extern TaskHandle_t mp_main_task_handle;
@@ -71,7 +69,7 @@ __attribute__((always_inline)) static inline uint32_t mp_hal_ticks_cpu(void) {
 }
 
 void mp_hal_delay_us(uint32_t);
-#define mp_hal_delay_us_fast(us) ets_delay_us(us)
+#define mp_hal_delay_us_fast(us) esp_rom_delay_us(us)
 void mp_hal_set_interrupt_char(int c);
 uint32_t mp_hal_get_cpu_freq(void);
 
@@ -83,6 +81,7 @@ void mp_hal_wake_main_task_from_isr(void);
 
 // C-level pin HAL
 #include "py/obj.h"
+#include "py/runtime.h"
 #include "driver/gpio.h"
 #define MP_HAL_PIN_FMT "%u"
 #define mp_hal_pin_obj_t gpio_num_t
@@ -91,28 +90,26 @@ mp_hal_pin_obj_t machine_pin_get_id(mp_obj_t pin_in);
 #define mp_obj_get_pin(o) machine_pin_get_id(o) // legacy name; only to support esp8266/modonewire
 #define mp_hal_pin_name(p) (p)
 static inline void mp_hal_pin_input(mp_hal_pin_obj_t pin) {
-    gpio_pad_select_gpio(pin);
-    gpio_set_direction(pin, GPIO_MODE_INPUT);
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("low-level GPIO not supported"));
 }
 static inline void mp_hal_pin_output(mp_hal_pin_obj_t pin) {
-    gpio_pad_select_gpio(pin);
-    gpio_set_direction(pin, GPIO_MODE_INPUT_OUTPUT);
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("low-level GPIO not supported"));
 }
 static inline void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) {
-    gpio_pad_select_gpio(pin);
-    gpio_set_direction(pin, GPIO_MODE_INPUT_OUTPUT_OD);
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("low-level GPIO not supported"));
 }
 static inline void mp_hal_pin_od_low(mp_hal_pin_obj_t pin) {
-    gpio_set_level(pin, 0);
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("low-level GPIO not supported"));
 }
 static inline void mp_hal_pin_od_high(mp_hal_pin_obj_t pin) {
-    gpio_set_level(pin, 1);
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("low-level GPIO not supported"));
 }
 static inline int mp_hal_pin_read(mp_hal_pin_obj_t pin) {
-    return gpio_get_level(pin);
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("low-level GPIO not supported"));
+    return mp_const_none;
 }
 static inline void mp_hal_pin_write(mp_hal_pin_obj_t pin, int v) {
-    gpio_set_level(pin, v);
+    mp_raise_NotImplementedError(MP_ERROR_TEXT("low-level GPIO not supported"));
 }
 
 spi_host_device_t machine_hw_spi_get_host(mp_obj_t in);
diff --git a/components/micropython/vendor/ports/esp32/mpnimbleport.c b/components/micropython/vendor/ports/esp32/mpnimbleport.c
index a58fcbdbf49f43076b6085ccd494af14418fdd26..8235275be6fd63b36478a8e690bc7aac91c82868 100644
--- a/components/micropython/vendor/ports/esp32/mpnimbleport.c
+++ b/components/micropython/vendor/ports/esp32/mpnimbleport.c
@@ -46,13 +46,13 @@ STATIC void ble_host_task(void *param) {
 
 void mp_bluetooth_nimble_port_hci_init(void) {
     DEBUG_printf("mp_bluetooth_nimble_port_hci_init\n");
-    esp_nimble_hci_and_controller_init();
+    esp_nimble_hci_init();
 }
 
 void mp_bluetooth_nimble_port_hci_deinit(void) {
     DEBUG_printf("mp_bluetooth_nimble_port_hci_deinit\n");
 
-    esp_nimble_hci_and_controller_deinit();
+    esp_nimble_hci_deinit();
 }
 
 void mp_bluetooth_nimble_port_start(void) {
diff --git a/components/micropython/vendor/ports/esp32/network_common.c b/components/micropython/vendor/ports/esp32/network_common.c
index 1e76d679db0462c0d25129c5e1f6a01520ce115b..082943e2aecc48fd61f4843fc5e8b74fc6c67731 100644
--- a/components/micropython/vendor/ports/esp32/network_common.c
+++ b/components/micropython/vendor/ports/esp32/network_common.c
@@ -38,15 +38,10 @@
 #include "shared/netutils/netutils.h"
 #include "modnetwork.h"
 
-#include "esp_wifi.h"
 #include "esp_log.h"
-#include "lwip/dns.h"
-
-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 1, 0)
-#define DNS_MAIN TCPIP_ADAPTER_DNS_MAIN
-#else
-#define DNS_MAIN ESP_NETIF_DNS_MAIN
-#endif
+#include "esp_netif.h"
+#include "esp_wifi.h"
+// #include "lwip/dns.h"
 
 NORETURN void esp_exceptions_helper(esp_err_t e) {
     switch (e) {
@@ -80,64 +75,15 @@ NORETURN void esp_exceptions_helper(esp_err_t e) {
             mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Would Block"));
         case ESP_ERR_WIFI_NOT_CONNECT:
             mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Wifi Not Connected"));
-        case ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS:
-            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("TCP/IP Invalid Parameters"));
-        case ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:
-            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("TCP/IP IF Not Ready"));
-        case ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED:
-            mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("TCP/IP DHCP Client Start Failed"));
-        case ESP_ERR_TCPIP_ADAPTER_NO_MEM:
-            mp_raise_OSError(MP_ENOMEM);
         default:
             mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Wifi Unknown Error 0x%04x"), e);
     }
 }
 
-// This function is called by the system-event task and so runs in a different
-// thread to the main MicroPython task.  It must not raise any Python exceptions.
-static esp_err_t event_handler(void *ctx, system_event_t *event) {
-    switch (event->event_id) {
-        #if MICROPY_PY_NETWORK_WLAN
-        case SYSTEM_EVENT_STA_START:
-        case SYSTEM_EVENT_STA_CONNECTED:
-        case SYSTEM_EVENT_STA_GOT_IP:
-        case SYSTEM_EVENT_STA_DISCONNECTED:
-            network_wlan_event_handler(event);
-            break;
-        #endif
-        case SYSTEM_EVENT_GOT_IP6:
-            ESP_LOGI("network", "Got IPv6");
-            break;
-        case SYSTEM_EVENT_ETH_START:
-            ESP_LOGI("ethernet", "start");
-            break;
-        case SYSTEM_EVENT_ETH_STOP:
-            ESP_LOGI("ethernet", "stop");
-            break;
-        case SYSTEM_EVENT_ETH_CONNECTED:
-            ESP_LOGI("ethernet", "LAN cable connected");
-            break;
-        case SYSTEM_EVENT_ETH_DISCONNECTED:
-            ESP_LOGI("ethernet", "LAN cable disconnected");
-            break;
-        case SYSTEM_EVENT_ETH_GOT_IP:
-            ESP_LOGI("ethernet", "Got IP");
-            break;
-        default:
-            ESP_LOGI("network", "event %d", event->event_id);
-            break;
-    }
-    return ESP_OK;
-}
-
 STATIC mp_obj_t esp_initialize() {
     static int initialized = 0;
     if (!initialized) {
-        ESP_LOGD("modnetwork", "Initializing TCP/IP");
-        tcpip_adapter_init();
-        ESP_LOGD("modnetwork", "Initializing Event Loop");
-        esp_exceptions(esp_event_loop_init(event_handler, NULL));
-        ESP_LOGD("modnetwork", "esp_event_loop_init done");
+        esp_exceptions(esp_netif_init());
         initialized = 1;
     }
     return mp_const_none;
@@ -145,11 +91,11 @@ STATIC mp_obj_t esp_initialize() {
 MP_DEFINE_CONST_FUN_OBJ_0(esp_network_initialize_obj, esp_initialize);
 
 STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
-    wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
-    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, DNS_MAIN, &dns_info);
+    base_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+    esp_netif_ip_info_t info;
+    esp_netif_dns_info_t dns_info;
+    esp_netif_get_ip_info(self->netif, &info);
+    esp_netif_get_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &dns_info);
     if (n_args == 1) {
         // get
         mp_obj_t tuple[4] = {
@@ -171,36 +117,36 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
                 // 16 -> 255.255.0.0
                 // etc...
                 uint32_t *m = (uint32_t *)&info.netmask;
-                *m = htonl(0xffffffff << (32 - mp_obj_get_int(items[1])));
+                *m = esp_netif_htonl(0xffffffff << (32 - mp_obj_get_int(items[1])));
             } else {
                 netutils_parse_ipv4_addr(items[1], (void *)&info.netmask, NETUTILS_BIG);
             }
             netutils_parse_ipv4_addr(items[2], (void *)&info.gw, NETUTILS_BIG);
             netutils_parse_ipv4_addr(items[3], (void *)&dns_info.ip, NETUTILS_BIG);
             // To set a static IP we have to disable DHCP first
-            if (self->if_id == WIFI_IF_STA || self->if_id == ESP_IF_ETH) {
-                esp_err_t e = tcpip_adapter_dhcpc_stop(self->if_id);
-                if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) {
+            if (self->if_id == ESP_IF_WIFI_STA || self->if_id == ESP_IF_ETH) {
+                esp_err_t e = esp_netif_dhcpc_stop(self->netif);
+                if (e != ESP_OK && e != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) {
                     esp_exceptions_helper(e);
                 }
-                esp_exceptions(tcpip_adapter_set_ip_info(self->if_id, &info));
-                esp_exceptions(tcpip_adapter_set_dns_info(self->if_id, 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(esp_netif_set_ip_info(self->netif, &info));
+                esp_exceptions(esp_netif_set_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &dns_info));
+            } else if (self->if_id == ESP_IF_WIFI_AP) {
+                esp_err_t e = esp_netif_dhcps_stop(self->netif);
+                if (e != ESP_OK && e != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) {
                     esp_exceptions_helper(e);
                 }
-                esp_exceptions(tcpip_adapter_set_ip_info(WIFI_IF_AP, &info));
-                esp_exceptions(tcpip_adapter_set_dns_info(WIFI_IF_AP, DNS_MAIN, &dns_info));
-                esp_exceptions(tcpip_adapter_dhcps_start(WIFI_IF_AP));
+                esp_exceptions(esp_netif_set_ip_info(self->netif, &info));
+                esp_exceptions(esp_netif_set_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &dns_info));
+                esp_exceptions(esp_netif_dhcps_start(self->netif));
             }
         } else {
             // check for the correct string
             const char *mode = mp_obj_str_get_str(args[1]);
-            if ((self->if_id != WIFI_IF_STA && self->if_id != ESP_IF_ETH) || strcmp("dhcp", mode)) {
+            if ((self->if_id != ESP_IF_WIFI_STA && self->if_id != ESP_IF_ETH) || strcmp("dhcp", mode)) {
                 mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments"));
             }
-            esp_exceptions(tcpip_adapter_dhcpc_start(self->if_id));
+            esp_exceptions(esp_netif_dhcpc_start(self->netif));
         }
         return mp_const_none;
     }
@@ -212,9 +158,4 @@ STATIC mp_obj_t esp_phy_mode(size_t n_args, const mp_obj_t *args) {
 }
 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_phy_mode_obj, 0, 1, esp_phy_mode);
 
-#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
-#define TEST_WIFI_AUTH_MAX 9
-#else
-#define TEST_WIFI_AUTH_MAX 8
-#endif
-_Static_assert(WIFI_AUTH_MAX == TEST_WIFI_AUTH_MAX, "Synchronize WIFI_AUTH_XXX constants with the ESP-IDF. Look at esp-idf/components/esp_wifi/include/esp_wifi_types.h");
+_Static_assert(WIFI_AUTH_MAX == 10, "Synchronize WIFI_AUTH_XXX constants with the ESP-IDF. Look at esp-idf/components/esp_wifi/include/esp_wifi_types.h");
diff --git a/components/micropython/vendor/ports/esp32/network_lan.c b/components/micropython/vendor/ports/esp32/network_lan.c
index 9b7a31cc4f9d30f551312172123846255f98c5a5..8128eb5e11d49188a00760dca446458f1b14855a 100644
--- a/components/micropython/vendor/ports/esp32/network_lan.c
+++ b/components/micropython/vendor/ports/esp32/network_lan.c
@@ -32,7 +32,6 @@
 
 #include "esp_idf_version.h"
 
-// LAN only for ESP32 (not ESP32S2) and only for ESP-IDF v4.1 and higher
 #if MICROPY_PY_NETWORK_LAN
 
 #include "esp_eth.h"
@@ -47,8 +46,7 @@
 #include "modnetwork.h"
 
 typedef struct _lan_if_obj_t {
-    mp_obj_base_t base;
-    int if_id; // MUST BE FIRST to match wlan_if_obj_t
+    base_if_obj_t base;
     bool initialized;
     bool active;
     int8_t mdc_pin;
@@ -59,12 +57,11 @@ typedef struct _lan_if_obj_t {
     uint8_t phy_addr;
     uint8_t phy_type;
     esp_eth_phy_t *phy;
-    esp_netif_t *eth_netif;
     esp_eth_handle_t eth_handle;
 } lan_if_obj_t;
 
 const mp_obj_type_t lan_if_type;
-STATIC lan_if_obj_t lan_obj = {{&lan_if_type}, ESP_IF_ETH, false, false};
+STATIC lan_if_obj_t lan_obj = {{{&lan_if_type}, ESP_IF_ETH, NULL}, false, false};
 STATIC uint8_t eth_status = 0;
 
 static void eth_event_handler(void *arg, esp_event_base_t event_base,
@@ -114,11 +111,8 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         { MP_QSTR_spi,          MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
         { MP_QSTR_cs,           MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
         { MP_QSTR_int,          MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
-        #if ESP_IDF_VERSION_MINOR >= 4
-        // Dynamic ref_clk configuration available at v4.4
         { MP_QSTR_ref_clk_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
         { MP_QSTR_ref_clk,      MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
-        #endif
     };
 
     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -147,12 +141,8 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         args[ARG_phy_type].u_int != PHY_LAN8720 &&
         args[ARG_phy_type].u_int != PHY_IP101 &&
         args[ARG_phy_type].u_int != PHY_RTL8201 &&
-        #if ESP_IDF_VERSION_MINOR >= 3      // KSZ8041 is new in ESP-IDF v4.3
         args[ARG_phy_type].u_int != PHY_KSZ8041 &&
-        #endif
-        #if ESP_IDF_VERSION_MINOR >= 4      // KSZ8081 is new in ESP-IDF v4.4
         args[ARG_phy_type].u_int != PHY_KSZ8081 &&
-        #endif
         #if CONFIG_ETH_USE_SPI_ETHERNET
         #if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
         args[ARG_phy_type].u_int != PHY_KSZ8851SNL &&
@@ -169,17 +159,21 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
     }
 
     eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
+    #if CONFIG_IDF_TARGET_ESP32
+    eth_esp32_emac_config_t esp32_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
+    #endif
+
     esp_eth_mac_t *mac = NULL;
 
-    // Dynamic ref_clk configuration available at v4.4
-    #if ESP_IDF_VERSION_MINOR >= 4
+    #if CONFIG_IDF_TARGET_ESP32
+    // Dynamic ref_clk configuration.
     if (args[ARG_ref_clk_mode].u_int != -1) {
         // Map the GPIO_MODE constants to EMAC_CLK constants.
-        mac_config.clock_config.rmii.clock_mode =
+        esp32_config.clock_config.rmii.clock_mode =
             args[ARG_ref_clk_mode].u_int == GPIO_MODE_INPUT ? EMAC_CLK_EXT_IN : EMAC_CLK_OUT;
     }
     if (args[ARG_ref_clk].u_obj != mp_const_none) {
-        mac_config.clock_config.rmii.clock_gpio = machine_pin_get_id(args[ARG_ref_clk].u_obj);
+        esp32_config.clock_config.rmii.clock_gpio = machine_pin_get_id(args[ARG_ref_clk].u_obj);
     }
     #endif
 
@@ -224,7 +218,7 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         #if CONFIG_IDF_TARGET_ESP32
         case PHY_LAN8710:
         case PHY_LAN8720:
-            self->phy = esp_eth_phy_new_lan8720(&phy_config);
+            self->phy = esp_eth_phy_new_lan87xx(&phy_config);
             break;
         case PHY_IP101:
             self->phy = esp_eth_phy_new_ip101(&phy_config);
@@ -235,17 +229,11 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         case PHY_DP83848:
             self->phy = esp_eth_phy_new_dp83848(&phy_config);
             break;
-        #if ESP_IDF_VERSION_MINOR >= 3 // KSZ8041 is new in ESP-IDF v4.3
         case PHY_KSZ8041:
-            self->phy = esp_eth_phy_new_ksz8041(&phy_config);
-            break;
-        #endif
-        #if ESP_IDF_VERSION_MINOR >= 4 // KSZ8081 is new in ESP-IDF v4.4
         case PHY_KSZ8081:
-            self->phy = esp_eth_phy_new_ksz8081(&phy_config);
+            self->phy = esp_eth_phy_new_ksz80xx(&phy_config);
             break;
         #endif
-        #endif
         #if CONFIG_ETH_USE_SPI_ETHERNET
         #if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
         case PHY_KSZ8851SNL: {
@@ -282,9 +270,9 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         if (self->mdc_pin == -1 || self->mdio_pin == -1) {
             mp_raise_ValueError(MP_ERROR_TEXT("mdc and mdio must be specified"));
         }
-        mac_config.smi_mdc_gpio_num = self->mdc_pin;
-        mac_config.smi_mdio_gpio_num = self->mdio_pin;
-        mac = esp_eth_mac_new_esp32(&mac_config);
+        esp32_config.smi_mdc_gpio_num = self->mdc_pin;
+        esp32_config.smi_mdio_gpio_num = self->mdio_pin;
+        mac = esp_eth_mac_new_esp32(&esp32_config, &mac_config);
     }
     #endif
 
@@ -293,11 +281,7 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
     }
 
     esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
-    self->eth_netif = esp_netif_new(&cfg);
-
-    if (esp_eth_set_default_handlers(self->eth_netif) != ESP_OK) {
-        mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("esp_eth_set_default_handlers failed (invalid parameter)"));
-    }
+    self->base.netif = esp_netif_new(&cfg);
 
     if (esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL) != ESP_OK) {
         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("esp_event_handler_register failed"));
@@ -323,7 +307,7 @@ STATIC mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
         }
     }
 
-    if (esp_netif_attach(self->eth_netif, esp_eth_new_netif_glue(self->eth_handle)) != ESP_OK) {
+    if (esp_netif_attach(self->base.netif, esp_eth_new_netif_glue(self->eth_handle)) != ESP_OK) {
         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("esp_netif_attach failed"));
     }
 
@@ -384,7 +368,7 @@ STATIC mp_obj_t lan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
                         }
                         if (
                             (esp_eth_ioctl(self->eth_handle, ETH_CMD_S_MAC_ADDR, bufinfo.buf) != ESP_OK) ||
-                            (esp_netif_set_mac(self->eth_netif, bufinfo.buf) != ESP_OK)
+                            (esp_netif_set_mac(self->base.netif, bufinfo.buf) != ESP_OK)
                             ) {
                             mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("failed setting MAC address"));
                         }
diff --git a/components/micropython/vendor/ports/esp32/network_ppp.c b/components/micropython/vendor/ports/esp32/network_ppp.c
index b3cab835981e169e4f0d84e0dfd69b89d8f591f8..caad7eb48bfe5f65fb0e26275f92dd23e3d8a83d 100644
--- a/components/micropython/vendor/ports/esp32/network_ppp.c
+++ b/components/micropython/vendor/ports/esp32/network_ppp.c
@@ -32,6 +32,7 @@
 #include "py/stream.h"
 #include "shared/netutils/netutils.h"
 #include "modmachine.h"
+#include "ppp_set_auth.h"
 
 #include "netif/ppp/ppp.h"
 #include "netif/ppp/pppos.h"
diff --git a/components/micropython/vendor/ports/esp32/network_wlan.c b/components/micropython/vendor/ports/esp32/network_wlan.c
index aefc4394c2ac3bbbb76ec70744196dee96cd0574..cfedd898cdf24e912c3eae8218ca66f9dade37d0 100644
--- a/components/micropython/vendor/ports/esp32/network_wlan.c
+++ b/components/micropython/vendor/ports/esp32/network_wlan.c
@@ -41,7 +41,6 @@
 
 #include "esp_wifi.h"
 #include "esp_log.h"
-#include "mdns.h"
 
 #if MICROPY_PY_NETWORK_WLAN
 
@@ -49,8 +48,10 @@
 #error WIFI_MODE_STA and WIFI_MODE_AP are supposed to be bitfields!
 #endif
 
-STATIC const wlan_if_obj_t wlan_sta_obj;
-STATIC const wlan_if_obj_t wlan_ap_obj;
+typedef base_if_obj_t wlan_if_obj_t;
+
+STATIC wlan_if_obj_t wlan_sta_obj;
+STATIC wlan_if_obj_t wlan_ap_obj;
 
 // Set to "true" if esp_wifi_start() was called
 static bool wifi_started = false;
@@ -71,38 +72,26 @@ static bool mdns_initialised = false;
 #endif
 
 static uint8_t conf_wifi_sta_reconnects = 0;
-static uint8_t wifi_sta_reconnects;
+static volatile uint8_t wifi_sta_reconnects;
 
 // This function is called by the system-event task and so runs in a different
 // thread to the main MicroPython task.  It must not raise any Python exceptions.
-void network_wlan_event_handler(system_event_t *event) {
-    switch (event->event_id) {
-        case SYSTEM_EVENT_STA_START:
+static void network_wlan_wifi_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
+    switch (event_id) {
+        case WIFI_EVENT_STA_START:
             ESP_LOGI("wifi", "STA_START");
             wifi_sta_reconnects = 0;
             break;
-        case SYSTEM_EVENT_STA_CONNECTED:
+
+        case WIFI_EVENT_STA_CONNECTED:
             ESP_LOGI("network", "CONNECTED");
             break;
-        case SYSTEM_EVENT_STA_GOT_IP:
-            ESP_LOGI("network", "GOT_IP");
-            wifi_sta_connected = true;
-            wifi_sta_disconn_reason = 0; // Success so clear error. (in case of new error will be replaced anyway)
-            #if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER
-            if (!mdns_initialised) {
-                mdns_init();
-                #if MICROPY_HW_ENABLE_MDNS_RESPONDER
-                mdns_hostname_set(mod_network_hostname);
-                mdns_instance_name_set(mod_network_hostname);
-                #endif
-                mdns_initialised = true;
-            }
-            #endif
-            break;
-        case SYSTEM_EVENT_STA_DISCONNECTED: {
+
+        case WIFI_EVENT_STA_DISCONNECTED: {
             // This is a workaround as ESP32 WiFi libs don't currently
             // auto-reassociate.
-            system_event_sta_disconnected_t *disconn = &event->event_info.disconnected;
+
+            wifi_event_sta_disconnected_t *disconn = event_data;
             char *message = "";
             wifi_sta_disconn_reason = disconn->reason;
             switch (disconn->reason) {
@@ -152,34 +141,74 @@ void network_wlan_event_handler(system_event_t *event) {
     }
 }
 
+static void network_wlan_ip_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
+    switch (event_id) {
+        case IP_EVENT_STA_GOT_IP:
+            ESP_LOGI("network", "GOT_IP");
+            wifi_sta_connected = true;
+            wifi_sta_disconn_reason = 0; // Success so clear error. (in case of new error will be replaced anyway)
+            #if MICROPY_HW_ENABLE_MDNS_QUERIES || MICROPY_HW_ENABLE_MDNS_RESPONDER
+            if (!mdns_initialised) {
+                mdns_init();
+                #if MICROPY_HW_ENABLE_MDNS_RESPONDER
+                mdns_hostname_set(mod_network_hostname);
+                mdns_instance_name_set(mod_network_hostname);
+                #endif
+                mdns_initialised = true;
+            }
+            #endif
+            break;
+
+        default:
+            break;
+    }
+}
+
 STATIC void require_if(mp_obj_t wlan_if, int if_no) {
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if);
     if (self->if_id != if_no) {
-        mp_raise_msg(&mp_type_OSError, if_no == WIFI_IF_STA ? MP_ERROR_TEXT("STA required") : MP_ERROR_TEXT("AP required"));
+        mp_raise_msg(&mp_type_OSError, if_no == ESP_IF_WIFI_STA ? MP_ERROR_TEXT("STA required") : MP_ERROR_TEXT("AP required"));
     }
 }
 
-STATIC mp_obj_t get_wlan(size_t n_args, const mp_obj_t *args) {
-    static int initialized = 0;
-    if (!initialized) {
+void esp_initialise_wifi(void) {
+    static int wifi_initialized = 0;
+    if (!wifi_initialized) {
+        esp_exceptions(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, network_wlan_wifi_event_handler, NULL, NULL));
+        esp_exceptions(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, network_wlan_ip_event_handler, NULL, NULL));
+
+        wlan_sta_obj.base.type = &esp_network_wlan_type;
+        wlan_sta_obj.if_id = ESP_IF_WIFI_STA;
+        wlan_sta_obj.netif = esp_netif_create_default_wifi_sta();
+
+        wlan_ap_obj.base.type = &esp_network_wlan_type;
+        wlan_ap_obj.if_id = ESP_IF_WIFI_AP;
+        wlan_ap_obj.netif = esp_netif_create_default_wifi_ap();
+
         wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
         ESP_LOGD("modnetwork", "Initializing WiFi");
         esp_exceptions(esp_wifi_init(&cfg));
         esp_exceptions(esp_wifi_set_storage(WIFI_STORAGE_RAM));
+
         ESP_LOGD("modnetwork", "Initialized");
-        initialized = 1;
+        wifi_initialized = 1;
     }
+}
 
-    int idx = (n_args > 0) ? mp_obj_get_int(args[0]) : WIFI_IF_STA;
-    if (idx == WIFI_IF_STA) {
+STATIC mp_obj_t network_wlan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+    mp_arg_check_num(n_args, n_kw, 0, 1, false);
+
+    esp_initialise_wifi();
+
+    int idx = (n_args > 0) ? mp_obj_get_int(args[0]) : ESP_IF_WIFI_STA;
+    if (idx == ESP_IF_WIFI_STA) {
         return MP_OBJ_FROM_PTR(&wlan_sta_obj);
-    } else if (idx == WIFI_IF_AP) {
+    } else if (idx == ESP_IF_WIFI_AP) {
         return MP_OBJ_FROM_PTR(&wlan_ap_obj);
     } else {
         mp_raise_ValueError(MP_ERROR_TEXT("invalid WLAN interface identifier"));
     }
 }
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_network_get_wlan_obj, 0, 1, get_wlan);
 
 STATIC mp_obj_t network_wlan_active(size_t n_args, const mp_obj_t *args) {
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
@@ -191,7 +220,7 @@ STATIC mp_obj_t network_wlan_active(size_t n_args, const mp_obj_t *args) {
         esp_exceptions(esp_wifi_get_mode(&mode));
     }
 
-    int bit = (self->if_id == WIFI_IF_STA) ? WIFI_MODE_STA : WIFI_MODE_AP;
+    int bit = (self->if_id == ESP_IF_WIFI_STA) ? WIFI_MODE_STA : WIFI_MODE_AP;
 
     if (n_args > 1) {
         bool active = mp_obj_is_true(args[1]);
@@ -204,16 +233,16 @@ STATIC mp_obj_t network_wlan_active(size_t n_args, const mp_obj_t *args) {
         } else {
             esp_exceptions(esp_wifi_set_mode(mode));
             if (!wifi_started) {
+                // WIFI_EVENT_STA_START must be received before esp_wifi_connect() can be called.
+                // Use the `wifi_sta_reconnects` variable to detect that event.
+                wifi_sta_reconnects = 1;
                 esp_exceptions(esp_wifi_start());
                 wifi_started = true;
+                while (wifi_sta_reconnects != 0) {
+                    MICROPY_EVENT_POLL_HOOK;
+                }
             }
         }
-        // This delay is a band-aid patch for issues #8289, #8792 and #9236,
-        // allowing the esp data structures to settle. It looks like some
-        // kind of race condition, which is not yet found. But at least
-        // this small delay seems not hurt much, since wlan.active() is
-        // usually not called in a time critical part of the code.
-        mp_hal_delay_ms(1);
     }
 
     return (mode & bit) ? mp_const_true : mp_const_false;
@@ -257,7 +286,7 @@ STATIC mp_obj_t network_wlan_connect(size_t n_args, const mp_obj_t *pos_args, mp
         esp_exceptions(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config));
     }
 
-    esp_exceptions(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, mod_network_hostname));
+    esp_exceptions(esp_netif_set_hostname(wlan_sta_obj.netif, mod_network_hostname));
 
     wifi_sta_reconnects = 0;
     // connect to the WiFi AP
@@ -280,7 +309,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_wlan_disconnect_obj, network_wlan_disco
 STATIC mp_obj_t network_wlan_status(size_t n_args, const mp_obj_t *args) {
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
     if (n_args == 1) {
-        if (self->if_id == WIFI_IF_STA) {
+        if (self->if_id == ESP_IF_WIFI_STA) {
             // Case of no arg is only for the STA interface
             if (wifi_sta_connected) {
                 // Happy path, connected with IP
@@ -305,7 +334,7 @@ STATIC mp_obj_t network_wlan_status(size_t n_args, const mp_obj_t *args) {
     switch ((uintptr_t)args[1]) {
         case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_stations): {
             // return list of connected stations, only if in soft-AP mode
-            require_if(args[0], WIFI_IF_AP);
+            require_if(args[0], ESP_IF_WIFI_AP);
             wifi_sta_list_t station_list;
             esp_exceptions(esp_wifi_ap_get_sta_list(&station_list));
             wifi_sta_info_t *stations = (wifi_sta_info_t *)station_list.sta;
@@ -319,7 +348,7 @@ STATIC mp_obj_t network_wlan_status(size_t n_args, const mp_obj_t *args) {
         }
         case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_rssi): {
             // return signal of AP, only in STA mode
-            require_if(args[0], WIFI_IF_STA);
+            require_if(args[0], ESP_IF_WIFI_STA);
 
             wifi_ap_record_t info;
             esp_exceptions(esp_wifi_sta_get_ap_info(&info));
@@ -378,7 +407,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_wlan_scan_obj, network_wlan_scan);
 
 STATIC mp_obj_t network_wlan_isconnected(mp_obj_t self_in) {
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
-    if (self->if_id == WIFI_IF_STA) {
+    if (self->if_id == ESP_IF_WIFI_STA) {
         return mp_obj_new_bool(wifi_sta_connected);
     } else {
         wifi_sta_list_t sta;
@@ -395,7 +424,7 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
 
     wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
 
-    bool is_wifi = self->if_id == WIFI_IF_AP || self->if_id == WIFI_IF_STA;
+    bool is_wifi = self->if_id == ESP_IF_WIFI_AP || self->if_id == ESP_IF_WIFI_STA;
 
     wifi_config_t cfg;
     if (is_wifi) {
@@ -423,7 +452,7 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
                     }
                     case MP_QSTR_ssid:
                     case MP_QSTR_essid: {
-                        req_if = WIFI_IF_AP;
+                        req_if = ESP_IF_WIFI_AP;
                         size_t len;
                         const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len);
                         len = MIN(len, sizeof(cfg.ap.ssid));
@@ -432,19 +461,19 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
                         break;
                     }
                     case MP_QSTR_hidden: {
-                        req_if = WIFI_IF_AP;
+                        req_if = ESP_IF_WIFI_AP;
                         cfg.ap.ssid_hidden = mp_obj_is_true(kwargs->table[i].value);
                         break;
                     }
                     case MP_QSTR_security:
                     case MP_QSTR_authmode: {
-                        req_if = WIFI_IF_AP;
+                        req_if = ESP_IF_WIFI_AP;
                         cfg.ap.authmode = mp_obj_get_int(kwargs->table[i].value);
                         break;
                     }
                     case MP_QSTR_key:
                     case MP_QSTR_password: {
-                        req_if = WIFI_IF_AP;
+                        req_if = ESP_IF_WIFI_AP;
                         size_t len;
                         const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len);
                         len = MIN(len, sizeof(cfg.ap.password) - 1);
@@ -483,13 +512,13 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
                         break;
                     }
                     case MP_QSTR_max_clients: {
-                        req_if = WIFI_IF_AP;
+                        req_if = ESP_IF_WIFI_AP;
                         cfg.ap.max_connection = mp_obj_get_int(kwargs->table[i].value);
                         break;
                     }
                     case MP_QSTR_reconnects: {
                         int reconnects = mp_obj_get_int(kwargs->table[i].value);
-                        req_if = WIFI_IF_STA;
+                        req_if = ESP_IF_WIFI_STA;
                         // parameter reconnects == -1 means to retry forever.
                         // here means conf_wifi_sta_reconnects == 0 to retry forever.
                         conf_wifi_sta_reconnects = (reconnects == -1) ? 0 : reconnects + 1;
@@ -504,6 +533,10 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
                         esp_exceptions(esp_wifi_set_protocol(self->if_id, mp_obj_get_int(kwargs->table[i].value)));
                         break;
                     }
+                    case MP_QSTR_pm: {
+                        esp_exceptions(esp_wifi_set_ps(mp_obj_get_int(kwargs->table[i].value)));
+                        break;
+                    }
                     default:
                         goto unknown;
                 }
@@ -533,8 +566,8 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
         case MP_QSTR_mac: {
             uint8_t mac[6];
             switch (self->if_id) {
-                case WIFI_IF_AP: // fallthrough intentional
-                case WIFI_IF_STA:
+                case ESP_IF_WIFI_AP: // fallthrough intentional
+                case ESP_IF_WIFI_STA:
                     esp_exceptions(esp_wifi_get_mac(self->if_id, mac));
                     return mp_obj_new_bytes(mac, sizeof(mac));
                 default:
@@ -544,23 +577,23 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
         case MP_QSTR_ssid:
         case MP_QSTR_essid:
             switch (self->if_id) {
-                case WIFI_IF_STA:
+                case ESP_IF_WIFI_STA:
                     val = mp_obj_new_str((char *)cfg.sta.ssid, strlen((char *)cfg.sta.ssid));
                     break;
-                case WIFI_IF_AP:
+                case ESP_IF_WIFI_AP:
                     val = mp_obj_new_str((char *)cfg.ap.ssid, cfg.ap.ssid_len);
                     break;
                 default:
-                    req_if = WIFI_IF_AP;
+                    req_if = ESP_IF_WIFI_AP;
             }
             break;
         case MP_QSTR_hidden:
-            req_if = WIFI_IF_AP;
+            req_if = ESP_IF_WIFI_AP;
             val = mp_obj_new_bool(cfg.ap.ssid_hidden);
             break;
         case MP_QSTR_security:
         case MP_QSTR_authmode:
-            req_if = WIFI_IF_AP;
+            req_if = ESP_IF_WIFI_AP;
             val = MP_OBJ_NEW_SMALL_INT(cfg.ap.authmode);
             break;
         case MP_QSTR_channel: {
@@ -573,7 +606,7 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
         case MP_QSTR_hostname:
         case MP_QSTR_dhcp_hostname: {
             // TODO: Deprecated. Use network.hostname() instead.
-            req_if = WIFI_IF_STA;
+            req_if = ESP_IF_WIFI_STA;
             val = mp_obj_new_str(mod_network_hostname, strlen(mod_network_hostname));
             break;
         }
@@ -582,7 +615,7 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
             break;
         }
         case MP_QSTR_reconnects:
-            req_if = WIFI_IF_STA;
+            req_if = ESP_IF_WIFI_STA;
             int rec = conf_wifi_sta_reconnects - 1;
             val = MP_OBJ_NEW_SMALL_INT(rec);
             break;
@@ -598,6 +631,12 @@ STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_
             val = MP_OBJ_NEW_SMALL_INT(protocol_bitmap);
             break;
         }
+        case MP_QSTR_pm: {
+            wifi_ps_type_t ps_type;
+            esp_exceptions(esp_wifi_get_ps(&ps_type));
+            val = MP_OBJ_NEW_SMALL_INT(ps_type);
+            break;
+        }
         default:
             goto unknown;
     }
@@ -623,17 +662,20 @@ STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = {
     { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&network_wlan_isconnected_obj) },
     { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_wlan_config_obj) },
     { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_network_ifconfig_obj) },
+
+    // Constants
+    { MP_ROM_QSTR(MP_QSTR_PM_NONE), MP_ROM_INT(WIFI_PS_NONE) },
+    { MP_ROM_QSTR(MP_QSTR_PM_PERFORMANCE), MP_ROM_INT(WIFI_PS_MIN_MODEM) },
+    { MP_ROM_QSTR(MP_QSTR_PM_POWERSAVE), MP_ROM_INT(WIFI_PS_MAX_MODEM) },
 };
 STATIC MP_DEFINE_CONST_DICT(wlan_if_locals_dict, wlan_if_locals_dict_table);
 
 MP_DEFINE_CONST_OBJ_TYPE(
-    wlan_if_type,
+    esp_network_wlan_type,
     MP_QSTR_WLAN,
     MP_TYPE_FLAG_NONE,
+    make_new, network_wlan_make_new,
     locals_dict, &wlan_if_locals_dict
     );
 
-STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA};
-STATIC const wlan_if_obj_t wlan_ap_obj = {{&wlan_if_type}, WIFI_IF_AP};
-
 #endif // MICROPY_PY_NETWORK_WLAN
diff --git a/components/micropython/vendor/ports/esp32/ppp_set_auth.c b/components/micropython/vendor/ports/esp32/ppp_set_auth.c
new file mode 100644
index 0000000000000000000000000000000000000000..88ab668d48d3a476c18d4c27096f15031cdcc0e4
--- /dev/null
+++ b/components/micropython/vendor/ports/esp32/ppp_set_auth.c
@@ -0,0 +1,35 @@
+/*
+ * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// The pppapi_set_auth function was made static in the ESP-IDF, so it's re-added here.
+// See ESP-IDF commit c67f4c2b4c2bb4b7740f988fc0f8a3e911e56afe
+
+#include "ppp_set_auth.h"
+
+#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP
+
+#include "netif/ppp/pppapi.h"
+
+typedef struct {
+    struct tcpip_api_call_data call;
+    ppp_pcb *ppp;
+    u8_t authtype;
+    const char *user;
+    const char *passwd;
+} set_auth_msg_t;
+
+static err_t pppapi_do_ppp_set_auth(struct tcpip_api_call_data *m) {
+    set_auth_msg_t *msg = (set_auth_msg_t *)m;
+    ppp_set_auth(msg->ppp, msg->authtype, msg->user, msg->passwd);
+    return ERR_OK;
+}
+
+void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) {
+    set_auth_msg_t msg = { .ppp = pcb, .authtype = authtype, .user = user, .passwd = passwd};
+    tcpip_api_call(pppapi_do_ppp_set_auth, &msg.call);
+}
+
+#endif
diff --git a/components/micropython/vendor/ports/esp32/ppp_set_auth.h b/components/micropython/vendor/ports/esp32/ppp_set_auth.h
new file mode 100644
index 0000000000000000000000000000000000000000..67676ef4d6c7665bb85bbf9837d5907962ccfe12
--- /dev/null
+++ b/components/micropython/vendor/ports/esp32/ppp_set_auth.h
@@ -0,0 +1,22 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// The pppapi_set_auth function was made static in the ESP-IDF, so it's re-added here.
+// See ESP-IDF commit c67f4c2b4c2bb4b7740f988fc0f8a3e911e56afe
+
+#pragma once
+
+#include "esp_netif.h"
+
+#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP
+
+#include "lwip/netif.h"
+
+typedef struct ppp_pcb_s ppp_pcb;
+
+void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd);
+
+#endif
diff --git a/components/micropython/vendor/ports/esp32/uart.c b/components/micropython/vendor/ports/esp32/uart.c
index f6493dc796797e76106e4916012dd471dff5f47e..358d4347099518315981788b5ac203121aca7c6b 100644
--- a/components/micropython/vendor/ports/esp32/uart.c
+++ b/components/micropython/vendor/ports/esp32/uart.c
@@ -28,77 +28,93 @@
 
 #include <stdio.h>
 
-#include "driver/uart.h"
-#include "soc/uart_periph.h"
+#include "hal/uart_hal.h"
 
 #include "py/runtime.h"
 #include "py/mphal.h"
 #include "uart.h"
 
+// Backwards compatibility for when MICROPY_HW_UART_REPL was a ESP-IDF UART
+// driver enum. Only UART_NUM_0 was supported with that version of the driver.
+#define UART_NUM_0 0
+
 STATIC void uart_irq_handler(void *arg);
 
+// Declaring the HAL structure on the stack saves a tiny amount of static RAM
+#define REPL_HAL_DEFN() { .dev = UART_LL_GET_HW(MICROPY_HW_UART_REPL) }
+
+// RXFIFO Full interrupt threshold. Set the same as the ESP-IDF UART driver
+#define RXFIFO_FULL_THR (SOC_UART_FIFO_LEN - 8)
+
+// RXFIFO RX timeout threshold. This is in bit periods, so 10==one byte. Same as ESP-IDF UART driver.
+#define RXFIFO_RX_TIMEOUT (10)
+
 void uart_stdout_init(void) {
-    uart_config_t uartcfg = {
-        .baud_rate = MICROPY_HW_UART_REPL_BAUD,
-        .data_bits = UART_DATA_8_BITS,
-        .parity = UART_PARITY_DISABLE,
-        .stop_bits = UART_STOP_BITS_1,
-        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
-        .rx_flow_ctrl_thresh = 0
-    };
-    uart_param_config(MICROPY_HW_UART_REPL, &uartcfg);
-
-    const uint32_t rxbuf = 129; // IDF requires > 128 min
-    const uint32_t txbuf = 0;
-
-    uart_driver_install(MICROPY_HW_UART_REPL, rxbuf, txbuf, 0, NULL, 0);
-
-    uart_isr_handle_t handle;
-    uart_isr_free(MICROPY_HW_UART_REPL);
-    uart_isr_register(MICROPY_HW_UART_REPL, uart_irq_handler, NULL, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM, &handle);
-    uart_enable_rx_intr(MICROPY_HW_UART_REPL);
+    uart_hal_context_t repl_hal = REPL_HAL_DEFN();
+    uint32_t sclk_freq;
+
+    #if UART_SCLK_DEFAULT == SOC_MOD_CLK_APB
+    sclk_freq = APB_CLK_FREQ; // Assumes no frequency scaling
+    #else
+    // ESP32-H2 and ESP32-C2, I think
+    #error "This SoC uses a different default UART SCLK source, code needs updating."
+    #endif
+
+    uart_hal_init(&repl_hal, MICROPY_HW_UART_REPL); // Sets defaults: 8n1, no flow control
+    uart_hal_set_baudrate(&repl_hal, MICROPY_HW_UART_REPL_BAUD, sclk_freq);
+    uart_hal_rxfifo_rst(&repl_hal);
+    uart_hal_txfifo_rst(&repl_hal);
+
+    ESP_ERROR_CHECK(
+        esp_intr_alloc(uart_periph_signal[MICROPY_HW_UART_REPL].irq,
+            ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM,
+            uart_irq_handler,
+            NULL,
+            NULL)
+        );
+
+    // Enable RX interrupts
+    uart_hal_set_rxfifo_full_thr(&repl_hal, RXFIFO_FULL_THR);
+    uart_hal_set_rx_timeout(&repl_hal, RXFIFO_RX_TIMEOUT);
+    uart_hal_ena_intr_mask(&repl_hal, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT);
 }
 
 int uart_stdout_tx_strn(const char *str, size_t len) {
+    uart_hal_context_t repl_hal = REPL_HAL_DEFN();
     size_t remaining = len;
+    uint32_t written = 0;
     // TODO add a timeout
     for (;;) {
-        int ret = uart_tx_chars(MICROPY_HW_UART_REPL, str, remaining);
-        if (ret == -1) {
-            return -1;
-        }
-        remaining -= ret;
-        if (remaining <= 0) {
+        uart_hal_write_txfifo(&repl_hal, (const void *)str, remaining, &written);
+
+        if (written >= remaining) {
             break;
         }
-        str += ret;
+        remaining -= written;
+        str += written;
         ulTaskNotifyTake(pdFALSE, 1);
     }
-    return len - remaining;
+    return len;
 }
 
 // all code executed in ISR must be in IRAM, and any const data must be in DRAM
 STATIC void IRAM_ATTR uart_irq_handler(void *arg) {
-    volatile uart_dev_t *uart = &UART0;
-    #if CONFIG_IDF_TARGET_ESP32S3
-    uart->int_clr.rxfifo_full_int_clr = 1;
-    uart->int_clr.rxfifo_tout_int_clr = 1;
-    #else
-    uart->int_clr.rxfifo_full = 1;
-    uart->int_clr.rxfifo_tout = 1;
-    uart->int_clr.frm_err = 1;
-    #endif
-    while (uart->status.rxfifo_cnt) {
-        #if CONFIG_IDF_TARGET_ESP32
-        uint8_t c = uart->fifo.rw_byte;
-        #elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
-        uint8_t c = READ_PERI_REG(UART_FIFO_AHB_REG(0)); // UART0
-        #endif
-        if (c == mp_interrupt_char) {
+    uint8_t rbuf[SOC_UART_FIFO_LEN];
+    int len;
+    uart_hal_context_t repl_hal = REPL_HAL_DEFN();
+
+    uart_hal_clr_intsts_mask(&repl_hal, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_FRAM_ERR);
+
+    len = uart_hal_get_rxfifo_len(&repl_hal);
+
+    uart_hal_read_rxfifo(&repl_hal, rbuf, &len);
+
+    for (int i = 0; i < len; i++) {
+        if (rbuf[i] == mp_interrupt_char) {
             mp_sched_keyboard_interrupt();
         } else {
             // this is an inline function so will be in IRAM
-            ringbuf_put(&stdin_ringbuf, c);
+            ringbuf_put(&stdin_ringbuf, rbuf[i]);
         }
     }
 }
diff --git a/components/micropython/vendor/ports/esp32/uart.h b/components/micropython/vendor/ports/esp32/uart.h
index e3c7482e7b4851e710f748f32bd4c09b0d277d8d..ab9e17d500c65cef5b624da12c9cd5e40e4b90fb 100644
--- a/components/micropython/vendor/ports/esp32/uart.h
+++ b/components/micropython/vendor/ports/esp32/uart.h
@@ -30,7 +30,7 @@
 
 // Whether to enable the REPL on a UART.
 #ifndef MICROPY_HW_ENABLE_UART_REPL
-#define MICROPY_HW_ENABLE_UART_REPL (!CONFIG_USB_ENABLED && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG)
+#define MICROPY_HW_ENABLE_UART_REPL (!CONFIG_USB_OTG_SUPPORTED && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG)
 #endif
 
 #ifndef MICROPY_HW_UART_REPL
diff --git a/components/micropython/vendor/ports/esp32/usb.c b/components/micropython/vendor/ports/esp32/usb.c
index 80612cd276e74dd5c655a6b61a5a77437511fc56..83ba9533d3802bb2fd25f426ea0f39b0053c50ca 100644
--- a/components/micropython/vendor/ports/esp32/usb.c
+++ b/components/micropython/vendor/ports/esp32/usb.c
@@ -28,14 +28,17 @@
 #include "py/mphal.h"
 #include "usb.h"
 
-#if CONFIG_USB_ENABLED
+#if CONFIG_USB_OTG_SUPPORTED
 
+#include "esp_timer.h"
+#ifndef NO_QSTR
 #include "tinyusb.h"
 #include "tusb_cdc_acm.h"
+#endif
 
 #define CDC_ITF TINYUSB_CDC_ACM_0
 
-static uint8_t usb_rx_buf[CONFIG_USB_CDC_RX_BUFSIZE];
+static uint8_t usb_rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE];
 
 static void usb_callback_rx(int itf, cdcacm_event_t *event) {
     // TODO: what happens if more chars come in during this function, are they lost?
@@ -79,7 +82,7 @@ void usb_init(void) {
 
 void usb_tx_strn(const char *str, size_t len) {
     // Write out the data to the CDC interface, but only while the USB host is connected.
-    uint64_t timeout = esp_timer_get_time() + (uint64_t)(MICROPY_HW_USB_CDC_TX_TIMEOUT * 1000);
+    uint64_t timeout = esp_timer_get_time() + (uint64_t)(MICROPY_HW_USB_CDC_TX_TIMEOUT_MS * 1000);
     while (tud_cdc_n_connected(CDC_ITF) && len && esp_timer_get_time() < timeout) {
         size_t l = tinyusb_cdcacm_write_queue(CDC_ITF, (uint8_t *)str, len);
         str += l;
@@ -88,4 +91,4 @@ void usb_tx_strn(const char *str, size_t len) {
     }
 }
 
-#endif // CONFIG_USB_ENABLED
+#endif // CONFIG_USB_OTG_SUPPORTED
diff --git a/components/micropython/vendor/ports/esp32/usb.h b/components/micropython/vendor/ports/esp32/usb.h
index 009bf42624d98518af1c04b5a9f377fd45f2b202..a4c7d40701dfcb2942b417cea80b1b0bce98f497 100644
--- a/components/micropython/vendor/ports/esp32/usb.h
+++ b/components/micropython/vendor/ports/esp32/usb.h
@@ -26,7 +26,7 @@
 #ifndef MICROPY_INCLUDED_ESP32_USB_H
 #define MICROPY_INCLUDED_ESP32_USB_H
 
-#define MICROPY_HW_USB_CDC_TX_TIMEOUT  (500)
+#define MICROPY_HW_USB_CDC_TX_TIMEOUT_MS (500)
 
 void usb_init(void);
 void usb_tx_strn(const char *str, size_t len);
diff --git a/components/micropython/vendor/ports/esp32/usb_serial_jtag.c b/components/micropython/vendor/ports/esp32/usb_serial_jtag.c
index a7d06a355a2ea62c5101e7b1849bb2200a7e4bef..3289a1b5c078395524832402539fba8d244c8bc6 100644
--- a/components/micropython/vendor/ports/esp32/usb_serial_jtag.c
+++ b/components/micropython/vendor/ports/esp32/usb_serial_jtag.c
@@ -79,9 +79,9 @@ void usb_serial_jtag_tx_strn(const char *str, size_t len) {
         if (l > USB_SERIAL_JTAG_PACKET_SZ_BYTES) {
             l = USB_SERIAL_JTAG_PACKET_SZ_BYTES;
         }
-        portTickType start_tick = xTaskGetTickCount();
+        TickType_t start_tick = xTaskGetTickCount();
         while (!usb_serial_jtag_ll_txfifo_writable()) {
-            portTickType now_tick = xTaskGetTickCount();
+            TickType_t now_tick = xTaskGetTickCount();
             if (!terminal_connected || now_tick > (start_tick + pdMS_TO_TICKS(200))) {
                 terminal_connected = false;
                 return;
diff --git a/components/st3m/st3m_gfx.c b/components/st3m/st3m_gfx.c
index 0b94f623b89c3010837ce9c0c72cee13a930242e..eb6b8b132ca53d577d0a995e85f30fbe5ff5c7c5 100644
--- a/components/st3m/st3m_gfx.c
+++ b/components/st3m/st3m_gfx.c
@@ -270,7 +270,7 @@ void st3m_gfx_flush(void) {
 
     // Delay, making sure pipeline tasks have returned all used descriptors. One
     // second is enough to make sure we've processed everything.
-    vTaskDelay(1000 / portTICK_RATE_MS);
+    vTaskDelay(1000 / portTICK_PERIOD_MS);
 
     // And drain again.
     xQueueReset(framebuffer_freeq);
diff --git a/nix/esp-idf/default.nix b/nix/esp-idf/default.nix
index 29f6a88fc0a4956b612cc02220b88b9f46ee958a..d46cba554877c9716c66c273bba15ca6d93051a6 100644
--- a/nix/esp-idf/default.nix
+++ b/nix/esp-idf/default.nix
@@ -1,7 +1,7 @@
 # Based on https://github.com/mirrexagon/nixpkgs-esp-dev/
 
-{ rev ? "v4.4.5"
-, sha256 ? "sha256-Jz9cbTYoourYYNo873kLt4CQXbE704zc9Aeq9kbNdPU="
+{ rev ? "v5.1"
+, sha256 ? "sha256-IEa9R9VCWvbRjZFRPb2Qq2Qw1RFxsnVALFVgQlBCXMw="
 , stdenv
 , python3Packages
 , fetchFromGitHub
@@ -15,6 +15,91 @@ let
     sha256 = sha256;
     fetchSubmodules = true;
   };
+
+  deps = with python3Packages; rec {
+    pygdbmi_ = pygdbmi.overrideAttrs (oa: rec {
+      version = "0.9.0.2";
+      src = fetchFromGitHub {
+        owner = "cs01";
+        repo = "pygdbmi";
+        rev = version;
+        hash = "sha256-bZQYcT5lA8xkG2YIK7P7fxkbVJhO6T5YpWo1EdLpOgY=";
+      };
+    });
+
+    esptool = buildPythonPackage rec {
+      pname = "esptool";
+      version = "4.6.2";
+      src = fetchPypi {
+        inherit pname version;
+        sha256 = "sha256-VJ75Pu9C7n6UYs5aU8Ft96DHHZGz934Z7BV0mATN8wA=";
+      };
+      doCheck = false;
+      propagatedBuildInputs = [
+        cryptography
+        pyyaml
+        bitstring
+        ecdsa
+        reedsolo
+        pyserial
+        python-pkcs11
+        construct
+      ];
+    };
+
+    esp-idf-kconfig = buildPythonPackage rec {
+      pname = "esp-idf-kconfig";
+      version = "1.1.0";
+      src = fetchPypi {
+        inherit pname version;
+        sha256 = "sha256-s8ZXt6cf5w2pZSxQNIs/SODAUvHNgxyQ+onaCa7UbFA=";
+      };
+      propagatedBuildInputs = [
+        kconfiglib
+      ];
+    };
+
+    esp-coredump = buildPythonPackage rec {
+      pname = "esp-coredump";
+      version = "1.2";
+      src = fetchPypi {
+        inherit pname version;
+        sha256 = "sha256-xcBDMy/1/UZo5K1+nXAE220Tb2DaP2VgSkeN5eC3XYg=";
+      };
+      doCheck = false;
+      propagatedBuildInputs = [
+        pygdbmi_
+        esptool
+      ];
+    };
+
+    esp-idf-monitor = buildPythonPackage rec {
+      pname = "esp-idf-monitor";
+      version = "1.1.1";
+      src = fetchPypi {
+        inherit pname version;
+        sha256 = "sha256-c62X3ZHRShhbAFmuPc/d2keqE9T9SXYIlJTyn32LPaE=";
+      };
+      propagatedBuildInputs = [
+        pyserial
+        esp-coredump
+        pyelftools
+        pyparsing
+      ];
+    };
+
+    esp-idf-size = buildPythonPackage rec {
+      pname = "esp-idf-size";
+      version = "0.3.1";
+      src = fetchPypi {
+        inherit pname version;
+        sha256 = "sha256-OzthhzKGjyqDJrmJWs4LMkHz0rAwho+3Pyc2BYFK0EU=";
+      };
+      propagatedBuildInputs = [
+        pyyaml
+      ];
+    };
+  };
 in
 stdenv.mkDerivation rec {
   pname = "esp-idf";
@@ -27,17 +112,7 @@ stdenv.mkDerivation rec {
 
   propagatedBuildInputs = with python3Packages; [
     setuptools click future pyelftools urllib3
-    jinja2 itsdangerous
-
-    (pyparsing.overrideAttrs (oa: rec {
-      version = "2.3.1";
-      src = fetchFromGitHub {
-        owner = "pyparsing";
-        repo = "pyparsing";
-        rev = "pyparsing_${version}";
-        hash = "sha256-m4mvPUXjDxz77rofg2Bop4/RnVTBDBNL6lRDd5zkpxM=";
-      };
-    }))
+    jinja2 itsdangerous pyyaml
 
     (kconfiglib.overrideAttrs (oa: rec {
       version = "13.7.1";
@@ -81,21 +156,13 @@ stdenv.mkDerivation rec {
       });
     })
 
-    (pygdbmi.overrideAttrs (oa: rec {
-      version = "0.9.0.2";
-      src = fetchFromGitHub {
-        owner = "cs01";
-        repo = "pygdbmi";
-        rev = version;
-        hash = "sha256-bZQYcT5lA8xkG2YIK7P7fxkbVJhO6T5YpWo1EdLpOgY=";
-      };
-    }))
+    deps.esp-idf-monitor
+    deps.esp-idf-kconfig
+    deps.esp-idf-size
   ];
 
   patches = [
-    # Can't be bothered to package gdbgui and idf-component-manager and we
-    # don't need them.
-    ./fixup-requirements.patch
+    ./rack-off-me-nix-mate.patch
   ];
 
   installPhase = ''
diff --git a/nix/esp-idf/rack-off-me-nix-mate.patch b/nix/esp-idf/rack-off-me-nix-mate.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c6c951e1459d39154d3b3657f64ae3f956dcc6be
--- /dev/null
+++ b/nix/esp-idf/rack-off-me-nix-mate.patch
@@ -0,0 +1,76 @@
+diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake
+index 70bb2d636c..e7b5c7f3bc 100644
+--- a/tools/cmake/build.cmake
++++ b/tools/cmake/build.cmake
+@@ -352,20 +352,6 @@ endfunction()
+ #
+ function(__build_check_python)
+     idf_build_get_property(check __CHECK_PYTHON)
+-    if(check)
+-        idf_build_get_property(python PYTHON)
+-        idf_build_get_property(idf_path IDF_PATH)
+-        message(STATUS "Checking Python dependencies...")
+-        execute_process(COMMAND "${python}" "${idf_path}/tools/idf_tools.py" "check-python-dependencies"
+-            RESULT_VARIABLE result)
+-        if(result EQUAL 1)
+-            # check_python_dependencies returns error code 1 on failure
+-            message(FATAL_ERROR "Some Python dependencies must be installed. Check above message for details.")
+-        elseif(NOT result EQUAL 0)
+-            # means check_python_dependencies.py failed to run at all, result should be an error message
+-            message(FATAL_ERROR "Failed to run Python dependency check. Python: ${python}, Error: ${result}")
+-        endif()
+-    endif()
+ endfunction()
+ 
+ #
+diff --git a/tools/idf.py b/tools/idf.py
+index a74439a069..e8f5a6d41d 100755
+--- a/tools/idf.py
++++ b/tools/idf.py
+@@ -33,16 +33,11 @@ sys.dont_write_bytecode = True
+ 
+ import python_version_checker  # noqa: E402
+ 
+-try:
+-    from idf_py_actions.errors import FatalError  # noqa: E402
+-    from idf_py_actions.tools import (PROG, SHELL_COMPLETE_RUN, SHELL_COMPLETE_VAR, PropertyDict,  # noqa: E402
+-                                      debug_print_idf_version, get_target, merge_action_lists, print_warning)
+-    if os.getenv('IDF_COMPONENT_MANAGER') != '0':
+-        from idf_component_manager import idf_extensions
+-except ImportError:
+-    # For example, importing click could cause this.
+-    print('Please use idf.py only in an ESP-IDF shell environment.', file=sys.stderr)
+-    sys.exit(1)
++from idf_py_actions.errors import FatalError  # noqa: E402
++from idf_py_actions.tools import (PROG, SHELL_COMPLETE_RUN, SHELL_COMPLETE_VAR, PropertyDict,  # noqa: E402
++                                  debug_print_idf_version, get_target, merge_action_lists, print_warning)
++if os.getenv('IDF_COMPONENT_MANAGER') != '0':
++    from idf_component_manager import idf_extensions
+ 
+ # Use this Python interpreter for any subprocesses we launch
+ PYTHON = sys.executable
+@@ -82,24 +77,6 @@ def check_environment() -> List:
+     except RuntimeError as e:
+         raise FatalError(e)
+ 
+-    # check Python dependencies
+-    checks_output.append('Checking Python dependencies...')
+-    try:
+-        out = subprocess.check_output(
+-            [
+-                os.environ['PYTHON'],
+-                os.path.join(os.environ['IDF_PATH'], 'tools', 'idf_tools.py'),
+-                'check-python-dependencies',
+-            ],
+-            env=os.environ,
+-        )
+-
+-        checks_output.append(out.decode('utf-8', 'ignore').strip())
+-    except subprocess.CalledProcessError as e:
+-        print_warning(e.output.decode('utf-8', 'ignore'), stream=sys.stderr)
+-        debug_print_idf_version()
+-        raise SystemExit(1)
+-
+     return checks_output
+ 
+ 
diff --git a/nix/esp32s3-toolchain-bin.nix b/nix/esp32s3-toolchain-bin.nix
index b8d69a84e0037e2df35f374dbfad6ab0c6ed50f8..f7869a4dd5cd4100c14184269585c6990f486d1b 100644
--- a/nix/esp32s3-toolchain-bin.nix
+++ b/nix/esp32s3-toolchain-bin.nix
@@ -1,7 +1,7 @@
 # Based on https://github.com/mirrexagon/nixpkgs-esp-dev/
 
-{ version ? "2021r2-patch5"
-, hash ? "sha256-iqF6at8B76WxYoyKxXgGOkTSaulYHTlIa5IiOkHvJi8="
+{ version ? "12.2.0_20230208"
+, hash ? "sha256-KbXqazDZgjHwwX8jJ0BBCeCr9ZtI0PKJDZ2YmWeKiaM="
 , stdenv
 , lib
 , fetchurl
@@ -24,7 +24,7 @@ stdenv.mkDerivation rec {
   inherit version;
 
   src = fetchurl {
-    url = "https://github.com/espressif/crosstool-NG/releases/download/esp-${version}/xtensa-esp32s3-elf-gcc8_4_0-esp-${version}-linux-amd64.tar.gz";
+    url = "https://github.com/espressif/crosstool-NG/releases/download/esp-${version}/xtensa-esp32s3-elf-${version}-x86_64-linux-gnu.tar.xz";
     inherit hash;
   };
 
diff --git a/nix/shell.nix b/nix/shell.nix
index eeaf9f150be371ab0b46de22b4ec56885fdcc935..479c419ae3412d395f7ba27bc3c64934efb8202f 100644
--- a/nix/shell.nix
+++ b/nix/shell.nix
@@ -1,5 +1,5 @@
 let
-  sources = import ./niv/sources.nix;
+  sources = import ./sources.nix;
   nixpkgs = import sources.nixpkgs {
     overlays = [
       (self: super: {
@@ -34,8 +34,6 @@ in with nixpkgs; pkgs.mkShell {
   shellHook = ''
     # For esp.py openocd integration.
     export OPENOCD_SCRIPTS="${pkgs.openocd-esp32-bin}/share/openocd/scripts"
-    # For GDB to be able to find libpython2.7 (????).
-    export LD_LIBRARY_PATH="${pkgs.python2}/lib:$LD_LIBRARY_PATH"
 
     # Some nice-to-have defaults.
     export ESPPORT=/dev/ttyACM0
diff --git a/nix/niv/sources.json b/nix/sources.json
similarity index 54%
rename from nix/niv/sources.json
rename to nix/sources.json
index 60c24b7b39a6e5fd3e05feb0105a55408cc070d9..b64d0d8da00afe718bf313a7933565a9f0365d1e 100644
--- a/nix/niv/sources.json
+++ b/nix/sources.json
@@ -5,10 +5,10 @@
         "homepage": "",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "c11d08f02390aab49e7c22e6d0ea9b176394d961",
-        "sha256": "017jdga9j0qkdplly8pypxxcsski0h9galzaf9qsvpq0j50x86cv",
+        "rev": "68b3d3225096da1bc66ba8e65f69fa8d19248358",
+        "sha256": "0ccljssfq473pf5dhy1zcf7gb2adapgj9jcbkk1mmn9g025533wn",
         "type": "tarball",
-        "url": "https://github.com/NixOS/nixpkgs/archive/c11d08f02390aab49e7c22e6d0ea9b176394d961.tar.gz",
+        "url": "https://github.com/NixOS/nixpkgs/archive/68b3d3225096da1bc66ba8e65f69fa8d19248358.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     }
 }
diff --git a/nix/niv/sources.nix b/nix/sources.nix
similarity index 100%
rename from nix/niv/sources.nix
rename to nix/sources.nix
diff --git a/sdkconfig.defaults b/sdkconfig.defaults
index 8c7cb72d1b25eb90ce7a98b5fe38af70d5961e54..fe91028bf7ee39187842c00acd35e44af94ed6fc 100644
--- a/sdkconfig.defaults
+++ b/sdkconfig.defaults
@@ -1,6 +1,6 @@
+CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
 CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y
 CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=y
-CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
 CONFIG_ESPTOOLPY_NO_STUB=y
 CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
 CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
@@ -13,28 +13,26 @@ CONFIG_BT_ENABLED=y
 CONFIG_BT_NIMBLE_ENABLED=y
 CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
 CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
-CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
-CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
-CONFIG_ESP32S3_DATA_CACHE_64KB=y
-CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
-CONFIG_ESP32S3_SPIRAM_SUPPORT=y
+CONFIG_PM_ENABLE=y
+CONFIG_SPIRAM=y
 CONFIG_SPIRAM_MODE_OCT=y
 CONFIG_SPIRAM_TYPE_ESPPSRAM64=y
 CONFIG_SPIRAM_SPEED_80M=y
 CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
 CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
-CONFIG_PM_ENABLE=y
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
+CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
+CONFIG_ESP32S3_DATA_CACHE_64KB=y
+CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
 CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
 # CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
 # CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
-# CONFIG_ESP32_WIFI_IRAM_OPT is not set
-# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set
 CONFIG_FATFS_LFN_HEAP=y
 CONFIG_FATFS_API_ENCODING_UTF_8=y
 CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
-CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP=y
 CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
 CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
+CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP=y
 CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
 CONFIG_LWIP_PPP_SUPPORT=y
 CONFIG_LWIP_PPP_PAP_SUPPORT=y
diff --git a/usermodule/mp_kernel.c b/usermodule/mp_kernel.c
index 1c2a334923205dcaf0259e3c8dbbfdfb7f56637a..9160ee12815672e5e2b0d1e26d34febbed9675dd 100644
--- a/usermodule/mp_kernel.c
+++ b/usermodule/mp_kernel.c
@@ -42,11 +42,7 @@ STATIC void task_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
     (void)kind;
     task_obj_t *self = MP_OBJ_TO_PTR(self_in);
     mp_print_str(print, "Task(name=");
-    if (self->name != NULL) {
-        mp_print_str(print, self->name);
-    } else {
-        mp_print_str(print, "NULL");
-    }
+    mp_print_str(print, self->name);
     mp_print_str(print, ",state=");
     switch (self->state) {
     case eRunning: