I’ve been having some fun with the Raspberry Pi Pico and Circuitpython thanks to Mark Hughes and the Teach Me PCB course that he’s putting on at the moment. For whatever reason, I decided it would be cool to iterate on my word clock design. I’m not done yet, but I am making sure to struggle along the way. Here’s a problem I had with the Pico I wanted to share in case someone else does what I did:
TLDR: Don’t pull some? pins high without first configuring them as input or output in your code. Go to fix
This is what I did:
Wire the clock up – 3v to VCC, GND to GND, GP16 to SDA, GP17 to SCL (just like this guy did).
Power it back up – immediately windows says there is something wrong with my device.
Symptoms:
- Windows makes a sad dingle noise and says there is something wrong with the device
- Device manager shows a device with “device descriptor request failed”
- Replacing the driver doesn’t help
- Same problem if you plug the Pico into another computer
- Your code doesn’t run
- No serial port (naturally, USB isn’t working)
- Power up with the BOOTSEL button held down does work, and allows loading UF2 files
- Re-loading a circuitpython or micropython UF2 doesn’t change the behavior
- Undoing the wiring doesn’t make the problem go away
- Flashing the Pico with the Arduino framework and using C++ still works
It was a struggle to troubleshoot (I bricked 4 Picos before I found out how to recover them), although I admit I didn’t read the entire datasheet before embarking on this quest. I narrowed in on the cause by removing variables until I had only the RTC and Pico connected directly with wires. I found:
- With only GND and VCC connected, there are no issues
- If you plug the SCL and SDA in while the Pico is running, it is not interrupted, no problem
- If you boot the Pico with SCL and SDA connected, all the bad things happen
- Note at this point I have not added any code to configure GP16 and GP17, I am assembling the circuit first
What is the cause?
I noticed that the DS3231 module I’m using pulls SCL and SDA high when it is powered, this seems to be a key part of my problem. Initially I thought the flash was somehow being corrupted, but after making lots of guesses with help from the folks on the TMPCB Discord, on a hunch I tried setting my pins as inputs and bingo, no more problems. This could be correct, or could be a red herring, more important is how to recover.
What I think is happening is that during boot, if you leave these pins undefined and pull them high, it interrupts things after your code has started running but before the USB is initialized. In this state you don’t have a USB disk to update the code with, nor a serial port to figure out what’s up. Even switching to bootloader mode and replacing the Circuitpython UF2 file doesn’t help. It’s possible that this is a code-only problem, but it suspicious that it was reproducible by connecting the GPIOs.
I think this page and the note on line 28 here explain a similar problem, but I am using different pins.
I found a reference to this “nuke” file in a forum post, here’s the description in the FAQ sheet and a link to the file:
Here’s what to do:
- Hope that you saved a copy of your code and libraries on your computer (you did, right?)
- Download the flash_nuke.uf2 file
- Connect the Pico to USB, hold the BOOTSEL switch while doing this to enter bootloader mode
- Copy the nuke file to the Pico drive
- Pico should reboot into bootloader mode again
- Copy the Circuitpython or Micropython or whatever UF2 to the Pico drive
- Pico should reboot in the usual mode now, copy your code and libraries
- Next time configure the pins before building and powering the circuit
Thanks:
These links for clues:
https://nahog.medium.com/raspberry-pi-pico-dead-serial-5f57e622020f
https://forums.raspberrypi.com/viewtopic.php?t=314269
https://forums.adafruit.com/viewtopic.php?f=60&t=174992
https://github.com/adafruit/circuitpython/issues/4034
Wokwi for a screenshot
And to my pals from the TMPCB course for all the ideas.