An implementation of the Sirf Binary and NMEA Protocol for gps devices using the SiRFstarIII chipset

BinaryPackets.h

Committer:
p3p
Date:
2012-06-28
Revision:
0:43da35949666

File content as of revision 0:43da35949666:

#ifndef SIRF_PROTOCOL_BINARY_PACKETS
#define SIRF_PROTOCOL_BINARY_PACKETS

namespace SirfStarIII {

namespace BinaryPacket {

enum PacketNames {
    //inbound
    ID_MeasuredTrackingData = 4,
    ID_DGPSStatus = 27,
    ID_GeodeticNavigationData = 41,
    //outbound
    ID_ConfigureNMEA = 129,
    ID_SetBinarySerialPort = 134,
    ID_SetProtocol = 135
};

class SetProtocol : public SimpleSerialProtocol::Packet {
public:
    SetProtocol(uint8_t _protocol) {
        interface.protocol = _protocol;
    }

#pragma pack(push, 1)
    struct Interface {
        Interface() {
            message_id = ID_SetProtocol;
        }
        uint8_t message_id;
        uint8_t protocol;
    } interface;
#pragma pack(pop)

};

class SetBinarySerialPort :  public SimpleSerialProtocol::Packet {
public:
    SetBinarySerialPort(uint32_t _bitrate) {
        interface.bitrate = swapEndian(_bitrate);
    }
#pragma pack(push, 1)
    struct Interface {
        Interface() {
            message_id = ID_SetBinarySerialPort;
            data_bits = 8;
            stop_bit = 1;
            parity = 0;
        }
        uint8_t message_id;
        uint32_t bitrate;
        uint8_t data_bits;
        uint8_t stop_bit;
        uint8_t parity;
        uint8_t padding;
    } interface;
#pragma pack(pop)
};

class ConfigureNMEA :  public SimpleSerialProtocol::Packet {
public:
    ConfigureNMEA(uint16_t _bitrate) {
        interface.bitrate = swapEndian(_bitrate);;
    }

#pragma pack(push, 1)
    struct Interface {
        Interface() {
            message_id = ID_ConfigureNMEA;
            mode = 2;
            gga_message = 0;
            gga_checksum = 1;
            gll_message = 0;
            gll_checksum = 1;
            gsa_message = 0;
            gsa_checksum = 1;
            gsv_message = 0;
            gsv_checksum = 1;
            rmc_message = 1;
            rmc_checksum = 1;
            vtg_message = 0;
            vtg_checksum = 1;
            mss_message = 0;
            mss_checksum = 1;
            epe_message = 0;
            epe_checksum = 0;
            zda_message = 0;
            zda_checksum = 1;
            padding = 0;
        }
        uint8_t message_id;
        uint8_t mode;
        uint8_t gga_message;
        uint8_t gga_checksum;
        uint8_t gll_message;
        uint8_t gll_checksum;
        uint8_t gsa_message;
        uint8_t gsa_checksum;
        uint8_t gsv_message;
        uint8_t gsv_checksum;
        uint8_t rmc_message;
        uint8_t rmc_checksum;
        uint8_t vtg_message;
        uint8_t vtg_checksum;
        uint8_t mss_message;
        uint8_t mss_checksum;
        uint8_t epe_message;
        uint8_t epe_checksum;
        uint8_t zda_message;
        uint8_t zda_checksum;
        uint16_t padding;
        uint16_t bitrate;
    } interface;
#pragma pack(pop)

};

class MeasuredTrackingData : public SimpleSerialProtocol::Packet {
public:
    MeasuredTrackingData() {}

#pragma pack(push, 1)
    struct Interface {
        uint8_t message_id;
        int16_t gps_week;
        uint32_t gps_time_of_week;
        uint8_t channels;
        struct {
            uint8_t svid;
            uint8_t azimuth;
            uint8_t elevation;
            uint16_t state;
            uint8_t c_no_1;
            uint8_t c_no_2;
            uint8_t c_no_3;
            uint8_t c_no_4;
            uint8_t c_no_5;
            uint8_t c_no_6;
            uint8_t c_no_7;
            uint8_t c_no_8;
            uint8_t c_no_9;
            uint8_t c_no_10;
        } channel_data[12];
    };
#pragma pack(pop)

    static void swapByteOrder(Interface* interface) {
        interface->gps_week = swapEndian(interface->gps_week);
        interface->gps_time_of_week = swapEndian(interface->gps_time_of_week);
        for (int i = 0; i < 12; i++) {
            interface->channel_data[i].state = swapEndian(interface->channel_data[i].state);
        }
    }
};

class DGPSStatus : public SimpleSerialProtocol::Packet {
public:
#pragma pack(push, 1)
    struct Interface {
        uint8_t message_id;
        uint8_t dgps_source;
        union {
            struct {
                int32_t beacon_frequency;
                uint8_t beacon_bitrate;
                uint8_t status;
                int32_t signal_magnitude;
                int16_t signal_strength;
                int16_t signal_noise_ratio;
            };
            struct {
                uint8_t correction_age[12];
                uint16_t reserved;
            };
        };
        struct {
            uint8_t satalite_prn_code;
            int16_t dgps_correction;
        } satalite_corrections[12];
    };
#pragma pack(pop)

    static void swapByteOrder(Interface* interface) {
        for (int i = 0; i < 12; i++) {
            interface->satalite_corrections[i].dgps_correction = swapEndian(interface->satalite_corrections[i].dgps_correction);
        }
    }
};

class GeodeticNavigationData : public SimpleSerialProtocol::Packet {
public:
#pragma pack(push, 1)
    struct Interface {
        uint8_t message_id;
        uint16_t nav_valid;
        uint16_t nav_type;
        uint16_t week_number;
        uint32_t time_of_week;
        uint16_t year;
        uint8_t month;
        uint8_t day;
        uint8_t hour;
        uint8_t minute;
        uint16_t second;
        uint32_t satalite_id_list;
        int32_t latitude;
        int32_t longitude;
        int32_t altitude_elipsoid;
        int32_t altitude_MSL;
        int8_t map_datum;
        uint16_t speed_over_ground;
        uint16_t course_over_ground;
        int16_t magnetic_variation;
        int16_t climb_rate;
        int16_t heading_rate;
        uint32_t est_h_position_error;
        uint32_t est_v_position_error;
        uint32_t est_time_error;
        uint16_t est_h_velocity_error;
        int32_t clock_bias;
        uint32_t clock_bias_error;
        int32_t clock_drift;
        uint32_t clock_drift_error;
        uint32_t distance;
        uint16_t distance_error;
        uint16_t heading_error;
        uint8_t satalites_in_fix;
        uint8_t horizontal_dilution_of_presision;
        uint8_t additional_mode_info;
    };
#pragma pack(pop)

    static void swapByteOrder(Interface* interface) {
        interface->nav_valid = swapEndian(interface->nav_valid);
        interface->nav_type = swapEndian(interface->nav_type);
        interface->week_number = swapEndian(interface->week_number);
        interface->time_of_week = swapEndian(interface->time_of_week);
        interface->year = swapEndian(interface->year);
        interface->second = swapEndian(interface->second);
        interface->satalite_id_list = swapEndian(interface->satalite_id_list);
        interface->latitude = swapEndian(interface->latitude);
        interface->longitude = swapEndian(interface->longitude);
        interface->altitude_elipsoid = swapEndian(interface->altitude_elipsoid);
        interface->altitude_MSL = swapEndian(interface->altitude_MSL);
        interface->speed_over_ground = swapEndian(interface->speed_over_ground);
        interface->course_over_ground = swapEndian(interface->course_over_ground);
        interface->magnetic_variation = swapEndian(interface->magnetic_variation);
        interface->climb_rate = swapEndian(interface->climb_rate);
        interface->heading_rate = swapEndian(interface->heading_rate);
        interface->est_h_position_error = swapEndian(interface->est_h_position_error);
        interface->est_v_position_error = swapEndian(interface->est_v_position_error);
        interface->est_time_error = swapEndian(interface->est_time_error);
        interface->est_h_velocity_error = swapEndian(interface->est_h_velocity_error);
        interface->clock_bias = swapEndian(interface->clock_bias);
        interface->clock_bias_error = swapEndian(interface->clock_bias_error);
        interface->clock_drift = swapEndian(interface->clock_drift);
        interface->clock_drift_error = swapEndian(interface->clock_drift_error);
        interface->distance = swapEndian(interface->distance);
        interface->distance_error = swapEndian(interface->distance_error);
        interface->heading_error = swapEndian(interface->heading_error);
    }
};

}

}

#endif