|
Mobil_surveillance_system 1
|
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 }
1.7.4