ESP32-S3: digitalio open-drain output doesn't work on GPIO45, so bitbangio.I2C fails there
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 48/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Área
- embedded-iot
Línea de trabajo
Start with the GPIO handling in ports/espressif/common-hal/digitalio/DigitalInOut.c and the open-drain release and read sequence in shared-module/bitbangio/I2C.c. Reproduce the reported difference on GPIO45 with the supplied digitalio script, then trace the lower-level ESP32-S3 GPIO behavior. Done means open-drain transactions on GPIO45 work as they do on GPIO0, without breaking the reported working cases.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
CircuitPython 10.3.1 on an ESP32-S3 (M5Stack AtomS3R: espressif_esp32s3_devkitc_1_n8r8, and a local m5stack_atoms3r build). The board's internal I2C bus is SCL GPIO0 / SDA GPIO45 with external pull-ups, a BMI270 at 0x68 and an LP5562 at 0x30.
Symptom: bitbangio.I2C(GPIO0, GPIO45) finds both devices with scan() (at 100 kHz and 10 kHz), but writeto and writeto_then_readfrom raise [Errno 5], and readfrom_into returns 0xFF. busio.I2C on the same pins works (with CIRCUITPY_I2C_ALLOW_STRAPPING_PINS), so the wiring and pull-ups are fine.
Narrowed: the same transaction bit-banged with digitalio, changing only how a line is released. "-od" = the way shared-module/bitbangio/I2C.c does it: an open-drain output set to 1, switched to input and back to read (sda_read, and scl_release's clock-stretch check).
| SCL (GPIO0) released by | SDA (GPIO45) released by | Result |
|---|---|---|
| switching to input | switching to input | works: chip ID 0x24 |
| open-drain output (with the input round trip) | switching to input | works |
| switching to input | open-drain output (with the input round trip) | address ACKed, register byte NACKed, read 0xFF |
| open-drain output | open-drain output | the same failure (bitbangio's way) |
The identical open-drain sequence works on GPIO0 and fails on GPIO45 (a strapping pin), on both builds, repeatably.
Two more observations:
DigitalInOut.drive_modereportsDriveMode.OPEN_DRAINon GPIO45 afterswitch_to_output(drive_mode=OPEN_DRAIN), before and after the input round trip (same as GPIO0, 5 and 6), so the requested mode does read back.- The address byte is ACKed in every variant; the failure begins after the first input → open-drain round trip on SDA (reading the ACK, then going back to an open-drain output set to 1).
ports/espressif/common-hal/digitalio/DigitalInOut.c is pin-agnostic (gpio_set_direction(GPIO_MODE_OUTPUT | GPIO_MODE_OUTPUT_OD)), so the cause looks to be below it; I haven't found it. Seen on one board (one AtomS3R), so I can't say whether every ESP32-S3's GPIO45 does this.
Repro (save as code.py; output above):
# Repro: digitalio open-drain output fails on ESP32-S3 GPIO45 (so bitbangio.I2C fails there). Save as code.py on an
# M5Stack AtomS3R (internal I2C: SCL GPIO0, SDA GPIO45, external pull-ups; BMI270 at 0x68, chip ID register 0x00 = 0x24)
# and read the serial console. Each run bit-bangs "read the BMI270's chip ID" with digitalio; a line in an "-od" mode is
# released the way shared-module/bitbangio/I2C.c does it (open-drain output set to 1, switched to input and back to
# read). Seen on CircuitPython 10.3.1 (espressif_esp32s3_devkitc_1_n8r8, and an m5stack_atoms3r build):
# input / scl-od-roundtrip: acks (True, True, True), chip id 24
# sda-od-roundtrip / both-od-roundtrip: acks (True, False, True), chip id ff
import digitalio, microcontroller as mc
OD = digitalio.DriveMode.OPEN_DRAIN
def run(mode):
scl = digitalio.DigitalInOut(mc.pin.GPIO0); sda = digitalio.DigitalInOut(mc.pin.GPIO45)
od = {"scl-od-roundtrip": (scl,), "sda-od-roundtrip": (sda,), "both-od-roundtrip": (scl, sda), "input": ()}[mode]
for p in od:
p.switch_to_output(value=True, drive_mode=OD)
def rel(p):
if p in od:
p.value = True
p.switch_to_input(); p.value; p.switch_to_output(value=True, drive_mode=OD) # bitbangio's round trip
else:
p.switch_to_input()
def low(p):
if p in od: p.value = False
else: p.switch_to_output(value=False)
def rd(p):
p.switch_to_input(); v = p.value
if p in od: p.switch_to_output(value=True, drive_mode=OD)
return v
def wbyte(v):
for i in range(8):
(rel if v & (0x80 >> i) else low)(sda); rel(scl); low(scl)
rel(sda); rel(scl); ack = not rd(sda); low(scl); return ack
def rbyte():
rel(sda); v = 0
for _ in range(8):
rel(scl); v = (v << 1) | rd(sda); low(scl)
rel(sda); rel(scl); low(scl); return v
rel(scl); rel(sda); low(sda); low(scl)
acks = (wbyte(0x68 << 1), wbyte(0x00))
rel(sda); rel(scl); low(sda); low(scl)
acks += (wbyte((0x68 << 1) | 1),)
v = rbyte()
low(sda); rel(scl); rel(sda)
scl.deinit(); sda.deinit()
print("%-18s acks %s chip id %02x" % (mode, acks, v))
for m in ("input", "scl-od-roundtrip", "sda-od-roundtrip", "both-od-roundtrip", "input"):
run(m)
- Lenguaje dominante
- C
- Estrellas
- 4.6k
- Forks
- 1.4k
- Merge medio
- 1 d 8 h
- PR fusionados (30 d)
- 158
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de adafruit/circuitpython
-
bug
Dificultad 4/5 1-2 días Aptitud para principiantes 35/100
adafruit/circuitpython#11641 ·
Los mantenedores suelen responder en 1 día
-
Web Workflow Locks UpAbiertobug esp32 web workflow
Dificultad 5/5 Más de una semana Aptitud para principiantes 12/100
adafruit/circuitpython#11616 · 9 comentarios ·
Los mantenedores suelen responder en 1 día
-
nordic
Dificultad 4/5 3-5 días Aptitud para principiantes 30/100
adafruit/circuitpython#11611 ·
Los mantenedores suelen responder en 1 día
-
zephyr: REPL on console?Abierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 15/100
adafruit/circuitpython#11606 ·
Los mantenedores suelen responder en 1 día
-
busio zephyr
Dificultad 5/5 Más de una semana Aptitud para principiantes 18/100
adafruit/circuitpython#11605 ·
Los mantenedores suelen responder en 1 día
Todos los issues de adafruit/circuitpython
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
HexaCluster/credcheck#86 ·
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
AOMediaCodec/SVT-AV1#3320 ·
-
Add `CPC_TAKE_TILL_CHARS`Abiertodifficulty: easy
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
-
ML-KEM: OQS_KEM_encaps/decaps cannot do the FIPS 203 length (type) checks; please document itAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
open-quantum-safe/liboqs#2647 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
Los mantenedores suelen responder en 1 día