An implementation of the Sirf Binary and NMEA Protocol for gps devices using the SiRFstarIII chipset
Revision 0:43da35949666, committed 2012-06-28
- Comitter:
- p3p
- Date:
- Thu Jun 28 21:17:29 2012 +0000
- Commit message:
- update to baud selection
Changed in this revision
diff -r 000000000000 -r 43da35949666 BinaryPackets.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BinaryPackets.h Thu Jun 28 21:17:29 2012 +0000 @@ -0,0 +1,268 @@ +#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 \ No newline at end of file
diff -r 000000000000 -r 43da35949666 GpsInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GpsInterface.cpp Thu Jun 28 21:17:29 2012 +0000 @@ -0,0 +1,88 @@ +#include "GpsInterface.h" + +namespace SirfStarIII { + +GpsInterface::GpsInterface(PinName tx, PinName rx) : SirfStarIII(tx, rx) { + receiveCallback(BinaryPacket::ID_GeodeticNavigationData, this, &GpsInterface::onReceiveGeodeticNavigationData); + receiveCallback(BinaryPacket::ID_MeasuredTrackingData, this, &GpsInterface::onReceiveMeasuredTrackingData); + receiveCallback(BinaryPacket::ID_DGPSStatus, this, &GpsInterface::onReceiveDGPSStatus); + receiveCallback(NMEAPacket::ID_RMC, this, &GpsInterface::onReceiveRMC); +} + +void GpsInterface::onReceiveGeodeticNavigationData(SimpleSerialProtocol::Packet* packet) { + if(!packet)return; + + if (packet->_valid) { + BinaryPacket::GeodeticNavigationData::Interface* interface = packet->interpretData<BinaryPacket::GeodeticNavigationData::Interface>(); + if (interface) { + BinaryPacket::GeodeticNavigationData::swapByteOrder(interface); + _fix.sats = interface->satalites_in_fix; + _position.longitude = (((float)interface->longitude)/10000000); + _position.latitude = (((float)interface->latitude)/10000000); + + _time.year = interface->year; + _time.month = interface->month; + _time.day = interface->day; + _time.hours = interface->hour; + _time.minutes = interface->minute; + _time.seconds = interface->second/1000; + } + } + return; +} + +void GpsInterface::onReceiveMeasuredTrackingData(SimpleSerialProtocol::Packet* packet) { + if(!packet)return; + + if (packet->_valid) { + BinaryPacket::MeasuredTrackingData::Interface* interface = packet->interpretData<BinaryPacket::MeasuredTrackingData::Interface>(); + if (interface) { + + } + } + return; +} + +void GpsInterface::onReceiveDGPSStatus(SimpleSerialProtocol::Packet* packet) { + if(!packet)return; + + if (packet->_valid) { + BinaryPacket::DGPSStatus::Interface* interface = packet->interpretData<BinaryPacket::DGPSStatus::Interface>(); + if (interface) { + + } + } + return; +} + +void GpsInterface::onReceiveRMC(SimpleSerialProtocol::Packet* packet) { + if(!packet)return; + + NMEAPacket::NMEAPacket nmeaPacket; + if (packet->_valid) { + nmeaPacket.interpretData(packet); + float time = atof(nmeaPacket._fields[1].c_str()); + _time.seconds = (int)time % 100; + _time.minutes = (int)(time / 100)%100; + _time.hours = (int)(time / 10000); + + // 2 Time Status + _position.latitude.set(atof(nmeaPacket._fields[3].c_str()), (char)nmeaPacket._fields[4].c_str()[0]); + _position.longitude.set(atof(nmeaPacket._fields[5].c_str()), (char)nmeaPacket._fields[6].c_str()[0]); + _position.speed = atof(nmeaPacket._fields[7].c_str()); + _position.course = atof(nmeaPacket._fields[8].c_str()); + + uint32_t date = atoi(nmeaPacket._fields[9].c_str()); + _time.year = 2000 + (date % 100); + date /= 100; + _time.month = date % 100; + _time.day = date / 100; + + // 10 magnetic variation + // 11 mode + } + + return; +} + +} \ No newline at end of file
diff -r 000000000000 -r 43da35949666 GpsInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GpsInterface.h Thu Jun 28 21:17:29 2012 +0000 @@ -0,0 +1,95 @@ +#ifndef SIRF_PROTOCOL_GPS_INTERFACE +#define SIRF_PROTOCOL_GPS_INTERFACE + +#include "sIRFstarIII.h" + +namespace SirfStarIII { + +class GpsInterface : public SirfStarIII { +public: + GpsInterface(PinName tx, PinName rx); + virtual ~GpsInterface() {} + + void onReceiveGeodeticNavigationData(SimpleSerialProtocol::Packet* packet); + void onReceiveMeasuredTrackingData(SimpleSerialProtocol::Packet* packet); + void onReceiveDGPSStatus(SimpleSerialProtocol::Packet* packet); + void onReceiveRMC(SimpleSerialProtocol::Packet* packet); + + class Coordinate { + public: + Coordinate() { + _gps_format = 0; + _dec_degrees = 0; + _degrees = 0; + _minutes = 0; + _seconds = 0; + } + ~Coordinate() {} + float _gps_format; + char _indicator; + float _dec_degrees; + uint16_t _degrees; + uint16_t _minutes; + float _seconds; + + void set(float raw, char indicator) { + if(indicator == '0')return; + if (raw < 10000) { + raw = raw / 100; + } else { + raw = raw / 1000; + } + _gps_format = raw; + _degrees = static_cast<uint16_t>(raw); + raw = (raw - _degrees)*100; + _minutes = static_cast<uint16_t>(raw); + _seconds = 60 * (raw - _minutes); + _dec_degrees = _degrees + (float)((float)_minutes/60) + (float)(_seconds/3600); + _indicator = indicator; + if(indicator == 'S' || indicator == 'W') _dec_degrees *= -1; + } + + void operator= (float param) { + _dec_degrees = param; + } + + }; + + struct FixData { + enum Type { + NoFix, + Fixed, + DifFix, + Reserved1, + Reserved2, + Reserved3, + DeadReckFix + }; + uint8_t valid; + uint8_t fix_type; + uint8_t sats; + } _fix; + + struct Position { + Coordinate longitude; + Coordinate latitude; + float altitude; + float speed; + float course; + uint8_t fix_type; + } _position; + + struct Time { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; + } _time; + +}; + +} + +#endif \ No newline at end of file
diff -r 000000000000 -r 43da35949666 NmeaPackets.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NmeaPackets.h Thu Jun 28 21:17:29 2012 +0000 @@ -0,0 +1,52 @@ +#ifndef SIRF_PROTOCOL_NMEA_PACKETS +#define SIRF_PROTOCOL_NMEA_PACKETS + +#include <string> +#include <vector> +#include <map> + +namespace SirfStarIII { + +namespace NMEAPacket { + +enum PacketNames{ + ID_GGA, //Time, position and fix type data. + ID_GLL, //Latitude, longitude, UTC time of position fix and status. + ID_GSA, //GPS receiver operating mode, satellites used in the position solution, and DOP values. + ID_GSV, //The number of GPS satellites in view satellite ID numbers, elevation, azimuth, and SNR values. + ID_MSS, //Signal-to-noise ratio, signal strength, frequency, and bit rate from a radio-beacon receiver. + ID_RMC, //Time, date, position, course and speed data. + ID_VTG, //Course and speed information relative to the ground. + ID_ZDA, //PPS timing message (synchronized to PPS). + ID_150 //OK to send message. +}; + +class NMEAPacket { +public: + NMEAPacket() {} + virtual ~NMEAPacket() {} + + std::vector<std::string> _fields; + + void interpretData(SimpleSerialProtocol::Packet* packet) { + std::string raw_data( (char *) packet->_data); + std::string temp; + while (raw_data.find(",", 0) != std::string::npos) { + size_t pos = raw_data.find(",", 0); + temp = raw_data.substr(0, pos); + raw_data.erase(0, pos + 1); + if (temp.size() == 0) { + temp = "0"; + } + _fields.push_back(temp); + } + _fields.push_back(raw_data); + } + +}; + +} + +} + +#endif \ No newline at end of file
diff -r 000000000000 -r 43da35949666 sIRFstarIII.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sIRFstarIII.cpp Thu Jun 28 21:17:29 2012 +0000 @@ -0,0 +1,373 @@ +#include "sIRFstarIII.h" + +extern Serial debug; + +namespace SirfStarIII { + +SirfStarIII::SirfStarIII(PinName tx, PinName rx) : SimpleSerialProtocol::Protocol(tx, rx, LED1) { + _mode = BINARY; +} + +SirfStarIII::~SirfStarIII() { + +} + +void SirfStarIII::initialise() { + //find the device + selectMode(_mode, 57600, true); + _receive_timeout.start(); +} + +void SirfStarIII::initialise(ProtocolMode mode, uint32_t baud_rate) { + selectMode(mode, baud_rate, true); + _receive_timeout.start(); +} + +void SirfStarIII::receive() { + if (_mode == BINARY) { + receiveBinary(); + } else if (_mode == NMEA) { + receiveNMEA(); + } +} + +void SirfStarIII::sendPacket(SimpleSerialProtocol::Packet* packet) { + if (_mode == BINARY) { + sendBinaryPacket(packet); + } else if (_mode == NMEA) { + sendNMEAPacket(packet); + } +} + +void SirfStarIII::receiveBinary() { + uint8_t new_byte = 0; + uint16_t cs = 0; + _receive_timeout.reset(); + while ( MODSERIAL::rxBufferGetCount() > 0 && _receive_timeout.read_us() < 50 ) { + switch (_state) { + case PACKET_START: + new_byte = MODSERIAL::getc(); + if (_last_byte == 0xA0 && new_byte == 0xA2) { + _state = HEADER_RECEIVE; + } + _last_byte = new_byte; + break; + + case HEADER_RECEIVE: + _header[_header_read++] = MODSERIAL::getc(); + if (_header_read == 2) { + _state = HEADER_DECODE; + } + break; + + case HEADER_DECODE: + _packet._size = *(uint16_t*) _header; + _packet._size = _packet.swapEndian(_packet._size); + if (_packet._size < 512) { + _state = DATA_RECEIVE; + } else { + _state = PACKET_RESET; + } + break; + + case DATA_RECEIVE: + if (_data_read < _packet._size) { + _packet._data[_data_read++] = MODSERIAL::getc(); + if (_data_read == _packet._size) { + _state = FOOTER_RECEIVE; + } + } + break; + + case FOOTER_RECEIVE: + if (_footer_read < 4) { + _footer[_footer_read++] = MODSERIAL::getc(); + } else { + _state = DATA_VALIDATE; + } + break; + + case DATA_VALIDATE: + if (_footer[2] == 0xB0 && _footer[3] == 0xB3) { + + _packet._checksum = *(uint16_t*) _footer; + _packet._checksum = _packet.swapEndian(_packet._checksum); + + cs = checksumBinary(_packet._data, _packet._size); + + if (cs == _packet._checksum) { + _packet._type = _packet._data[0]; + _state = PACKET_VALID; + _packet._valid = true; + } else { + _state = PACKET_RESET; + } + } else { + _state = PACKET_RESET; + } + break; + + case PACKET_VALID: + if (!_packet._valid) { + _state = PACKET_RESET; + } else { + return; + } + return; + + default: + _state = PACKET_START; + _header_read = 0; + _data_read = 0; + _footer_read = 0; + break; + } + } +} + +void SirfStarIII::sendBinaryPacket(SimpleSerialProtocol::Packet* packet) { + if (packet!=0) { + send(0xA0); + send(0xA2); + + //size (reversed 2 byte value) + uint8_t* size_array = reinterpret_cast<uint8_t *>(&packet->_size); + send( size_array[1] ); + send( size_array[0] ); + + //packet data + for (int i = 0; i < packet->_size; i++) { + send(packet->_data[i]); + } + + //checksum (reversed 2 byte value) + uint16_t check_value = checksumBinary(packet->_data, packet->_size); + uint8_t* check_array = reinterpret_cast<uint8_t *>( &check_value ); + send( check_array[1] ); + send( check_array[0] ); + + //end bytes + send(0xB0); + send(0xB3); + + } +} + +uint16_t SirfStarIII::checksumBinary(uint8_t* packet, uint16_t packet_size) { + uint16_t cs = 0; + for (int i = 0; i < packet_size; i++) { + cs += packet[i]; + cs &= 32767; + } + return cs; +} + +void SirfStarIII::receiveNMEA() { + uint8_t new_byte = 0; + uint16_t cs = 0; + char checksum_array[2]; + + _receive_timeout.reset(); + while (MODSERIAL::rxBufferGetCount() > 0 && _receive_timeout.read_us() < 50) { + + switch (_state) { + case PACKET_START: + new_byte = MODSERIAL::getc(); + if (new_byte == '$') { + _state = DATA_RECEIVE; + } + break; + + case DATA_RECEIVE: + new_byte = MODSERIAL::getc(); + if (new_byte != '\r') { + _packet._data[_data_read++] = new_byte; + } else { + _packet._size = _data_read - 3; //checksum is last 3 bytes + _state = FOOTER_RECEIVE; + } + break; + + case FOOTER_RECEIVE: + //discard '\n" + new_byte = MODSERIAL::getc(); + _state = DATA_VALIDATE; + break; + + case DATA_VALIDATE: + _packet._data[_packet._size] = 0; + checksum_array[0] = _packet._data[_packet._size + 1]; + checksum_array[1] = _packet._data[_packet._size + 2]; + cs = (uint16_t)strtoul(checksum_array, 0, 16); + + if (cs == checksumNMEA((const char *)_packet._data)) { + _state = PACKET_VALID; + _packet._valid = true; + std::string raw_data( (char *) _packet._data); + size_t pos = raw_data.find(",", 0); + std::string temp = raw_data.substr(0, pos); + + if (!temp.compare("GPGGA")) { + _packet._type = NMEAPacket::ID_GGA; + } else if (!temp.compare("GPGLL")) { + _packet._type = NMEAPacket::ID_GLL; + } else if (!temp.compare("GPGSA")) { + _packet._type = NMEAPacket::ID_GSA; + } else if (!temp.compare("GPGSV")) { + _packet._type = NMEAPacket::ID_GSV; + } else if (!temp.compare("GPMSS")) { + _packet._type = NMEAPacket::ID_MSS; + } else if (!temp.compare("GPRMC")) { + _packet._type = NMEAPacket::ID_RMC; + } else if (!temp.compare("GPVTG")) { + _packet._type = NMEAPacket::ID_VTG; + } else if (!temp.compare("GPZDA")) { + _packet._type = NMEAPacket::ID_ZDA; + } else if (!temp.compare("PSRF150")) { + _packet._type = NMEAPacket::ID_150; + } else { + _packet._type = 255; + } + } else { + _state = PACKET_RESET; + } + break; + + case PACKET_VALID: + if (!_packet._valid) { + _state = PACKET_RESET; + } else { + return; + } + + default: + _state = PACKET_START; + _data_read = 0; + break; + } + } +} + +void SirfStarIII::sendNMEAPacket(SimpleSerialProtocol::Packet* packet) { + +} + +uint8_t SirfStarIII::checksumNMEA(const char * command) { + uint8_t i = 1; + uint8_t command_checksum = command[0]; + while (command[i] != 0) { + command_checksum = command_checksum ^ command[i]; + i++; + } + return command_checksum; +} + +void SirfStarIII::selectMode(ProtocolMode mode, uint32_t baud_rate, bool find_baud) { + int default_baud_rate[6]; + default_baud_rate[0] = 4800; + default_baud_rate[1] = 9600; + default_baud_rate[2] = 14400; + default_baud_rate[3] = 19200; + default_baud_rate[4] = 38400; + default_baud_rate[5] = 57600; + + _mode = mode; +/* + if (find_baud) { + char command[] = "PSRF100,0,%d,8,1,0\0"; + char buffer[sizeof(command) + 10]; + snprintf(buffer, sizeof(buffer), command, baud_rate ); + + uint8_t c_checksum = checksumNMEA(buffer); + //send NMEA command at all baud rates to switch to BINARY @ 57600 + for (int i = 0; i < 6; ++i) { + Protocol::baud(default_baud_rate[i]); + wait_ms(100); + Protocol::printf("$%s*%02X\r\n", buffer, c_checksum); + blockUntilTxEmpty(); + } + + //send Binary command at all baud rates to switch to 57600 + for (int i = 0; i < 6; ++i) { + Protocol::baud(default_baud_rate[i]); + wait_ms(100); + BinaryPacket::SetBinarySerialPort binary_config(baud_rate); + binary_config.buildData<BinaryPacket::SetBinarySerialPort::Interface>(&binary_config.interface); + sendBinaryPacket(&binary_config); + blockUntilTxEmpty(); + + BinaryPacket::ConfigureNMEA nmea_config(baud_rate); + nmea_config.buildData<BinaryPacket::ConfigureNMEA::Interface>(&nmea_config.interface); + sendBinaryPacket(&nmea_config); + blockUntilTxEmpty(); + } + + //should be binary @ baud now + } + wait_ms(50); + */ + if (mode == BINARY) { + baud(4800); + wait_ms(100); + //Build the NMEA packet + char command[] = "PSRF100,0,%d,8,1,0\0"; + char buffer[sizeof(command) + 10]; + snprintf(buffer, sizeof(buffer), command, baud_rate ); + uint8_t c_checksum = checksumNMEA(buffer); + Serial::printf("$%s*%02X\r\n", buffer, c_checksum); + wait_ms(10); + Serial::printf("$%s*%02X\r\n", buffer, c_checksum); + wait_ms(10); + Serial::printf("$%s*%02X\r\n", buffer, c_checksum); + wait_ms(10); + Serial::printf("$%s*%02X\r\n", buffer, c_checksum); + wait_ms(10); + Serial::printf("$%s*%02X\r\n", buffer, c_checksum); + wait_ms(10); + Serial::printf("$%s*%02X\r\n", buffer, c_checksum); + blockUntilTxEmpty(); + } +/* + if (mode == NMEA) { + Protocol::baud(4800); + + NMEAChangeBaud(baud_rate); + wait_ms(10); + + BinaryPacket::ConfigureNMEA nmea_config(baud_rate); + nmea_config.buildData<BinaryPacket::ConfigureNMEA::Interface>(&nmea_config.interface); + sendBinaryPacket(&nmea_config); + + BinaryPacket::SetProtocol protocol_select(2); + protocol_select.buildData<BinaryPacket::SetProtocol::Interface>(&protocol_select.interface); + sendBinaryPacket(&protocol_select); + + BinaryPacket::SetBinarySerialPort binary_config(baud_rate); + binary_config.buildData<BinaryPacket::SetBinarySerialPort::Interface>(&binary_config.interface); + sendBinaryPacket(&binary_config); + + blockUntilTxEmpty();*/ + baud(baud_rate); + // } +} + +void SirfStarIII::NMEAChangeBaud(uint32_t baud_rate){ + //Build the NMEA packet + char command[] = "PSRF100,1,%d,8,1,0"; + char buffer[sizeof(command) + 10]; + snprintf(buffer, sizeof(buffer), command, baud_rate ); + uint8_t c_checksum = checksumNMEA(buffer); + + Protocol::printf("$%s*%02X\r\n", buffer, c_checksum); + baud(9600); +} + +void SirfStarIII::BinaryChangeBaud(uint32_t baud_rate){ + BinaryPacket::SetBinarySerialPort binary_config(baud_rate); + binary_config.buildData<BinaryPacket::SetBinarySerialPort::Interface>(&binary_config.interface); + sendBinaryPacket(&binary_config); + blockUntilTxEmpty(); + baud(baud_rate); +} + +} \ No newline at end of file
diff -r 000000000000 -r 43da35949666 sIRFstarIII.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sIRFstarIII.h Thu Jun 28 21:17:29 2012 +0000 @@ -0,0 +1,46 @@ +#ifndef SIRF_PROTOCOL +#define SIRF_PROTOCOL + +#include "mbed.h" +#include "MODSERIAL.h" +#include "Protocol.h" +#include "BinaryPackets.h" +#include "NmeaPackets.h" + +namespace SirfStarIII { + +enum ProtocolMode { + BINARY, + NMEA +}; + +class SirfStarIII : public SimpleSerialProtocol::Protocol { +public: + SirfStarIII(PinName tx, PinName rx); + virtual ~SirfStarIII(); + + virtual void initialise(); + virtual void initialise(ProtocolMode mode, uint32_t baud_rate); + virtual void receive(); + virtual void sendPacket(SimpleSerialProtocol::Packet* packet); + + void receiveBinary(); + uint16_t checksumBinary(uint8_t* packet, uint16_t packet_size); + void sendBinaryPacket(SimpleSerialProtocol::Packet* packet); + + void receiveNMEA(); + uint8_t checksumNMEA(const char * command); + void sendNMEAPacket(SimpleSerialProtocol::Packet* packet); + + void selectMode(ProtocolMode mode, uint32_t baud, bool find_baud = false); + void selectBaud(uint32_t baud); + + void NMEAChangeBaud(uint32_t baud_rate); + void BinaryChangeBaud(uint32_t baud_rate); + + ProtocolMode _mode; +}; + +} + +#endif \ No newline at end of file