4343
4444#include "drivers/nvic.h"
4545
46+ #include "fc/config.h"
4647#include "fc/rc_modes.h"
4748#include "fc/runtime_config.h"
4849
5152#include "io/gps.h"
5253#include "io/serial.h"
5354
55+ #include "navigation/navigation.h"
56+
5457#include "rx/rx.h"
5558#include "rx/ghst.h"
5659#include "rx/ghst_protocol.h"
6770
6871#define GHST_CYCLETIME_US 100000 // 10x/sec
6972#define GHST_FRAME_PACK_PAYLOAD_SIZE 10
73+ #define GHST_FRAME_GPS_PAYLOAD_SIZE 10
7074#define GHST_FRAME_LENGTH_CRC 1
7175#define GHST_FRAME_LENGTH_TYPE 1
7276
@@ -112,11 +116,51 @@ void ghstFramePackTelemetry(sbuf_t *dst)
112116 sbufWriteU8 (dst , 0x00 ); // tbd3
113117}
114118
119+
120+ // GPS data, primary, positional data
121+ void ghstFrameGpsPrimaryTelemetry (sbuf_t * dst )
122+ {
123+ // use sbufWrite since CRC does not include frame length
124+ sbufWriteU8 (dst , GHST_FRAME_GPS_PAYLOAD_SIZE + GHST_FRAME_LENGTH_CRC + GHST_FRAME_LENGTH_TYPE );
125+ sbufWriteU8 (dst , GHST_DL_GPS_PRIMARY );
126+
127+ sbufWriteU32 (dst , gpsSol .llh .lat );
128+ sbufWriteU32 (dst , gpsSol .llh .lon );
129+
130+ // constrain alt. from -32,000m to +32,000m, units of meters
131+ const int16_t altitude = (constrain (getEstimatedActualPosition (Z ), -32000 * 100 , 32000 * 100 ) / 100 );
132+ sbufWriteU16 (dst , altitude );
133+ .}
134+
135+ // GPS data, secondary, auxiliary data
136+ void ghstFrameGpsSecondaryTelemetry (sbuf_t * dst )
137+ {
138+ // use sbufWrite since CRC does not include frame length
139+ sbufWriteU8 (dst , GHST_FRAME_GPS_PAYLOAD_SIZE + GHST_FRAME_LENGTH_CRC + GHST_FRAME_LENGTH_TYPE );
140+ sbufWriteU8 (dst , GHST_DL_GPS_SECONDARY );
141+
142+ sbufWriteU16 (dst , gpsSol .groundSpeed ); // speed in 0.1m/s
143+ sbufWriteU16 (dst , gpsSol .groundCourse ); // degrees * 10
144+ sbufWriteU8 (dst , gpsSol .numSat );
145+
146+ sbufWriteU16 (dst , (uint16_t ) (GPS_distanceToHome / 10 )); // use units of 10m to increase range of U16 to 655.36km
147+ sbufWriteU16 (dst , GPS_directionToHome );
148+
149+ uint8_t gpsFlags = 0 ;
150+ if (STATE (GPS_FIX ))
151+ gpsFlags |= GPS_FLAGS_FIX ;
152+ if (STATE (GPS_FIX_HOME ))
153+ gpsFlags |= GPS_FLAGS_FIX_HOME ;
154+ sbufWriteU8 (dst , gpsFlags );
155+ }
156+
115157// schedule array to decide how often each type of frame is sent
116158typedef enum {
117159 GHST_FRAME_START_INDEX = 0 ,
118160 GHST_FRAME_PACK_INDEX = GHST_FRAME_START_INDEX , // Battery (Pack) data
119- GHST_SCHEDULE_COUNT_MAX
161+ GHST_FRAME_GPS_PRIMARY_INDEX , // GPS, primary values (Lat, Long, Alt)
162+ GHST_FRAME_GPS_SECONDARY_INDEX , // GPS, secondary values (Sat Count, HDOP, etc.)
163+ GHST_SCHEDULE_COUNT_MAX
120164} ghstFrameTypeIndex_e ;
121165
122166static uint8_t ghstScheduleCount ;
@@ -136,6 +180,19 @@ static void processGhst(void)
136180 ghstFramePackTelemetry (dst );
137181 ghstFinalize (dst );
138182 }
183+
184+ if (currentSchedule & BIT (GHST_FRAME_GPS_PRIMARY_INDEX )) {
185+ ghstInitializeFrame (dst );
186+ ghstFrameGpsPrimaryTelemetry (dst );
187+ ghstFinalize (dst );
188+ }
189+
190+ if (currentSchedule & BIT (GHST_FRAME_GPS_SECONDARY_INDEX )) {
191+ ghstInitializeFrame (dst );
192+ ghstFrameGpsSecondaryTelemetry (dst );
193+ ghstFinalize (dst );
194+ }
195+
139196 ghstScheduleIndex = (ghstScheduleIndex + 1 ) % ghstScheduleCount ;
140197}
141198
@@ -152,6 +209,14 @@ void initGhstTelemetry(void)
152209 if (isBatteryVoltageConfigured () || isAmperageConfigured ()) {
153210 ghstSchedule [index ++ ] = BIT (GHST_FRAME_PACK_INDEX );
154211 }
212+
213+ #ifdef USE_GPS
214+ if (feature (FEATURE_GPS )) {
215+ ghstSchedule [index ++ ] = BIT (GHST_FRAME_GPS_PRIMARY_INDEX );
216+ ghstSchedule [index ++ ] = BIT (GHST_FRAME_GPS_SECONDARY_INDEX );
217+ }
218+ #endif
219+
155220 ghstScheduleCount = (uint8_t )index ;
156221 }
157222
0 commit comments