summaryrefslogtreecommitdiff
path: root/src/garmin.h
blob: c9ce67170e689013098a2b8600bf10e760357a72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
	Garmin protocol to NMEA 0183 converter
	Copyright (C) 2004 Manuel Kasper <mk@neon1.net>.
	All rights reserved.

	Input:
		- D800_Pvt_Data_Type (PID 51)
		- satellite data record (PID 114)

	Available output sentences:
		GPGGA, GPRMC, GPGLL, GPGSA, GPGSV

	Known caveats:
		- DOP (Dilution of Precision) information not available
		  (Garmin protocol includes EPE only)
		- DGPS information in GPGGA sentence not returned
		- speed and course over ground are calculated from the
		  north/east velocity and may not be accurate
		- magnetic variation information not available
		- Garmin 16-bit SNR scale unknown

	---------------------------------------------------------------------------
	
	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:
	
	1. Redistributions of source code must retain the above copyright notice,
	   this list of conditions and the following disclaimer.
	
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef GARMIN_H
#define GARMIN_H

#include <sys/types.h>
#include "nmea.h"


/*
 *  Garmin device driver defines
 */

/* private layer-id to use for some ioctl-like control mechanisms */
#define GARMIN_LAYERID_PRIVATE	0x01106E4B

// packet ids used in the private layer
#define GARMIN_PRIV_PKTID_SET_DEBUG	1
#define GARMIN_PRIV_PKTID_SET_MODE	2
#define GARMIN_PRIV_PKTID_INFO_REQ	3
#define GARMIN_PRIV_PKTID_INFO_RESP	4
#define GARMIN_PRIV_PKTID_RESET_REQ	5
#define GARMIN_PRIV_PKTID_SET_DEF_MODE	6

#define GARMIN_MODE_NATIVE	0
#define GARMIN_MODE_SERIAL	1

#define GARMIN_PRIV_PKT_MAX_SIZE	32

/*
	PRIV_PKTID_INFO_RESP packet:

	pkt[0] = __cpu_to_le32(GARMIN_LAYERID_PRIVATE);
	pkt[1] = __cpu_to_le32(PRIV_PKTID_INFO_RESP);
	pkt[2] = __cpu_to_le32(12);
	pkt[3] = __cpu_to_le32(VERSION_MAJOR << 16 | VERSION_MINOR);
	pkt[4] = __cpu_to_le32(garmin_data_p->mode);
	pkt[5] = __cpu_to_le32(garmin_data_p->serial_num);
*/

#define GARMIN_PRIV_PKT_INFO_RESP_SIZE	24

/*
 *  Garmin device definitions
 */

#pragma pack(push, 1)

typedef struct {
	u_int8_t	tag;
	u_int16_t	data;
} Protocol_Data_Type;

typedef struct
{
	float	alt;
	float	epe;
	float	eph;
	float	epv;
	int16_t	fix;
	double	tow;
	double	lat;
	double	lon;
	float	east;
	float	north;
	float	up;
	float	msl_hght;
	int16_t	leap_scnds;
	int32_t	wn_days;
}
D800_Pvt_Data_Type;

typedef struct
{
	u_int8_t	svid;
	u_int16_t	snr;
	u_int8_t	elev;
	u_int16_t	azmth;
	u_int8_t	status;
}
cpo_sat_data;

/*
    The following defines have been determined empirically.  I could not find
    any definitive info on the sat data record, even in the Garmin spec.  What
    I see is a status of 0x04 when a sat is being tracked but not used for locating,
    and a status of 0x05 when the sat is good.  I have not seen any other values.
    The mask is needed to filter out extraneous bits that are unknown.
    
    Here is a snapshot of what is seen in nmea_gpgsv():

	sat 11: status = 05  SNR = 1800
	sat 13: status = 04  SNR = 2200
	sat 16: status = 05  SNR = 3200
	sat 20: status = 05  SNR = 3600
	sat 23: status = 05  SNR = 3500
	sat 25: status = 04  SNR = 1900
	sat 31: status = 05  SNR = 3000
	sat 32: status = 05  SNR = 3700
	sat 04: status = 04  SNR = 65436
	sat 30: status = 04  SNR = 65436

    The SNR value of 65436 is the 16-bit 2's complement value of -100.
*/

#define SAT_STATUS_MASK	0x07
#define SAT_STATUS_GOOD	0x05
#define SAT_SNR_BAD	65436

typedef struct
{
	u_int32_t	cycles;
	double		pr;
	u_int16_t	phase;
	u_int8_t	slp_dtct;
	u_int8_t	snr_dbhz;
	u_int8_t	svid;
	u_int8_t	valid;
}
cpo_rcv_sv_data;

typedef struct
{
	double			rcvr_tow;
	u_int16_t		rcvr_wn;
	cpo_rcv_sv_data		sv[SAT_MAX_COUNT];
}
cpo_rcv_data;

/* This is the packet definition for Garmin */

#define GARMIN_HEADER_SIZE 12

typedef struct
{
	u_int8_t	mPacketType;	// byte 0
	u_int8_t	mReserved1;	// bytes 1-3 
	u_int16_t	mReserved2;
	u_int16_t	mPacketId;	// bytes 4-5
	u_int16_t	mReserved3;	// bytes 6-7
	u_int32_t	mDataSize;	// bytes 8-11
	u_int8_t	mData[1];	// bytes 12..N
}
G_Packet_t;

#pragma pack(pop)

enum {
	Pid_Command_Data	= 10,
	Pid_Xfer_Cmplt		= 12,
	Pid_Date_Time_Data	= 14,
	Pid_Position_Data	= 17,
	Pid_Prx_Wpt_Data	= 19,
	Pid_Records		= 27,
	Pid_Rte_Hdr		= 29,
	Pid_Rte_Wpt_Data	= 30,
	Pid_Almanac_Data	= 31,
	Pid_Trk_Data		= 34,
	Pid_Wpt_Data		= 35,
	Pid_Pvt_Data		= 51,
	Pid_RMR_Data		= 52,
	Pid_Rte_Link_Data	= 98,
	Pid_Trk_Hdr		= 99,
	Pid_SatData_Record	= 114,
	Pid_FlightBook_Record	= 134,
	Pid_Lap			= 149
};

enum {
	Cmnd_Abort_Transfer      =   0,	/* abort current transfer */
	Cmnd_Transfer_Alm        =   1,	/* transfer almanac */
	Cmnd_Transfer_Posn       =   2,	/* transfer position */
	Cmnd_Transfer_Prx        =   3,	/* transfer proximity waypoints */
	Cmnd_Transfer_Rte        =   4,	/* transfer routes */
	Cmnd_Transfer_Time       =   5,	/* transfer time */
	Cmnd_Transfer_Trk        =   6,	/* transfer track log */
	Cmnd_Transfer_Wpt        =   7,	/* transfer waypoints */
	Cmnd_Turn_Off_Pwr        =   8,	/* turn off power */
	Cmnd_Start_Pvt_Data      =  49,	/* start transmitting PVT data */
	Cmnd_Stop_Pvt_Data       =  50,	/* stop transmitting PVT data */
	Cmnd_FlightBook_Transfer =  92,	/* start transferring flight records */
	Cmnd_Start_RMR           = 110,	/* start transmitting Receiver Measurement Records */
	Cmnd_Stop_RMR            = 111,	/* start transmitting Receiver Measurement Records */
	Cmnd_Transfer_Laps       = 117	/* transfer laps */
};

#endif