Close

HardwareDDC: Reverse-Engineering the DisplayPort AUX Channel

alexandre-boutoilleAlexandre Boutoille wrote 07/07/2026 at 01:50 • 6 min read • Like

Whether you're coming from my Twitter or stumbled across this through a Google search, welcome to my first Hackaday.io article!

My interest in the DisplayPort Auxiliary channel comes from the lack of many MCCS VCP codes like 10 and 60 for brightness and input source on certain monitors. Specifically, the lack of an MCCS implementation through the DisplayPort connections of my Samsung G9—the monitor firmware supports it through HDMI. Two years ago, I built an HDMI DDC accessory as a janky solution to this. However, it was never a "clean" solution I was satisfied with. This started my open-source HardwareDDC project, where I have been exploring better solutions to this problem.

Currently, I have been exploring the use of differential transceivers to receive and transmit messages over the DisplayPort AUX channel with the end goal of creating a DisplayPort AUX to HDMI bridge device of sorts. In this article, I'd like to share a quick update on the project, my current challenges, and future plans.

Hardware Design

To MitM (Man in the Middle) the AUX channel, I'm using a pair of TI's SN65MLVD200A/AD transceivers. These can act as drivers and receivers—depending on their mode—to read and write messages on the half-duplex AUX channel. This decision was inspired by J5XS' DP-aux emulator. Although it focuses on modifying the EDID through a DP Alt Mode connection, the same basic principles apply to my application.



The MitM circuit relies on two halves—the sink and source transceiver circuits. The differential pair hardware layout comes from VESA's DisplayPort 1.2 Standard document. Admittedly, my current physics and math skills are lacking to fully understand this circuit from a theoretical level. I understand that termination resistors and their accompanying caps create some form of high-pass filter to allow the square waves to pass, while blocking the DC current.


I am also unsure why, in JX5S' reference design, the termination resistors are connected to GPIOs instead of directly pulled up to 3.3V and down to ground. While designing the board, I kept this design decision as if need be, cutting and re-routing the traces to 3.3v and the ground plane is easier than to the MCU pads. While prototyping in MicroPython, I simply defined the GPIO states as:

# source side pins
Pin(6, Pin.OUT).value(1)
Pin(7, Pin.OUT).value(0)

# sink side pins
Pin(8, Pin.OUT).value(0)
Pin(9, Pin.OUT).value(1)

The side which plugs into the user's sink uses 100k terminations to act as a source, and vice versa. On the transceivers' outputs, they provide access to the differential pair as single-ended lines for the microcontroller to interact with. Like in J5XS' design, I left the 10k pull-downs to leave the transceivers in receiver mode by default.

The Auxiliary channel is only one part of the DisplayPort link. There are still the four high-speed video lanes and the HPD pin. Luckily, this project can simply pass-through the video signal like a coupler, as high-speed video debugging is far beyond my capabilities at home. However, I still had to design a board capable of carrying the video signals while minimizing noise. This is where PCBWay, this project's sponsor, and their services have been incredibly useful. Their high-quality manufacturing and assembly are especially important for this project.

Using PCBWay's IPC 2141 high-frequency impedance calculator, I was able to control the differential impedance of the video lanes to 100 Ω ± 10% based on the selected stackup.


I opted to use PCBWay's 0.6mm 4-layer PCB stackup, as the thin 0.0925 mm dielectric prepreg material keeps the signal layer close to the ground plane. This was my first time working with and designing a very rigid circuit board. Although it was interesting to try it, and useful for my somewhat niche use-case, I might go back to a thicker PCB in the future. The main downsides of using a 0.6mm PCB were: excessive board warping when soldering the MCU dev board if not careful, greater potential of cracking copper traces and difficulty in unplugging and replugging the large DisplayPort Type-A connector. In the future, I will either use a 1.6mm 4-layer PCB with an odd stackup featuring a very thick inner core, or, depending on manufacturing constraints, a 6-layer PCB which would have the added benefit of sandwiching the DisplayPort video differential pairs with two ground planes.

Once again, a big thank you to PCBWay! Without their sponsorship and high-quality manufacturing, this project would not be where it is today. If you're in need of subtractive manufacturing, additive manufacturing and PCB services, consider using PCBWay for your next project. Disclaimer: the referral link gives you $5 off your first order and helps support HardwareDDC.

Firmware Design

Part of what makes this project special is using the RP2040 microcontroller, and its two cores and two PIO blocks (four state machines each). This allows for custom protocol implementation without costly purpose-built silicon. This design choice is again inspired by J5XS. However, iVRy's firmware is not open-source, leading me to figure that part out myself. As this is my first PIO project, I have had to start with the basics. I have watched Professor V. Hunter Adams' lecture 12–15 recordings from Cornell University to receive a high-level overview, and utilized Life with David's video series as a more practical set of examples.

With the help of captured oscilloscope data and a generic 24 MHz 8-channel logic analyzer, I was able to capture the following data with my PIO code:

10011111100001101111110000011110
11011111100001101111110000011111

I believe that this is the source attempting to read the sink's capabilities in the form of DPCD data and ack-ing. This would later be followed by the source attempting to read the monitor's EDID through I2C Over Aux.

As a prototype, I used MicroPython to define two of the state machines to move data entering GPIO pin 2, and two other state machines run at 8 MHz—reducing the likelihood I miss something—to print 32-bit segments. I then used the RP2040's regular general-purpose ARM cores to remain passive when the channel sits low (or high) and format the data into human-parsable binary.

Current Challenges & What's Next

Despite being used in almost every modern "computer" with a display, DisplayPort AUX is still a fairly niche topic amongst hobbyists. This has made it challenging to easily learn the necessary information from the limited resources. However, learning about the AUX Channel has been a slow and cumulative process.

Even after making great progress, this project is far from finished. Currently, I am working on acquiring a new logic analyzer to help me parse through the digital signals. After that, this is my rough plan to continue hacking away at this:

  1. Achieve accurate & consistent readings through PIO confirmed with the LA
  2. Goal: read the EDID passively, then on demand
  3. Understand and simulate I2C over AUX DDC communication for MCCS
  4. Last mile: release a fully-featured beta firmware

If you're interested in following the project, I will continue sharing brief updates on Twitter, decently polished source updates will be pushed to the GitHub repo, and I will share more update(s) on Hackaday.io as I reach new milestones.

Additional Resources

If you're reading this because you're also a hobbyist interested in the DisplayPort AUX channel, below are some helpful resources I've relied on (backward reference searching may also be useful):

Like

Discussions