Csr location class shows location and satellite information, which supports H13467 + ST F103RB/NXP LCP1549 boards now.
Dependents: CsrLocationDemo CsrLocationDemo
Fork of CsrLocation by
Diff: CsrLocation.cpp
- Revision:
- 3:71690f7bb480
- Parent:
- 2:d4fe184925f2
- Child:
- 4:0d9b711fb646
--- a/CsrLocation.cpp Wed Mar 26 09:16:55 2014 +0000 +++ b/CsrLocation.cpp Wed May 21 08:55:55 2014 +0000 @@ -17,6 +17,8 @@ static uint8_t sOspSwitch2NmeaReq[] = {0xA0, 0xA2, 0x00, 0x18, 0x81, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x05, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x12, 0xC0, 0x01, 0x64, 0xB0, 0xB3}; static char sNmeaSwitch2OspReq[] = "$PSRF100,0,115200,8,1,0*04\r\n"; +static char sNmeaStopReq[] = "$PSRF117,16*0B\r\n"; + CsrLocation::CsrLocation(tCsrLocConfig *pLocConfig) { @@ -56,7 +58,7 @@ _CsrLocHwReset(); } -void CsrLocation::CsrLocStart(ePowerMode pwrMode) +void CsrLocation::CsrLocStart(ePowerMode pwrMode, eProto proto) { csrLocInst.pwrMode = pwrMode; @@ -64,10 +66,22 @@ { /* Csr Location SDK version */ CSR_LOG_INFO("==== CSR LOC SDK version: %s Date: %s ====\r\n", CSR_LOC_SDK_VER, __DATE__ " " __TIME__); + + csrLocInst.proto = proto; + /* open UART */ - CSR_LOG_INFO("Checking OSP protocol...\r\n"); - csrLocInst.protoState = PROTO_STATE_DET_OSP; - csrLocInst.baudRate = BAUDRATE_OSP; + if(proto == PROTO_NMEA) + { + CSR_LOG_INFO("Checking NMEA protocol...\r\n"); + csrLocInst.protoState = PROTO_STATE_DET_NMEA; + csrLocInst.baudRate = BAUDRATE_NMEA; + } + else + { + CSR_LOG_INFO("Checking OSP protocol...\r\n"); + csrLocInst.protoState = PROTO_STATE_DET_OSP; + csrLocInst.baudRate = BAUDRATE_OSP; + } _CsrLocUartInit(); /* trigger on_off */ @@ -103,8 +117,15 @@ /* in sleep mode, trigger on_off firstly */ _CsrLocHwOnoff(); wait_ms(500); - } - _CsrLocSendData(SEND_DATA_TYPE_OSP_STOP_REQ); + } + if(csrLocInst.proto == PROTO_NMEA) + { + _CsrLocSendData(SEND_DATA_TYPE_NMEA_STOP_REQ); + } + else + { + _CsrLocSendData(SEND_DATA_TYPE_OSP_STOP_REQ); + } wait_ms(10); _CsrLocHwReset(); csrLocInst.locState = CSR_LOC_STATE_IDLE; @@ -166,6 +187,25 @@ tCsrLocInst *pLocInst = &csrLocInst; uint8_t data; + if(pLocInst->bTimeoutFlag) + { + pLocInst->pTimeoutChk->detach(); + pLocInst->bTimeoutFlag = false; + if(pLocInst->protoState == PROTO_STATE_DET_OSP || pLocInst->protoState == PROTO_STATE_DET_OSP_FROM_NMEA) + { + _CsrLocDetProtoOspTimeout(); + } + else if(pLocInst->protoState == PROTO_STATE_DET_NMEA || pLocInst->protoState == PROTO_STATE_DET_NMEA_FROM_OSP) + { + _CsrLocDetProtoNmeaTimeout(); + } + else + { + CSR_LOG_INFO("timeout in unknown protocol state %d.\r\n", pLocInst->protoState); + } + return; + } + if(pLocInst->in != pLocInst->out) { data = pLocInst->serialBuf[pLocInst->out++]; @@ -174,13 +214,21 @@ { case PROTO_STATE_DET_OSP: case PROTO_STATE_DET_OSP_FROM_NMEA: - _CsrLocDetProtoOsp(data); + _CsrLocProcessRawOspStream(data); break; case PROTO_STATE_DET_NMEA: - _CsrLocDetProtoNmea(data); + case PROTO_STATE_DET_NMEA_FROM_OSP: + _CsrLocProcessRawNmeaStream(data); break; case PROTO_STATE_DET_OK: - _CsrLocProcessRawOspStream(data); + if(pLocInst->proto == PROTO_NMEA) + { + _CsrLocProcessRawNmeaStream(data); + } + else + { + _CsrLocProcessRawOspStream(data); + } break; default: /* Discard received data */ @@ -190,16 +238,23 @@ } } -void CsrLocation::_CsrLocDetProtoOsp(uint8_t data) +void CsrLocation::_CsrLocDetProtoOspTimeout(void) { tCsrLocInst *pLocInst = &csrLocInst; - if(pLocInst->bTimeoutFlag) + if(pLocInst->proto == PROTO_NMEA) + { + /* Failed to detect OSP */ + pLocInst->pSerialLoc->attach(NULL); + pLocInst->protoState = PROTO_STATE_DET_INVALID; + pLocInst->baudRate = BAUDRATE_NMEA; + CSR_LOG_INFO("Checking OSP failed.\r\n"); + pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 1); + } + else { /* Failed to detect OSP and try to detect NMEA */ pLocInst->pSerialLoc->attach(NULL); - pLocInst->pTimeoutChk->detach(); - pLocInst->bTimeoutFlag = false; if(pLocInst->protoState == PROTO_STATE_DET_OSP) { pLocInst->protoState = PROTO_STATE_DET_NMEA; @@ -213,29 +268,48 @@ CSR_LOG_INFO("Checking switched OSP protocol failed.\r\n"); pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 1); } - return; } - - _CsrLocProcessRawOspStream(data); } -void CsrLocation::_CsrLocDetProtoNmea(uint8_t data) +void CsrLocation::_CsrLocDetProtoNmeaTimeout(void) { tCsrLocInst *pLocInst = &csrLocInst; - if(pLocInst->bTimeoutFlag) + CSR_LOG_INFO("Checking NMEA protocol failed\r\n"); + + if(pLocInst->proto == PROTO_NMEA) { - /* Failed to detect OSP and try to detect NMEA */ + /* Failed to detect NMEA and try to detect OSP */ pLocInst->pSerialLoc->attach(NULL); - pLocInst->pTimeoutChk->detach(); - pLocInst->bTimeoutFlag = false; + if(pLocInst->protoState == PROTO_STATE_DET_NMEA) + { + pLocInst->protoState = PROTO_STATE_DET_OSP; + pLocInst->baudRate = BAUDRATE_OSP; + CSR_LOG_INFO("Checking NMEA protocol failed, now check OSP protocol...\r\n"); + _CsrLocUartInit(); + } + else + { + pLocInst->protoState = PROTO_STATE_DET_INVALID; + CSR_LOG_INFO("Checking switched NMEA protocol failed.\r\n"); + pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 1); + } + } + else + { + /* Failed to detect NEMA */ + pLocInst->pSerialLoc->attach(NULL); pLocInst->protoState = PROTO_STATE_DET_INVALID; pLocInst->baudRate = BAUDRATE_OSP; CSR_LOG_INFO("Checking NMEA failed.\r\n"); pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 1); - return; } +} +void CsrLocation::_CsrLocProcessRawNmeaStream(uint8_t data) +{ + tCsrLocInst *pLocInst = &csrLocInst; + switch (pLocInst->protoDetState) { case STATE_START1: @@ -249,6 +323,8 @@ if (NMEA_MSG_HEAD1 == data) { pLocInst->protoDetState = STATE_END1; + pLocInst->decodeIndex = 0; + pLocInst->serialPkt[pLocInst->decodeIndex++] = data; } else if (NMEA_MSG_HEAD0 == data) { @@ -262,24 +338,49 @@ case STATE_END1: if (NMEA_MSG_TAIL0 == data) { - pLocInst->pSerialLoc->attach(NULL); pLocInst->pTimeoutChk->detach(); pLocInst->bTimeoutFlag = false; - pLocInst->protoState = PROTO_STATE_SWI_OSP_FROM_NMEA; - pLocInst->protoDetState = STATE_START1; - CSR_LOG_INFO("Checking OSP protocol OK, switching to OSP...\r\n"); - _CsrLocSendData(SEND_DATA_TYPE_NMEA_SWITCH2OSP_REQ); - wait_ms(100); + if(pLocInst->proto == PROTO_NMEA) + { + pLocInst->protoDetState = STATE_START1; + if(pLocInst->protoState == PROTO_STATE_DET_NMEA || pLocInst->protoState == PROTO_STATE_DET_NMEA_FROM_OSP) + { + CSR_LOG_INFO("Checking NMEA protocol OK.\r\n"); + pLocInst->protoState = PROTO_STATE_DET_OK; + pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 0); + } - pLocInst->protoState = PROTO_STATE_DET_OSP_FROM_NMEA; - pLocInst->baudRate = BAUDRATE_OSP; - CSR_LOG_INFO("Checking switched OSP protocol...\r\n"); - _CsrLocUartInit(); + pLocInst->serialPkt[pLocInst->decodeIndex++] = '\0'; + _CsrLocProcessRawNmeaPkt(); + } + else + { + pLocInst->pSerialLoc->attach(NULL); + + CSR_LOG_INFO("Checking NMEA protocol OK, switching to OSP...\r\n"); + _CsrLocSendData(SEND_DATA_TYPE_NMEA_SWITCH2OSP_REQ); + wait_ms(100); + pLocInst->protoState = PROTO_STATE_DET_OSP_FROM_NMEA; + pLocInst->baudRate = BAUDRATE_OSP; + CSR_LOG_INFO("Checking switched OSP protocol...\r\n"); + _CsrLocUartInit(); + } } else if (NMEA_MSG_HEAD0 == data) { pLocInst->protoDetState = STATE_START2; } + else + { + if(pLocInst->decodeIndex < (MAX_SERIAL_PKT_LEN - 2)) + { + pLocInst->serialPkt[pLocInst->decodeIndex++] = data; + } + else + { + pLocInst->protoDetState = STATE_START1; + } + } break; default: break; @@ -418,16 +519,32 @@ { pLocInst->pTimeoutChk->detach(); pLocInst->bTimeoutFlag = false; + pLocInst->protoDetState = STATE_START1; - if(pLocInst->protoState == PROTO_STATE_DET_OSP || pLocInst->protoState == PROTO_STATE_DET_OSP_FROM_NMEA) + if(pLocInst->proto == PROTO_NMEA) { - CSR_LOG_INFO("Checking OSP protocol OK.\r\n"); - pLocInst->protoState = PROTO_STATE_DET_OK; - pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 0); + pLocInst->pSerialLoc->attach(NULL); + + CSR_LOG_INFO("Checking OSP protocol OK, switching to NMEA...\r\n"); + _CsrLocSendData(SEND_DATA_TYPE_OSP_SWITCH2NMEA_REQ); + wait_ms(100); + pLocInst->protoState = PROTO_STATE_DET_NMEA_FROM_OSP; + pLocInst->baudRate = BAUDRATE_NMEA; + CSR_LOG_INFO("Checking switched NMEA protocol...\r\n"); + _CsrLocUartInit(); + } - - _CsrLocProcessRawOspPkt(); - pLocInst->protoDetState = STATE_START1; + else + { + if(pLocInst->protoState == PROTO_STATE_DET_OSP || pLocInst->protoState == PROTO_STATE_DET_OSP_FROM_NMEA) + { + CSR_LOG_INFO("Checking OSP protocol OK.\r\n"); + pLocInst->protoState = PROTO_STATE_DET_OK; + pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 0); + } + + _CsrLocProcessRawOspPkt(); + } } else { @@ -445,6 +562,61 @@ } +void CsrLocation::_CsrLocProcessRawNmeaPkt(void) +{ + tCsrLocInst *pLocInst = &csrLocInst; + tLocPosResp pos; + const char *pNmeaGga = "GPGGA"; + float deg, min; + char ns, ew; + int svUsed; + float horDop; + int valid; + int i, cnt; + + if(strncmp((char *)pLocInst->serialPkt, pNmeaGga, strlen(pNmeaGga)) == 0) + { + cnt = 0; + for(i = 0; i < (int)strlen((char *)pLocInst->serialPkt); i++) + { + if(pLocInst->serialPkt[i] == ',') + { + cnt++; + if(cnt == 6) + { + break; + } + } + } + if(cnt != 6) + { + return; + } + i++; + sscanf((char *)(&pLocInst->serialPkt[i]), "%d,", &valid); + if(valid == 0) + { + return; + } + + /* Parse GPGGA and output position information */ + memset(&pos, 0, sizeof(tLocPosResp)); + if(sscanf((char *)pLocInst->serialPkt, "GPGGA,%f,%lf,%c,%lf,%c,%d,%d,%f,%lf", &pos.u.utcTime, &pos.lat, &ns, &pos.lon, &ew, &valid, &svUsed, &horDop, &pos.alt) >= 1) + { + if(ns == 'S') { pos.lat *= -1.0; } + if(ew == 'W') { pos.lon *= -1.0; } + deg = (float)(static_cast<int>(pos.lat * 0.01f)); + min = pos.lat - (deg * 100.0f); + pos.lat = deg + min / 60.0f; + deg = (float)(static_cast<int>(pos.lon * 0.01f)); + min = pos.lon - (deg * 100.0f); + pos.lon = deg + min / 60.0f; + + csrLocInst.appOutCb(LOC_OUTPUT_LOCATION, &pos, sizeof(tLocPosResp)); + } + } +} + void CsrLocation::_CsrLocProcessRawOspPkt(void) { tCsrLocInst *pLocInst = &csrLocInst; @@ -582,8 +754,8 @@ *pMsgLen = sizeof(*pPos); ptr += 2; - pPos->gps_week = BINARY_IMPORT_UINT16(ptr); - pPos->tow = BINARY_IMPORT_UINT32(ptr); + pPos->u.gpsTime.gps_week = BINARY_IMPORT_UINT16(ptr); + pPos->u.gpsTime.tow = BINARY_IMPORT_UINT32(ptr); ptr += 12; pPos->lat = (double)BINARY_IMPORT_SINT32(ptr); pPos->lat *= 1e-7; @@ -785,7 +957,7 @@ pLocInst->in &= (MAX_SERIAL_BUF_LEN-1); if(pLocInst->in == pLocInst->out) { - CSR_LOG_INFO("rx overwritten %d %d.\r\n", pLocInst->in, pLocInst->out); + CSR_LOG_INFO("rx overwritten %lu %lu.\r\n", pLocInst->in, pLocInst->out); } } @@ -821,7 +993,11 @@ pData = (const uint8_t *)sNmeaSwitch2OspReq; size = strlen(sNmeaSwitch2OspReq); break; - + case SEND_DATA_TYPE_NMEA_STOP_REQ: + pData = (const uint8_t *)sNmeaStopReq; + size = strlen(sNmeaStopReq); + break; + default: pData = NULL; }