HDMI CEC interface

I'll have to take a look at what you've implemented. I'm working on my own version as well. It's a C++ class that implements the full CEC wire protocol. The class in and of itself is (mostly) platform agnostic. To use you would have to subclass it to implement the arduino specific code.

It implements auto acknowledging frames addressed to it. It handles frame retransmission, line arbitration, etc. Receiving and transmitting are all handled through the state machine.

I have a little bit left on the transmission side to implement and I need to build some tests for the code. When its done and functioning, I'll post the code here.

phil

Awesome Mike! Phil, looking forward to what you come up with.

I put together an EAGLE library for a FCI hdmi receptical:
http://www.andrewncarr.com/hdmi/hdmi.lbr

Mouser part for 71 cents each:
649-10029449-001RLF

This is my first attempt at using EAGLE, so I can't guarantee it is correct, and the naming isn't consistent, but I think I got it. I'll probably do a breakout PCB design tomorrow to connect it to pin headers. At some point we could do an entire pcb design, with AVR chip, FTDI chip, USB and HDMI connectors, etc.

I've got my code working in the test framework. I need to add some code to stress things a bit but I've at least got basic functionality. The only thing in the wire protocol that I haven't implemented yet is sections 7.2, 7.3 and 7.4. 7.2 (flow control) will be easy to implement. 7.3 needs to occur at a higher level and 7.4 would be very simple to add.

I'll probably post my code tomorrow. I want to spend some time tonight cleaning things up.

My next step will be to implement the arduino side of the code with 2 CEC devices implemented on the breadboard with wiring done so that both are connected and one can act as a initiator and the other as the follower. Then I can hook up an oscope with data capture and verify that the wire level activity actually looks correct.

Making progress...

phil

Hi phil,

I'm curious about your code! Do you see a chance to merge our code?

My next step will be to implement the arduino side of the code with 2 CEC devices implemented on the breadboard with wiring done so that both are connected and one can act as a initiator and the other as the follower.

That's what I have done with my code and hardware: The same Arduino sketch is working as initiator and follower at the same time, this means it can receive its own message which is really nice for testing. This works because receiving is done completely in the ISR and sending is based on busy waiting (with IRQs enabled).

The check with the scope looks good.

The current limitation of my code is the ACK handling in the ISR, because this requires time based IRQ (ACK must be active for 1.3 to 1.5 ms) and cannot be done using the PIN change IRQ. At the moment I'm using delayMicroseconds() which means the main sketch is blocked during ACK handling in the ISR and the send function cannot read the ACK bit. It also blocks the Arduino timer IRQ which is used for mills() / micros().

After completing this issue, I will rewrite the send function to be also completely IRQ based, so it runs asynchronously.

MikeT

I don't really run the state machine directly from an ISR. I would have to deal with serialization issues if I did. My (pseudo) code runs like this:

LineStateISR()
{
lineStateChangeFlag = true;
}

wait = -1;
MainLoop()
{
if ((wait != -1 && wait <= micros()) || lineStateChangeFlag)
{
lineStateChangeFlag = false;
wait = device.Process(); // run the CEC state machine
}

// do some other processing...
// or sleep util micros() <= wait (as long as it can be awakened by the ISR)
}

Feel free to download:
http://theburrs.net/CEC.zip

Oh another thing not implemented: my code will retry a transmission indefinitely instead of the max 5 times.

New version:
http://theburrs.net/CEC-2.zip

This implements retransmit limit (5) and CEC Line Error Handling per CEC 7.4. General bug fixes and code cleanup. The test code now implements 3 virtual devices which forward a message round robin to each of the devices.

Next I'm going to implement the higher levels of the protocol, namely CEC sections 10 and 12.

You wrote in the first post that you want to use this (Arduino) with your HTPC. Can you elaborate what your exact goals are?

I am interested to know because I also use a HTPC.

In general terms, I want my HTPC to function as a CEC device allowing all things to be controlled by a single remote control.

In specific terms, I'm building an arduino based device that sits on the HDMI line and will also connect via serial usb to the HTPC. The device will receive and send CEC commands to the computer through the serial usb line.

Initially I want to control my HTPC through my TV remote control. Eventually I would like to be able to do other things such as launching a bluray by switching the TV to the appropriate input and sending codes to the bluray to start playback. I'm also considering adding IR reception to my device and using a universal remote to control everything from the HTPC.

Single remote nirvana...

phil

New version:
http://theburrs.net/CEC-3.zip

This version adds beginnings for higher levels of the protocol. It does logical address allocation per CEC section 10.2. It has a lot of code reorganization and refactoring for the test code. More bug fixes.

Enjoy..

phil

Sorry for the noise. I am new to the Arduino project.

I read this topic carefully - great project.

At the end there will be a breakout board for the Arduino (nano ?) which has 2 HDMI connectors (in/out). One will be connected to the TV set, the other to a HTPC. The CEC in/out will be sent/received via the USB connection to a PC. That way a HTPC can be driven by the remote control of the TV set.

Am i right ?

That is my plans for the project. Others may have slightly different needs.

For me this is exactly what i need.

Having already a VDR system (linux) running this would be the cream on it.

I think full pass through might be a challenge, the video/audio signals have much stricter tolerances. However, for people just coming to the topic, it isn't a requirement to use pass through in order for it to work, a separate port should work, with only the expense of using up an HDMI port. Though if this project went as far as having custom PCBs fabricated, I imagine traces meeting requirements for pass through could be done correctly.

For the EDID address resolution: is the DDC i2c bus on hdmi run at 5v or 3.3v? I know DDC provides a dedicated 5v supply pin, but the specs I've read so far didn't clarify if the signaling lines were also 5v. w/USB, the power is 5v but the signal is 3.3v, so I don't assume anything in the case of DDC and HDMI.

I'm using RadioShack.com Official Site - America's Technology Store for passthrough. It's easy to pop open. The pins are easy to solder. I'm just tapping pins 13, 15, 16, 17 and 19.

As for the 5v vs 3.3v for the DDC i2c bus. That's a very good question. I'll see if I can borrow a scope and answer that. My next Q would be can the arduino drive the i2c directly or does it need some circuitry. I guess that question depends on yours being answered first. DDC is a VESA spec but I haven't found a free PDF of it yet.

Also have you given thought to the hot plug detect signal and wiring it to the arduino?

My CEC code is coming along very nicely. I've added broadcast support, promiscuous mode (receiving frames not addressed to me) and monitor mode (disables writing to the CEC line). It's time for me to get the hardware side of things moving along.

phil

I think interfacing with i2c only requires a couple pull-up resistors:
http://www.nearfuturelaboratory.com/2007/01/11/arduino-and-twi/

If we use EDID to set the device address, may as well do things proper and check the hotplug before initiating EDID queries. I think it is just sensing the state on a pin, easy even for someone new to this like me!

Has any one come across actual examples of CEC device command dialogs yet? As in, BrandX DVD player telling the TV to switch inputs looks like the following packets?

Very exciting to see this coming together, can't wait for the first successful device manipulation. Would "first packet" be the equivalent term to a telescopes "first light" ? :smiley:

Yes very exciting.. I will probably be testing my arduino with my CEC code hooked up to a scope tomorrow. If all goes well, I may be pinging my TV this weekend.

There are generic commands in the 1.3a spec which general 'classes' of devices must accept. However, my TV (LG) won't recognize my blue ray (Sony). My guess is that the TV is making the decision based upon the vendor ID of the dvd player. It might be cool if I could forge a packet for my DVD player with an LG vendor ID and see if it will start controlling my DVD.

As far as vendor specific commands are concerned, I haven't found any documentation anywhere. My guess is that it would take someone dumping CEC traffic between two same vendor devices to reverse their vendor specific codes.

They may not use vendor specific codes. It may be (as I am hoping) that my LG tv will send generic codes once it identifies an LG dvd.

Maybe what we'll need is a program that will proxy CEC commands over the internet. If someone had a Sony TV, we could proxy the CEC commands to my Sony blue ray and reverse things. The CEC spec has a desired max response time of 200 ms with a required max response time of 1 second. If round trip pings were acceptable, this could work.

phil

New version:
http://theburrs.net/CEC-5.zip

New features:
broadcast support, promiscuous mode, monitor mode

A few bug fixes...

This includes a preliminary arduino sketch which doesn't have the hardware pins hooked up but that's coming soon...

phil

HDMI-CEC over TCP/IP, I love it! ;D Reminds me of Kali, the old service for playing IPX games over the internet back in the day.

I'll ask around at work and check with some friends, I'm sure I can come up with someone who has matching gear, or a blu-ray player I can borrow. It should be really easy to find someone with a ps3 and sony tv, and I think samsung blu-ray players are somewhat common?

From what I've read, current generations of hardware speak very different dialects over CEC:
http://www.cepro.com/article/hdmi_to_enhance_cec_two_way_control_protocol

So I don't think it is a matter of just changing vendor ID in commands.
Browsing around the hdmi.org site I saw an A/V Installer presentation that mentioned TMDS required that wires in the cable be identical length to within 1/20,000 of an inch! Edit: that has to be bogus, that is .0005 mm, no way 5$ cables are made to that kind of precision. Slide 34 of the presentation: http://www.hdmi.org/installers/#

My next step is to hook up my code to a digital in and a digital out pin. Can I connect them together directly, assuming I turn on the internal pull up?

This will allow me to test the actual signal with a scope.