1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-25 09:16:07 +03:00

GPS - differenciate between timeouts and crc errors. Improve packet

logging.  Cleanup UBLOX packet parsing.
This commit is contained in:
Dominic Clifton 2014-12-12 18:26:38 +00:00
parent 34385041ad
commit 20f32d632c
3 changed files with 57 additions and 30 deletions

View file

@ -302,29 +302,29 @@ void showGpsPage() {
i2c_OLED_set_line(rowIndex++); i2c_OLED_set_line(rowIndex++);
i2c_OLED_send_string(lineBuffer); i2c_OLED_send_string(lineBuffer);
tfp_sprintf(lineBuffer, "Lat: %d, Lon: %d", GPS_coord[LAT] / GPS_DEGREES_DIVIDER, GPS_coord[LON] / GPS_DEGREES_DIVIDER); tfp_sprintf(lineBuffer, "Lat: %d Lon: %d", GPS_coord[LAT] / GPS_DEGREES_DIVIDER, GPS_coord[LON] / GPS_DEGREES_DIVIDER);
padLineBuffer(); padLineBuffer();
i2c_OLED_set_line(rowIndex++); i2c_OLED_set_line(rowIndex++);
i2c_OLED_send_string(lineBuffer); i2c_OLED_send_string(lineBuffer);
tfp_sprintf(lineBuffer, "Msg Delta: %d", gpsData.lastMessage - gpsData.lastLastMessage); tfp_sprintf(lineBuffer, "Spd: %d cm/s GC: %d", GPS_speed, GPS_ground_course);
padLineBuffer(); padLineBuffer();
i2c_OLED_set_line(rowIndex++); i2c_OLED_set_line(rowIndex++);
i2c_OLED_send_string(lineBuffer); i2c_OLED_send_string(lineBuffer);
#ifdef GPS_PH_DEBUG #ifdef GPS_PH_DEBUG
tfp_sprintf(lineBuffer, "Angles: P:%d, R:%d", GPS_angle[PITCH], GPS_angle[ROLL]); tfp_sprintf(lineBuffer, "Angles: P:%d R:%d", GPS_angle[PITCH], GPS_angle[ROLL]);
padLineBuffer(); padLineBuffer();
i2c_OLED_set_line(rowIndex++); i2c_OLED_set_line(rowIndex++);
i2c_OLED_send_string(lineBuffer); i2c_OLED_send_string(lineBuffer);
#endif #endif
tfp_sprintf(lineBuffer, "%d cm/s, gc: %d", GPS_speed, GPS_ground_course); tfp_sprintf(lineBuffer, "RX: %d Delta: %d", GPS_packetCount, gpsData.lastMessage - gpsData.lastLastMessage);
padLineBuffer(); padLineBuffer();
i2c_OLED_set_line(rowIndex++); i2c_OLED_set_line(rowIndex++);
i2c_OLED_send_string(lineBuffer); i2c_OLED_send_string(lineBuffer);
tfp_sprintf(lineBuffer, "Errors: %d", gpsData.errors); tfp_sprintf(lineBuffer, "ERRs: %d TOs: %d", gpsData.errors, gpsData.timeouts);
padLineBuffer(); padLineBuffer();
i2c_OLED_set_line(rowIndex++); i2c_OLED_set_line(rowIndex++);
i2c_OLED_send_string(lineBuffer); i2c_OLED_send_string(lineBuffer);

View file

@ -56,10 +56,13 @@ void updateDisplay(void);
extern int16_t debug[4]; extern int16_t debug[4];
#define LOG_NMEA_GGA 'g'
#define LOG_NMEA_RMC 'r'
#define LOG_UBLOX_SOL 'O' #define LOG_ERROR '?'
#define LOG_IGNORED '!'
#define LOG_SKIPPED '>'
#define LOG_NMEA_GGA 'g'
#define LOG_NMEA_RMC 'r'
#define LOG_UBLOX_SOL 'O'
#define LOG_UBLOX_STATUS 'S' #define LOG_UBLOX_STATUS 'S'
#define LOG_UBLOX_SVINFO 'I' #define LOG_UBLOX_SVINFO 'I'
#define LOG_UBLOX_POSLLH 'P' #define LOG_UBLOX_POSLLH 'P'
@ -74,6 +77,7 @@ int32_t GPS_coord[2]; // LAT/LON
uint8_t GPS_numSat; uint8_t GPS_numSat;
uint16_t GPS_hdop = 9999; // Compute GPS quality signal uint16_t GPS_hdop = 9999; // Compute GPS quality signal
uint32_t GPS_packetCount = 0;
uint8_t GPS_update = 0; // it's a binary toggle to distinct a GPS position update uint8_t GPS_update = 0; // it's a binary toggle to distinct a GPS position update
uint16_t GPS_altitude; // altitude in 0.1m uint16_t GPS_altitude; // altitude in 0.1m
@ -170,6 +174,16 @@ enum {
gpsData_t gpsData; gpsData_t gpsData;
static void shiftPacketLog(void)
{
uint32_t i;
for (i = sizeof(gpsPacketLog) - 1; i > 0 ; i--) {
gpsPacketLog[i] = gpsPacketLog[i-1];
}
}
static void gpsNewData(uint16_t c); static void gpsNewData(uint16_t c);
static bool gpsNewFrameNMEA(char c); static bool gpsNewFrameNMEA(char c);
static bool gpsNewFrameUBLOX(uint8_t data); static bool gpsNewFrameUBLOX(uint8_t data);
@ -196,8 +210,8 @@ void gpsInit(serialConfig_t *initialSerialConfig, gpsConfig_t *initialGpsConfig)
} }
} }
// clear error counter
gpsData.errors = 0; gpsData.errors = 0;
gpsData.timeouts = 0;
memset(gpsPacketLog, 0x00, sizeof(gpsPacketLog)); memset(gpsPacketLog, 0x00, sizeof(gpsPacketLog));
@ -207,7 +221,6 @@ void gpsInit(serialConfig_t *initialSerialConfig, gpsConfig_t *initialGpsConfig)
gpsSetState(GPS_UNKNOWN); gpsSetState(GPS_UNKNOWN);
gpsData.lastMessage = millis(); gpsData.lastMessage = millis();
gpsData.errors = 0;
portMode_t mode = MODE_RXTX; portMode_t mode = MODE_RXTX;
// only RX is needed for NMEA-style GPS // only RX is needed for NMEA-style GPS
@ -349,7 +362,7 @@ void gpsThread(void)
break; break;
case GPS_LOST_COMMUNICATION: case GPS_LOST_COMMUNICATION:
gpsData.errors++; gpsData.timeouts++;
if (gpsConfig->autoBaud) { if (gpsConfig->autoBaud) {
// try another rate // try another rate
gpsData.baudrateIndex++; gpsData.baudrateIndex++;
@ -410,7 +423,7 @@ bool gpsNewFrame(uint8_t c)
/* This is a light implementation of a GPS frame decoding /* This is a light implementation of a GPS frame decoding
This should work with most of modern GPS devices configured to output NMEA frames. This should work with most of modern GPS devices configured to output 5 frames.
It assumes there are some NMEA GGA frames to decode on the serial bus It assumes there are some NMEA GGA frames to decode on the serial bus
Now verifies checksum correctly before applying data Now verifies checksum correctly before applying data
@ -582,10 +595,11 @@ static bool gpsNewFrameNMEA(char c)
case '\r': case '\r':
case '\n': case '\n':
if (checksum_param) { //parity checksum if (checksum_param) { //parity checksum
shiftPacketLog();
uint8_t checksum = 16 * ((string[0] >= 'A') ? string[0] - 'A' + 10 : string[0] - '0') + ((string[1] >= 'A') ? string[1] - 'A' + 10 : string[1] - '0'); uint8_t checksum = 16 * ((string[0] >= 'A') ? string[0] - 'A' + 10 : string[0] - '0') + ((string[1] >= 'A') ? string[1] - 'A' + 10 : string[1] - '0');
if (checksum == parity) { if (checksum == parity) {
*gpsPacketLogChar = '?'; *gpsPacketLogChar = LOG_IGNORED;
GPS_packetCount++;
switch (gps_frame) { switch (gps_frame) {
case FRAME_GGA: case FRAME_GGA:
*gpsPacketLogChar = LOG_NMEA_GGA; *gpsPacketLogChar = LOG_NMEA_GGA;
@ -603,6 +617,8 @@ static bool gpsNewFrameNMEA(char c)
GPS_ground_course = gps_Msg.ground_course; GPS_ground_course = gps_Msg.ground_course;
break; break;
} // end switch } // end switch
} else {
*gpsPacketLogChar = LOG_ERROR;
} }
} }
checksum_param = 0; checksum_param = 0;
@ -789,10 +805,7 @@ static bool UBLOX_parse_gps(void)
{ {
uint32_t i; uint32_t i;
for (i = sizeof(gpsPacketLog) - 1; i > 0 ; i--) { *gpsPacketLogChar = LOG_IGNORED;
gpsPacketLog[i] = gpsPacketLog[i-1];
}
*gpsPacketLogChar = '?';
switch (_msg_id) { switch (_msg_id) {
case MSG_POSLLH: case MSG_POSLLH:
@ -859,16 +872,18 @@ static bool gpsNewFrameUBLOX(uint8_t data)
bool parsed = false; bool parsed = false;
switch (_step) { switch (_step) {
case 1: // Sync char 2 (0x62) case 0: // Sync char 1 (0xB5)
if (PREAMBLE2 == data) { if (PREAMBLE1 == data) {
_step++;
_skip_packet = false; _skip_packet = false;
_step++;
}
break;
case 1: // Sync char 2 (0x62)
if (PREAMBLE2 != data) {
_step = 0;
break; break;
} }
_step = 0; _step++;
case 0: // Sync char 1 (0xB5)
if (PREAMBLE1 == data)
_step++;
break; break;
case 2: // Class case 2: // Class
_step++; _step++;
@ -899,21 +914,32 @@ static bool gpsNewFrameUBLOX(uint8_t data)
if (_payload_counter < UBLOX_PAYLOAD_SIZE) { if (_payload_counter < UBLOX_PAYLOAD_SIZE) {
_buffer.bytes[_payload_counter] = data; _buffer.bytes[_payload_counter] = data;
} }
if (++_payload_counter == _payload_length) if (++_payload_counter >= _payload_length) {
_step++; _step++;
}
break; break;
case 7: case 7:
_step++; _step++;
if (_ck_a != data) if (_ck_a != data) {
_step = 0; // bad checksum _skip_packet = true; // bad checksum
gpsData.errors++;
}
break; break;
case 8: case 8:
_step = 0; _step = 0;
shiftPacketLog();
if (_ck_b != data) { if (_ck_b != data) {
*gpsPacketLogChar = LOG_ERROR;
gpsData.errors++;
break; // bad checksum break; // bad checksum
} }
GPS_packetCount++;
if (_skip_packet) { if (_skip_packet) {
*gpsPacketLogChar = LOG_SKIPPED;
break; break;
} }

View file

@ -89,7 +89,8 @@ typedef enum {
typedef struct gpsData_t { typedef struct gpsData_t {
uint8_t state; // GPS thread state. Used for detecting cable disconnects and configuring attached devices uint8_t state; // GPS thread state. Used for detecting cable disconnects and configuring attached devices
uint8_t baudrateIndex; // index into auto-detecting or current baudrate uint8_t baudrateIndex; // index into auto-detecting or current baudrate
int errors; // gps error counter - crc error/lost of data/sync etc. reset on each reinit. uint32_t errors; // gps error counter - crc error/lost of data/sync etc..
uint32_t timeouts;
uint32_t lastMessage; // last time valid GPS data was received (millis) uint32_t lastMessage; // last time valid GPS data was received (millis)
uint32_t lastLastMessage; // last-last valid GPS message. Used to calculate delta. uint32_t lastLastMessage; // last-last valid GPS message. Used to calculate delta.
@ -107,7 +108,7 @@ extern int32_t GPS_coord[2]; // LAT/LON
extern uint8_t GPS_numSat; extern uint8_t GPS_numSat;
extern uint16_t GPS_hdop; // GPS signal quality extern uint16_t GPS_hdop; // GPS signal quality
extern uint8_t GPS_update; // it's a binary toogle to distinct a GPS position update extern uint8_t GPS_update; // it's a binary toogle to distinct a GPS position update
extern uint32_t GPS_packetCount;
extern uint16_t GPS_altitude; // altitude in 0.1m extern uint16_t GPS_altitude; // altitude in 0.1m
extern uint16_t GPS_speed; // speed in 0.1m/s extern uint16_t GPS_speed; // speed in 0.1m/s
extern uint16_t GPS_ground_course; // degrees * 10 extern uint16_t GPS_ground_course; // degrees * 10