Files

1691 lines
52 KiB
C

/**
******************************************************************************
* @file name : gps.c
* @author :
* @version :
* @date :
* @brief : gps uart for atsc
******************************************************************************
* @attention
//USE_GPS
//
******************************************************************************
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sched.h>
#include <time.h>
#include "../inc/type.h"
#include "../inc/delay.h"
#include "../inc/lcd_task.h"
#include "../inc/isys_config.h"
#include "../inc/i2c_drv.h"
#include "../inc/dpd_proc.h"
#include "../inc/iuart_user.h"
#include "../inc/eeprom.h"
#include "../inc/gps.h"
#include "../inc/main.h"
#include "../inc/msg.h"
#include "../inc/iweb_task.h"
#include "../inc/general_api.h"
#include "../inc/isys_com.h"
#include "../inc/dac38j82.h"
#include "../inc/os_task.h"
#include "../inc/fpga.h"
/*
#include <string.h>
#include "type.h"
#include "delay.h"
#include "os_task.h"
#include "gps.h"
#include "lcd_task.h"
#include "i2c_drv.h"
#include "sys_config.h"
*/
#if 1
#define GPS_UART_RCV_BUF_LEN 1024
char gps_uart_recv_buff[GPS_UART_RCV_BUF_LEN] = {0};
char gps_cmd_buff[GPS_UART_RCV_BUF_LEN] = {0};
#endif
extern uint32 update_flag;
extern void rtc_update_by_gps(GPRMC_T *p);
extern S_SYS_TIME *os_get_sys_time_ptr(void);
#if 1//_USE_RVL_
extern S_ATSC_PARA atsc_para;
#endif//_USE_RVL_
extern S_RUN_TIME run_time;
static GPRMC_T gps_time;
static GPRMC_T time_temp;
static GPGSA_T gps_sa;
static POLYP_T gps_polyp = {FALSE,};
static uint32 ublox_cfg_msg_index = 0; //配置UBLOX向外发送的消息数
//查询命令由于与设置命令相同,只是长度为0,因此模块出了响应返回信息外,还会有一条ack应答,
//因此,对此状态的处理需小心处理
static E_UBLOX_STATE ublox_state = UBLOX_STATE_ANT_CFG_READ;
static S_UBLOX_PARA ublox_para;
static S_UBLOX_PARA ublox_para_read; //保存查询返回的数据
static S_UBLOX_UBX_MSG ublox_cfg_msg;
static S_UBLOX_UBX_MSG ublox_rec_msg;
static uint8 ublox_cfg_buf[UBLOX_MAX_DATE_SND_BUF_LEN]; //发送UBX协议数据区
static uint8 ublox_rec_buf[UBLOX_MAX_DATE_REC_BUF_LEN]; //接收UBX协议数据区
static uint8 ublox_send_buf[UBLOX_MAX_DATE_SND_BUF_LEN+16];
static UBLOX_FRAME_CLASS_ID cfg_rec_msg[UBLOX_CFG_MSG_MAX];
#if GPS_TEST_DEBUG
static S_UBLOX_NAV_STATUS_PARA ublox_nav_status_para;
#endif
static uint32 ublox_init_over_time = 0; //上电后ublox模块初始化完成时间
static uint32 ublox_gps_lock_frame = 0; //收到的锁定gps报文的条数
static uint32 ublox_save_need_flag = 0; //配置参数过程中,判断是否需要发送保存参数标志
static uint32 ublox_last_lock_time = 0; //最近一次解析到lock的时间
static uint32 ublox_need_restart = 0; //是否需要重启
static uint32 gps_uart_send(S_UBLOX_UBX_MSG *psend)
{
uint32 send_len = 0;
if(psend==NULL)
return 0;
#if 0
UARTCharPut(GPS_UART_BASE,psend->sync_char1);
UARTCharPut(GPS_UART_BASE,psend->sync_char2);
UARTCharPut(GPS_UART_BASE,psend->cfg_class);
UARTCharPut(GPS_UART_BASE,psend->cfg_id);
UARTCharPut(GPS_UART_BASE,psend->length);
UARTCharPut(GPS_UART_BASE,psend->length>>8); //小端序
if((psend->length)&&(psend->pdata))
{
uint16 len = psend->length;
uint8 *ptemp = psend->pdata;
while(len--)
{
UARTCharPut(GPS_UART_BASE,*ptemp++);
send_len++;
}
}
UARTCharPut(GPS_UART_BASE,psend->sum.ck_a);
UARTCharPut(GPS_UART_BASE,psend->sum.ck_b);
#else
memcpy(ublox_send_buf,&psend->sync_char1,6);
if((psend->length)&&(psend->pdata))
{
memcpy(&ublox_send_buf[6],psend->pdata,psend->length);
}
ublox_send_buf[6+psend->length] = psend->sum.ck_a;
ublox_send_buf[7+psend->length] = psend->sum.ck_b;
send_len = psend->length+8;
#if 1//_USE_RVL_
log_printf(LOG_DEBUG,I_NOUSED,"snd_2_gps:%s,len=%d\n",ublox_send_buf,send_len);
gps_rs232_send_string(ublox_send_buf,send_len);//uart_send_string
#endif
#endif
return send_len; //must be equl psend->length+8;
}
//初始化需向UBLOX模块配置的参数,在发送时,若有特殊需要,可在另行配置(默认不需更改)
static void gps_ublox_para_init(void)
{
memset(&ublox_para,0,sizeof(ublox_para));
/***TP5参数初始化***/
ublox_para.tp5_para.tp_index = 1;
ublox_para.tp5_para.freq_period = UBLOX_TP5_FREQ_PERIOD;
ublox_para.tp5_para.freq_period_lock = UBLOX_TP5_FREQ_PERIOD; //配置相同,但有下面参数配置为未锁定时不输出脉冲
ublox_para.tp5_para.pulse_len_ratio = UBLOX_TP5_FREQ_PULSE_LEN_RATIO(UBLOX_TP5_FREQ_PULSE_RATIO); //占空比为50%; 未锁定时,输出
ublox_para.tp5_para.pulse_len_ratio_lock = UBLOX_TP5_FREQ_PULSE_LEN_RATIO(UBLOX_TP5_FREQ_PULSE_RATIO); //占空比为50%
ublox_para.tp5_para.flags = MASK_TP5_ACTIVE|MASK_TP5_LOCK_GPS_FREQ|MASK_TP5_LOCKED_OTHER_SET|MASK_TP5_IS_FREQ|MASK_TP5_GRID_UTC_GPS;
/*****MODE参数初始化***/
ublox_para.mode_para.time_mode = UBLOX_TIME_MODE_SURVEY_IN; //固定为survey in,模式
ublox_para.mode_para.svin_mindur = UBLOX_FIND_SAT_TIME;
ublox_para.mode_para.svin_varlinmit = UBLOX_FIND_SAT_ACCURACY;
/*****保存参数初始化***/
ublox_para.cfg_para.save_mask = (uint32)-1;
ublox_para.cfg_para.device_mask = MASK_DEV_SPI_FLASH;
/*****复位参数初始化***/
ublox_para.rst_para.nav_bbr_mask = UBLOX_RST_BBR_COLDSTART;
ublox_para.rst_para.reset_mode = UBLOX_RST_GPS_ONLY;
}
void gps_ublox_init(void)
{
ublox_cfg_msg.sync_char1 = UBLOX_SYNC_CHAR1;
ublox_cfg_msg.sync_char2 = UBLOX_SYNC_CHAR2;
memset(cfg_rec_msg,0xff,sizeof(cfg_rec_msg));
cfg_rec_msg[0].frame_class = UBLOX_MSG_MON;
cfg_rec_msg[0].frame_id = UBX_MON_HW;
cfg_rec_msg[1].frame_class = 0XF0;
cfg_rec_msg[1].frame_id = 0X00;
cfg_rec_msg[2].frame_class = 0XF0;
cfg_rec_msg[2].frame_id = 0X04;
gps_ublox_para_init();
}
static void ublox_get_sum(S_UBLOX_UBX_MSG *pmsg,UBLOX_UBX_SUM *psum)
{
uint16 len = 0;
if((pmsg==NULL)||(psum==NULL))
return;
psum->ck_a = 0;
psum->ck_b = 0;
psum->ck_a+=pmsg->cfg_class;
psum->ck_b+=psum->ck_a;
psum->ck_a+=pmsg->cfg_id;
psum->ck_b+=psum->ck_a;
psum->ck_a+=(pmsg->length&0xff);
psum->ck_b+=psum->ck_a;
psum->ck_a+=((pmsg->length&0xff00)>>8);
psum->ck_b+=psum->ck_a;
if(pmsg->pdata)
{
uint8 *pbuf = pmsg->pdata;
len = pmsg->length;
while(len--)
{
psum->ck_a+=*pbuf;
psum->ck_b+=psum->ck_a;
pbuf++;
}
}
}
static uint32 ublox_init_send_param(S_UBLOX_UBX_MSG *pubx_msg,uint8 *pdata,E_UBLOX_CFG_TYPE type)
{
uint32 data_len = 0;
switch(pubx_msg->cfg_class)
{
case UBLOX_MSG_CFG:
switch(pubx_msg->cfg_id)
{
case UBX_CFG_ANT:
ublox_para.ant_para.flag|=ENABLE_OPEN_CIRCUIT_DETECTION; //开路检测
memcpy(pdata,&ublox_para.ant_para,sizeof(ublox_para.ant_para));
data_len =sizeof(ublox_para.ant_para);
break;
case UBX_CFG_TP5:
if(type==UBX_CFG_WRITE1)
{
S_UBLOX_TP5_PARA *psettp5_para = &ublox_para.tp5_para;
(void)psettp5_para; //防止调试开关关闭时产生编译告警
gps_info_printf("%s:Set Para tpindex:%d,freqPeriod:%d,freqPeriodLock:%d,pulseRatio:0x%X,pulseRatioLock:0x%X.\n",__FUNCTION__,
psettp5_para->tp_index,psettp5_para->freq_period,psettp5_para->freq_period_lock,psettp5_para->pulse_len_ratio,
psettp5_para->pulse_len_ratio_lock);
memcpy(pdata,&ublox_para.tp5_para,sizeof(ublox_para.tp5_para));
data_len = sizeof(ublox_para.tp5_para);
}
else
{
gps_info_printf("%s:Set Para tpindex:%d,len:%d.\n",__FUNCTION__,ublox_para.tp5_para.tp_index,sizeof(ublox_para.tp5_para.tp_index));
*pdata = ublox_para.tp5_para.tp_index;
data_len = sizeof(ublox_para.tp5_para.tp_index);
}
break;
case UBX_CFG_MODE:
memcpy(pdata,&ublox_para.mode_para,sizeof(ublox_para.mode_para));
data_len =sizeof(ublox_para.mode_para);
break;
case UBX_CFG_MSG: //
{
UBLOX_FRAME_CLASS_ID *precmsg = &cfg_rec_msg[ublox_cfg_msg_index];
memcpy(pdata,precmsg,sizeof(UBLOX_FRAME_CLASS_ID));
data_len = 2;
}
break;
case UBX_CFG_CFG:
memcpy(pdata,&ublox_para.cfg_para,sizeof(ublox_para.cfg_para));
data_len =sizeof(ublox_para.cfg_para);
break;
case UBX_CFG_RST:
memcpy(pdata,&ublox_para.rst_para,sizeof(ublox_para.rst_para));
data_len =sizeof(ublox_para.rst_para);
break;
default:
break;
}
break;
case UBLOX_MSG_MON:
switch(pubx_msg->cfg_id)
{
case UBX_MON_HW:
break;
default:
break;
}
break;
default:
break;
}
return data_len&0xffff;
}
//负责发送不同类型的配置信息
static void ublox_send_cmd(E_UBLOX_MSG_TYPE msg_type,uint8 index,E_UBLOX_CFG_TYPE rw)
{
ublox_cfg_msg.sync_char1 = UBLOX_SYNC_CHAR1;
ublox_cfg_msg.sync_char2 = UBLOX_SYNC_CHAR2;
ublox_cfg_msg.cfg_class = (uint8)msg_type;
ublox_cfg_msg.cfg_id = (uint8)index;
if(rw == UBX_CFG_READ)
{
ublox_cfg_msg.length = 0;
ublox_cfg_msg.pdata = NULL;
}
else
{
memset(ublox_cfg_buf,0,sizeof(ublox_cfg_buf));
ublox_cfg_msg.pdata = ublox_cfg_buf;
ublox_cfg_msg.length = ublox_init_send_param(&ublox_cfg_msg,ublox_cfg_buf,rw);
}
ublox_get_sum(&ublox_cfg_msg,&ublox_cfg_msg.sum);
gps_uart_send(&ublox_cfg_msg);
}
//ublox状态检测,负责上电后的配置等
void ublox_proc_state(void)
{
static uint32 tick_bak = 0;
if(update_flag)
return;
if(ublox_state>=UBLOX_STATE_SAVE_CFG)
{
#if 1//_USE_RVL_
if(check_delay_over(&tick_bak,1000*10)==FALSE) // raw 1000
return;
#endif
}
switch(ublox_state)
{
case UBLOX_STATE_ANT_CFG_READ: //上电,读取开路配置状态
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_ANT,UBX_CFG_READ);
gps_info_printf("%s:UBLOX_STATE_ANT_CFG_READ\n",__FUNCTION__);
break;
case UBLOX_STATE_ANT_CFG:
ublox_save_need_flag++;
gps_info_printf("%s:UBLOX_STATE_ANT_CFG\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_ANT,UBX_CFG_WRITE1);
gps_info_printf("\t flag-%04x.\n",*((uint16*)ublox_cfg_msg.pdata));
break;
case UBLOX_STATE_TP5_CFG_READ:
/*注意:此处直接使用数据长度为0的读取命令将返回模式0的错误信息,必需发送设置信息,然后利用返回的信息进行判断*/
gps_info_printf("%s:UBLOX_STATE_TP5_CFG_READ\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_TP5,UBX_CFG_WRITE2);
break;
case UBLOX_STATE_TP5_CFG:
ublox_save_need_flag++;
gps_info_printf("%s:UBLOX_STATE_TP5_CFG\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_TP5,UBX_CFG_WRITE1);
break;
case UBLOX_STATE_TP5_CFG2:
ublox_save_need_flag++;
gps_info_printf("%s:UBLOX_STATE_TP5_CFG2\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_TP5,UBX_CFG_WRITE2);
break;
case UBLOX_STATE_MODE_READ:
gps_info_printf("%s:UBLOX_STATE_MODE_READ\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_MODE,UBX_CFG_READ);
break;
case UBLOX_STATE_MODE_CFG:
ublox_save_need_flag++;
gps_info_printf("%s:UBLOX_STATE_MODE_CFG\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_MODE,UBX_CFG_WRITE1);
break;
case UBLOX_STATE_MSG_CFG:
gps_info_printf("%s:UBLOX_STATE_MSG_CFG\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_MSG,UBX_CFG_WRITE1);
gps_info_printf("\t class-%02x,id-%02x.\n",*ublox_cfg_msg.pdata,*(ublox_cfg_msg.pdata+1));
break;
case UBLOX_STATE_SAVE_CFG:
if(ublox_save_need_flag)
{
gps_info_printf("%s:UBLOX_STATE_SAVE_CFG\n",__FUNCTION__);
gps_info_printf("%s:Some Para change ,need save!\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_CFG,UBX_CFG_WRITE1);
ublox_save_need_flag = 0;
}
else
{
gps_info_printf("%s:nothing change,don't need save!\n",__FUNCTION__);
ublox_state = UBLOX_STATE_INIT_OVER;
}
break;
case UBLOX_STATE_INIT_OVER: //周期性需要发送的命令
{
static uint32 last_hw_read_tick = 0;
#if GPS_TEST_DEBUG
static uint32 last_hw_nav_tick = 0;
#endif
#if UBLOX_RXM_RAW_READ_INTERVAL
static uint32 last_raw_read_tick = 0;
if(last_raw_read_tick+UBLOX_RXM_RAW_READ_INTERVAL*SYSTICKHZ<get_sys_tick())
{
gps_info_printf("%s:UBLOX_STATE_RXM_RAW READ.\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_RXM,UBX_RXM_RAW,UBX_CFG_READ);
last_raw_read_tick = get_sys_tick();
break; //此处读取的话,本次就不再读取下一个命令
}
#endif
if(last_hw_read_tick+UBLOX_MON_HW_READ_CYCLE*SYSTICKHZ<get_sys_tick())
{
gps_info_printf("%s:UBLOX_STATE_HW_MON READ.\n",__FUNCTION__);
ublox_send_cmd(UBLOX_MSG_MON,UBX_MON_HW,UBX_CFG_READ);
last_hw_read_tick = get_sys_tick();
break;
}
#if GPS_TEST_DEBUG
if(last_hw_nav_tick+2*SYSTICKHZ<get_sys_tick())
{
ublox_send_cmd(UBLOX_MSG_NAV,UBX_NAV_STATUS,UBX_CFG_READ);
last_hw_nav_tick = get_sys_tick();
break;
}
#else
//初始化完成后,一直未锁定
if(ublox_init_over_time+UBLOX_NO_SAT_TIMEOUT*SYSTICKHZ<get_sys_tick())
{
if(0==ublox_gps_lock_frame) //需复位GPS模块
{
//pS_RUN_TIME ptime = sys_get_run_time();
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_RST,UBX_CFG_WRITE1);
gps_info_printf("**********************UBLOX_MOULE_RESET!************************\n");
//gps_info_printf("\ttime:%02d-%02d-%02d.\n",ptime->hour,ptime->min,ptime->sec);
gps_info_printf("****************************************************************\n");
ublox_init_over_time = get_sys_tick(); //重启后,是否重新配置参数(暂不配置)
ublox_last_lock_time = 0;
}
break;
}
//锁定过,但最后一次锁定时间过长
if(ublox_gps_lock_frame)
{
if(ublox_last_lock_time+UBLOX_LOCK_TO_UNLOCK_TIMEWAIT<get_sys_tick())
{
//已经发送过,且解析后需要重启
if(ublox_need_restart)
{
ublox_send_cmd(UBLOX_MSG_CFG,UBX_CFG_RST,UBX_CFG_WRITE1);
ublox_init_over_time = get_sys_tick(); //重启后,是否重新配置参数(暂不配置)
ublox_last_lock_time = 0;
ublox_need_restart = 0;
}
else
{
ublox_send_cmd(UBLOX_MSG_NAV,UBX_NAV_STATUS,UBX_CFG_READ);
gps_info_printf("%s:send NAV_STATUS CMD.\n",__FUNCTION__);
}
}
break;
}
#endif
}
break;
default:
break;
}
}
//查询返回
static E_GPS_ERROR ublox_ubx_proc_cfg_reply(S_UBLOX_UBX_MSG *pubx_msg)
{
if(pubx_msg==NULL)
return GPS_ERROR_PTR_INVALID;
switch(pubx_msg->cfg_id)
{
case UBX_CFG_ANT:
if(pubx_msg->length!=sizeof(S_UBLOX_ANT_PARA))
return GPS_ERROR_FORMAT;
if(pubx_msg->pdata==NULL)
return GPS_ERROR_PTR_INVALID;
memcpy(&ublox_para.ant_para,pubx_msg->pdata,pubx_msg->length);
gps_info_printf("%s:ant para flag %04X,pins %04X.\n",__FUNCTION__,ublox_para.ant_para.flag,ublox_para.ant_para.pins);
break;
case UBX_CFG_TP5: //设置或查询,必须与设置一致
if(ublox_state==UBLOX_STATE_TP5_CFG_READ)
{
S_UBLOX_TP5_PARA *ptp5_para = (S_UBLOX_TP5_PARA *)pubx_msg->pdata;
S_UBLOX_TP5_PARA *preadtp5_para = &ublox_para_read.tp5_para;;
if(pubx_msg->length!=sizeof(S_UBLOX_TP5_PARA))
{
return GPS_ERROR_FORMAT;
}
if(pubx_msg->pdata==NULL)
{
return GPS_ERROR_PTR_INVALID;
}
memcpy(preadtp5_para,ptp5_para,sizeof(S_UBLOX_TP5_PARA));
}
break;
case UBX_CFG_MODE: //查询返回
{
S_UBLOX_TMODE_PARA *pmode_para = NULL;
S_UBLOX_TMODE_PARA *plocal_para = NULL;
if(pubx_msg->length!=sizeof(S_UBLOX_TMODE_PARA))
return GPS_ERROR_FORMAT;
if(pubx_msg->pdata==NULL)
return GPS_ERROR_PTR_INVALID;
pmode_para = (S_UBLOX_TMODE_PARA *)pubx_msg->pdata;
plocal_para = &ublox_para_read.mode_para;
memcpy(plocal_para,pmode_para,sizeof(S_UBLOX_TMODE_PARA));
}
break;
case UBX_CFG_MSG:
break;
default:
gps_info_printf("%s:Unknow cfg id %02X.\n",__FUNCTION__,pubx_msg->cfg_id);
break;
}
return GPS_ERROR_OK;
}
static E_GPS_ERROR ublox_ubx_proc_ack_reply(S_UBLOX_UBX_MSG *pubx_msg)
{
S_UBLOX_TP5_PARA *ptp5_para = NULL;
S_UBLOX_TP5_PARA *psettp5_para = NULL;
if(pubx_msg==NULL)
return GPS_ERROR_PTR_INVALID;
switch(pubx_msg->cfg_id)
{
case UBX_ACK_NAK:
gps_info_printf("%s: Error nak class 0x%02X id 0x%02X.\n",__FUNCTION__,*pubx_msg->pdata,*(pubx_msg->pdata+1));
break;
case UBX_ACK_ACK:
gps_info_printf("%s:Successfull ack class 0x%02X id 0x%02X state:%02d.\n",__FUNCTION__,*pubx_msg->pdata,*(pubx_msg->pdata+1),ublox_state);
switch(ublox_state)
{
case UBLOX_STATE_ANT_CFG_READ: //上电,读取开路配置状态
if(ublox_para.ant_para.flag&ENABLE_OPEN_CIRCUIT_DETECTION) //开路检测是否打开
{
ublox_state = UBLOX_STATE_TP5_CFG_READ; //若开路,直接读取TP5
}
else
{
ublox_state++;
}
break;
case UBLOX_STATE_ANT_CFG:
ublox_state = UBLOX_STATE_TP5_CFG_READ;
break;
case UBLOX_STATE_TP5_CFG_READ:
psettp5_para = &ublox_para.tp5_para; //本地参数
ptp5_para = &ublox_para_read.tp5_para; //读取的参数
//需配置的参数,已在上电时配置好,与查询返回的比较
if((ptp5_para->tp_index !=psettp5_para->tp_index )||(ptp5_para->freq_period != psettp5_para->freq_period)||(ptp5_para->freq_period_lock !=psettp5_para->freq_period_lock )
||(ptp5_para->pulse_len_ratio != psettp5_para->pulse_len_ratio)||(ptp5_para->pulse_len_ratio_lock !=psettp5_para->pulse_len_ratio_lock ))
{
gps_info_printf("%s:Para Error! tpindex:%d,freqPeriod:%d,freqPeriodLock:%d,pulseRatio:0x%X,pulseRatioLock:0x%X.\n",__FUNCTION__,
ptp5_para->tp_index,ptp5_para->freq_period,ptp5_para->freq_period_lock,ptp5_para->pulse_len_ratio,
ptp5_para->pulse_len_ratio_lock);
gps_info_printf("\t Need Para tpindex:%d,freqPeriod:%d,freqPeriodLock:%d,pulseRatio:0x%X,pulseRatioLock:0x%X.\n",
psettp5_para->tp_index,psettp5_para->freq_period,psettp5_para->freq_period_lock,psettp5_para->pulse_len_ratio,
psettp5_para->pulse_len_ratio_lock);
ublox_state = UBLOX_STATE_TP5_CFG; //读取发现与需要不一致,需要配置参数
}
else
{ //跳过1PPS配置
gps_info_printf("%s:Set Successfull!tpindex:%d,freqPeriod:%d,freqPeriodLock:%d,pulseRatio:0x%X,pulseRatioLock:0x%X.\n",__FUNCTION__,
ptp5_para->tp_index,ptp5_para->freq_period,ptp5_para->freq_period_lock,ptp5_para->pulse_len_ratio,
ptp5_para->pulse_len_ratio_lock);
ublox_state = UBLOX_STATE_MODE_READ;
}
break;
case UBLOX_STATE_TP5_CFG:
ublox_state++;
break;
case UBLOX_STATE_TP5_CFG2:
ublox_state++;
break;
case UBLOX_STATE_MODE_READ:
{
S_UBLOX_TMODE_PARA *pmode_para = &ublox_para_read.mode_para;
S_UBLOX_TMODE_PARA *plocal_para = &ublox_para.mode_para;
if((pmode_para->time_mode!=plocal_para->time_mode)||(pmode_para->svin_mindur!=plocal_para->svin_mindur)||(pmode_para->svin_varlinmit!=plocal_para->svin_varlinmit))
{
gps_info_printf("%s:Set Error! time_mode:%d,svin_mindur:%d,svin_varlinmit:%d.\n",__FUNCTION__,
pmode_para->time_mode,pmode_para->svin_mindur,pmode_para->svin_varlinmit);
ublox_state = UBLOX_STATE_MODE_CFG;
}
else
{
gps_info_printf("%s:Set Successfull! time_mode:%d,svin_mindur:%d,svin_varlinmit:%d.\n",__FUNCTION__,
pmode_para->time_mode,pmode_para->svin_mindur,pmode_para->svin_varlinmit);
ublox_state = UBLOX_STATE_MSG_CFG;
}
}
break;
case UBLOX_STATE_MODE_CFG:
ublox_state++;
break;
case UBLOX_STATE_MSG_CFG:
if(ublox_cfg_msg_index+1<UBLOX_CFG_MSG_MAX)
{
UBLOX_FRAME_CLASS_ID *precmsg = &cfg_rec_msg[ublox_cfg_msg_index+1];
if((precmsg->frame_id!=0xff)||(precmsg->frame_class!=0xff))
{
ublox_cfg_msg_index++;
break; //直接返回,状态不加1,消息未配置完
}
}
ublox_state++;
break;
case UBLOX_STATE_SAVE_CFG:
{
//pS_RUN_TIME ptime = sys_get_run_time();
ublox_init_over_time = get_sys_tick(); //初始化完成获取当前时间
gps_info_printf("********************UBLOX_MOULE_INIT_OVER!************************\n");
//gps_info_printf("\ttime:%02d-%02d-%02d.\n",ptime->hour,ptime->min,ptime->sec);
gps_info_printf("******************************************************************\n");
ublox_state++;
}
break;
case UBLOX_STATE_INIT_OVER: //周期性需要发送的命令
break;
}
break;
default:
gps_info_printf("%s:Unknow ack id 0x%02X.\n",__FUNCTION__,pubx_msg->cfg_id);
break;
}
return GPS_ERROR_OK;
}
//mon信息报文,主要是HW信息
static E_GPS_ERROR ublox_ubx_proc_mon_reply(S_UBLOX_UBX_MSG *pubx_msg)
{
if(pubx_msg==NULL)
return GPS_ERROR_PTR_INVALID;
switch(pubx_msg->cfg_id)
{
case UBX_MON_HW:
{
#if GPS_INFO_DEBUG
static const char s_astatus[][12] ={"INIT","DONTKNOW","OK","SHORT","OPEN"};
static const char s_apower[][12] ={"OFF","ON","DONTKNOW"};
#endif
S_UBLOX_HW_PARA *phw =&ublox_para.hw_para;
if(pubx_msg->length!=sizeof(S_UBLOX_HW_PARA)) //当前为68字节
return GPS_ERROR_FORMAT;
if(pubx_msg->pdata==NULL)
return GPS_ERROR_PTR_INVALID;
memcpy(phw,pubx_msg->pdata,pubx_msg->length);
gps_info_printf("MON_HW_INFO:Noise:%d,agcCnt:%d,aStatus:%s,aPowe:%s,flags:%d.\n",
phw->noise_perms,phw->agc_cnt,s_astatus[phw->a_status&0x07],s_apower[phw->a_power&0x03],phw->flags);
}
break;
default:
gps_info_printf("%s:Unknow mon id %02X.\n",__FUNCTION__,pubx_msg->cfg_id);
break;
}
return GPS_ERROR_OK;
}
#if UBLOX_RXM_RAW_READ_INTERVAL
static E_GPS_ERROR ublox_ubx_proc_rxm_reply(S_UBLOX_UBX_MSG *pubx_msg)
{
uint32 max_len = 0;
uint32 i = 0;
uint32 max_sv = 0;
S_UBLOX_RAW_PARA *praw =&ublox_para.raw_para;
if(pubx_msg==NULL)
return GPS_ERROR_PTR_INVALID;
switch(pubx_msg->cfg_id)
{
case UBX_RXM_RAW:
max_len = pubx_msg->length>sizeof(S_UBLOX_RAW_PARA)?sizeof(S_UBLOX_RAW_PARA):pubx_msg->length;
if(pubx_msg->pdata==NULL)
return GPS_ERROR_PTR_INVALID;
memcpy(praw,pubx_msg->pdata,max_len);
max_sv = praw->num_sv>UBLOX_RXM_RAW_MAX_SV_NUM?UBLOX_RXM_RAW_MAX_SV_NUM:praw->num_sv;
if(max_sv!=0)
{
gps_info_printf("%s:satellite raw data tow:%dms,weed:%d,sv num:%d.Details:\n",__FUNCTION__,praw->i_tow,praw->week,praw->num_sv);
for(i=0;i<max_sv;i++)
{
gps_info_printf("\tnum:%02d,mesQI:%02d,cno:%02d,lli:%02d\n",
praw->sv_raw[i].sv,praw->sv_raw[i].mes_qi,praw->sv_raw[i].cno,praw->sv_raw[i].lli);
}
}
else
gps_info_printf("%s:satellite raw data sv num:0.\n",__FUNCTION__);
break;
default:
gps_info_printf("%s:Unknow rxm id %02X.\n",__FUNCTION__,pubx_msg->cfg_id);
break;
}
return GPS_ERROR_OK;
}
#endif
static E_GPS_ERROR ublox_ubx_proc_nav_reply(S_UBLOX_UBX_MSG *pubx_msg)
{
S_UBLOX_NAV_STATUS_PARA *pstatus;
if(pubx_msg==NULL)
return GPS_ERROR_PTR_INVALID;
switch(pubx_msg->cfg_id)
{
case UBX_NAV_STATUS:
if(pubx_msg->length!=sizeof(S_UBLOX_NAV_STATUS_PARA))
return GPS_ERROR_FORMAT;
if(pubx_msg->pdata==NULL)
return GPS_ERROR_PTR_INVALID;
pstatus = (S_UBLOX_NAV_STATUS_PARA*)pubx_msg->pdata;
#if GPS_TEST_DEBUG
memcpy((void*)&ublox_nav_status_para,(void*)pstatus,sizeof(ublox_nav_status_para));
#else
//再次判断锁定状态,防止误重启
if(ublox_gps_lock_frame)
{
if(ublox_last_lock_time+UBLOX_LOCK_TO_UNLOCK_TIMEWAIT<get_sys_tick())
{
if((pstatus->fix_stat!=UBX_NAV_GPS_NO_FIX)&&(pstatus->fix_stat!=UBX_NAV_GPS_TIME_ONLY_FIX))
{//处于锁定状态,说明未发送保文,异常,需重启,置重启标志,在proc_state函数中复位
ublox_need_restart++;
gps_info_printf("%s:lock status err!\n",__FUNCTION__);
}
else
{ //更新时间,等待下次检查
ublox_last_lock_time = get_sys_tick();
}
}
}
#endif
break;
default:
gps_info_printf("%s:Unknow nav id %02X.\n",__FUNCTION__,pubx_msg->cfg_id);
break;
}
return GPS_ERROR_OK;
}
//解析UBX协议
uint32 ublox_ubx_proc(uint8 *pbuf)
{
uint32 proc_len = 0;
uint32 cpy_len = 0;
UBLOX_UBX_SUM ubx_sum;
if(pbuf==NULL)
return 0;
if((*pbuf!=UBLOX_SYNC_CHAR1)||(*(pbuf+1)!=UBLOX_SYNC_CHAR2))
return 0;
memset(&ublox_rec_msg,0,sizeof(ublox_rec_msg));
memcpy(&ublox_rec_msg,pbuf,OFFSET_OF_STRUCT(S_UBLOX_UBX_MSG,pdata)); //拷贝数据头的内容
pbuf+=OFFSET_OF_STRUCT(S_UBLOX_UBX_MSG,pdata);
cpy_len = ublox_rec_msg.length>UBLOX_MAX_DATE_REC_BUF_LEN?UBLOX_MAX_DATE_REC_BUF_LEN:ublox_rec_msg.length;
memcpy(ublox_rec_buf,pbuf,cpy_len); //拷贝数据区内容
pbuf+=ublox_rec_msg.length; //调整偏移
memcpy(&ublox_rec_msg.sum,pbuf,sizeof(UBLOX_UBX_SUM)); //校验和
ublox_rec_msg.pdata = &ublox_rec_buf[0];
ublox_get_sum(&ublox_rec_msg,&ubx_sum); //若数据区长度过大,此处校验和不准确
if((ubx_sum.ck_a!=ublox_rec_msg.sum.ck_a)||(ubx_sum.ck_b!=ublox_rec_msg.sum.ck_b))
{
gps_info_printf("%s:Check sum Err! rec cka:%02X,ckb:%02X,calc a:%02X,b:%02X.\n",__FUNCTION__,
ublox_rec_msg.sum.ck_a,ublox_rec_msg.sum.ck_b,ubx_sum.ck_a,ubx_sum.ck_b);
return 0;
}
switch(ublox_rec_msg.cfg_class)
{
case UBLOX_MSG_ACK:
gps_info_printf("%s:UBLOX_MSG_ACK.\n",__FUNCTION__);
ublox_ubx_proc_ack_reply(&ublox_rec_msg);
break;
case UBLOX_MSG_CFG:
gps_info_printf("%s:UBLOX_MSG_CFG.\n",__FUNCTION__);
ublox_ubx_proc_cfg_reply(&ublox_rec_msg);
break;
case UBLOX_MSG_MON:
gps_info_printf("%s:UBLOX_MSG_MON.\n",__FUNCTION__);
ublox_ubx_proc_mon_reply(&ublox_rec_msg);
break;
#if UBLOX_RXM_RAW_READ_INTERVAL
case UBLOX_MSG_RXM:
gps_info_printf("%s:UBLOX_MSG_RXM.\n",__FUNCTION__);
ublox_ubx_proc_rxm_reply(&ublox_rec_msg);
break;
#endif
case UBLOX_MSG_NAV:
gps_info_printf("%s:UBLOX_MSG_NAV.\n",__FUNCTION__);
ublox_ubx_proc_nav_reply(&ublox_rec_msg);
break;
default:
gps_info_printf("%s:class:%02X,ID:%02X\n",__FUNCTION__,ublox_rec_msg.cfg_class,ublox_rec_msg.cfg_id);
break;
}
return proc_len;
}
/*****************************************************************************
函 数 名 : gps_proc_ubx_nmea
功能描述 : 解析GPS模块返回的报文信息,使用UBLOX模块,返回报文有两种了类型,要
分别解析处理,另外由于GPS模块返回信息较快,当前串口相应模式下,一次处理
信息中可能有多个命令帧,需考虑如何解析
输入参数 : PROC_BUFFER_S *psbuf
输出参数 : 无
返 回 值 : uint8*
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2012年9月11日
作 者 : 郭金涛
修改内容 : 新生成函数
*****************************************************************************/
uint8* gps_proc_ubx_nmea(PROC_BUFFER_S *psbuf)
{
uint32 i = 0;
uint8 *pdata = psbuf->rxRec;
E_GPS_ERROR gps_error = GPS_ERROR_OK;
psbuf->msgtype = MSG_UNKNOW;
(void)gps_error;
for(i=0;i<psbuf->rxReclen;i++,pdata++)
{
if(psbuf->msgtype==MSG_UNKNOW)
{ //找有效字节
if((*pdata!='$')&&(*pdata!=UBLOX_SYNC_CHAR1))
continue;
if(*pdata=='$')
psbuf->msgtype= MSG_START; //nmea协议类型
else if((*pdata==UBLOX_SYNC_CHAR1)&&(*(pdata+1)==UBLOX_SYNC_CHAR2))
psbuf->msgtype = MSG_UBX; //ubx协议类型
else
continue;
}
if(psbuf->msgtype==MSG_START)
{ //超过配置时间未锁定,需发送重启命令
if(!memcmp(pdata,"$GPGSA",strlen("$GPGSA"))) //星体
{
psbuf->msgtype = MSG_SA;
}
else if(!memcmp(pdata,"$GPRMC",strlen("$GPRMC"))) //时间
{
psbuf->msgtype=MSG_DA;
}
else if(!memcmp(pdata,"$POLYP",strlen("$POLYP"))) //卫星定位信息 新的ublox暂无此协议
{
psbuf->msgtype=MSG_POLYP;
}
else
{
psbuf->msgtype = MSG_UNKNOW;
}
if(psbuf->msgtype!=MSG_UNKNOW)
{
if(gps_check_sum(pdata))
{
gps_info_printf("%s:NMEA check sum err!\n",__FUNCTION__);
psbuf->msgtype =MSG_UNKNOW;
continue;
}
switch(psbuf->msgtype)
{
case MSG_DA: //日期
gps_error = gps_proc_GPRMC(pdata);
switch(gps_error)
{
case GPS_ERROR_OK:
ublox_gps_lock_frame++;
ublox_last_lock_time = get_sys_tick();
break;
case GPS_ERROR_INVALID:
break;
default:
//printf("%s:rec MSG_DA Error %d!\n",__FUNCTION__,gps_error);
break;
}
break;
case MSG_SA: //星体
gps_error =gps_proc_GPGSA(pdata);
/*if(gps_error!=OK)
printf("%s:rec MSG_SA Error %d!\n",__FUNCTION__,gps_error);
else
{
printf("%s:rec MSG_SA Successfull!\n",__FUNCTION__);
printf("\tsat %d\n",gps_sa.sv);
}*/
break;
default:
break;
}
}
}
else if(psbuf->msgtype == MSG_UBX) //UBX协议
{
ublox_ubx_proc(pdata);
}
psbuf->msgtype=MSG_UNKNOW;
}
return 0;
}
#if GPS_TEST_DEBUG
uint32 ublox_get_nav_status(void)
{
return ublox_nav_status_para.fix_stat;
}
#endif
void gps_hw_reset(void)
{
#if 1//_USE_RVL_
fpga_byte_write(0x01,0xf0,0x5a);
delay_ms(300); //防止任务切换,重新发送段地址
fpga_byte_write(0x01,0xf0,0x00);
#endif
}
/************************************************************************************************
功能:将输入的字符串中的小写字母转换为大写,其它不做处理
************************************************************************************************/
void str_uppercase(char* pbuf,uint32 len)
{
if(pbuf==NULL)
return;
while((*pbuf)&&(len))
{
*pbuf=((*pbuf<='z')&&(*pbuf>='a'))?(*pbuf&(0xdf)):*pbuf;
pbuf++;
len--;
}
}
//返回字符串中的数值,以输入字符为结束符.字符为10进制
static uint32 get_num_with_char(uint8 *pbuf,uint8 ch)
{
uint32 num =0;
while((*pbuf!=ch)&&(*pbuf))
{
if((*pbuf<='9')&&(*pbuf>='0'))
num = num*10+(*pbuf-'0');
else
break;
pbuf++;
}
return num;
}
//解析指定字节长度的字符,转换为数值
static uint32 get_num_with_len(char *pbuf,uint32 len,BOOL ishex)
{
uint32 num =0;
if(ishex==FALSE)
{
while(len)
{
if((*pbuf<='9')&&(*pbuf>='0'))
num = num*10+(*pbuf-'0');
else
break;
pbuf++;
len--;
}
}
else
{
str_uppercase((char*)pbuf,len); //先统一转换为大写字母处理
while(len)
{
if((*pbuf<='9')&&(*pbuf>='0'))
num = num*16+(*pbuf-'0');
else if((*pbuf<='F')&&(*pbuf>='A'))
num = num*16+(*pbuf-'A'+10);
else
break;
pbuf++;
len--;
}
}
return num;
}
void gps_uart_proc(MSG *pmsg)
{
static PROC_BUFFER_S recbuf;
if(!pmsg->wPara)
{
return;
}
if(!pmsg->lPara)
{
return;
}
log_printf(LOG_DEBUG,I_NOUSED,"gps_uart_proc len=%d,bf_len=%d\n",pmsg->wPara,sizeof(recbuf.rxRec));
recbuf.rxReclen = pmsg->wPara;
if(recbuf.rxReclen < sizeof(recbuf.rxRec))
{
memcpy(recbuf.rxRec,(void*)pmsg->lPara,pmsg->wPara);
//printf("GPS_R:len=%d,%s\n",pmsg->wPara,recbuf.rxRec);
//解析收取报文中的信息,可能含有多条有效信息,
log_printf(LOG_DEBUG,I_NOUSED,"gps_uart_proc 1.\n");
gps_proc_ubx_nmea(&recbuf);
log_printf(LOG_DEBUG,I_NOUSED,"gps_uart_proc 2.\n");
}
}
void rtc_update_by_gps(GPRMC_T *p)
{
S_SYS_TIME sys_time={0};
sys_time.year = p->year-1900;
sys_time.date = p->day;
sys_time.month= p->month;
sys_time.hour = p->hour; //默认为24小时模式
sys_time.min = p->min;
sys_time.sec = p->sec;
sys_time.valid = 1;
usr_set_sys_rtc_time(&sys_time);
}
//处理返回时间
//$GPRMC,hhmmss.sss,status,latitude,N,Hemisphere,longitude,E,spd,cmg,ddmmyy,mv,mvd,Mode*cs
//$GPRMC,025518.005,A,3110.365007,N,12123.814054,E,0.051,31.17,260711,,,A*68
//$GPRMC,032739.00, A,3110.45065, N,12123.82896, E,0.007,,130912,,,A*7C
E_GPS_ERROR gps_proc_GPRMC(uint8 *pbuf)
{
uint8 *pbak;
uint32 i;
pbuf +=(sizeof("$GPRMC")-1);
if(*pbuf++!=',')
return GPS_ERROR_HEADER;
gps_set_time(pbuf);
pbuf+=(sizeof("hhmmss.ss")-1);
if(*pbuf++!=',')
return GPS_ERROR_HEADER;
if(*pbuf++=='A')
time_temp.valid = 1;
else
return GPS_ERROR_INVALID; /*需确定是否直接返回,不再解析*/
if(*pbuf++!=',')
return GPS_ERROR_HEADER;
gps_set_area(pbuf);
//ddmm.mmmmm,N,dddmm.mmmmm,E, //新的ublox模块
pbuf+=(sizeof("ddmm.mmmmm,N,dddmm.mmmmm,E")-1);
if(*pbuf++!=',')
return GPS_ERROR_FORMAT;
//速度 和cmg长度未知
pbak = (uint8*)strchr((const char *)pbuf,',');
if((!pbak)||((pbak-pbuf)>10))
return GPS_ERROR_NUM;
if(str_to_float(pbuf,pbak-pbuf,&i))
return GPS_ERROR_NUM;
time_temp.speed = i;
pbuf = pbak;
pbuf++;
pbak = (uint8 *)strchr((const char *)pbuf,',');
if((!pbak)||((pbak-pbuf)>10))
return GPS_ERROR_NUM;
if(str_to_float(pbuf,pbak-pbuf,&i))
return GPS_ERROR_NUM;
time_temp.cmg = i;
pbuf = pbak;
pbuf++;
gps_set_date(pbuf);
utc_to_localtime(&time_temp);
memcpy(&gps_time,&time_temp,sizeof(gps_time));
rtc_update_by_gps(&gps_time);
return GPS_ERROR_OK;
}
//处理返回的卫星信息
//$GPGSA,Smode,FS,sv,sv,sv,sv,,,,,,,,PDOP,HDOP,VDOP*cs
//$GPGSA,A,2,16,06,14,25,,,,,,,,,5.25,2.01,4.85*08
E_GPS_ERROR gps_proc_GPGSA(uint8 *pbuf)
{
uint32 i;
pbuf +=(sizeof("$GPGSA")-1);
if(*pbuf++!=',')
return GPS_ERROR_HEADER;
switch(*pbuf++)
{
case 'A':case 'a':
gps_sa.mode = AUTO;
break;
case 'M':case 'm':
gps_sa.mode = MANUAL;
default:return GPS_ERROR_INVALID;
}
if(*pbuf++!=',')
return GPS_ERROR_HEADER;
if(str_to_int(pbuf++,1,&i))
return GPS_ERROR_NUM;
if((i>3)||(i<1))
return GPS_ERROR_NUM;
gps_sa.fix_status =(FIX_STATUS_E)i;
if(*pbuf++!=',')
return GPS_ERROR_HEADER;
//使用中的星体
gps_sa.sv = 0;
for(i=0;i<12;i++)
{
if(*pbuf==',')
{
pbuf++;
continue;
}
gps_sa.sv++;
pbuf+=3;
}
if(*pbuf == ',')
pbuf++;
//是否可以不解析
/*
if(str_to_float(pbuf,4,&i))
return GPS_ERROR_NUM;
gps_sa.pdop = i;
pbuf+=4;
if(*pbuf++!=',')
return GPS_ERROR_FORMAT;
if(str_to_float(pbuf,4,&i))
return GPS_ERROR_NUM;
gps_sa.hdop = i;
pbuf+=4;
if(*pbuf++!=',')
return GPS_ERROR_HEADER;
if(str_to_float(pbuf,4,&i))
return GPS_ERROR_NUM;
gps_sa.vdop = i;*/
return GPS_ERROR_OK;
}
//gps_polyp
E_GPS_ERROR gps_proc_POLYP(uint8 *pbuf)
{
pbuf +=(sizeof("$POLYP")-1);
if(*pbuf++!=',')
goto LABEL_ERR;
pbuf+=(sizeof("hhmmss.sss")-1);
if(*pbuf++!=',')
goto LABEL_ERR;
gps_polyp.latitude.integer = get_num_with_char(pbuf,'.');
pbuf+=strlen("ddmm.");
gps_polyp.latitude.ft= get_num_with_len((char*)pbuf,6,TRUE);
pbuf+=strlen("mmmmmm"); //解析纬度信息
if(*pbuf++!=',')
goto LABEL_ERR;
if(*pbuf=='N')
gps_polyp.latitude.hemisphere = 0;
else if(*pbuf=='S')
gps_polyp.latitude.hemisphere = 1;
else
goto LABEL_ERR;
*pbuf++; //N S
if(*pbuf++!=',')
goto LABEL_ERR;
gps_polyp.longitude.integer = get_num_with_char(pbuf,'.');
pbuf+=strlen("dddmm.");
gps_polyp.longitude.ft= get_num_with_len((char*)pbuf,6,TRUE);
pbuf+=strlen("mmmmmm");
if(*pbuf++!=',')
goto LABEL_ERR;
if(*pbuf=='E')
gps_polyp.longitude.direction = 0;
else if(*pbuf=='W')
gps_polyp.longitude.direction = 1;
else
goto LABEL_ERR;
gps_polyp.valid = TRUE;
return GPS_ERROR_OK;
LABEL_ERR:
return GPS_ERROR_FORMAT;
}
uint32 gps_check_sum(uint8 *pbuf)
{
uint32 rec_sum = 0;
uint8 *psum = 0;
uint32 len = 0;
if(!pbuf)
return ERR;
psum = (uint8 *)strchr((const char *)pbuf,'*');
if(!psum)
return GPS_ERROR_HEADER;
len = (uint32)psum>(uint32)pbuf?(uint32)psum-(uint32)pbuf-1:(uint32)pbuf-(uint32)psum-1;
psum++; //*
if(str_to_hex(psum,2,&rec_sum))
return GPS_ERROR_NUM;
if(rec_sum == gps_get_sum(pbuf+1,len)) //$ * sum(2字节)共4字节
return GPS_ERROR_OK;
else
return GPS_ERROR_SUM;
}
//$符号和sum前的*不做计算,$和*中间的异或计算
uint8 gps_get_sum(uint8 *pbuf,uint32 len)
{
uint8 sum = 0;
if(!pbuf)
return sum;
while(len--)
sum ^=*pbuf++;
return sum;
}
uint32 gps_set_time(uint8 *pbuf)
{
uint32 i;
if(str_to_int(pbuf,2,&i))
return ERR;
time_temp.hour = i;
pbuf+=2; //hh
if(str_to_int(pbuf,2,&i))
return ERR;
time_temp.min =i;
pbuf+=2; //mm
if(str_to_int(pbuf,2,&i))
return ERR;
time_temp.sec =i;
pbuf+=2; //ss
if(*pbuf++!='.')
return ERR;
if(str_to_int(pbuf,2,&i))
return ERR; //sss
time_temp.ms = i;
if((time_temp.hour>=24)||(time_temp.min>=60)||(time_temp.sec>=60))
return ERR;
return OK;
}
uint32 gps_set_date(uint8 *pbuf)
{
uint32 i;
if(str_to_int(pbuf,sizeof("dd")-1,&i))
return ERR;
if(i>31)
return ERR;
time_temp.day = i;
pbuf+=(sizeof("dd")-1);
if(str_to_int(pbuf,sizeof("mm")-1,&i))
return ERR;
if(i>12)
return ERR;
time_temp.month = i;
pbuf+=(sizeof("mm")-1);
if(str_to_int(pbuf,sizeof("yy")-1,&i))
return ERR;
time_temp.year = 2000+i;
return OK;
}
//ddmm.mmmmmm,N,dddmm.mmmmmm,E //老模块
//ddmm.mmmmm,N,dddmm.mmmmm,E //新的ublox模块
uint32 gps_set_area(uint8 *pbuf)
{
time_temp.latitude.integer = get_num_with_char(pbuf,'.');
while(*pbuf++!='.');
time_temp.latitude.ft= get_num_with_char(pbuf,',');
while(*pbuf++!=',');
if((*pbuf=='N')||(*pbuf=='n'))
time_temp.latitude.hemisphere = 0;
else if((*pbuf=='S')||(*pbuf=='s'))
time_temp.latitude.hemisphere = 1;
else
goto LABEL_ERR;
pbuf++; //N S
if(*pbuf++!=',')
goto LABEL_ERR;
time_temp.longitude.integer = get_num_with_char(pbuf,'.');
while(*pbuf++!='.');
time_temp.longitude.ft= get_num_with_char(pbuf,',');
while(*pbuf++!=',');
if((*pbuf=='E')||(*pbuf=='e'))
time_temp.longitude.direction = 0;
else if((*pbuf=='W')||(*pbuf=='w'))
time_temp.longitude.direction = 1;
else
goto LABEL_ERR;
return OK;
LABEL_ERR:
return ERR;
}
uint32 str_to_int(uint8 *pbuf,uint8 len,uint32 *result)
{
uint32 i=0;
uint8 c=0;
if((!pbuf)||(!result))
return ERR;
while(len--)
{
c=*pbuf++;
if((c>='0')&&(c<='9'))
{
c-='0';
i*=10;
i+=c;
}
else
{
return ERR;
}
}
*result = i;
return OK;
}
uint32 str_to_hex(uint8 *pbuf,uint8 len,uint32 *result)
{
uint32 i=0;
uint8 c=0;
if((!pbuf)||(!result))
return ERR;
while(len--)
{
c=*pbuf++;
if((c>='0')&&(c<='9'))
c=c-'0';
else if((c>='a')&&(c<='f'))
c=c-'a'+10;
else if((c>='A')&&(c<='F'))
c=c-'A'+10;
else
return ERR;
i<<=4;
i+=c;
}
*result = i;
return OK;
}
uint32 str_to_float(uint8 *pbuf,uint8 len,uint32 *result)
{
float f = 0,t=0;
uint8 c = 0;
uint8 flag=0;
if((!pbuf)||(!result))
return ERR;
while(len--)
{
c=*pbuf++;
if((c>='0')&&(c<='9'))
{
c-='0';
if(!flag)
{
f*=10;
f+=c;
}
else
{
int i = flag;
t = c;
while(i--)
t/=10;
f+=t;
flag++;
}
}
else if(c=='.')
{
flag =1;
}
else
return ERR;
}
*result =FLOAT_TO_INT_PTR(f);
return OK;
}
uint32 str_to_double(uint8 *pbuf,uint8 len,uint64 *result)
{
double f = 0,t=0;
uint8 c = 0;
uint8 flag=0;
if((!pbuf)||(!result))
return ERR;
while(len--)
{
c=*pbuf++;
if((c>='0')&&(c<='9'))
{
c-='0';
if(!flag)
{
f*=10;
f+=c;
}
else
{
int i = flag;
t = c;
while(i--)
t/=10;
f+=t;
flag++;
}
}
else if(c=='.')
{
flag =1;
}
else
return ERR;
}
*result =DOUBLE_TO_INT_PTR(f);
return OK;
}
const static uint8 month_day[]={0,31,28,31,30,31,30,31,31,30,31,30,31,0};
void inc_hour(GPRMC_T *ptime,uint8 num)
{
if(ptime->hour+num<24)
{
ptime->hour+=num;
return;
}
ptime->hour=ptime->hour+num-24;
ptime->day++;
if(ptime->day<=month_day[ptime->month])
return;
if(ptime->month==2) //需考虑闰年
{ //能被4并且不能被100整除,或者能被400整除
if(((ptime->year%4==0) && (ptime->year%100!=0)) ||(ptime->year%400==0))
{
if(ptime->day<=month_day[2]+1)
return;
}
}
ptime->day = 1;
ptime->month ++;
if(ptime->month>12)
{
ptime->month=1;
ptime->year++;
}
}
void dec_hour(GPRMC_T *ptime,uint8 num)
{
if(ptime->hour-num>=0)
{
ptime->hour-=num;
return;
}
ptime->hour=ptime->hour+24-num;
if(ptime->day>1)
{
ptime->day--;
return;
}
else
{
if(ptime->month>1)
{
ptime->month--;
ptime->day = month_day[ptime->month];
if(ptime->month==2) //需考虑闰年
{ //能被4并且不能被100整除,或者能被400整除
if(((ptime->year%4==0) && (ptime->year%100!=0)) ||(ptime->year%400==0))
{
ptime->day=month_day[2]+1;
}
}
return;
}
else
{
ptime->month=12;
ptime->day = month_day[12];
ptime->year--;
}
}
}
void utc_to_localtime(GPRMC_T *ptime)
{
if(!ptime)
return;
#if 1//_USE_RVL_
if(atsc_para.wj_para.gmt>=0)//if(dvbt_para.wj_para.gmt>=0)
inc_hour(ptime,atsc_para.wj_para.gmt);
else
dec_hour(ptime,-atsc_para.wj_para.gmt);
return;
#endif
}
S_SYS_TIME *gps_get_time(void)
{
static S_SYS_TIME sys_time={0};
usr_get_sys_rtc_time(&sys_time,NULL);
if(sys_time.year>=100)
sys_time.year=sys_time.year-100;
return &sys_time;//os_get_sys_time_ptr();
}
GPGSA_T *gps_get_sa(void)
{
return &gps_sa;
}
/*
pS_RUN_TIME sys_get_run_time(void)
{
static S_RUN_TIME temp_run_time;
memcpy(&temp_run_time,&run_time,sizeof(run_time));
return &temp_run_time;
}*/
POLYP_T *gps_get_polyp(void)
{
gps_polyp.latitude = gps_time.latitude;
gps_polyp.longitude = gps_time.longitude;
gps_polyp.valid = (BOOL)gps_time.valid;
return &gps_polyp;
}
S_UBLOX_HW_PARA *gps_ublox_get_hw_info(void)
{
return &ublox_para.hw_para;
}
/*
void gps_task(void * pvParameters)
{
MSG *pmsg = NULL;
(void)pvParameters;
#if 1//_USE_RVL_
uart_com_init(GPS_COMM_NUM,GPS_COMM_BAUD,PARITY_NO,INT_ON);
#endif
gps_ublox_init();
config_time_msg(MSG_SEC);
gps_info_printf("Ublox GPS uart init over.\n");
while((pmsg = get_msg(OS_WAIT_FOREVER))!=NULL)
{
switch(pmsg->type)
{
case MSG_RS232:
gps_uart_proc(pmsg);
break;
case MSG_SEC:
task_is_ok();
ublox_proc_state();
break;
default:
break;
}
if(MSG_NEED_TO_FREE(pmsg))
free_msg(pmsg);
}
}
*/
#if 1
#define DBG_GPS_232 1
extern int rs232_send_string(const uint8 *pbuf,uint32 len);
void * gps_uart_thr(void * args)
{
int nread;
MSG msg;
int ret;
static int sec_cnt=0;
log_printf(LOG_DEBUG,I_NOUSED,"[.thr.] gps_uart_thr Start.\n");
while(1) {
//O_NONBLOCK
nread = gps_rs232_read_string(gps_uart_recv_buff, sizeof(gps_uart_recv_buff) );
if (nread > 0) {
//printf("recv:%s\n",gps_uart_recv_buff);
log_printf(LOG_DEBUG,I_NOUSED,"gps uart recv someth,len=%d\n",nread);
memset(gps_cmd_buff, 0 ,sizeof(gps_cmd_buff));
memcpy(gps_cmd_buff, gps_uart_recv_buff, nread);
msg.type = MSG_RS232;
msg.need_free = MSG_NO_NEED_FREE; // lpara no need free
msg.lPara = (uint32)&gps_cmd_buff;
msg.wPara = nread;
msg.rPara = UART_USER_232_COM;
ret = msg_send_to_gps_uart(&msg);//cttb_msg_send_to_uart
if(ret<0){
fprintf(stderr, "Err.msg_send_to_gps_uart[errno=%d]\n", errno);
usleep(200*1000);
}
}
usleep(5000);// wait 5ms
}
}
#endif