Pi Pico projects
ECE 4760 Cornell University
rp2040/2350
rp2040/2350 Microcontrollerprogramming using C-SDK
The C-SDK is open source, has good examples and is very well documented.
The C-SDK directly supports PIO assembly language and the many interesting co-processors available in the Pico..
The instructor for ece4760, Van Hunter Adams, has produced many interesting C applications for the Pico, as well
as open-source lectures.
My projects are broken down by category below.
ece4760 Support
General utilities and information relevant to ece4760 at Cornell.
Startup Message with compile information (SDK 2.1)
Several C environment variables are parsed and printed.
Information includes C file name, compile time/date, C SDK version, and
target board name.
Protothreads (written by Adam Dunkels)
All examples and student code are written using the Protohreads framework for multitasking.
Protothreads 1.4 (SDK 2.1 or higher) for rp2040 and rp2350
This version uses the SDK 2.1 mutex and semaphore implementations for core-safe
communication between threads. It is NOT backwards compatable in those constructs.
It has been tested on the rp2040 and on the rp2350 to 300 MHz. BUT use carefully and please report bugs to Bruce.
Protothreads 1.3 (SDK 1.5) mod for rp2040 and rp2350 by Bruce (used 2024-2025)
A port to the rp2040/2350, extended for two cores with support for hardware locks, core-safe semaphores, and core-to-core hardware FIFOs.
Protothreads provides a simple, cooperative, thread environment with very fast context switch and low memory overhead.
Modified thread dispatcher implements priority scheduling in addition the default round-robin.
Three simple protothreads 1.3 examples. (and a couple of more advanced examples)
One blinky thread on one core; two threads on one core, three threads on two cores, with signaling.
Advanced examples: spawning a thread, locking a variable, priority scheduler.
Graphicsand GUIs
Graphics input and output using 640x480 VGA, possibly with optional joystick or encoder wheel.
A mouse interface is also shown in the USB section.
The serial interface is not really graphics, but plays around with color and formatting.
VGA 16-color 640x480 (LWIP compatable, protothreads 1.4, SDK 2.1.1)
Adding classic IBM VGA-437
font, and boldface for the 5x7 font.
An extension of Hunter's PIO VGA driver from 3-bit color to 4 bit color, with Protothreads.
Two bits of green allows more shades of blue and red, and adds orange.
VGA 16 640x480 3D perspective polygon render. (SDK 2.0, rp2350 version)
The rp2350 version can render many more polygons than the 2040 (see below).
To demo this, a larger parametric surface is rendered with 400 triangles.
3D polygons are rendered in perspective by full 4D matrix transforms. VGA 16-color 640x480 3D Polygon Perspective viewer. (SDK 1.50, rp2040 version)
3D polygons rendered in perspective by full 4D matrix transfroms.
VGA 256 color 319x240. (LWIP compatable, SDK 1.5, protothreads 1.3, PIO bug fix)
An extension of Hunter's PIO VGA driver for 8 bit color.
Three bits of green, three bits of red, and two bits of blue.
Serial command interface
Modern serial terminal emulators can produce a good looking user interface.
PuTTY emulates VT100 control code for color, cursor control,
and limited
graphics
Joystick and encoder wheel with VGA
A simple analog joystick with select button, and a digital encoder wheel with direction and selector buttons.
Mouse controlled graphics.
See USB HID examples below.
External Memory
Everyone needs more memory. FRAM works well for simple files with bandwidth
requirments below about 1.5 Mbyte/sec.
SD card with FatFS has a larger program size overhead, but is compatable with PC read/write of huge files.
USB FLASH drives are exzplained the the USB MSC example below.
LWIP on PicoW
LWIP is the supported TCP/IP stack for the PicoW. LWIP has lots of options and somewhat limited documentation.
This section has lots of examples to exercise some of the options.
Opotions include bringing up the PicoW as an WIFI access point or WIFI station and
data transfer by UDP or TCP.
WIFI setup.
The physical considerations and software necessary for WIFI.
NTP and RTC clock using LWIP and vga16_v2 (SDK 2.1.1, protothreads 4, pico W)
The
LWIP and VGA16 both use significant hardware. With care they are compatable and run at the same time.
The NTP
can be used to automatically set the rp2040 RTC, perhaps daily, to maintain accuracy.
The Pico board clock oscillator is rated at ±30 ppm, or accuracy of 3x10-5.
Since there are 86400 seconds/day, this means up to 2.6 sec/day drift.
Daily setting seems reasonable, unless you need time accuracy better than one second.
This example does not work with rp2350 because the 2350 has no RTC. But see below for AON timer vesion.
NTP and AON clock using LWIP and vga16_v2 (SDK 2.1.1, protothreads 4, pico2 W)
Like te example above, this uses NTP to set a local clock, in this case the AON timer.
I believe, but have not tested, that the AON SDK notices whether you are using pico or pico2
and correctly sets either the RTC on the 2040 or the AON on the 2350.
Data array UDP send/receive (station to station thru hotspot)
Sending an array of data allows performance testing as well as understanding of data sizes, and dealing with packet efficiency.
UDP send/receive from desktop (station to station thru hotspot)
UDP
protocol is a simple and fast, but does little error checking. It is therefore useful for data streams where a bad value is not a show stopper. You might send music but not code.
UDP send/receive pico-to-pico. (station to station thru hotspot)
A simple scheme for figuring out IP addresses on the fly allows two picos to send data to each other.
USB host on Pico
USB uses the tinyUSB implementation and is fairly big.
There are lots of ways to use it. Examples are your friend.
Amusing (to me) computational projects
These may have little general appeal, although the DMA computing machine could be a co-proessor.
DMA computing machine.
The DMA subsystem is capable of running a compute-universal system.
This implementation uses three channels for fetch/execute, and a list of DMA control blocks as a program.
Random number generation.
Using the ROSC to make reasonable quality random numbers. Routines for integers, fixed-point uniform and normal distributions, and for single bits.
Note that this page may be obsolete with the addition of TRG routines in C SDK 2.1.1,
BUT
the DMA based TRG here is very fast.
Lattice-Boltzmann fluid flow simulation
A strange hybrid of finite difference and cellular automaton using fixed point arithmetic for speed.
The fixed point system used is s1x25. The shorter, and faster, 16-bit fixed point did not have enough precision for stable solutions.
There is a floating point version
in the Arithmetic section below.
16-bit floating point,
with similar bit layout to the IEEE standard FP16, but without infinities or NANs.
The reason for doing this annoying exercise is to see if ODE solvers run faster in limited precision floating point than in fixed point.
The 16-bit floats have a dynamic range similar to s15x16 fixed point, but are not faster then standard 32-bit floats.
Arithmetic Systems
The rp2350 has hardware floating point instructions, as well as an improved integer multiplier and divider.
The integer multiplier now produces a full 64 bit result from a 32x32 multiply. This speeds up the fixed point multiply by about a factor of 5.
The pare includes ome test programs attempt to estimate the speed of the operations.
Video below compares float to fix for Mandelbrot set.
DSP
More numerical flogging of the M0 architecture, with an emphisis on speed using 16-bit fixed point.
The IIR and FIR sections use design implementations which run completely in C on the the M0, at the
cost some slightly non-optimal designs.
IIR filter designer
Using s1x14 fixed point format. Lowpass, bandpass, and highpass filters design.
Plots the Bode plot of the designed filter, and allows the new filter to be used in realtime for audio input.
(rp2040).
FIR filter designer
Using s1x14 fixed point format. Lowpass, bandpass, and highpass filters design.
Plots the Bode plot of the designed filter, and allows the new filter to be used in realtime for audio input.
Also a version for linear frequency plots. (rp2040).
Speech compression/playback from IIR filterbank.
Speech sampled at 12.8 Ksample/sec is sent through 32 MEL-distibuted IIR filters.
The filter powers are sampled every 20 mSec and used to reconstruct speech using DDS.
(rp2040).
FFT Spectrogram
Plotting the power spectrum, log power spectrum, and spectrogram of voice signals.
The spectrogram actually has enough info to decode what is being said.
DSP development
IIR filters in fixed point s7x24 format. Butterworth lowpass and bandpass filter.
Sound Synthesis
Since we can do DSP, can we use it to make sounds we might actually want to listen to.
FM synthesis is very 1970's synth kind of sound.
The Karplus-Strong algorithm actually solves the wave equation on a stirng in realtime to make
physically reasonable stringed instrument sounds.
FM synthesis of sounds.
Some FM synthesis even sounds like music.
Widely used in the 1970's, '80s, and even into the 90's. for music and sound effects.
Karplus-Strong strings
Plucked and bowed string physical synthesis.
An approximation of the actual PDE of a string. (fixed point on rp2040)
Gravitational system in floating point on rp2350.
Gravity is a long-range force, so the force computations are O(n2) in the
simplest implementation get big quickly. The example animates 150 gravitating particles
at about 140 frames/sec or 300 at 30 frames/sec. (floating point on rp2350 only)
PIO
Using Verilog to understand the rp2040 PIO processors. The Pi rp2040 microcontroller has 8, single cycle, deterministic, Programmable i/o blocks (PIO). Each PIO is programmed using a 9-instruction assembly language. We have been speculationg about how you make a single-cycle machine (including jump). This project attemptes to answer that, without implementing the entire PIO architercture.
rp2040 PIO control
Experiments to see if modifing the code of a running PIO channel is feasable.
Implementing a input capture ability.
To emulate the precise time stamp feature found on AVR and PIC32
With two PIO state machines, you can get single cycle capture resolution.