Sunday, March 27, 2016

Hacking Honda Odyssey 2007 RES DVD-player: part 2

Part 1: Overview
Part 2: Hardware (This part)


I finally built a PCB that works great and  even helped me to track down a nasty bug (took me a while, too. Hang on here with me, I'm actually going to tell you about it because it's fun).
But now, hardware.

My home PCB manufacturing process does suck

I'm very much not proud of neither how PCB turned out nor my soldering. But I decided I'd still show this as it does the job, and at this point this is kind of OK with me. Note that RCA connectors are to be connected with the green header with shielded wire and I didn't have anything laying around, that's why it just hangs there.

This one will be very simple – only the components that allow to emulate DVD presence and bypass audio/video signal to the head.
What we heed first of all, is the communication channel between the audio head and the emulator. As you remember from the previous part, we have an inverted UART, operating at 9600 8e1. This means that it sends 9600 bits per second, and a frame consists of 1 start bit, 8 data bits, 1 even parity bit and 1 stop bit. The UART is inverted; the way it works, is a receiver pulls up the line and the transmitter holds the line down (active LOW) and releases it for short periods of time to clock out bits.


We need to pull the line up to a certain voltage and when the audio sends the signal, read it. I just measured the voltage on the RX line of the audio and it's around 2volts. I just use a simple resistor divider to hold my RX line at the 2volts and than a mosfet inverter to feed the signal to the MCU.

Some MCUs can actually invert UART signal, so you may end up having different configuration.
Here R1 and R3 form the voltage on RXD line and the formula is:

RX_VOLTAGE = VDD * R3 / (R1 + R3)

E.g. if you have VDD of 5 volts (convenient to be able to power up some USB devices!), and your R1 is 10k (good value, high enough), your R3 will be ~6.6k, so 6k2 or 6k8 will play nicely.
When choosing a mosfet, remember about the Vgs – the threshold voltage that will open the transistor. It has to be less, than 2V, so your standard logic level MOSFET will probably not work. As I type, I think an inverter gate will be actually a better fit for the task.


The audio pulls the line high, and we need to pull it low to communicate, so I just use a MOSFET in open collector configuration.


I used PIC16F1827 as it's the easiest for me. This MCU cannot invert UART signal (it actually can, but with a lot of black magic). It doesn't really matter what MCU to use as long as it has UART. If you are planning to build something bigger out of this (e.g. bypass/spoof commands on the comm line, you'd rather have 2 UARTS and if you are going to connect it to a computer - all three of them). I'm pretty sure Raspberry Pi can be set up to  do the job with scripts and that was my initial intention, I even ordered some headers to connect my PCB to the Raspberry Pi, but then decided I'm to lazy to write another communication script now.


Believe it or not, three days of restless googling yielded the result – I was able to find the model of the connector used in DVD and actually order it from Mouser. This is the DVD part (PCB mount):
Mouser Part #: 656-IL-AG5-22P-D3L2
Manufacturer Part #: IL-AG5-22P-D3L2
And this is the audio head part (wire crimp mount):
Mouser Part #: 656-IL-AG5-22S-D3C1
Manufacturer Part #: IL-AG5-22S-D3C1
The manufacturer is JAE Electronics.

Overall design

I had a few issues wen designing this PCB and one of them is that I didn't save the PCB layout. It's not a big deal as the MCU uses only two lines to communicate and it needs a normal layout anyway, so I don't worry too much about this. I yet to figure out how to publish the files, so you can probably use the library I created for connector, schematics itself and the firmware for the MCU. Actually, here they are!
Again, some pretty lousy Eagle skills there..

Ah, the bug! Nearly forgot.

The bug

SSO I did build an ugly board, and it didn't work initially, but took very little troubleshooting to start. Than interesting things started to happen. The board worked in the car. Until it wouldn't. It took about 3-4 minutes for it to stop working. And then I couldn't make it work, again unless I killed the ignition and restarted the car. And it worked again for another 3-4 minutes. So definitely doesn't look like MY board issue, right?
As the only display I had was a bi-color LED, I only knew that it receives a request from the head, but thinks it's not a properly formatted frame. What the hell? Can the head figure out I'm messing with it? Are there any requests that it sends that I miss and do not respond to so it can tell there's something instead of DVD? Why would anyone took such a precaution? I mean it's just a car and just a DVD player...
Spent most of the day to figure that out. Tried many things and was almost ready to switch on my soldering iron again... But. But. I luckily decided to exhaust my firmware possibilities first. And what I figured out, if you don't check for the correctness of the frame, but just respond to it in a way as if it would be a normal frame, it works. Interesting! I started digging into my code and figured I made a mistake in one of the places where check sum was calculated. IT ONLY USES 7 LSBs of the sum! Fixed that and it worked as a charm!
So what was happening, when you restart the car, the frame ids would start from 0x00. And the checksums were some numbers less than 128. But the frame id keeps incrementing and eventually the checksum would roll over 127 to 0. My code that calculates checksums for packets to respond was correct and would do that, so I respond to the frames correctly. However when I was receiving the packets, at some point I would expect to see the checksum of 128, and I would be receiving 0, so I flagged that frame as incorrect. The audio head though seems to be persistent and if it doesn't get a response to a frame, it retries several times and then figures there's nobody on the line! And then just stop offering DVD mode.

No comments: