Skip to content

TinyUSB re-pin fixes ESP32-S2 and S3 REPL race - #11433

Merged
tannewt merged 2 commits into
adafruit:mainfrom
mikeysklar:tusb-repin
Sep 21, 2026
Merged

tannewt merged 2 commits into
adafruit:mainfrom
mikeysklar:tusb-repin

Conversation

@mikeysklar

@mikeysklar mikeysklar commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

What

Moves the CircuitPython TinyUSB pin to current master (441 commits).

Adds one line so nRF52 boards still build.

Why

Pasting more than a few lines into the ESP32-S2 or S3 REPL drops and scrambles characters. TinyUSB fixed it upstream. Might as well re-pin to get the fix.

Link What it is
hathach/tinyusb#3937 the fix, merged 2026-09-21
hathach/tinyusb#1292 the bug report, now closed
#11354 the CircuitPython-side attempt, closed in favour of fixing TinyUSB

CircuitPython changes

Two lines in supervisor/shared/usb/tusb_config.h. Every TinyUSB source file and option CircuitPython uses still exists.

Line Why
+#define nrf52_errata_199 errata_199 newer dcd_nrf5x.c calls it; nordic fails with implicit declaration without it. Same mapping as the three already there. First commit, so every commit builds.
-#define CFG_TUH_VENDOR 0 upstream deleted the vendor host class and the option

Flash cost

All nine boards build clean on both sides with GCC 15.2.1, no new warnings. Bytes free, en_US:

Board main 9701f33a8f this PR 1e55bbdcff delta
metro_m0_express 4236 3964 -272
metro_m4_airlift_lite 16232 15940 -292
feather_nrf52840_express 140648 140040 -608
feather_stm32f405_express 374100 373876 -224
adafruit_metro_rp2040 84532 83740 -792
adafruit_metro_rp2350 124900 124092 -808
raspberry_pi_pico2_w 56928 56136 -792
adafruit_metro_esp32s2 1299536 1298848 -688
adafruit_metro_esp32s3 157392 156688 -704

Hardware tested

All eight farm boards on 10.4.0-alpha.2-26-g1e55bbdcff, Ubuntu 24.04 host.

Board 2000 REPL pastes, corrupted 5 x 64 KB CDC, lost or foreign bytes KB/s MSC write and read-back
Metro ESP32-S2 0 0 64.1 OK, 8 KB
Metro ESP32-S3 0 0 64.0-64.3 OK
Metro M0 Express n/a 0 40.0-40.4 OK
Metro M4 AirLift Lite n/a 0 185.7-187.8 OK
Feather nRF52840 Express n/a 0 92.0-93.5 OK
Feather STM32F405 Express n/a 0 254.0 OK
Metro RP2040 n/a 0 117.7-118.5 OK
Metro RP2350 n/a 0 200.4-201.6 OK

How I tested it

Metro ESP32-S3. 40 test files, 50 times each, through the raw REPL:

### flash repin 2026-09-21T07:43:35-07:00
after: mnt=/media/sklarm/CIRCUITPY2 Adafruit CircuitPython 10.4.0-alpha.2-26-g1e55bbdcff on 2026-09-21; Adafruit Metro ESP32S3 with ESP32S3
### burn repin 2026-09-21T07:46:39-07:00
ESP32-S2: 0 failed iterations of 50, 2000 pastes
ESP32-S3: 0 failed iterations of 50, 2000 pastes

[s3 stress] /media/sklarm/CIRCUITPY2
  before:  Adafruit CircuitPython 10.4.0-alpha.2-26-g1e55bbdcff on 2026-09-21; Adafruit Metro ESP32S3 with ESP32S3
    rep 0: n=65536/65536 bad=0 first_bad=-1 1019 ms first->last = 64.3 KB/s, host write 1019 ms, intact=True
    rep 1: n=65536/65536 bad=0 first_bad=-1 1023 ms first->last = 64.1 KB/s, host write 1023 ms, intact=True
    rep 2: n=65536/65536 bad=0 first_bad=-1 1024 ms first->last = 64.0 KB/s, host write 1024 ms, intact=True
    rep 3: n=65536/65536 bad=0 first_bad=-1 1023 ms first->last = 64.1 KB/s, host write 1023 ms, intact=True
    rep 4: n=65536/65536 bad=0 first_bad=-1 1023 ms first->last = 64.1 KB/s, host write 1023 ms, intact=True
    64k write+read-back OK
### STRESS DONE s3
[s3 restore] /media/sklarm/CIRCUITPY2
  firmware line matches pre-test
  files match backup (23 files)

The 64 KB test, sent over the REPL:

import sys,time,supervisor,os
def run(N):
    c=sys.stdin.read(1)
    t=time.monotonic_ns(); last=t; n=1
    bad=0 if c=='x' else 1
    fb=-1 if c=='x' else 0
    while n<N:
        k=supervisor.runtime.serial_bytes_available
        if k:
            d=sys.stdin.read(min(k,N-n))
            x=d.count('x')
            if x!=len(d) and fb<0:
                fb=n+[i for i in range(len(d)) if d[i]!='x'][0]
            bad+=len(d)-x; n+=len(d); last=time.monotonic_ns()
        elif time.monotonic_ns()-last>2000000000:
            break
    print('GOT',n,(last-t)//1000000,bad,fb)

AI assistance

Claude Code was used. It made the change and ran the builds and farm. I checked the results.

mikeysklar and others added 2 commits September 21, 2026 05:59
nRF52840 and nRF52833. Newer TinyUSB also calls nrf52_errata_199, which
the pinned nrfx does not name. Map it to the MDK errata_199 like the
other three, so the nordic port builds across the TinyUSB bump.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ESP32-S2 and S3. Moves the pin from 5453ed09f1 to 147ccf5e9, the merge
of hathach/tinyusb#3937, which stops pasted REPL input being corrupted.
441 commits:
hathach/tinyusb@5453ed0...147ccf5

Drop CFG_TUH_VENDOR: upstream removed the vendor host class and the
option with it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mikeysklar
mikeysklar marked this pull request as ready for review September 21, 2026 16:03
@mikeysklar mikeysklar changed the title Update TinyUSB so pasted code stops getting corrupted on ESP32-S2 and S3 TinyUSB re-pin fixes ESP32-S2 and S3 REPL race Sep 21, 2026

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Code changes looks fine. I poked the CI

@tannewt
tannewt merged commit 9d73f07 into adafruit:main Sep 21, 2026
1375 of 1382 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants