Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: example-ublox-at-cellular-interface-ext example-low-power-sleep example-C030-out-of-box-demo example-C030-out-of-box-demo ... more
gnss.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 u-blox 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /** 00018 * @file gnss.cpp 00019 * This file defines a class that communicates with a u-blox GNSS chip. 00020 */ 00021 00022 #include "mbed.h" 00023 #include "ctype.h" 00024 #include "gnss.h" 00025 00026 #ifdef UBLOX_WEARABLE_FRAMEWORK 00027 #include "SDCardModel.h" 00028 #else 00029 #define SEND_LOGGING_MESSAGE printf 00030 #endif 00031 00032 GnssParser::GnssParser(void) 00033 { 00034 // Create the enable pin but set everything to disabled 00035 _gnssEnable = NULL; 00036 00037 #ifdef TARGET_UBLOX_C030 00038 _gnssEnable = new DigitalInOut(GNSSEN, PIN_OUTPUT, PushPullNoPull, 0); 00039 #else 00040 _gnssEnable = new DigitalInOut(GNSSEN, PIN_OUTPUT, PullNone, 1); 00041 #endif 00042 } 00043 00044 GnssParser::~GnssParser(void) 00045 { 00046 if (_gnssEnable != NULL) { 00047 *_gnssEnable = 0; 00048 delete _gnssEnable; 00049 } 00050 } 00051 00052 void GnssParser::powerOff(void) 00053 { 00054 // Set the GNSS into backup mode using the command RMX-LPREQ 00055 struct { 00056 unsigned long dur; 00057 unsigned long flags; 00058 } msg = {0/*endless*/,0/*backup*/}; 00059 sendUbx(0x02, 0x41, &msg, sizeof(msg)); 00060 } 00061 00062 void GnssParser::cutOffPower(void) 00063 { 00064 //Disabling PA15 to cut off power supply 00065 if (_gnssEnable != NULL) 00066 *_gnssEnable = 0; 00067 wait_ms(1); 00068 } 00069 00070 void GnssParser::_powerOn(void) 00071 { 00072 if (_gnssEnable != NULL) { 00073 *_gnssEnable = 1; 00074 } 00075 wait_ms (1); 00076 } 00077 00078 int GnssParser::_getMessage(Pipe<char> * pipe, char* buf, int len) 00079 { 00080 int unkn = 0; 00081 int sz = pipe->size(); 00082 int fr = pipe->free(); 00083 if (len > sz) 00084 len = sz; 00085 while (len > 0) 00086 { 00087 // NMEA protocol 00088 pipe->set(unkn); 00089 int nmea = _parseNmea(pipe,len); 00090 if ((nmea != NOT_FOUND) && (unkn > 0)) 00091 return UNKNOWN | pipe->get (buf,unkn); 00092 if (nmea == WAIT && fr) 00093 return WAIT; 00094 if (nmea > 0) 00095 return NMEA | pipe->get (buf,nmea); 00096 // UBX protocol 00097 00098 pipe->set(unkn); 00099 int ubx = _parseUbx(pipe,len); 00100 if ((ubx != NOT_FOUND) && (unkn > 0)) 00101 return UNKNOWN | pipe->get (buf,unkn); 00102 if (ubx == WAIT && fr) 00103 return WAIT; 00104 if (ubx > 0) 00105 return UBX | pipe->get (buf,ubx); 00106 00107 // UNKNOWN 00108 unkn ++; 00109 len--; 00110 } 00111 if (unkn > 0) 00112 return UNKNOWN | pipe->get (buf,unkn); 00113 return WAIT; 00114 } 00115 00116 int GnssParser::_parseNmea(Pipe<char> * pipe, int len) 00117 { 00118 int o = 0; 00119 int c = 0; 00120 char ch; 00121 if (++o > len) return WAIT; 00122 if ('$' != pipe->next()) return NOT_FOUND; 00123 // This needs to be extended by crc checking 00124 for (;;) 00125 { 00126 if (++o > len) return WAIT; 00127 ch = pipe->next(); 00128 if ('*' == ch) break; // crc delimiter 00129 if (!isprint(ch)) return NOT_FOUND; 00130 c ^= ch; 00131 } 00132 if (++o > len) return WAIT; 00133 ch = _toHex[(c >> 4) & 0xF]; // high nibble 00134 if (ch != pipe->next()) return NOT_FOUND; 00135 if (++o > len) return WAIT; 00136 ch = _toHex[(c >> 0) & 0xF]; // low nibble 00137 if (ch != pipe->next()) return NOT_FOUND; 00138 if (++o > len) return WAIT; 00139 if ('\r' != pipe->next()) return NOT_FOUND; 00140 if (++o > len) return WAIT; 00141 if ('\n' != pipe->next()) return NOT_FOUND; 00142 return o; 00143 } 00144 00145 int GnssParser::_parseUbx(Pipe<char> * pipe, int l) 00146 { 00147 int o = 0; 00148 if (++o > l) return WAIT; 00149 if ('\xB5' != pipe->next()) return NOT_FOUND; 00150 if (++o > l) return WAIT; 00151 if ('\x62' != pipe->next()) return NOT_FOUND; 00152 o += 4; 00153 if (o > l) return WAIT; 00154 int i,j,ca,cb; 00155 i = pipe->next(); 00156 ca = i; 00157 cb = ca; // cls 00158 i = pipe->next(); 00159 ca += i; 00160 cb += ca; // id 00161 i = pipe->next(); 00162 ca += i; 00163 cb += ca; // len_lsb 00164 j = pipe->next(); 00165 ca += j; 00166 cb += ca; // len_msb 00167 j = i + (j << 8); 00168 while (j--) 00169 { 00170 if (++o > l) return WAIT; 00171 i = pipe->next(); 00172 ca += i; 00173 cb += ca; 00174 } 00175 ca &= 0xFF; 00176 cb &= 0xFF; 00177 if (++o > l) return WAIT; 00178 if (ca != pipe->next()) return NOT_FOUND; 00179 if (++o > l) return WAIT; 00180 if (cb != pipe->next()) return NOT_FOUND; 00181 return o; 00182 } 00183 00184 int GnssParser::send(const char* buf, int len) 00185 { 00186 return _send(buf, len); 00187 } 00188 00189 int GnssParser::sendNmea(const char* buf, int len) 00190 { 00191 char head[1] = { '$' }; 00192 char tail[5] = { '*', 0x00/*crc_high*/, 0x00/*crc_low*/, '\r', '\n' }; 00193 int i; 00194 int crc = 0; 00195 for (i = 0; i < len; i ++) 00196 crc ^= *buf++; 00197 i = _send(head, sizeof(head)); 00198 i += _send(buf, len); 00199 tail[1] = _toHex[(crc > 4) & 0xF0]; 00200 tail[2] = _toHex[(crc > 0) & 0x0F]; 00201 i += _send(tail, sizeof(tail)); 00202 return i; 00203 } 00204 00205 int GnssParser::sendUbx(unsigned char cls, unsigned char id, const void* buf /*= NULL*/, int len /*= 0*/) 00206 { 00207 char head[6] = { 0xB5, 0x62, cls, id, (char) len, (char) (len >> 8)}; 00208 char crc[2]; 00209 int i; 00210 int ca = 0; 00211 int cb = 0; 00212 for (i = 2; i < 6; i ++) 00213 { 00214 ca += head[i]; 00215 cb += ca; 00216 } 00217 for (i = 0; i < len; i ++) 00218 { 00219 ca += ((char*)buf)[i]; 00220 cb += ca; 00221 } 00222 i = _send(head, sizeof(head)); 00223 i += _send(buf, len); 00224 crc[0] = ca & 0xFF; 00225 crc[1] = cb & 0xFF; 00226 i += _send(crc, sizeof(crc)); 00227 return i; 00228 } 00229 00230 const char* GnssParser::findNmeaItemPos(int ix, const char* start, const char* end) 00231 { 00232 // Find the start 00233 for (; (start < end) && (ix > 0); start ++) 00234 { 00235 if (*start == ',') 00236 ix --; 00237 } 00238 // Found and check bounds 00239 if ((ix == 0) && (start < end) && 00240 (*start != ',') && (*start != '*') && (*start != '\r') && (*start != '\n')) 00241 return start; 00242 else 00243 return NULL; 00244 } 00245 00246 bool GnssParser::getNmeaItem(int ix, char* buf, int len, double& val) 00247 { 00248 char* end = &buf[len]; 00249 const char* pos = findNmeaItemPos(ix, buf, end); 00250 // Find the start 00251 if (!pos) 00252 return false; 00253 val = strtod(pos, &end); 00254 // Restore the last character 00255 return (end > pos); 00256 } 00257 00258 bool GnssParser::getNmeaItem(int ix, char* buf, int len, int& val, int base /*=10*/) 00259 { 00260 char* end = &buf[len]; 00261 const char* pos = findNmeaItemPos(ix, buf, end); 00262 // Find the start 00263 if (!pos) 00264 return false; 00265 val = (int)strtol(pos, &end, base); 00266 return (end > pos); 00267 } 00268 00269 bool GnssParser::getNmeaItem(int ix, char* buf, int len, char& val) 00270 { 00271 const char* end = &buf[len]; 00272 const char* pos = findNmeaItemPos(ix, buf, end); 00273 // Find the start 00274 if (!pos) 00275 return false; 00276 // Skip leading spaces 00277 while ((pos < end) && isspace(*pos)) 00278 pos++; 00279 // Check bound 00280 if ((pos < end) && 00281 (*pos != ',') && (*pos != '*') && (*pos != '\r') && (*pos != '\n')) 00282 { 00283 val = *pos; 00284 return true; 00285 } 00286 return false; 00287 } 00288 00289 bool GnssParser::getNmeaAngle(int ix, char* buf, int len, double& val) 00290 { 00291 char ch; 00292 if (getNmeaItem(ix,buf,len,val) && getNmeaItem(ix+1,buf,len,ch) && 00293 ((ch == 'S') || (ch == 'N') || (ch == 'E') || (ch == 'W'))) 00294 { 00295 val *= 0.01; 00296 int i = (int)val; 00297 val = (val - i) / 0.6 + i; 00298 if (ch == 'S' || ch == 'W') 00299 val = -val; 00300 return true; 00301 } 00302 return false; 00303 } 00304 00305 int GnssParser::enable_ubx() { 00306 00307 unsigned char ubx_cfg_prt[]= {0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,0x00, 0x00}; 00308 int conf = RETRY; 00309 int length = 0; 00310 00311 while(conf) 00312 { 00313 length = sendUbx(0x06, 0x00, ubx_cfg_prt, sizeof(ubx_cfg_prt)); 00314 if(length >= (int)(sizeof(ubx_cfg_prt) + UBX_FRAME_SIZE)) 00315 { 00316 wait(5); 00317 break; 00318 } 00319 else 00320 { 00321 conf = conf - 1; 00322 } 00323 } 00324 return (conf == 0) ? 0 : 1; 00325 } 00326 00327 eUBX_MESSAGE GnssParser::get_ubx_message(char *buff) { 00328 eUBX_MESSAGE return_value = UNKNOWN_UBX; 00329 00330 if(buff[SYNC_CHAR_INDEX_1] == 0xB5 && buff[SYNC_CHAR_INDEX_2] == 0x62) { 00331 00332 switch (buff[MSG_CLASS_INDEX]) { 00333 00334 case NAV: { 00335 switch (buff[MSG_ID_INDEX]) { 00336 00337 case 0x07: { 00338 return_value = UBX_NAV_PVT; 00339 } 00340 break; 00341 case 0x09: { 00342 return_value = UBX_NAV_ODO; 00343 } 00344 break; 00345 case 0x03: { 00346 return_value = UBX_NAV_STATUS; 00347 } 00348 break; 00349 case 0x35: { 00350 return_value = UBX_NAV_SAT; 00351 } 00352 break; 00353 default: 00354 { 00355 return_value = UNKNOWN_UBX; 00356 } 00357 break; 00358 } 00359 } 00360 break; 00361 case ACK: { 00362 switch (buff[MSG_ID_INDEX]) { 00363 case 0x00: { 00364 return_value = UBX_ACK_NAK; 00365 } 00366 break; 00367 case 0x01: { 00368 return_value = UBX_ACK_ACK; 00369 } 00370 break; 00371 default: 00372 { 00373 return_value = UNKNOWN_UBX; 00374 } 00375 break; 00376 } 00377 } 00378 break; 00379 case LOG: { 00380 switch (buff[MSG_ID_INDEX]) { 00381 case 0x11: { 00382 return_value = UBX_LOG_BATCH; 00383 } 00384 break; 00385 default: 00386 { 00387 return_value = UNKNOWN_UBX; 00388 } 00389 break; 00390 } 00391 } 00392 break; 00393 default: 00394 { 00395 return_value = UNKNOWN_UBX; 00396 } 00397 break; 00398 } 00399 } 00400 return return_value; 00401 } 00402 00403 tUBX_ACK_ACK GnssParser::decode_ubx_cfg_ack_nak_msg(char *buf) { 00404 tUBX_ACK_ACK return_decoded_msg; 00405 uint8_t index = UBX_PAYLOAD_INDEX; 00406 00407 return_decoded_msg.msg_class = buf[index++]; 00408 return_decoded_msg.msg_id = buf[index]; 00409 00410 return return_decoded_msg; 00411 } 00412 00413 tUBX_NAV_ODO GnssParser::decode_ubx_nav_odo_msg(char *buf) { 00414 tUBX_NAV_ODO return_decoded_msg; 00415 uint8_t index = UBX_PAYLOAD_INDEX; 00416 00417 return_decoded_msg.version = buf[index++]; 00418 index +=3; // 3 bytes are reserved 00419 00420 return_decoded_msg.itow = buf[index++]; 00421 return_decoded_msg.itow |= (buf[index++] << 8); 00422 return_decoded_msg.itow |= (buf[index++] << 16); 00423 return_decoded_msg.itow |= (buf[index++] << 24); 00424 00425 return_decoded_msg.distance = buf[index++]; 00426 return_decoded_msg.distance |= (buf[index++] << 8); 00427 return_decoded_msg.distance |= (buf[index++] << 16); 00428 return_decoded_msg.distance |= (buf[index++] << 24); 00429 00430 return_decoded_msg.totalDistance = buf[index++]; 00431 return_decoded_msg.totalDistance |= (buf[index++] << 8); 00432 return_decoded_msg.totalDistance |= (buf[index++] << 16); 00433 return_decoded_msg.totalDistance |= (buf[index++] << 24); 00434 00435 return_decoded_msg.distanceSTD = buf[index++]; 00436 return_decoded_msg.distanceSTD |= (buf[index++] << 8); 00437 return_decoded_msg.distanceSTD |= (buf[index++] << 16); 00438 return_decoded_msg.distanceSTD |= (buf[index++] << 24); 00439 00440 return return_decoded_msg; 00441 } 00442 00443 tUBX_NAV_PVT GnssParser::decode_ubx_nav_pvt_msg(char *buf) { 00444 tUBX_NAV_PVT return_decoded_msg; 00445 uint8_t index = UBX_PAYLOAD_INDEX; 00446 00447 return_decoded_msg.itow = buf[index++]; 00448 return_decoded_msg.itow |= (buf[index++] << 8); 00449 return_decoded_msg.itow |= (buf[index++] << 16); 00450 return_decoded_msg.itow |= (buf[index++] << 24); 00451 00452 return_decoded_msg.year = buf[index++]; 00453 return_decoded_msg.year |= (buf[index++] << 8); 00454 00455 return_decoded_msg.month = buf[index++]; 00456 00457 return_decoded_msg.day = buf[index++]; 00458 00459 // Go to Fix type 00460 index = UBX_PAYLOAD_INDEX + 20; 00461 return_decoded_msg.fixType = buf[index++]; 00462 return_decoded_msg.flag1 = buf[index]; 00463 00464 // Go to lon 00465 index = UBX_PAYLOAD_INDEX + 24; 00466 00467 return_decoded_msg.lon = buf[index++]; 00468 return_decoded_msg.lon |= (buf[index++] << 8); 00469 return_decoded_msg.lon |= (buf[index++] << 16); 00470 return_decoded_msg.lon |= (buf[index++] << 24); 00471 00472 return_decoded_msg.lat = buf[index++]; 00473 return_decoded_msg.lat |= (buf[index++] << 8); 00474 return_decoded_msg.lat |= (buf[index++] << 16); 00475 return_decoded_msg.lat |= (buf[index++] << 24); 00476 00477 return_decoded_msg.height = buf[index++]; 00478 return_decoded_msg.height |= (buf[index++] << 8); 00479 return_decoded_msg.height |= (buf[index++] << 16); 00480 return_decoded_msg.height |= (buf[index++] << 24); 00481 00482 // Go to gSpeed 00483 index = UBX_PAYLOAD_INDEX + 60; 00484 return_decoded_msg.speed = buf[index++]; 00485 return_decoded_msg.speed |= (buf[index++] << 8); 00486 return_decoded_msg.speed |= (buf[index++] << 16); 00487 return_decoded_msg.speed |= (buf[index++] << 24); 00488 00489 return return_decoded_msg; 00490 } 00491 00492 tUBX_LOG_BATCH GnssParser::decode_ubx_log_batch_msg(char *buf) { 00493 tUBX_LOG_BATCH return_decoded_msg; 00494 uint8_t index = UBX_PAYLOAD_INDEX; 00495 00496 // move index itow 00497 index = UBX_PAYLOAD_INDEX + 4; 00498 00499 return_decoded_msg.itow = buf[index++]; 00500 return_decoded_msg.itow |= (buf[index++] << 8); 00501 return_decoded_msg.itow |= (buf[index++] << 16); 00502 return_decoded_msg.itow |= (buf[index++] << 24); 00503 00504 // move index lon 00505 index = UBX_PAYLOAD_INDEX + 24; 00506 00507 return_decoded_msg.lon = buf[index++]; 00508 return_decoded_msg.lon |= (buf[index++] << 8); 00509 return_decoded_msg.lon |= (buf[index++] << 16); 00510 return_decoded_msg.lon |= (buf[index++] << 24); 00511 00512 return_decoded_msg.lat = buf[index++]; 00513 return_decoded_msg.lat |= (buf[index++] << 8); 00514 return_decoded_msg.lat |= (buf[index++] << 16); 00515 return_decoded_msg.lat |= (buf[index++] << 24); 00516 00517 return_decoded_msg.height = buf[index++]; 00518 return_decoded_msg.height |= (buf[index++] << 8); 00519 return_decoded_msg.height |= (buf[index++] << 16); 00520 return_decoded_msg.height |= (buf[index++] << 24); 00521 00522 // move index to distance 00523 index = UBX_PAYLOAD_INDEX + 84; 00524 00525 return_decoded_msg.distance = buf[index++]; 00526 return_decoded_msg.distance |= (buf[index++] << 8); 00527 return_decoded_msg.distance |= (buf[index++] << 16); 00528 return_decoded_msg.distance |= (buf[index++] << 24); 00529 00530 return_decoded_msg.totalDistance = buf[index++]; 00531 return_decoded_msg.totalDistance |= (buf[index++] << 8); 00532 return_decoded_msg.totalDistance |= (buf[index++] << 16); 00533 return_decoded_msg.totalDistance |= (buf[index++] << 24); 00534 00535 return_decoded_msg.distanceSTD = buf[index++]; 00536 return_decoded_msg.distanceSTD |= (buf[index++] << 8); 00537 return_decoded_msg.distanceSTD |= (buf[index++] << 16); 00538 return_decoded_msg.distanceSTD |= (buf[index++] << 24); 00539 00540 return return_decoded_msg; 00541 } 00542 00543 tUBX_NAV_STATUS GnssParser::decode_ubx_nav_status_msg(char *buf) { 00544 00545 tUBX_NAV_STATUS return_decoded_msg; 00546 uint8_t index = UBX_PAYLOAD_INDEX; 00547 00548 return_decoded_msg.itow = buf[index++]; 00549 return_decoded_msg.itow |= (buf[index++] << 8); 00550 return_decoded_msg.itow |= (buf[index++] << 16); 00551 return_decoded_msg.itow |= (buf[index++] << 24); 00552 00553 // move index flag 00554 return_decoded_msg.fix = buf[index++]; 00555 00556 return_decoded_msg.flags = buf[index++]; 00557 00558 // move to ttff 00559 index+=2; 00560 00561 return_decoded_msg.ttff = buf[index++]; 00562 return_decoded_msg.ttff |= (buf[index++] << 8); 00563 return_decoded_msg.ttff |= (buf[index++] << 16); 00564 return_decoded_msg.ttff |= (buf[index++] << 24); 00565 00566 return_decoded_msg.msss = buf[index++]; 00567 return_decoded_msg.msss |= (buf[index++] << 8); 00568 return_decoded_msg.msss |= (buf[index++] << 16); 00569 return_decoded_msg.msss |= (buf[index++] << 24); 00570 00571 return return_decoded_msg; 00572 } 00573 00574 00575 tUBX_NAV_SAT GnssParser::decode_ubx_nav_sat_msg(char *buf, int length) { 00576 tUBX_NAV_SAT return_decoded_msg; 00577 uint8_t index = UBX_PAYLOAD_INDEX; 00578 uint8_t numberSVs = buf[index + 5]; 00579 00580 if(length == (UBX_FRAME_SIZE + 8 + (12*numberSVs))) { 00581 return_decoded_msg.status = true; 00582 } 00583 else { 00584 return_decoded_msg.status = false; 00585 } 00586 00587 return return_decoded_msg; 00588 } 00589 00590 int GnssParser::ubx_request_batched_data(bool sendMonFirst) { 00591 unsigned char ubx_log_retrieve_batch[]= {0x00, 0x00, 0x00, 0x00}; 00592 00593 ubx_log_retrieve_batch[1] = (sendMonFirst == true) ? 0x01 : 0x00; 00594 00595 int conf = RETRY; 00596 while(conf) 00597 { 00598 00599 int length = sendUbx(0x21, 0x10, ubx_log_retrieve_batch, sizeof(ubx_log_retrieve_batch)); 00600 if(length >= (int)(sizeof(ubx_log_retrieve_batch) + UBX_FRAME_SIZE)) 00601 { 00602 wait(1); 00603 break; 00604 } 00605 else 00606 { 00607 conf = conf - 1; 00608 } 00609 } 00610 if(conf == 0) 00611 { 00612 return 1; 00613 } 00614 00615 return 0; 00616 } 00617 00618 const char GnssParser::_toHex[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; 00619 00620 // ---------------------------------------------------------------- 00621 // Serial Implementation 00622 // ---------------------------------------------------------------- 00623 00624 GnssSerial::GnssSerial(PinName tx /*= GNSSTXD */, PinName rx /*= GNSSRXD */, int baudrate /*= GNSSBAUD */, 00625 int rxSize /*= 256 */, int txSize /*= 128 */) : 00626 SerialPipe(tx, rx, baudrate, rxSize, txSize) 00627 { 00628 baud(baudrate); 00629 } 00630 00631 GnssSerial::~GnssSerial(void) 00632 { 00633 powerOff(); 00634 } 00635 00636 bool GnssSerial::init(PinName pn) 00637 { 00638 Timer timer; 00639 int size; 00640 00641 // Unused (kept only for compatibility with the I2C version) 00642 (void)pn; 00643 00644 // Power up and enable the module 00645 _powerOn(); 00646 00647 // Send a byte to wakup the device again 00648 putc(0xFF); 00649 // Wait until we get some bytes 00650 size = _pipeRx.size(); 00651 timer.start(); 00652 while ((timer.read_ms() < 1000) && (size == _pipeRx.size())) { 00653 /* Nothing, just wait */ 00654 } 00655 timer.stop(); 00656 00657 enable_ubx(); 00658 00659 wait_ms(1000); 00660 00661 baud(115200); 00662 00663 // Send a byte to wakup the device again 00664 putc(0xFF); 00665 // Wait until we get some bytes 00666 size = _pipeRx.size(); 00667 timer.start(); 00668 while ((timer.read_ms() < 1000) && (size == _pipeRx.size())) { 00669 /* Nothing, just wait */ 00670 } 00671 00672 return (size != _pipeRx.size()); 00673 } 00674 00675 int GnssSerial::getMessage(char* buf, int len) 00676 { 00677 return _getMessage(&_pipeRx, buf, len); 00678 } 00679 00680 int GnssSerial::_send(const void* buf, int len) 00681 { 00682 #ifdef UBLOX_WEARABLE_FRAMEWORK 00683 GET_SDCARD_INSTANCE->write(logging_file_name, (void *)buf, len); 00684 #endif 00685 return put((const char*)buf, len, true/*=blocking*/); 00686 } 00687 00688 // ---------------------------------------------------------------- 00689 // I2C Implementation 00690 // ---------------------------------------------------------------- 00691 00692 GnssI2C::GnssI2C(PinName sda /*= NC */, PinName scl /*= NC */, 00693 unsigned char i2cAdr /*= (66<<1) */, int rxSize /*= 256 */) : 00694 I2C(sda,scl), 00695 _pipe(rxSize), 00696 _i2cAdr(i2cAdr) 00697 { 00698 frequency(100000); 00699 } 00700 00701 GnssI2C::~GnssI2C(void) 00702 { 00703 powerOff(); 00704 } 00705 00706 bool GnssI2C::init(PinName pn) 00707 { 00708 // Power up and enable the module 00709 _powerOn(); 00710 00711 if (pn != NC) { 00712 DigitalOut pin(pn, 0); 00713 ::wait_us(1); 00714 pin = 1; 00715 ::wait_ms(100); 00716 } 00717 return !I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM)); 00718 } 00719 00720 int GnssI2C::getMessage(char* buf, int len) 00721 { 00722 // Fill the pipe 00723 int sz = _pipe.free(); 00724 if (sz) 00725 sz = _get(buf, sz); 00726 if (sz) 00727 _pipe.put(buf, sz); 00728 // Now parse it 00729 return _getMessage(&_pipe, buf, len); 00730 } 00731 00732 int GnssI2C::send(const char* buf, int len) 00733 { 00734 int sent = 0; 00735 if (len) 00736 { 00737 if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true)) 00738 sent = send(buf, len); 00739 stop(); 00740 } 00741 return sent; 00742 } 00743 00744 int GnssI2C::sendNmea(const char* buf, int len) 00745 { 00746 int sent = 0; 00747 if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true)) 00748 sent = GnssParser::sendNmea(buf, len); 00749 stop(); 00750 return sent; 00751 } 00752 00753 int GnssI2C::sendUbx(unsigned char cls, unsigned char id, const void* buf, int len) 00754 { 00755 int sent = 0; 00756 if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true)) 00757 sent = GnssParser::sendUbx(cls, id, buf, len); 00758 I2C::stop(); 00759 return sent; 00760 } 00761 00762 int GnssI2C::_get(char* buf, int len) 00763 { 00764 int read = 0; 00765 unsigned char sz[2] = {0,0}; 00766 if (!I2C::write(_i2cAdr,®LEN,sizeof(REGLEN),true) && 00767 !I2C::read(_i2cAdr,(char*)sz,sizeof(sz))) 00768 { 00769 int size = 256 * (int)sz[0] + sz[1]; 00770 if (size > len) 00771 size = len; 00772 if (size > 0) 00773 { 00774 if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true) && 00775 !I2C::read(_i2cAdr,buf,size)) { 00776 read = size; 00777 } 00778 } 00779 } 00780 return read; 00781 } 00782 00783 int GnssI2C::_send(const void* buf, int len) 00784 { 00785 return !I2C::write(_i2cAdr,(const char*)buf,len,true) ? len : 0; 00786 } 00787 00788 const char GnssI2C::REGLEN = 0xFD; 00789 const char GnssI2C::REGSTREAM = 0xFF; 00790 00791 // End Of File
Generated on Tue Jul 12 2022 14:18:20 by
