Hacker News new | ask | show | jobs
by LeonM 1011 days ago
I've worked on something similar while in college. HDMI is actually a fairly simple protocol, based on VGA. It still has scanlines and such, but the signals are digital instead of analog. So instead of a RAMDAC, you have the HDMI encoder chip. You typically need control some i2c interface to set the HDMI encoder chip in the correct mode, but that's about it.
6 comments

It's worth mentioning that HDMI encoder chips are actually quite difficult to get hold of as a hobbyist; the HDMI association prohibits their sale to anybody who has not signed the relevant NDAs, paid membership fees and whatnot. The project shown here gets around this by using a freely available DVI encoder chip instead, which works fine (the HDMI specification mandates backwards compatibility with DVI) but lacks support for a number of HDMI-only features such as audio and higher resolutions.

The only HDMI encoder I have seen so far with easily accessible (i.e. leaked) documentation is the CAT6613/IT6613 from ITE, which also happens to be available for purchase in single quantities from a number of Chinese retailers. It seems to be used in the OSSC and several FPGA development boards, so it's about as close to being an unofficial standard for open source projects as it could be.

This is a good reason to bit-bang the protocol. It is in fact possible to get HDMI including audio out of an RP2040, as is demonstrated by infones[1], a NES emulator.

[1]: https://github.com/shuichitakano/pico-infones

Based on what you said, you didn't actually look at HDMI protocol, only the protocol exposed to your HDMI encoder chip. You could have such a protocol on Thunderbolt 3 encoder chip.

FWIW, yes HDMI is still pretty simple, but not as simple as you describe it. Even though there are 3 pairs of data it's not one pair R, one pair G, one pair B (highest-bandwidth HDMI uses 4 pairs), it's just one data bus. The data pairs aren't only used for data colors, but also conveys audio, and info frames (which will include various stuff like HDR or VRR metadata). Of course there is the matter of DRM: the content will often be encrypted (but negotiation of that encryption happen separately, over I2C)

That's only the case in the (relatively) shiny new 2.1 spec with FRL. Prior versions are TMDS with 3 channels for red, green, blue, along with a clock. The audio and InfraFrames slot into the data islands in blanking periods on those signals.
Thanks for the complementary infos. YCbCr420 (which you can't just mux on the channels directly?) dates back to HDMI 1.4 though
As the source device, you can simply choose not to send YCbCr420.
Absolutely - YCbCr 4:2:2 and 4:2:0 use different encodings across the lines to balance bandwidth. Complexity then continues to stack with deep colour pixel packing. There's a beautiful pocket of simplicity for RGB 4:4:4 8bpc which is essentially a direct digital encoding of ye oldy RGBHV signals. More than OK for any retro-comp needs, and a fun starting point for general hacking.
> Based on what you said, you didn't actually look at HDMI protocol, only the protocol exposed to your HDMI encoder chip.

You are correct. Though as part of my studies (and curiosity, of course) I did end up analyzing the signalling protocol. The side-effect of standardizing line protocols is that it offers an abstraction for the engineers working with it. I didn't have to understand the signalling methods per se to use HDMI in my project.

> FWIW, yes HDMI is still pretty simple, but not as simple as you describe it.

I should have added that at the time I used it, HDMI was still in the 1.0 spec (1080i, 60Hz max), which was effectively DVI. Much has changed since then.

While that's true, you really only need to blast out RGB data to get an image on screen. Most of what you are talking about is layered on top and optional.

I did a tiny HDMI implementation in an FPGA for a project, the TMDS implementation was what took the longest.

I remember i2c support was added to the Linux kernel. I never understood what it is.

Next in line is BPF, which is also unclear.

I2C is basically "USB for things where USB would be overkill". It's a standardized protocol [1] that allows for one host to communicate with up to 128 different devices on a shared serial bus consisting of two wires. The specification does not define any discovery mechanism or higher-level functionality on top of basic packet sending and receiving, so I2C is meant to be used in cases where the host already knows what is connected and has the appropriate drivers set up (hence why embedded Linux devices typically use a "device tree" or similar configuration file to tell the kernel about their I2C hardware). Many of the chips used in modern electronics are either controlled entirely via I2C or use it as a configuration port in addition to a separate high-bandwidth interface for data; the accelerometer, power management chip, audio DAC, display and cameras in your phone all have I2C interfaces.

Another use case for I2C is device identification: since I2C-interfaced ROMs are so cheap, it's common to embed them in various types of peripherals and have the host read them out to retrieve information about the peripheral. This is how your PC gets to know which resolutions are supported by your monitor [2] (VGA, DVI and HDMI all have dedicated I2C pins for this purpose) and which type of RAM you have installed [3], for instance.

[1] https://en.wikipedia.org/wiki/I%C2%B2C

[2] https://en.wikipedia.org/wiki/Extended_Display_Identificatio...

[3] https://en.wikipedia.org/wiki/Serial_presence_detect

If you're talking about (e)BPF, the (extended) Berkeley Packet Filter, the easiest way to think about it is like a tiny virtual machine running inside the kernel, which can execute "simple" commands that would otherwise be very slow or very complex from within userspace. The traditional example would be counting the number of packets being sent out by a network interface. But it turns out that eBPF is massively more general purpose than that, allowing people to develop all kinds of monitoring applications.
I2C is a simple serial communications protocol typically used for things like configuring on-board devices and reading sensors.

BPF is anything but simple.

How does its complexity compare to DisplayPort?
HDMI is simpler to have a simple implementation; DisplayPort is simpler to have a fully featured implementation.

HDMI keeps normal analog video timing with blank/hblank, etc. Stuffing anything other than video is pretty complex and a mish mash of finding weird gaps in the video data.

DisplayPort is it's own packet based protocol. Sending things other than video are just other packet types over the same link.

If you only want to drive the monitor in DVI compatibility mode, you don't need very much because the interface is (as you describe) fairly simple and electrically compatible - if you actually want "real" HDMI then it's much more complex.