Mobil_surveillance_system 1
GPS.c
Go to the documentation of this file.
00001 #include "GPS.h"
00002 
00004 
00011 //*****************************************************************************
00012 //
00013 // Init GPS commands global cont variables
00014 //
00015 //*****************************************************************************
00016 
00017 
00019 const unsigned char g_pcConfigureNmeaMessage[] = {0xA0, 0xA1, 0x00, 0x09, 0x08, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x0D, 0x0A};
00020 
00022 const unsigned char g_pcConfigureMessageType[] = {0xA0, 0xA1, 0x00, 0x03, 0x09, 0x01, 0x00, 0x08, 0x0D, 0x0A};
00023 
00025 const unsigned char g_pcConfigureSystemPowerMode[] = {0xA0, 0xA1, 0x00, 0x03, 0x0C, 0x01, 0x00, 0x0C, 0x0D, 0x0A};
00026 
00028 const unsigned char g_pcConfigureSystemPositionRate[] = {0xA0, 0xA1, 0x00, 0x03, 0x0E, 0x10, 0x00, 0x0F, 0x0D, 0x0A};
00029 
00031 const unsigned char g_pcConfigureSystemRestart[] = {0xA0, 0xA1, 0x00, 0x0F, 0x01, 0x01, 0xD6, 0x07, 0x0C, 0x12, 0x08, 0x32, 0x29, 0xC4, 0x09, 0x70, 0x30, 0x64, 0x00, 0x35, 0x0D, 0x0A};
00032  
00034 const unsigned char g_pcConfigureSerialPort[] = {0xA0, 0xA1, 0x00, 0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x0D, 0x0A};
00035 
00036 
00037 //*****************************************************************************
00038 //
00039 // Globale variables
00040 //
00041 //*****************************************************************************
00042 
00044 tGPS_state g_eGPSstate;
00045 
00047 tGPS_state g_eGPSnextState;
00048 
00050 tDateTime g_GPSdeadline = 0;
00051 
00053 tGPSInfoArray g_GPSInfoArray;
00054 
00056 tDinamicArray g_GPS_CommandQueue;
00057 
00059 tpfGPSHttpPostCallbackFunction g_pfOnCallbackGPRShttpPost = NULL;
00060 
00062 char* g_pcGPSResponseBuffer = NULL;
00063 
00065 char* g_pcGPSResponseBufferEnd = NULL;
00066 
00068 char g_nmeaPacket[PACKET_SIZE] = {'\0'};
00069 
00071 tGPSInfo g_GPSInfoGpsPacket = {'\0'};   
00072 
00074 tBoolean g_GPS_GPGGApart = 0;
00075 
00077 tBoolean g_GPS_GPRMCpart = 0;
00078 
00079 
00080 //*****************************************************************************
00081 //
00082 // Function definations
00083 //
00084 //*****************************************************************************
00085 
00087 void GPS_executeGPS(void)
00089 {
00090     if (g_eGPSstate < GPS_Inizialized){
00091         
00092         GPS_setupGPS();
00093     }   
00094     
00095     else if ( g_eGPSstate == GPS_InitError){
00096         
00097         // lid 2.3 pin led
00098         Ports_setPort2Pin(LED_NUMBER_3);
00099         
00100         _disable_interrupts();
00101         // stop cpu
00102         _bis_SR_register(LPM4_bits);    
00103     }
00104     
00105     else if ( g_eGPSstate == GPS_Inizialized){
00106         
00107         tNMEA_messages test;
00108         // start parsing the nmea sentences
00109         test = GPS_NMEAProcess(g_nmeaPacket);
00110                 
00111         if(test == NMEA_GPGGA){
00112                     
00113             GPS_ProcessGPGGA(g_nmeaPacket, &g_GPSInfoGpsPacket);
00114             g_GPS_GPGGApart = 1;
00115         }
00116                 
00117         else if(test == NMEA_GPRMC){
00118                     
00119             g_GPS_GPRMCpart = 1;
00120         }
00121                 
00122         if(g_GPS_GPGGApart && g_GPS_GPRMCpart){
00123                     
00124             g_GPS_GPGGApart = 0;
00125             g_GPS_GPRMCpart = 0;
00126             // put the received packet into the queue
00127             GPSpacket_pushGPSInfoArray(&g_GPSInfoArray, &g_GPSInfoGpsPacket);
00128             GPS_clearGPSInfoPacket(&g_GPSInfoGpsPacket);
00129             
00130         }
00131         
00132         // if we have any data in the queue make an attempt to post through GPRS
00133         if(g_GPSInfoArray.uiIdx){
00134             
00135             if(g_pfOnCallbackGPRShttpPost){
00136                 
00137                 g_pfOnCallbackGPRShttpPost("host", "3010", "url", (char*)GPSpacket_getGPSInfoArray(&g_GPSInfoArray), sizeof(tGPSInfo) * g_GPSInfoArray.uiCurrentSize);
00138             }
00139             
00148         }
00149         
00150     }
00151 }
00152 
00153 
00155 void GPS_setupGPS(void)
00157 {
00158     // number of reconections   
00159     static unsigned char ucAttempt = ATTEMPT_NUMBER;
00160     
00161     switch(g_eGPSstate){
00162         
00163         case GPS_Uninizialized:
00164             GPS_setState(GPS_SendCommand);
00165         break;
00166         
00167         case GPS_SendCommand:
00168             GPS_sendCommand();
00169             GPS_setState(GPS_CommandSent);
00170         break;
00171         
00172         case GPS_CommandSent:
00173             if(GPS_isCommandSent()){    
00174                 GPS_setState(GPS_StarWaitingForTheAnswer);
00175             }
00176             // do nothing until the command has not been sent completely
00177         break;
00178 
00179         case GPS_StarWaitingForTheAnswer:
00180             GPS_setDeadline(SECOND);
00181             GPS_setState(GPS_WaitingForTheAnswer);
00182         break;
00183     
00184         case GPS_WaitingForTheAnswer:
00185             if(strstr(g_pcGPSResponseBuffer, "ACK")){
00186                 if(GPS_isCommandAvaiable()){
00187                     // reset the number of attempts
00188                     ucAttempt = ATTEMPT_NUMBER;
00189                     GPS_clearResponseBuffer();
00190                     GPS_goToNextCommand();
00191                     GPS_setState(GPS_SendCommand);
00192                 }
00193                 // if all command have already sent
00194                 else{           
00195                     
00196                     GPS_clearResponseBuffer();          
00197                     GPS_setState(GPS_Inizialized);
00198                 }
00199             }
00200             else if(GPS_isDeadlinePassed() || strstr(g_pcGPSResponseBuffer, "NACK")){
00201                 if(--ucAttempt){
00202                     
00203                     GPS_clearResponseBuffer();
00204                     // if at least one more attepmpt is remained sent the current command again
00205                     GPS_setState(GPS_SendCommand);
00206                     
00207                 }
00208                 else{
00209                 
00210                     GPS_setState(GPS_InitError);
00211                 }
00212             }   // else if
00213         break;
00214     }           // switch
00215 }
00216 
00217 
00219 void GPS_setGPShttpPostCallbackFunction(tpfGPSHttpPostCallbackFunction pfCallbackGPRShttpPost)
00221 {
00222     g_pfOnCallbackGPRShttpPost = pfCallbackGPRShttpPost;
00223 }
00224 
00225 
00227 void GPS_initGPS(void)
00229 {
00230     g_pcGPSResponseBuffer = (char*)calloc('\0', sizeof(char)* GPS_RESPONSE_BUFFER_SIZE);
00231     GPS_clearResponseBuffer();
00232     Dinamic_Array_Init(&g_GPS_CommandQueue);
00233     GPS_addCommand(g_pcConfigureSystemRestart);
00234     GPS_addCommand(g_pcConfigureSerialPort);
00235     GPS_addCommand(g_pcConfigureSystemPowerMode);
00236     GPS_addCommand(g_pcConfigureMessageType);
00237     GPS_addCommand(g_pcConfigureSystemPositionRate);
00238     GPS_addCommand(g_pcConfigureNmeaMessage);
00239     // set current state
00240     GPS_setState(GPS_Uninizialized);
00241     GPSpacket_initGPSInfoArray(&g_GPSInfoArray);
00242     // set GPS_appendResponse for UART_read function as a callback function
00243     UART1_setAppendResponseCallbackFunction(&GPS_appendResponse);
00244 }
00245 
00246 
00248 tBoolean GPS_isResponseBufferFull(void)
00250 {
00251     return ((strlen(g_pcGPSResponseBuffer) == (GPS_RESPONSE_BUFFER_SIZE-1)) ? 1: 0);
00252 }
00253 
00254 
00256 void GPS_clearResponseBuffer(void)
00258 {
00259     g_pcGPSResponseBufferEnd = g_pcGPSResponseBuffer;
00260     *g_pcGPSResponseBufferEnd = 0;
00261 }
00262 
00263 
00265 tBoolean GPS_isCommandSent(void)
00267 {
00268     return (UART1_isWritingDone()); 
00269 }
00270 
00271 
00273 void GPS_setDeadline(unsigned int uiDeadline)
00275 {
00276     tDateTime Now;
00277     Time_getCurrentDateTime(&Now);
00278     g_GPSdeadline = Now + uiDeadline; 
00279 }
00280 
00281 
00283 tBoolean GPS_isDeadlinePassed(void)
00285 {
00286     tDateTime Now;
00287     Time_getCurrentDateTime(&Now);
00288     return ((Now > g_GPSdeadline )? 1 : 0);
00289 }
00290 
00291 
00293 void GPS_setState(tGPS_state newState)
00295 {
00296     g_eGPSstate = newState;
00297 }
00298 
00299 
00301 void GPS_setNextState(tGPS_state newState)
00303 {
00304     g_eGPSnextState = newState;
00305 }
00306 
00307 
00309 tGPS_state GPS_getGPSstate(void)
00311 {
00312     return g_eGPSstate;
00313 }
00314 
00315 
00317 void GPS_addCommand(const unsigned char* pcCommand)
00319 {
00320     // TODO kell e mely masolat ?
00321     Dinamic_Array_Add(&g_GPS_CommandQueue, pcCommand);
00322 }
00323 
00324 
00326 void GPS_goToNextCommand(void)
00328 {
00329     Dinamic_Array_Delete(&g_GPS_CommandQueue, 0);   
00330 }
00331 
00332 
00334 tBoolean GPS_isCommandAvaiable(void)
00336 {
00337     return ((g_GPS_CommandQueue.uiSize == 0) ? 1 : 0);
00338 }
00339 
00340 
00342 void GPS_sendCommand(void)
00344 {
00345     if(g_eGPSstate == GPS_SendCommand){
00346         GPS_processCommand();
00347     }
00348 }
00349 
00350 
00352 void GPS_processCommand(void)
00354 {
00355     if(g_GPS_CommandQueue.uiSize){
00356         
00357         char* pcCommand = (char*) g_GPS_CommandQueue.pArray[ 0 ];
00358         UART1_write(pcCommand, strlen(pcCommand));
00359     }
00360 }
00361 
00362 
00364 void GPS_appendResponse(const char* pcResponse)
00366 {
00367     unsigned int uiLength = strlen(pcResponse);
00368     if(uiLength + g_pcGPSResponseBufferEnd < g_pcGPSResponseBuffer + GPS_RESPONSE_BUFFER_SIZE){
00369         
00370         strcat(g_pcGPSResponseBufferEnd, pcResponse);
00371         g_pcGPSResponseBufferEnd += uiLength;
00372     }
00373     
00374     else{
00375         
00376         // buffer is full 
00377     }   
00378 }
00379 
00380 
00381 
00383 tNMEA_messages GPS_NMEAProcess(char* pcNmeaPacket)
00385 {
00386     // clear nmeapacket
00387     memset(pcNmeaPacket, '\0', strlen(pcNmeaPacket));
00388     // no data will send
00389     tNMEA_messages foundpacket = NMEA_NODATA;
00390     tBoolean startFlag = 0;
00391     // if the buffer is empty we don't have to do anything...
00392     if(g_pcGPSResponseBuffer != g_pcGPSResponseBufferEnd){
00393         // pharse until the all character in the buffer has been tested.
00394         while(*g_pcGPSResponseBuffer++){
00395             if(*g_pcGPSResponseBuffer == '$'){
00396                 startFlag = 1;
00397                 break;
00398             }
00399             else{
00400                 continue;
00401             }
00402         }
00403     } 
00404     unsigned uiAvail = strlen(g_pcGPSResponseBuffer);
00405     unsigned char i;
00406     if(startFlag){
00407         // decrase uiAvail $ character dosen't count...
00408         for(i = 1; i < (uiAvail - 1); i++){
00409             if((g_pcGPSResponseBuffer[i] == '\r') && (g_pcGPSResponseBuffer[i+1] == '\n')){
00410                 unsigned char j;
00411                 for(j = 0; j < (i - 1); j++){
00412                     *pcNmeaPacket++ = g_pcGPSResponseBuffer[j];
00413                 }
00414                 // Add a null termination to the string
00415                 *pcNmeaPacket = 0;
00416                 foundpacket = NMEA_UNKNOWN;
00417                 break;
00418             }
00419         }
00420         if(foundpacket){
00421             if(!strncmp(pcNmeaPacket, "GPGGA", 5)){
00422                 // if we've found a correct packet we can clear the response buffer
00423                 GPS_clearResponseBuffer();
00424                 foundpacket = NMEA_GPGGA;
00425             }
00426             else if(!strncmp(pcNmeaPacket, "GPRMC", 5)){
00427                 // if we've found a correct packet we can clear the response buffer
00428                 GPS_clearResponseBuffer();
00429                 foundpacket = NMEA_GPRMC;
00430             }
00431             // default  foundpacket = NMEA_NODATA   
00432         }
00433         else if(GPS_isResponseBufferFull()){
00434             // if we did'nt find packet and the buffer is full
00435             // we're logjammed, flush entire buffer
00436             GPS_clearResponseBuffer();
00437         }
00438     }
00439     // return the type of the found pakcet
00440     // if no packet has found the function will return with NMEA_NODATA
00441     return foundpacket;
00442 }
00443 
00444 
00446 void GPS_clearGPSInfoPacket(tGPSInfo* pGPSInfoPacket)
00448 {
00449     tGPSInfo g_GPSInfoBlank = {0}; 
00450     *pGPSInfoPacket = g_GPSInfoBlank;
00451 }
00452 
00453 
00455 void GPS_ProcessGPGGA(const char* pcFoundPacket, tGPSInfo* pGPSInfoPacket)
00457 {
00458     // temporaly buffer to store the part of the packet wants to be converted
00459     char cpTmpBuffer[20] = {'\0'};
00460     // index for array is pointed by the pcFoundPacket
00461     unsigned int i;
00462     // for the strtod functions
00463     char* endptr;
00464     // start parsing just after "GPGA"
00465     i = 6;
00466     // an attempt to reject the empty packet
00467     if(pcFoundPacket[i] == ',' && pcFoundPacket[i+1] == ','){
00468         return;
00469     }
00470     // Increase the value of index in order to the first digit of the hours will be addressed.
00471     i++;
00472     // get the hour from the packet
00473     strncpy(cpTmpBuffer,&pcFoundPacket[i], 2);
00474     pGPSInfoPacket->currentTime.ucHour = (unsigned char)atoi(cpTmpBuffer);
00475     // clear the temporaly buffer
00476     memset(cpTmpBuffer, sizeof(cpTmpBuffer),0);
00477     // Step forward to the place where the min begins.
00478     i+=2;
00479     // get the minute from the packet 
00480     strncpy(cpTmpBuffer,&pcFoundPacket[i], 2); 
00481     pGPSInfoPacket->currentTime.ucMin = (unsigned char)atoi(cpTmpBuffer);
00482     // clear the temporaly buffer
00483     memset(cpTmpBuffer, sizeof(cpTmpBuffer),0);
00484     // Step forward to the place where the sec begins.  
00485     i+=2; 
00486     // get the sec from the packet 
00487     strncpy(cpTmpBuffer,&pcFoundPacket[i], 2);    
00488     pGPSInfoPacket->currentTime.ucSec = (unsigned char)atoi(cpTmpBuffer);
00489     // clear the temporaly buffer
00490     memset(cpTmpBuffer, sizeof(cpTmpBuffer),0);
00491     // Step forward to the place where the msec begins.
00492     i+=3;   
00493     // get the msec from the packet     
00494     strncpy(cpTmpBuffer,&pcFoundPacket[i], 3);    
00495     pGPSInfoPacket->currentTime.ucSec = atoi(cpTmpBuffer);  
00496     // clear the temporaly buffer
00497     memset(cpTmpBuffer, sizeof(cpTmpBuffer),0);                                                      
00498     // next field: latitude
00499     while(pcFoundPacket[i++] != ',');
00500     // get latitude
00501     pGPSInfoPacket->currentPosition.latitude = strtod(&pcFoundPacket[i], &endptr);
00502     // Step forward where the latitude indicator begins.
00503     i++;
00504     // if the direction is South set the forth bit of the direction variable
00505     if(pcFoundPacket[i] == 'S'){
00506         SET_BIT(pGPSInfoPacket->currentPosition.altitudeFractPartAndDir, 3);
00507     }
00508     // if the direction is North clear the forth bit of the direction variable
00509     else{
00510         CLEAR_BIT(pGPSInfoPacket->currentPosition.altitudeFractPartAndDir, 3);
00511     }
00512     // get longitude
00513     pGPSInfoPacket->currentPosition.longitude = strtod(&pcFoundPacket[i], &endptr);
00514     // if the direction is West set the fifth bit of the direction variable
00515     // increase the endptr by one because now it's pointing to the comma
00516     if(*(endptr+1) == 'W'){
00517         SET_BIT(pGPSInfoPacket->currentPosition.altitudeFractPartAndDir, 4);
00518     }
00519     // if the direction is East clear it
00520     else{
00521         CLEAR_BIT(pGPSInfoPacket->currentPosition.altitudeFractPartAndDir, 4);
00522     }
00523     // next field: gps gualitiy indicator, we don't need it, so skip it
00524     while(pcFoundPacket[i++] != ',');
00525     // next field: satellites used, we don't need it, so skip it
00526     while(pcFoundPacket[i++] != ',');
00527     // next field: HDOP, we don't need it, so skip it
00528     while(pcFoundPacket[i++] != ',');
00529     // next field: altitude
00530     while(pcFoundPacket[i++] != ',');
00531     // now we're pointing to the first figure of the altitude
00532     i++;
00533     unsigned char j = 0;
00534     while(pcFoundPacket[i] != '.'){
00535         // copy the intiger part of the altitude to the temporaly buffer
00536         cpTmpBuffer[j++] = pcFoundPacket[i++];
00537     }
00538     // get the intiger part of the altitude
00539     pGPSInfoPacket->currentPosition.altitudeFractPartAndDir = atoi(cpTmpBuffer);
00540     // clear the temporaly buffer
00541     memset(cpTmpBuffer, sizeof(cpTmpBuffer),0);
00542     // now we're pointig the fractional part of the altitude
00543     i++;
00544     // get the franctional part of the altitude
00545     OR(pGPSInfoPacket->currentPosition.altitudeFractPartAndDir, (unsigned char)atoi(&pcFoundPacket[i]));
00546 }
 All Data Structures Files Functions Variables Typedefs Enumerations Defines