# Using DVI Video in CircuitPython

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/138/049/medium800/lcds___displays_Untitled.png?1751303886)

Modern versions of CircuitPython display a small purple Blinka snake and some initial information when you see the REPL on a microcontroller connected display. This isn't just a cutesy way to put a mascot on your screen. It's a window into using CircuitPython on displays with both REPL information and user information.

![](https://cdn-learn.adafruit.com/assets/assets/000/138/473/medium800/feather_20250716_191349.jpg?1752711500)

CircuitPython calls using the display in the same node as the REPL the CircuitPython Terminal. It seems like a handy mode, especially for displaying text (which I want to do in a game I'm porting).

This guide aims to be a centralized information on how to use DVI/HDMI displays with CircuitPython.

## What can you do with larger displays?
![](https://cdn-learn.adafruit.com/assets/assets/000/138/474/medium800/feather_Untitled.png?1752711806 A one inch OLED display common in smaller projects vs. a 7 inch HDMI display with many times more pixels.)

Historically, user output to screens with microcontrollers have involved small TFT, OLED, or eInk displays.

With larger displays, this opens up the world to:

- Advanced User Interfaces
- Games
- Classic Computer Emulation
- Small Standalone Computers
- Kiosks and Controllers
- More Pixels Makes More Pretty Colors

While a microcontroller will not replace a full laptop or desktop, it can do some tasks previously done by computers.

# Using DVI Video in CircuitPython

## DVI vs. HDMI

![](https://cdn-learn.adafruit.com/assets/assets/000/138/154/medium800/lcds___displays_dvi.png?1751845199)

## What is DVI?

The video that most folks generate using Raspberry Pi RP2xxx microcontrollers over the HSTX bus is technically not HDMI, it is Digital Visual Interface (DVI). It was designed in 1999 to give a better quality video at higher resolutions than VGA and Super VGA.

Note: Some folks generate analog VGA on RP2xxx microcontrollers.. That is not covered in this guide.

To maintain compatibility with VGA, the DVI standards mandate a "low pixel format" display mode: VGA 640x480 pixels @ 60 Hz with a pixel clock frequency of 25 MHz.

There are higher resolutions in the DVI standard up to 2560x1600 (single link).

DVI was phased out on computers around 2010 in favor of HDMI and DisplayPort.

DVI cables do not carry audio or other signals, only video. There is analog DVI but this guide is only looking at digital DVI. There are adapters to change the connector above to an HDMI connector on the market, but it's much more likely you'll find monitors with HDMI connectors.

## What is HDMI?
![](https://cdn-learn.adafruit.com/assets/assets/000/138/079/medium800/lcds___displays_hdmi.png?1751320561)

High-Definition Multimedia Interface&nbsp;(HDMI) was introduced in 2003 and surpassed DVI in transmitting video to both computer displays and consumer devices. HDMI is electrically compatible with DVI video signals, and&nbsp;adapters allow interoperability between the two without signal conversion or loss of quality. This includes HDMI supporting a 640x480 digital mode from DVI. It is this compatibility that is utilized to display DVI video on HDMI devices (as HDMI displays, televisions, etc. are predominant in the market today).

The HDMI standard has audio lines defined for cabling, etc. But note that DVI to HDMI cables, for example, do not put audio into the HDMI cable.

As most folks have display(s)/television(s) with HDMI input. It makes it an ideal way to connect to those devices. And the DVI backwards compatibility allows for low cost devices like RP2xxx microcontrollers to generate digital DVI video.

## Connectors
![](https://cdn-learn.adafruit.com/assets/assets/000/138/108/medium800/lcds___displays_hdmi_2.png?1751404001)

HDMI cables typically have the plug shown under the HDMI heading above with devices having a socket as shown directly above. The cables are ubiquitous and easily obtained from many retail outlets.

The Adafruit devices capable of DVI video will have the socket above, either on the PC board (Fruit Jam) or via an HSTX to DVI adapter board.

### HDMI Cable - 1 meter

[HDMI Cable - 1 meter](https://www.adafruit.com/product/608)
Connect two HDMI devices together with this basic HDMI cable. It has nice molded grips for easy installation, and is 1 meter long (about 3 feet). This is a HDMI 1.3 cable.

We're now stocking a very fancy Official Raspberry Pi cable with overmolding and a Pi logo. Please note...

In Stock
[Buy Now](https://www.adafruit.com/product/608)
[Related Guides to the Product](https://learn.adafruit.com/products/608/guides)
![Official Raspberry Pi HDMI Cable - 1 meter](https://cdn-shop.adafruit.com/640x480/608-03.jpg)

And for Feather, Metro, and Raspberry Pi Pico boards with a HSTX Cowbell, don't forget the cable and DVI adapter:

### Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays

[Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays](https://www.adafruit.com/product/6055)
You may have noticed that our [RP2350 Feather](https://www.adafruit.com/product/6000) has an FPC output connector on the end&nbsp;for accessing the HSTX (High Speed Transmission)&nbsp;peripheral. This new capability, not available on the RP2040, is specifically designed to allow the...

In Stock
[Buy Now](https://www.adafruit.com/product/6055)
[Related Guides to the Product](https://learn.adafruit.com/products/6055/guides)
![black, square-shaped breakout board with DVI and 22-pin FPC connectors connected to a black, rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/6055-01.jpg)

## What do I call this video then?
Technically **the video being generated is DVI** , going over the RP2xxx HSTX port. The cabling between the female socket on the project and the display or television is an HDMI cable. The display will most likely accept it as there is backwards compatibility for digital DVI in the HDMI standard.

**Many folks just call it HDMI,** but note that audio is not being transmitted over the cable. There are audio inserters to add external audio but they can add cost to the process. Most projects will have a separate DAC for audio for headphones or a speaker, such as the Fruit Jam.

**When the display resolution is below 640 horizontal pixels** , CircuitPython will look to double or quadruple the number of pixels to get it to at least 640 so it can be displayed over HDMI per the backwards compatibility with DVI.

**This guide will continue to call it DVI** , but note that the cable going between the board and the display and the display itself are labeled HDMI.

# Using DVI Video in CircuitPython

## Adafruit Hardware

Currently DVI video in CircuitPython is limited to only a few Adafruit products using Raspberry Pi RP2040 and RP2350 chips. These chips have the speed and resources to output the large amount of data required in a DVI video stream.

## Adafruit Metro RP2350
The Adafruit Metro RP2350 has an HSTX connector which connects via a ribbon cable to an Adafruit RP2350 22-pin HSTX to DVI Out breakout. Both have 16MB of QSPI flash memory for a great deal of static storage.

![HSTX Connection to DVI](https://cdn-learn.adafruit.com/assets/assets/000/138/071/medium800/lcds___displays_gaming_hstx.png?1751309032 An Adafruit Metro RP2350 connected to a DVI breakout via HSTX using a ribbon cable)

The Metro RP2350 comes in two PSRAM variants:

- [Without PSRAM](https://www.adafruit.com/product/6003) (shown above)
- [With 8MB (64 Mbit) PSRAM](https://www.adafruit.com/product/6267) (same as above but with a chip on the PSRAM footprint)

The version with the PSRAM chip can provide additional RAM space which may be needed for higher video resolutions.

## Adafruit Fruit Jam
![](https://cdn-learn.adafruit.com/assets/assets/000/138/443/medium800/feather_6200-09a.jpg?1752675469)

The [Adafruit Fruit Jam](https://www.adafruit.com/product/6200 "Fruit Jam") is an upcoming product based on the Raspberry Pi RP2350B microcontroller. It has a DVI connector on the top so no adapter from HSTX is needed. The Fruit Jam comes with the same 16 MB Flash and 8 MB external PSRAM as the augmented Metro RP2350 for more flexible storage.

## Adafruit Feather RP2350
![](https://cdn-learn.adafruit.com/assets/assets/000/138/074/medium800/lcds___displays_WIN_20250630_14_28_45_edit.jpg?1751311806)

The Feather RP2350 comes in two PSRAM variants:

- [Without PSRAM](https://www.adafruit.com/product/6000) (shown in picture)
- [With 8MB (64 Mbit) PSRAM](https://www.adafruit.com/product/6130) (chip goes on PSRAM footprint)

The version with the PSRAM chip can provide additional RAM space which may be needed for higher video resolutions.

## Adafruit Feather RP2040 with DVI Output Port
![](https://cdn-learn.adafruit.com/assets/assets/000/138/109/medium800/lcds___displays_rp2040dvi.png?1751405834)

[The Feather RP2040 with DVI](https://www.adafruit.com/product/5710) uses the older RP2040 and has the DVI/HDMI connector on-board. Due to memory limitations on the RP2040, only lower video resolutions like 320x240 should be used.

## Boards for use with the Raspberry Pi Pico, Pico 2 and other Pi microcontroller boards
![](https://cdn-learn.adafruit.com/assets/assets/000/138/480/medium800/feather_b.png?1752849638)

The [Adafruit PiCowBell HSTX DVI Output for Pico](https://www.adafruit.com/product/6363) connects, via header pins, to a Raspberry Pi Pico 2 / 2W (using the RP2350 microcontroller). It connects the RP2350 HSTX pins to the HDMI connector for DVI video. It also has USB Host pins broken out in the center. If you have a Pico 2 or Pico 2W, this is the board you want to add video capabilities.

There are a couple more ways you can add DVI output:

### Adafruit DVI Breakout Board - For HDMI Source Devices

[Adafruit DVI Breakout Board - For HDMI Source Devices](https://www.adafruit.com/product/4984)
We designed this little breakout board after seeing [some cool demos for the Raspberry Pi Pico driving an HDMI display](https://github.com/Wren6991/PicoDVI). By using some fun 'abuse' of overclocking and the RP2040's PIO system a low-cost microcontroller can have great...

In Stock
[Buy Now](https://www.adafruit.com/product/4984)
[Related Guides to the Product](https://learn.adafruit.com/products/4984/guides)
![Video of DVI breakout board on breadboard with Raspberry Pico RP2040 hooked up with jumper wires. A small HDMI monitor displays a psychedelic animation with Raspberry Pi logos and bouncing middle-aged white man bust of Raspberry Pi founder. ](https://cdn-shop.adafruit.com/product-videos/640x480/4984-04.jpg)

### Adafruit DVI Sock for Pico - Works with HDMI Displays

[Adafruit DVI Sock for Pico - Works with HDMI Displays](https://www.adafruit.com/product/5957)
Wouldn't it be cool to display images and graphics directly from your Pico or Pico W&nbsp;to an HDMI monitor or television? We think so! So we designed this **DVI Sock** with a digital video output (a.k.a DVI) that will work with any HDMI monitor or display. Note it...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5957)
[Related Guides to the Product](https://learn.adafruit.com/products/5957/guides)
![Video of an HDMI monitor displaying an aquarium animation.](https://cdn-shop.adafruit.com/product-videos/640x480/5957-01.jpg)

These boards can be soldered to a Pico or wired to a Pico or Pico 2 board to provide the same DVI capabilities as the Adafruit Feather RP2040 with DVI.

Note: these are **not** for the Raspberry Pi single board computers (Raspberry Pi 1, 2, 3, 4, or 5) as the Raspberry Pi single board computers already have HDMI video on-board.

## Other Parts
For DVI out on the Metro RP2350 and the Feather RP2350, you'll need one of the cables below and the HSTX to DVI adapter board.

### Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays

[Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays](https://www.adafruit.com/product/6055)
You may have noticed that our [RP2350 Feather](https://www.adafruit.com/product/6000) has an FPC output connector on the end&nbsp;for accessing the HSTX (High Speed Transmission)&nbsp;peripheral. This new capability, not available on the RP2040, is specifically designed to allow the...

In Stock
[Buy Now](https://www.adafruit.com/product/6055)
[Related Guides to the Product](https://learn.adafruit.com/products/6055/guides)
![black, square-shaped breakout board with DVI and 22-pin FPC connectors connected to a black, rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/6055-01.jpg)

### 22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX -  5cm

[22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX -  5cm](https://www.adafruit.com/product/6034)
Connect this to that when a 22-pin FPC connector is needed. This 5 cm long cable is made of a flexible PCB. It's A-B style, meaning that pin one on one side will match with pin one on the other. How handy!

[We're stocking this to fit...](https://www.adafruit.com/category/360)

In Stock
[Buy Now](https://www.adafruit.com/product/6034)
[Related Guides to the Product](https://learn.adafruit.com/products/6034/guides)
![Angled shot of 5cm long, 22-pin FPC cable.](https://cdn-shop.adafruit.com/640x480/6034-00.jpg)

### 22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 10cm

[22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 10cm](https://www.adafruit.com/product/6035)
Connect this to that when a 22-pin FPC connector is needed. This 10 cm long cable is made of a flexible PCB. It's A-B style, meaning that pin one on one side will match with pin one on the other. How handy!

[We're stocking this to...](https://www.adafruit.com/category/360)

In Stock
[Buy Now](https://www.adafruit.com/product/6035)
[Related Guides to the Product](https://learn.adafruit.com/products/6035/guides)
![Angled shot of 10cm long 22-pin FPC cable.](https://cdn-shop.adafruit.com/640x480/6035-00.jpg)

### 22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 20cm

[22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 20cm](https://www.adafruit.com/product/6036)
Connect this to that when a 22-pin FPC connector is needed. This 20 cm long cable is made of a flexible PCB. It's A-B style, meaning that pin one on one side will match with pin one on the other. How handy!

[We're stocking this to...](https://www.adafruit.com/category/360)

In Stock
[Buy Now](https://www.adafruit.com/product/6036)
[Related Guides to the Product](https://learn.adafruit.com/products/6036/guides)
![Angled shot of 20cm long, 22-pin FPC cable.](https://cdn-shop.adafruit.com/640x480/6036-00.jpg)

### Enclosure for the Adafruit Feather RP2350 with HSTX

[Enclosure for the Adafruit Feather RP2350 with HSTX](https://www.adafruit.com/product/6305)
Here is a cute and minimal enclosure for your [Adafruit Feather RP2350 with HSTX Port](https://www.adafruit.com/product/6130)&nbsp;(or the [version with 8MB of PSRAM](https://www.adafruit.com/product/6130))&nbsp;to keep it safe during use and transport. This case has been...

In Stock
[Buy Now](https://www.adafruit.com/product/6305)
[Related Guides to the Product](https://learn.adafruit.com/products/6305/guides)
![Demo Shot of the RP2350 Case.](https://cdn-shop.adafruit.com/640x480/6305-03.jpg)

### HDMI Cable - 1 meter

[HDMI Cable - 1 meter](https://www.adafruit.com/product/608)
Connect two HDMI devices together with this basic HDMI cable. It has nice molded grips for easy installation, and is 1 meter long (about 3 feet). This is a HDMI 1.3 cable.

We're now stocking a very fancy Official Raspberry Pi cable with overmolding and a Pi logo. Please note...

In Stock
[Buy Now](https://www.adafruit.com/product/608)
[Related Guides to the Product](https://learn.adafruit.com/products/608/guides)
![Official Raspberry Pi HDMI Cable - 1 meter](https://cdn-shop.adafruit.com/640x480/608-03.jpg)

# Using DVI Video in CircuitPython

## Supported Screen Resolutions

![](https://cdn-learn.adafruit.com/assets/assets/000/138/430/medium800/lcds___displays_140.jpg?1752610272)

## Resolutions

Widely supported resolutions are (width x height):

- 320x240 with pixel doubling and color depth 8, 16, or 32 bits per pixel
- 640x480 with color depth 1, 2, 4 or 8 bits per pixel

For a limited number of displays:

- 360x200 with pixel doubling and color depth 8, 16, or 32 bits per pixel
- 720x400 with color depth 1, 2, 4 or 8 bits per pixel

Not supported at the moment:

- 800x480 with color depth 1, 2, 4 or 8 bits per pixel

Info: Larger resolutions and higher bit depths require more memory on the microcontroller board. The RP2040 has limited memory (264K total). The RP2350 has more (520K + PSRAM if present). RP2350 boards with PSRAM are recommended for large screens, big fonts, and/or complex graphics.

The default value, if unspecified, is 360x200 16 bits per pixel if the connected display is 1920x1080 or a multiple of it, otherwise 320x240 with 16 bits per pixel.

Output resolution support varies between the RP2040 and RP2350 microcontrollers. Per the [picoDVI documentation](https://docs.circuitpython.org/en/latest/shared-bindings/picodvi/index.html):

## RP2040

On RP2040, two output resolutions are currently supported, 640x480 and 800x480. Monochrome framebuffers (color\_depth=1 or 2) must be full resolution. Color framebuffers must be half resolution (320x240 or 400x240) and pixels will be duplicated to create the signal.

## RP2350

On RP2350, output resolution is either 640x480 or 720x400. Monochrome framebuffers (color\_depth=1 or 2) must be full resolution. 4-bit color must also be full resolution. 8-bit color can be quarter, half or full resolution. 16-bit color and 32-bit color must be quarter or half resolution due to internal RAM limitations.

## Pixel Depth

The framebuffer pixel format varies depending on color depth:

- 1 - Each bit is a pixel. Either white (1) or black (0).
- 2 - Each two bits is a pixel. Grayscale between white (0x3) and black (0x0).
- 4 - Each nibble is a pixel in RGB format. The fourth bit is ignored. (RP2350 only)
- 8 - Each byte is a pixel in RGB332 format.
- 16 - Each two bytes is a pixel in RGB565 format.
- 32 - Each four bytes is a pixel in RGB888 format. The top byte is ignored.

Warning: Note that the 720x400 and 360x200 resolutions are not supported by a majority of older or smaller displays. A display may show an error or just refuse to change to that resolution.

# Using DVI Video in CircuitPython

## Monitor Display Capabilities

![](https://cdn-learn.adafruit.com/assets/assets/000/138/429/medium800/lcds___displays_1667-00.jpg?1752605061)

Not all monitors can handle displaying data in every resolution you might see in the display world. Some gorgeous HDMI display might handle 1600x900 at 144Hz refresh rate for gaming. But that same monitor might not be able to display 720x400 resolution graphics as the circuitry inside just doesn't allow it.

While we think every monitor is robust enough to handle whatever video we throw at it, it just isn't so.

Warning: Not all HDMI monitors support all DVI and HDMI resolutions

## Extended Display Identification Data
The Extended Display Identification Data (EDID for short) standard was developed by industry to help computers figure out if the display can support certain resolutions. Just like Windows changing screen resolutions, there is a list of resolutions to choose from and likely that list was obtained from the monitor's EDID.

In each monitor that supports EDID is a chip accessible by I2C via DVI/HDMI and later display standards. One can simply look to see if device 0x50 is on that I2C bus and if so, read the data structure defined by the standard.&nbsp;

With the EDID data, a program can try to set the graphics to a particular resolution to use or give a message that the resolution the program wants isn't one the display can support.

## CircuitPython and EDID

CircuitPython does check a monitor's EDID to check for 640x480 and 720x400 ([here](https://github.com/adafruit/circuitpython/blob/fa4caf835ff194c7c8ba4dede7caf69e5f011602/ports/raspberrypi/common-hal/picodvi/ __init__.c#L46)). But the EDID information for all modes is not available to a CircuitPython program via a library (yet). But a user's program can do the same thing. I whipped up this program based on the CircuitPython&nbsp;`picodvi` library and a bit of Claude parsing of the EDID standard. It displays what modes are available on a given monitor.

Info: Just because a monitor can display certain resolutions, it is likely CircuitPython cannot match all those resolutions. Given factors including memory, microcontroller speed, and code support, likely any resolution over 720x400 is not supported, although in time perhaps more resolutions might be available.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/Find_EDID_Values.py

And the output for the small HDMI/VGA/Composite display on my work table:

```terminal
]0;🐍code.py | 10.0.0-alpha.8\
I2C Present
Device 0x50 found!
Valid EDID signature!
Good EDID checksum!

Supported Display Modes (21 found):
==================================================
  720x400 @70Hz
  640x480 @60Hz
  640x480 @72Hz
  640x480 @75Hz
  800x600 @56Hz
  800x600 @60Hz
  800x600 @72Hz
  800x600 @75Hz
  832x624 @75Hz
  1024x768 @60Hz
  1024x768 @70Hz
  1024x768 @75Hz
  1280x1024 @75Hz
  1152x864 @75Hz, Aspect: 4:3
  1280x720 @60Hz, Aspect: 16:9
  1280x1024 @60Hz, Aspect: 5:4
  1280x1024 @70Hz, Aspect: 5:4
  1280x1024 @76Hz, Aspect: 5:4
  1440x900 @60Hz, Aspect: 16:10
  1440x900 @75Hz, Aspect: 16:10
  1280x800 @59Hz

Default resolution: 640x480
Preferred resolution: 1280x800

Done!
```

## HDMI to USB Capture
![](https://cdn-learn.adafruit.com/assets/assets/000/138/503/medium800/feather_b.png?1753048030)

The [Adafruit PID 4669 video capture device](https://www.adafruit.com/product/4669) provides the following EDID responses:

Supported Display Modes (15 found):

==================================================

- 640x480 @60Hz
- 800x600 @60Hz
- 1024x768 @60Hz
- 1024x768 @70Hz
- 1024x768 @75Hz
- 1280x1024 @75Hz
- 1280x800 @60Hz, Aspect: 16:10
- 1280x960 @60Hz, Aspect: 4:3
- 1280x1024 @60Hz, Aspect: 5:4
- 1400x1050 @60Hz, Aspect: 4:3
- 1440x900 @60Hz, Aspect: 16:10
- 1600x1200 @60Hz, Aspect: 4:3
- 1680x1050 @60Hz, Aspect: 16:10
- 1280x720 @60Hz
- 1280x768 @59Hz

Default resolution: 640x480 Preferred: 1280x720

The device does not like the 640x480 @72Hz the Fruit Jam with CircuitPython currently outputs, but will display the 320x240 mode and 720x400 mode.

Your monitor(s) likely will have a different list of supported resolutions.

# Using DVI Video in CircuitPython

## Fonts

Many CircuitPython projects use the built-in `terminalio.FONT` font provided by CircuitPython itself.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/138/113/medium800/lcds___displays_terminalio-FONT_32_a.jpg?1752085589 The terminal.FONT built into CircuitPython. The large number of periods indicate that no glyph is available for that character number.)

There is a period in the table where a non-printable character is located. Basically, `terminalio.FONT` contains a limited character set of what might be found on a US keyboard.

## Font File Types
There are several font types that can be used with CircuitPython. Some have better support than others, so keep this in mind when choosing.

### BDF

The&nbsp;[**Glyph Bitmap Distribution Format**](https://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format)&nbsp;(BDF) by&nbsp;Adobe&nbsp;is a file format for storing&nbsp;bitmap fonts. The content takes the form of a text file intended to be human- and computer-readable. It has largely been replaced by the&nbsp;PCF&nbsp;font format which is somewhat more efficient.

BDF fonts in CircuitPython tend to load slower than PCF files and they render text slower as the character representations must be converted at runtime to a bitmap.

### PCF

[**Portable Compiled Format**](https://en.wikipedia.org/wiki/Portable_Compiled_Format)&nbsp;(PCF) is a binary bitmap font&nbsp;format. They are generally similar to BDF fonts as far as capability, but the file format being binary they tend to be smaller and load quicker than BDF font files.

Check out the guide below for information on BDF and PCF fonts:

### Custom Fonts for CircuitPython Displays - Overview

[Custom Fonts for CircuitPython Displays](https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display)
[Overview](https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display/overview)
### LVGL

Support for LVGL fonts is "the latest" added to CircuitPython. They should be in binary format with a **.bin** file extension.

The `OnDiskFont` function should be used when opening these files,&nbsp;documented&nbsp;[here](https://docs.circuitpython.org/en/latest/shared-bindings/lvfontio/index.html).

You can convert TTF files to LVGL using the web utility [here](https://lvgl.io/tools/fontconverter).

See an issue with use of fonts in the CircuitPython Terminal on [GitHub](https://github.com/adafruit/circuitpython/issues/10448).

## Displaying BDF and PCF Fonts
The following code will take a PCF font and display all the character glyphs on a DVI display using a RP2350 microcontroller with no extra PSRAM. The RP2040 does not have enough memory. Printing a BDF with an RP2350 without PSRAM will likely run out of RAM before all 256 characters are printed.

If a character doesn't have a graphical glyph, it is represented by a period (.)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/Display_BDF_PCF_Font.py

Here is a custom font for IBM PC emulation, commonly called CP437 at 8x12 character size, as an example. This works on an RP2350 board without PSRAM with a PCF font. Memory will run out on a board without PSRAM if you use a BDF font or an RP2040.

![The IBM Code Page 437 font as a PCF. Note that all glyphs appear to be available.](https://cdn-learn.adafruit.com/assets/assets/000/138/134/medium800/lcds___displays_cp437-on-screen_2.jpg?1752085647 The IBM Code Page 437 font as a PCF. Note that all glyphs appear to be available.)

Change the font name and the desired screen resolution in the code for your situation.

Note that a full 256 character font will **not** print out fully on an RP2350-based board without PSRAM.

Note that printing fonts with more than a few characters on RP2040 will likely fail when the amount of RAM is used up. Consider using an RP2350 board, preferably with a PSRAM chip, to fully display fonts.

## Displaying LVGL Fonts
https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/Display_LVGL_Font.py

![An LVGL font rendering for the IBM Code Page 437 font. This was converted from a TrueType font.](https://cdn-learn.adafruit.com/assets/assets/000/138/280/medium800/lcds___displays_LVGL_437.jpg?1752085509 An LVGL font rendering for the IBM Code Page 437 font. This was converted from a TrueType font.)

## Converting Fonts

Adafruit has a web utility for converting text-based BDF fonts to PCF. Go to [https://adafruit.github.io/web-bdftopcf/](https://adafruit.github.io/web-bdftopcf/), enter in the BDF font file and it'll prompt where to save the PCF file.

There is an online TTF to LVGL font converter at [https://lvgl.io/tools/fontconverter](https://lvgl.io/tools/fontconverter).

There are other font conversion programs online as well as some possible web-based utilities.

## Loading Fonts for Use
Fonts are loaded on CircuitPython with `adafruit_bitmap_font.bitmap_font()`. This applies to BDF, PCF, and LVGL (.bin). CircuitPython looks inside the file and at the file extension, both, to [identify a valid font file](https://github.com/adafruit/Adafruit_CircuitPython_Bitmap_Font/blob/main/adafruit_bitmap_font/bitmap_font.py).

The `OnDiskFont()` function can also be used for LVGL fonts.

## Obtaining Fonts

Besides many fonts being available on the Internet, a number of fonts are available for CircuitPython in the Adafruit [GitHub repository](https://github.com/adafruit/circuitpython-fonts). They fall under a number of permissible use licenses, so check to be sure the license applies to your project.

Some fonts on other online sites have restrictive use licenses or are available at a cost. Be sure you check on the status of fonts you obtain before use.

The IBM CP437 fonts used in this guide in BDF, PCF, and LVGL format are from open sources and can be downloaded in GitHub via the green button below:

[CP437 Fonts](https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/main/Fruit_Jam/CircuitPython_DVI_Video/fonts)
For more information, please see this companion guide.

### Custom Fonts for CircuitPython Displays - Overview

[Custom Fonts for CircuitPython Displays](https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display)
[Overview](https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display/overview)
# Using DVI Video in CircuitPython

## CircuitPython Terminal

![](https://cdn-learn.adafruit.com/assets/assets/000/138/444/medium800/feather_20250716_094957a.jpg?1752677627)

In CircuitPython, a terminal refers to a text-based interface used for interacting with the microcontroller. It's a way to send commands to and receive output from your CircuitPython board, often through a serial connection over USB. This interface is essential for tasks like debugging, viewing program output, and interacting with the REPL (Read-Eval-Print Loop).&nbsp;

- **Serial Console:** The serial console, accessed via a terminal, displays output from your CircuitPython board, including print statements and error messages.&nbsp;
- **REPL:** The REPL is an interactive environment where you can type and execute CircuitPython code directly on the board.&nbsp;The terminal provides the means to access and interact with the REPL.&nbsp;
- **[terminalio](https://docs.circuitpython.org/en/latest/shared-bindings/terminalio/)&nbsp;Module:**The&nbsp;`terminalio`&nbsp;module in CircuitPython allows you to display text on a&nbsp;`TileGrid` (a display element) using a specific font, often with ANSI control codes. 
- **[ANSI/VT100 Commands](https://www.google.com/search?cs=0&sca_esv=6d27a280cc9bfc7a&q=VT100+Commands&sa=X&ved=2ahUKEwiB1tDB1pmOAxUYG9AFHc9RA2oQxccNegQIDxAB&mstk=AUtExfCy7XOG2yo_y53T9RazMfGgchAjPoPmBB6Qx8GBaRrrA3otmXzu306ubl_TPjGdgqBTz-x9HiAhe9m5TXF1i0PPRmgFBPG3q03DYNiRe4-Jo5QaJ3u2-Qc3gKeL9vKdssJwD_EGy74zZZGOK7KyLDMQxgGuY90tJmqdRbhVEB2g-5A&csui=3): ANSI/**VT100 is a standard for text-based communication, and&nbsp;`terminalio` uses it to manage cursor position, text color and other display elements (see `adafruit_color_terminal` for the best ANSI emulation).&nbsp;
- **Examples:** You might use a terminal to view the output of `print()` statements in your code, troubleshoot errors, or interact with the REPL for quick testing.

## Terminal and `terminalio`

Writes to the Terminal are done with `terminalio.write()`. Unlike `print` or `Label.label`, `write` places text at the bottom of the display, unless there are ANSI/VT100 Escape Codes embedded in the text to move the cursor to a desired location. See [Read The Docs](https://docs.circuitpython.org/en/latest/shared-bindings/terminalio/) for additional information.

Note as of version 10.0.0.alpha.8,&nbsp;`terminalio.Terminal` only accepts the built-in font `terminalio.FONT` or LVGL fonts.

The code examples below show how to use a Terminal with the `terminalio.FONT` built-in font and a custom Terminal LVGL font:

Info: `terminalio.Terminal.write` writes to the bottom of the TileGrid. That is unless an ANSI cursor move code is used prior to writing to move the text location.

Warning: The color changing ANSI escape codes in `terminalio.Terminal` currently allow only one color for the text on screen. If you need more than one color, use the `adafruit_color_terminal` library.

Below is a simple Terminal program which uses the built-in `terminal.FONT`.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/138/445/medium800/feather_20250716_094957a.jpg?1752677642)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/Simple_Terminal.py

Here is an example of using an LVGL font in Terminal instead of the built-in font:

![](https://cdn-learn.adafruit.com/assets/assets/000/138/446/medium800/feather_20250710_110159.jpg?1752677778)

[Font used in this example](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/fonts/cp437_16h.bin)
https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/LVGL_Font_Terminal.py

# Using DVI Video in CircuitPython

## adafruit_color_terminal

![](https://cdn-learn.adafruit.com/assets/assets/000/138/447/medium800/feather_20250713_175136.jpg?1752677822)

Info: This library is in the Adafruit CircuitPython bundle for CircuitPython 10.0.0.alpha.8 and later

Writes to the Terminal with color escape codes may be done with the `adafruit_color_terminal.write()` library. The library provides, at present, a more complete implementation of the ANSI/VT100 escape sequence handling than `terminalio.Terminal`. If you are doing extensive work with colors, using the `adafruit_color_terminal` library is recommended.

Like terminalio.Terminal, output is not via `print` or `Label.label`but uses the `write` method. This places text at the bottom of the display, unless there are ANSI/VT100 Escape Codes embedded in the text to move the cursor to a desired location.

Please refer to [Read The Docs](https://docs.circuitpython.org/projects/color_terminal/en/latest/api.html#adafruit_color_terminal.ColorTerminal) for more information and [Read the Docs](https://docs.circuitpython.org/projects/color_terminal/en/latest/) example.

Primary: Note that the escape sequence used to change colors of text must immediately precede the text being written. As currently implemented, writing the color change escape sequence in one write and then the text in a second write does not result in text of the desired color.

Below is a [simple color Terminal program](https://github.com/adafruit/Adafruit_CircuitPython_Color_Terminal/blob/main/examples/color_terminal_simpletest.py) which uses DVI.&nbsp;

https://github.com/adafruit/Adafruit_CircuitPython_Color_Terminal/blob/main/examples/color_terminal_fruit_jam_test.py

## ANSI/VT100 Escape Codes
![A VT100 video display terminal](https://cdn-learn.adafruit.com/assets/assets/000/138/141/medium800/lcds___displays_DEC_VT100_terminal.jpg?1751485835 A VT100 video display terminal)

[ANSI/VT100 Escape Codes](https://en.wikipedia.org/wiki/ANSI_escape_code) are introduced into a text output stream to alter certain behaviors in working with text. Originating in the later 1970s, it became a standard due to use on the popular DEC VT100 terminals on Digital Equipment Corporation and Unix systems. The Unix `curses` library was written to facilitate escape code use. With graphical displays becoming more common, escape code use tapered off although it is still used worldwide. It's great for use on resource constrained systems (like microcontrollers) and for porting code which uses `curses` to other systems as the graphics system doesn't need to be reinvented.

Common codes clear the screen, position the cursor to a row and column, and set a specific color to write text out.

Here is an example of using the `adafruit_color_terminal` library to write multiple colors on a screen with an LVGL font (Code Page 437, the one IBM used in their original PC).

## A More Involved Program
This program demonstrates:

- Using 8 colors which align with the ANSI terminal color codes
- Using a font other than `terminalio.Terminal`. This uses an LVGL font that contains many of the characters in the IBM CP437 IBM PC font which includes "drawing characters"
- Moving the cursor to positions and writing text of a certain color in that location.
- Drawing in special characters in a font

[Font file used in this example](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/fonts/cp437_16h.bin)
https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/ANSI_color_terminal.py

![](https://cdn-learn.adafruit.com/assets/assets/000/138/381/medium800/lcds___displays_20250713_175136.jpg?1752447336)

# Using DVI Video in CircuitPython

## CircuitPython_FruitJam Library

![](https://cdn-learn.adafruit.com/assets/assets/000/138/448/medium800/feather_6200-09.jpg?1752677856)

The&nbsp;`CircuitPython_FruitJam`&nbsp;library provides a cleaner interface for using HSTX DVI video. The board does not need to be a Fruit Jam (currently) but it must use HSTX video to a DVI breakout, such as the Adafruit Feather RP2350 and Adafruit Metro RP2350.

This is a cleaner way to set video values than setting up a Framebuffer. Especially on the Adafruit Fruit Jam board.&nbsp;

Info: The display setup helper will only work for devices that have the following pin names defined: board.CKP, `board.CKN`, `board.CKN`, `board.D0N`, `board.D1P`, `board.D1N`, `board.D2P`, `board.D2N` in the boards library.

Warning: If you have a different pin mapping from HSTX to DVI than the one above, you should define your own framebuffer as noted later in this guide.

## Examples
https://github.com/adafruit/Adafruit_CircuitPython_FruitJam/blob/main/examples/fruitjam_simpletest.py

![](https://cdn-learn.adafruit.com/assets/assets/000/138/449/medium800/feather_20250716_100130a.jpg?1752678297)

An optional `color_depth` parameter can be added in the latest iteration:

```python
from adafruit_fruitjam.peripherals import request_display_config

# Use the easy library call to set the resolution
request_display_config(640, 480, color_depth=8)  # Ask for a 640x480 display with 8 bit color depth
```

As a helper, there is a new `get_display_configuration()` function that will return the width, height, and color depth of the current display as a tuple with 3 elements. If the display isn't initialized, it returns `(None, None, None)`.

```python
from adafruit_fruitjam.peripherals import get_display_config

display_config = get_display_config()

print(display_config)
```

## Allowed Resolutions
The default resolutions when calling `request_display_config()` are below.&nbsp;

- 320x240 (default 16 bit color)
- 360x200 (default 16 bit color)
- 640x480 (default 8 bit color)
- 720x400 (default 8 bit color)

Warning: 360 and 720 resolutions may not work on all displays.

## Documentation
See documentation for the library on [Read the Docs](https://docs.circuitpython.org/projects/fruitjam/en/latest/api.html) and the implementation on `Read the Docs`.

Note that is you need more flexibility as to resolution and color depth, see `picodvi.Framebuffer` later in this guide.

# Using DVI Video in CircuitPython

## Setting Monitor Values via Environment Variables

Environment variables are set in a&nbsp; **settings.toml** &nbsp;file. They can provide a CircuitPython program information, such as WiFi SSID and password, access to Adafruit IO, and much more.

Documentation on this file are on [Read the Docs](https://docs.circuitpython.org/en/latest/docs/environment.html).

There are some environment variables which work or are specific to DVI displays, such as the ones below.

Info: The variables are read on a power-up or restart. They are not reread on a reload (control-D) from the REPL.

Here is a typical example of a **settings.toml** file that is placed in the **CIRCUITPY** root directory of the board you are using. The WiFi and Adafruit IO credentials are not needed if you are not using those services. This script sets the screen to 640x480 resolution at an 8 bit color depth and uses a specific font in the CircuitPython Terminal.

```auto
CIRCUITPY_WIFI_SSID = "your-wifi-ssid-here"
CIRCUITPY_WIFI_PASSWORD = "your-wifi-password-here"

aio_username = "your-Adafruit-IO-username-here"
aio_key = "your-Adafruit-IO-key-here"

CIRCUITPY_DISPLAY_WIDTH = 640
CIRCUITPY_DISPLAY_HEIGHT = 480
CIRCUITPY_DISPLAY_COLOR_DEPTH = 8
CIRCUITPY_TERMINAL_FONT = "/fonts/CP437_12h.bin"
```

#### **CIRCUITPY\_DISPLAY\_ROTATION**

Selects the correct screen rotation (0, 90, 180 or 270) for the particular board variant. If the CIRCUITPY\_DISPLAY\_ROTATION parameter is set the display will be initialized during power up with the selected rotation, otherwise the display will be initialized with a rotation of 0. Attempting to initialize the screen with a rotation other than 0, 90, 180 or 270 is not supported and will result in an unexpected screen rotation.

#### **CIRCUITPY\_PICODVI\_ENABLE**

Whether to configure the display at board initialization time, one of the following:

```
="detect" # when EDID EEPROM is detected (default)
="always"
="never"
```

A display configured in this manner is available at `supervisor.runtime.display`&nbsp;until it is released by&nbsp;`displayio.release_displays()`. It does not appear at&nbsp;`board.DISPLAY`.

#### **CIRCUITPY\_DISPLAY\_WIDTH, CIRCUITPY\_DISPLAY\_HEIGHT, and CIRCUITPY\_DISPLAY\_COLOR\_DEPTH (RP2350 boards with DVI or HSTX connector)**

Selects the desired resolution and color depth.

Supported resolutions are:

- 640x480 with color depth 1, 2, 4 or 8 bits per pixel

- 320x240 with pixel doubling and color depth 8, 16, or 32 bits per pixel

- 360x200 with pixel doubling and color depth 8, 16, or 32 bits per pixel

See [`picodvi.Framebuffer`](https://docs.circuitpython.org/en/9.2.x/shared-bindings/picodvi/index.html#picodvi.Framebuffer "picodvi.Framebuffer") for more details.

The default value, if unspecified, is 360x200 16 bits per pixel if the connected display is 1920x1080 or a multiple of it, otherwise 320x240 with 16 bits per pixel.

If height is unspecified, it is set from the width. For example, a width of 640 implies a height of 480.

Example: Configure the display to 640x480 black and white (1 bit per pixel), add these lines to your **settings.toml** file.

```auto
CIRCUITPY_DISPLAY_WIDTH=640
CIRCUITPY_DISPLAY_COLOR_DEPTH=1
```

## Changing the Terminal Font
New to CircuitPython 10 and later is the ability to change the font of the CircuitPython Terminal. Per the documentation on [Read the Docs](https://docs.circuitpython.org/en/latest/docs/environment.html):

#### **CIRCUITPY\_TERMINAL\_FONT**

Specifies a custom font file path to use for the `terminalio` console instead of the default&nbsp;`/fonts/terminal.lvfontbin`. This allows users to create and use custom fonts for the CircuitPython console.

This feature requires both `CIRCUITPY_OS_GETENV` and `CIRCUITPY_LVFONTIO` to be enabled.

Example:

```
CIRCUITPY\_TERMINAL\_FONT="/fonts/myfont.lvfontbin"
```

[Boards where the terminalio core module is available](https://docs.circuitpython.org/en/latest/shared-bindings/terminalio/)

[Boards where the lvfontio core module is available](https://docs.circuitpython.org/en/latest/shared-bindings/lvfontio/index.html)

# Using DVI Video in CircuitPython

## Create Your settings.toml File

CircuitPython works with WiFi-capable boards to enable you to make projects that have network connectivity. This means working with various passwords and API keys. As of [CircuitPython 8](https://circuitpython.org/downloads), there is support for a **settings.toml** file. This is a file that is stored on your **CIRCUITPY** drive, that contains all of your secret network information, such as your SSID, SSID password and any API keys for IoT services. It is designed to separate your sensitive information from your **code.py** file so you are able to share your code without sharing your credentials.

CircuitPython previously used a **secrets.py** file for this purpose. The **settings.toml** file is quite similar.

Warning: Your **settings.toml** file should be stored in the main directory of your **CIRCUITPY** drive. It should not be in a folder.

## CircuitPython **settings.toml** File

This section will provide a couple of examples of what your **settings.toml** file should look like, specifically for CircuitPython WiFi projects in general.

The most minimal **settings.toml** file must contain your WiFi SSID and password, as that is the minimum required to connect to WiFi. Copy this example, paste it into your **settings.toml** , and update:

- `your_wifi_ssid`
- `your_wifi_password`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
```

Many CircuitPython network-connected projects on the Adafruit Learn System involve using Adafruit IO. For these projects, you must _also_ include your Adafruit IO username and key. Copy the following example, paste it into your settings.toml file, and update:

- `your_wifi_ssid`
- `your_wifi_password`
- `your_aio_username`
- `your_aio_key`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
ADAFRUIT_AIO_USERNAME = "your_aio_username"
ADAFRUIT_AIO_KEY = "your_aio_key"
```

Some projects use different variable names for the entries in the **settings.toml** file. For example, a project might use `ADAFRUIT_AIO_ID` in the place of `ADAFRUIT_AIO_USERNAME`. **If you run into connectivity issues, one of the first things to check is that the names in the settings.toml file match the names in the code.**

Warning: Not every project uses the same variable name for each entry in the **settings.toml** file! Always verify it matches the code.

## **settings.toml** File Tips
Here is an example **settings.toml** file.

```auto
# Comments are supported
CIRCUITPY_WIFI_SSID = "guest wifi"
CIRCUITPY_WIFI_PASSWORD = "guessable"
CIRCUITPY_WEB_API_PORT = 80
CIRCUITPY_WEB_API_PASSWORD = "passw0rd"
test_variable = "this is a test"
thumbs_up = "\U0001f44d"
```

In a **settings.toml** file, it's important to keep these factors in mind:

- Strings are wrapped in double quotes; ex: `"your-string-here"`
- Integers are _ **not** _ quoted and may be written in decimal with optional sign (`+1`, `-1`, `1000`) or hexadecimal (`0xabcd`).
  - Floats (decimal numbers), octal (`0o567`) and binary (`0b11011`) are not supported.

- Use `\u` escapes for weird characters, `\x` and `\ooo` escapes are not available in **.toml** files
  - Example: `\U0001f44d` for 👍 (thumbs up emoji) and `\u20ac` for € (EUR sign)

- Unicode emoji, and non-ASCII characters, stand for themselves as long as you're careful to save in "UTF-8 without BOM" format

&nbsp;

&nbsp;

When your&nbsp; **settings.toml&nbsp;** file is ready, you can save it in your text editor with the **.toml** &nbsp;extension.

![adafruit_products_dotToml.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/071/medium640/adafruit_products_dotToml.jpg?1671034293)

## Accessing Your **settings.toml** Information in **code.py**
In your **code.py** file, you'll need to `import` the `os` library to access the **settings.toml** file. Your settings are accessed with the `os.getenv()` function. You'll pass your settings entry to the function to import it into the **code.py** file.

```python
import os

print(os.getenv("test_variable"))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/117/072/medium800/adafruit_products_tomlOutput.jpg?1671034496)

In the upcoming CircuitPython WiFi examples, you'll see how the **settings.toml&nbsp;** file is used for connecting to your SSID and accessing your API keys.

# Using DVI Video in CircuitPython

## Using a Framebuffer and PicoDVI

Primary: This method works for CircuitPython 9.2 and later, including CircuitPython 10

The way the DVI/HDMI connection is established is using a framebuffer. The modules used to do this are&nbsp;`board`,&nbsp;`framebufferio`,&nbsp;`displayio`&nbsp;and&nbsp;`picodvi`. Their use is as follows:

`board`&nbsp;is used to define the clock, red, green, and blue differential wire pins used by the development board. These can vary from board to board, so a general definition is coded into the board definition for our use.

`framebufferio`&nbsp;defines a memory space to store the graphics placed onto the screen.

`picodvi`&nbsp;is a library that provides DVI/HDMI use via the CircuitPython&nbsp;`displayio`&nbsp;graphics system.

`displayio`&nbsp;is the high level graphics system used most often in CircuitPython to write to displays. See the guide linked below if you want to delve into how&nbsp;`displayio`&nbsp;works.

### CircuitPython Display Support Using displayio - Introduction

[CircuitPython Display Support Using displayio](https://learn.adafruit.com/circuitpython-display-support-using-displayio)
[Introduction](https://learn.adafruit.com/circuitpython-display-support-using-displayio/introduction)
For smaller displays, there is some hardware that must be set up using the connectivity the display uses before using the Terminal and&nbsp;`displayio`. There is setup that an HDMI display needs too.&nbsp;

### Creating a&nbsp;`displayio`&nbsp;Object for a DVI Display
```python
import sys
import board
import displayio
import terminalio
import framebufferio
import picodvi

displayio.release_displays()
try:
    fb = picodvi.Framebuffer(320, 240, clk_dp=board.CKP, clk_dn=board.CKN,
                             red_dp=board.D0P, red_dn=board.D0N,
                             green_dp=board.D1P, green_dn=board.D1N,
                             blue_dp=board.D2P, blue_dn=board.D2N,
                             color_depth=8)
except ValueError as e:
    print("Framebuffer error: ", e)
    sys.exit(e)

display = framebufferio.FramebufferDisplay(fb)
```

If you wish to set the system display, as is done in the **adafruit\_fruitjam** [`request_display_config()`](https://github.com/adafruit/Adafruit_CircuitPython_FruitJam/blob/main/adafruit_fruitjam/peripherals.py):

```auto
supervisor.runtime.display = framebufferio.FramebufferDisplay(fb)
```

Above creates a&nbsp;`displayio`&nbsp;`display`&nbsp;object for DVI/HDMI display. A more complete program is below. This is suitable for creating a 320pixel x 240pixel (pixel doubled behind the scenes) x 8bit display suitable for an RP2040 or RP2350 microcontroller.

The display is released (if in use) in the first line.

Then a framebuffer is created using the&nbsp;`picodvi`&nbsp;library. The first two numbers are the width and height of the display in pixels. You will want to refer to the&nbsp;[documentation here](https://docs.circuitpython.org/en/latest/shared-bindings/picodvi/index.html)&nbsp;for valid values.

The&nbsp;`_dp`&nbsp;values map the pins the HSTX bus from the microcontroller is mapped. Using the&nbsp;`board`&nbsp;library, these are mapped to the appropriate values, you do not need to know which pins have which functions.

The&nbsp;`color_depth`&nbsp;parameter may be&nbsp;`1`,&nbsp;`2`,&nbsp;`4`,&nbsp;`8`,&nbsp;`16`, or&nbsp;`32`&nbsp;bits with&nbsp;`1`,&nbsp;`2`, and&nbsp;`4`&nbsp;being grayscale. Again see the&nbsp;[documentation](https://docs.circuitpython.org/en/latest/shared-bindings/picodvi/index.html)&nbsp;for valid values. The larger the number, the more RAM used.

The exception handling catches instances where the size and color depth are not valid values. If you have a set value and you know it works, you may omit the exception handling.

Finally a&nbsp;`displayio`&nbsp;`display`&nbsp;is created from the framebuffer.

![](https://cdn-learn.adafruit.com/assets/assets/000/138/450/medium800/feather_20250716_100950.jpg?1752678720)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/CircuitPython_DVI_Video/DVI_Framebuffer.py

# Using DVI Video in CircuitPython

## A Full DVI displayio Example

![](https://cdn-learn.adafruit.com/assets/assets/000/138/451/medium800thumb/feather_hacks_5745-06_1.jpg?1752679614)

Linked below is a `displayio` sample program by Liz Clark based on Arduino code by Phil Burgess. It shows how to use certain display functions and methods on a DVI display.

The code is clever in seeing what displays may be connected by:

1. Testing if `board.DISPLAY` exists
2. Seeing if a DVI Adafruit board is being used
3. Then assuming a Raspberry Pi Pico is being used

Then various text and graphics are displayed. It uses many `displayio` functions and libraries and can be used to see what capabilities are available.

### Adafruit PiCowbell DVI Output - CircuitPython

[Adafruit PiCowbell DVI Output](https://learn.adafruit.com/adafruit-picowbell-dvi-output)
[CircuitPython](https://learn.adafruit.com/adafruit-picowbell-dvi-output/circuitpython)
Also this guide is recommended for an introduction to `displayio`:

### CircuitPython Display Support Using displayio - Introduction

[CircuitPython Display Support Using displayio](https://learn.adafruit.com/circuitpython-display-support-using-displayio)
[Introduction](https://learn.adafruit.com/circuitpython-display-support-using-displayio/introduction)
# Using DVI Video in CircuitPython

## References and Other Guides

A selection of open IBM Code Page 437 fonts are available in this guide's GitHub repository:

[Code Page 437 Fonts in BDF, PCF and LVGL bin Formats](https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/main/Fruit_Jam/CircuitPython_DVI_Video/fonts)
Here are some additional resources to read up on various topics related to this guide:

### CircuitPython Display Support Using displayio - Introduction

[CircuitPython Display Support Using displayio](https://learn.adafruit.com/circuitpython-display-support-using-displayio)
[Introduction](https://learn.adafruit.com/circuitpython-display-support-using-displayio/introduction)
### Custom Fonts for CircuitPython Displays - Overview

[Custom Fonts for CircuitPython Displays](https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display)
[Overview](https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display/overview)
The Adafruit [`Display_Shapes`](https://docs.circuitpython.org/projects/display-shapes/en/latest/) library

[`vectorio`](https://docs.circuitpython.org/en/latest/shared-bindings/vectorio/ "vectorio")&nbsp;– Lightweight 2D shapes for displays

There is an online [Video Timings Calculator](https://tomverbeure.github.io/video_timings_calculator) for the parameters needed in various resolutions


## Featured Products

### Adafruit Fruit Jam - Mini RP2350 Computer

[Adafruit Fruit Jam - Mini RP2350 Computer](https://www.adafruit.com/product/6200)
We were catching up on a recent [hackaday hackchat with eben upton](https://hackaday.io/event/202122-raspberry-pi-hack-chat-with-eben-upton)&nbsp;and learned some fun facts: such as the DVI hack for the RP2040 was inspired by <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/6200)
[Related Guides to the Product](https://learn.adafruit.com/products/6200/guides)
### Adafruit Metro RP2350 with PSRAM

[Adafruit Metro RP2350 with PSRAM](https://www.adafruit.com/product/6267)
Choo! Choo! This is the RP2350 Metro Line, making all station stops at "Dual Cortex M33 mountain", "528K RAM round-about" and "16 Megabytes of Flash town" and a bonus stop at "8 Megabytes of PSRAM village". This train is piled high with hardware that...

In Stock
[Buy Now](https://www.adafruit.com/product/6267)
[Related Guides to the Product](https://learn.adafruit.com/products/6267/guides)
### Adafruit Metro RP2350

[Adafruit Metro RP2350](https://www.adafruit.com/product/6003)
Choo! Choo! This is the RP2350 Metro Line, making all station stops at "Dual Cortex M33 mountain", "528K RAM round-about" and "16 Megabytes of Flash town". This train is piled high with hardware that complements the Raspberry Pi RP2350 chip to make it an excellent...

In Stock
[Buy Now](https://www.adafruit.com/product/6003)
[Related Guides to the Product](https://learn.adafruit.com/products/6003/guides)
### Adafruit Feather RP2350 with HSTX Port and 8MB PSRAM

[Adafruit Feather RP2350 with HSTX Port and 8MB PSRAM](https://www.adafruit.com/product/6130)
RP2350&nbsp;flies high with the&nbsp;Feather&nbsp;format - now you can use any FeatherWings with this battery-powered dev board. It comes with 8MB of flash, 22pin HSTX output port, Stemma QT, debug SWD, and optional PSRAM spot. It's our first RP2350 board and we crammed a ton of goodies...

In Stock
[Buy Now](https://www.adafruit.com/product/6130)
[Related Guides to the Product](https://learn.adafruit.com/products/6130/guides)
### 22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 10cm

[22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX - 10cm](https://www.adafruit.com/product/6035)
Connect this to that when a 22-pin FPC connector is needed. This 10 cm long cable is made of a flexible PCB. It's A-B style, meaning that pin one on one side will match with pin one on the other. How handy!

[We're stocking this to...](https://www.adafruit.com/category/360)

In Stock
[Buy Now](https://www.adafruit.com/product/6035)
[Related Guides to the Product](https://learn.adafruit.com/products/6035/guides)
### Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays

[Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays](https://www.adafruit.com/product/6055)
You may have noticed that our [RP2350 Feather](https://www.adafruit.com/product/6000) has an FPC output connector on the end&nbsp;for accessing the HSTX (High Speed Transmission)&nbsp;peripheral. This new capability, not available on the RP2040, is specifically designed to allow the...

In Stock
[Buy Now](https://www.adafruit.com/product/6055)
[Related Guides to the Product](https://learn.adafruit.com/products/6055/guides)
### 7" Display 1280x800 (720p) IPS + Speakers - HDMI/VGA/NTSC/PAL

[7" Display 1280x800 (720p) IPS + Speakers - HDMI/VGA/NTSC/PAL](https://www.adafruit.com/product/1667)
Yes, this is an adorable small HDMI television with incredibly high resolution **and built in 3W stereo speakers**! We tried to get the smallest possible HDMI/VGA display with high-res, high-contrast visibility. The visible display measures only 7" (17.8cm) diagonal, and the TFT comes...

In Stock
[Buy Now](https://www.adafruit.com/product/1667)
[Related Guides to the Product](https://learn.adafruit.com/products/1667/guides)
### HDMI Cable - 1 meter

[HDMI Cable - 1 meter](https://www.adafruit.com/product/608)
Connect two HDMI devices together with this basic HDMI cable. It has nice molded grips for easy installation, and is 1 meter long (about 3 feet). This is a HDMI 1.3 cable.

We're now stocking a very fancy Official Raspberry Pi cable with overmolding and a Pi logo. Please note...

In Stock
[Buy Now](https://www.adafruit.com/product/608)
[Related Guides to the Product](https://learn.adafruit.com/products/608/guides)

## Related Guides

- [Adafruit Feather RP2350 with HSTX](https://learn.adafruit.com/adafruit-feather-rp2350.md)
- [Adafruit RP2350 22-pin FPC HSTX to DVI Adapter](https://learn.adafruit.com/adafruit-rp2350-22-pin-fpc-hstx-to-dvi-adapter.md)
- [Adafruit Metro RP2350](https://learn.adafruit.com/adafruit-metro-rp2350.md)
- [Adafruit Fruit Jam](https://learn.adafruit.com/adafruit-fruit-jam.md)
- [Chip's Challenge on Fruit Jam and Metro RP2350](https://learn.adafruit.com/256-color-gaming-on-the-metro-rp2350.md)
- [Snake Game on Metro RP2350](https://learn.adafruit.com/snake-game-on-metro-rp2350.md)
- [Flappy Nyan Cat Game on Fruit Jam and Metro RP2350](https://learn.adafruit.com/flappy-nyan-cat-game-on-metro-rp2350.md)
- [Feather RP2350 Audio Reactive Video Synth](https://learn.adafruit.com/feather-rp2350-audio-reactive-video-synth.md)
- [Tile-Matching Game on the Fruit Jam and Metro RP2350](https://learn.adafruit.com/tile-matching-game-on-the-adafruit-metro-rp2350.md)
- [Minesweeper on the Fruit Jam and Metro RP2350](https://learn.adafruit.com/minesweeper-on-metro-rp2350.md)
- [USB Game Controller with SNES-like Layout](https://learn.adafruit.com/usb-game-controller-with-snes-like-layout.md)
- [Breakout Game on the Metro RP2350 and Fruit Jam](https://learn.adafruit.com/breakout-game-on-metro-rp2350-and-fruit-jam.md)
- [How to Choose a Microcontroller](https://learn.adafruit.com/how-to-choose-a-microcontroller.md)
- [Driving TM1814 addressable LEDs](https://learn.adafruit.com/driving-tm1814-addressable-leds.md)
- [Lightsaber Prop-Maker RP2040](https://learn.adafruit.com/lightsaber-rp2040.md)
- [MagTag Sports Schedule Viewer](https://learn.adafruit.com/magtag-sports-schedule-viewer.md)
- [Busy Box Interruption Sign](https://learn.adafruit.com/busy-box-interruption-sign.md)
