Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

ESP32-S3: digitalio open-drain output doesn't work on GPIO45, so bitbangio.I2C fails there

Abierto
#11,669 0 comentarios 0 reacciones 0 asignados Ver en GitHub

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
Stack tecnológico
c, python
Á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_mode reports DriveMode.OPEN_DRAIN on GPIO45 after switch_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

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de adafruit/circuitpython

Todos los issues de adafruit/circuitpython

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.