PicoPOST firmware development
The RP2040 is a very powerful MCU, which allows for some fascinating results in an impressively small form factor. This dual-core ARM Cortex running at 125 MHz (or even more!) hits basically all the sweet spots for making a powerful and flexible PC diagnostic solution.
I've decided to use C++ for this project, despite being "heavier" than pure C, because of some QoL features that simplify a lot of the otherwise hard-wired logic. But hey, at least it's not MicroPython!
The application starts obviously from the
main() function. It doesn't do much other than initializing peripherals, launching the application logic in the second core and start dealing with user interface in the primary core.
This class is instantiated as a singleton, as an extra assurance there can't be multiple objects trying to run the Pico.
When first generated, the constructor initializes the various hardware and firmware facilities required for operation:
- A fail-safe 150 milliseconds startup delay is in place.
When powered by the ISA bus, I2C devices may take some time to stabilize their own power supply, eventually causing the subsequent initialization steps to fail.
- The 1024-place inter-core data queue is initialized.
This queue will be used to send data from the data reader core to the UI task in the other core.
- The primary I2C bus is initialized at 400 kHz.
While both the GPIO expander and the OLED display would be able to scale up to faster clock speeds, we're keeping it slightly more conservative to compensate for lower quality cabling between the PicoPOST main board and the remote.
If your device often fails to correctly set up I2C devices, you may want to tune the bus pull-up resistors on the remote PCB, or you can try lowering the bus clock rate to 200 or even 100 kHz.
- I2C GPIO expander initialization.
PicoPOST will now look for an MCP23009 GPIO expander on the I2C bus. In PCB Rev. 6 and newer, it's a fundamental device, as it's used for the remote keypad and for configuring the display options.
By default, failure to find the GPIO expander will cause a fatal error condition, which results in the Pico halting execution. The Pico's on-board LED will keep flashing constantly with 2 quick flashes.
By enabling the
PICOPOST_SUPPORT_REV5compiler flag, instead of halting, the application will keep loading, defaulting back to the older Rev. 5 keypad style, which uses only built-in Pico's GPIO pins. At the time of writing, the GPIO keypad polling routine has not been implemented, so this option should be avoided at all costs. If you have an older Rev. 5 board, you should be using an older firmware version, like 0.3.0.
- I2C OLED display initialization.
Before starting detection, the configuration pins from the GPIO expander are read to determine how to set up the OLED display. The most important bits are controller type and display size.
By default, if nothing is set, the firmware attempts to initialize an SSD1306 128x32 display. The config pins on the remote PCB can be used to switch the controller type to SH1106 and display size to 128x64.
By default, failure to find the OLED display will cause a fatal error condition, which results in the Pico halting execution. The Pico's on-board LED will keep flashing constantly with 2 quick flashes.
By enabling the
PICOPOST_USB_FALLBACKcompiler flag, instead of halting, the application will keep loading, entering the 80h port reader and outputting meaningful data via the virtual UART exposed via the Pico's own USB port. If no link is detected within 500 milliseconds, the firmware will enter a zombie state, where nothing really happens.
- On-board LED goes steady on!
If all the initialization steps succeeded, the Pico's on-board LED will turn on and the main menu will be shown on the remote.