📄 gpsdrv.c
字号:
/****************************************************************
** *
** FILE : GpsDrv.C *
** COPYRIGHT : (c) 2001 .Xiamen Yaxon NetWork CO.LTD *
** *
** *
** By : CCH 2002.1.15 *
****************************************************************/
#define GPSDRV_GLOBALS
#include "includes.h"
#include "bsp.h"
#include "errcode.h"
#include "tools.h"
#include "errtask.h"
#include "timetask.h"
#include "systask.h"
#include "message.h"
#include "systime.h"
#include "gpsrecer.h"
#include "gpsdrv.h"
#include "zprint.h"
/*
********************************************************************************
* DEFINE CONFIG PARAMETERS
********************************************************************************
*/
#if EN_GPS_LEA_4A
#define DEF_BAUD 9600L
#define SET_BAUD 4800L
#elif EN_GPS_SONY
#define GPS_UARTBAUD 4800
#else
#define GPS_UARTBAUD 9600L
#endif
#define SIZE_MSGBUF 100
#define MAX_INVALID (20 * 60)
#define MAX_APPLY 20
#define MAX_SEND 3
#define MAX_NOMSG 10
#define MAX_RMC (10 * 30) /* 30秒内没收到RMC数据,表示GPS模块异常 */
#define MAX_GGA (10 * 30) /* 30秒内没收到GGA数据,表示GPS模块异常 */
#define MAX_GSA (10 * 30) /* 30秒内没收到GSA数据,表示GPS模块异常 */
#define MAX_GSV (10 * 120) /* 120秒内没收到GSV数据,表示GPS模块异常 */
#define MAX_PUBX04 (10 * 30) /* 30秒内没收到PUBX04数据,表示GPS模块异常 */
#define PERIOD_POWERDOWN SECOND, 6
#define PERIOD_POWERUP SECOND, 5
#define PERIOD_MONITOR SECOND, 30
#define PERIOD_SCAN MILTICK, 2
#define PERIOD_INITWAIT SECOND, 2
#define PERIOD_INTERVAL MILTICK, 10
/*
********************************************************************************
* DEFINE STATUS
********************************************************************************
*/
#define SLEEP_ 0x01
#define RESET_ 0x02
#define INIT_ 0x04
#define VALID_ 0x08
/*
********************************************************************************
* DEFINE SENDPARA_STRUCT
********************************************************************************
*/
typedef struct {
INT32U baud; /* 波特率*/
INT8U delay; /* 延时时间,单位:秒 */
INT8U sendlen; /* 设置参数长度 */
const INT8U *sendptr; /* 设置参数指针 */
} SENDPARA_STRUCT;
/*
********************************************************************************
* DEFINE sendpara
********************************************************************************
*/
#if EN_GPS_LEA_4A
static INT8U NMEA_SETBAUD_4800[] = {"$PUBX,41,1,0007,0003,4800,0*13\r\n"}; /* 波特率:4800 */
//static INT8U code NMEA_DISGGA[] = {"$PUBX,40,GGA,0,0,0,0*5A\r\n"}; /* 禁止GGA消息输出 */
static INT8U NMEA_DISGLL[] = {"$PUBX,40,GLL,0,0,0,0*5C\r\n"}; /* 禁止GLL消息输出 */
static INT8U NMEA_DISZDA[] = {"$PUBX,40,ZDA,0,0,0,0*44\r\n"}; /* 禁止ZDA消息输出 */
static INT8U NMEA_DISVTG[] = {"$PUBX,40,VTG,0,0,0,0*5E\r\n"}; /* 禁止VTG消息输出 */
static INT8U NMEA_ENGGA[] = {"$PUBX,40,GGA,5,5,5,0*5F\r\n"}; /* 允许GGA消息输出,每5秒输出一次 */
static INT8U NMEA_ENGSV_2[] = {"$PUBX,40,GSV,2,2,2,0*5B\r\n"}; /* 允许GSV消息输出,每2秒输出一次 */
////static INT8U code NMEA_ENGSV_17[] = {"$PUBX,40,GSV,17,17,17,0*6F\r\n"}; /* 允许GSV消息输出,每17秒输出一次 */
static INT8U NMEA_ENGSA[] = {"$PUBX,40,GSA,7,7,7,0*49\r\n"}; /* 允许GSA消息输出,每7秒输出一次 */
static INT8U NMEA_ENPUBX04[] = {"$PUBX,40,04,2,2,2,0*1D\r\n"}; /* 允许PUBX04消息输出,每2秒输出一次 */
static INT8U NMEA_ENGPRMC[] = {"$PUBX,40,RMC,1,1,1,1*47\r\n"};
/* 冷启动GPS模块 */
static INT8U CFG_RST[] = {0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0xFF, 0x07, 0x02, 0x00, 0x16, 0x79};
static SENDPARA_STRUCT sendpara[]
= {
#if EN_GPS_LEA_4A
{DEF_BAUD, 2, sizeof(NMEA_SETBAUD_4800) - 1, NMEA_SETBAUD_4800},
#endif
{SET_BAUD, 2, sizeof(NMEA_DISGLL) - 1, NMEA_DISGLL},
{SET_BAUD, 2, sizeof(NMEA_DISZDA) - 1, NMEA_DISZDA},
{SET_BAUD, 2, sizeof(NMEA_DISVTG) - 1, NMEA_DISVTG},
////{SET_BAUD/UART_BASE_BAUD-1, 2, sizeof(NMEA_ENGSV_17) - 1, NMEA_ENGSV_17},
{SET_BAUD, 2, sizeof(NMEA_ENGSV_2) - 1, NMEA_ENGSV_2},
{SET_BAUD, 2, sizeof(NMEA_ENGGA) - 1, NMEA_ENGGA},
{SET_BAUD, 2, sizeof(NMEA_ENGSA) - 1, NMEA_ENGSA},
{SET_BAUD, 2, sizeof(NMEA_ENPUBX04) - 1, NMEA_ENPUBX04},
{SET_BAUD, 2, sizeof(NMEA_ENGPRMC) - 1, NMEA_ENGPRMC},
};
#endif /* end of GPS_TYPE */
/*
********************************************************************************
* DEFINE RESET STEP
********************************************************************************
*/
#define STEP_POWERDOWN 0
#define STEP_POWERUP 1
#define STEP_STOPRESET 2
/*
********************************************************************************
* DEFINE MODULE VARIANT
********************************************************************************
*/
static INT8U status, numapply;
static INT8U opstep, ct_send, ct_nomsg;
static INT16U ct_invalid,ct_rmc, ct_gga, ct_gsa, ct_gsv, ct_pubx04;
static BOOLEAN isnormal, coldstart;
static TMR_TSK *optmr, *monitortmr, *scantmr;
static INT8U HEAD_GPRMC[] = {"$GPRMC"};
static INT8U HEAD_GPGGA[] = {"$GPGGA"};
static INT8U HEAD_GPGSA[] = {"$GPGSA"};
static INT8U HEAD_PUBX04[] = {"$PUBX,04,"};
static INT8U HEAD_GPGSV[] = {"$GPGSV"};
static INT8U msgbuf[SIZE_MSGBUF];
static INT8U msglen;
static void StartInit(void)
{
opstep = 0;
status |= INIT_;
ct_send = 0;
StopTmr(scantmr);
StopTmr(monitortmr);
StartTmr(optmr, PERIOD_INITWAIT);
}
static void SetInit(void)
{
INT8U sendlen;
INT8U *sendptr;
#if DEBUG_UARTNo_GPS <= 3
PrintFromUART(DEBUG_UARTNo_GPS, "\nSetInit");
#endif
if (opstep >= sizeof(sendpara) / sizeof(sendpara[0])) {
status &= ~INIT_;
StopTmr(optmr);
StartTmr(monitortmr, PERIOD_MONITOR);
ct_rmc = 0;
ct_gga = 0;
ct_gsa = 0;
ct_gsv = 0;
ct_pubx04 = 0;
uarts_init(UARTNo_GPS, SET_BAUD);
} else {
uarts_init(UARTNo_GPS, sendpara[opstep].baud);
sendlen = sendpara[opstep].sendlen;
sendptr = (INT8U *)sendpara[opstep].sendptr;
uarts_writeblock(UARTNo_GPS, sendptr, sendlen);
if (++ct_send >= MAX_SEND) {
StartTmr(optmr, SECOND, sendpara[opstep].delay);
ct_send = 0;
opstep++;
#if EN_GPS_LEA_4A
if (opstep==4) {
#else
if (opstep==0) {
#endif
UART_Close(UARTNo_GPS);
StartTmr(scantmr, PERIOD_SCAN);
}
} else {
StartTmr(optmr, PERIOD_INTERVAL);
}
}
}
static BOOLEAN GpsMsgValid(void)
{
INT8U i, j, cur, chksum, recvsum;
chksum = '$';
recvsum = 0;
for (i = 0; i < msglen; i++) {
cur = msgbuf[i];
if (cur != '*') chksum ^= cur;
else
{
if ((i + 2) <= (msglen - 1))
{
for (j = 1; j <= 2; j++)
{
cur = CharToHex(msgbuf[i + j]);
if (j == 1) cur <<= 4;
recvsum += cur;
}
}
break;
}
}
if (chksum == recvsum) return TRUE;
else return FALSE;
}
static const INT8U CHARSET_GPRMC[] = {',', '.', '*', 'A', 'B', 'C', 'D', 'E', 'F', 'V', 'N', 'S', 'W','M','-'};
static BOOLEAN CharSetValid(INT8U *ptr, INT8U len)
{
INT8U temp, i;
for (; len > 0; len--) {
temp = *ptr++;
if (temp >= '0' && temp <= '9') continue;
i = 0;
for (;;) {
if (temp == CHARSET_GPRMC[i]) break;
if (++i >= sizeof(CHARSET_GPRMC)) return FALSE;
}
}
return TRUE;
}
static BOOLEAN HdlMsg_GPRMC(void)
{
INT8U i;
for (i = 0; i < sizeof(HEAD_GPRMC) - 1; i++) {
if (msgbuf[i] != HEAD_GPRMC[i]) return FALSE;
}
if (!GpsMsgValid() || !CharSetValid(&msgbuf[6], msglen - 8)) { /* 8 = $GPRMC, 0x0d, 0x0a */
#if DEBUG_UARTNo_GPS <= 3
PrintFromUART(DEBUG_UARTNo_GPS, "<rceive error GPS message>\n");
#endif
return TRUE;
}
#if DEBUG_UARTNo_GPS <= 3
SendFromUART_MEM(DEBUG_UARTNo_GPS, msgbuf, msglen);
#endif
if ((status & SLEEP_) == 0) { /* 表示接收到GPS模块输出的RMC数据 */
ct_rmc = 0;
isnormal = TRUE;
}
StartTmr(monitortmr, PERIOD_MONITOR);
isnormal = TRUE;
memcpy(MSG_GPRMC, msgbuf, msglen);
ResolveGPRMC(); /* resolve MSG_GPRMC */
StoreOldPosition();
if (GpsDataValid()) {
ct_invalid = 0;
if (GpsTimeError())
{
coldstart = TRUE;
ResetGps();
}
else
{
if (!SysTimeValid()) ReviseSysTime();
if ((status & VALID_) == 0)
{
status |= VALID_;
StartInit();
}
}
}
else
{
if (++ct_invalid > MAX_INVALID) ResetGps();
}
return TRUE;
}
#if EN_GGA > 0
static BOOLEAN HdlMsg_GPGGA(void)
{
INT8U i;
for (i = 0; i < sizeof(HEAD_GPGGA) - 1; i++)
{
if (msgbuf[i] != HEAD_GPGGA[i]) return FALSE;
}
if (!GpsMsgValid() || !CharSetValid(&msgbuf[6], msglen - 8)) { /* 8 = $GPGGA, 0x0d, 0x0a */
#if DEBUG_GPS > 0
printf("<receive error GPGGA message>\n");
#endif
return TRUE;
}
if ((status & SLEEP_) == 0) { /* 表示接收到GPS模块输出的GGA数据 */
ct_gga = 0;
isnormal = TRUE;
}
isnormal = TRUE;
StartTmr(monitortmr, PERIOD_MONITOR);
ResolveGPGGA(msgbuf, msglen);
return TRUE;
}
#endif
static BOOLEAN HdlMsg_GPGSA(void)
{
INT8U i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -