Cornell University ECE4760
VGA 640x480, 16-color, version 2
Pi Pico RP2040/2350
VGA 4-bit color
Here we use Hunter Adam's VGA driver, specifically this example, but slightly modified for 4-bit rather than 3-bit color. The extra bit is used to make four green levels. Of course, the extra bit means that a 2-bit DAC is required for the green channel. The rgb.pio assembler program had to be slightly modified, and the drawPixel routine had to be recoded. A few extra text drawing routines were added to VGA_graphics_v2.c and VG_graphics_v2.h.
-- This version works with both 2040 and 2350 because main sets the clock to a standard 150 MHz.
--
This VGA version is compatable with LWIP for tcp/ip networking.
-- It also uses Protothreads 1.4 with options for roundrobin or priority scheduler.
The VGA implementation uses:
-
PIO state machines 0, 1, and 2 on PIO 0;
the three state machine need to be on one PIO instance, so they are
unconditionally hard-claimed.
Initialize
VGA before other libraries!
- DMA channels determined by the dma_claim_unused_channel routine
(this is to conform to the protocol ued by LWIP for DMA channels)
- 153.6 kBytes of RAM (for 640x480 pixel, 4-bit, color data)
The blue and red VGA lines are driven directly through 330 ohm resistors, as in Hunter's implementation.
The VGA-green connection requires two resistors connected to the VGA-green line
If you don't like my color balance for bits on the green channel, try varying the 470 ohm resistor.
- GPIO 16 ---> VGA Hsync
- GPIO 17 ---> VGA Vsync
- GPIO 18 ---> VGA Green lo-bit --> 470 ohm resistor --> VGA_Green
- GPIO 19 ---> VGA Green hi_bit --> 330 ohm resistor --> VGA_Green
- GPIO 20 ---> 330 ohm resistor ---> VGA-Blue
- GPIO 21 ---> 330 ohm resistor ---> VGA-Red
- RP2040 GND ---> VGA-GND
Performance is good. The drawPixel routine takes about 0.43 uSec (125 MHz on 2040)
So you can draw about 2.3 million pixels/sec, or around 38,000 pixels per 60 Hz frame.
This translates to about 1000-2000 small chars per frame depending on whether you use one color or two. Small bold will be about half that rate. The large VGA437 characters will draw 300-600 characters per 60 Hz frame. If you decide to hack one of the fonts, I suggest using the bigger 8x16 format because the file format is easier to understand. The 8x16 font allows 80 characters per line, and 30 lines of text.
In the image and video below, I made an attempt to show all of the available drawing commands, coupled to an example of what they draw.
Refer to the VGA16_graphics_v2.h for a complete list of all graphics routines and their parameters.
There are two functions which are invoked via a serial interface to erase and restart the graphics.
The text routines enable boldface for default 5x7 text and a new(old) 8x16 font VGA437 from the earliest days of IBM personal computers (~1982).
Demo Code
With animated shapes, and
with 5x7 bold, 8x16 Big font (VGA437), and color palette
Fonts Code
Adafruit glcdfont.h
VGA437 font_rom.h
My mods to VGA437 font_rom_brl4.h
ZIP of project
Note that this project is using Protothreads 1.4 (priority scheduler).
The video works on either pico or picoW, but the LED blinking only works on pico.
Copyright Cornell University May 22, 2025