From baeb379a827c6f987814cca27472c203ed424e2c Mon Sep 17 00:00:00 2001 From: Cliff Geerdes <cliffsjunk@att.net> Date: Thu, 11 Feb 2016 00:55:47 -0500 Subject: [PATCH] LP-212 changes from code review --- flight/modules/GPS/DJI.c | 302 +++++++++--------- flight/modules/GPS/GPS.c | 2 + flight/modules/GPS/UBX.c | 55 ++-- flight/modules/GPS/inc/DJI.h | 68 ++-- flight/modules/GPS/inc/UBX.h | 2 +- flight/modules/GPS/ubx_autoconfig.c | 6 +- flight/modules/Sensors/sensors.c | 8 +- .../firmware/inc/pios_config.h | 1 + 8 files changed, 226 insertions(+), 218 deletions(-) diff --git a/flight/modules/GPS/DJI.c b/flight/modules/GPS/DJI.c index a68c6a9d5..4d7ddf1de 100644 --- a/flight/modules/GPS/DJI.c +++ b/flight/modules/GPS/DJI.c @@ -33,47 +33,47 @@ #include "pios_math.h" #include <pios_helpers.h> #include <pios_delay.h> -// dji parser is required for sensorType -#if (defined(PIOS_INCLUDE_GPS_DJI_PARSER) && defined(PIOS_INCLUDE_GPS_DJI_PARSER)) + +#if defined(PIOS_INCLUDE_GPS_DJI_PARSER) + #include "inc/DJI.h" #include "inc/GPS.h" #include <string.h> - #include <auxmagsupport.h> -bool useMag = false; - -// this is defined in DJI.c -extern GPSPositionSensorSensorTypeOptions sensorType; - // parsing functions, roughly ordered by reception rate (higher rate messages on top) -static void parse_dji_mag(struct DJIPacket *dji, GPSPositionSensorData *GpsPosition); -static void parse_dji_gps(struct DJIPacket *dji, GPSPositionSensorData *GpsPosition); -static void parse_dji_ver(struct DJIPacket *dji, GPSPositionSensorData *GpsPosition); +static void parse_dji_mag(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); +static void parse_dji_gps(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); +static void parse_dji_ver(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); + +static bool checksum_dji_message(struct DJIPacket *dji); +static uint32_t parse_dji_message(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); // parse table item typedef struct { - uint8_t msgID; - void (*handler)(struct DJIPacket *, GPSPositionSensorData *GpsPosition); -} dji_message_handler; + uint8_t msgId; + void (*handler)(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition); +} djiMessageHandler; -const dji_message_handler dji_handler_table[] = { - { .msgID = DJI_ID_GPS, .handler = &parse_dji_gps }, - { .msgID = DJI_ID_MAG, .handler = &parse_dji_mag }, - { .msgID = DJI_ID_VER, .handler = &parse_dji_ver }, +const djiMessageHandler djiHandlerTable[] = { + { .msgId = DJI_ID_GPS, .handler = &parse_dji_gps }, + { .msgId = DJI_ID_MAG, .handler = &parse_dji_mag }, + { .msgId = DJI_ID_VER, .handler = &parse_dji_ver }, }; -#define DJI_HANDLER_TABLE_SIZE NELEMENTS(dji_handler_table) +#define DJI_HANDLER_TABLE_SIZE NELEMENTS(djiHandlerTable) +static bool useMag = false; // detected hw version uint32_t djiHwVersion = -1; uint32_t djiSwVersion = -1; + // parse incoming character stream for messages in DJI binary format -int parse_dji_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPositionSensorData *GpsData, struct GPS_RX_STATS *gpsRxStats) +#define djiPacket ((struct DJIPacket *)parsedDjiStruct) +int parse_dji_stream(uint8_t *inputBuffer, uint16_t inputBufferLength, char *parsedDjiStruct, GPSPositionSensorData *gpsPosition, struct GPS_RX_STATS *gpsRxStats) { - int ret = PARSER_INCOMPLETE; // message not (yet) complete - enum proto_states { + enum ProtocolStates { START, DJI_SY2, DJI_ID, @@ -83,105 +83,104 @@ int parse_dji_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition DJI_CHK2, FINISHED }; - enum restart_states { + enum RestartStates { RESTART_WITH_ERROR, RESTART_NO_ERROR }; - uint8_t c; - static enum proto_states proto_state = START; - static uint16_t rx_count = 0; - struct DJIPacket *dji = (struct DJIPacket *)gps_rx_buffer; - uint16_t i = 0; - uint16_t restart_index = 0; - enum restart_states restart_state; - static bool previous_packet_good = true; - bool current_packet_good; + static uint16_t payloadCount = 0; + static enum ProtocolStates protocolState = START; + static bool previousPacketGood = true; + int ret = PARSER_INCOMPLETE; // message not (yet) complete + uint16_t inputBufferIndex = 0; + uint16_t restartIndex = 0; // input buffer location to restart from + enum RestartStates restartState; + uint8_t inputByte; + bool currentPacketGood; // switch continue is the normal condition and comes back to here for another byte // switch break is the error state that branches to the end and restarts the scan at the byte after the first sync byte - while (i < len) { - c = rx[i++]; - switch (proto_state) { + while (inputBufferIndex < inputBufferLength) { + inputByte = inputBuffer[inputBufferIndex++]; + switch (protocolState) { case START: // detect protocol - if (c == DJI_SYNC1) { // first DJI sync char found - proto_state = DJI_SY2; + if (inputByte == DJI_SYNC1) { // first DJI sync char found + protocolState = DJI_SY2; // restart here, at byte after SYNC1, if we fail to parse - restart_index = i; + restartIndex = inputBufferIndex; } continue; case DJI_SY2: - if (c == DJI_SYNC2) { // second DJI sync char found - proto_state = DJI_ID; + if (inputByte == DJI_SYNC2) { // second DJI sync char found + protocolState = DJI_ID; } else { - restart_state = RESTART_NO_ERROR; + restartState = RESTART_NO_ERROR; break; } continue; case DJI_ID: - dji->header.id = c; - proto_state = DJI_LEN; + djiPacket->header.id = inputByte; + protocolState = DJI_LEN; continue; case DJI_LEN: - if (c > sizeof(DJIPayload)) { + if (inputByte > sizeof(DJIPayload)) { gpsRxStats->gpsRxOverflow++; #if defined(PIOS_GPS_MINIMAL) - restart_state = RESTART_NO_ERROR; - break; + restartState = RESTART_NO_ERROR; #else - restart_state = RESTART_WITH_ERROR; - break; + restartState = RESTART_WITH_ERROR; #endif + break; } else { - dji->header.len = c; - if (c == 0) { - proto_state = DJI_CHK1; + djiPacket->header.len = inputByte; + if (inputByte == 0) { + protocolState = DJI_CHK1; } else { - rx_count = 0; - proto_state = DJI_PAYLOAD; + payloadCount = 0; + protocolState = DJI_PAYLOAD; } } continue; case DJI_PAYLOAD: - if (rx_count < dji->header.len) { - dji->payload.payload[rx_count] = c; - if (++rx_count == dji->header.len) { - proto_state = DJI_CHK1; + if (payloadCount < djiPacket->header.len) { + djiPacket->payload.payload[payloadCount] = inputByte; + if (++payloadCount == djiPacket->header.len) { + protocolState = DJI_CHK1; } } continue; case DJI_CHK1: - dji->header.ck_a = c; - proto_state = DJI_CHK2; + djiPacket->header.checksumA = inputByte; + protocolState = DJI_CHK2; continue; case DJI_CHK2: - dji->header.ck_b = c; + djiPacket->header.checksumB = inputByte; // ignore checksum errors on correct mag packets that nonetheless have checksum errors // these checksum errors happen very often on clone DJI GPS (never on real DJI GPS) // and are caused by a clone DJI GPS firmware error // the errors happen when it is time to send a non-mag packet (4 or 5 per second) // instead of a mag packet (30 per second) - current_packet_good = checksum_dji_message(dji); + currentPacketGood = checksum_dji_message(djiPacket); // message complete and valid or (it's a mag packet and the previous "any" packet was good) - if (current_packet_good || (dji->header.id == DJI_ID_MAG && previous_packet_good)) { - parse_dji_message(dji, GpsData); + if (currentPacketGood || (djiPacket->header.id == DJI_ID_MAG && previousPacketGood)) { + parse_dji_message(djiPacket, gpsPosition); gpsRxStats->gpsRxReceived++; - proto_state = START; + protocolState = START; // overwrite PARSER_INCOMPLETE with PARSER_COMPLETE // but don't overwrite PARSER_ERROR with PARSER_COMPLETE // pass PARSER_ERROR to caller if it happens even once // only pass PARSER_COMPLETE back to caller if we parsed a full set of GPS data // that allows the caller to know if we are parsing GPS data // or just other packets for some reason (DJI clone firmware bug that happens sometimes) - if (dji->header.id == DJI_ID_GPS && ret == PARSER_INCOMPLETE) { + if (djiPacket->header.id == DJI_ID_GPS && ret == PARSER_INCOMPLETE) { ret = PARSER_COMPLETE; // message complete & processed } } else { gpsRxStats->gpsRxChkSumError++; - restart_state = RESTART_WITH_ERROR; - previous_packet_good = false; + restartState = RESTART_WITH_ERROR; + previousPacketGood = false; break; } - previous_packet_good = current_packet_good; + previousPacketGood = currentPacketGood; continue; default: continue; @@ -192,13 +191,13 @@ int parse_dji_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition // and it does the expected thing across calls // if restarting due to error detected in 2nd call to this function (on split packet) // then we just restart at index 0, which is mid-packet, not the second byte - if (restart_state == RESTART_WITH_ERROR) { + if (restartState == RESTART_WITH_ERROR) { ret = PARSER_ERROR; // inform caller that we found at least one error (along with 0 or more good packets) } - rx += restart_index; // restart parsing just past the most recent SYNC1 - len -= restart_index; - i = 0; - proto_state = START; + inputBuffer += restartIndex; // restart parsing just past the most recent SYNC1 + inputBufferLength -= restartIndex; + inputBufferIndex = 0; + protocolState = START; } return ret; @@ -208,21 +207,21 @@ int parse_dji_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition bool checksum_dji_message(struct DJIPacket *dji) { int i; - uint8_t ck_a, ck_b; + uint8_t checksumA, checksumB; - ck_a = dji->header.id; - ck_b = ck_a; + checksumA = dji->header.id; + checksumB = checksumA; - ck_a += dji->header.len; - ck_b += ck_a; + checksumA += dji->header.len; + checksumB += checksumA; for (i = 0; i < dji->header.len; i++) { - ck_a += dji->payload.payload[i]; - ck_b += ck_a; + checksumA += dji->payload.payload[i]; + checksumB += checksumA; } - if (dji->header.ck_a == ck_a && - dji->header.ck_b == ck_b) { + if (dji->header.checksumA == checksumA && + dji->header.checksumB == checksumB) { return true; } else { return false; @@ -230,53 +229,59 @@ bool checksum_dji_message(struct DJIPacket *dji) } -static void parse_dji_gps(struct DJIPacket *dji, GPSPositionSensorData *GpsPosition) +static void parse_dji_gps(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition) { - static bool inited = false; - - if (!inited) { - inited = true; - // Is there a model calculation we can do to get a reasonable value for geoid separation? - } - - GPSVelocitySensorData GpsVelocity; - struct DJI_GPS *gps = &dji->payload.gps; + GPSVelocitySensorData gpsVelocity; + struct DjiGps *djiGps = &dji->payload.gps; // decode with xor mask - uint8_t mask = gps->unused5; - // for (uint8_t i=0; i<dji->header->len; ++i) { - for (uint8_t i = 0; i < 56; ++i) { - // if (i!=48 && i!=49 && i<=55) { - if (i != 48 && i != 49) { + uint8_t mask = djiGps->unused5; + + // some bytes at the end are not xored + // some bytes in the middle are not xored + for (uint8_t i = 0; i < GPS_DECODED_LENGTH; ++i) { + if (i != GPS_NOT_XORED_BYTE_1 && i != GPS_NOT_XORED_BYTE_2) { dji->payload.payload[i] ^= mask; } } - GpsVelocity.North = (float)gps->velN * 0.01f; - GpsVelocity.East = (float)gps->velE * 0.01f; - GpsVelocity.Down = (float)gps->velD * 0.01f; - GPSVelocitySensorSet(&GpsVelocity); + gpsVelocity.North = (float)djiGps->velN * 0.01f; + gpsVelocity.East = (float)djiGps->velE * 0.01f; + gpsVelocity.Down = (float)djiGps->velD * 0.01f; + GPSVelocitySensorSet(&gpsVelocity); - GpsPosition->Groundspeed = sqrtf(GpsVelocity.North * GpsVelocity.North + GpsVelocity.East * GpsVelocity.East); - GpsPosition->Heading = RAD2DEG(atan2f(-GpsVelocity.East, -GpsVelocity.North)) + 180.0f; - GpsPosition->Altitude = (float)gps->hMSL * 0.001f; + gpsPosition->Groundspeed = sqrtf(gpsVelocity.North * gpsVelocity.North + gpsVelocity.East * gpsVelocity.East); + // don't allow a funny number like 4.87416e-06 to show up in Uavo Browser for Heading + // smallest groundspeed is 0.01f from (int)1 * (float)0.01 + // so this is saying if groundspeed is zero + if (gpsPosition->Groundspeed < 0.009f) { + gpsPosition->Heading = 0.0f; + } else { + gpsPosition->Heading = RAD2DEG(atan2f(-gpsVelocity.East, -gpsVelocity.North)) + 180.0f; + } + gpsPosition->Altitude = (float)djiGps->hMSL * 0.001f; // there is no source of geoid separation data in the DJI protocol - GpsPosition->GeoidSeparation = 0.0f; - GpsPosition->Latitude = gps->lat; - GpsPosition->Longitude = gps->lon; - GpsPosition->Satellites = gps->numSV; - GpsPosition->PDOP = gps->pDOP * 0.01f; - GpsPosition->HDOP = sqrtf((float)gps->nDOP * (float)gps->nDOP + (float)gps->eDOP * (float)gps->eDOP) * 0.01f; - GpsPosition->VDOP = gps->vDOP * 0.01f; - if (gps->flags & FLAGS_GPSFIX_OK) { - GpsPosition->Status = gps->fixType == FIXTYPE_3D ? + // Is there a reasonable world model calculation we can do to get a value for geoid separation? + gpsPosition->GeoidSeparation = 0.0f; + gpsPosition->Latitude = djiGps->lat; + gpsPosition->Longitude = djiGps->lon; + gpsPosition->Satellites = djiGps->numSV; + gpsPosition->PDOP = djiGps->pDOP * 0.01f; + gpsPosition->HDOP = sqrtf((float)djiGps->nDOP * (float)djiGps->nDOP + (float)djiGps->eDOP * (float)djiGps->eDOP) * 0.01f; + if (gpsPosition->HDOP > 99.99f) { + gpsPosition->HDOP = 99.99f; + } + gpsPosition->VDOP = djiGps->vDOP * 0.01f; + if (djiGps->flags & FLAGS_GPSFIX_OK) { + gpsPosition->Status = djiGps->fixType == FIXTYPE_3D ? GPSPOSITIONSENSOR_STATUS_FIX3D : GPSPOSITIONSENSOR_STATUS_FIX2D; } else { - GpsPosition->Status = GPSPOSITIONSENSOR_STATUS_NOFIX; + gpsPosition->Status = GPSPOSITIONSENSOR_STATUS_NOFIX; } - GpsPosition->SensorType = GPSPOSITIONSENSOR_SENSORTYPE_DJI; - GpsPosition->AutoConfigStatus = GPSPOSITIONSENSOR_AUTOCONFIGSTATUS_DISABLED; - GPSPositionSensorSet(GpsPosition); + gpsPosition->SensorType = GPSPOSITIONSENSOR_SENSORTYPE_DJI; + gpsPosition->AutoConfigStatus = GPSPOSITIONSENSOR_AUTOCONFIGSTATUS_DISABLED; + // gpsPosition->BaudRate = GPSPOSITIONSENSOR_BAUDRATE_115200; + GPSPositionSensorSet(gpsPosition); // Time is valid, set GpsTime GPSTimeData GpsTime; @@ -287,22 +292,22 @@ static void parse_dji_gps(struct DJIPacket *dji, GPSPositionSensorData *GpsPosit // and maybe make the assumption that most people will fly at 5pm, not 1am // this is part of the DJI protocol // see DJI.h for further info - GpsTime.Year = (int16_t)gps->year + 2000; - GpsTime.Month = gps->month; - GpsTime.Day = gps->day; - GpsTime.Hour = gps->hour; - GpsTime.Minute = gps->min; - GpsTime.Second = gps->sec; + GpsTime.Year = (int16_t)djiGps->year + 2000; + GpsTime.Month = djiGps->month; + GpsTime.Day = djiGps->day; + GpsTime.Hour = djiGps->hour; + GpsTime.Minute = djiGps->min; + GpsTime.Second = djiGps->sec; GPSTimeSet(&GpsTime); } -static void parse_dji_mag(struct DJIPacket *dji, __attribute__((unused)) GPSPositionSensorData *GpsPosition) +static void parse_dji_mag(struct DJIPacket *dji, __attribute__((unused)) GPSPositionSensorData *gpsPosition) { if (!useMag) { return; } - struct DJI_MAG *mag = &dji->payload.mag; + struct DjiMag *mag = &dji->payload.mag; union { struct { int8_t mask; @@ -318,45 +323,49 @@ static void parse_dji_mag(struct DJIPacket *dji, __attribute__((unused)) GPSPosi } -static void parse_dji_ver(struct DJIPacket *dji, __attribute__((unused)) GPSPositionSensorData *GpsPosition) +static void parse_dji_ver(struct DJIPacket *dji, __attribute__((unused)) GPSPositionSensorData *gpsPosition) { - struct DJI_VER *ver = &dji->payload.ver; + { + struct DjiVer *ver = &dji->payload.ver; + // decode with xor mask + uint8_t mask = (uint8_t)(ver->unused1); - // decode with xor mask - uint8_t mask = (uint8_t)(ver->unused1); + // first 4 bytes are unused and 0 before the encryption + // so any one of them can be used for the decrypting xor mask + for (uint8_t i = VER_FIRST_DECODED_BYTE; i < sizeof(struct DjiVer); ++i) { + dji->payload.payload[i] ^= mask; + } - // for (uint8_t i=0; i<dji->header->len; ++i) { - for (uint8_t i = 4; i < 12; ++i) { - dji->payload.payload[i] ^= mask; + djiHwVersion = ver->hwVersion; + djiSwVersion = ver->swVersion; + } + { + GPSPositionSensorSensorTypeOptions sensorType; + sensorType = GPSPOSITIONSENSOR_SENSORTYPE_DJI; + GPSPositionSensorSensorTypeSet((uint8_t *)&sensorType); } - - djiHwVersion = ver->hwVersion; - djiSwVersion = ver->swVersion; - sensorType = GPSPOSITIONSENSOR_SENSORTYPE_DJI; - GPSPositionSensorSensorTypeSet((uint8_t *)&sensorType); } // DJI message parser // returns UAVObjectID if a UAVObject structure is ready for further processing - -uint32_t parse_dji_message(struct DJIPacket *dji, GPSPositionSensorData *GpsPosition) +uint32_t parse_dji_message(struct DJIPacket *dji, GPSPositionSensorData *gpsPosition) { - uint32_t id = 0; static bool djiInitialized = false; + uint32_t id = 0; if (!djiInitialized) { // initialize dop values. If no DOP sentence is received it is safer to initialize them to a high value rather than 0. - GpsPosition->HDOP = 99.99f; - GpsPosition->PDOP = 99.99f; - GpsPosition->VDOP = 99.99f; + gpsPosition->HDOP = 99.99f; + gpsPosition->PDOP = 99.99f; + gpsPosition->VDOP = 99.99f; djiInitialized = true; } for (uint8_t i = 0; i < DJI_HANDLER_TABLE_SIZE; i++) { - const dji_message_handler *handler = &dji_handler_table[i]; - if (handler->msgID == dji->header.id) { - handler->handler(dji, GpsPosition); + const djiMessageHandler *handler = &djiHandlerTable[i]; + if (handler->msgId == dji->header.id) { + handler->handler(dji, gpsPosition); break; } } @@ -374,6 +383,7 @@ uint32_t parse_dji_message(struct DJIPacket *dji, GPSPositionSensorData *GpsPosi return id; } + void dji_load_mag_settings() { if (auxmagsupport_get_type() == AUXMAGSETTINGS_TYPE_DJI) { diff --git a/flight/modules/GPS/GPS.c b/flight/modules/GPS/GPS.c index 2306df0e9..f147bf5a0 100644 --- a/flight/modules/GPS/GPS.c +++ b/flight/modules/GPS/GPS.c @@ -574,6 +574,7 @@ static void updateHwSettings(UAVObjEvent __attribute__((unused)) *ev) if (gpsPort && gpsEnabled) { // if we have ubx auto config then sometimes we don't set the baud rate #if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) + // just for UBX, because it has autoconfig // if in startup, or not configured to do ubx and ubx auto config // // on first use of this port (previousGpsPort != gpsPort) we must set the Revo port baud rate @@ -588,6 +589,7 @@ static void updateHwSettings(UAVObjEvent __attribute__((unused)) *ev) // always set the baud rate gps_set_fc_baud_from_settings(); #if defined(PIOS_INCLUDE_GPS_UBX_PARSER) && !defined(PIOS_GPS_MINIMAL) + // just for UBX, because it has subtypes UBX(6), UBX7 and UBX8 // changing anything in HwSettings will make it re-verify the sensor type (including auto-baud if not completely disabled) // for auto baud disabled, the user can just try some baud rates and when the baud rate is correct, the sensor type becomes valid gps_ubx_reset_sensor_type(); diff --git a/flight/modules/GPS/UBX.c b/flight/modules/GPS/UBX.c index c80e1d007..368ca6b6c 100644 --- a/flight/modules/GPS/UBX.c +++ b/flight/modules/GPS/UBX.c @@ -34,22 +34,25 @@ #include "pios_math.h" #include <pios_helpers.h> #include <pios_delay.h> + #if defined(PIOS_INCLUDE_GPS_UBX_PARSER) + #include "inc/UBX.h" #include "inc/GPS.h" #include <string.h> -#ifndef PIOS_GPS_MINIMAL +#if !defined(PIOS_GPS_MINIMAL) #include <auxmagsupport.h> - static bool useMag = false; -#endif -GPSPositionSensorSensorTypeOptions sensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; +#endif /* !defined(PIOS_GPS_MINIMAL) */ + +// this is set and used by this low level ubx code +// it is also reset by the ubx configuration code (UBX6 vs. UBX7) in ubx_autoconfig.c +GPSPositionSensorSensorTypeOptions ubxSensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; static bool usePvt = false; static uint32_t lastPvtTime = 0; - // parse table item typedef struct { uint8_t msgClass; @@ -58,31 +61,27 @@ typedef struct { } ubx_message_handler; // parsing functions, roughly ordered by reception rate (higher rate messages on top) - static void parse_ubx_nav_posllh(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_velned(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_sol(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_dop(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); -#ifndef PIOS_GPS_MINIMAL +#if !defined(PIOS_GPS_MINIMAL) static void parse_ubx_nav_pvt(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_timeutc(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_nav_svinfo(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); - static void parse_ubx_op_sys(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_op_mag(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); - static void parse_ubx_ack_ack(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); static void parse_ubx_ack_nak(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); - static void parse_ubx_mon_ver(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition); -#endif +#endif /* !defined(PIOS_GPS_MINIMAL) */ const ubx_message_handler ubx_handler_table[] = { { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_POSLLH, .handler = &parse_ubx_nav_posllh }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_VELNED, .handler = &parse_ubx_nav_velned }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_SOL, .handler = &parse_ubx_nav_sol }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_DOP, .handler = &parse_ubx_nav_dop }, -#ifndef PIOS_GPS_MINIMAL +#if !defined(PIOS_GPS_MINIMAL) { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_PVT, .handler = &parse_ubx_nav_pvt }, { .msgClass = UBX_CLASS_OP_CUST, .msgID = UBX_ID_OP_MAG, .handler = &parse_ubx_op_mag }, { .msgClass = UBX_CLASS_NAV, .msgID = UBX_ID_NAV_SVINFO, .handler = &parse_ubx_nav_svinfo }, @@ -93,7 +92,7 @@ const ubx_message_handler ubx_handler_table[] = { { .msgClass = UBX_CLASS_ACK, .msgID = UBX_ID_ACK_NAK, .handler = &parse_ubx_ack_nak }, { .msgClass = UBX_CLASS_MON, .msgID = UBX_ID_MON_VER, .handler = &parse_ubx_mon_ver }, -#endif +#endif /* !defined(PIOS_GPS_MINIMAL) */ }; #define UBX_HANDLER_TABLE_SIZE NELEMENTS(ubx_handler_table) @@ -106,11 +105,10 @@ struct UBX_ACK_NAK ubxLastNak; // If a PVT sentence is received in the last UBX_PVT_TIMEOUT (ms) timeframe it disables VELNED/POSLLH/SOL/TIMEUTC #define UBX_PVT_TIMEOUT (1000) -// parse incoming character stream for messages in UBX binary format +// parse incoming character stream for messages in UBX binary format int parse_ubx_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPositionSensorData *GpsData, struct GPS_RX_STATS *gpsRxStats) { - int ret = PARSER_INCOMPLETE; // message not (yet) complete enum proto_states { START, UBX_SY2, @@ -127,13 +125,14 @@ int parse_ubx_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition RESTART_WITH_ERROR, RESTART_NO_ERROR }; - uint8_t c; - static enum proto_states proto_state = START; static uint16_t rx_count = 0; + static enum proto_states proto_state = START; struct UBXPacket *ubx = (struct UBXPacket *)gps_rx_buffer; + int ret = PARSER_INCOMPLETE; // message not (yet) complete uint16_t i = 0; uint16_t restart_index = 0; enum restart_states restart_state; + uint8_t c; // switch continue is the normal condition and comes back to here for another byte // switch break is the error state that branches to the end and restarts the scan at the byte after the first sync byte @@ -173,11 +172,10 @@ int parse_ubx_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition gpsRxStats->gpsRxOverflow++; #if defined(PIOS_GPS_MINIMAL) restart_state = RESTART_NO_ERROR; - break; #else restart_state = RESTART_WITH_ERROR; - break; #endif + break; } else { if (ubx->header.len == 0) { proto_state = UBX_CHK1; @@ -247,10 +245,8 @@ int parse_ubx_stream(uint8_t *rx, uint16_t len, char *gps_rx_buffer, GPSPosition return ret; } - // Keep track of various GPS messages needed to make up a single UAVO update // time-of-week timestamp is used to correlate matching messages - #define POSLLH_RECEIVED (1 << 0) #define STATUS_RECEIVED (1 << 1) #define DOP_RECEIVED (1 << 2) @@ -380,6 +376,7 @@ static void parse_ubx_nav_velned(struct UBXPacket *ubx, GPSPositionSensorData *G } } } + #if !defined(PIOS_GPS_MINIMAL) static void parse_ubx_nav_pvt(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition) { @@ -509,12 +506,12 @@ static void parse_ubx_mon_ver(struct UBXPacket *ubx, __attribute__((unused)) GPS { struct UBX_MON_VER *mon_ver = &ubx->payload.mon_ver; - ubxHwVersion = atoi(mon_ver->hwVersion); - sensorType = (ubxHwVersion >= 80000) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX8 : - ((ubxHwVersion >= 70000) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX7 : GPSPOSITIONSENSOR_SENSORTYPE_UBX); + ubxHwVersion = atoi(mon_ver->hwVersion); + ubxSensorType = (ubxHwVersion >= UBX_HW_VERSION_8) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX8 : + ((ubxHwVersion >= UBX_HW_VERSION_7) ? GPSPOSITIONSENSOR_SENSORTYPE_UBX7 : GPSPOSITIONSENSOR_SENSORTYPE_UBX); // send sensor type right now because on UBX NEMA we don't get a full set of messages // and we want to be able to see sensor type even on UBX NEMA GPS's - GPSPositionSensorSensorTypeSet((uint8_t *)&sensorType); + GPSPositionSensorSensorTypeSet((uint8_t *)&ubxSensorType); } static void parse_ubx_op_sys(struct UBXPacket *ubx, __attribute__((unused)) GPSPositionSensorData *GpsPosition) @@ -543,10 +540,8 @@ static void parse_ubx_op_mag(struct UBXPacket *ubx, __attribute__((unused)) GPSP } #endif /* if !defined(PIOS_GPS_MINIMAL) */ - // UBX message parser // returns UAVObjectID if a UAVObject structure is ready for further processing - uint32_t parse_ubx_message(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosition) { uint32_t id = 0; @@ -569,7 +564,7 @@ uint32_t parse_ubx_message(struct UBXPacket *ubx, GPSPositionSensorData *GpsPosi } } - GpsPosition->SensorType = sensorType; + GpsPosition->SensorType = ubxSensorType; if (msgtracker.msg_received == ALL_RECEIVED) { // leave BaudRate field alone! @@ -602,5 +597,5 @@ void op_gpsv9_load_mag_settings() useMag = false; } } -#endif -#endif // PIOS_INCLUDE_GPS_UBX_PARSER +#endif // !defined(PIOS_GPS_MINIMAL) +#endif // defined(PIOS_INCLUDE_GPS_UBX_PARSER) diff --git a/flight/modules/GPS/inc/DJI.h b/flight/modules/GPS/inc/DJI.h index cee8deccc..1cf58c82b 100644 --- a/flight/modules/GPS/inc/DJI.h +++ b/flight/modules/GPS/inc/DJI.h @@ -169,7 +169,7 @@ typedef enum { */ // DJI GPS packet -struct DJI_GPS { // byte offset from beginning of packet, subtract 5 for struct offset +struct DjiGps { // byte offset from beginning of packet, subtract 5 for struct offset struct { // YYYYYYYMMMMDDDDDHHHHMMMMMMSSSSSS uint32_t sec : 6; uint32_t min : 6; @@ -178,29 +178,29 @@ struct DJI_GPS { // byte offset from beginning of packet, subtract 5 for struct uint32_t month : 4; uint32_t year : 7; }; // BYTE 5-8 (DT): date and time, see details above - int32_t lon; // BYTE 9-12 (LO): longitude (x10^7, degree decimal) - int32_t lat; // BYTE 13-16 (LA): latitude (x10^7, degree decimal) - int32_t hMSL; // BYTE 17-20 (AL): altitude (in millimeters) (is this MSL or geoid?) + int32_t lon; // BYTE 9-12 (LO): longitude (x10^7, degree decimal) + int32_t lat; // BYTE 13-16 (LA): latitude (x10^7, degree decimal) + int32_t hMSL; // BYTE 17-20 (AL): altitude (in millimeters) (is this MSL or geoid?) uint32_t hAcc; // BYTE 21-24 (HA): horizontal accuracy estimate (see uBlox NAV-POSLLH message for details) uint32_t vAcc; // BYTE 25-28 (VA): vertical accuracy estimate (see uBlox NAV-POSLLH message for details) uint32_t unused1; // BYTE 29-32: ??? (seems to be always 0) - int32_t velN; // BYTE 33-36 (NV): NED north velocity (see uBlox NAV-VELNED message for details) - int32_t velE; // BYTE 37-40 (EV): NED east velocity (see uBlox NAV-VELNED message for details) - int32_t velD; // BYTE 41-44 (DV): NED down velocity (see uBlox NAV-VELNED message for details) + int32_t velN; // BYTE 33-36 (NV): NED north velocity (see uBlox NAV-VELNED message for details) + int32_t velE; // BYTE 37-40 (EV): NED east velocity (see uBlox NAV-VELNED message for details) + int32_t velD; // BYTE 41-44 (DV): NED down velocity (see uBlox NAV-VELNED message for details) uint16_t pDOP; // BYTE 45-46 (PD): position DOP (see uBlox NAV-DOP message for details) uint16_t vDOP; // BYTE 47-48 (VD): vertical DOP (see uBlox NAV-DOP message for details) uint16_t nDOP; // BYTE 49-50 (ND): northing DOP (see uBlox NAV-DOP message for details) uint16_t eDOP; // BYTE 51-52 (ED): easting DOP (see uBlox NAV-DOP message for details) - uint8_t numSV; // BYTE 53 (NS): number of satellites (not XORed) - uint8_t unused2; // BYTE 54: ??? (not XORed, seems to be always 0) - uint8_t fixType; // BYTE 55 (FT): fix type (0 - no lock, 2 - 2D lock, 3 - 3D lock, not sure if other values can be expected - // see uBlox NAV-SOL message for details) - uint8_t unused3; // BYTE 56: ??? (seems to be always 0) - uint8_t flags; // BYTE 57 (SF): fix status flags (see uBlox NAV-SOL message for details) + uint8_t numSV; // BYTE 53 (NS): number of satellites (not XORed) + uint8_t unused2; // BYTE 54: ??? (not XORed, seems to be always 0) + uint8_t fixType; // BYTE 55 (FT): fix type (0 - no lock, 2 - 2D lock, 3 - 3D lock, not sure if other values can be expected + // see uBlox NAV-SOL message for details) + uint8_t unused3; // BYTE 56: ??? (seems to be always 0) + uint8_t flags; // BYTE 57 (SF): fix status flags (see uBlox NAV-SOL message for details) uint16_t unused4; // BYTE 58-59: ??? (seems to be always 0) - uint8_t unused5; // BYTE 60 (XM): not sure yet, but I use it as the XOR mask + uint8_t unused5; // BYTE 60 (XM): not sure yet, but I use it as the XOR mask uint16_t seqNo; // BYTE 61-62 (SN): sequence number (not XORed), once there is a lock - // increases with every message. When the lock is lost later LSB and MSB are swapped with every message. + // increases with every message. When the lock is lost later LSB and MSB are swapped (in all messages where lock is lost). } __attribute__((packed)); #define FLAGS_GPSFIX_OK (1 << 0) @@ -208,12 +208,16 @@ struct DJI_GPS { // byte offset from beginning of packet, subtract 5 for struct #define FLAGS_WKNSET (1 << 2) #define FLAGS_TOWSET (1 << 3) -#define FIXTYPE_NO_FIX 0 -#define FIXTYPE_DEAD_RECKON 0x01 // Dead Reckoning only -#define FIXTYPE_2D 0x02 // 2D-Fix -#define FIXTYPE_3D 0x03 // 3D-Fix -#define FIXTYPE_GNSS_DEAD_RECKON 0x04 // GNSS + dead reckoning combined -#define FIXTYPE_TIME_ONLY 0x05 // Time only fix +#define FIXTYPE_NO_FIX 0x00 /* No Fix */ +#define FIXTYPE_DEAD_RECKON 0x01 /* Dead Reckoning only */ +#define FIXTYPE_2D 0x02 /* 2D-Fix */ +#define FIXTYPE_3D 0x03 /* 3D-Fix */ +#define FIXTYPE_GNSS_DEAD_RECKON 0x04 /* GNSS + dead reckoning combined */ +#define FIXTYPE_TIME_ONLY 0x05 /* Time only fix */ + +#define GPS_DECODED_LENGTH offsetof(struct DjiGps, seqNo) +#define GPS_NOT_XORED_BYTE_1 offsetof(struct DjiGps, numSV) +#define GPS_NOT_XORED_BYTE_2 offsetof(struct DjiGps, unused2) /* @@ -260,7 +264,7 @@ struct DJI_GPS { // byte offset from beginning of packet, subtract 5 for struct y any a (y and x?) values, convert radians to degrees and add 360 if the result is negative. */ -struct DJI_MAG { // byte offset from beginning of packet, subtract 5 for struct offset +struct DjiMag { // byte offset from beginning of packet, subtract 5 for struct offset int16_t x; // BYTE 5-6 (CX): compass X axis data (signed) - see comments below int16_t y; // BYTE 7-8 (CY): compass Y axis data (signed) - see comments below int16_t z; // BYTE 9-10 (CZ): compass Z axis data (signed) - see comments below @@ -294,26 +298,27 @@ struct DJI_MAG { // byte offset from beginning of packet, subtract 5 for struct BYTE 17-18 (CS): checksum, calculated the same way as for uBlox binary messages */ -struct DJI_VER { // byte offset from beginning of packet, subtract 5 for struct offset +struct DjiVer { // byte offset from beginning of packet, subtract 5 for struct offset uint32_t unused1; // BYTE 5-8" ??? (seems to be always 0) uint32_t swVersion; // BYTE 9-12 (FW): firmware version uint32_t hwVersion; // BYTE 13-16 (HW): hardware id } __attribute__((packed)); +#define VER_FIRST_DECODED_BYTE offsetof(struct DjiVer, swVersion) typedef union { uint8_t payload[0]; // Nav Class - struct DJI_GPS gps; - struct DJI_MAG mag; - struct DJI_VER ver; + struct DjiGps gps; + struct DjiMag mag; + struct DjiVer ver; } DJIPayload; struct DJIHeader { uint8_t id; uint8_t len; - uint8_t ck_a; // these are not part of the dji header, they are actually in the trailer - uint8_t ck_b; // but they are kept here for parsing ease + uint8_t checksumA; // these are not part of the dji header, they are actually in the trailer + uint8_t checksumB; // but they are kept here for parsing ease } __attribute__((packed)); struct DJIPacket { @@ -321,12 +326,7 @@ struct DJIPacket { DJIPayload payload; } __attribute__((packed)); -extern GPSPositionSensorSensorTypeOptions sensorType; - -bool checksum_dji_message(struct DJIPacket *); -uint32_t parse_dji_message(struct DJIPacket *, GPSPositionSensorData *); - -int parse_dji_stream(uint8_t *rx, uint16_t len, char *, GPSPositionSensorData *, struct GPS_RX_STATS *); +int parse_dji_stream(uint8_t *inputBuffer, uint16_t inputBufferLength, char *parsedDjiStruct, GPSPositionSensorData *GpsData, struct GPS_RX_STATS *GpsRxStats); void dji_load_mag_settings(); #endif /* DJI_H */ diff --git a/flight/modules/GPS/inc/UBX.h b/flight/modules/GPS/inc/UBX.h index 96ae75ab8..b7d92b3fa 100644 --- a/flight/modules/GPS/inc/UBX.h +++ b/flight/modules/GPS/inc/UBX.h @@ -613,7 +613,7 @@ union UBXSENTPACKET { // Used by AutoConfig code extern int32_t ubxHwVersion; -extern GPSPositionSensorSensorTypeOptions sensorType; +extern GPSPositionSensorSensorTypeOptions ubxSensorType; extern struct UBX_ACK_ACK ubxLastAck; extern struct UBX_ACK_NAK ubxLastNak; diff --git a/flight/modules/GPS/ubx_autoconfig.c b/flight/modules/GPS/ubx_autoconfig.c index 0fb8fc732..14db54527 100644 --- a/flight/modules/GPS/ubx_autoconfig.c +++ b/flight/modules/GPS/ubx_autoconfig.c @@ -239,10 +239,10 @@ void gps_ubx_reset_sensor_type() // is this needed? // what happens if two tasks / threads try to do an XyzSet() at the same time? if (__sync_fetch_and_add(&mutex, 1) == 0) { - ubxHwVersion = -1; + ubxHwVersion = -1; baud_to_try_index -= 1; // undo postincrement and start with the one that was most recently successful - sensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; - GPSPositionSensorSensorTypeSet(&sensorType); + ubxSensorType = GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN; + GPSPositionSensorSensorTypeSet(&ubxSensorType); // make the sensor type / autobaud code time out immediately to send the request immediately status->lastStepTimestampRaw += 0x8000000UL; } diff --git a/flight/modules/Sensors/sensors.c b/flight/modules/Sensors/sensors.c index a85608e5f..c13b96e5f 100644 --- a/flight/modules/Sensors/sensors.c +++ b/flight/modules/Sensors/sensors.c @@ -195,7 +195,7 @@ static uint8_t baro_temp_calibration_count = 0; #if defined(PIOS_INCLUDE_HMC5X83) // Allow AuxMag to be disabled without reboot // because the other mags are that way -static bool useMag = false; +static bool useAuxMag = false; #endif /** @@ -497,7 +497,7 @@ static void handleMag(float *samples, float temperature) #if defined(PIOS_INCLUDE_HMC5X83) static void handleAuxMag(float *samples) { - if (useMag) { + if (useAuxMag) { auxmagsupport_publish_samples(samples, AUXMAGSENSOR_STATUS_OK); } } @@ -639,9 +639,9 @@ void aux_hmc5x83_load_mag_settings() uint8_t magType = auxmagsupport_get_type(); if (magType == AUXMAGSETTINGS_TYPE_I2C || magType == AUXMAGSETTINGS_TYPE_FLEXI) { - useMag = true; + useAuxMag = true; } else { - useMag = false; + useAuxMag = false; } } #endif diff --git a/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h b/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h index 5138b10d9..47388c988 100644 --- a/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h +++ b/flight/targets/boards/discoveryf4bare/firmware/inc/pios_config.h @@ -6,6 +6,7 @@ * @{ * @file pios_config.h * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. + * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013. * @brief PiOS configuration header, the compile time config file for the PIOS. * Defines which PiOS libraries and features are included in the firmware. * @see The GNU Public License (GPL) Version 3