34 #if defined(PIOS_INCLUDE_GPS_UBX_PARSER)
39 static uint32_t parse_errors;
41 static bool checksum_ubx_message(
const struct UBXPacket *);
42 static uint32_t parse_ubx_message(
const struct UBXPacket *, GPSPositionData *);
61 static enum proto_states proto_state = START;
62 static uint16_t rx_count = 0;
65 switch (proto_state) {
68 proto_state = UBX_SY2;
72 proto_state = UBX_CLASS;
82 proto_state = UBX_LEN1;
86 proto_state = UBX_LEN2;
95 proto_state = UBX_PAYLOAD;
102 proto_state = UBX_CHK1;
110 proto_state = UBX_CHK2;
114 if (checksum_ubx_message(ubx)) {
115 parse_ubx_message(ubx, GpsData);
116 proto_state = FINISHED;
125 if (proto_state == START)
127 else if (proto_state == FINISHED) {
140 #define POSLLH_RECEIVED (1 << 0)
141 #define STATUS_RECEIVED (1 << 1)
142 #define DOP_RECEIVED (1 << 2)
143 #define VELNED_RECEIVED (1 << 3)
144 #define SOL_RECEIVED (1 << 4)
145 #define ALL_RECEIVED (SOL_RECEIVED | VELNED_RECEIVED | DOP_RECEIVED | POSLLH_RECEIVED)
146 #define NONE_RECEIVED 0
148 static struct msgtracker{
150 uint8_t msg_received;
154 bool check_msgtracker (uint32_t tow, uint8_t msg_flag)
157 if (tow > msgtracker.currentTOW ?
true
158 : (msgtracker.currentTOW - tow > 6*24*3600*1000)) {
159 msgtracker.currentTOW = tow;
160 msgtracker.msg_received = NONE_RECEIVED;
161 }
else if (tow < msgtracker.currentTOW)
164 msgtracker.msg_received |= msg_flag;
168 static bool checksum_ubx_message (
const struct UBXPacket *ubx)
195 UBloxInfoParseErrorsSet(&parse_errors);
202 static void parse_ubx_nav_posllh (
const struct UBX_NAV_POSLLH *posllh, GPSPositionData *GpsPosition)
204 if (check_msgtracker(posllh->
iTOW, POSLLH_RECEIVED)) {
205 if (GpsPosition->Status != GPSPOSITION_STATUS_NOFIX) {
206 GpsPosition->Altitude = (float)posllh->
hMSL*0.001f;
207 GpsPosition->GeoidSeparation = (
float)(posllh->
height - posllh->
hMSL)*0.001
f;
208 GpsPosition->Latitude = posllh->
lat;
209 GpsPosition->Longitude = posllh->
lon;
214 static void parse_ubx_nav_sol (
const struct UBX_NAV_SOL *sol, GPSPositionData *GpsPosition)
216 if (check_msgtracker(sol->
iTOW, SOL_RECEIVED)) {
217 GpsPosition->Satellites = sol->
numSV;
218 GpsPosition->Accuracy = sol->
pAcc / 100.0f;
223 GpsPosition->Status = GPSPOSITION_STATUS_FIX2D;
227 GPSPOSITION_STATUS_DIFF3D : GPSPOSITION_STATUS_FIX3D;
229 default: GpsPosition->Status = GPSPOSITION_STATUS_NOFIX;
233 GpsPosition->Status = GPSPOSITION_STATUS_NOFIX;
237 static void parse_ubx_nav_dop (
const struct UBX_NAV_DOP *dop, GPSPositionData *GpsPosition)
239 if (check_msgtracker(dop->
iTOW, DOP_RECEIVED)) {
240 GpsPosition->HDOP = (float)dop->
hDOP * 0.01f;
241 GpsPosition->VDOP = (
float)dop->
vDOP * 0.01f;
242 GpsPosition->PDOP = (float)dop->
pDOP * 0.01f;
246 static void parse_ubx_nav_velned (
const struct UBX_NAV_VELNED *velned, GPSPositionData *GpsPosition)
248 GPSVelocityData GpsVelocity;
250 if (check_msgtracker(velned->
iTOW, VELNED_RECEIVED)) {
251 if (GpsPosition->Status != GPSPOSITION_STATUS_NOFIX) {
252 GpsVelocity.North = (float)velned->
velN/100.0f;
253 GpsVelocity.East = (
float)velned->
velE/100.0f;
254 GpsVelocity.Down = (float)velned->
velD/100.0f;
255 GpsVelocity.Accuracy = (
float)velned->
sAcc/100.0f;
256 GPSVelocitySet(&GpsVelocity);
257 GpsPosition->Groundspeed = (float)velned->
gSpeed * 0.01f;
258 GpsPosition->Heading = (
float)velned->
heading * 1.0e-5
f;
263 static void parse_ubx_nav_timeutc (
const struct UBX_NAV_TIMEUTC *timeutc)
270 GpsTime.Year = timeutc->
year;
271 GpsTime.Month = timeutc->
month;
272 GpsTime.Day = timeutc->
day;
273 GpsTime.Hour = timeutc->
hour;
274 GpsTime.Minute = timeutc->
min;
275 GpsTime.Second = timeutc->
sec;
277 GPSTimeSet(&GpsTime);
280 static void parse_ubx_nav_svinfo (
const struct UBX_NAV_SVINFO *svinfo)
283 GPSSatellitesData svdata;
287 svdata.SatsInView = svinfo->
numCh;
293 (i < svinfo->
numCh) && (chan < GPSSATELLITES_PRN_NUMELEM);
297 if (!svinfo->
sv[i].
cno) {
302 svdata.Azimuth[chan] = svinfo->
sv[
i].
azim;
303 svdata.Elevation[chan] = svinfo->
sv[
i].
elev;
304 svdata.PRN[chan] = svinfo->
sv[
i].
svid;
310 if (svinfo->
sv[chan].
cno < 66) {
311 svdata.SNR[chan] = svinfo->
sv[
i].
cno * 3 / 2;
313 svdata.SNR[chan] = 99;
322 (i < svinfo->
numCh) && (chan < GPSSATELLITES_PRN_NUMELEM);
324 if (!svinfo->
sv[i].
cno) {
325 svdata.Azimuth[chan] = svinfo->
sv[
i].
azim;
326 svdata.Elevation[chan] = svinfo->
sv[
i].
elev;
327 svdata.PRN[chan] = svinfo->
sv[
i].
svid;
328 svdata.SNR[chan] = svinfo->
sv[
i].
cno;
335 for (; chan < GPSSATELLITES_PRN_NUMELEM; chan++) {
336 svdata.Azimuth[chan] = 0;
337 svdata.Elevation[chan] = 0;
338 svdata.PRN[chan] = 0;
339 svdata.SNR[chan] = 0;
342 GPSSatellitesSet(&svdata);
345 static void parse_ubx_mon_ver (
const struct UBX_MON_VER *version_info)
348 UBloxInfoGet(&ublox);
350 ublox.swVersion = (version_info->
swVersion[0] -
'0') +
351 (version_info->
swVersion[2] -
'0') * 0.1f +
353 for (uint32_t i = 0; i < 4; i++) {
354 ublox.hwVersion = ublox.hwVersion * 10 +
357 ublox.ParseErrors = parse_errors;
358 UBloxInfoSet(&ublox);
364 static uint32_t parse_ubx_message (
const struct UBXPacket *ubx, GPSPositionData *GpsPosition)
399 if (msgtracker.msg_received == ALL_RECEIVED) {
400 GPSPositionSet(GpsPosition);
401 msgtracker.msg_received = NONE_RECEIVED;
402 id = GPSPOSITION_OBJID;
407 #endif // PIOS_INCLUDE_GPS_UBX_PARSER
static char * gps_rx_buffer
struct UBX_NAV_DOP nav_dop
Main PiOS header to include all the compiled in PiOS options.
struct UBX_NAV_VELNED nav_velned
struct UBX_NAV_TIMEUTC nav_timeutc
struct UBX_NAV_SOL nav_sol
struct UBX_NAV_POSLLH nav_posllh
#define STATUS_FLAGS_GPSFIX_OK
#define STATUS_GPSFIX_3DFIX
uint16_t gpsRxChkSumError
Include file of the GPS module.
int parse_ubx_stream(uint8_t, char *, GPSPositionData *, struct GPS_RX_STATS *)
#define STATUS_FLAGS_DIFFSOLN
struct UBX_MON_VER mon_ver
Includes PiOS and core architecture components.
struct UBX_NAV_SVINFO nav_svinfo
Include file for UBX processing.
static struct GPS_RX_STATS gpsRxStats
#define STATUS_GPSFIX_2DFIX
struct UBX_NAV_SVINFO_SV sv[MAX_SVS]
#define PARSER_INCOMPLETE