Csr location class shows location and satellite information, which supports H13467 + ST F103RB/NXP LCP1549 boards now.
Dependents: CsrLocationDemo CsrLocationDemo
Fork of CsrLocation by
Revision 0:aba381fc8158, committed 2014-03-24
- Comitter:
- zhjcpi
- Date:
- Mon Mar 24 08:23:25 2014 +0000
- Child:
- 1:bbaf9b8d646a
- Commit message:
- First edition for the CsrLocation lib.
Changed in this revision
| CsrLocation.cpp | Show annotated file Show diff for this revision Revisions of this file |
| CsrLocation.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CsrLocation.cpp Mon Mar 24 08:23:25 2014 +0000
@@ -0,0 +1,838 @@
+
+/* CsrLocation class for mbed Microcontroller
+ * Copyright 2014 CSR plc
+ */
+
+
+#include "mbed.h"
+#include "CsrLocation.h"
+
+
+const static CsrUint8 sOspStopReq[] = {0xa0, 0xa2, 0x00, 0x02, 0xcd, 0x10, 0x00, 0xdd, 0xb0, 0xb3};
+const static CsrUint8 sOspVerReq[] = {0xA0, 0xA2, 0x00, 0x02, 0x84, 0x00, 0x00, 0x84, 0xB0, 0xB3};
+const static CsrUint8 sOspLpmReq[] = {0xA0, 0xA2, 0x00, 0x2A, 0xDA, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x01, 0x00, 0x78, 0x00, 0x1E,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x63, 0xB0, 0xB3};
+const static CsrUint8 sOspFpmReq[] = {0xA0, 0xA2, 0x00, 0x03, 0xDA, 0x00, 0x00, 0x00, 0xDA, 0xB0, 0xB3};
+const static CsrUint8 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};
+const static CsrCharString sNmeaSwitch2OspReq[] = "$PSRF100,0,115200,8,1,0*04\r\n";
+
+CsrLocation::CsrLocation(tCsrLocConfig *pLocConfig)
+{
+ memset(&csrLocInst, 0, sizeof(tCsrLocInst));
+ csrLocInst.pSerialDebug = pLocConfig->pSerialDebug;
+ csrLocInst.pSerialLoc = pLocConfig->pSerialLoc;
+ csrLocInst.pPinOnoff = pLocConfig->pPinOnoff;
+ csrLocInst.pPinReset = pLocConfig->pPinReset;
+ csrLocInst.pTimeoutChk = new Timeout();
+
+ csrLocInst.pPinReset->write(1);
+ csrLocInst.pPinOnoff->write(0);
+}
+
+CsrLocation::~CsrLocation(void)
+{
+ if(csrLocInst.pTimeoutChk != NULL)
+ {
+ delete csrLocInst.pTimeoutChk;
+ csrLocInst.pTimeoutChk = NULL;
+ }
+ csrLocInst.pSerialLoc->attach(NULL);
+ csrLocInst.pPinReset->write(0);
+ csrLocInst.pPinOnoff->write(0);
+ memset(&csrLocInst, 0, sizeof(tCsrLocInst));
+
+}
+
+void CsrLocation::CsrLocRegOutput(csr_app_output_callback app_output_cb, csr_app_event_callback app_event_cb)
+{
+ csrLocInst.appOutCb = app_output_cb;
+ csrLocInst.appEventCb = app_event_cb;
+}
+
+void CsrLocation::CsrLocReset(void)
+{
+ _CsrLocHwReset();
+}
+
+void CsrLocation::CsrLocStart(ePowerMode pwrMode)
+{
+ csrLocInst.pwrMode = pwrMode;
+
+ if(csrLocInst.locState == CSR_LOC_STATE_IDLE)
+ {
+ /* Csr Location SDK version */
+ CSR_LOG_INFO("==== CSR LOC SDK version: %s Date: %s ====\r\n", CSR_LOC_SDK_VER, __DATE__ " " __TIME__);
+ /* open UART */
+ CSR_LOG_INFO("Checking OSP protocol...\r\n");
+ csrLocInst.protoState = PROTO_STATE_DET_OSP;
+ csrLocInst.baudRate = BAUDRATE_OSP;
+ _CsrLocUartInit();
+
+ /* trigger on_off */
+ _CsrLocHwOnoff();
+
+ csrLocInst.locState = CSR_LOC_STATE_RUN;
+ }
+ else
+ {
+ CSR_LOG_INFO("Already started.\r\n");
+ }
+}
+
+void CsrLocation::CsrLocUpdate(void)
+{
+ if(csrLocInst.locState == CSR_LOC_STATE_RUN)
+ {
+ /* wait and process uart data */
+ _CsrLocProcessRawStream();
+ }
+}
+
+void CsrLocation::CsrLocStop(void)
+{
+ csrLocInst.pSerialLoc->attach(NULL);
+ CSR_LOG_INFO("Stop command processed.\r\n");
+
+ if(csrLocInst.locState == CSR_LOC_STATE_RUN && csrLocInst.pwrMode == PWR_PTF && csrLocInst.engStatus == ENGINE_STATUS_NOTOK2SEND)
+ {
+ /* in sleep mode, trigger on_off firstly */
+ _CsrLocHwOnoff();
+ wait_ms(500);
+ }
+ _CsrLocSendData(SEND_DATA_TYPE_OSP_STOP_REQ);
+ wait_ms(10);
+ _CsrLocHwReset();
+ csrLocInst.locState = CSR_LOC_STATE_IDLE;
+ csrLocInst.appEventCb(CSR_LOC_EVENT_STOP_RESULT, 0);
+
+}
+
+void CsrLocation::CsrLocLpmGetPos(void)
+{
+ if(csrLocInst.locState == CSR_LOC_STATE_RUN && csrLocInst.pwrMode == PWR_PTF && csrLocInst.engStatus == ENGINE_STATUS_NOTOK2SEND)
+ {
+ CSR_LOG_INFO("LpmGetPos ");
+ _CsrLocHwOnoff();
+ }
+}
+
+void CsrLocation::CsrLocDebugSwitch2Nmea(void)
+{
+ if(csrLocInst.locState == CSR_LOC_STATE_RUN)
+ {
+ _CsrLocSendData(SEND_DATA_TYPE_OSP_SWITCH2NMEA_REQ);
+ wait_ms(200);
+ _CsrLocHwReset();
+ }
+}
+
+void CsrLocation::_CsrLocUartInit(void)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+
+ pLocInst->in = 0;
+ pLocInst->out = 0;
+ memset(pLocInst->serialBuf, 0 , MAX_SERIAL_BUF_LEN);
+ memset(pLocInst->serialPkt, 0 , MAX_SERIAL_PKT_LEN);
+
+ pLocInst->isOspHeader = FALSE;
+ pLocInst->isNmeaHeader = FALSE;
+
+ pLocInst->checksum = 0;
+ pLocInst->msgSize = 0;
+ pLocInst->decodeIndex = 0;
+ pLocInst->protoDetState = STATE_START1;
+ pLocInst->pTimeoutChk->attach(this, &CsrLocation::_CsrLocTimeout, PROTO_CHECK_TIMEOUT);
+
+ pLocInst->pSerialLoc->baud(pLocInst->baudRate);
+ pLocInst->pSerialLoc->attach(this, &CsrLocation::_CsrLocRxHandler );
+}
+
+void CsrLocation::_CsrLocProcessRawStream(void)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+ CsrUint8 data;
+
+ if(pLocInst->in != pLocInst->out)
+ {
+ data = pLocInst->serialBuf[pLocInst->out++];
+ pLocInst->out &= (MAX_SERIAL_BUF_LEN-1);
+ switch(pLocInst->protoState)
+ {
+ case PROTO_STATE_DET_OSP:
+ _CsrLocDetProtoOsp(data);
+ break;
+ case PROTO_STATE_DET_NMEA:
+ _CsrLocDetProtoNmea(data);
+ break;
+ case PROTO_STATE_DET_OSP_FROM_NMEA:
+ _CsrLocDetProtoOsp(data);
+ break;
+ case PROTO_STATE_DET_OK:
+ _CsrLocProcessRawOspStream(data);
+ break;
+ default:
+ /* Discard received data */
+ pLocInst->out = pLocInst->in;
+ break;
+ }
+ }
+ else
+ {
+ wait_ms(1);
+ }
+}
+
+void CsrLocation::_CsrLocDetProtoOsp(CsrUint8 data)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+
+ if(pLocInst->bTimeoutFlag)
+ {
+ /* 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;
+ pLocInst->baudRate = BAUDRATE_NMEA;
+ CSR_LOG_INFO("Checking OSP protocol failed, now check NMEA protocol...\r\n");
+ _CsrLocUartInit();
+ }
+ else
+ {
+ pLocInst->protoState = PROTO_STATE_DET_INVALID;
+ CSR_LOG_INFO("Checking switched OSP protocol failed.\r\n");
+ pLocInst->appEventCb(CSR_LOC_EVENT_START_RESULT, 1);
+ }
+ return;
+ }
+
+ _CsrLocProcessRawOspStream(data);
+}
+
+void CsrLocation::_CsrLocDetProtoNmea(CsrUint8 data)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+
+ if(pLocInst->bTimeoutFlag)
+ {
+ /* Failed to detect OSP and try to detect NMEA */
+ pLocInst->pSerialLoc->attach(NULL);
+ pLocInst->pTimeoutChk->detach();
+ pLocInst->bTimeoutFlag = FALSE;
+ 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;
+ }
+
+ switch (pLocInst->protoDetState)
+ {
+ case STATE_START1:
+ if (NMEA_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ break;
+
+ case STATE_START2:
+ if (NMEA_MSG_HEAD1 == data)
+ {
+ pLocInst->protoDetState = STATE_END1;
+ }
+ else if (NMEA_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_START1;
+ }
+ break;
+ 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);
+
+ 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;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void CsrLocation::_CsrLocProcessRawOspStream(CsrUint8 data)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+
+ switch (pLocInst->protoDetState)
+ {
+ case STATE_START1:
+ if (OSP_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ break;
+
+ case STATE_START2:
+ if (OSP_MSG_HEAD1 == data)
+ {
+ pLocInst->protoDetState = STATE_SIZE1;
+ }
+ else if (OSP_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_START1;
+ }
+ break;
+
+ case STATE_SIZE1:
+ pLocInst->msgSize = data ;
+ pLocInst->msgSize <<= 8; /* high CsrUint8 */
+ pLocInst->protoDetState = STATE_SIZE2;
+ break;
+
+ case STATE_SIZE2:
+ pLocInst->msgSize += data ;
+ if (MAX_SERIAL_PKT_LEN < pLocInst->msgSize || 0 == pLocInst->msgSize)
+ {
+ if (OSP_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_START1;
+ }
+ }
+ else
+ {
+ pLocInst->computedCheckSum = 0;
+ pLocInst->decodeIndex = 0;
+ pLocInst->protoDetState = STATE_PAYLOAD;
+ }
+ break;
+
+ case STATE_PAYLOAD:
+ /* check for a catastrophic error case */
+ if (MAX_SERIAL_PKT_LEN <= pLocInst->decodeIndex)
+ {
+ /* This is really bad. And should never happen since we
+ * gurantee that msgSize is always less than RECEIVE_PACKET_SIZE
+ * Change the state back to STATE_START1 and start over */
+ if (OSP_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_START1;
+ }
+ break;
+ }
+ /* Store the byte */
+ pLocInst->serialPkt[pLocInst->decodeIndex++] = data;
+ pLocInst->computedCheckSum += data;
+
+ /* Check to see if we've read the full payload */
+ if (0 == (--pLocInst->msgSize))
+ {
+ pLocInst->computedCheckSum &= 0x7FFF;
+ pLocInst->protoDetState = STATE_CHECKSUM1;
+ }
+ break;
+
+ case STATE_CHECKSUM1:
+ pLocInst->checksum = data ;
+ pLocInst->checksum <<= 8;
+ pLocInst->protoDetState = STATE_CHECKSUM2;
+ break;
+
+ case STATE_CHECKSUM2:
+ pLocInst->checksum += data;
+ if (pLocInst->computedCheckSum != pLocInst->checksum)
+ {
+ if (OSP_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_START1;
+ }
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_END1;
+ }
+ break;
+
+ case STATE_END1:
+ if (OSP_MSG_TAIL0 == data)
+ {
+ pLocInst->protoDetState = STATE_END2;
+ }
+ else
+ {
+ if (OSP_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_START1;
+ }
+ }
+ break;
+
+ case STATE_END2:
+ if (OSP_MSG_TAIL1 == data)
+ {
+ pLocInst->pTimeoutChk->detach();
+ pLocInst->bTimeoutFlag = FALSE;
+
+ 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();
+ pLocInst->protoDetState = STATE_START1;
+ }
+ else
+ {
+ if (OSP_MSG_HEAD0 == data)
+ {
+ pLocInst->protoDetState = STATE_START2;
+ }
+ else
+ {
+ pLocInst->protoDetState = STATE_START1;
+ }
+ }
+ break;
+ } /* switch. */
+
+}
+
+void CsrLocation::_CsrLocProcessRawOspPkt(void)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+ tOspMsg *pOspMsg;
+ CsrUint32 msgSize;
+ CsrResult result;
+
+ msgSize = _CsrLocCalcMsgSize();
+ if(msgSize > 0)
+ {
+ msgSize += sizeof(tOspMsg);
+ pOspMsg = (tOspMsg *)malloc(msgSize);
+ if(pOspMsg != NULL)
+ {
+ memset(pOspMsg, 0, msgSize);
+ }
+ else
+ {
+ CSR_LOG_INFO("No memory for received OSP message.\r\n");
+ return;
+ }
+ }
+ else
+ {
+ /* discard the unprocessed message */
+ return;
+ }
+
+ result = _CsrLocDecodeOspPkt(pLocInst->serialPkt,pLocInst->decodeIndex, &pOspMsg->msgId, pOspMsg->payload, &pOspMsg->length);
+ if ( CSR_RESULT_SUCCESS == result)
+ {
+ _CsrLocProcessOspPkt(pOspMsg);
+ }
+
+ free(pOspMsg);
+}
+
+CsrUint32 CsrLocation::_CsrLocCalcMsgSize(void)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+ CsrUint8 *ptr = pLocInst->serialPkt;
+ CsrUint32 msgSize = 0;
+ CsrUint32 msgId;
+ CsrUint8 mid, sid = 0;
+
+ mid = BINARY_IMPORT_UINT8(ptr);
+ msgId = OSP_MAKE_MSG_ID(mid,sid);
+
+ if(OSP_MSG_PWR_MODE_RSP == msgId || OSP_MSG_MULTI_CONSTELLATION == msgId)
+ {
+ /* add the sub-id to the message id */
+ sid = BINARY_IMPORT_UINT8(ptr);
+ msgId = OSP_MAKE_MSG_ID(mid,sid);
+ }
+
+ switch(msgId)
+ {
+ case OSP_MSG_OK_TO_SEND:
+ case OSP_MSG_PWR_MODE_FPM_RSP:
+ case OSP_MSG_PWR_MODE_LPM_RSP:
+ case OSP_MSG_HW_CONFIG_REQ :
+ msgSize = sizeof(CsrUint8);
+ break;
+ case OSP_MSG_SW_VERSION :
+ msgSize = MAX_VERSION_LENGTH;
+ break;
+ case OSP_MSG_GEODETIC_NAVIGATION:
+ msgSize = sizeof(tLocPosResp);
+ break;
+ case OSP_MSG_GNSS_SAT_DATA:
+ msgSize = sizeof(CsrUint8);
+ break;
+ case OSP_MSG_GNSS_NAV_DATA:
+ msgSize = sizeof(CsrUint8);
+ break;
+
+ default :
+ msgSize = 0;
+ break;
+ }
+
+ return msgSize;
+}
+
+CsrResult CsrLocation::_CsrLocDecodeOspPkt( CsrUint8 *pPayload, CsrUint32 payloadLen, CsrUint32 *pMsgId, void *pMsgData, CsrUint32 *pMsgLen)
+{
+ CsrResult tRet = CSR_RESULT_SUCCESS;
+ CsrUint8 *ptr = pPayload;
+ CsrUint32 i;
+ CsrUint8 mid, sid = 0;
+
+ mid = BINARY_IMPORT_UINT8(ptr);
+ *pMsgId = OSP_MAKE_MSG_ID(mid,sid);
+ *pMsgLen = 0;
+
+ /* add the sub-id to the message id */
+ if (OSP_MSG_PWR_MODE_RSP == *pMsgId || OSP_MSG_MULTI_CONSTELLATION == *pMsgId)
+ {
+ sid = BINARY_IMPORT_UINT8(ptr);
+ *pMsgId = OSP_MAKE_MSG_ID(mid,sid);
+ }
+
+ switch (*pMsgId)
+ {
+ case OSP_MSG_SW_VERSION: /* 0x06 */
+ *pMsgLen = BINARY_IMPORT_UINT8(ptr);
+ ptr++;
+ if(*pMsgLen >= MAX_VERSION_LENGTH)
+ {
+ tRet = CSR_RESULT_FAILURE;
+ }
+ else
+ {
+ memcpy(pMsgData, ptr, *pMsgLen);
+ }
+ break;
+
+ case OSP_MSG_OK_TO_SEND: /* 0x12 */
+ *((CsrUint8 *)pMsgData) = BINARY_IMPORT_UINT8(ptr);
+ *pMsgLen = sizeof(CsrUint8);
+ break;
+
+ case OSP_MSG_GEODETIC_NAVIGATION: /* 0x29 */
+ {
+ tLocPosResp *pPos = (tLocPosResp*) pMsgData;
+ CsrUint16 valid;
+
+ valid = BINARY_IMPORT_UINT16(ptr);
+ if(valid != 0)
+ {
+ tRet = CSR_RESULT_FAILURE;
+ }
+ else
+ {
+ *pMsgLen = sizeof(*pPos);
+
+ ptr += 2;
+ pPos->gps_week = BINARY_IMPORT_UINT16(ptr);
+ pPos->tow = BINARY_IMPORT_UINT32(ptr);
+ ptr += 12;
+ pPos->lat = (CsrDouble)BINARY_IMPORT_SINT32(ptr);
+ pPos->lat *= 1e-7;
+ pPos->lon = (CsrDouble)BINARY_IMPORT_SINT32(ptr);
+ pPos->lon *= 1e-7;
+ ptr += 4;
+ pPos->alt = (CsrDouble)BINARY_IMPORT_SINT32(ptr);
+ pPos->alt *= 1e-2;
+ }
+ break;
+ }
+
+ case OSP_MSG_GNSS_NAV_DATA: /* 0x43, 0x01 */
+ {
+ tLocSvStatus *pSvStatus = &csrLocInst.svStatus;
+
+ *pMsgLen = sizeof(*pSvStatus);
+
+ ptr += 100;
+ pSvStatus->svUsedInFixMask = BINARY_IMPORT_UINT32(ptr);
+ pSvStatus->sbasSvUsedInFixMask = BINARY_IMPORT_UINT32(ptr);
+ pSvStatus->gloSvUsedInFixMask = BINARY_IMPORT_UINT32(ptr);
+ pSvStatus->qzssSvUsedInFixMask = BINARY_IMPORT_UINT32(ptr);
+ break;
+ }
+
+ case OSP_MSG_GNSS_SAT_DATA: /* 0x43, 0x10 */
+ {
+ tLocSvStatus *pSvStatus = &csrLocInst.svStatus;
+ CsrUint16 week;
+ CsrUint32 tow;
+ CsrUint32 towSubMs;
+ CsrUint8 info;
+ CsrInt32 nMsg = 0;
+ CsrUint16 satInfo;
+ CsrUint16 az;
+ CsrUint16 el;
+ CsrUint16 cno;
+ CsrUint8 gnssType;
+ CsrUint16 index = 0;
+
+ *pMsgLen = sizeof(*pSvStatus);
+
+ week = BINARY_IMPORT_UINT16(ptr);
+ tow = BINARY_IMPORT_UINT32(ptr);
+ towSubMs = BINARY_IMPORT_UINT32(ptr);
+ ptr += 4;
+ info = BINARY_IMPORT_UINT8(ptr);
+
+ nMsg = info & 0x0F;
+ if(nMsg == 1)
+ {
+ memset(pSvStatus, 0, sizeof(tLocSvStatus));
+ pSvStatus->gps_week = week;
+ pSvStatus->tow = tow;
+ pSvStatus->tow_sub_ms = towSubMs;
+ }
+
+ ptr++;
+ for (i = 0; i < GNSS_SAT_DATA_NUM_OF_SATS; i++)
+ {
+ satInfo = BINARY_IMPORT_UINT16(ptr);
+ az = BINARY_IMPORT_UINT16(ptr);
+ el = BINARY_IMPORT_UINT16(ptr);
+ cno = BINARY_IMPORT_UINT16(ptr);
+ ptr += 4;
+
+ gnssType = (CsrUint8)((satInfo>>13)&0x0003);
+ if(0 == gnssType || 1 == gnssType) // GPS, SBAS, QZSS
+ {
+ index = pSvStatus->numOfSVs;
+ if(index < LOC_MAX_GNSS_SVS && cno >0)
+ {
+ pSvStatus->svList[index].prn = (CsrUint8)(satInfo & 0xFF);
+ pSvStatus->svList[index].cno = (CsrFloat)(cno/10.0); // Scale: 10
+ pSvStatus->svList[index].elevation = (CsrFloat)(el/10.0); // Scale: 10
+ pSvStatus->svList[index].azimuth = (CsrFloat)(az/10.0); // Scale: 10
+ pSvStatus->numOfSVs++;
+ pSvStatus->ephemerisMask |= 0x1 << (pSvStatus->svList[index].prn-1); // prn range: 1-32
+ }
+ }
+ else if(2 == gnssType) // GLONASS
+ {
+ index = pSvStatus->numOfGloSVs;
+ if(index < CODEC_GLO_MAX_CHANNELS && cno>0)
+ {
+ CsrInt16 freqChan = (satInfo & 0X1F00)>>8;
+ CsrInt16 slotNum = (satInfo & 0X00FF);
+ if(slotNum > 0)
+ {
+ if(freqChan & 0X0010)
+ {
+ freqChan |= 0xFFE0;
+ }
+ pSvStatus->gloSvList[index].prn = (CsrUint8)(freqChan + LOC_GLO_FREQ_OFFSET);
+ pSvStatus->gloSvList[index].sno = (CsrUint8)slotNum;
+ pSvStatus->gloSvList[index].cno = (CsrFloat)(cno/10.0); // Scale: 10
+ pSvStatus->gloSvList[index].elevation = (CsrFloat)(el/10.0); // Scale: 10
+ pSvStatus->gloSvList[index].azimuth = (CsrFloat)(az/10.0); // Scale: 10
+ pSvStatus->numOfGloSVs++;
+ pSvStatus->gloEphemerisMask |= 0x1 << (pSvStatus->gloSvList[index].prn-LOC_GLO_FREQ_ID_START);
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case OSP_MSG_HW_CONFIG_REQ: /* 0x47 */
+ break;
+
+ case OSP_MSG_PWR_MODE_FPM_RSP: /* 0x5A, 0x00 */
+ break;
+
+ case OSP_MSG_PWR_MODE_LPM_RSP: /* 0x5A, 0x06 */
+ *((CsrUint8 *)pMsgData) = *ptr;
+ *pMsgLen = sizeof(CsrUint8);
+ break;
+
+ default:
+ tRet = CSR_RESULT_FAILURE;
+ break;
+ }
+
+ /* check if length does not match */
+ if(tRet == CSR_RESULT_FAILURE)
+ {
+ *pMsgId = *pMsgLen = 0;
+ }
+
+ return tRet;
+
+} /* CsrUlocCodecSsbDecode() */
+
+void CsrLocation::_CsrLocProcessOspPkt(tOspMsg *pOspMsg)
+{
+ switch(pOspMsg->msgId)
+ {
+ case OSP_MSG_GEODETIC_NAVIGATION:
+ csrLocInst.appOutCb(LOC_OUTPUT_LOCATION, pOspMsg->payload, sizeof(tLocPosResp));
+ break;
+ case OSP_MSG_GNSS_SAT_DATA:
+ break;
+ case OSP_MSG_GNSS_NAV_DATA:
+ csrLocInst.appOutCb(LOC_OUTPUT_SV_STATUS, &csrLocInst.svStatus, sizeof(tLocSvStatus));
+ break;
+ case OSP_MSG_OK_TO_SEND:
+ csrLocInst.engStatus = (*(pOspMsg->payload)) ? ENGINE_STATUS_OK2SEND : ENGINE_STATUS_NOTOK2SEND;
+ CSR_LOG_INFO("Ok to send %u\r\n", csrLocInst.engStatus);
+ break;
+ case OSP_MSG_SW_VERSION:
+ CSR_LOG_INFO("Ver: %s\r\n", pOspMsg->payload);
+ break;
+ case OSP_MSG_HW_CONFIG_REQ:
+ CSR_LOG_INFO("hw config req.\r\n");
+ if(csrLocInst.pwrMode == PWR_PTF)
+ {
+ _CsrLocSendData(SEND_DATA_TYPE_OSP_VER_REQ);
+ _CsrLocSendData(SEND_DATA_TYPE_OSP_LPM_REQ);
+ }
+ else
+ {
+ _CsrLocSendData(SEND_DATA_TYPE_OSP_FPM_REQ);
+ _CsrLocSendData(SEND_DATA_TYPE_OSP_VER_REQ);
+ }
+ break;
+ case OSP_MSG_PWR_MODE_LPM_RSP:
+ CSR_LOG_INFO("lpm response.\r\n");
+ break;
+ case OSP_MSG_PWR_MODE_FPM_RSP:
+ CSR_LOG_INFO("fpm response.\r\n");
+ break;
+ default:
+ CSR_LOG_INFO("Unknown OSP message 0x%lx.\r\n", pOspMsg->msgId);
+ break;
+ }
+}
+
+void CsrLocation::_CsrLocTimeout(void)
+{
+ csrLocInst.bTimeoutFlag = TRUE;
+}
+
+void CsrLocation::_CsrLocRxHandler(void)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+
+ pLocInst->serialBuf[pLocInst->in++] = pLocInst->pSerialLoc->getc();
+ pLocInst->in &= (MAX_SERIAL_BUF_LEN-1);
+ if(pLocInst->in == pLocInst->out)
+ {
+ CSR_LOG_INFO("rx overwritten.\r\n");
+ }
+}
+
+void CsrLocation::_CsrLocSendData(eSendDataType type)
+{
+ tCsrLocInst *pLocInst = &csrLocInst;
+ CsrUint32 i, size;
+ const CsrUint8 *pData;
+
+ switch(type)
+ {
+ case SEND_DATA_TYPE_OSP_STOP_REQ:
+ pData = sOspStopReq;
+ size = sizeof(sOspStopReq);
+ break;
+ case SEND_DATA_TYPE_OSP_VER_REQ:
+ pData = sOspVerReq;
+ size = sizeof(sOspVerReq);
+ break;
+ case SEND_DATA_TYPE_OSP_LPM_REQ:
+ pData = sOspLpmReq;
+ size = sizeof(sOspLpmReq);
+ break;
+ case SEND_DATA_TYPE_OSP_FPM_REQ:
+ pData = sOspFpmReq;
+ size = sizeof(sOspFpmReq);
+ break;
+ case SEND_DATA_TYPE_OSP_SWITCH2NMEA_REQ:
+ pData = sOspSwitch2NmeaReq;
+ size = sizeof(sOspSwitch2NmeaReq);
+ break;
+ case SEND_DATA_TYPE_NMEA_SWITCH2OSP_REQ:
+ pData = (const CsrUint8 *)sNmeaSwitch2OspReq;
+ size = strlen(sNmeaSwitch2OspReq);
+ break;
+
+ default:
+ pData = NULL;
+ }
+
+ if(pData != NULL)
+ {
+ for (i = 0; i < size; i++)
+ {
+ while(pLocInst->pSerialLoc->writeable() == 0) {}
+ pLocInst->pSerialLoc->putc(pData[i]);
+ }
+ }
+}
+
+void CsrLocation::_CsrLocHwOnoff(void)
+{
+ csrLocInst.pPinOnoff->write(1);
+ wait_ms(10);
+ csrLocInst.pPinOnoff->write(0);
+ CSR_LOG_INFO("Onoff pulse given.\r\n");
+}
+
+void CsrLocation::_CsrLocHwReset(void)
+{
+ csrLocInst.pPinReset->write(1);
+ wait_ms(10);
+ csrLocInst.pPinReset->write(0);
+ CSR_LOG_INFO("Reset pulse given.\r\n");
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CsrLocation.h Mon Mar 24 08:23:25 2014 +0000
@@ -0,0 +1,444 @@
+
+/* CsrLocation class for mbed Microcontroller
+ * Copyright 2014 CSR plc
+ */
+
+
+#ifndef CSRLOCATION_H
+#define CSRLOCATION_H
+
+
+#define CSR_LOC_SDK_VER "CSR-LOC-SDK-0.5"
+
+/* Data type definitions */
+#undef FALSE
+#define FALSE (0)
+
+#undef TRUE
+#define TRUE (1)
+
+/* Unsigned fixed width types */
+typedef unsigned char CsrUint8;
+typedef unsigned short CsrUint16;
+typedef unsigned int CsrUint32;
+
+/* Signed fixed width types */
+typedef signed char CsrInt8;
+typedef signed short CsrInt16;
+typedef signed int CsrInt32;
+
+/* Boolean */
+typedef CsrUint8 CsrBool;
+
+/* String types */
+typedef char CsrCharString;
+typedef CsrUint8 CsrUtf8String;
+typedef CsrUint16 CsrUtf16String; /* 16-bit UTF16 strings */
+typedef CsrUint32 CsrUint24;
+
+/*
+ * Floating point
+ *
+ * Note: If a given compiler does not support floating point, it is
+ * OK to omit these definitions; alternative versions of the code using
+ * these types may be available. Consult the relevant documentation
+ * or the customer support group for information on this.
+ */
+typedef float CsrFloat;
+typedef double CsrDouble;
+
+typedef CsrUint16 CsrResult;
+#define CSR_RESULT_SUCCESS ((CsrResult) 0x0000)
+#define CSR_RESULT_FAILURE ((CsrResult) 0xFFFF)
+/* The end of data type definitions */
+
+/* OSP protocol related definitions */
+#define MAX_VERSION_LENGTH 80
+
+/* OSP message header */
+#define OSP_MSG_HEAD0 (0xA0)
+#define OSP_MSG_HEAD1 (0xA2)
+/* OSP message footer */
+#define OSP_MSG_TAIL0 (0xB0)
+#define OSP_MSG_TAIL1 (0xB3)
+
+/* NMEA message header */
+#define NMEA_MSG_HEAD0 ('$')
+#define NMEA_MSG_HEAD1 ('G')
+/* NMEA message footer */
+#define NMEA_MSG_TAIL0 ('*')
+
+#define CSR_SWAPIN16(bytestream) (((CsrUint16)*((bytestream)+0) << 8) | ((CsrUint16)*((bytestream)+1)))
+
+#define CSR_SWAPIN32(bytestream)\
+ ( ((CsrUint32)*((bytestream)+0) << 24)\
+ | ((CsrUint32)*((bytestream)+1) << 16)\
+ | ((CsrUint32)*((bytestream)+2) << 8)\
+ | ((CsrUint32)*((bytestream)+3) ))
+
+
+/* import macros for little endian: */
+/* NOTE: must use {} around these macros when calling in a loop */
+#define BINARY_IMPORT_UINT8(bytestream) ( *((bytestream)++))
+#define BINARY_IMPORT_UINT16(bytestream) ((CsrUint16) CSR_SWAPIN16((bytestream))); bytestream+=2
+#define BINARY_IMPORT_UINT32(bytestream) ((CsrUint32) CSR_SWAPIN32((bytestream))); bytestream+=4
+#define BINARY_IMPORT_SINT32(bytestream) ((CsrInt32) CSR_SWAPIN32((bytestream))); bytestream+=4
+
+
+#define OSP_MAKE_MSG_ID(mid, sid) ((((mid) & 0xFF) << 8) | ((sid) & 0xFF))
+
+#define OSP_MSG_SW_VERSION OSP_MAKE_MSG_ID(0x06, 0x0)
+#define OSP_MSG_OK_TO_SEND OSP_MAKE_MSG_ID(0x12, 0x0)
+#define OSP_MSG_GEODETIC_NAVIGATION OSP_MAKE_MSG_ID(0x29, 0x0)
+#define OSP_MSG_MULTI_CONSTELLATION OSP_MAKE_MSG_ID(0x43, 0x0)
+ #define OSP_MSG_GNSS_NAV_DATA OSP_MAKE_MSG_ID(0x43, 0x01)
+ #define OSP_MSG_GNSS_SAT_DATA OSP_MAKE_MSG_ID(0x43, 0x10)
+#define OSP_MSG_HW_CONFIG_REQ OSP_MAKE_MSG_ID(0x47, 0x0)
+#define OSP_MSG_PWR_MODE_RSP OSP_MAKE_MSG_ID(0x5A, 0x0)
+ #define OSP_MSG_PWR_MODE_FPM_RSP OSP_MAKE_MSG_ID(0x5A, 0x0)
+ #define OSP_MSG_PWR_MODE_LPM_RSP OSP_MAKE_MSG_ID(0x5A, 0x6)
+
+
+#define GNSS_SAT_DATA_NUM_OF_SATS (15)
+#define CODEC_GLO_MAX_CHANNELS (14)
+/* The end of OSP protocol definitions */
+
+
+#define LOC_MAX_GNSS_SVS (32)
+#define LOC_GLO_FREQ_OFFSET (77)
+#define LOC_GLO_FREQ_ID_START (70)
+#define LOC_GLO_FREQ_ID_END (83)
+#define LOC_NUM_OF_GLO_FREQ_CHANNELS (1+LOC_GLO_FREQ_ID_END-LOC_GLO_FREQ_ID_START)
+
+#define MAX_PORT_NUM_STRING_LENGTH (16)
+#define MAX_SERIAL_BUF_LEN (2048)
+#define MAX_SERIAL_PKT_LEN (512)
+
+#define BAUDRATE_NMEA 4800
+#define BAUDRATE_OSP 115200
+
+#define PROTO_CHECK_TIMEOUT (2.0)
+
+/** Indicates the outputted location information */
+#define LOC_OUTPUT_LOCATION (1)
+/* Indicates the outputted sv status information */
+#define LOC_OUTPUT_SV_STATUS (2)
+
+#define CSR_LOG_INFO(...) \
+{\
+ if(csrLocInst.pSerialDebug != NULL)\
+ {\
+ (csrLocInst.pSerialDebug->printf(__VA_ARGS__));\
+ }\
+}
+
+/** Location enent definitions */
+typedef enum
+{
+ /** Start result event */
+ CSR_LOC_EVENT_START_RESULT,
+ /** Stop result event */
+ CSR_LOC_EVENT_STOP_RESULT,
+}eCsrLocEventType;
+
+/** Power mode selection */
+typedef enum
+{
+ /** full power mode */
+ PWR_FULL,
+ /** Low power push to fix mode */
+ PWR_PTF,
+}ePowerMode;
+
+/* Protocol detection state */
+typedef enum
+{
+ STATE_START1, /* Indicates the first byte of the OSP or NMEA message header*/
+ STATE_START2, /* Indicates the second byte of the OSP or NMEA message header */
+ STATE_SIZE1, /* Indicates the first byte of the OSP message length */
+ STATE_SIZE2, /* Indicates the second byte of the OSP message length */
+ STATE_PAYLOAD, /* Indicates the start of payload of the OSP message */
+ STATE_CHECKSUM1, /* Indicates the first byte of the OSP message checksum */
+ STATE_CHECKSUM2, /* Indicates the second byte of the OSP message checksum */
+ STATE_END1, /* Indicates the first byte of the OSP or NMEA message footer */
+ STATE_END2 /* Indicates the second byte of the OSP message footer */
+}eProtoDetState;
+
+/* Csr Location state */
+typedef enum
+{
+ CSR_LOC_STATE_IDLE,
+ CSR_LOC_STATE_RUN,
+}eCsrLocState;
+
+/* Locatin chip protocol detection state */
+typedef enum
+{
+ PROTO_STATE_DET_INVALID = 0,
+ PROTO_STATE_DET_OSP,
+ PROTO_STATE_DET_NMEA,
+ PROTO_STATE_SWI_OSP_FROM_NMEA,
+ PROTO_STATE_DET_OSP_FROM_NMEA,
+ PROTO_STATE_DET_OK,
+}eProtoState;
+
+/* Locaiton chip status */
+typedef enum
+{
+ /* Location chip is going to hibernation mode and cannot accept message any more */
+ ENGINE_STATUS_NOTOK2SEND,
+ /* Locaitn come back from hibernation mode and can accept message now */
+ ENGINE_STATUS_OK2SEND
+}eEngineStatus;
+
+/* OSP data type to be sent to location chip */
+typedef enum
+{
+ SEND_DATA_TYPE_OSP_STOP_REQ,
+ SEND_DATA_TYPE_OSP_VER_REQ,
+ SEND_DATA_TYPE_OSP_LPM_REQ,
+ SEND_DATA_TYPE_OSP_FPM_REQ,
+ SEND_DATA_TYPE_OSP_SWITCH2NMEA_REQ,
+ SEND_DATA_TYPE_NMEA_SWITCH2OSP_REQ
+}eSendDataType;
+
+/** Structure to hold Position Response Message Information. */
+typedef struct LocPosResp
+{
+ /** Week part of GPS time */
+ CsrUint16 gps_week;
+ /** Time of second part of GPS time */
+ CsrUint32 tow;
+ /** Latitude */
+ CsrDouble lat;
+ /** Longitude */
+ CsrDouble lon;
+ /** Altitude */
+ CsrDouble alt;
+} tLocPosResp;
+
+/** Structure to hold Satellite Information. */
+typedef struct LocSvInfo
+{
+ /** Prn or svId */
+ CsrUint8 prn;
+ /** The ratio of carrier and noise */
+ CsrFloat cno;
+ /** elevation */
+ CsrFloat elevation;
+ /** azimuth */
+ CsrFloat azimuth;
+ /** satellite state */
+ CsrUint16 state;
+} tLocSvInfo;
+
+/** Structure to hold Satellite Information for GLONASS */
+typedef struct LocGloSvInfo
+{
+ /** Prn or svId */
+ CsrUint8 prn;
+ /** Slot number */
+ CsrUint8 sno;
+ /** The ratio of carrier and noise */
+ CsrFloat cno;
+ /** elevation */
+ CsrFloat elevation;
+ /** azimuth */
+ CsrFloat azimuth;
+ /** satellite state */
+ CsrUint16 state;
+} tLocGloSvInfo;
+
+/** Structure to hold Satellite Status Information. */
+typedef struct LocSvStatus
+{
+ /** Week part of GPS time */
+ CsrUint16 gps_week;
+ /** Time of second part of GPS time */
+ CsrUint32 tow;
+ /** Time of millisecond part of GPS time */
+ CsrUint32 tow_sub_ms;
+
+ /**Number of GPS SVs currently visible **/
+ CsrUint8 numOfSVs;
+ /**Number of GLONASS SVs currently visible **/
+ CsrUint8 numOfGloSVs;
+ /** GPS SVs information */
+ tLocSvInfo svList[LOC_MAX_GNSS_SVS];
+ /** GLONASS SVs information */
+ tLocGloSvInfo gloSvList[LOC_NUM_OF_GLO_FREQ_CHANNELS];
+ /** Bit mask indicating which SVs have ephemeris data **/
+ CsrUint32 ephemerisMask;
+ /** Bit mask indicating which GLONASS SVs have ephemeris data **/
+ CsrUint32 gloEphemerisMask;
+ /** Bit mask indicating which SVs were used in latest sent fix **/
+ CsrUint32 svUsedInFixMask;
+ /** Bit mask indicating which GLONASS SVs were used in latest sent fix **/
+ CsrUint32 gloSvUsedInFixMask;
+ /** Bit mask indicating which QZSS SVs were used in latest sent fix **/
+ CsrUint32 qzssSvUsedInFixMask;
+ /** Bit mask indicating which SBAS SVs were used in latest sent fix **/
+ CsrUint32 sbasSvUsedInFixMask;
+} tLocSvStatus;
+
+
+/** Applicaiton register this out callback function and CsrLocaiton class will pass outputted information to application */
+typedef void (*csr_app_output_callback)(CsrUint32 msgId, void * const pMsgData, CsrUint32 msgLength);
+
+/** Applicaiton register this event callback function and CsrLocaiton class will pass internal porcessing event to application */
+typedef void (*csr_app_event_callback)(eCsrLocEventType event, CsrUint32 data);
+
+/** tCsrLocConfig structure
+ * Application needs to decides and pass the configuration into CsrLocation class.
+ */
+typedef struct CsrLocConfig
+{
+ /** Debug serial port to print debug information */
+ Serial *pSerialDebug;
+ /** location serail port to communicate between mbed host side and location chip */
+ Serial *pSerialLoc;
+ /** GPIO pin to control location chip on, a rising edge is uset to activate location chip. Please note, before activate chip, reset pin should be pull high */
+ DigitalOut *pPinOnoff;
+ /** GPIO pin to control location chip reset, low level will keep location chip in hibernation state and high level will permit location chip to be activated */
+ DigitalOut *pPinReset;
+}tCsrLocConfig;
+
+/* General OSP mesasge format */
+typedef struct OspMsg
+{
+ CsrUint32 msgId;
+ CsrUint32 length;
+ CsrUint8 payload[4];
+} tOspMsg;
+
+/* keep the internal data of CsrLocation class */
+typedef struct CsrLocInst
+{
+ CsrBool bStopFlag;
+
+ eCsrLocState locState;
+ eProtoState protoState;
+ ePowerMode pwrMode;
+ CsrUint32 baudRate;
+ CsrBool isOspHeader;
+ CsrBool isNmeaHeader;
+ CsrInt32 computedCheckSum;
+ CsrInt32 checksum;
+ CsrInt32 msgSize;
+ CsrInt32 decodeIndex;
+ eProtoDetState protoDetState;
+ Timeout *pTimeoutChk; /* timeout process */
+ CsrBool bTimeoutFlag;
+ eEngineStatus engStatus;
+
+ tLocSvStatus svStatus; /* 2 kind of messages contribute the svStaus */
+
+ Serial *pSerialDebug;
+ Serial *pSerialLoc;
+ DigitalOut *pPinOnoff;
+ DigitalOut *pPinReset;
+
+ CsrUint8 serialBuf[MAX_SERIAL_BUF_LEN]; /* buffer the serial data from uart callback function */
+ CsrUint8 serialPkt[MAX_SERIAL_PKT_LEN]; /* decoded osp data */
+ CsrUint16 in;
+ CsrUint16 out;
+
+ csr_app_output_callback appOutCb;
+ csr_app_event_callback appEventCb;
+}tCsrLocInst;
+
+/** CsrLocation class.
+ * A location interface to control location chip and get position and satellite information.
+ */
+class CsrLocation
+{
+public:
+ /** Constructor: CsrLocaiton
+ * Create the CsrLocation, accept specified configuration
+ * @param pLocConfig Configuration including debug serial port, location communication serail port, onoff pin, reset pin
+ */
+ CsrLocation(tCsrLocConfig *pLocConfig);
+
+ /** Destructor: CsrLocation
+ * Free allocated resource
+ */
+ ~CsrLocation();
+
+ /** Register output callback and enent callback functions
+ * @param app_output_cb CsrLocation class output the loaction and satellite information to application
+ * @param app_event_cb CsrLocation class output the start and stop result to application
+ */
+ void CsrLocRegOutput(csr_app_output_callback app_output_cb, csr_app_event_callback app_event_cb);
+
+ /** hw reset to get location chip into hibernation mode */
+ void CsrLocReset(void);
+
+ /** Start location request, activate location chip */
+ void CsrLocStart(ePowerMode pwrMode);
+
+ /** Process location data from chip and update location and satellite information */
+ void CsrLocUpdate(void);
+
+ /** Stop location request, get location chip into hibernation mode */
+ void CsrLocStop(void);
+
+ /** Speical for low power PTF mode.
+ * During low power PTF mode, after reporting position, chip will go to hibernation mode automatically.
+ * After 30 seconds, chip will recover and report position again. Then chip will go to hibernation mode again.
+ * During the hibernation, application can call CsrLocLpmGetPos to get position immediately and no need to wait for the whole interval.
+ */
+ void CsrLocLpmGetPos(void);
+
+ /* A debug interface to switch location chip protocol from OSP at 115200bps to NMEA at 4800bps */
+ void CsrLocDebugSwitch2Nmea(void);
+
+private:
+ /* Internal kept data */
+ tCsrLocInst csrLocInst;
+
+ /* Initialize the serial port and open it */
+ void _CsrLocUartInit(void);
+
+ /* Process the raw stream from location seraial port */
+ void _CsrLocProcessRawStream(void);
+
+ /* Detect the OSP protocol outputted from location serial port */
+ void _CsrLocDetProtoOsp(CsrUint8 data);
+
+ /* Detect the NMEA protocol outputted from location serial port */
+ void _CsrLocDetProtoNmea(CsrUint8 data);
+
+ /* Process the raw OSP stream, remove the OSP header, size, check sum, and save the OSP data into interal buffer */
+ void _CsrLocProcessRawOspStream(CsrUint8 data);
+
+ /* Process the saved OSP data and decode them */
+ void _CsrLocProcessRawOspPkt(void);
+
+ /* Calculate the OSP message size to allcate buffer to save the decoded OSP data */
+ CsrUint32 _CsrLocCalcMsgSize(void);
+
+ /* Decode OSP data into pakcet data structure */
+ CsrResult _CsrLocDecodeOspPkt( CsrUint8 *payload, CsrUint32 payload_length, CsrUint32 *message_id, void *message_structure, CsrUint32 *message_length);
+
+ /* Process the decode OSP packet and pass to application when needed */
+ void _CsrLocProcessOspPkt(tOspMsg *pOspMsg);
+
+ /* Timeout process, such as detect OSP and NMEA protocol */
+ void _CsrLocTimeout(void);
+
+ /* Location serial port data recevier */
+ void _CsrLocRxHandler(void);
+
+ /* Send special OSP messges to location chip */
+ void _CsrLocSendData(eSendDataType type);
+
+ /* Trigger a pulse on the onoff pin */
+ void _CsrLocHwOnoff(void);
+
+ /* Trigger a reset on the reset pin */
+ void _CsrLocHwReset(void);
+};
+
+
+
+#endif /* CSRLOCATION_H */

GPS mbed Shield