This fork maintained by @johannessen
has the following differences from the original upstream
hxtool created by @cr as of this writing:
-
Add working support for other models than the HX870 (#41, #46)
-
Add
peekandpokecommands for raw memory access (#43,patch/poke-command) -
Add
navcommand for GPX navigation data (waypoints and routes) (#1, #33,patch/nav-command)- HX870 only (adding support for other models wouldn't be too difficult, but I have little interest to work on that now; you should consider using SHsync instead)
- Writing routes from GPX to the device has only been tested sporadically
-
Add executable scripts that can be run directly from the working directory, avoiding the need to set up a virtual environment and/or install
hxtool(note that this approach may require system-wide dependency installation, which is generally not recommended)-
./hxtool.pysimply runshxtool, passing through any arguments (patch/hxtool-script) -
./read-config.pyand./write-config.pyare alternatives to theconfigcommand with some extra features that may be especially useful when you work with several devices connected at the same time (#4,patch/read-write-script)- Use the wording read/write instead of dump/flash, which I find easier to type and remember (YMMV)
- Show a simple progress bar
- Show MMSI and callsign of the device being operated on
- Refuse to work whenever the device selection would be ambiguous
- Automagically use the magic in the data file for device selection
-
-
Fix region mismatch check on
hxtool config --flash(1643f9e) -
Various internal improvements (dependencies, testing, code style etc.) – @cr
Obviously, the original upstream repository cr/hx870 is maintained independently of this fork, so the actual set of differences may be larger or smaller than described above by the time you view this.
Contributions are probably best made to the upstream repository, so that everybody benefits from them. Anything merged upstream may be expected to eventually trickle down to this fork. Should you still wish to contribute something to this fork directly, I suggest you start by describing your proposal in a new issue.
See also:
-
A different open-source tool to access the memory of connected radios: SHsync
-
Memory layout information for specific radio models: HX870 · HX890 · GX1400
The remainder of this document is the original hxtool readme.
Here's my collection of experimental Python code and reverse engineering notes for hacking the Standard Horizon HX-style maritime radios by Yaesu. Currently supported are the HX870, HX890, and GX1400 model series.
Radios in "CP mode" are usually automatically detected when connected.
You can also manually select devices with the --tty or --model CLI options.
The GX1400 has no USB port and is connected to a RS-232 style serial port. The GX1400 connector wiring is as follows. See the SHsync docs for a diagram of the DE-9 connector pin-out.
RxD: accessory cable whiteTxD: accessory cable yellowGND: accessory cable green + speaker cable shield
The code also works on FT750-style aviation radios, which share the same hardware platform, to some degree as well, but that functionality is not exposed on the command line frontend, yet.
It is very easy to completely screw up your radio with low-level tooling like this, so BE EXTREMELY CAREFUL and get help from your geek friend if you're out of your depth. The software probably contains mistakes that can permanently damage your radio. Although it has been used a lot on my personal radio, I cannot guarantee that it works on yours. Use it AT YOUR OWN RISK!
This software does not work with Python 2.7! It produces just a cryptic error message.
The code is hardly documented and largely user-unfriendly and I am feeling
slightly awful about it. However, you may install the command line tool into your
(preferably virtual) Python 3.6+ environment via
pip install git+https://github.com/cr/hx870. Then see hxtool --help for usage
information.
hxtool works on Linux, Mac OS, and Windows 10 (and probably older ones, too) and it
has been extensively tested with the HX870 radio without any ill effects when used appropriately.
The HX890 portion has only been tested sporadically, and be mindful of the disclaimer above.
This work extends on Arne Johannessen's work. It is still incomplete and currently only documented in form of a 010 Editor template.
If you can C and figure out their custom lingo for defining bitfields, you'll have no trouble reading it.
GPS logs can now be exported and erased. Supported output formats are GPX, JSON, and raw log bytes.
hxtool gpslog should dump some log content to screen if radio is in programming mode.
See hxtool gpslog --help for usage info.
The hardware exposes three USB endpoints, EP0, EP1, and EP2. EP0 is a control endpoint. URB_BULK data is sent from EP1 and received on EP2. Advertises itself as AT command interface, hence device is captured by the USB Serial kernel driver on Linux and Mac OS X.
Radio is exposed as /dev/tty.usbmodem1411 on Mac OS X.
P- Sent by host without trailing \r\n, unacknowledged0- Sent by host without trailing \r\n, unacknowledgedACMD:002\r\n- StartCP, sent by host in the beginning, unacknowledged#CMDSY\r\n- Sync command, radio acknowledges with #CMDOK\r\n
Tab-separated message fields, concluded by checksum and \r\n. Example:
b'#CEPRD\tARG\tARG\t...ARG\tCHECKSUM\r\n'
Checksum is XOR reduce over raw bytes until and including the last \t.
There are messages with and without arguments. All messages with arguments have a checksum, and most messages (there are exceptions) without arguments do not.
Unary messages with checksum observed: #CVRRQ
Radio starts repeating messages if you don't acknowledge with #CMDOK or similar, so timing is important.
-
#CCPWC- Appears in firmware 02.03 -
#CDFCB -
#CDFER -
#CDFIN -
#CDFRR -
#CDFSR -
#CDFWR -
#CEPDT ADDRESS4 LENGTH <HEXBYTES>- Reply from radio after CEPRD -
#CEPRD ADDRESS4 LENGTH- Read from config flash -
#CEPSD 00or01- Radio status, 00 if ready to receive new writes, 01 if not ready -
#CEPSR 00- Radio replies with flash status #CEPSR message -
#CEPWR ADDRESS4 LENGTH <HEXBYTES>- Write to config flash -
#CIORD- Appears in firmware 02.03 -
#CFLCB 000000- CheckBlank -
#CFLER 000000- FlashErase -
#CFLID AM057N\0\0\0\0orAM057N2\0\0\0- FlashID, firmware flasher tries both during hardware detection/setup -
#CFLMC 01- CommandMd, sent by firmware flasher before #CFLER -
#CFLMC 03- CommandMdr, sent by firmware flasher after last #CFLWR -
#CFLRD- Appears in firmware 02.03, perhaps firmware flash read? Radio says #CMDUN -
#CFLSD 10- Radio status response observed during hardware detection -
#CFLSR 00- CheckStatus -
#CFLWR ADDRESS6 LENGTH <HEXBYTES>- Write to firmware flash -
#CMDER- CmdError -
#CMDNR STANDARD\x20HORIZON- CommandNr, radio answers with #CMDND -
#CMDND AM057NorAM057N2- Radio reply after #CMDNR request -
#CMDOK- CmdStatusOK, message Acknowledgement -
#CMDSM- CmdCheckSum error -
#CMDSY- Sync, sent by host, acknowledged by radio with #CMDOK -
#CMDUN- CmdUnknown -
#CRPWC -
#CSTDQ -
#CSTRQ -
#CVRDQ 02.03- Reply with firmware version -
#CVRRQ- Radio replies with firmware version in #CVRDQ message
Implemented as standard-compliant proprietary $P NMEA sentences.
b'$PMTKarg,arg,...,arg*checksum\r\n'
Checksum is XOR reduce over the raw bytes between $ and *.
-
$PMTK251,115200*1F- Sent to radio before GPS Log Transfer -
$PMTK183*38- StatusLog, sent to radio -
$PMTKLOG,FULL_STOP*3EInterspersed warning by radio after log commands -
$PMTKLOG,8,1,b,127,5,0,0,1,1430,22*1B- Radio reply to StatusLog8: number 4k flash pages used by log (expect to be transfered)1: unknown from raw log header offset 2b: unknown from raw log header offset 3127: unknown from raw log header offset 45: logger interval (in seconds) when log was started0: unknown0: unknown1: unknown1430: number of log slots used (max. 6432)22: log usage percentage
-
$PMTK001,183,3*3A- Radio ACK of StatusLog -
$PMTK622,1*29- ReadLog, sent to radio -
$PMTKLOX,0,43*6E- Radio response with data, expect 43LOX,1log lines -
$PMTKLOX,1,0,0100010B,7F000000,...,FFFFFFF*27- Log data -
$PMTKLOX,1,1,FFFFFFFF,FFFFFFFF,...,FFFFFFF*59- Log data -
$PMTKLOX,1,2,FFFFFFFF,FFFFFFFF,...,FFFFFFF*5A- Log data -
... -
$PMTKLOX,1,42,FFFFFFFF,FFFFFFFF,...,FFFFFFF*6E- Log data -
$PMTKLOX,2*47- From radio, end of log -
$PMTK001,622,3*36- Radio ACK of ReadLog -
$PMTK184,1*22- EraseLog -
$PMTK001,184,3*3D- Radio ACK EraseLog -
$PMTK...- numArray -
$PMTK0..$PMTK8
PMTK183*Query logging statusPMTK184,0*Erase logger flashPMTK185,1*Stop logging dataPMTK186,1*Snapshot write logPMTK187,1,1*Configure Locus setting, interval mode 1sPMTK225,0*Set periodic power saving mode, normal modePMTK251,0*Set NMEA baud rate, defaultPMTK301,0*Set DGPS correction source, nonePMTK313,0*Enable or disable SBAS searchPMTK386,0*Set speed threshold for static navigationPMTK605*Query firmware release informationPMTK622,0*Dump Locus flash data
OK- AnswerOK, not seen from HX870ERROR- AnswerERROR, not seen from HX870
These haven't been observed on the line, yet.
After factory reset, the following values are present at offset 0x0110 in config flash:
17 12 26 18 53 52 18 88 80 4E 00 06 11 76 21 45
After a full reboot, those values are replaced by all FF.
pytest -v- running the test suitepytest --cov=hxtool --cov-report=term- running test coverage
- https://www.telit.com/wp-content/uploads/2018/03/1VV0301162_V13_Software_User_Guide_r4.pdf
- https://cdn-shop.adafruit.com/datasheets/PMTK+command+packet-Complete-C39-A01.pdf
- https://cdn-shop.adafruit.com/datasheets/GTop+LOCUS+Library+User+Manual-v13.pdf
- https://simcomturkiye.com/pdf/GNSS/SIM28/Locus_Manual_for_MTK_GNSS_Platform_V1.00.pdf