LED Display 2014-2015

Problem Statement
The past senior design project LED Video Player allowed us to drive full-motion video to LED panels using an FPGA.

The system we're developing now will send an HDMI video signal directly to an FPGA. The FPGA will then pass a scaled down copy of the video to the LED panels. This will allow "plug-and-play" usage with any HDMI source, without the need for a computer, and with little to no configuration required.

Upon completion of this project we will be able to drive real-time video to multiple LED panels from any HDMI signal that's in a supported resolution.

Background
LED panels are used around the world for businesses large and small. However the choices are a little lacking when it comes to inexpensive solutions that are easy to use, open source, and that work with commodity hardware such as the Adafruit LED panels. Filling this gap would be nice for small businesses who aren't afraid to get their hands a little dirty, as well as provide an excellent starting codebase for LED enthusiasts.

The previous LED Video Player project was a good start, but it had some downsides and required custom software. In our LED Display project we hope to make sending video to a LED panel as easy as plugging in an HDMI cable.

Previous Work
Main page: LED Video Player.

Interview with Dr. Robert Rinker
Our interview with Dr. Rinker was totally laid back. We made sure we were all on the same page with the general project direction, but we did not lay down super detailed requirements or specifications.

Dr. Rinker was happy with our initial (and in the end final) FPGA choice, the Digilent Atlys. He was concerned with the difficulty of FPGA development and for that reason didn't want the project goals to be too difficult.

HDMI2USB
The HDMI2USB project on github has a lot of existing opensource HDMI HDL. In particular there's a complete implementation of sending EDID data to the HDMI video source here.

HDMI Basics
HDMI is based on DVI, and as we’re only concerned with unencrypted uncompressed video, a lot of our work will actually be DVI work in disguise.

A typical HDMI connector looks like this:



Features:


 * 1) Hot plug detect detects when the cable is plugged in or not.
 * 2) DDC is an I2C based protocol and stands for Display Data Channel. Having this working is a requirement for being an HDMI sink, as it’s what tells the source the # display capabilities and whatnot.
 * 3) CEC stands for Consumer Electronics Control. It’s a bus that can chain multiple HDMI devices together for things like allowing a remote to operate all devices at the same time.
 * 4) TMDS is a differential signalled pair of wires that send over bytes of data using an 8b/10b encoding. There are three different TMDS pairs.

TMDS
TMDS stands for transition minimized differential signalling. The “transition minimized” refers to trying to minimize transition between zero and one, as well as trying to keep the 0’s and 1’s balanced. Apparently these properties are beneficial somehow.

The “differential signalling” refers to sending a signal over a pair of wires. One wire carries the complement signal of the other wire. This can help protect against interference as the interference will probably effect both wires similarly.

There are three TMDS channels (or six for the Type B cable), one for each color out of Red, Green Blue. Each one of these needs to be 8/10 encoded seperately. The pixel clock is also sent over a DS pair, but isn’t 8/10 encoded.

Here is a block diagram of a TMDS receiver:



8/10b Encoding
HDMI uses an 8/10 encoding where an 8 bit word is transformed into a 10 bit word with properties good for the “transition minimized” goal.

As each 8-bit color needs 10 bits to transmit, this means the bits have to be sent 10x the speed of the pixel clock.

The algorithm is a bit involved, but comes down to some simple combinatorial logic. Basically it chooses either XOR or XNOR to encode the 2nd through 8th bits based on what will minimize transitions. Then it sometimes inverts the signal to keep 1’s and 0’s balanced.

[TODO EXPAND]

DDC
DDC is an I2C based protocol which allows an HDMI video sink to convey it's supported display modes (among other things) to the HDMI video source.

This information is conveyed in the form of an EDID blob, which is either 128 or 256 bytes.

It's possible for an HDMI video source to send a signal without receiving any EDID data, but to be robust and portable this has to be implemented.

Fortunately the HDMI2USB project includes a working EDID HDL module.

Implementation/Testing
For implementation purposes we decided to use the Digilent Atlys. The Atlys is a pretty heavyweight FPGA, but the ideal board to develop an HDMI based project on. This is because there's a lot of existing work for it, and it's beefy enough to have more than we need.

Once the problem is well understood, it would be easy to "port" the FPGA design to a cheaper board.

[TODO implement LED video! :D]

[The following might need changing, I just wanted to get some of my notes uploaded in case they proved useful.]

Generating EDID files
EDID is a (somewhat quirky) binary format, so it's hard to create one with a text editor and writing a program to create them would be slightly involved.

However, there are tools out there that can be used to generate EDID files.

For instance one comes with recent Linux kernels in the Documentation/EDID/ folder. It's only dependencies are gcc and Make, and it allows one to easily create custom EDIDs.

Here is one such EDID file created with that tool that supports a 640x480@60 resolution. [TODO: dropbox is a terrible place for wiki-links]

Implementing EDID / DDC on the FPGA
The HDMI2USB project includes a working EDID HDL module. (The Atlys or Xilinx demos might too, but I haven't looked)

The edidslave module can be used almost as is, except as there's no need for the dvi_only flag-- it can be set to a constant 1 or removed entirely for our purposes.

The ROM to load is specified by the edidrom.hex file. It's easy to convert binary files to .hex files with a short C++ program.