Microcontrollers have begun to rival early PCs and retro gaming consoles in measures like speed and memory capacity, and even leapfrog them with new capabilities like multiple cores and wireless connectivity.  One area that still seems a bit lacking is video output.  Sure, the ability to connect a smallish LCD via i2c or SPI is normal, but can these little marvels do more?  With a little spicier circuit, I think so...

And, in fact, we know so: Wren6991 successfully bitbanged DVI on the RP2040 [ https://github.com/Wren6991/PicoDVI ] and validated the output up to 372Mbps (good enough for HD 720 @ 30Hz).  That leaves some resolution milestones unxplored, for example FHD 1920 x 1080 @ 60Hz (1080p) x 24 bit color depth (i.e. 8 bits for each of the red, green, and blue subpixels, aka RGB888) = 2.985984Gbits/second not including control signals and blanking overhead -- approaching an order of magnitude larger.  Back to Wren6991: the CPU cycles for QVGA (320 x 240) consume 60% of one of the RP2040's two M0+ cores, i.e. around 30% of its total processing power, so that means there's only headroom to about triple the processing rate.  Maybe with a very aggressive overclock it could get in the ballpark, but it seemed like, considering we have up to 30 GPIO pins to play with and DVI's Transition Minimized Differential Signalling (TMDS) encoding uses only 6 pins, there had to be a way of using the 32-bit width to help escape the bottleneck.  The RP2040's M0+ cores can execute 1 32-bit move instruction in 1 clock cycle, which means that if all 30 GPIO pins were tasked with sending this output, the theoretical maximum output from an ideal 1 core x 1 ipc code x 30 pins x 133Mhz 'normal' clock speed is around 3.99Gbits/second, although GPIOs are needed for other functions and some processing is necessary to work out what to send (and note that only 26 GPIO pins are exposed in the RPi Pico).  I considered an overclock and a Ghz-speed capable shift register, specifically the very interesting MC100EP142FA.  I considered a reduced color bit depth, like RGB565 or RGB666.  Ultimately, it sememed like an RGB to HDMI encoder would be the best idea to offload the encoding functions, and one can be had cheaper than the ultra-fast shift registers.

Another problem: with only 260KB of RAM onboard, how would the RP2040 store even a single frame that is 1920 x 1080 x 24 bits/pixel = 49,766,400 bits / 8 bits/byte = 6.220800 MB?  Display protocols require the frame transmitted many times per second.  Clearly the RP2040 needs another ic in the mix: external RAM >= 49.7664Mbits.  With this, the RP2040 could store the entire desired output for the current frame at all times, which frees the RP2040 from 'forgetting' and redrawing sections of each frame, i.e. it only has to deal with pixels that need to be updated and it can write those updates into memory over time, sending the current state of the frame in memory each time the video protocol needs a frame.  The best part about an independent memory chip is that the RP2040 doesn't necessarily need the data returned to it (supposing the use case doesn't require acting upon the existing frame, but simply overwriting it).  The RP2040 only needs to send the RAM the address of the next batch of pixels, which the RAM can then make available to the HDMI encoder/transmitter between their respective outputs and inputs.

When considering different RAM module options: static RAM (SRAM) would have the least timing hassles, but becuase they are often 16- or 8-bit (and exclusively so from JLCPCB at the time of working out the circuit; 24-bit options were available at Digikey), you would potentially need multiple RAM 'ranks' to alternate between to keep your reads continuous and have time to write.  Dynamic RAM (DRAM/SDRAM) has more timing overhead considering the refreshes DRAMs require, but there are some inexpensive options in the right size,...

Read more »