PM_G-1: fix I2C init on the pull-up-less Scroll Pack (busio+internal-pulls, bitbangio fallback)

The Pico Scroll Pack has no external I2C pull-up resistors (Pimoroni's C++ uses the
RP2040 internal pulls), so busio.I2C raised 'No pull up found on SDA or SCL' and the
firmware crashed before the splash. _make_i2c() now pre-enables the internal pull-ups
for busio and falls back to bitbangio (which uses them inherently). Pins GP4/GP5 were
correct.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-31 21:53:45 -05:00
parent 4afac44d06
commit 67182cd74c

View file

@ -279,9 +279,28 @@ LETTERS = {
} }
# ============================== APP ============================== # ============================== APP ==============================
def _make_i2c():
# The Pico Scroll Pack has NO external I2C pull-up resistors - it relies on the RP2040's
# *internal* pull-ups (Pimoroni's C++ calls gpio_pull_up()). CircuitPython's busio.I2C
# refuses with "No pull up found on SDA or SCL" unless those internal pulls are on, so:
# 1) pre-enable the internal pull-ups on the pads, then try the fast hardware busio;
# 2) if that still won't init, fall back to bitbangio, which drives the lines using the
# internal pulls inherently (slower, but always works on a pull-up-less board).
try:
for p in (P_SDA, P_SCL):
d = digitalio.DigitalInOut(p); d.switch_to_input(pull=digitalio.Pull.UP); d.deinit()
except Exception:
pass
try:
return busio.I2C(P_SCL, P_SDA, frequency=400_000)
except Exception as e:
print("busio I2C unavailable (%s) - using bitbangio" % e)
import bitbangio
return bitbangio.I2C(P_SCL, P_SDA, frequency=400_000)
class App: class App:
def __init__(self): def __init__(self):
self.i2c = busio.I2C(scl=P_SCL, sda=P_SDA, frequency=400_000) self.i2c = _make_i2c()
while not self.i2c.try_lock(): pass # the firmware owns the matrix bus for its lifetime while not self.i2c.try_lock(): pass # the firmware owns the matrix bus for its lifetime
self.mtx = Matrix(self.i2c) self.mtx = Matrix(self.i2c)
self.midi = usb_midi.ports[1] if (MIDI_ENABLED and usb_midi and len(usb_midi.ports) > 1) else None self.midi = usb_midi.ports[1] if (MIDI_ENABLED and usb_midi and len(usb_midi.ports) > 1) else None