Skip to content. | Skip to navigation

Personal tools

Navigation

Personal tools

You are here: Home / Projects / IC7000 display protocol

IC7000 display protocol

by datacop last modified Apr 16, 2012 09:07 PM
reversed display protocol of an Icom IC7000 amateur radio transceiver, for separating transceiver and head unit, e.g. remote stations

About

In 2011 I started reverse engineering the serial protocol of the ICOM IC7000 Amateur Radio Transceiver, which is used between the display and the transceiver unit.

The aim of this project is being able to detach the display unit from the radio unit and using it as a remote station, where the display unit is communicating with the TRX over network/Internet.

This is work-in-progress.

Hardware

The IC7000 uses a proprietary 10-pin connector between TRX and display unit.

pinout:

IC7000 display unit pinout

LRXD, LRXD (and GND) are used for 3,3V TTL asynchronous serial communication, using 19200, 8N1.

Framing

Both the display unit and radio unit are sending their data in binary frames

  1. starting delimiter (0xfe)
  2. comand-id (byte)
  3. variable-length payload (if any)
  4. end delimiter (0xfd)
SD (0xfe) CMD payload ED (0xfd)

Display Commands

These are the commands I discovered:

keep-alive (0x14)

Every ~200ms the display sends a keep-alive package without payload to the TRX. Without this, the TRX automatically switches off.

SD (0xfe) 0x14 ED (0xfd)

button sets

There are 4 different button set commands, each one has 1 byte payload, where each bit represents one button. (1 = pressed, 0 = released)


0x80
0x40
0x20
0x10 0x08
0x04
0x02
0x01
0x00 -
BAND_DN BAND_UP SPCH
TS
TUNER/CALL CLR
SET
0x01 MODE P.AMP/ATT MENU_UP MENU_DN F1
F2
F3
F4
0x02 NB/ADJ NR/LEV MNF/ADJ ANF/REC -
-
-
-
0x03 MIC Cable - phones
PTT - ?? (dail?) - MIC Button

rotary encoders

there are basically 3 different kinds of rotary encoders:

  • the frequency dail
  • binary rotary encoders (PBT/M-ch and RIT)
  • volume and squelch knobs
IDcommandpayload
0x07 main dail 2 or 3 bytes
0x0a PBT/M-ch 1 or 2 bytes
0x0b RIT 1 or 2 bytes
0x0c AF 1 byte
0x0d RF/SQL 1 byte

volume and squelch knobs (0x0c, 0x0d)

those are the pretty easy, the payload is just a 1-byte encoded (analog) value, 0-255.

binary rotary encoders PBT/M-ch and RIT (0x0a, 0x0b)

the encoding of this is a bit weird, this is basically a round-robin 8-bit unsigned integer with a default value of 0 after power up.

If the first byte would get bigger than 240 a second byte gets added with a value from 1-15 and the first byte is 255.

Don't ask me why this is implemented like this, I've got no idea.
(If you know why please contact me)

small python function for decoding:

def decode_multibyte(bytes):
val = bytes[0]
if len(bytes) == 2:
val += bytes[1]-15
return val

 

main dail (0x07)

this is almost like binary rotary encoders, except that the first byte is the high byte of a 16-bit integer.

def decode_dail(bytes):
val = (bytes[0] << 8 ) + decode_multibyte(bytes[1:])
return val

 

mic data (0x0e)

This packet represents data from the MIC connected to the display unit.
I'm not sure if the payload data is directly passed from the MIC IC to the TRX, I haven't looked into this yet.

startup (0xf0)

The display unit sends 0xf0 requests (no payload) after powering up to tell the TRX that it's ready to receive data. Those requests are sent periodically until it receives a startup frame (also 0xf0) from the TRX.

startup ACK (0xf1)

The display answers with 0xf1 (no payload) after it successfully received a startup frame (0xf0) from the TRX.

unknown commands

0x19
I received this frame with payloads 0x00, 0x40 and 0x43, I've got no idea what this should be.

TRX commands

LCD flicker (0x09), contrast (0x12) and unit brigth (0x17)

encoded like the binary rotary encoders PBT/M-ch and RIT with 1-2 bytes payload, value range 0-255.

LEDs (0x18)

the CLR, TX and RX LEDs on the display unit are binary encoded, 0x00 is all off.

Bit 0x80 (8) 0x20 (6) 0x10 (5)
LED CLR TX RX

LCD Bright (0x1a, 0x1b)

TODO

Backlight Switches (0x1c, 0x1d)

TODO

startup (0xf0)

same as display, display unit answers to this with the startup ACK (0xf1).

There is also an initialization string which seems to be always the same (at least for my TRX, I didn't have time yet to compare it to a 2nd unit.)
TODO

 

And now?

I started writing a script that spoofs the display unit to an attatched TRX unit, but I didn't have time yet to finish it.