Qualcomm Technologies International, Ltd. / CsrLocation

Dependents:   CsrLocationDemo CsrLocationDemo

Fork of CsrLocation by jie zhao

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CsrLocation.h Source File

CsrLocation.h

00001 /* CSRLocation class for mbed Microcontroller
00002  * Copyright 2014 CSR plc
00003  */
00004 
00005 #ifndef CSRLOCATION_H
00006 #define CSRLOCATION_H
00007 
00008 #include <GPSProviderImplBase.h>
00009 
00010 #define CSR_LOC_SDK_VER                 "CSR-LOC-SDK-0.5"
00011 
00012 typedef uint16_t CsrResult;
00013 #define CSR_RESULT_SUCCESS  ((CsrResult) 0x0000)
00014 #define CSR_RESULT_FAILURE  ((CsrResult) 0xFFFF)
00015 
00016 /* Time related definitions */
00017 #define CSR_ULOC_UTC_GPS_OFFSET_MS      ((uint64_t)(315964800000LL))
00018 #define CSR_ULOC_SEC_IN_WEEK_MS         (604800000)
00019 #define CSR_ULOC_UTC_LEAP_OFFSET_MS     (15000)
00020 
00021 
00022 /* IOCTL commands */
00023 #define CSR_IOCTL_CMD_WAKEUP_STATUS     (0x01)
00024 #define CSR_IOCTL_CMD_ONOFF_ON          (0x02)
00025 #define CSR_IOCTL_CMD_ONOFF_OFF         (0x03)
00026 #define CSR_IOCTL_CMD_ONOFF_PULSE       (0x04)
00027 #define CSR_IOCTL_CMD_RESET_ON          (0x05)
00028 #define CSR_IOCTL_CMD_RESET_OFF         (0x06)
00029 #define CSR_IOCTL_CMD_PROTO_NMEA        (0x07)
00030 #define CSR_IOCTL_CMD_PROTO_OSP         (0x08)
00031 
00032 
00033 /* OSP protocol related definitions */
00034 #define MAX_VERSION_LENGTH 80
00035 
00036 /* OSP message header */
00037 #define OSP_MSG_HEAD0                   (0xA0)
00038 #define OSP_MSG_HEAD1                   (0xA2)
00039 /* OSP message footer */
00040 #define OSP_MSG_TAIL0                   (0xB0)
00041 #define OSP_MSG_TAIL1                   (0xB3)
00042 
00043 /* NMEA message header */
00044 #define NMEA_MSG_HEAD0                  ('$')
00045 #define NMEA_MSG_HEAD1                  ('G')
00046 /* NMEA message footer */
00047 #define NMEA_MSG_TAIL0                  ('*')
00048 
00049 #define CSR_SWAPIN16(bytestream) (((uint16_t)*((bytestream) + 0) << 8) | ((uint16_t)*((bytestream) + 1)))
00050 
00051 #define CSR_SWAPIN32(bytestream)             \
00052     (((uint32_t)*((bytestream) + 0) << 24)   \
00053      | ((uint32_t)*((bytestream) + 1) << 16) \
00054      | ((uint32_t)*((bytestream) + 2) << 8)  \
00055      | ((uint32_t)*((bytestream) + 3)))
00056 
00057 
00058 /* import macros for little endian: */
00059 /* NOTE: must use {} around these macros when calling in a loop */
00060 #define BINARY_IMPORT_UINT8(bytestream) (*((bytestream)++))
00061 #define BINARY_IMPORT_UINT16(bytestream) ((uint16_t) CSR_SWAPIN16((bytestream))); bytestream += 2
00062 #define BINARY_IMPORT_UINT32(bytestream) ((uint32_t) CSR_SWAPIN32((bytestream))); bytestream += 4
00063 #define BINARY_IMPORT_SINT32(bytestream) ((int32_t)  CSR_SWAPIN32((bytestream))); bytestream += 4
00064 
00065 #define OSP_MAKE_MSG_ID(mid, sid) ((((mid) & 0xFF) << 8) | ((sid) & 0xFF))
00066 
00067 #define OSP_MSG_SW_VERSION              OSP_MAKE_MSG_ID(0x06, 0x0)
00068 #define OSP_MSG_OK_TO_SEND              OSP_MAKE_MSG_ID(0x12, 0x0)
00069 #define OSP_MSG_GEODETIC_NAVIGATION     OSP_MAKE_MSG_ID(0x29, 0x0)
00070 #define OSP_MSG_MULTI_CONSTELLATION     OSP_MAKE_MSG_ID(0x43, 0x0)
00071     #define OSP_MSG_GNSS_NAV_DATA       OSP_MAKE_MSG_ID(0x43, 0x01)
00072     #define OSP_MSG_GNSS_SAT_DATA       OSP_MAKE_MSG_ID(0x43, 0x10)
00073 #define OSP_MSG_HW_CONFIG_REQ           OSP_MAKE_MSG_ID(0x47, 0x0)
00074 #define OSP_MSG_PWR_MODE_RSP            OSP_MAKE_MSG_ID(0x5A, 0x0)
00075     #define OSP_MSG_PWR_MODE_FPM_RSP    OSP_MAKE_MSG_ID(0x5A, 0x0)
00076     #define OSP_MSG_PWR_MODE_LPM_RSP    OSP_MAKE_MSG_ID(0x5A, 0x6)
00077 
00078 
00079 #define GNSS_SAT_DATA_NUM_OF_SATS       (15)
00080 #define CODEC_GLO_MAX_CHANNELS          (14)
00081 /* The end of OSP protocol definitions */
00082 
00083 
00084 #define LOC_MAX_GNSS_SVS                (32)
00085 #define LOC_GLO_FREQ_OFFSET             (77)
00086 #define LOC_GLO_FREQ_ID_START           (70)
00087 #define LOC_GLO_FREQ_ID_END             (83)
00088 #define LOC_NUM_OF_GLO_FREQ_CHANNELS    (1 + LOC_GLO_FREQ_ID_END - LOC_GLO_FREQ_ID_START)
00089 
00090 #define MAX_PORT_NUM_STRING_LENGTH      (16)
00091 #define MAX_SERIAL_BUF_LEN              (2048)
00092 #define MAX_SERIAL_PKT_LEN              (512)
00093 
00094 #define BAUDRATE_NMEA                   4800
00095 #define BAUDRATE_OSP                    115200
00096 
00097 #define PROTO_CHECK_TIMEOUT             (2.0)
00098 
00099 /** Indicates the outputted location information */
00100 #define LOC_OUTPUT_LOCATION             (1)
00101 /* Indicates the outputted sv status information */
00102 #define LOC_OUTPUT_SV_STATUS            (2)
00103 #define LOC_OUTPUT_NMEA                 (3)
00104 
00105 #if 0
00106 #define CSR_LOG_INFO    printf
00107 #else
00108 #define CSR_LOG_INFO(...) {                             \
00109         if (pSerialDebug != NULL) {                     \
00110             (pSerialDebug->printf(__VA_ARGS__));        \
00111         }                                               \
00112     }
00113 #endif // if 0
00114 
00115 /** Location event definitions */
00116 typedef enum {
00117     /** Start result event */
00118     CSR_LOC_EVENT_START_RESULT,
00119     /** Stop result event */
00120     CSR_LOC_EVENT_STOP_RESULT,
00121 } eCsrLocEventType;
00122 
00123 /** Power mode selection */
00124 typedef enum {
00125     /** full power mode */
00126     PWR_FULL,
00127     /** Low power push to fix mode */
00128     PWR_PTF,
00129 } ePowerMode;
00130 
00131 /** Power mode selection */
00132 typedef enum {
00133     /** NMEA protocol */
00134     PROTO_NMEA,
00135     /** OSP protocol */
00136     PROTO_OSP,
00137 } eProto;
00138 
00139 /* Protocol detection state */
00140 typedef enum {
00141     STATE_START1,       /* Indicates the first byte of the OSP or NMEA message header*/
00142     STATE_START2,       /* Indicates the second byte of the OSP or NMEA message header */
00143     STATE_SIZE1,        /* Indicates the first byte of the OSP message length */
00144     STATE_SIZE2,        /* Indicates the second byte of the OSP message length  */
00145     STATE_PAYLOAD,      /* Indicates the start of payload of the OSP message */
00146     STATE_CHECKSUM1,    /* Indicates the first byte of the OSP message checksum  */
00147     STATE_CHECKSUM2,    /* Indicates the second byte of the OSP message checksum  */
00148     STATE_END1,         /* Indicates the first byte of the OSP or NMEA message footer  */
00149     STATE_END2          /* Indicates the second byte of the OSP message footer  */
00150 } eProtoDetState;
00151 
00152 /* CSR Location state */
00153 typedef enum {
00154     CSR_LOC_STATE_IDLE,
00155     CSR_LOC_STATE_RUN,
00156 } eCsrLocState;
00157 
00158 /* Location chip protocol detection state */
00159 typedef enum {
00160     PROTO_STATE_DET_INVALID = 0,
00161     PROTO_STATE_DET_OSP,
00162     PROTO_STATE_DET_NMEA,
00163     //   PROTO_STATE_SWI_OSP_FROM_NMEA,
00164     PROTO_STATE_DET_OSP_FROM_NMEA,
00165     //   PROTO_STATE_SWI_NMEA_FROM_OSP,
00166     PROTO_STATE_DET_NMEA_FROM_OSP,
00167     PROTO_STATE_DET_OK,
00168 } eProtoState;
00169 
00170 /* Location chip status */
00171 typedef enum {
00172     /* Location chip is going to hibernation mode and cannot accept message any more */
00173     ENGINE_STATUS_NOTOK2SEND,
00174     /* Location come back from hibernation mode and can accept message now */
00175     ENGINE_STATUS_OK2SEND
00176 } eEngineStatus;
00177 
00178 /* OSP data type to be sent to location chip */
00179 typedef enum {
00180     SEND_DATA_TYPE_OSP_STOP_REQ,
00181     SEND_DATA_TYPE_OSP_VER_REQ,
00182     SEND_DATA_TYPE_OSP_LPM_REQ,
00183     SEND_DATA_TYPE_OSP_FPM_REQ,
00184     SEND_DATA_TYPE_OSP_SWITCH2NMEA_REQ,
00185     SEND_DATA_TYPE_NMEA_SWITCH2OSP_REQ,
00186     SEND_DATA_TYPE_NMEA_STOP_REQ
00187 } eSendDataType;
00188 
00189 typedef struct GpsTime {
00190     /** Week part of GPS time */
00191     uint16_t gps_week;
00192     /** Time of second part of GPS time */
00193     uint32_t tow;
00194 } tGpsTime;
00195 
00196 /** Structure to hold Position Response Message Information. */
00197 typedef struct LocPosResp {
00198     tGpsTime gpsTime;
00199     uint64_t utcTime;
00200     /** Latitude */
00201     double lat;
00202     /** Longitude */
00203     double lon;
00204     /** Altitude */
00205     double alt;
00206 } tLocPosResp;
00207 
00208 /** Structure to hold Satellite Information. */
00209 typedef struct LocSvInfo {
00210     /** Prn or svId */
00211     uint8_t  prn;
00212     /** The ratio of carrier and noise */
00213     float    cno;
00214     /** elevation */
00215     float    elevation;
00216     /** azimuth */
00217     float    azimuth;
00218     /** satellite state */
00219     uint16_t state;
00220 } tLocSvInfo;
00221 
00222 /** Structure to hold Satellite Information for GLONASS */
00223 typedef struct LocGloSvInfo {
00224     /** Prn or svId */
00225     uint8_t  prn;
00226     /** Slot number */
00227     uint8_t  sno;
00228     /** The ratio of carrier and noise */
00229     float    cno;
00230     /** elevation */
00231     float    elevation;
00232     /** azimuth */
00233     float    azimuth;
00234     /** satellite state */
00235     uint16_t state;
00236 } tLocGloSvInfo;
00237 
00238 /** Structure to hold Satellite Status Information. */
00239 typedef struct LocSvStatus {
00240     /** Week part of GPS time */
00241     uint16_t      gps_week;
00242     /** Time of second part of GPS time */
00243     uint32_t      tow;
00244     /** Time of millisecond part of GPS time */
00245     uint32_t      tow_sub_ms;
00246 
00247     /**Number of GPS SVs currently visible **/
00248     uint8_t       numOfSVs;
00249     /**Number of GLONASS SVs currently visible **/
00250     uint8_t       numOfGloSVs;
00251     /** GPS SVs information */
00252     tLocSvInfo    svList[LOC_MAX_GNSS_SVS];
00253     /** GLONASS SVs information */
00254     tLocGloSvInfo gloSvList[LOC_NUM_OF_GLO_FREQ_CHANNELS];
00255     /** Bit mask indicating which SVs have ephemeris data **/
00256     uint32_t      ephemerisMask;
00257     /** Bit mask indicating which GLONASS SVs have ephemeris data **/
00258     uint32_t      gloEphemerisMask;
00259     /** Bit mask indicating which SVs were used in latest sent fix **/
00260     uint32_t      svUsedInFixMask;
00261     /** Bit mask indicating which GLONASS SVs were used in latest sent fix **/
00262     uint32_t      gloSvUsedInFixMask;
00263     /** Bit mask indicating which QZSS SVs were used in latest sent fix **/
00264     uint32_t      qzssSvUsedInFixMask;
00265     /** Bit mask indicating which SBAS SVs were used in latest sent fix **/
00266     uint32_t      sbasSvUsedInFixMask;
00267 } tLocSvStatus;
00268 
00269 
00270 /** Application register this out callback function and CsrLocation class will pass outputted information to application */
00271 typedef void (*csr_app_output_callback)(uint32_t msgId, void *const pMsgData, uint32_t msgLength);
00272 
00273 /** Application register this event callback function and CsrLocation class will pass internal processing event to application */
00274 typedef void (*csr_app_event_callback)(eCsrLocEventType event, uint32_t data);
00275 
00276 /* General OSP message format */
00277 typedef struct OspMsg {
00278     uint32_t msgId;
00279     uint32_t length;
00280     uint8_t  payload[4];
00281 } tOspMsg;
00282 
00283 
00284 /** CSRLocation class.
00285  *  A location interface to control location chip and get position and satellite information.
00286  */
00287 class CSRLocation : public GPSProviderImplBase
00288 {
00289 public:
00290     /** Constructor: CsrLocation
00291      * Create the CSRLocation, accept specified configuration
00292      *
00293      * @param [in] pSerialLoc
00294      *             serial communication channel between host and GPS controller.
00295      * @param [in] pPinOnoff
00296      *             GPIO pin to control location chip on, a rising edge is used to activate
00297      *             location chip. Please note, before activate chip, reset pin should be
00298      *             pull high.
00299      * @param [in] pPinReset
00300      *             GPIO pin to control location chip reset, low level will keep location
00301      *             chip in hibernation state and high level will permit location chip to be
00302      *             activated.
00303      * @param [in] pWakeup
00304      *             GPIO pin to detect if the chip is still wakeup.
00305      * @param [in] pLocConfig
00306      *             Configuration including debug serial port, location communication serial port, onoff pin, reset pin
00307      * @param [in] debugP
00308      *             The debug port for diagnostic messages; can be NULL.
00309      */
00310     CSRLocation(RawSerial  &serialLoc,
00311                 DigitalOut &pinOnoff,
00312                 DigitalOut &pinReset,
00313                 DigitalIn  &wakeup,
00314                 Serial     *debugP = NULL);
00315 
00316     /** Destructor: CSRLocation
00317      * Free allocated resource
00318      */
00319     virtual ~CSRLocation();
00320 
00321     /** Register output callback and event callback functions
00322      * @param app_output_cb CSRLocation class output the location and satellite information to application
00323      * @param app_event_cb CSRLocation class output the start and stop result to application
00324      */
00325     void CsrLocRegOutput(csr_app_output_callback app_output_cb, csr_app_event_callback app_event_cb);
00326 
00327     /** HW reset to get location chip into hibernation mode */
00328     virtual void reset(void);
00329 
00330     /* A debug interface to switch location chip protocol from OSP at 115200bps to NMEA at 4800bps */
00331     void CsrLocDebugSwitch2Nmea(void);
00332 
00333 private:
00334     /* Initialize the serial port and open it */
00335     void _CsrLocUartInit(void);
00336 
00337     /* Process the raw stream from location serial port */
00338     void _CsrLocProcessRawStream(void);
00339 
00340     /* Detect the OSP protocol detection timeout */
00341     void _CsrLocDetProtoOspTimeout(void);
00342 
00343     /* Detect the NMEA protocol outputted from location serial port */
00344     void _CsrLocDetProtoNmeaTimeout(void);
00345 
00346     /* Process the raw NMEA stream, remove the NMEA header, tail, and save the NMEA data into internal buffer */
00347     void _CsrLocProcessRawNmeaStream(uint8_t data);
00348 
00349     /* Process the raw OSP stream, remove the OSP header, size, check sum, and save the OSP data into internal buffer */
00350     void _CsrLocProcessRawOspStream(uint8_t data);
00351 
00352     /* Process the saved NMEA data and decode them */
00353     void _CsrLocProcessRawNmeaPkt(void);
00354 
00355     /* Process the saved OSP data and decode them */
00356     void _CsrLocProcessRawOspPkt(void);
00357 
00358     /* Calculate the OSP message size to allocate buffer to save the decoded OSP data */
00359     uint32_t _CsrLocCalcMsgSize(void);
00360 
00361     /* Decode OSP data into packet data structure */
00362     CsrResult _CsrLocDecodeOspPkt(uint8_t  *payload,
00363                                   uint32_t  payload_length,
00364                                   uint32_t *message_id,
00365                                   void     *message_structure,
00366                                   uint32_t *message_length);
00367 
00368     /* Process the decode OSP packet and pass to application when needed */
00369     void _CsrLocProcessOspPkt(tOspMsg *pOspMsg);
00370 
00371     /* Timeout process, such as detect OSP and NMEA protocol */
00372     void _CsrLocTimeout(void);
00373 
00374     /* Location serial port data receiver */
00375     void _CsrLocRxHandler(void);
00376 
00377     /* Send special OSP messages to location chip */
00378     void _CsrLocSendData(eSendDataType type);
00379 
00380     /* Trigger a pulse on the onoff pin */
00381     void _CsrLocHwOnoff(void);
00382 
00383     /* Trigger a reset on the reset pin */
00384     void _CsrLocHwReset(void);
00385 
00386     /* Detect wakeup status on the wakeup pin */
00387     bool _CsrLocIsWakeup(void);
00388 
00389 private:
00390     void outputHandler(uint32_t msgId, void *const pMsgData, uint32_t msgLength);
00391     void eventHandler(eCsrLocEventType event, uint32_t data);
00392 
00393     /**
00394      * APIs needed to extend GPSProviderImplBase
00395      */
00396 private:
00397     virtual bool setPowerMode(GPSProvider::PowerMode_t pwrMode);
00398     virtual void start(void);
00399     virtual void stop(void);
00400     virtual void process(void);
00401     virtual uint32_t ioctl(uint32_t command, void *arg);
00402 
00403     /** Special for low power PTF mode.
00404       * During low power PTF mode, after reporting position, chip will go to hibernation mode automatically.
00405       * After 30 seconds, chip will recover and report position again. Then chip will go to hibernation mode again.
00406       * During the hibernation, application can call lpmGetImmediateLocation to get position immediately and no need to wait for the whole interval.
00407       */
00408     virtual void lpmGetImmediateLocation(void);
00409 
00410     /* Internal data */
00411 private:
00412     RawSerial       &serialLoc; /**< serial communication channel between host and GPS controller. */
00413     DigitalOut      &pinOnoff;
00414     DigitalOut      &pinReset;
00415     DigitalIn       &wakeup;
00416 
00417     bool             bPwrModeRsp;
00418     bool             bVerRsp;
00419 
00420     eProto           proto;
00421     eCsrLocState     locState;
00422     eProtoState      protoState;
00423     ePowerMode       pwrMode;
00424 
00425     uint32_t         baudRate;
00426     int32_t          computedCheckSum;
00427     int32_t          checksum;
00428     int32_t          msgSize;
00429     int32_t          decodeIndex;
00430     eProtoDetState   protoDetState;
00431     Timeout         *pTimeoutChk; /* timeout process */
00432     bool             bTimeoutFlag;
00433     eEngineStatus    engStatus;
00434 
00435     tLocSvStatus     svStatus; /* 2 kind of messages contribute the svStaus */
00436 
00437     uint8_t          serialBuf[MAX_SERIAL_BUF_LEN]; /* buffer the serial data from UART callback function */
00438     uint8_t          serialPkt[MAX_SERIAL_PKT_LEN]; /* decoded OSP data */
00439     uint32_t         in;
00440     uint32_t         out;
00441 
00442     csr_app_output_callback appOutCb;
00443     csr_app_event_callback  appEventCb;
00444 
00445     Serial *pSerialDebug;
00446 };
00447 
00448 #endif /* CSRLOCATION_H */