?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{FILE START}

library

?curdirlinks? - Rev 6

?prevdifflink? - Blame - ?getfile?

/*! \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 <avr/io.h>
        #include <avr/pgmspace.h>
        #include <string.h>
        #include <stdlib.h>
#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; i<dataLength; i++)
        {
                checksum ^= MitelGpsPacket[dataIdx];
                MitelGpsPacket[dataIdx++] = *data++;
        }
        // checksum
        convertIntToAsciiHex(checksum, &MitelGpsPacket[dataIdx], 2);
        dataIdx += 2;
        // end of packet
        MitelGpsPacket[dataIdx++] = ETX;

        // send it
        for(i=0; i<dataIdx; i++)
                TxByteFunc(MitelGpsPacket[i]);
}

u08 mitelgpsProcess(cBuffer* rxBuffer)
{
        u08 foundpacket = FALSE;
        u08 startFlag = FALSE;
        u08 checksum = 0;
        u08 packetType;
        u16 i,j;

        // process the receive buffer
        // go through buffer looking for packets
        while(rxBuffer->datalength > 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<numdigits; i++)
        {
                // shift number up
                num = num<<4;
                // decode hex digit
                if(string[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<numdigits; i++)
        {
                if((num & 0x0000000F) < 10)
                        string[numdigits-1-i] = (num & 0x0000000F)+'0';
                else
                        string[numdigits-1-i] = (num & 0x0000000F)+'A'-10;
                // next digit
                num = num>>4;
        }
}
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3