LED Matrix Schematic question/odd power up behavior

I made a external housing for input modules, with a USB hub. I’ve tested it, and it works great for both my custom modules (based on the “microcontroller input module” in the framework git repo, as well as one based on the LED Matrix schematics on the git repo) and the framework keyboard. However, when I insert the stock framework LED module, I get unusual behavior: the input module is stuck in RPi bootloader mode, and won’t start up the actual application code.

Flipping the dip switches doesn’t have an effect, and I can insert the card into my framework chassis and it boots up fine. It also enumerates correctly on USB…just as the bootloader device. You can upload new firmware to it, but when it restarts it still stays in bootloader mode.

Some googling I’ve done indicates that the RP2040 getting stuck in bootloader mode can be due to unstable power supplies that glitch the RPi during startup, but in my case this happens during warm boot as well. I’ve commented out all the code related to the --bootloader option in the led Matrix firmware, and the same thing happens, but it’s possible we’re getting into the application code and panicking and the rust runtime is switching us to bootloader mode?

I’m wondering if someone from framework (@nrp?) could tell me if there are any hardware differences on the production led Matrix card, that aren’t in the published amitech schematic, which could lead to this behavior. (It’s known that the published schematic doesn’t match the production module in at least some respects: it is missing a connection for the SLEEP pin.) Are the sleep or board ID pins wired up in some way which could cause this behavior if my external enclosure doesn’t provide them in exactly the same way the FW16 does?

I’ve also tested the LED Matrix against the framework “spring adapter” development card, which framework was kind enough to supply me with, and it works correctly there. The primary differences between my enclosure and the spring adapter are: (a) I have a USB hub upstream so I can supply more than one set of pogo pins, (b) the sleep pin is wired up to the hub suspend signal in what may be a bogus way (but testing on the spring adapter card with the sleep switch set in all different ways doesn’t seem to reproduce this behavior), (c) board ID is left floating, and (d) the 3.3v supply is fed from a 200mA regulator instead of the 600mA regulator on the spring adapter (but I’ve disconnected my on-board regulator and replaced it with a beefy bench 3.3v supply without causing a difference in behavior).

The schematic for my external enclosure PCB on github.

Can anyone offer some ideas on why the production LED Matrix card is getting stuck in bootloader mode? Even just confirming that the wiring of the BOOTSEL, SLEEP, and BOARD_ID pins on the production LED Matrix module matches the Amitech schematic would help me eliminate some possibilities as I try to debug this.

Ok, removing the line from the USB hub’s PGANG output to /SLEEP (and letting it float!) seems to have fixed the issue with the LED matrix card. I don’t fully understand /why/, so if someone at Framework could offer some hints about how /SLEEP and QSPI_* are connected on the production LED Matrix board that would cause /SLEEP to trigger the bootloader I’d appreciate it. It can’t “just” be connecting /SLEEP to GPIO0, because I do that on my seven-segment display input module as well and that doesn’t trigger this anomalous behavior. Anyway, I’m curious.

But in the meantime, I’m pretty sure this can be solved in v2 of my external enclosure PCB, where SLEEP is under software control. So I’m unblocked.

1 Like

I think when you power on the modules before power has ramped up. the SLEEP gpio on the module side will be pulling this low due to the internal body diode on the RP2040.

I would guess that this either sets PGANG low on U3. Or provides enough power to start running the RP2040 through gpio leakage.

Try changing R12 to something like 50K.
Sometimes devices like U3 will sample the PGANG pin by pulling it high, low, float, to see if there is an external pullup/pulldown on boot as well. so PGANG may be driven high during U3 init, instead of just being pulled up.

The part I don’t understand is how /anything/ I would do to GPIO0 would affect bootloader mode, especially on a warm boot. IE, it comes up in bootloader mode and I can upload new firmware to the RPI USB drive, and it will usually warm boot into the new firmware right away. But with GPIO0 tied to PGANG that lands you back into bootloader mode and I don’t understand how that could happen. Some weird interaction between PGANG and the USB hub during initialization after warm boot, I guess, causes RP2040 startup to land back in the bootloader instead of executing the firmware.

I’ll try a 50k resistor there and see if it changes anything.