Experimenting With MicroPython On The Bus Pirate 5

I recently got one of the new RP2040-based Bus Pirate 5 (BP5), a multi-purpose interface debugging and testing tool. Scanning the various such tools in my toolbox already: an Analog Discovery 2, a new Glasgow Interface Explorer, and a couple of pyboards, I realized they all had a Python or MicroPython user interface. A few people on the BP5 forums had tossed around the idea of MicroPython, and it just so happened that I was experimenting with building beta versions of MicroPython for a RP2350 board at the time. Naturally, I started wondering, “just how hard can it be to get MicroPython running on the BP5?”

The Lazy Approach

Rather than duplicating the BP5 firmware functionality, I decided to ignore it completely and go with existing MicroPython capabilities. I planned to just make a simple set of board definition files — perhaps Board Support Package (BSP) is a better term? I’ve done this a dozen times before for development and custom boards. Then write a collection of MicroPython modules to conform to the unique aspects in the BP5 hardware. As user [torwag] over on the Bus Pirate forums said back in March:

Micropython comes already with some modules and enough functions to get some stuff out-of-the-box working. E.g. the infamous version of “hello world” for microcontrollers aka led-blinking.

The Tailoring

The main interfaces to the BP5’s RP2040 MCU were apparently done with the Pico reference design in mind. That is why  you can just load and run the latest RP2 MicroPython build without defining a custom board (note that this only worked with the current v1.24, and failed when I tried to load v1.23 using Thonny,  something I did not investigate further). But there are some things that can be done to tweak the build, so I did go ahead and make set of custom board definition files for the BP5.

First I tried to tell MicroPython about the larger QSPI flash. This is a standard thing in configuring MicroPython, but I found an issue with the RP2. The Pico C SDK has a 2 GiB hard-coded flash limit in a linker script. One can fix this by hand editing and rebuilding the SDK, something I decided to leave for later. So I did all my testing using just 2 GiB of the flash.

Several of the customizations that I would normally make, like the serial interface pins assignments, were not necessary. The customization I did make was for help files. Since the intended application of this project is a manual debugging, I wanted the modules and functions to have help text. By default, MicroPython builds on the RP2 do not enable __doc__ strings, but they can be re-enabled with a compiler directive. Unfortunately, while the __doc__ strings are now retained, the build-in help() function doesn’t print them like CPython. The workaround is to add a help() function to each class. So instead of help(adc) you’t type add.help().

Finally, I wanted to add a board top-level help screen, appending to the existing RP2 port help screen. That turned out to be much harder to do, and in the end, I just gave up doing that in the BP5 board definition folder. Instead, I kludged a couple of files in the RP2 port directory — ugly, but this is just an experiment after all.

The Interfaces

These are the basic interfaces of the BP5 hardware, and all of them are already or easily supported in MicroPython.

  • Eight Buffered IO pins
  • Programmable Power Supply
  • NAND flash 1 Gbit
  • IPS LCD screen, 320 x 240 pixels
  • 18 RGB LEDs
  • Push button

Going for some instant gratification, I decided to drive the chain of LEDs around the perimeter of the unit first. The RP2 port of MicroPython already has a NeoPixel class. Once I sorted out the chained shift register I/O expansion circuitry, I was blinking LEDs in no time. The eight main buffered I/O signals posed a bit more of a challenge, because there are bidirectional logic level translators on each pin. After writing a I/O pin wrapper class around the regular MP Pin class to handle that aspect of the hardware, I realized that wasn’t quite enough.

But the digital I/O signals on the BP5 aren’t useful until you also control the adjustable voltage reference rail. That led to the Power supply class next, which in turn led to the Analog to Digital class to handle ADC operations. To do this, you need to control the analog MUX. And you need to drive the 74HC595 output expander shift register to select the desired analog MUX channel. No more instant gratification.

The shift register was pretty easy, as I have done this before. The only thing I noted was that there is no feedback, so you can’t read the current state. This requires instead that you keep a shadow register of the current output expander state.

Ian Lesnet, former Hackaday writer and creator of the Bus Pirate, did a great job documenting all of these hardware sections of the design. The resulting power supply circuit is quite flexible. In brief, voltage and current control are done using PWM outputs, and actual voltage and current are sensed using the RP2040’s internal ADCs via the MUX. In addition, a programmable current limit threshold triggers a power supply shutdown, which can be overridden or reset as desired.

The Display

The BP5 uses a two inch IPS TFT LCD having 240 x 320 pixel resolution. It is controlled using a Sitronix ST7789 over SPI. Having driven similar setups before from MicroPython, this was pretty easy. At first. I used the ST7789 library by Russ Hughes. The display was up and displaying text and running a few demo examples in short order.

The NAND Flash

Turning attention to the Micron MT29F1G01A 1 Gib (128 MiB) NAND flash next, I ran into some difficulty. Peter Hinch’s memory chip driver library seemed like a good start. But this chip isn’t on the list of already tested chips. I changed the scan function to recognized the Micron ID manufacturer’s byte codes, but after configuring the correct chip size, sector size, and block size parameters, it still didn’t work. After finally asking for help, Mr Hinch explained that my problem was the large 138 KiB block size of this chip. His library buffers one entire block, and 138 KiB is just too big for most microprocessors.

He pointed me to a non-buffered SPI block device driver by Robert Hammelrath. I tried this briefly, but gave up after a few hours because I was spending too much time on this chip. This is a solvable problem, but not strictly needed for this goals of this experimental project.

The Images

Speaking of wasting time, I spent way too much time on this part of the project. Not because it was necessary, but just because it was just cool. My idea was a pong-like demo where an icon moves around the screen, rebounding off the screen edges. These LCD screen driver chips use a packed pixel format, RGB565. I found a tool on GitHub called rgb565-converter which converts PNG images to and from RGB565 format in C++ format. I forked and heavily modified this to generate Python code as well, in addition to 4-bit grayscale format as well. The animated GIF shows this in action.

The Wrap-up

I enjoyed making this project, and learned a few more things about MicroPython along the way. I knew that the STM32 and the ESP8266 / ESP32 families had been supported by MicroPython almost since the beginning, and that the Pico RP2040 was a relative newcomer to the ecosystem. But I was surprised when I stumbled on this talk by founder Damien George about the history of the project at the 2023 PyCon Australia conference. He shows some statistics collected over 8 years of downloads broken down by microprocessor family. The RP2040 has been extremely popular since its introduction, quickly surpassing all other families.

MicroPython Monthly Downloads by MCU Family, provided by [Damien George]
This project presented a few frustrating issues, none of which would be showstoppers if this approach were to be developed further. I continue to be impressed by the number of people in the MicroPython community who have developed a wide variety of support libraries and continue to work on the project to this day.

Which begs the question, does the idea of MicroPython on the Bus Pirate even make sense? The existing C-based Bus Pirate firmware is now well established and works well for its intended purpose — quick explorations of an interface from the command line. Would a alternate MicroPython build benefit the community or just waste people’s limited development hours?

There could be some way to create an MicroPython implementation without duplicating a lot of code. The existing BP5 firmware could be treated as a library, and compiled with various C to MicroPython shim functions to create an extensively customized build. That is beyond my MicroPython experience for now, but it might be worth consideration.

Bus Pirate 5

Another way would be just build a set of “big Python” classes to represent the BP5 on the desktop. This module would talk to the BP5 using the existing serial / USB port protocol, potentially requiring no firmware modifications at all. This seems like a good idea in general, since it allows users to easily script operations from the desktop using Python, and still retain the original capabilities of the BP5 in standalone operation.

The code for this project and associated documentation can be found here on GitHub. You can build your own binary if you want, but one is provided in the repository. And as [torwag] said back in March, you can just run the factory RP2040 MicroPython as well. In my testing, the only thing you’ll miss are the help messages.

If you want to learn more about MicroPython, visit their website and GitHub repository. Pre-built binaries are available for many standard development boards, and instructions on building it for a custom boards are quite clear and easy to follow. I’ve heard rumors that docker containers may be available soon, to make the building process even easier. Visit the Bus Pirate website and corresponding GitHub repository to learn more about the latest Bus Pirate 5 project.

Hackaday’s own Tom Nardi did an extensive hands-on review of BP5 upon its release the release of the Bus Pirate 5 back in February. Also Arya Voronova has written several articles on MicroPython, including this one on the eleventh anniversary of the project. Do you use MicroPython? What’s your take on the idea of using it with the Bus Pirate 5?

2 thoughts on “Experimenting With MicroPython On The Bus Pirate 5

  1. I know “constomizations” was probably a spelling mistake, but I rather like the idea of a portmanteau of constant and customization being the initial changes you always make to a particular device.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.