OBSERVATIONS OF THE GARMIN-GARMIN PROTOCOL last update: March 6, 1998 author: william.soley@sun.com, werme@zk3.dec.com URL: http://playground.sun.com/pub/soley/garmin.txt (this work has nothing to do with Sun Microsystems) (nor Digital Equipment Corp.) # Remarks by A. Helm November 29, 1997 # tony@nt.tuwien.ac.at # # All REMARK-lines are preceeded by a '#'. = more Remarks by D. Zuppinger March 06, 1998 = softtoys@webshuttle.ch = = All REMARK-lines are preceeded by a '='. This is a description of the GARMIN-GARMIN protocol as spoken by the Garmin GPS-75 GPS receiver and the Garmin PCX5 MS-DOS software. The information here has been determined by observing the communication between the two units while sending "chosen plaintext". This spec is at best, incomplete, and at worst, incorrect. Lots of assumptions were made based on the observed behavior of the protocol. It is also unknown how much of this protocol is common to other Garmin products. But, unless Garmin decides to be cooperative, this is about the best we can do. Use it at your own risk! All references to GPS-75 behavior came from William Soley. A major update to this was made in July, 1996 by Eric Werme, studying the behavior of his GPS-45. There is much in common between the protocols used by the two models, but there are differences. Much of Werme's study focused on protocol commands not used by PCX5, all of which are subject to change, even between revisions of firmware within a model! If you must rely on some part of the protocol, it should be part that is used by Garmin's PCX5 software. Layer 1 ------- Data is standard Async. 9600 bits per second. 8 data bits. no parity. 1 stop bit. Layer 2 ------- The data stream consists of frames each having the following format: DataLinkEscape (0x10) RecordType (one byte) $$ Length (one byte) ** $$ DataField ("length" bytes) ** $$ CheckSum (one byte) ** DataLinkEscape (0x10) EndTransmission (0x03) ** - fields indicated by "**" are subject to escape. Any occurrence of a DataLinkEscape character (0x10) in these fields is preceded by another DataLinkEscape (0x10) resulting in a pair. Escape bytes added in this way are not counted in the record length (i.e. bytes are counted before the escapes are added). $$ - the bytes comprising fields indicated by "$$" are summed and the low-order 8 bits are then negated (2's complement) to form the CheckSum. Any added DataLinkEscapes are not included in the sum. Software processing this protocol layer on input can discard the initial DataLinkEscape, the checksum and later bytes, and compress the double DataLinkEscapes into one. The remaining bytes constitute Layer 3 protocol frames. Layer 3 ------- When a non-ACK/NAK or asynchronous frame is received an ACK or NAK is sent depending on the checksum validity of the received frame. ACK/NAK frames are the same format as a regular frame: RecordType = 0x06 (ACK) or 0x15 (NAK) Length = 2 DataField = RecordType of record being acknowledged, 0x00 When a non-ACK/NAK frame is sent, the sender waits for an ACK/NAK. If a NAK is received, or if no ACK is received after about 1 second, the sender retransmits the frame. Power Up -------- When the GPS-75 is powered on, it transmits an 0x5A character. When the GPS-45 is powered on, it transmits 0xFE and 0X5A characters. Holding the button while pressing to turn the unit on will erase the unit's memory and result in the messages: Stored Data Lost Searching the Sky Holding the button while pressing to turn the unit on will put the unit in TEST mode. The GPS-75 a will display a series of concentric rectangles will be displayed and animated to give the illusion of passing through a tunnel. Pressing will toggle between the tunnel display and a display showing: Testing ... Sgnl Amplitude 2168 TCX0 Drift -19.978 While in TEST mode, a continuous stream of RecordType=0x00, 0x01, and 0x0d messages will be sent to the serial port. Also, while in TEST mode the "<" and ">" may be used to adjust display contrast, but the adjustment does not appear to be saved. The GPS-45 behaves somewhat differently. The status screen is the first to be displayed and includes a keypad test test feature. In addition to the box display is an all black display. The GPS will send a stream of RecordTypes 0x00, 0x27, 0x28. Data Presentation ----------------- Numeric data within the Garmin protocol is in binary, and several formats are used. Those are described here. Skimming this section now will make it easier to understand the protocol's commands. short integer - length = 2 bytes, in order of increasing significance. Negative numbers are expressed as 2's complement. Examples: 00 00 = 0x0 = 0 01 00 = 0x1 = 1 10 00 = 0x10 = 16 00 01 = 0x100 = 256 00 10 = 0x1000 = 4096 ff ff = 0xffff = -1 f0 ff = 0xfff0 = -16 long integer - length = 4 bytes, in order of increasing significance. Negative numbers are expressed as 2's complement. Examples: 00 00 00 00 = 0x0 = 0 01 00 00 00 = 0x1 = 1 00 01 00 00 = 0x100 = 256 00 00 01 00 = 0x10000 = 65536 00 00 00 01 = 0x1000000 = 16777216 ff ff ff ff = 0xffffffff = -1 f0 ff ff ff = 0xfffffff0 = -16 float - length = 4 bytes, IEEE single precision floating point. Least significant byte first. This format consists of: 1 bit - sign 8 bits - exponent, excess 127 23 bits - mantissa, implied high-order 1 double - length = 8 bytes, IEEE double precision floating point. Least significant byte first. This format consists of: 1 bit - sign 11 bits - exponent, excess 1023 52 bits - mantissa, implied high-order 1 ASCII string - series of ASCII bytes, usually padded with blanks. Example: 47 50 53 20 37 35 20 20 32 2e 32 31 20 = "GPS 75 2.21" date/time - length = 4 bytes, long unsigned integer encoded as 86400 + number of seconds since midnight, Jan 1 1990. Note: unix_time = garmin_time + 631065600 Examples: 00 00 00 00 = 0x0 = undefined 80 51 01 00 = 0x15180 = Jan 1 1990 00:00:00 7d f0 ef 2d = 0x2deff07d = Jun 4 1994 03:09:49 # # date/time information is ignored when uploading to garmin. # When downloading, the only records that have a nonzero time # field are trackpoints. (tested with GPS45 and GPS II+) # long lat/lon - length = 4 bytes, long signed integer encoded as 11930464.7111111111 * lat/lon in degrees, or 683565275.576431632 * lat/lon in radians. The former factor as a ratio is 2**30/90. As a C expression, it is ((1L << 30) / 90.0). All values are in map datum WGS 84. Examples: 00 00 00 00 = 0x0 = 0.0 deg 61 0b b6 00 = 0xb60b61 = 1.0 deg 00 00 00 40 = 0x40000000 = 90.0 deg 00 00 00 c0 = 0xc0000000 = -90.0 deg 00 00 00 80 = 0x80000000 = -180.0 deg # # For some garmin models the 6 least significant bits are ignored. # This doesn't make much precision problems as the resulting error # is below 1.2m but you have to be careful when rounding numbers. # You might get some "pentium-results", e.g 4.9999345 instead of 5.0 # For a DMS output the least significant number is 0.1s. Anything # smaller is garbage due to the numerical representation in the # garmin protocol. # double lat/lon - length = 8 bytes, IEEE double precision floating point encoded as lat/lon in radians. All values are in map datum WGS 84. Examples: 00 00 00 00 00 00 00 00 = 0.0 rad 00 00 00 00 00 00 f0 3f = 1.0 rad 00 00 00 00 00 00 f8 3f = 1.5 rad 00 00 00 00 00 00 00 40 = 2.0 rad 00 00 00 00 00 00 08 40 = 3.0 rad 00 00 00 00 00 00 f0 bf = -1.0 rad 00 00 00 00 00 00 00 c0 = -2.0 rad Record Types and Formats ------------------------ The following table describes the observed RecordTypes. ---------------------------------------------------------------- RecordType = 0x00 Length = 4 Description: Sent asynchronously while in TEST mode or when enabled by the RecordType=0x1C command, with mask 0x01. ---------------------------------------------------------------- RecordType = 0x01 SignalAmplitude Length = 4 DataField = 2 bytes - unsigned short - Signal Amplitude 2 bytes - ? 00 fe Description: Sent every 4 seconds while in TEST mode or when enabled by the RecordType=0x1C command, with mask 0x01. The exact meaning of the last 2 bytes is unknown. ---------------------------------------------------------------- RecordType = 0x06 ACK Length = 2 DataField = 1 byte - copy of RecordType from record being ACK'd 1 byte - always zero Description: The recipient is expected to retransmit the last record if an ACK is not received within about 1 second. ACK is not sent in response to ACK or NAK. ---------------------------------------------------------------- RecordType = 0x09 Unknown Length = 2 DataField = 2 bytes - ? 02 00 Description: Sent in response to 1c command. ---------------------------------------------------------------- RecordType = 0x0a Request Length = 2 DataField = 2 bytes - unsigned short - operation code 01 00 = 0x1 = download almanac (RecordType 1f) 02 00 = 0x2 = query position (RecordType 11) 03 00 = 0x3 = download proximity waypoints (RecType 13) 04 00 = 0x4 = download route (RecordType 1d and 1e) 05 00 = 0x5 = query UTC clock time (RecordType 0e) 06 00 = 0x6 = download tracks (RecordType 22) 07 00 = 0x7 = download waypoints (RecordType 23) 08 00 = 0x8 = power off 0b 00 = 0xb = set Tone=MSG+KEY then power off. The GPS-75 may beep, the 45 does not. Description: This record is sent to request the recipient to download the specified data records. For requests 1,3,4,6, and 7, the recipient should respond with RecordType=0x1B (Begin- Transfer), followed by some number of data records, followed by RecordType=0x0C (EndTransfer). For requests 2 and 5, the recipient should respond with a single data record. The 2nd DataField byte appears to be ignored. # # I have observed some situations where a "power off" command # is executed too fast(!). That means the garmin goes down # before the software handshake is complete. # ---------------------------------------------------------------- RecordType = 0x0c EndTransfer Length = 2 DataField = 2 bytes - unsigned short - type of transfer being ended 01 00 = 0x1 = almanac 03 00 = 0x3 = proximity waypoints 04 00 = 0x4 = routes 06 00 = 0x6 = tracks 07 00 = 0x7 = waypoints Description: This record is sent following the last data record of an upload or download to denote the end of the transfer. When the GPS receives this, it removes the " of packets" message. ---------------------------------------------------------------- RecordType = 0x0d Event Length = 4 DataField = 2 bytes - EventType 05 00 Satellite acquired 07 00 Navigation quality 0c 00 Keyboard event (TEST mode only) 10 00 Screen message displayed 14 00 Power on sequence message 2 bytes - SubType This is a function of the EventType. Each known EventType is described below with a list of the SubTypes. 4 bytes - GPS clock time This is a time that is initialized to 0 at startup and incremented 255750 per second. This is 1/4 of the 1.023 Mhz bit rate of the CA code transmitted by GPS satellites. (Rumors that GPS satellites are powered by Apple ][ computers are totally untrue!) Some events may use the low one or two bytes for additional data. Description: Sent asynchronously while in TEST mode or when enabled by the RecordType=0x1C command, with mask 0x02. There are other possible values of EventType but we haven't figured them out, yet. Those seen from the GPS-45 but not understood are listed at the end of this document. SubType list: EventType 05 00 Satellite acquired This is sent when a satellite is acquired. In diagnostic mode (Enter held down while powered on) or on the GPS-38 This coincides with the satellite signal strength bar changing from white to black. The SubType field is the satellite ID number - 1. EventType 07 00 Navigation quality The subtype is either 2 or 3 for 2D or 3D navigation. EventType 0c 00 Keyboard event (TEST mode only) GPS-75 codes: 01 00 down 02 00 down + 1 sec 03 00 down + 2 sec 04 00 05 00 08 00