From 3c9546ea0911b50d4b85ad4046864c90f84b3fd3 Mon Sep 17 00:00:00 2001
From: Damien George <damien@micropython.org>
Date: Sat, 2 Aug 2025 08:52:05 +1000
Subject: [PATCH 1/8] esp32/mpconfigport: Disable I2CTarget on ESP32-C6 to
 reduce code size.

I2CTarget costs about 8k of flash size on ESP32-S2, and about 11k on
ESP32-C6.  The ESP32-C6 only has about 8k remaining, so disable I2CTarget
on that SoC until more flash can be made available.

Signed-off-by: Damien George <damien@micropython.org>
---
 ports/esp32/mpconfigport.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h
index 48ad39ef7ed1..cc10fd0b7bbb 100644
--- a/ports/esp32/mpconfigport.h
+++ b/ports/esp32/mpconfigport.h
@@ -140,7 +140,8 @@
 #define MICROPY_PY_MACHINE_I2C              (1)
 #define MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 (1)
 // I2C target hardware is limited on ESP32 (eg read event comes after the read) so we only support newer SoCs.
-#define MICROPY_PY_MACHINE_I2C_TARGET       (SOC_I2C_SUPPORT_SLAVE && !CONFIG_IDF_TARGET_ESP32)
+// ESP32C6 does not have enough flash space so also disable it on that SoC.
+#define MICROPY_PY_MACHINE_I2C_TARGET       (SOC_I2C_SUPPORT_SLAVE && !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32C6)
 #define MICROPY_PY_MACHINE_I2C_TARGET_INCLUDEFILE "ports/esp32/machine_i2c_target.c"
 #define MICROPY_PY_MACHINE_I2C_TARGET_MAX   (2)
 #define MICROPY_PY_MACHINE_SOFTI2C          (1)

From 658a2e3dbd0316204a13f2478d98ea3f8649f064 Mon Sep 17 00:00:00 2001
From: Damien George <damien@micropython.org>
Date: Sat, 2 Aug 2025 08:39:16 +1000
Subject: [PATCH 2/8] github/workflows: Add a CI job to build ESP32-C2 and
 ESP32-C6 boards.

So that all six supported SoCs are built by CI.

Signed-off-by: Damien George <damien@micropython.org>
---
 .github/workflows/ports_esp32.yml | 1 +
 tools/ci.sh                       | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/.github/workflows/ports_esp32.yml b/.github/workflows/ports_esp32.yml
index 4c07f8943775..36ab341cfcdd 100644
--- a/.github/workflows/ports_esp32.yml
+++ b/.github/workflows/ports_esp32.yml
@@ -25,6 +25,7 @@ jobs:
         ci_func:  # names are functions in ci.sh
           - esp32_build_cmod_spiram_s2
           - esp32_build_s3_c3
+          - esp32_build_c2_c6
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout@v4
diff --git a/tools/ci.sh b/tools/ci.sh
index d787cbcf0733..8f045639b80c 100755
--- a/tools/ci.sh
+++ b/tools/ci.sh
@@ -214,6 +214,13 @@ function ci_esp32_build_s3_c3 {
     make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_C3
 }
 
+function ci_esp32_build_c2_c6 {
+    ci_esp32_build_common
+
+    make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_C2
+    make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_C6
+}
+
 ########################################################################################
 # ports/esp8266
 

From c0252d73c6499cf8c09fa57e17f4b530315b0ee0 Mon Sep 17 00:00:00 2001
From: Jeff Epler <jepler@gmail.com>
Date: Sat, 2 Aug 2025 15:24:45 -0500
Subject: [PATCH 3/8] py/parse: Fix missing nlr_pop call in complex path of
 binary_op_maybe.

Reproducer (needs to be run as one compilation unit):

    ans = (-1) ** 2.3
    aa

Fixes issue #17815.

Signed-off-by: Jeff Epler <jepler@gmail.com>
---
 py/parse.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/py/parse.c b/py/parse.c
index 91eea3e36890..6260987b28a3 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -671,13 +671,13 @@ static bool binary_op_maybe(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs, mp_ob
     nlr_buf_t nlr;
     if (nlr_push(&nlr) == 0) {
         mp_obj_t tmp = mp_binary_op(op, lhs, rhs);
+        nlr_pop();
         #if MICROPY_PY_BUILTINS_COMPLEX
         if (mp_obj_is_type(tmp, &mp_type_complex)) {
             return false;
         }
         #endif
         *res = tmp;
-        nlr_pop();
         return true;
     } else {
         return false;

From 7c8ae78a0384ce3fac2e9421df2590ef7d7031ef Mon Sep 17 00:00:00 2001
From: Damien George <damien@micropython.org>
Date: Mon, 4 Aug 2025 01:45:30 +1000
Subject: [PATCH 4/8] lib/micropython-lib: Update submodule to latest.

This brings in:
- lora: fix SNR value in SX126x received packets
- utop: add initial implementation for ESP32
- utop: print MicroPython memory info
- utop: print IDF heap details
- urllib.urequest: add support for headers to urequest.urlopen
- aiorepl: use blocking reads for raw REPL and raw paste
- errno: add ENOTCONN constant
- logging: allow logging.exception helper to handle tracebacks
- aioble-l2cap: raise correct error if l2cap disconnects during send
- abc: add ABC base class
- aiohttp: fix partial reads by using readexactly
- aiorepl: handle stream shutdown

Signed-off-by: Damien George <damien@micropython.org>
---
 lib/micropython-lib | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/micropython-lib b/lib/micropython-lib
index 5b496e944ec0..34c4ee1647ac 160000
--- a/lib/micropython-lib
+++ b/lib/micropython-lib
@@ -1 +1 @@
-Subproject commit 5b496e944ec045177afa1620920a168410b7f60b
+Subproject commit 34c4ee1647ac4b177ae40adf0ec514660e433dc0

From 255d74b5a8c31ec06d1c2c528f7888f6c2dfc246 Mon Sep 17 00:00:00 2001
From: Damien George <damien@micropython.org>
Date: Mon, 4 Aug 2025 02:00:47 +1000
Subject: [PATCH 5/8] renesas-ra/mpconfigport: Enable
 MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE.

This setting was missed in df05caea6c6437a8b4756ec502a5e6210f4b6256.  It's
needed for this port to pass its `tests/ports/renesas-ra/modtime.py` test.

Signed-off-by: Damien George <damien@micropython.org>
---
 ports/renesas-ra/mpconfigport.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ports/renesas-ra/mpconfigport.h b/ports/renesas-ra/mpconfigport.h
index 868cdbc7d6ad..70d38e7d20e0 100644
--- a/ports/renesas-ra/mpconfigport.h
+++ b/ports/renesas-ra/mpconfigport.h
@@ -99,6 +99,7 @@
 #ifndef MICROPY_FLOAT_IMPL // can be configured by each board via mpconfigboard.mk
 #define MICROPY_FLOAT_IMPL          (MICROPY_FLOAT_IMPL_FLOAT)
 #endif
+#define MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE (1)
 #define MICROPY_USE_INTERNAL_ERRNO  (1)
 #define MICROPY_SCHEDULER_DEPTH     (8)
 #define MICROPY_SCHEDULER_STATIC_NODES (1)

From d5ecda05eb743839e9011f3d23657b39cd05e6c0 Mon Sep 17 00:00:00 2001
From: Damien George <damien@micropython.org>
Date: Thu, 7 Aug 2025 10:33:26 +1000
Subject: [PATCH 6/8] ports: Allow MICROPY_PY_MACHINE_I2C_TARGET to be disabled
 by board cfg.

Signed-off-by: Damien George <damien@micropython.org>
---
 ports/alif/mpconfigport.h          | 2 ++
 ports/esp32/mpconfigport.h         | 2 ++
 ports/mimxrt/mpconfigport.h        | 2 ++
 ports/rp2/mpconfigport.h           | 2 ++
 ports/stm32/mpconfigboard_common.h | 2 ++
 5 files changed, 10 insertions(+)

diff --git a/ports/alif/mpconfigport.h b/ports/alif/mpconfigport.h
index a8c8c842977e..8a65721bb0ff 100644
--- a/ports/alif/mpconfigport.h
+++ b/ports/alif/mpconfigport.h
@@ -132,10 +132,12 @@
 #define MICROPY_PY_MACHINE_PULSE                (1)
 #define MICROPY_PY_MACHINE_I2C                  (MICROPY_HW_ENABLE_HW_I2C)
 #define MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1  (1)
+#ifndef MICROPY_PY_MACHINE_I2C_TARGET
 #define MICROPY_PY_MACHINE_I2C_TARGET           (MICROPY_HW_ENABLE_HW_I2C)
 #define MICROPY_PY_MACHINE_I2C_TARGET_INCLUDEFILE "ports/alif/machine_i2c_target.c"
 #define MICROPY_PY_MACHINE_I2C_TARGET_MAX       (4)
 #define MICROPY_PY_MACHINE_I2C_TARGET_HARD_IRQ  (1)
+#endif
 #define MICROPY_PY_MACHINE_SOFTI2C              (1)
 #define MICROPY_PY_MACHINE_SPI                  (1)
 #define MICROPY_PY_MACHINE_SOFTSPI              (1)
diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h
index cc10fd0b7bbb..e47b333c7369 100644
--- a/ports/esp32/mpconfigport.h
+++ b/ports/esp32/mpconfigport.h
@@ -139,11 +139,13 @@
 #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE  "ports/esp32/machine_pwm.c"
 #define MICROPY_PY_MACHINE_I2C              (1)
 #define MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 (1)
+#ifndef MICROPY_PY_MACHINE_I2C_TARGET
 // I2C target hardware is limited on ESP32 (eg read event comes after the read) so we only support newer SoCs.
 // ESP32C6 does not have enough flash space so also disable it on that SoC.
 #define MICROPY_PY_MACHINE_I2C_TARGET       (SOC_I2C_SUPPORT_SLAVE && !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32C6)
 #define MICROPY_PY_MACHINE_I2C_TARGET_INCLUDEFILE "ports/esp32/machine_i2c_target.c"
 #define MICROPY_PY_MACHINE_I2C_TARGET_MAX   (2)
+#endif
 #define MICROPY_PY_MACHINE_SOFTI2C          (1)
 #define MICROPY_PY_MACHINE_SPI              (1)
 #define MICROPY_PY_MACHINE_SOFTSPI          (1)
diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h
index 8ceb3b418370..3cf6550d7b07 100644
--- a/ports/mimxrt/mpconfigport.h
+++ b/ports/mimxrt/mpconfigport.h
@@ -92,11 +92,13 @@ uint32_t trng_random_u32(void);
 #define MICROPY_PY_MACHINE_PWM              (1)
 #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE  "ports/mimxrt/machine_pwm.c"
 #define MICROPY_PY_MACHINE_I2C              (1)
+#ifndef MICROPY_PY_MACHINE_I2C_TARGET
 #define MICROPY_PY_MACHINE_I2C_TARGET       (1)
 #define MICROPY_PY_MACHINE_I2C_TARGET_INCLUDEFILE "ports/mimxrt/machine_i2c_target.c"
 #define MICROPY_PY_MACHINE_I2C_TARGET_MAX   (FSL_FEATURE_SOC_LPI2C_COUNT)
 #define MICROPY_PY_MACHINE_I2C_TARGET_HARD_IRQ (1)
 #define MICROPY_PY_MACHINE_I2C_TARGET_FINALISER (1)
+#endif
 #ifndef MICROPY_PY_MACHINE_I2S
 #define MICROPY_PY_MACHINE_I2S              (0)
 #endif
diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h
index d35563bd0702..c312293ace6e 100644
--- a/ports/rp2/mpconfigport.h
+++ b/ports/rp2/mpconfigport.h
@@ -171,10 +171,12 @@
 #define MICROPY_PY_MACHINE_PWM                  (1)
 #define MICROPY_PY_MACHINE_PWM_INCLUDEFILE      "ports/rp2/machine_pwm.c"
 #define MICROPY_PY_MACHINE_I2C                  (1)
+#ifndef MICROPY_PY_MACHINE_I2C_TARGET
 #define MICROPY_PY_MACHINE_I2C_TARGET           (1)
 #define MICROPY_PY_MACHINE_I2C_TARGET_INCLUDEFILE "ports/rp2/machine_i2c_target.c"
 #define MICROPY_PY_MACHINE_I2C_TARGET_MAX       (2)
 #define MICROPY_PY_MACHINE_I2C_TARGET_HARD_IRQ  (1)
+#endif
 #define MICROPY_PY_MACHINE_SOFTI2C              (1)
 #define MICROPY_PY_MACHINE_I2S                  (1)
 #define MICROPY_PY_MACHINE_I2S_INCLUDEFILE      "ports/rp2/machine_i2s.c"
diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h
index dcbbbccceb6b..a8e50be5c6a8 100644
--- a/ports/stm32/mpconfigboard_common.h
+++ b/ports/stm32/mpconfigboard_common.h
@@ -639,11 +639,13 @@
 #if defined(MICROPY_HW_I2C1_SCL) || defined(MICROPY_HW_I2C2_SCL) \
     || defined(MICROPY_HW_I2C3_SCL) || defined(MICROPY_HW_I2C4_SCL)
 #define MICROPY_HW_ENABLE_HW_I2C (1)
+#ifndef MICROPY_HW_ENABLE_HW_I2C_TARGET
 #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32WB)
 #define MICROPY_HW_ENABLE_HW_I2C_TARGET (1)
 #else
 #define MICROPY_HW_ENABLE_HW_I2C_TARGET (0)
 #endif
+#endif
 #else
 #define MICROPY_HW_ENABLE_HW_I2C (0)
 #define MICROPY_HW_ENABLE_HW_I2C_TARGET (0)

From ce109af712452474dfe3864f82b5430f4e2a5ff0 Mon Sep 17 00:00:00 2001
From: Angus Gratton <angus@redyak.com.au>
Date: Wed, 6 Aug 2025 15:47:15 +1000
Subject: [PATCH 7/8] esp32/machine_timer: Enable timer clock source for
 ESP32C6.

Otherwise the PLL is not enabled.  These changes are adapted from
`timer_legacy.h` in ESP-IDF.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
---
 ports/esp32/machine_timer.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c
index a104288f6ee3..faa47d59afc1 100644
--- a/ports/esp32/machine_timer.c
+++ b/ports/esp32/machine_timer.c
@@ -38,6 +38,8 @@
 #include "hal/timer_hal.h"
 #include "hal/timer_ll.h"
 #include "soc/timer_periph.h"
+#include "esp_private/esp_clk_tree_common.h"
+#include "esp_private/periph_ctrl.h"
 #include "machine_timer.h"
 
 #define TIMER_DIVIDER  8
@@ -163,8 +165,18 @@ static void machine_timer_isr_handler(machine_timer_obj_t *self) {
 void machine_timer_enable(machine_timer_obj_t *self) {
     // Initialise the timer.
     timer_hal_init(&self->hal_context, self->group, self->index);
+
+    PERIPH_RCC_ACQUIRE_ATOMIC(timer_group_periph_signals.groups[self->index].module, ref_count) {
+        if (ref_count == 0) {
+            timer_ll_enable_bus_clock(self->index, true);
+            timer_ll_reset_register(self->index);
+        }
+    }
+
     timer_ll_enable_counter(self->hal_context.dev, self->index, false);
+    esp_clk_tree_enable_src(GPTIMER_CLK_SRC_DEFAULT, true);
     timer_ll_set_clock_source(self->hal_context.dev, self->index, GPTIMER_CLK_SRC_DEFAULT);
+    timer_ll_enable_clock(self->hal_context.dev, self->index, true);
     timer_ll_set_clock_prescale(self->hal_context.dev, self->index, TIMER_DIVIDER);
     timer_hal_set_counter_value(&self->hal_context, 0);
     timer_ll_set_count_direction(self->hal_context.dev, self->index, GPTIMER_COUNT_UP);

From 593ae04eeb06b6fd7c6232eb41912b8d26170ddd Mon Sep 17 00:00:00 2001
From: Angus Gratton <angus@redyak.com.au>
Date: Wed, 6 Aug 2025 15:57:38 +1000
Subject: [PATCH 8/8] esp32/machine_timer: Fix machine.Timer() tick frequency
 on ESP32C2,C6.

Also future-proofs this code for other chips. Apart form C6 and C2, all
currently supported chips use APB clock for GPTIMER_CLK_SRC_DEFAULT.

ESP32-C2 uses 40MHz PLL but APB_CLK_FREQ was 26MHz.
ESP32-C6 uses 80MHz PLL but APB_CLK_FREQ was 40MHz.

Implementation now gets the correct frequency from ESP-IDF.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
---
 ports/esp32/machine_timer.c | 24 +++++++++++++++---------
 ports/esp32/machine_timer.h |  9 ++-------
 ports/esp32/machine_uart.c  |  4 ++--
 3 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/ports/esp32/machine_timer.c b/ports/esp32/machine_timer.c
index faa47d59afc1..3fb893aadf1a 100644
--- a/ports/esp32/machine_timer.c
+++ b/ports/esp32/machine_timer.c
@@ -42,11 +42,9 @@
 #include "esp_private/periph_ctrl.h"
 #include "machine_timer.h"
 
+#define TIMER_CLK_SRC GPTIMER_CLK_SRC_DEFAULT
 #define TIMER_DIVIDER  8
 
-// TIMER_BASE_CLK is normally 80MHz. TIMER_DIVIDER ought to divide this exactly
-#define TIMER_SCALE    (APB_CLK_FREQ / TIMER_DIVIDER)
-
 #define TIMER_FLAGS    0
 
 const mp_obj_type_t machine_timer_type;
@@ -54,6 +52,14 @@ const mp_obj_type_t machine_timer_type;
 static mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
 static mp_obj_t machine_timer_deinit(mp_obj_t self_in);
 
+uint32_t machine_timer_freq_hz(void) {
+    // The timer source clock is APB or a fixed PLL (depending on chip), both constant frequency.
+    uint32_t freq;
+    check_esp_err(esp_clk_tree_src_get_freq_hz(TIMER_CLK_SRC, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq));
+    assert(freq % TIMER_DIVIDER == 0); // Source clock should divide evenly into TIMER_DIVIDER
+    return freq / TIMER_DIVIDER;
+}
+
 void machine_timer_deinit_all(void) {
     // Disable, deallocate and remove all timers from list
     machine_timer_obj_t **t = &MP_STATE_PORT(machine_timer_obj_head);
@@ -68,7 +74,7 @@ void machine_timer_deinit_all(void) {
 static void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
     machine_timer_obj_t *self = self_in;
     qstr mode = self->repeat ? MP_QSTR_PERIODIC : MP_QSTR_ONE_SHOT;
-    uint64_t period = self->period / (TIMER_SCALE / 1000); // convert to ms
+    uint64_t period = self->period / (machine_timer_freq_hz() / 1000); // convert to ms
     #if SOC_TIMER_GROUP_TIMERS_PER_GROUP == 1
     mp_printf(print, "Timer(%u, mode=%q, period=%lu)", self->group, mode, period);
     #else
@@ -174,8 +180,8 @@ void machine_timer_enable(machine_timer_obj_t *self) {
     }
 
     timer_ll_enable_counter(self->hal_context.dev, self->index, false);
-    esp_clk_tree_enable_src(GPTIMER_CLK_SRC_DEFAULT, true);
-    timer_ll_set_clock_source(self->hal_context.dev, self->index, GPTIMER_CLK_SRC_DEFAULT);
+    esp_clk_tree_enable_src(TIMER_CLK_SRC, true);
+    timer_ll_set_clock_source(self->hal_context.dev, self->index, TIMER_CLK_SRC);
     timer_ll_enable_clock(self->hal_context.dev, self->index, true);
     timer_ll_set_clock_prescale(self->hal_context.dev, self->index, TIMER_DIVIDER);
     timer_hal_set_counter_value(&self->hal_context, 0);
@@ -236,7 +242,7 @@ static mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n
 
     #if MICROPY_PY_BUILTINS_FLOAT
     if (args[ARG_freq].u_obj != mp_const_none) {
-        self->period = (uint64_t)(TIMER_SCALE / mp_obj_get_float(args[ARG_freq].u_obj));
+        self->period = (uint64_t)(machine_timer_freq_hz() / mp_obj_get_float(args[ARG_freq].u_obj));
     }
     #else
     if (args[ARG_freq].u_int != 0xffffffff) {
@@ -244,7 +250,7 @@ static mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, mp_uint_t n
     }
     #endif
     else {
-        self->period = (((uint64_t)args[ARG_period].u_int) * TIMER_SCALE) / args[ARG_tick_hz].u_int;
+        self->period = (((uint64_t)args[ARG_period].u_int) * machine_timer_freq_hz()) / args[ARG_tick_hz].u_int;
     }
 
     self->repeat = args[ARG_mode].u_int;
@@ -280,7 +286,7 @@ static mp_obj_t machine_timer_value(mp_obj_t self_in) {
         mp_raise_ValueError(MP_ERROR_TEXT("timer not set"));
     }
     uint64_t result = timer_ll_get_counter_value(self->hal_context.dev, self->index);
-    return MP_OBJ_NEW_SMALL_INT((mp_uint_t)(result / (TIMER_SCALE / 1000))); // value in ms
+    return MP_OBJ_NEW_SMALL_INT((mp_uint_t)(result / (machine_timer_freq_hz() / 1000))); // value in ms
 }
 static MP_DEFINE_CONST_FUN_OBJ_1(machine_timer_value_obj, machine_timer_value);
 
diff --git a/ports/esp32/machine_timer.h b/ports/esp32/machine_timer.h
index 10fe2f39c90a..5dd0ce95ac80 100644
--- a/ports/esp32/machine_timer.h
+++ b/ports/esp32/machine_timer.h
@@ -34,13 +34,6 @@
 #include "hal/timer_ll.h"
 #include "soc/timer_periph.h"
 
-#define TIMER_DIVIDER  8
-
-// TIMER_BASE_CLK is normally 80MHz. TIMER_DIVIDER ought to divide this exactly
-#define TIMER_SCALE    (APB_CLK_FREQ / TIMER_DIVIDER)
-
-#define TIMER_FLAGS    0
-
 typedef struct _machine_timer_obj_t {
     mp_obj_base_t base;
 
@@ -64,4 +57,6 @@ machine_timer_obj_t *machine_timer_create(mp_uint_t timer);
 void machine_timer_enable(machine_timer_obj_t *self);
 void machine_timer_disable(machine_timer_obj_t *self);
 
+uint32_t machine_timer_freq_hz(void);
+
 #endif // MICROPY_INCLUDED_ESP32_MACHINE_TIMER_H
diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c
index 661c07138e53..c4dab2cae5c8 100644
--- a/ports/esp32/machine_uart.c
+++ b/ports/esp32/machine_uart.c
@@ -58,7 +58,7 @@
 #define UART_IRQ_RXIDLE (0x1000)
 #define UART_IRQ_BREAK (1 << UART_BREAK)
 #define MP_UART_ALLOWED_FLAGS (UART_IRQ_RX | UART_IRQ_RXIDLE | UART_IRQ_BREAK)
-#define RXIDLE_TIMER_MIN (5000)  // 500 us
+#define RXIDLE_TIMER_MIN (machine_timer_freq_hz() * 5 / 10000) // 500us minimum rxidle time
 #define UART_QUEUE_SIZE (3)
 
 enum {
@@ -535,7 +535,7 @@ static void uart_irq_configure_timer(machine_uart_obj_t *self, mp_uint_t trigger
         self->mp_irq_obj->ishard = false;
         uint32_t baudrate;
         uart_get_baudrate(self->uart_num, &baudrate);
-        mp_int_t period = TIMER_SCALE * 20 / baudrate + 1;
+        mp_int_t period = machine_timer_freq_hz() * 20 / baudrate + 1;
         if (period < RXIDLE_TIMER_MIN) {
             period = RXIDLE_TIMER_MIN;
         }
