Csr location class shows location and satellite information, which supports H13467 + ST F103RB/NXP LCP1549 boards now.

Dependents:   CsrLocationDemo CsrLocationDemo

Fork of CsrLocation by jie zhao

CsrLocation.h

Committer:
zhjcpi
Date:
2014-08-04
Revision:
6:aed3c66b39d9
Parent:
5:219dfc2905dc
Child:
7:1fde78f27d5b

File content as of revision 6:aed3c66b39d9:


/* 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"

typedef uint16_t CsrResult;
#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       D9
#define PINMAP_GPIO_LOC_WAKEUP      D3
#define PINMAP_GPIO_LOC_RESET       D4
#define LOC_LED1                    D7
#define LOC_LED2                    D5
#define DBG_SERIAL_TYPE             Serial
#define LOC_SERIAL_TYPE             RawSerial
#endif


/* 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) (((uint16_t)*((bytestream)+0) << 8) | ((uint16_t)*((bytestream)+1)))

#define CSR_SWAPIN32(bytestream)\
   ( ((uint32_t)*((bytestream)+0) << 24)\
   | ((uint32_t)*((bytestream)+1) << 16)\
   | ((uint32_t)*((bytestream)+2) <<  8)\
   | ((uint32_t)*((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) ((uint16_t) CSR_SWAPIN16((bytestream))); bytestream+=2
#define BINARY_IMPORT_UINT32(bytestream) ((uint32_t) CSR_SWAPIN32((bytestream))); bytestream+=4
#define BINARY_IMPORT_SINT32(bytestream) ((int32_t)  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)

#if 0
#define CSR_LOG_INFO    printf
#else
#define CSR_LOG_INFO(...) \
{\
    if(csrLocInst.pSerialDebug != NULL)\
    {\
        (csrLocInst.pSerialDebug->printf(__VA_ARGS__));\
    }\
}
#endif

/** 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;

/** Power mode selection */
typedef enum
{
    /** NMEA protocol */
    PROTO_NMEA,
    /** OSP protocol */
    PROTO_OSP,
}eProto;

/* 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_SWI_NMEA_FROM_OSP,
   PROTO_STATE_DET_NMEA_FROM_OSP,
   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,
    SEND_DATA_TYPE_NMEA_STOP_REQ
}eSendDataType;

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 */
    double            lon;
    /** Altitude */
    double            alt;
} tLocPosResp;

/** Structure to hold Satellite Information. */
typedef struct LocSvInfo
{
    /** Prn or svId */
    uint8_t             prn;
    /** The ratio of carrier and noise */
    float             cno;
    /** elevation */
    float             elevation;
    /** azimuth */
    float             azimuth;
    /** satellite state */
    uint16_t            state;
} tLocSvInfo;

/** Structure to hold Satellite Information for GLONASS */
typedef struct LocGloSvInfo
{
    /** Prn or svId */
    uint8_t             prn;
    /** Slot number */
    uint8_t             sno;
    /** The ratio of carrier and noise */
    float             cno;
    /** elevation */
    float             elevation;
    /** azimuth */
    float             azimuth;
    /** satellite state */
    uint16_t            state;
} tLocGloSvInfo;

/** Structure to hold Satellite Status Information. */
typedef struct LocSvStatus
{
    /** Week part of GPS time */
    uint16_t           gps_week;
    /** Time of second part of GPS time */
    uint32_t           tow;
    /** Time of millisecond part of GPS time */
    uint32_t           tow_sub_ms;
   
    /**Number of GPS SVs currently visible **/
    uint8_t            numOfSVs;
    /**Number of GLONASS SVs currently visible **/
    uint8_t            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 **/
    uint32_t           ephemerisMask;
    /** Bit mask indicating which GLONASS SVs have ephemeris data **/
    uint32_t           gloEphemerisMask;
    /** Bit mask indicating which SVs were used in latest sent fix **/
    uint32_t           svUsedInFixMask;
    /** Bit mask indicating which GLONASS SVs were used in latest sent fix **/
    uint32_t           gloSvUsedInFixMask;
    /** Bit mask indicating which QZSS SVs were used in latest sent fix **/   
    uint32_t           qzssSvUsedInFixMask;
    /** Bit mask indicating which SBAS SVs were used in latest sent fix **/   
    uint32_t           sbasSvUsedInFixMask;
} tLocSvStatus;


/** Applicaiton register this out callback function and CsrLocaiton class will pass outputted information to application */
typedef void (*csr_app_output_callback)(uint32_t  msgId, void * const pMsgData, uint32_t 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, uint32_t data);

/** tCsrLocConfig structure
 * Application needs to decides and pass the configuration into CsrLocation class.
 */
typedef struct CsrLocConfig
{
    /** Debug serial port to print debug information */
    DBG_SERIAL_TYPE *pSerialDebug;
    /** location serail port to communicate between mbed host side and location chip */
    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 */
    DigitalOut      *pPinReset;
}tCsrLocConfig;

/* General OSP mesasge format */
typedef struct OspMsg
{
   uint32_t        msgId;   
   uint32_t        length;
   uint8_t         payload[4];
} tOspMsg;

/* keep the internal data of CsrLocation class */
typedef struct CsrLocInst
{
    bool            bStopFlag;
    bool            bPwrModeRsp;
    bool            bVerRsp;

    eProto          proto;
    eCsrLocState    locState;
    eProtoState     protoState;
    ePowerMode      pwrMode;
    uint32_t        baudRate;
    int32_t         computedCheckSum;
    int32_t         checksum;
    int32_t         msgSize;
    int32_t         decodeIndex;
    eProtoDetState  protoDetState;
    Timeout         *pTimeoutChk;    /* timeout process */
    bool            bTimeoutFlag;
    eEngineStatus   engStatus;

    tLocSvStatus    svStatus;   /* 2 kind of messages contribute the svStaus */

    DBG_SERIAL_TYPE *pSerialDebug;
    LOC_SERIAL_TYPE *pSerialLoc;
    DigitalOut      *pPinOnoff;
    DigitalOut      *pPinReset;

    uint8_t         serialBuf[MAX_SERIAL_BUF_LEN]; /* buffer the serial data from uart callback function */
    uint8_t         serialPkt[MAX_SERIAL_PKT_LEN]; /* decoded osp data */
    uint32_t        in;
    uint32_t        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);
    
    /** get location state */
    eCsrLocState CsrLocGetState(void);

    /** Start location request, activate location chip */
    void CsrLocStart(ePowerMode pwrMode, eProto proto);

    /** 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 detection timeout */
    void _CsrLocDetProtoOspTimeout(void);

    /* Detect the NMEA protocol outputted from location serial port */
    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);

    /* Calculate the OSP message size to allcate buffer to save the decoded OSP data */
    uint32_t _CsrLocCalcMsgSize(void);

    /* Decode OSP data into pakcet data structure */
    CsrResult _CsrLocDecodeOspPkt( uint8_t *payload, uint32_t payload_length, uint32_t *message_id, void   *message_structure, uint32_t *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 */