/*! \file .c \brief Mitel GPS STX/ETX driver function library. */ //***************************************************************************** // // File Name : 'mitelgps.c' // Title : Mitel GPS STX/ETX driver function library // Author : Pascal Stang - Copyright (C) 2002 // Created : 2003.04.11 // Revised : 2003.08.26 // Version : 0.1 // Target MCU : Atmel AVR Series // Editor Tabs : 4 // // NOTE: This code is currently below version 1.0, and therefore is considered // to be lacking in some functionality or documentation, or may not be fully // tested. Nonetheless, you can expect most functions to work. // // This code is distributed under the GNU Public License // which can be found at http://www.gnu.org/licenses/gpl.txt // //***************************************************************************** #ifndef WIN32 #include #include #include #include #endif #include "global.h" #include "buffer.h" #include "rprintf.h" #include "uart2.h" #include "gps.h" #include "mitelgps.h" // Program ROM constants // Global variables // external GPS information structure/repository (in gps.h/gps.c) extern GpsInfoType GpsInfo; // packet processing buffer u08 MitelGpsPacket[MITELGPS_BUFFERSIZE]; // debug flag u08 debug; #define MITELGPS_DEBUG_PKTPARSE 0x01 #define MITELGPS_DEBUG_EXTRACT 0x02 // function pointer to single byte output routine static void (*TxByteFunc)(unsigned char c); void mitelgpsInit(void (*txbytefunc)(unsigned char c)) { // set transmit function // (this function will be used for all SendPacket commands) TxByteFunc = txbytefunc; // set debug status debug = 0; } void mitelgpsSendPacket(u08* data, u08 dataLength) { u08 i; u08 dataIdx = 0; u08 checksum = 0; // start of packet MitelGpsPacket[dataIdx++] = STX; // add packet type and packet data for(i=0; idatalength > 1) { // look for a start of Mitel GPS STX/ETX packet if(bufferGetAtIndex(rxBuffer,0) == STX) { // found start startFlag = TRUE; // done looking for start break; } else // not STX, dump character from buffer bufferGetFromFront(rxBuffer); } // if we detected a start, look for end of packet if(startFlag) { for(i=1; i<(rxBuffer->datalength); i++) { // check for end of Mitel GPS STX/ETX packet if(bufferGetAtIndex(rxBuffer,i) == ETX) { // have a packet end // dump initial STX bufferGetFromFront(rxBuffer); // copy data to MitelGpsPacket for(j=0; j<(i-1); j++) { MitelGpsPacket[j] = bufferGetFromFront(rxBuffer); checksum ^= MitelGpsPacket[j]; } // null-terminate copied string MitelGpsPacket[j] = 0; // dump ending ETX bufferGetFromFront(rxBuffer); // verify checksum // undo checksum summing of the checksum itself checksum ^= MitelGpsPacket[j-2]; checksum ^= MitelGpsPacket[j-1]; if( checksum == convertAsciiHexToInt(&MitelGpsPacket[j-2], 2) ) { // found a good packet if(debug & MITELGPS_DEBUG_PKTPARSE) { rprintf("Rx Mitel GPS packet type: %c%c%c len: %d\r\n", MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j); rprintfStr(MitelGpsPacket); rprintfCRLF(); } // done with this processing session foundpacket = TRUE; break; } else { if(debug & MITELGPS_DEBUG_PKTPARSE) { rprintf("Rx Mitel GPS packet type: %c%c%c len: %d Bad Checksum Rcvd: 0x%c%c Calc: 0x%x\r\n", MitelGpsPacket[0], MitelGpsPacket[1], MitelGpsPacket[2], j, MitelGpsPacket[j-2], MitelGpsPacket[j-1], checksum); } } } } } // handle and direct the received packet if(foundpacket) { // switch on the packet type packetType = convertAsciiHexToInt(&MitelGpsPacket[1], 2); switch( packetType ) { case MITELTYPE_NAVDATAGND: mitelgpsProcessNAVDATAGND(MitelGpsPacket); break; case MITELTYPE_CHNLSTATGND: mitelgpsProcessCHNLSTATGND(MitelGpsPacket); break; case MITELTYPE_NAVDATA: mitelgpsProcessNAVDATA(MitelGpsPacket); break; case MITELTYPE_RAWDATA: mitelgpsProcessRAWDATA(MitelGpsPacket); break; case MITELTYPE_CHNLSTAT: mitelgpsProcessCHNLSTAT(MitelGpsPacket); break; case MITELTYPE_RELNAVECEF: break; case MITELTYPE_RELNAVRTN: break; default: if(debug & MITELGPS_DEBUG_PKTPARSE) rprintf("Unhandled Mitel GPS packet type: 0x%x\r\n", packetType); break; } } return foundpacket; } void mitelgpsProcessNAVDATAGND(u08* packet) { // process "F00" report packets - Navigation Data (Ground) char* endptr; if(debug & MITELGPS_DEBUG_EXTRACT) { rprintf("MITELGPS: "); rprintfStr(packet); rprintfCRLF(); } // start parsing just after "F00" // get latitude [sdd.dddddd] GpsInfo.PosLLA.lat.f = strtod(&packet[3], &endptr); // get longitude [sddd.dddddd] GpsInfo.PosLLA.lon.f = strtod(&packet[3+10], &endptr); // get altitude [sxxxxxx.x] GpsInfo.PosLLA.alt.f = strtod(&packet[3+10+11], &endptr); // get speed [sxxx.xx] GpsInfo.VelHS.speed.f = strtod(&packet[3+10+11+9], &endptr); // get heading [ddd] GpsInfo.VelHS.heading.f = strtod(&packet[3+10+11+9+7], &endptr); // get # of SVs tracked [xx] GpsInfo.numSVs = atoi(&packet[3+10+11+9+7+5+7+5+5+5]); } void mitelgpsProcessCHNLSTATGND(u08* packet) { // process "F03" report packets - Channel Status (Ground) } void mitelgpsProcessNAVDATA(u08* packet) { // process "F40" report packets - Navigation Data char* endptr; // start parsing just after "F40" // get gps week number [xxxx]=4 GpsInfo.WeekNum = atoi(&packet[3]); // get gps time of week [xxxxxx.xxxxx]=12 GpsInfo.TimeOfWeek.f = strtod(&packet[3+4], &endptr); // gps-utc time difference? [xx]=2 // get ECEF X [sxxxxxxxx.xx]=12 GpsInfo.PosECEF.x.f = strtod(&packet[3+4+12+2], &endptr); // get ECEF Y [sxxxxxxxx.xx]=12 GpsInfo.PosECEF.y.f = strtod(&packet[3+4+12+2+12], &endptr); // get ECEF Z [sxxxxxxxx.xx]=12 GpsInfo.PosECEF.z.f = strtod(&packet[3+4+12+2+12+12], &endptr); // get ECEF vX [sxxxxxxxx.xx]=12 GpsInfo.VelECEF.x.f = strtod(&packet[3+4+12+2+12+12+12], &endptr); // get ECEF vY [sxxxxxxxx.xx]=12 GpsInfo.VelECEF.y.f = strtod(&packet[3+4+12+2+12+12+12+12], &endptr); // get ECEF vZ [sxxxxxxxx.xx]=12 GpsInfo.VelECEF.z.f = strtod(&packet[3+4+12+2+12+12+12+12+12], &endptr); } void mitelgpsProcessRAWDATA(u08* packet) { // process "F42" report packets - Pseudorange, carrier phase, doppler } void mitelgpsProcessCHNLSTAT(u08* packet) { // process "F43" report packets - Channel Status } // data conversions u32 convertAsciiHexToInt(u08* string, u08 numdigits) { u08 i; u32 num = 0; for(i=0; i= 'a') num |= string[i]-'a'+10; else if(string[i] >= 'A') num |= string[i]-'A'+10; else num |= string[i]-'0'; } return num; } void convertIntToAsciiHex(u32 num, u08* string, u08 numdigits) { u08 i; for(i=0; i>4; } }