Use Emulation to Run RP2 PIO Code on Other Ports
The RP2 chip's PIO peripheral is a powerful piece of hardware capable of performing tasks that might otherwise require very fast bit-banging code, but it's also quite difficult to validate the correctness of a complicated PIO program as this code can then "only" be run on real hardware.
I'm planning to implement a library that's API-compatible with the rp2.StateMachine interface, to allow other ports to run PIO programs via emulation. I don't know if this can ever allow practical real-time I/O on any of the microcontroller ports; my primary use-case is to enable using the unix port to run test cases involving PIO functionality.
Given that initial goal, I intend to implement this by wrapping the rp2040-pio-emulator python package. A later stab at this idea might re-implement it in C later, if someone can figure out a path to doing this in real-time on microcontroller hardware.
Forked: https://github.com/AJMansfield/micropython-lib
Of course, this will miss a lot of what makes the PIOs really work: cycle accurate timing, the ability to lock multiple PIOs together with synchronized clocks, etc. It seems that for a lot of the uses, the PIOs are pretty special (and good!) and that a lot of the protocol applications for them depend on these features.
Still, an interesting project.
Of course, this will miss a lot of what makes the PIOs really work: cycle accurate timing, the ability to lock multiple PIOs together with synchronized clocks, etc. It seems that for a lot of the uses, the PIOs are pretty special (and good!) and that a lot of the protocol applications for them depend on these features.
Still, an interesting project.
Really the main thing I'm hoping to accomplish with the library is a way to extend my TDD workflow to include tests of the PIO programs and associated drivers -- just that since I'm going to the effort, I might as well try to make it usable on real hardware, too.
I've already got a small set of hacked-together mocks for some of micropython's machine peripherals (Pin, I2C, etc), so that I can run my test cases directly on my development machine (and inside my CI/CD pipelines) -- and maybe that can become its own library for me to publish at some point.
But even if emulation can't match real time performance for any but the slowest clock dividers, my test code would already be injecting a time-travel mock anyway (i.e. an alternative implementation of time whose tick values only advance when test code tells them to).