Adding Apple CarPlay to a 2013 Volvo XC70

Adding Apple CarPlay to a 2013 Volvo XC70
I don't recommend this :p

The Sensus navigation system in my car stopped receiving updates, and I needed a way to get my phone's maps on my car's screen. I originally looked into getting a standard double-DIN radio, but when I took the dash apart, it was a completely closed, custom-built system.

I decided to ditch the original idea and use an aftermarket HDMI screen from Amazon and design a system that could switch between the display signal from the original system and the display signal from the device that ran CarPlay. I researched a couple of HDMI converter ICs, but most of them required a license as they contained HDCP decryption keys (ahem Analog Devices.) Eventually, I stumbed on the TFP410 from Texas Instruments. It came in a QFP package and converts the RGB signal (to the original screen) to an HDMI source.

Volvo ICM with case removed (before frying it)

I tried to find a datasheet for this LCD panel, but it had been discontinued and the manufacturer was bought out. I emailed some companies overseas and had no luck. Time to do some digging!


The panel in the car utilized a 60 pin FPC cable, and all of the contacts were actually broken out right underneath the connector, so I started probing for power and ground pins to reduce the pins I would need to test. I ended up with more than 30 pins that I needed to test, but I plugged my Saleae Logic into 16 of them at a time, and I was surprised at how easy it became once I was able to see the stream of data across the pins. In total, I needed to identify four timing wires, and 18 for the RGB666 stream.

Identifying VSYNC was easy as it was sending a 60.0-60.1hz signal, so that was also easy. HSYNC and DE were slighly less straightforward as most TFT panels, utilize something called a "blanking period," where the display is still being clocked, but no pixels are being output to it. This means that the DE and HSYNC wires would be identical with only slight differences.

signals found and identified.

For the RGB pins, I just soldered a wire to 3v3 and touched it to them to see what the effect was. Touching certain pins made the display more (or less) red, green, or blue, and from that it was easy to determine which pins were the most or  least signifigant byte for each of the colors.

So, I opened up Excel and started to create my own "datasheet" of sorts to keep up with what I had discovered about this panel so far. I kept it simple with 60 rows, 1 for each pin.


As I was putting the ICM back together, I shorted the back of the display to the motherboard and the magic smoke decided to come out.  The only casualties on the board were the two base resistors on the FETs that drive the optical communication lines for the Volvo's MOST bus.

board fixed with 2 10㏀ resistors, luckily :)

This pushed the project back a couple of days as I had to fix the board before I would be able to do anything else.


With the display out of the way, I needed to design a board that could plug into the display output on the infotainment board, provide a HDMI output for the screen, and provide a HDMI input from whatever I am going to use to power CarPlay.

I settled on the TFP410 and I found a 2-port HDMI switch also from TI. I chose a SAMD21 to run the software as it provided enough GPIO pins to work with everything. Integrating the buttons on the steering wheel took more than I had expected. I thought that it would've used the CAN bus, but it used a dedicated LIN bus directly between the controls and the ICM. I cut that wire in half and am using the Arduino as a proxy between the (now two) different buses. For communicating with the car's CAN bus, I used a serial to CAN adapter with custom firmware

Revision 1 was supposed to work, but there were so many issues on this design that I decided to remake the whole thing. I had problems using the I2C bus, the solid state relay, and even the microcontroller itself.

Revision 2 was actually never ordered as I made the board too big and the fab house tacked on an extra $100 charge for a large board. So, I kept the same schematics and made revision 3. For the LIN bus, I went with 2 transcievers, one to act as master to communicate with the steering wheel and another as a slave to communicate with the infotainment console.

So, the next thing to do was to figure out how I was going to run CarPlay in the car. I debated between buying a used NUC on Ebay and running Android-X86 or just going with a Raspberry Pi 4 running a fork of LineageOS built for the Pi. To enable CarPlay functionality, I found a USB dongle on Aliexpress than enabled the functionality. Hooking these up on the kitchen counter ended up working great and I decided that this would be what I put in the dash.


I ran into an issue while trying to send LIN frames from my board. I needed a way to generate the 13 bit 'header break', but my UART would only send data in groups of 13 bits. I ended up using a transistor to manually drive the line low for 13 bit times. Using the Saleae confirmed that this worked. I also decoded the CAN bus to provide events to the Raspberry Pi when any dials or buttons are pushed to show the same popups and controls on the screen via a custom Android app.

analyzing lin bus traffic

I had to scan the CAN bus to find the messages associated with each of the buttons on the center console, and luckily, they were all inside three CAN addresses. One was controlling the two dials, while the other two dealt with the air controls and the keypad buttons. I posted my findings in the GitHub project linked at the bottom.

Now, the original Sensus infotainment OS shows little "modals" whenever the volume is turned up, or whenever the air settings are changed. I replicated these by having an always-running Android app that listened for messages over USB and used the "draw over other apps" permission.

This project wasn't easy but the outcome was totally worth it. I still have access to the original screen by holding the Menu button on the dash and can switch between the two easily. All of the original buttons function in both modes as well due to the converter board. I learned a ton from this project and it was the first time I had used a logic analyzer of any kind and I honestly wouldn't have been able to do this without it. I 100% recommend the Saleae to anyone.

I still have a couple of issues that I need to fix before I count this project as completed.

  • Steering wheel controls don't reliably control original system
  • Center console FF/RW buttons fast forward twice when pushed 0nce.

I'll try to fix these in the future by having my board send commands over the CAN bus instead.

I have published the code for the Android app:

acvigue/VolvoCarPlay-APK
Contribute to acvigue/VolvoCarPlay-APK development by creating an account on GitHub.

the firmware for the SAMD21 chip:

acvigue/VolvoCarPlay-SAMD
Contribute to acvigue/VolvoCarPlay-SAMD development by creating an account on GitHub.

and the CAN bus converter board

acvigue/VolvoCarPlay-CANbus
Alternate firmware for the Serial to CAN bus adapter by Longan Labs - acvigue/VolvoCarPlay-CANbus