Menu
andipanda.dev

From Carlinkit Audio Issues to My Own CarPlay Implementation

From Finishing CaRadio to a New Idea

In my previous articles, I described the development of my custom CaRadio car head unit in detail. Step by step, the project reached a point where I could use it properly in my car.

After a long trip, during which I tested the head unit under real driving conditions, there were still a few issues to address. One of them involved audio handling when using CarPlay through the Carlinkit adapter.

The problem was related to navigation prompts.

When the navigation app started playing a voice prompt, CaRadio received the corresponding event and could lower the music volume. However, I never managed to determine exactly when the prompt ended.

As a result, the music either returned to its previous volume too early or remained quiet for longer than necessary.

I had to use a workaround based on time delays. After several experiments, I found an approach that worked reasonably well in practice.

At that point, the first version of CaRadio was essentially complete.

The head unit worked, CarPlay connected, music played, and navigation functioned. In fact, this implementation is still working today.

But I knew perfectly well that the problem had not been solved properly. Instead of responding to an actual event indicating the end of a navigation prompt, the program simply waited for a predefined amount of time.

That small technical compromise eventually led me in a completely new direction.

Trying to Understand the Carlinkit Protocol

Although the first version of CaRadio was already working, the problem of detecting when navigation prompts ended continued to bother me. I decided to return to the Carlinkit protocol and try to find a more appropriate solution.

By that point, I already had a fairly good understanding of the data exchange between CaRadio and the adapter. However, some commands and events were still unclear. Perhaps Carlinkit was sending the information I needed, but I simply did not know how to interpret it. I also considered the possibility that the adapter did not expose the necessary events at all.

I started searching again for documentation, source code, and reverse-engineering research. This time, I was interested not only in the commands exchanged with Carlinkit but also in how the adapter itself worked internally — particularly how it communicated with the iPhone.

Gradually, my research went beyond the original problem. I increasingly came across materials about native CarPlay connections without using ready-made adapters. Information was scarce and scattered across different sources, but this was when I once again turned my attention to MFi hardware authentication.

At some point, I began to wonder: if I could understand the authentication mechanism and communicate directly with the iPhone, would I be able to eliminate Carlinkit entirely?

MFi and Hardware Authentication

While researching CarPlay, I once again encountered references to MFi — Apple's Made for iPhone program.

Certain types of communication with Apple devices require a dedicated authentication chip. This chip performs the necessary cryptographic operations without exposing private keys directly to the software.

The idea of using such a chip for my own CarPlay implementation seemed interesting.

But there was an obvious question: where could I get one?

MFi authentication chips are not ordinary electronic components that you can simply select from a distributor's catalog and order in any quantity.

However, I already had a Carlinkit U2W Mini adapter.

So I decided to see what was inside.

Disassembling the Carlinkit U2W Mini

After opening the adapter, I started examining its circuit board.

I was less interested in the processor and memory than in the components responsible for communication with the iPhone.

Eventually, I managed to identify the authentication chip I needed.

This was an important discovery. I now had not only information about the existence of such chips but also a real component I could experiment with.

However, I initially decided to try a different approach.

If I could gain access to the adapter's operating system, I might be able to examine its software and understand the protocol much faster.

Attempting to Access the System Through UART

I found a UART interface on the U2W Mini circuit board and tried to use it to connect to the adapter.

Part of the task was relatively straightforward.

The adapter transmitted data through the serial interface, and I could observe its output.

However, I could not establish full two-way communication.

Although I was receiving data from the adapter, the commands I sent did not produce the expected results.

I tried to investigate the cause, but I could not quickly gain access to the operating system.

I did not want to spend more time on this approach at that point, so I temporarily put the UART experiments aside.

Still, disassembling the adapter had already produced a useful result: I knew where the MFi chip was located and could return to it later.

Searching for Information About Native CarPlay

After failing to gain access to the U2W Mini operating system, I continued my research.

But I was no longer interested only in the Carlinkit protocol.

Gradually, another idea emerged: was Carlinkit really necessary at all?

If I could understand how the iPhone connection worked and gain access to the required authentication chip, it might theoretically be possible to implement CarPlay directly on a Raspberry Pi.

That would mean I no longer needed a ready-made adapter acting as an intermediary between the iPhone and my head unit.

The main problem was the lack of information.

There were scattered pieces of documentation, protocol discussions, examples of MFi communication, and some research findings available online.

But turning all of that into a complete working implementation was far from easy.

I spent a considerable amount of time gathering information, piece by piece.

Nevertheless, the materials I found suggested that implementing Native CarPlay on a Raspberry Pi was entirely possible.

And that was when I remembered the LIVI project again.

An Unexpected Discovery in LIVI

I was already familiar with LIVI from my earlier CarPlay experiments.

The project had helped me understand certain aspects of communication with adapters and had been one of my sources of information while developing CaRadio.

I decided to check what had changed since the last time I examined its source code, so I opened the repository again.

And I discovered something I had not expected at all.

LIVI already included a Native CarPlay implementation.

What made it even more surprising was how recent those changes were. Judging by the project's history, they had appeared within just a few weeks while I was testing CaRadio and making the final improvements.

It was a rather amusing situation.

I had spent a great deal of time searching for scattered information, studying possible authentication methods, disassembling Carlinkit, and trying to gain access to its operating system.

Meanwhile, a project I already knew had gained an implementation of exactly what I had gradually been working toward myself.

Of course, that did not mean I could simply copy a few files and instantly have a fully working system.

I still needed to understand the source code, connect my own hardware, test communication with the iPhone, and adapt the necessary components to my requirements.

But now I had a much more concrete starting point.

From an Idea to a New Project

By this point, the original task had changed considerably. Everything had started with an attempt to fix navigation prompt handling in CaRadio, but now I had an opportunity to try implementing my own CarPlay connection without relying on a ready-made adapter.

After discovering the Native CarPlay implementation in LIVI, I decided to start with the hardware. I had already located the necessary MFi chip on the circuit board of the disassembled Carlinkit U2W Mini. The next step was figuring out how to connect it to the Raspberry Pi.

Fortunately, the chip had relatively few pins. Identifying the power connections was fairly straightforward, and examining the V851 processor documentation allowed me to confirm exactly which pins were used for the I²C bus.

I soldered thin wires to the appropriate connections and attached them to the I²C bus of my Raspberry Pi 3B+.

Then I ran an I²C bus scan.

Almost immediately, I saw exactly what I had been hoping for — the address of the MFi chip.

It was a small but very important result. The chip taken from the ready-made adapter was now detected by the Raspberry Pi as a separate I²C device. The next step was to understand the authentication commands and determine whether I could use it to establish a direct connection with the iPhone.

This marked the beginning of practical work on a new project, which would later become known as CaRaBack — a name derived from CaRadio and Backend.

But detecting the MFi chip on the bus was only the first step. A much more difficult challenge still lay ahead: getting the iPhone to establish a connection with my own CarPlay implementation.

That is what I will cover in the next article.