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