msm8974-common: gps: Adding a new NMEA sentence : $GNGSA.

Currently only $GPGSA was being generated for GPS satellites.
This change adds $GNGSA for GLONASS satellites as well.

Change-Id: I7ab0e92c7ed4ce73be11909eefe0d570a1a0fc1e
CRs-Fixed: 978745
This commit is contained in:
Saurabh Srivastava 2016-03-04 15:12:35 +05:30 committed by Kevin F. Haggerty
parent 62261a55b5
commit ee76952f5e
No known key found for this signature in database
GPG Key ID: 6D95512933112729
2 changed files with 110 additions and 5 deletions

View File

@ -119,7 +119,8 @@ typedef struct loc_eng_data_s
// For nmea generation // For nmea generation
boolean generateNmea; boolean generateNmea;
uint32_t sv_used_mask; uint32_t gps_used_mask;
uint32_t glo_used_mask;
float hdop; float hdop;
float pdop; float pdop;
float vdop; float vdop;

View File

@ -102,6 +102,12 @@ FUNCTION loc_eng_nmea_generate_pos
DESCRIPTION DESCRIPTION
Generate NMEA sentences generated based on position report Generate NMEA sentences generated based on position report
Currently below sentences are generated within this function:
- $GPGSA : GPS DOP and active SVs
- $GNGSA : GLONASS DOP and active SVs
- $GPVTG : Track made good and ground speed
- $GPRMC : Recommended minimum navigation information
- $GPGGA : Time, position and fix related data
DEPENDENCIES DEPENDENCIES
NONE NONE
@ -144,7 +150,7 @@ void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
uint32_t svUsedCount = 0; uint32_t svUsedCount = 0;
uint32_t svUsedList[32] = {0}; uint32_t svUsedList[32] = {0};
uint32_t mask = loc_eng_data_p->sv_used_mask; uint32_t mask = loc_eng_data_p->gps_used_mask;
for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++) for (uint8_t i = 1; mask > 0 && svUsedCount < 32; i++)
{ {
if (mask & 1) if (mask & 1)
@ -152,7 +158,7 @@ void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
mask = mask >> 1; mask = mask >> 1;
} }
// clear the cache so they can't be used again // clear the cache so they can't be used again
loc_eng_data_p->sv_used_mask = 0; loc_eng_data_p->gps_used_mask = 0;
char fixType; char fixType;
if (svUsedCount == 0) if (svUsedCount == 0)
@ -210,6 +216,99 @@ void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p); loc_eng_nmea_send(sentence, length, loc_eng_data_p);
// ------------------
// ------$GNGSA------
// ------------------
uint32_t gloUsedCount = 0;
uint32_t gloUsedList[32] = {0};
// Reset locals for GNGSA sentence generation
pMarker = sentence;
lengthRemaining = sizeof(sentence);
mask = loc_eng_data_p->glo_used_mask;
fixType = '\0';
// Parse the glonass sv mask, and fetch glo sv ids
// Mask corresponds to the offset.
// GLONASS SV ids are from 65-96
const int GLONASS_SV_ID_OFFSET = 64;
for (uint8_t i = 1; mask > 0 && gloUsedCount < 32; i++)
{
if (mask & 1)
gloUsedList[gloUsedCount++] = i + GLONASS_SV_ID_OFFSET;
mask = mask >> 1;
}
// clear the cache so they can't be used again
loc_eng_data_p->glo_used_mask = 0;
if (gloUsedCount == 0)
fixType = '1'; // no fix
else if (gloUsedCount <= 3)
fixType = '2'; // 2D fix
else
fixType = '3'; // 3D fix
// Start printing the sentence
// Format: $--GSA,a,x,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,p.p,h.h,v.v*cc
// GNGSA : for glonass SVs
// a : Mode : A : Automatic, allowed to automatically switch 2D/3D
// x : Fixtype : 1 (no fix), 2 (2D fix), 3 (3D fix)
// xx : 12 SV ID
// p.p : Position DOP (Dilution of Precision)
// h.h : Horizontal DOP
// v.v : Vertical DOP
// cc : Checksum value
length = snprintf(pMarker, lengthRemaining, "$GNGSA,A,%c,", fixType);
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
// Add first 12 GLONASS satellite IDs
for (uint8_t i = 0; i < 12; i++)
{
if (i < gloUsedCount)
length = snprintf(pMarker, lengthRemaining, "%02d,", gloUsedList[i]);
else
length = snprintf(pMarker, lengthRemaining, ",");
if (length < 0 || length >= lengthRemaining)
{
LOC_LOGE("NMEA Error in string formatting");
return;
}
pMarker += length;
lengthRemaining -= length;
}
// Add the position/horizontal/vertical DOP values
if (locationExtended.flags & GPS_LOCATION_EXTENDED_HAS_DOP)
{ // dop is in locationExtended, (QMI)
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
locationExtended.pdop,
locationExtended.hdop,
locationExtended.vdop);
}
else if (loc_eng_data_p->pdop > 0 && loc_eng_data_p->hdop > 0 && loc_eng_data_p->vdop > 0)
{ // dop was cached from sv report (RPC)
length = snprintf(pMarker, lengthRemaining, "%.1f,%.1f,%.1f",
loc_eng_data_p->pdop,
loc_eng_data_p->hdop,
loc_eng_data_p->vdop);
}
else
{ // no dop
length = snprintf(pMarker, lengthRemaining, ",,");
}
/* Sentence is ready, add checksum and broadcast */
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
// ------------------ // ------------------
// ------$GPVTG------ // ------$GPVTG------
// ------------------ // ------------------
@ -565,6 +664,10 @@ void loc_eng_nmea_generate_pos(loc_eng_data_s_type *loc_eng_data_p,
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p); loc_eng_nmea_send(sentence, length, loc_eng_data_p);
strlcpy(sentence, "$GNGSA,A,1,,,,,,,,,,,,,,,", sizeof(sentence));
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p);
strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence)); strlcpy(sentence, "$GPVTG,,T,,M,,N,,K,N", sizeof(sentence));
length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence)); length = loc_eng_nmea_put_checksum(sentence, sizeof(sentence));
loc_eng_nmea_send(sentence, length, loc_eng_data_p); loc_eng_nmea_send(sentence, length, loc_eng_data_p);
@ -790,9 +893,10 @@ void loc_eng_nmea_generate_sv(loc_eng_data_s_type *loc_eng_data_p,
}//if }//if
// cache the used in fix mask, as it will be needed to send $GPGSA // cache the used in fix mask, as it will be needed to send $GPGSA/$GNGSA
// during the position report // during the position report
loc_eng_data_p->sv_used_mask = svStatus.gps_used_in_fix_mask; loc_eng_data_p->gps_used_mask = svStatus.gps_used_in_fix_mask;
loc_eng_data_p->glo_used_mask = svStatus.glo_used_in_fix_mask;
// For RPC, the DOP are sent during sv report, so cache them // For RPC, the DOP are sent during sv report, so cache them
// now to be sent during position report. // now to be sent during position report.