This repository contains bits and pieces that I made while trying to figure out how the Raspberry Pi Pico state machines and the Programmable Input/Output (PIO) work.
Here I have written down the reusable 'tricks' I use in several of the projects listed below.
The following projects are contained in this repository:
The problem with the state machines is that debuggers do not give the insight I need when writing code for a sm. I typically write some code, upload it to the pico and find that it doesn't do what I want it to do. Instead of guessing what I do wrong, I would like to see the values of e.g. the registers when the sm is executing. So, I made an emulator.
This is just an example of two state machines running independently. Nothing special about it, but I had to do it.
This is an example of two state machines running independently, but one gets disabled temporarily.
This is an example of two state machines synchronized via setting and clearing an irq, one gets disabled temporarily.
This is an example of a state machine using DMA (Direct Memory Access) to write into a buffer.
This is an example where one state machine writes via DMA to another state machine whose output is put into a buffer via another DMA channel.
The RP2040 Datasheet states that "State machines can not communicate data". Or can they ... Yes they can, in several ways, including via GPIO pins.
Normally if the ISR shifts via the IN
instruction, the bits that come out of the ISR go to cyber space, never to be heard from again. Sometimes it is handy to have rotational shifting. Right shifting works fine, but left shifting needs some trickery.
This code reads a 4x4 button matrix using PIO code for the Raspberry Pico and returns the button pressed.
When using a GPIO to read noisy input, such as a mechanical button, a software debouncer makes sure that only after the input signal has stabilized, the code will read the new value.
Most microcontrollers have hardware to produce Pulse Width Modulation (PWM) signals. But sometimes it is useful to be able to read PWM signals and determine the period, pulse width and duty cycle.
This software reads an optical rotary encoder with very clean signals on its output using PIO code.
This code reads the HC-SR04, an ultrasonic distance measurement unit.
This code is my take on how to control a ws2812 led strip with 120 pixels
This code multiplies two numbers.
I wanted to see how I could use two pio programs in one file and use them from within the c/c++ program, see here.
This code is a pio implementation of the 1-wire protocol.
This code is a remake of the wonderfull little thingy made by Paul Dietz: blow on a LED to make it go out! Really!
This code can be used for protocols where the data is encoded by a number of pulses in a pulse train followed by a pause. E.g. the LMT01 temperature sensor uses this, see.
This code shows that subroutines in pioasm can be a thing and can - in some cases - be used to do more with the limited memory space than is possible with just writing the code in one program.
The SBUS protocol is typically used in Radio Controlled cars, drones, etc. If you want to read this protocol from a RC receiver in order to manipulate the data before setting motors and servos, you can use this code.
This code shows how a pio state machine can drive led panels. It is made for two 64x64 led panels connected to form a 64 row x 128 column panel. There are 16 brightness levels for each Red, Green and Blue of each pixel, allowing many colors. In its present form it updates the panel at about 144 Hz at standard clock settings (=125MHz.)