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 3:71690f7bb480, committed 2014-05-21
- Comitter:
- zhjcpi
- Date:
- Wed May 21 08:55:55 2014 +0000
- Parent:
- 2:d4fe184925f2
- Child:
- 4:0d9b711fb646
- Commit message:
- Unify code for different platform.
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 |
--- 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;
}
--- a/CsrLocation.h Wed Mar 26 09:16:55 2014 +0000
+++ b/CsrLocation.h Wed May 21 08:55:55 2014 +0000
@@ -14,6 +14,31 @@
#define CSR_RESULT_SUCCESS ((CsrResult) 0x0000)
#define CSR_RESULT_FAILURE ((CsrResult) 0xFFFF)
+#ifdef TARGET_LPC1768
+#define PINMAP_UART_DEBUG_TX USBTX
+#define PINMAP_UART_DEBUG_RX USBRX
+#define PINMAP_UART_LOC_TX D8
+#define PINMAP_UART_LOC_RX D9
+#define PINMAP_GPIO_LOC_ONOFF D11
+#define PINMAP_GPIO_LOC_RESET D12
+#define LOC_LED1 LED1
+#define LOC_LED2 LED2
+#define DBG_SERIAL_TYPE RawSerial
+#define LOC_SERIAL_TYPE RawSerial
+#elif defined(TARGET_LPC1549) || defined(TARGET_NUCLEO_F103RB)
+#define PINMAP_UART_DEBUG_TX D1
+#define PINMAP_UART_DEBUG_RX D0
+#define PINMAP_UART_LOC_TX D8
+#define PINMAP_UART_LOC_RX D2
+#define PINMAP_GPIO_LOC_ONOFF D3
+#define PINMAP_GPIO_LOC_RESET D4
+#define LOC_LED1 LED1
+#define LOC_LED2 LED2
+#define DBG_SERIAL_TYPE Serial
+#define LOC_SERIAL_TYPE RawSerial
+#endif
+
+
/* OSP protocol related definitions */
#define MAX_VERSION_LENGTH 80
@@ -86,6 +111,9 @@
/* Indicates the outputted sv status information */
#define LOC_OUTPUT_SV_STATUS (2)
+#if 0
+#define CSR_LOG_INFO printf
+#else
#define CSR_LOG_INFO(...) \
{\
if(csrLocInst.pSerialDebug != NULL)\
@@ -93,6 +121,7 @@
(csrLocInst.pSerialDebug->printf(__VA_ARGS__));\
}\
}
+#endif
/** Location enent definitions */
typedef enum
@@ -112,6 +141,15 @@
PWR_PTF,
}ePowerMode;
+/** Power mode selection */
+typedef enum
+{
+ /** NMEA protocol */
+ PROTO_NMEA,
+ /** OSP protocol */
+ PROTO_OSP,
+}eProto;
+
/* Protocol detection state */
typedef enum
{
@@ -139,8 +177,10 @@
PROTO_STATE_DET_INVALID = 0,
PROTO_STATE_DET_OSP,
PROTO_STATE_DET_NMEA,
- PROTO_STATE_SWI_OSP_FROM_NMEA,
+// PROTO_STATE_SWI_OSP_FROM_NMEA,
PROTO_STATE_DET_OSP_FROM_NMEA,
+// PROTO_STATE_SWI_NMEA_FROM_OSP,
+ PROTO_STATE_DET_NMEA_FROM_OSP,
PROTO_STATE_DET_OK,
}eProtoState;
@@ -161,16 +201,26 @@
SEND_DATA_TYPE_OSP_LPM_REQ,
SEND_DATA_TYPE_OSP_FPM_REQ,
SEND_DATA_TYPE_OSP_SWITCH2NMEA_REQ,
- SEND_DATA_TYPE_NMEA_SWITCH2OSP_REQ
+ SEND_DATA_TYPE_NMEA_SWITCH2OSP_REQ,
+ SEND_DATA_TYPE_NMEA_STOP_REQ
}eSendDataType;
-/** Structure to hold Position Response Message Information. */
-typedef struct LocPosResp
+typedef struct GpsTime
{
/** Week part of GPS time */
uint16_t gps_week;
/** Time of second part of GPS time */
uint32_t tow;
+}tGpsTime;
+
+/** Structure to hold Position Response Message Information. */
+typedef struct LocPosResp
+{
+ union
+ {
+ tGpsTime gpsTime;
+ float utcTime;
+ }u;
/** Latitude */
double lat;
/** Longitude */
@@ -256,9 +306,9 @@
typedef struct CsrLocConfig
{
/** Debug serial port to print debug information */
- RawSerial *pSerialDebug;
+ DBG_SERIAL_TYPE *pSerialDebug;
/** location serail port to communicate between mbed host side and location chip */
- RawSerial *pSerialLoc;
+ LOC_SERIAL_TYPE *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 */
@@ -280,6 +330,7 @@
bool bPwrModeRsp;
bool bVerRsp;
+ eProto proto;
eCsrLocState locState;
eProtoState protoState;
ePowerMode pwrMode;
@@ -295,8 +346,8 @@
tLocSvStatus svStatus; /* 2 kind of messages contribute the svStaus */
- RawSerial *pSerialDebug;
- RawSerial *pSerialLoc;
+ DBG_SERIAL_TYPE *pSerialDebug;
+ LOC_SERIAL_TYPE *pSerialLoc;
DigitalOut *pPinOnoff;
DigitalOut *pPinReset;
@@ -336,7 +387,7 @@
void CsrLocReset(void);
/** Start location request, activate location chip */
- void CsrLocStart(ePowerMode pwrMode);
+ void CsrLocStart(ePowerMode pwrMode, eProto proto);
/** Process location data from chip and update location and satellite information */
void CsrLocUpdate(void);
@@ -364,15 +415,21 @@
/* Process the raw stream from location seraial port */
void _CsrLocProcessRawStream(void);
- /* Detect the OSP protocol outputted from location serial port */
- void _CsrLocDetProtoOsp(uint8_t data);
+ /* Detect the OSP protocol detection timeout */
+ void _CsrLocDetProtoOspTimeout(void);
/* Detect the NMEA protocol outputted from location serial port */
- void _CsrLocDetProtoNmea(uint8_t data);
+ void _CsrLocDetProtoNmeaTimeout(void);
+
+ /* Process the raw NMEA stream, remove the NMEA header, tail, and save the NMEA data into interal buffer */
+ void _CsrLocProcessRawNmeaStream(uint8_t data);
/* Process the raw OSP stream, remove the OSP header, size, check sum, and save the OSP data into interal buffer */
void _CsrLocProcessRawOspStream(uint8_t data);
+ /* Process the saved nmea data and decode them */
+ void _CsrLocProcessRawNmeaPkt(void);
+
/* Process the saved OSP data and decode them */
void _CsrLocProcessRawOspPkt(void);
@@ -404,3 +461,4 @@
#endif /* CSRLOCATION_H */
+

GPS mbed Shield