/** ****************************************************************************** * @file name : gps.c * @author : * @version : * @date : * @brief : gps uart for atsc ****************************************************************************** * @attention //USE_GPS // ****************************************************************************** */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 #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*SYSTICKHZhour,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_TIMEWAITcfg_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+1frame_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;isv_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_TIMEWAITfix_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;irxReclen;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