Note : All that follows results from observation as a "man in the middle", the goal being to write interoperable software. No confidential information has been disclosed to us.
Levels observed between CD Changer and Head Unit are roughly 1V for low and 12V for high. For most PCs, a simple 10K resistor between pin 13 (resp 14) and Rx pin of serial port 1 (resp 2) should allow to capture the dialog on both ports at the same time. A cleaner approach is to use a real RS-232 tranceiver chip (MAX232 or equivalent) but don't forget to invert the signal again as the MAX inverts it in the first place.
The communication is asynchronous serial, 9600 baud, 8-bit, even parity, 1 stop bit.
The protocol consists of frames exchanged between head unit and CD changer. Each frame sent by one device is followed by an acknowledgement from the other.
Object | Value | Length |
---|---|---|
FRAME= | <FRAME_HEADER><FRAME_ID><DATA_LEN><DATA><FCS> | variable |
FRAME_HEADER= | 3Dh | 1 byte |
FRAME_ID= | Id, incremented at each frame sent and cycling (0>1>...>255>0>1>...) | 1 byte |
DATA_LEN= | Size of following <DATA> part | 1 byte |
DATA= | <PAYLOAD TYPE> <PAYLOAD> | variable |
PAYLOAD_TYPE= | Type of message carried by this frame, see below | 1 byte |
PAYLOAD= | Contents of message, dependant on message type | variable |
FCS= | Checksum, calculated as a XOR of all other bytes of the complete frame | 1 byte |
ACKNOWLEDGE = | C5h | 1 byte |
PAYLOAD_TYPE | Description and PAYLOAD details | PAYLOAD length | Symbolic
name (+obsolete name) |
PAYLOAD Example |
---|---|---|---|---|
11h | Observed as the first 2 frames after head unit
is turned on. Could be a message sent while changer is booting. Value is alternating 60h and 06h |
2 bytes | BOOTING | 60h 06h |
13h | PAYLOAD 02h 26h observed when HU requests a CD that is
not present in
the CD changer (displays "NO CD"). PAYLOAD 02h 86h observed when switching source to CD changer while the changer is still checking CDs after tray was inserted (displays "CD CHECK"). |
2 bytes | CD_CHECK | 02h 86h |
15h | Observed after the 2 BOOTING frames. Could be a signal to say changer is ready | 2 bytes | BOOT_OK | 00h 25h |
20h | Observed numerous times when CD is not playing,
notably just after the BOOT_OK, when a CD change is requested,
when the CD is on PAUSE, when the HU is on "Tuner" source and when tray
is removed or being checked. PAYLOAD = <A> <B> 09h 05h <C> <A> = CD State (see below) <B> = Tray state (see below) <C> = CD Number, or 00h if tray is ejected. |
5 bytes | STATUS (STANDBY) |
01h 03h 09h 05h 01h when tuner is playing <A> <B> 09h 05h <CD NUMBER> when a long operation is in progress 01h 02h 09h 01h 00h while tray isn't present |
21h | Observed after the STANDBY in the boot
sequence, when changing track, during FFWD or REWIND, when
loading another CD or when tray is being checked. PAYLOAD = CD State (see below) |
1 byte | CD_OPERATION (BUSY) |
05h |
22h | Observed mainly when changing CD, and while tray
is being ejected PAYLOAD = <A> <B> <A> = Tray state (see below) <B> = CD Number, or 00h if tray is ejected. |
2 bytes | TRAY_OPERATION (CD_LIFE_CYCLE) |
05h 01h 02h 00h when tray is being ejected |
23h | Observed while tray is being ejected, first frame with PAYLOAD=08h, then another with 09h | 1 byte | TRAY_EJECTION | 08h |
25h | Observed in the startup messages (twice), and
after each random status change (on/off) PAYLOAD=03h if random is OFF PAYLOAD=07h if random is ON |
1 byte | RANDOM_STATUS | 03h |
26h | Observed in the startup messages, as the first
frames when tray is inserted and as each CD is being checked PAYLOAD = <A> <B> <C> <C> <A> = probably CD State (see below), plus 82h when tray is being inserted. <B> = CD Number, or 00h if tray is ejected. <C> = CD Bitmap (see below), or 00h if tray is ejected. (byte C is repeated twice for an unknown reason) |
4 bytes | TRAY_STATUS | 05h 01h FCh FCh |
27h | Observed when changing tracks PAYLOAD = <A> <TRACK NUMBER> 22h. When staying on same CD, A=80h when starting change and 10h when done (or 15h when done and track# = 1). When track is on antoher CD, A=40h when starting and 14h when done Track number is BCD encoded |
3 bytes | TRACK_CHANGE | 80h 01h 22h |
46h | Observed in startup sequence and when changing
CDs. PAYLOAD = <TT> 01h 00h <TRT HOUR> <TRT MINUTE> <TRT SECOND> where TT= Total number of Tracks on CD TRT = Total Running Time of CD, with each part HOUR, MIN, SEC being BCD encoded |
6 bytes | CD_SUMMARY | 14h 01h 00h 77h 30h 54h |
47h | Observed while CD is playing. PAYLOAD=<TRACK NUMBER> 01h <CD TIME HOUR> <CD TIME MINUTE> <CD TIME SECOND> <CD TIME SECTOR> <TRACK TIME HOUR> <TRACK TIME MINUTE> <TRACK TIME SECOND> <CD TIME SECTOR> Track number and all time parts are BCD encoded |
10 bytes | PLAYING | 01h 01h 01h 13h 45h 67h 00h 02h 45h 00h |
Value | Meaning |
---|---|
01h | NO_CD_LOADED |
03h |
PAUSED |
04h | LOADING_TRACK (or PARKED ?) |
05h | PLAYING |
07h | CUEING_FWD |
08h | REWINDING |
09h | CD_READY |
0Ah | SEARCHING_TRACK |
Value | Meaning |
---|---|
02h | NO_TRAY |
04h | LOADING_CD |
03h | CD_READY |
05h | UNLOADING_CD |
PAYLOAD_TYPE | Description and PAYLOAD details | PAYLOAD length | Symbolic name (+obsolete names) | PAYLOAD Example |
---|---|---|---|---|
13h | 0 byte | START_PLAY | ||
17h | 1 byte | NEXT_TRACK | 01h | |
19h | 0 byte | STOP_PLAY | ||
1Ch | 0 byte | PAUSE | ||
20h | 1 byte | FAST_FWD | 0Ah | |
21h | 1 byte | FAST_REW | 0Ah | |
22h | 2 bytes | PREV_TRACK | 01h 02h | |
24h | 0 byte | NEXT_CD | ||
26h | PAYLOAD=<CD NUMBER> | 1 byte | LOAD_CD | 02h |
27h | PAYLOAD=<RANDOM STATUS> 0Ah RANDOM STATUS=07h for ON, 03h for OFF |
2 bytes | RANDOM | 07h 0Ah |
86h | 0 byte | REQ_CD_INFO | ||
93h | 0 byte | HU_ON (ACCEPTED) |
||
94h | 1 byte | CD_CHECK | 80h |
if you feel it deserves it... | This project is hosted by |