Quansheng TG-45UV Protocol Reversing
On a whim, I recently purchased the apparently new Quansheng TG-45UV to replace the Quansheng TG-UV2 I lost this last summer. A review and/or video might be forthcoming, but in the meantime I spent some time reverse engineering the serial protocol / data structure. If you have one of these radios and want programming software, the Quansheng TG-K4AT UV software works and is what I based my efforts on.
Most of this post will just be a text file document that I created for myself while doing the work. The protocol is a simple memory access scheme, and it appears that you read/write directly to the internal EEPROM. Unfortunately it’s not useful as a CAT scheme.
A final note is that while I was able to deduce most of this looking at the saved data files (which are raw memory dumps) from the software, I didn’t test the serial protocol reversing, so there might be additional reset codes etc. that are required. Good luck if you decide to implement a module for CHIRP or similar, that would be great to see!
MEMORY MAP FOR QUANSHENG TG-45UV
================================
OFFSET LENGTH DESC
0x0000 0x10 Fill with 0xff
0x0010 0x10 CH1 SETTINGS
0x0020 0x10 CH2 SETTINGS
...
0x07f0 0x10 CH127 SETTINGS
0x0b00 0x10 DTMF1 SETTINGS [1-9 0xa=0 0xb=* 0xc=# 0xd=A 0xe=B 0xf=C 0x10=D]
0x0b10 0x10 DTMF2 SETTINGS
...
0x0be0 0x10 DTMF15 SETTINGS
0x0bf0 0x10 Fill with 0xff
0x0e20 0x40 RADIO OPTIONS
0x0f60 0x10 VFOA SETTING
0x0f70 0x10 VFOB SETTING
0x0fd0 0x40 Unknown data
0x1000 0x10 Fill with 0xff
0x1010 0x10 CH1 NAME [0-9A-Z]
0x1020 0x10 CH2 NAME
...
0x17f0 0x10 CH127 SETTINGS
0x1f60 0x10 VFOA OPTIONS
0x1f70 0x10 VFOB OPTIONS
CHANNEL SETTINGS BLOCK
----------------------
0x00 0x4 RX FREQ [BCD LE]
0x04 0x4 TX FREQ [BCD LE]
0x08 0x2 RX TONE [i16 LE]
- all bits set - no tone
- n & 0x2000 - DCS - code is in lower 12b
- n & 0x8000 - if DCS, inverse code
- neither bit set - CTCSS - tone is lower 12b * 0.1Hz
0x0a 0x2 TX TONE [i16 LE] (see above)
0x0c 0x1 FLAGS:
[ MSB | | | / | | | LSB ]
[ | | | / BCL | | ]
[ | | | / Y:1 | | | ]
0x0d 0x1 FLAGS:
[ MSB | | | / | | | LSB ]
[ |SCAN?| POW | W/N /PROG?| | | ]
[ | Y:1 | H:1 | W:1 / N:1 | | | ]
0x0e 0x1 UNKNOWN:
[ MSB | | | / | | | LSB ]
[ | | | / SIGCODE-1 i4 ]
[ | | | / ]
0x0f 0x1 UNKNOWN
RADIO OPTIONS BLOCK (0xe20)
---------------------------
0x00 0x1 B_DISPLAY - 0=number 1=name 2=freq
0x01 0x1 VFOA_STEP - 0=2.5 1=5 2=6.25 3=10 4=12.5 5=25
0x02
0x03
0x04
0x05 0x1 VOX, 0 = off 1=on
0x06
0x07 0x1 BDR (dual watch) - 0=off 1=on
0x08
0x09 0x1 TOT - (n+1) * 15s, max value 0x27 = 600s
0x0a 0x1 ANI_ONPRESS - 0=off 1=on
0x0b 0x1 ANI_ONRELEASE 0=off 1=on
0x0c
0x0d 0x1 BEEP - 0=off 1=on
0x0e 0x1 VOICE - 0=off 1=on
0x0f
0x10 0x1 DTMF_SIDETONE - 0=off 1=keypad 2=id code 3=both
0x11
0x12 0x1 VFOB_STEP - 0=2.5 1=5 2=6.25 3=10 4=12.5 5=25
0x13 0x1 POWER_SAVE - 0-4
0x14 0x1 PTT_ID_DELAY - 0-30 ms
0x15 0x1 PTT_ID - 0=off 1=begin 2=end 3=both
0x16
0x17 0x1 A_DISPLAY - 0=number 1=name 2=freq
0x18 0x1 SCAN_RESUME - 0=time 1=carrier 2=search
0x19 0x1 AUTO_LOCK - 0=off 1=on
0x1a
0x1b 0x1 DTMF_ON_TIME - n*10 + 50 ms, 0-195 (max 2000)
0x1c 0x1 DTMF_OFF_TIME - n*10 + 50 ms, 0-195 (max 2000)
0x1d 0x1 WAIT_COLOR - 0=off 1=green 2=red 3=yellow
0x1e 0x1 RX_COLOR - 0=off 1=green 2=red 3=yellow
0x1f 0x1 TX_COLOR - 0=off 1=green 2=red 3=yellow
0x20 0x1 ALARM_MODE - 0=tone 1=code 2=site
0x21
0x22 0x1 TX_DURING_DW - 0=disable 1=CHA 2=CHB
0x23 0x1 TAIL_NOISE_CLEAR - 0=off 1=on
0x24 0x1 PASS_REPERT_NOISE (???) - n * 100
0x25 0x1 PASS_REPERT (???) - n * 100
0x26 0x1 POWER_ON_DISLAY - 0=all segments 1=message
0x27 0x1 ROGER_BEEP - 0=off 1=on
0x28 0x1 CH_MODE_MENU - 0=off 1=on
0x29 0x1 FM_RADIO_ENABLE - 0=off 1=on
0x2a
0x2b 0x1 RESET_ENABLED - 0=off 1=on
0x2c 0x1 VFO_MEM - 0=vfo 1=mem
0x2d 0x1 KEY_LOCK - 0=off 1=on
...
0x3a 0x5 ANI_CODE
...
0x4e 0x1 ABR (backlight timer) - 0-5 (seconds)
VFO OPTIONS BLOCK (0x1f60)
--------------------------
0x00 0x1 SHIFT - 0=off 1=+ 2=-
0x01 0x4 OFFSET - BCD * 10KHz
...
COMMANDS
========
serial 9600bps
MAGIC NUMBER - 0x49 0x69 0x4e 0x48 0x53 0x47 0x30 0x4e 0x02
EXPECT 0x06
IDENTIFY RADIO - 0x02
EXPECT 0x06 + MODEL "J5602C" + 0xf8 (cksum?)
ENTER MEMORY MODE? - 0x06
EXPECT 0x06
READ MEMORY - 0x52 [2 byte address] [1 byte length]
EXPECT 0x57 [2 byte address] [1 byte length] [n bytes data]
WRITE MEMORY - 0x57 [2 byte address] [1 byte length]
EXPECT 0x06