Apple iPod Remote Protocol

From Wiki
Jump to navigationJump to search

The content of this page is by David Carne, whose original page is located here. I have duplicated this content into this wiki page for my personal use for when I don't have internet access. All content is copyright by David Carne, and all work is his. Unfortunately, due to quirks in WikiMedia, retaining the exact same formatting is impossible.

Reverse Engineering the iPod Shuffle 3G headphone remote protocol

by David Carne

Background

On March 11th, 2009, Apple introduced the third generation iPod shuffle. Shortly thereafter, criticism[1] was raised regarding the presence of a proprietary chip inside the shuffle headphones, said by some to be an authentication, or DRM measure. The "DRM" argument was unsupported by the facts, given that the shuffle would simply start playing with a non-remote headphone connected, albeit with no remote functionality. The "authentication" argument was dismissed shortly thereafter by reports that the chip was simply a "Dual Mode Modulator." [2]

I purchased an iPod shuffle in June of 2009 to use while running, since my old iPod was a bit bulky for the task. However, the first time I took the shuffle with me, the headphone remote died halfway through the run because the remote module was not designed to deal with sweat, or moisture of any kind. Some would argue that this is a fatal design flaw for a product advertised for use during exercise. Now that I had a flaky/semi-broken pair of headphones, what else was there to do but hack them! I only got around to finishing and writing up the hack in February 2010, hence the delayed creation of this report.

Disassembly and Hardware Overview

Figure 1 - Button side of the Remote
Figure 2 - Circuit side of the Remote
Figure 3 - Remote connection Diagram
Figure 4 - Traciing of the visible remote tracks

Disassembly of the shuffle headphones is simple - the enclosure snaps together, and the remote control board sits within. No photos were taken of this stage of the process, but a disassembly photo can be found at iFixit. Once disassembled, the remote board can be desoldered from the two wires attached to it. Figures 1 and 2 show the button side and the circuit side [hereafter referred to as "Top" and "Bottom"] of the remote.

The Top of the remote contains 3 sets of pads, each composed of an outer ring, and a centre contact. Over each pad a metal dome held down with an adhesive pad is placed, and the dome, when pressed, makes contact between the outer ring and the central pad.

On the bottom of the board there is an integrated circuit, a diode for reverse polarity protection and 7 passive components. Two connection pads can be found on the bottom of the board, and the headphone cable is soldered to these pads. See Figure 3 for a connection diagram.

Fig. 4 is a colorized image of the tracks and components, as viewed through the bottom of the board. By following the tracks, it becomes apparent that the play/pause button simply shorts the CTL line and the GND line. The Volume up and Volume down buttons are connected to the proprietary IC and functionality cannot be determined from simply looking at the hardware.

Investigating the Signalling

Figure 5 - Volume Up/Down Signals
Figure 6 - Basic Test Circuit

To figure out the behaviour of the Volume Up and Volume Down buttons, we must look at the signalling as it is on the control line. The control line is driven from the shuffle with a known impedance, such that if a load is placed on it, the voltage on the control line will drop. See Figure 5 for captured waveforms of up/down button presses. Volume up was measured to cause voltage droop from a nominal 2.08V down to 1.68V. Volume Down was measured to cause a voltage droop to 1.52V. The voltage droop was present for the entire duration of the button push. At this point, the meaning and source of the 4.8 millisecond grounding of the signal was unknown.

To verify the behaviour gathered so far, I built a test circuit, described in Figure 6. I left the shuffle remote in-circuit so it could generate the "power-up" signalling [described later]. This circuit worked as expected, and it even worked perfectly with the original remote removed, as long as the remote was attached at powerup to identify the remote to the shuffle. Interestingly, the 4.8ms low-pulse was still present, with only the pushbutton/resistor circuit connected, without the original remote. That indicated that the shuffle was actually generating the low pulse, not the remote. This may serve as an acknowledgement of some kind. From now on, this kind of low pulse will be termed an "ACK" pulse.

Power-On signalling

Figure 7 - Power on signals
Figure 8 - Power on waveform mimic

Given that the remote signalling works after power-on authentication, the next logical step was to look at the power on signalling. Figure 7 is two captures of the Shuffle power-on behaviour. The upper signal [in grey] is a successful authentication of a remote, and power is kept on to the remote, from the shuffle. At bottom is the same power on behaviour, except without a remote connected. The waveform seemed fairly simple, and I figured that in this case, the "low" pulse was likely generated by the remote, as I couldn't see any other distinguishing features in the waveform.

I proceeded to build increasingly complex circuitry to accurately mimic the waveforms seen in a successful authentication [RC circuits to get rise times right] culminating in the waveform in Figure 8. Figure 8 is the emulated waveform in black overlapping the original remote waveform in grey. The circuits worked by switching in and out different impedances, with timing controlled by a microcontroller. None of these attempts successfully authenticated as a remote, despite the high level of similarity between the original and emulated waveforms.

To determine where the low pulse was coming from, I monitored the current flowing to the device - a simple 1K resistor works as a current sensor. This confirmed my suspicions that the low pulse was actually another "ack", and was generated by the shuffle. So the question then was - what the heck is the shuffle seeing in the signal?

Power-On signalling - take 2

Figure 9 - ID/Auth chirp

After digging around a bunch, and building an amplified current sensor, I found the power-on detection was actually a 100mV/10uA ultrasonic chirp occurring 8.1 msec after power up. This would seem to coincide with the mention of "ultrasonic" by iLounge. Figure 9 has a blown up view of the chirp. In figure 9, the upper signal is voltage, and the lower is current. The current signal, measured with a 1k resistor, was run through a 5x preamp made from a precision op-amp to bring it up to the level seen in the figure. The ultrasonic chirp is actually a dual-frequency chirp, consisting of 1.5msec of 280khz, followed by 4.6msec of 244khz. [Doing a binary-search by hand using the scope trigger to find the transition point is no fun].

There is a configurable pulldown applied by the remote during the period between the rising edge of CTL and the ack pulse. The shuffle expects this pull to be gone after the ack pulse, and operation is unreliable if the pullup is left on. The shuffle will not recognize the remote without the presence of this pulldown

The shuffle changes the power supply after the ack pulse. During the power-on phase, the power supply floats to around 2.72V, and rests at 2.4V with the expected pulldown. After the power-on phase, the CTL power supply floats at 2.08V. [See Fig. 8 for detail].

Emulating the Remote

Figure 10 - Test prototype schematic
Figure 11 - Filter response
Figure 12 - Test prototype
Figure 13 - Good working waveforms

Now that I knew how to successfully authenticate, I could extend the circuit in Figure 6 to add the power-on chirp, and power-on pulldown. For initial testing, I used an ATmega88 microcontroller to generate the chirp and control the pulldown, as I had a bunch kicking around in my parts drawers. The downside of using that part is that it won't run on the voltage or current the shuffle can supply, meaning for this test, I used an external power supply.

First off - the microcontroller had to detect when the power came on from the shuffle. Vih for the ATmega88 operating at 5V is ~ 2.6V, so I couldn't use a regular IO pin to watch the line. The ATmega88 has a handy internal analog comparator, and it also has a convenient 1.1V reference. The 1.1V ref can be connected internally to the positive side of the comparator, so I connected the CTL line to AIN1, Pin 13, which is the negative input to the comparator. To watch for the rising edge, the firmware polls bit AC0 of the ACSR register, watching for it to go low [to indicate the input has risen above 1.1V]. At this point the firmware starts timing to the start of the chirp + enables the pulldown.

The controllable pulldown is simple - a 17.2k resistor is connected from CTL to the drain of a 2n7002 mosfet, which in turn, has its source tied to GND. [See Fig 10 for more detail]. The 2n7002 is driven via a 100ohm resistor by pin PC5 of the ATmega88. Driving PC5 high will enable the pulldown, and driving PC5 low will disable it.

Creating the chirp is slightly more complex, but the onboard PWM hardware can be used as a starting point. I used the Fast PWM mode, and OCR0A + OCR0B as a frequency generator, and then filtered out the high frequency components. A quick thrown-together bandpass filter is shown in the schematic. The base frequency is not in the middle of the filter response [See Figure 11], but the filter suffices because we only care about eliminating DC and the higher harmonics, and attenuating the generated frequency to match the original chirp. At 276khz, the filter attenuates the fundamental frequency to 186mVp-p, and the 3rd harmonic is down at 24mVp-p which is sufficient for my purposes.

I created a quick test prototype - Figure 12, which ran the code in Listing 1.

#define F_CPU 8000000
#include <avr/io.h>

#include <util/delay.h>

#define CTL_PIN (1<<5)
#define CTL_HI (!(ACSR & (1<<ACO)))

void main()
{
	CLKPR = 0x80;
	CLKPR = 0x0;
	ADCSRB &= ~(1<< ACME);
	ACSR |= ( 1<< ACBG);
	TCCR0A = 0x03;
	TCCR0B = 0x09;
	OCR0B = 7;
	DDRC = CTL_PIN;
	
	while(1){
		PORTC = 0;	
		while (!CTL_HI);
		_delay_ms(4.1);
		PORTC |= CTL_PIN;
		_delay_ms(4.2);
		
		// 280khz burst
		TCCR0A = 0x23;
		TCNT0 = 0x0;
		OCR0A = 27;
		DDRD |= 1<<5;
		_delay_ms(1.5);
		
		// 245khz burst
		OCR0A = 33;
		TCNT0 = 0x0;
		_delay_ms(4.6);
		
		// burst off
		TCCR0A = 0x03;
		DDRD &= ~(1<<5);
		
		// wait for ack pulse
		while (CTL_HI);
		// kill init pulldown
		PORTC &= ~CTL_PIN;
		
		// Just hang around and 
		// wait for loss-of-signal
		while (1) {
			while (CTL_HI);
			_delay_ms(100);
			if (!CTL_HI)
				break;
		}
	}
}

After a bit of frequency + timing tweaking, the replacement remote reliably emulated the original shuffle remote. Volume controls, play pause, and power on detection all worked.

Conclusion

So, is that chip a "DRM" or "Authentication" chip? Well, the jury is still out on that one. The ultrasonic chirp at startup is a bit suspicious, but it may be to indicate the remote type to allow for future remote expansions, or so it can behave differently when connected to a phone type device.

Given the simplicity of the chirp - my thoughts are that it is purely an identifier, and less an authentication method. Any manufacturer that wanted to design a compatible accessory without Apple's permission would be able to reverse engineer the chirp just as I did.

Future Plans

At some point in the future when I have time, I plan to build a low power MSP430 based replacement, that can run solely off the power supply generated by the shuffle. I'd like to investigate building a capacitive touch sensor remote, since that could be made completely waterproof.

References