Skip to the content
PCBKitNew board
4 layers45 × 76 mmPatterngen hw, the printed circuit board in 3D

Patterngen hw

pavels/patterngen

Composite video test pattern generator

Size
45 × 76 mm
Copper layers
4
Thickness
1.6 mm
Parts
60
Nets
74
Pads
256
Tracks, vias
322, 174
Pours
6
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
25 Oct 2026
Updated
25 Oct 2026

Overview

Patterngen hw is an open-source printed circuit board by pavels, from the pavels/patterngen repository on GitHub, published under the BSD-2-Clause licence. It is a 4-layer board of 45 × 76 mm with 60 parts on 74 nets, routed with 322 tracks and 174 vias.

It is built around the RP2040, ADA4432-1BRJZ-R7 and ADV7391BCPZ, with the W25Q128JVSIQ, AMS1117-3.3 and ME6211C18M5G-N among its other parts. Its parts include 24 capacitors, 13 resistors, 6 ICs, 2 connectors and 2 switches. It belongs with the RP2040 boards of this library.

Main components

7

README

README.md

patterngen

Composite video test pattern generator: RP2040 + ADV7391 encoder, PAL and NTSC. It replays the patterns of two classic Philips generators from their original ROM dumps:

  • PM5644 Colour Circle (PAL-G and NTSC)
  • PM5631 multi-pattern generator, all 98 patterns (PAL-G and NTSC)

plus computed test signals named SYNTH ...: multiburst, and an edges demo showing hard and band-limited luma steps, pulses and colour bars side by side.

FolderContent
patterngen-hw/KiCad project: schematic, 4-layer PCB, JLCPCB production files
patterngen-box/3D-printed case (OpenSCAD source and STLs)
patterngen-fw/firmware (PlatformIO + pico-sdk), ROM dumps, converters and pattern data

Hardware

A 45 x 76 mm board, powered and controlled over USB-C:

  • RP2040 with 16 MB flash (W25Q128JVS) holding the pattern data.
  • ADV7391 encoder on a 27 MHz oscillator, fed BT.656 by the RP2040's PIO; CVBS on DAC1.
  • ADA4432-1 output amplifier, 75 ohm, BNC.
  • Two buttons, a status LED, test points RUN (TP1), USB_BOOT (TP2) and GND.

Getting it made

patterngen-hw/production/ has the files for JLCPCB PCB assembly: upload patterngen-hw.zip (Gerbers and drill files) as the PCB, enable assembly, and give it bom.csv (with LCSC part numbers) and positions.csv.

The BNC socket (J1) is not in the BOM; solder it yourself. Its footprint is the common right-angle PCB BNC layout, drawn for the Amphenol B6252HB-NPP3G-50. Any right-angle PCB BNC socket with this layout fits, including cheap generic ones; check the pin layout in its datasheet. A 75 ohm socket matches the cable, but a 50 ohm one works as well: the mismatch is negligible at video frequencies, and is compatible with 75 ohm cables.

Case

Print patterngen-box/patterngen-case-bottom.stl and patterngen-case-top.stl. The board is held by 4 x M3x12 socket head screws from below, screwed into the top half.

Firmware

Building and flashing

PlatformIO with the maxgerhardt/platform-raspberrypi platform and framework = picosdk:

text
cd patterngen-fw
pio run

For the first flash, hold TP2 (USB_BOOT) to GND while powering up and copy .pio/build/patterngen/firmware.uf2 to the drive that appears. Later updates can use picotool or pio run -t upload.

Controls

  • Button 1: next favourite (PM5644 Colour Circle, 15 PM5631 patterns, multiburst; list in src/patterns.c).
  • Button 2: toggle PAL / NTSC.
  • LED: slow blink = running, fast blink = ADV7391 does not answer on I2C.

Serial commands (USB CDC)

CommandFunction
helpcommand list
list / favall patterns of the current standard / button favourites
p <n>, n, bselect pattern n, next, previous
std pal|ntscswitch standard
statuspattern, encoder state, line/frame/late/underrun counters, flash copy time
bars on|offADV7391 internal colour bars
chroma on|offcolour subcarrier in the picture
burst on|offcolour burst
pll on|offencoder PLL (16x oversampling)
reg <r> [v]read/write an ADV7391 register (hex)

Bring-up

  1. Run status. "ADV7391 NOT FOUND": check I2C (GPIO2/3), ~RESET (GPIO0) and the encoder supplies.
  2. bars on shows the encoder's internal colour bars, without the pixel bus.
  3. With a pattern, late and underruns in status must stay at 0. Underruns show as green streaks on black, tearing or unstable sync.
  4. Vectorscope: colour bars (PM5631 2, 11, 12) in the targets; burst at +-135 degrees (PAL) or 180 (NTSC); chroma saw/staircase patterns (PM5631 85, 86, 88, 89) on their stated angles.

Video engine

The ADV7391 runs in SD slave mode with embedded EAV/SAV timing (BT.656, 8-bit 4:2:2), with the 16x oversampling PLL on.

Chroma is trimmed with the encoder's colour scale registers (adv7391_configure()): Cb x 1.039 (0x9E = 0x85), Cr x 1.047 (0x9F = 0x86), Y x 1.0 (0x9D = 0x80), 0x9C = 0x00, then enabled by 0x87 = 0x01. Write the scales before the enable: enabling with a scale still at 0 blanks the picture. Calibrated on a vectorscope in PAL only; another board may need different values.

The PIO program (src/bt656.pio) follows the 27 MHz clock on GPIO1, outputting one byte after each rising edge; the encoder latches it on the next. The RP2040 itself runs at 216 MHz, not locked to it. The data pins are bit-reversed (P7..P0 on GPIO4..11), which the PIO corrects.

src/video.c plays a ring of 8 complete BT.656 lines to the PIO with two chained DMA channels. Core 1 refills each slot 7 lines ahead, reading the active part from flash in one SSI burst per line (27 us). XIP is too slow for this and unavailable during a burst, so the firmware runs from SRAM (copy_to_ram) and only the pattern data stays in flash.

Pattern data

patterngen-fw/data/*.bin are generated from the ROM dumps in patterngen-fw/rom/ (described in patterngen-fw/rom/README.md) and embedded by src/blobs.S. From patterngen-fw/:

text
python3 tools/pm5644_convert.py rom/PM5644G00 rom/PM5644M00 -o data
python3 tools/pm5631_convert.py rom/PM5631G rom/PM5631M -o data
python3 tools/synth_convert.py -o data

--preview also writes PNG images (data/preview/). After changing the blobs, run pio run -t clean before building.

Blob format (tools/pmblob.py, little-endian)
PartContent
header, 32 bytes"PMBL", u16 version = 2, u8 standard (0 = 625/50 PAL, 1 = 525/60 NTSC), u8 reserved, u16 frame_lines, u16 line_bytes (1440), u16 num_lines, u16 num_patterns, u32 patterns_offset, u32 lines_offset, u32 total_size, 4 bytes pad
pattern directory, 56 bytes eachchar name[48], u8 num_frames, 3 bytes reserved, u32 map_offset
mapsu16 [num_frames][frame_lines]: line pool index for frame line n at n-1, 0 = black. Frames alternate every frame.
line poolnum_lines x 1440 bytes of active picture (Cb Y Cr Y), 4-byte aligned; line 0 is black

Credits

This project builds on the Philips test equipment preservation work of inaxeon:

  • PTV_Preservation: the PM5644 and PM5631 ROM dumps in patterngen-fw/rom/, and the GAL fuse map dumps, schematics and service manuals used to work out how the generators read them.
  • PhilipsPatternRom: the reverse-engineered PM5644 ROM format, which tools/pm5644_convert.py re-implements in Python.

License

Copyright (c) 2026 Pavel Sorejs mail@sorejs.eu

  • Firmware, tools and documentation: BSD 2-Clause.
  • Hardware (patterngen-hw/) and case (patterngen-box/): CERN-OHL-P v2, the permissive variant; see the LICENSE file in each folder.
  • Not covered: the Philips ROM dumps in patterngen-fw/rom/ and the pattern data generated from them (patterngen-fw/data/pm56*.bin and their previews). They are Philips' work and are included for preservation.

Parts

60
QtyValueFootprintReferences
10100nFCapacitor_SMD:C_0603_1608MetricC4, C5, C9, C11, C13, C16, C19, C21, C24, C25
51uFCapacitor_SMD:C_0603_1608MetricC1, C10, C18, C26, C27
4MountingHoleMountingHole:MountingHole_3.2mm_M3H1, H2, H3, H4
210nFCapacitor_SMD:C_0603_1608MetricC17, C20
210uFCapacitor_SMD:C_0805_2012MetricC6, C7
215pCapacitor_SMD:C_0603_1608MetricC2, C3
21kResistor_SMD:R_0603_1608MetricR1, R5
222RResistor_SMD:R_0603_1608MetricR6, R7
24k7Resistor_SMD:R_0603_1608MetricR12, R13
25k1Resistor_SMD:R_0603_1608MetricR2, R3
2FerriteBead_SmallInductor_SMD:L_0603_1608MetricFB1, FB2
2GNDTestPoint:TestPoint_Pad_D1.0mmTP3, TP4
2SW_PushButton_Switch_SMD:SW_SPST_TL3342SW3, SW4
112nFCapacitor_SMD:C_0603_1608MetricC22
1150nFCapacitor_SMD:C_0603_1608MetricC23
1169RResistor_SMD:R_0603_1608MetricR11
12.2nFCapacitor_SMD:C_0603_1608MetricC8
1300RResistor_SMD:R_0603_1608MetricR9
1470RResistor_SMD:R_0603_1608MetricR4
14k12Resistor_SMD:R_0603_1608MetricR10
175RResistor_SMD:R_0603_1608MetricR8
1ABM8-272-T3Crystal:Crystal_SMD_3225-4Pin_3.2x2.5mmY1
1ADA4432-1BRJZ-R7Package_TO_SOT_SMD:SOT-23-6U2
1ADV7391BCPZPackage_CSP:LFCSP-32-1EP_5x5mm_P0.5mm_EP3.1x3.1mmU1
1AMS1117-3.3Package_TO_SOT_SMD:SOT-223-3_TabPin2U3
1Conn_CoaxialConnector_Coaxial:BNC_Amphenol_B6252HB-NPP3G-50_HorizontalJ1
1LEDLED_SMD:LED_0805_2012MetricD3
1ME6211C18M5Package_TO_SOT_SMD:SOT-23-5U5
1RP2040Package_DFN_QFN:QFN-56-1EP_7x7mm_P0.4mm_EP3.2x3.2mmU7
1RUNTestPoint:TestPoint_Pad_D1.0mmTP1
1USB_BOOTTestPoint:TestPoint_Pad_D1.0mmTP2
1USB_C_Receptacle_USB2.0_16PConnector_USB:USB_C_Receptacle_GCT_USB4105-xx-A_16P_TopMnt_HorizontalJ3
1W25Q128JVSPackage_SO:SOIC-8_5.3x5.3mm_P1.27mmU6
1XO32Crystal:Crystal_SMD_3225-4Pin_3.2x2.5mmY2

Questions

How big is the Patterngen hw PCB?

It measures 45 × 76 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Patterngen hw use?

60 parts, built around the RP2040, ADA4432-1BRJZ-R7, ADV7391BCPZ and W25Q128JVSIQ. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Patterngen hw KiCad files?

From the pavels/patterngen repository on GitHub, at the commit this page was made from: the board is patterngen-hw/patterngen-hw.kicad_pcb and its schematic patterngen-hw/patterngen-hw.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Patterngen hw design in my own project?

Its repository publishes it under the BSD-2-Clause licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 4 layers100 × 85 mmPAL sign, the printed circuit board in 3D

    PAL sign

    PE5PVB/PAL-sign

    Advanced CVBS PAL video generator

    115 parts2GPL-3.0
  • 2 layers110 × 52 mmArcus, the printed circuit board in 3D

    Arcus

    MeghanaM4/arcus

    Hack Club's Parthenon PCB Badge (with an RP2040 and ePaper display)

    72 parts8
  • 2 layers62 × 47 mmPhoneController, the printed circuit board in 3D

    PhoneController

    gili-yankovitch/joyfon

    Physical Phone Controller

    59 parts7MIT
  • 4 layers279.5 × 97 mmAlpha centauri pcb, the printed circuit board in 3D

    Alpha centauri pcb

    jacob-w-gable/alpha_centauri

    A split, ergonomic, mechanical keyboard with 40 keys, designed for typing speed and comfort.

    224 parts1MIT
  • 4 layers51.1 × 40.7 mmKbd nes v2, the printed circuit board in 3D

    Kbd nes v2

    bchelf/keyboard-nes

    Remapping order: Right, Left, Down, Up, A, B, Select, Start

    53 parts
  • 2 layers65.1 × 60 mmSPROJ3G2 Receiver PCB, the printed circuit board in 3D

    SPROJ3G2 Receiver PCB

    boenike/SPROJ3G2_PRX_PCB

    SPROJ3G2 PRX PCB - KiCad files

    59 partsGPL-3.0
  • 4 layers91 × 91 mmKeymodule revides, the printed circuit board in 3D

    Keymodule revides

    Mosselman/PixelPanel

    Keymodule & pcb design

    123 partsMIT