How we added interlaced video to Raspberry Pi 5

The very first Raspberry Pi had a composite video output, and all models with a 40-pin header have a display parallel interface (DPI) output. With some external components, DPI can be converted to VGA or RGB/SCART video. Those analogue interfaces are still in demand for retro media and gaming.

Raspberry Pi 5 was a big step up in processing power, but unlike previous models, its DPI block didn’t support interlaced video (which isn’t really part of the DPI standard), so it couldn’t send full-resolution RGB to a CRT television. Until now.

Now with interlace

What is interlaced video?

Early TV systems worked by scanning the image from (usually) left to right, top to bottom. There were tradeoffs between frame rate, resolution, and radio bandwidth demands. With interlace, the frame is divided into odd and even lines. The odd lines are scanned from top to bottom, followed by the even ones. This reduces flicker and improves smoothness without increasing bandwidth. The two parts of each frame are called ‘fields’.

Animation of a Raspberry Pi logo being scanned in progressive and interlaced orders.
Illustration of progressive and interlaced scanning

Analogue TVs don’t need to do anything special to tell which field is which. Provided the horizontal scanning rate is an odd multiple of half the vertical rate, the scan-lines will fall into the right places on the screen. A key feature of interlaced video is that vertical synchronisation pulses can occur in two different phases, relative to the horizontal ones.

The problem to solve

To generate interlaced video, we had to do three things:

  1. Get DPI to emit fields (even or odd lines of a frame-buffer) instead of frames
  2. Time those signals so they will be in the proper arrangement for interlace
  3. Generate appropriate sync pulses

The first part is easy. By changing an address and doubling the ‘stride’ between lines, we can arrange for DPI to read and display just the even or odd lines of a frame-buffer. We use an interrupt to switch back and forth between even and odd fields, 50 or 60 times a second.

The second problem is solved by hacking the DPI peripheral. If we time it just right, we can change its configuration on the fly, so that every second frame — every second field, I should say — gets one extra blank line at the end. The extra line should come after an upper field and before a lower one.

The third problem is harder. RP1’s DPI has no way to make vertical sync pulses start midway through a line.

PIO to the rescue

Like Raspberry Pi’s RP2040 and RP2350 microcontrollers, our RP1 chip has a Programmable Input/Output (PIO) block. It can generate many kinds of real-time waveforms. We recently added PIO support to our version of the Linux kernel, exposing it to device drivers and user programs.

Here, PIO snoops on DPI’s horizontal sync (HSync) and data enable (DE) pins to generate vertical sync (VSync). Two of PIO’s four state machines (SMs) are used: one SM serves as a timer, generating an ‘interrupt’ at the start and middle of each line. The other SM finds the start of the vertical blanking interval (the first line without DE), then counts half-lines to work out when to start and end the VSync pulse. Finally, it samples DE again to detect the extra blank line, to ensure it has the correct field-phase for next time.

Waveforms of PIO inputs and outputs (to generate interlaced VSync).
PIO snoops on HSync and DE to generate VSync; the odd field is shown by fainter waveforms

There are some gotchas: the DE signal must be output on GPIO1, whether it’s used or not. PIO is not synchronised to the DPI clock and its VSync output can jitter up to ±5 ns. That isn’t significant at standard-definition TV rates, but it could be a problem at higher resolutions! Finally, the sync fixup consumes most of RP1’s PIO instruction memory, so PIO can’t be used for other cool things at the same time as generating interlaced DPI.

If you have a Raspberry Pi 5, a VGA666 HAT, and a VGA monitor that can run at 50Hz TV rates, you could test it by adding this to config.txt:

dtoverlay=vc4-kms-dpi-generic
dtparam=clock-frequency=13500000
dtparam=hactive=720,hfp=12,hsync=64,hbp=68
dtparam=vactive=576,vfp=5,vsync=5,vbp=39
dtparam=vsync-invert,hsync-invert
dtparam=interlaced

Make sure you’ve upgraded to the latest Raspberry Pi OS. Note that the above configuration will output DPICLK (which isn’t used) on GPIO0, and DE (which PIO needs to snoop on) on GPIO1, and precludes the use of I2C/DDC on those pins. Other HATs might need a custom overlay, to enable DE output on GPIO1 (where safe to do so).

Composite sync too

VGA cables have separate wires for horizontal and vertical sync, but TVs combine everything in one signal (composite video). A halfway house, used in SCART, is ‘composite sync’, which multiplexes the two sync signals but keeps them separate from RGB.

Most existing SCART HATs have circuitry to generate composite sync, but PIO can do it too! To keep the code size down, it’s not in the kernel driver; sample PIO code can be found here. To test it you’ll most likely need modified hardware, and this time you’ll need a pin control that does not output DE on GPIO1. Select an interlaced video mode, then run the example PIO program with sudo and a few parameters.

Remember that RP1’s DPI can’t generate VSync in interlaced modes. Instead, we get it to output a ‘helper signal’ that alternates between 1-line and 2-line pulses. PIO snoops on HSync and the helper signal to synthesize CSync.

Waveforms of PIO inputs and outputs (to generate Composite Sync with equalizing pulses).
PIO uses HSync and a ‘helper signal’ (modified VSync) to make interlaced CSync

In progressive modes, DPI can generate a normal VSync, so PIO snoops on that instead.

The ins and outs

You might be wondering why PIO can’t completely replace DPI. It’s mostly down to bandwidth and clocking. The DPI block has larger FIFOs and can transfer data across the PCIe link much more efficiently. DPI benefits from a dedicated clock, to generate arbitrary pixel rates. PIO would also struggle with some pixel format conversions.

Fortunately, DPI can take care of the pixels, leaving PIO to fix up the sync signals.

Diagrams showing connections between DPI, PIO and GPIO pins.
Two ways PIO can help DPI: (a) Fix up VSync for interlace; (b) Generate composite sync

The two blocks communicate only through GPIO pins — normally GPIOs 1, 2 and 3.

We hope this helps people to enjoy an authentic retro experience with their favourite television shows and games on a real CRT TV!

The post How we added interlaced video to Raspberry Pi 5 appeared first on Raspberry Pi.



from News - Raspberry Pi https://ift.tt/Kvw1y62

Comments

Popular Posts