1188 lines
36 KiB
C
1188 lines
36 KiB
C
/*============================================================================================
|
||
Copyright(c) 2018 Quectel Wierless Solution,Co.,Ltd. All Rights Reserved.
|
||
Quectel Wireless Solution Proprietary and Confidential.
|
||
============================================================================*/
|
||
|
||
#include "quec_hx_gps.h"
|
||
#include "quec_rtos.h"
|
||
#include "gps_debug.h"
|
||
#include "gps_channel.h"
|
||
#include "quec_hx_gps_update.h"
|
||
#include "quec_nmea_parse.h"
|
||
#include "quec_gps_rom.h"
|
||
#include "gps_app.h"
|
||
#include "quec_hx_apflash.h"
|
||
#include "quec_cust_feature.h"
|
||
#include "quec_hx_agps.h"
|
||
#include "quec_gps_http.h"
|
||
|
||
|
||
|
||
#define QUEC_GNSS_MSG_MAX_ITEM_NBR 50
|
||
#define QUEC_GPS_TASK_STACK_SIZE 10*1024
|
||
#define APFLASH_DATA_LEN 4*1024
|
||
#define HX_GPS_KEEPALIVE_CNT 5*1000 //5S内没有nmea语句将会重启gps模块
|
||
|
||
QUEC_GPS_DEV_T g_quec_gps_dev;
|
||
QUEC_GPS_OPS g_quec_gps_ops;
|
||
QUEC_NMEA_CB g_quec_nmea_cb;
|
||
hx_locationg_t hx_loactiong_para;/*解析出的位置信息*/
|
||
extern int quec_gnss_type_check(void);
|
||
static int gnss_rom_type;
|
||
|
||
//多合一固件当前的gnss类型
|
||
hx_gnss_sys_t quec_hxgps_type = GNSS_SYS;
|
||
|
||
#if 0
|
||
hx_locationg_t hx_loactiong_para_back;
|
||
#endif
|
||
quec_gnss_sate_num_t gnss_sate_num;
|
||
|
||
#ifdef QUEC_HX_GNSS_SUPPORT
|
||
#include "gps_app.h"
|
||
//定义全局变量保存HTTP账号和密码,防止在头文件中被开源出去
|
||
quec_agps_cfg_t quec_hx_agps_cfg={
|
||
.profile_inx=1,\
|
||
.agps_url="http://quectel-api1.rx-networks.cn/rxn-api/locationApi/rtcm\0",\
|
||
.agpsvendorID="wLgWwv6JQt\0",\
|
||
.agpsmodelID="Quectel\0",\
|
||
.agpspassWord="aFltUERDZzZxeTY5cEp2eA==\0"\
|
||
};
|
||
|
||
#endif
|
||
|
||
|
||
#define ARRAY_LENGTH(a) (sizeof a / sizeof (a[0]))
|
||
extern int nmea_parse_aidinfo( quec_gnss_sate_num_t * gnss_sate_num,char *sentence);
|
||
int quec_hx_gnss_sys_set(int sys_type)
|
||
{
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
if(quec_hxgps_type==BEIDOU_ONLY)
|
||
{
|
||
return 0;
|
||
}
|
||
#endif
|
||
quec_gps_msg_t cmd_ptr;
|
||
memset(&cmd_ptr,0,sizeof(quec_gps_msg_t));
|
||
int cfg_sys = 0;
|
||
|
||
cfg_sys=sys_type;
|
||
if((cfg_sys<=8)&&(cfg_sys>=0))
|
||
{
|
||
char *data=malloc(4);
|
||
if(NULL==data)
|
||
{
|
||
return -1;
|
||
}
|
||
memcpy(data,&cfg_sys,4);
|
||
cmd_ptr.cmd_id = QUEC_GNSS_CFGSYS;
|
||
cmd_ptr.data = data;
|
||
quec_gnss_cmd_send(&cmd_ptr);
|
||
free(data);
|
||
}
|
||
return 0;
|
||
|
||
}
|
||
/****************************************************
|
||
nmea语句 value
|
||
禁用 0
|
||
GGA 1
|
||
RMC 2
|
||
GSV 4
|
||
GSA 8
|
||
VTG 16
|
||
GLL 32
|
||
全部打开 63
|
||
*****************************************************/
|
||
int quec_hx_gnss_nmea_set(char value)
|
||
{
|
||
int i=0;
|
||
quec_gps_msg_t cmd_ptr;
|
||
memset(&cmd_ptr,0,sizeof(quec_gps_msg_t));
|
||
char *data = NULL;
|
||
cmd_ptr.cmd_id = QUEC_GNSS_NMEA_TYPE;
|
||
uint16 quec_gnss_nmea_type[]={0,4,3,2,5,1};
|
||
for(i=0;i<6;i++)
|
||
{
|
||
data=malloc(4);
|
||
if(NULL==data)
|
||
{
|
||
return -1;
|
||
}
|
||
else{
|
||
memset(data,0,4);
|
||
}
|
||
|
||
data[0] = quec_gnss_nmea_type[i];
|
||
data[1] = (value & 0x1);
|
||
value = value >>1;
|
||
cmd_ptr.data = data;
|
||
quec_gnss_cmd_send(&cmd_ptr);
|
||
free(data);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/********************************************************************
|
||
R3.4.0.0以下版本(国内镜像包)
|
||
value:
|
||
0 H1: GPS
|
||
5 H11: GPS+BDS
|
||
7 H10: BDS
|
||
|
||
R3.4.1.12 适用如下配置 北斗支持B1I
|
||
value:
|
||
0 H1: GPS
|
||
1 H11: GPS+BDS
|
||
3 H1101: GPS+GLONASS+GALILEO
|
||
4 H101: GPS+ GLONASS
|
||
5 H1011: GPS+BDS+GALILEO
|
||
6 H1001: GPS+GALILEO
|
||
7 H10: BDS
|
||
和芯CC1161W支持4个星系随意组合,北斗支持B1I+B1C,QZSS和GPS绑定关系
|
||
新增2,8两个组合,后续可以根据客户需求进行扩展
|
||
0 H10001: GPS
|
||
1 H10091: GPS+BDS
|
||
2 H11191: GPS+BDS+GALILEO+GLONASS
|
||
3 H11101: GPS+GLONASS+GALILEO
|
||
4 H10101: GPS+GLONASS
|
||
5 H11091: GPS+BDS+GALILEO
|
||
6 H11001: GPS+GALILEO
|
||
7 H90: BDS
|
||
8 H10191: GPS+BDS+GLONASS
|
||
|
||
*********************************************************************/
|
||
static int quec_gnss_cmd_cfgsys_process(quec_gps_msg_t *cmd_ptr)
|
||
{
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
uint16 quec_gnss_cfgsys_table_v2[]={10001,10091,11191,11101,10101,11091,11001,90,10191};
|
||
#else
|
||
uint16 quec_gnss_cfgsys_table_v2[]={1,11,0,1101,101,1011,1001,10,0};
|
||
#endif
|
||
int data = *(int*)(cmd_ptr->data);
|
||
if((data<0)||(data>8))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
return quec_gnss_cfgsys_table_v2[data];
|
||
}
|
||
|
||
//修复CC11系列1PPS有380ms的误差,在初始化gnss时发送命令消除
|
||
void quec_gnss_cmd_1pps_config(void)
|
||
{
|
||
int i=0;
|
||
quec_gps_msg_t cmd_ptr;
|
||
memset(&cmd_ptr,0,sizeof(quec_gps_msg_t));
|
||
cmd_ptr.cmd_id = QUEC_GNSS_1PPS_CONFIG;
|
||
cmd_ptr.data = NULL;
|
||
quec_gnss_cmd_send(&cmd_ptr);
|
||
return 0;
|
||
}
|
||
|
||
int quec_gps_reset(int type)
|
||
{
|
||
quec_gps_msg_t cmd_ptr;
|
||
QUEC_GPS_DEV_T *gps_dev=quec_get_gps_dev();
|
||
|
||
if(!(gps_dev->worke_state & QUEC_NMEA_PASRE_STATE)){//必须时等到gps开始输出nmea语句时才允许发指令
|
||
return -3;
|
||
}
|
||
memset(&cmd_ptr,0,sizeof(quec_gps_msg_t));
|
||
|
||
if((type<QGPS_START_COLD)||(type>QGPS_START_WARM))
|
||
{
|
||
return -1;
|
||
}
|
||
switch(type)
|
||
{
|
||
case QGPS_START_COLD:
|
||
cmd_ptr.cmd_id = QUEC_GNSS_COLD_RESET;
|
||
cmd_ptr.data = NULL;
|
||
break;
|
||
case QGPS_START_WARM:
|
||
cmd_ptr.cmd_id = QUEC_GNSS_WARM_RESET;
|
||
cmd_ptr.data = NULL;
|
||
break;
|
||
case QGPS_START_HOT:
|
||
cmd_ptr.cmd_id = QUEC_GNSS_HOT_RESET;
|
||
cmd_ptr.data = NULL;
|
||
break;
|
||
|
||
default:
|
||
return -2;
|
||
}
|
||
quec_gnss_cmd_send(&cmd_ptr);
|
||
gps_dev->worke_state |= QUEC_GPS_RESET_STATE;
|
||
|
||
return 0;
|
||
}
|
||
|
||
#if 0
|
||
void quec_gnss_aidpos_msg_send(void)
|
||
{
|
||
|
||
quec_gps_msg_t cmd_ptr;
|
||
memset(&cmd_ptr,0,sizeof(quec_gps_msg_t));
|
||
cmd_ptr.cmd_id = QUEC_GNSS_AIDPOS_SET;
|
||
cmd_ptr.data = NULL;
|
||
quec_gnss_cmd_send(&cmd_ptr);
|
||
}
|
||
#endif
|
||
void quec_gnss_aidtime_msg_send(void)
|
||
{
|
||
|
||
quec_gps_msg_t cmd_ptr;
|
||
memset(&cmd_ptr,0,sizeof(quec_gps_msg_t));
|
||
cmd_ptr.cmd_id = QUEC_GNSS_AIDTIME_SET;
|
||
cmd_ptr.data = NULL;
|
||
quec_gnss_cmd_send(&cmd_ptr);
|
||
}
|
||
|
||
int quec_gnss_nmea_cnf(void)
|
||
{
|
||
QuecOSStatus err = kNoErr;
|
||
quec_gps_handle *quec_param_ptr = quec_gnss_config_para_get();
|
||
if((quec_param_ptr->nmea_handle_cfg.mdflag&GNSS_SYSCONFGE_ENABLE)==0){
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
if(quec_hxgps_type==BEIDOU_ONLY)
|
||
{
|
||
quec_param_ptr->nmea_handle_cfg.gnss_sys_type = BEIDOU_SYS;
|
||
}
|
||
else
|
||
{
|
||
quec_param_ptr->nmea_handle_cfg.gnss_sys_type = GPS_BEIDOU_GALILEO_SYS;
|
||
}
|
||
#else
|
||
quec_param_ptr->nmea_handle_cfg.gnss_sys_type = GPS_BEIDOU_GALILEO_SYS;
|
||
#endif
|
||
}
|
||
/*设置GNSS nmea语句种类 //默认打开GGA/RMC/GSA/GSV/VTG */
|
||
if((quec_param_ptr->nmea_handle_cfg.mdflag&GNSS_NMEATYPE_ENABLE)==0){
|
||
quec_param_ptr->nmea_handle_cfg.gps_nmea_type =
|
||
GGA_EN|RMC_EN|GSV_EN|GSA_EN|VTG_EN;
|
||
}
|
||
|
||
quec_gnss_sys_set(quec_param_ptr->nmea_handle_cfg.gnss_sys_type);
|
||
quec_gnss_nmea_set(quec_param_ptr->nmea_handle_cfg.gps_nmea_type & 0x3f);
|
||
return 0;
|
||
}
|
||
|
||
void *quec_get_gnss_sate_num(void)
|
||
{
|
||
return &gnss_sate_num;
|
||
}
|
||
int quec_gnss_nmea_ret_value_parse(char *sentence, int length)
|
||
{
|
||
int len = 0;
|
||
int ret = 0;
|
||
|
||
static int appentry = 1;
|
||
QUEC_GPS_DEV_T *gps_dev=quec_get_gps_dev();
|
||
|
||
len = jmin(length,GNSS_CMD_MAX_LENGTH);
|
||
|
||
if (strncmp(sentence, "$OK", 3) == 0){
|
||
GPS_LOGI("ok %d",gps_dev->worke_state);
|
||
gps_dev->worke_state &= (~QUEC_GPS_RESET_STATE);
|
||
GPS_LOGI("ok %d",gps_dev->worke_state);
|
||
}else if(strncmp(sentence, "$FAIL", 5) == 0){
|
||
|
||
}else if(strncmp(sentence, "$AIDINFO", 8)==0){
|
||
GPS_LOGD("%s\r\n",sentence);
|
||
nmea_parse_aidinfo(&gnss_sate_num,sentence);
|
||
check_aidinfo_and_update_agps();
|
||
if(g_quec_gps_dev.nmea_cb->gnss_ephemeris_info_cb){
|
||
g_quec_gps_dev.nmea_cb->gnss_ephemeris_info_cb(&gnss_sate_num);
|
||
}
|
||
|
||
}else if(strncmp(sentence, "$CFGGEOID", 9) == 0){
|
||
;
|
||
}else if (strncmp(sentence, "$PDTINFO", 8)==0){
|
||
;
|
||
}else{/*非回复数据,走nmea解析器*/
|
||
|
||
ret = 1;
|
||
}
|
||
return ret ;
|
||
}
|
||
|
||
static struct tm *gmtime_r(const time_t *tloc, struct tm *result) {
|
||
struct tm *tm;
|
||
/* Bug Fix.
|
||
* Return Value of gmtime() is NULL On CranePlatform.
|
||
* SO local_time() is replaced here.By JoshuaWang.@0205/2021.
|
||
*/
|
||
|
||
tm = localtime(tloc);
|
||
if(tm)
|
||
return memcpy(result, tm, sizeof(struct tm));
|
||
|
||
return NULL;
|
||
}
|
||
|
||
int quec_gnss_aidtime_process(char *msgbuf)
|
||
{
|
||
int send_len =0;
|
||
struct tm time;
|
||
unsigned int now= GPS_GET_RTC_TIME();
|
||
gmtime_r(&now, &time);
|
||
send_len = snprintf((char *)(msgbuf), sizeof("$AIDTIME"),"$AIDTIME");
|
||
send_len += snprintf((char *)(msgbuf+send_len), GNSS_CMD_MAX_LENGTH - send_len,",%d,%d,%d,%d,%d,%d,%d",
|
||
time.tm_year+1900,time.tm_mon+1,
|
||
time.tm_mday,time.tm_hour,time.tm_min,
|
||
time.tm_sec,rand()%1000);
|
||
send_len+=snprintf(msgbuf+send_len, GNSS_CMD_MAX_LENGTH - send_len, "\r\n");
|
||
GPS_LOGD("%s",msgbuf);
|
||
return send_len;
|
||
}
|
||
#if 0
|
||
int quec_gnss_aidpos_process(char *msgbuf,hx_locationg_t *nema_data)
|
||
{
|
||
char rsp_str[256]= {0};
|
||
int len = 0;
|
||
int send_len = 0;
|
||
memset(rsp_str, 0, 256);
|
||
|
||
len += (uint16)snprintf((char *)(rsp_str+len), sizeof("$AIDPOS"),"$AIDPOS");
|
||
len += (uint16)snprintf((char *)(rsp_str+len), sizeof(rsp_str)-len,",%09.6lf",nema_data->latitude);
|
||
len += (uint16)snprintf((char *)(rsp_str+len), sizeof(rsp_str)-len,",%c",nema_data->latitude_cardinal);
|
||
len += (uint16)snprintf((char *)(rsp_str+len), sizeof(rsp_str)-len,",%010.6lf",nema_data->longitude);
|
||
len += (uint16)snprintf((char *)(rsp_str+len), sizeof(rsp_str)-len,",%c",nema_data->longitude_cardinal);
|
||
len += (uint16)snprintf((char *)(rsp_str+len), sizeof(rsp_str)-len,",%.1f",nema_data->altitude);
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "%s",rsp_str);
|
||
send_len+=snprintf(msgbuf+send_len, GNSS_CMD_MAX_LENGTH - send_len, "\r\n");
|
||
|
||
return send_len;
|
||
}
|
||
#endif
|
||
|
||
uint8_t one_system_cnr_index = 0;
|
||
uint8_t total_cnr_index = 0;
|
||
static int quec_gnss_nmea_value_update(struct nmea_s *nmea, hx_locationg_t *gps_data)
|
||
{
|
||
struct nmea_gprmc_s *rmc = NULL;
|
||
struct nmea_gpgsv_s *gsv = NULL;
|
||
struct nmea_gpgga_s *gga = NULL;
|
||
struct nmea_gpgsa_s *gsa = NULL;
|
||
struct nmea_gpvtg_s *vtg = NULL;
|
||
unsigned int *temp_cnr = NULL;
|
||
uint8_t i = 0;
|
||
|
||
if(nmea == NULL || gps_data == NULL)
|
||
{
|
||
GPS_LOGE("param invalid. \r\n");
|
||
return -1;
|
||
}
|
||
if(nmea->type == NMEA_UNKNOWN)
|
||
{
|
||
GPS_LOGE("gps nmea type is unknown! \r\n");
|
||
return -1;
|
||
}
|
||
switch(nmea->type)
|
||
{
|
||
case NMEA_RMC:
|
||
rmc = (struct nmea_gprmc_s*)nmea->data;
|
||
if(rmc)
|
||
{
|
||
gps_data->valid = rmc->valid;
|
||
//经纬??
|
||
gps_data->longitude = (rmc->longitude.degrees)*100 + rmc->longitude.minutes;
|
||
gps_data->longitude_cardinal = rmc->longitude.cardinal;
|
||
gps_data->latitude = (rmc->latitude.degrees)*100 + rmc->latitude.minutes;
|
||
gps_data->latitude_cardinal = rmc->latitude.cardinal;
|
||
//地面航向
|
||
gps_data->heading = rmc->course;
|
||
//地面速率
|
||
gps_data->gps_speed = rmc->speed;
|
||
//UTC
|
||
gps_data->time.tm_year = rmc->time.tm_year;
|
||
gps_data->time.tm_mon = rmc->time.tm_mon;
|
||
gps_data->time.tm_mday = rmc->time.tm_mday;
|
||
gps_data->time.tm_hour = rmc->time.tm_hour;
|
||
gps_data->time.tm_min = rmc->time.tm_min;
|
||
gps_data->time.tm_sec = rmc->time.tm_sec;
|
||
}
|
||
if(gps_data->gsv_status == SV_UPDATING)
|
||
{
|
||
gps_data->cnrs_index = total_cnr_index;
|
||
gps_data->gsv_status = SV_UPDATED;
|
||
}
|
||
break;
|
||
case NMEA_GGA:
|
||
gga = (struct nmea_gpgga_s*)nmea->data;
|
||
if(gga)
|
||
{
|
||
gps_data->altitude = gga->altitude;
|
||
gps_data->satellites_num = gga->satellites_tracked;
|
||
}
|
||
break;
|
||
case NMEA_GSA:
|
||
gsa = (struct nmea_gpgsa_s*)nmea->data;
|
||
if(gsa != NULL)
|
||
{
|
||
gps_data->hdop = gsa->hdop;
|
||
gps_data->pdop = gsa->pdop;
|
||
gps_data->fix_mode = gsa->navmode;
|
||
}
|
||
break;
|
||
case NMEA_VTG:
|
||
vtg = (struct nmea_gpvtg_s*)nmea->data;
|
||
|
||
if(vtg != NULL)
|
||
{
|
||
//地面航向
|
||
gps_data->cogt = vtg->cogt;
|
||
//地面速率
|
||
gps_data->sog = vtg->sog;
|
||
gps_data->kph = vtg->kph;
|
||
}
|
||
break;
|
||
case NMEA_GSV:
|
||
if(gps_data->gsv_status == SV_NEED_UPDATE)
|
||
{
|
||
memset(gps_data->cnrs, 0, sizeof(gps_data->cnrs));
|
||
one_system_cnr_index = 0;
|
||
total_cnr_index = 0;
|
||
gps_data->gsv_status = SV_UPDATING;
|
||
}
|
||
|
||
gsv = (struct nmea_gpgsv_s *)nmea->data;
|
||
if (gsv != NULL)
|
||
{
|
||
//每次解析一条GSV,每条最多4个卫星,等到一组NMEA读取完
|
||
temp_cnr = &(gps_data->cnrs[total_cnr_index]);
|
||
for (i = 0; one_system_cnr_index < gsv->total_sats && i < 4 && total_cnr_index + one_system_cnr_index < HX_GSV_MAX_SATS &&
|
||
gsv->sats[i].snr; i++)
|
||
{
|
||
temp_cnr[one_system_cnr_index] = gsv->sats[i].snr;
|
||
GPS_LOGD("sat[%d]:%d total_cnr_index:%d one_system_cnr_index:%d --max%d", i, gsv->sats[i].snr,
|
||
total_cnr_index, one_system_cnr_index, HX_GSV_MAX_SATS);
|
||
one_system_cnr_index++;
|
||
}
|
||
if (one_system_cnr_index >= gsv->total_sats)
|
||
{
|
||
total_cnr_index += one_system_cnr_index;
|
||
one_system_cnr_index = 0;
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int quec_gnss_nmea_parse(char* buf,int buf_len)
|
||
{
|
||
char nmea_buff[256];
|
||
char nmea_buff1[256];
|
||
unsigned int port_channel;
|
||
struct nmea_s *nmea = NULL;
|
||
int len = 0;
|
||
int ret = 0;
|
||
|
||
int i = 0;
|
||
QUEC_NMEA_CB *nmea_callback = g_quec_gps_dev.nmea_cb;
|
||
if(NULL == buf)
|
||
return -1;
|
||
|
||
len = jmin(sizeof(nmea_buff)-1, buf_len);
|
||
memset(nmea_buff, 0, sizeof(nmea_buff));
|
||
memcpy(nmea_buff, buf, len);
|
||
memcpy(nmea_buff1,nmea_buff,len);
|
||
|
||
GPS_LOGI("%s ,%d\r\n",nmea_buff,len);
|
||
if (NULL == memchr(nmea_buff, '$', len)){
|
||
return -1;
|
||
}
|
||
|
||
ret = quec_gnss_nmea_ret_value_parse(nmea_buff,len);
|
||
if(ret == 0){
|
||
return 0;
|
||
}
|
||
|
||
nmea = nmea_parse(nmea_buff, len, 1);
|
||
if (nmea){
|
||
ret = quec_gnss_nmea_value_update(nmea, &hx_loactiong_para);
|
||
if(nmea_callback->loaction_update_cb){
|
||
nmea_callback->loaction_update_cb(&hx_loactiong_para); /*定位数据通过回调更新到上层*/
|
||
}
|
||
|
||
if(nmea_callback->nmea_str_cb){
|
||
nmea_callback->nmea_str_cb(&hx_loactiong_para.time, nmea_buff1,len); /*实时nmea数据通过回调输出到上层*/
|
||
}
|
||
//20230616 屏蔽和芯gnss aidpos注入功能,实际测试无效,且概率性会引起串口冲突,产生assert dump
|
||
#if 0
|
||
if(hx_loactiong_para.valid){
|
||
/*非重启快速启动*/
|
||
memset(&(hx_loactiong_para_back),0,sizeof(struct quec_gnss_data_struct));
|
||
/*缓存重启前的定位数据,在重启后需要使用指令注入*/
|
||
memcpy((void*)(&(hx_loactiong_para_back)),(void*)(&hx_loactiong_para),sizeof(struct quec_gnss_data_struct));
|
||
}else {
|
||
if(hx_loactiong_para_back.valid){
|
||
quec_gnss_aidpos_msg_send();
|
||
hx_loactiong_para_back.valid = 0;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
if (ret){
|
||
GPS_LOGE("nmea_value_update error. \r\n");
|
||
GPS_LOGE(" %s", nmea_buff);
|
||
}
|
||
|
||
if (nmea->data) {
|
||
free(nmea->data);
|
||
nmea->data = NULL;
|
||
}
|
||
free(nmea);
|
||
nmea = NULL;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
hx_locationg_t * hx_location_data_get(void)
|
||
{
|
||
return &hx_loactiong_para;
|
||
}
|
||
|
||
int quec_gnss_cmd_send(quec_gps_msg_t *rcv)
|
||
{
|
||
unsigned int send_len = 0;
|
||
if(rcv == NULL)
|
||
return -1;
|
||
|
||
char *msgbuf=malloc(GNSS_CMD_MAX_LENGTH);
|
||
if(msgbuf == NULL)
|
||
ASSERT(0);
|
||
|
||
memset(msgbuf,0,GNSS_CMD_MAX_LENGTH);
|
||
|
||
switch(rcv->cmd_id)
|
||
{
|
||
case QUEC_GNSS_PDTINFO_CMD:
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$PDTINFO\r\n");
|
||
break;
|
||
case QUEC_GNSS_HOT_RESET: /*热启动*/
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$RESET,0,h00\r\n");
|
||
break;
|
||
case QUEC_GNSS_WARM_RESET:/*温启动*/
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$RESET,0,h01\r\n");
|
||
break;
|
||
case QUEC_GNSS_COLD_RESET:/*冷启动*/
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$RESET,0,hFF\r\n");
|
||
#else
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$RESET,0,h85\r\n");
|
||
#endif
|
||
break;
|
||
case QUEC_GNSS_AGPS_AIDINFO_REQ:
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$AIDINFO\r\n");
|
||
break;
|
||
case QUEC_GNSS_CFG_GEOID_REQ:
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$CFGGEOID\r\n");
|
||
break;
|
||
case QUEC_GNSS_CFG_GEOID_SET:
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$CFGGEOID,1\r\n");
|
||
break;
|
||
case QUEC_GNSS_CFGSYS:
|
||
if(quec_gnss_cmd_cfgsys_process(rcv))
|
||
{
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$CFGSYS,H%d",quec_gnss_cmd_cfgsys_process(rcv));
|
||
send_len+=snprintf(msgbuf+send_len, GNSS_CMD_MAX_LENGTH - 1, "\r\n");
|
||
}
|
||
break;
|
||
case QUEC_GNSS_NMEA_TYPE:
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$CFGMSG,0,%d,%d,1",rcv->data[0],rcv->data[1]);
|
||
#else
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$CFGMSG,0,%d,%d",rcv->data[0],rcv->data[1]);
|
||
#endif
|
||
send_len+=snprintf(msgbuf+send_len, GNSS_CMD_MAX_LENGTH - 1, "\r\n");
|
||
break;
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
case QUEC_GNSS_1PPS_CONFIG:
|
||
send_len=snprintf(msgbuf, GNSS_CMD_MAX_LENGTH - 1, "$CFGTP,1000000,500000,1,0,800,-380");
|
||
break;
|
||
#endif
|
||
#if 0
|
||
case QUEC_GNSS_AIDPOS_SET:
|
||
send_len = quec_gnss_aidpos_process(msgbuf,&(hx_loactiong_para_back));
|
||
break;
|
||
#endif
|
||
case QUEC_GNSS_AIDTIME_SET:
|
||
send_len = quec_gnss_aidtime_process(msgbuf);
|
||
break;
|
||
default:
|
||
free(msgbuf);
|
||
return -2;
|
||
}
|
||
if(send_len)
|
||
{
|
||
GPS_COM_PutByte_Buffer(msgbuf,send_len);
|
||
}
|
||
free(msgbuf);
|
||
return 0;
|
||
}
|
||
|
||
int quec_gps_open(void)
|
||
{
|
||
QUEC_GPS_DEV_T * quec_gps = &g_quec_gps_dev;
|
||
int ret = QUEC_GPS_NO_ERROR;
|
||
do{
|
||
if(quec_gps->power_state == QUEC_POWER_OFF){
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref, QUEC_GPS_OPEN_EVENT, QUEC_FLAG_OR);
|
||
ret = QUEC_GPS_NO_ERROR;
|
||
break;
|
||
}
|
||
ret = QUEC_GPS_ALREADY_CLOSED_ERROR;
|
||
GPS_LOGE("GPS_ALREADY Be CLOSED!!!\n");
|
||
}while(0);
|
||
return ret;
|
||
}
|
||
|
||
int quec_gps_close(void)
|
||
{
|
||
QUEC_GPS_DEV_T * quec_gps = &g_quec_gps_dev;
|
||
int ret = QUEC_GPS_NO_ERROR;
|
||
do{
|
||
if(quec_gps->power_state == QUEC_POWER_ON){
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref, QUEC_GPS_CLOSE_EVENT, QUEC_FLAG_OR);
|
||
ret = QUEC_GPS_NO_ERROR;
|
||
break;
|
||
}
|
||
ret = QUEC_GPS_NOT_OPEN_ERROR;
|
||
GPS_LOGE("need to OPEN GPS!!!\n");
|
||
}while(0);
|
||
return ret;
|
||
}
|
||
|
||
void quec_gps_register_nmea_str_cb(nmea_str_put cb)
|
||
{
|
||
g_quec_nmea_cb.nmea_str_cb = cb;
|
||
}
|
||
|
||
void quec_gps_register_nmea_packet_cb(gps_packet_put cb)
|
||
{
|
||
g_quec_nmea_cb.nmea_packets_cb = cb;
|
||
}
|
||
|
||
void quec_gps_register_open_success_cb(gps_open_success cb)
|
||
{
|
||
g_quec_nmea_cb.open_gps_success_cb = cb;
|
||
}
|
||
void quec_gps_register_location_para_cb(location_update cb)
|
||
{
|
||
g_quec_nmea_cb.loaction_update_cb = cb;
|
||
}
|
||
|
||
void quec_gps_register_agps_sate_cb(gnss_ephemeris_info cb)
|
||
{
|
||
g_quec_nmea_cb.gnss_ephemeris_info_cb = cb;
|
||
}
|
||
|
||
void quec_apflash_req_flag_set(void)
|
||
{
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref,QUEC_APFLSH_REQ_EVENT,QUEC_FLAG_OR);
|
||
}
|
||
|
||
void quec_apflsh_req_statue_clear(void)
|
||
{
|
||
g_quec_gps_dev.worke_state &= ~QUEC_APFLASH_REQED;
|
||
}
|
||
|
||
#ifdef QUEC_HX_AGPS_TIMER
|
||
void quec_agps_req_flag_set(void)
|
||
{
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref,QUEC_AGPS_DATA_REQ_EVENT,QUEC_FLAG_OR);
|
||
}
|
||
#endif
|
||
void quec_gps_load_fw_cb(void * para)
|
||
{
|
||
if(g_quec_gps_dev.power_state != QUEC_POWER_ON)/*若未开机则走下载流程*/
|
||
{
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref,QUEC_GPS_DOWNLOAD_FIRM,QUEC_FLAG_OR);
|
||
}
|
||
}
|
||
|
||
/*gps 保活机制如果超过5s没检测到串口回调则会重新开关串口和gps */
|
||
void quec_keep_alive_timer(UINT32 argv)
|
||
{
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref,QUEC_GPS_RESTART,QUEC_FLAG_OR);
|
||
}
|
||
|
||
void quec_gps_nmea_data_cb(void * para)
|
||
{
|
||
quec_gps_handle * gnss_config = quec_gnss_config_para_get();
|
||
if((1 == gnss_rom_type) ||(3 == gnss_rom_type))
|
||
{
|
||
quec_gnss_apflash_struct_t * gnss_apflash = get_hx_apflash_req_status();
|
||
|
||
if(gnss_apflash->request_flag)/*如果此时发起了apflsh请求*/
|
||
{
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref,QUEC_GPS_APFLASH_EVENT,QUEC_FLAG_OR);
|
||
}
|
||
else
|
||
{
|
||
if(g_quec_gps_dev.worke_state & QUEC_NMEA_PASRE_STATE){
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref, QUEC_GPS_NMEA_PARSE_EVENT, QUEC_FLAG_OR);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(g_quec_gps_dev.worke_state & QUEC_NMEA_PASRE_STATE){
|
||
quec_rtos_flag_release(g_quec_gps_dev.gps_event_flag_ref, QUEC_GPS_NMEA_PARSE_EVENT, QUEC_FLAG_OR);
|
||
}
|
||
}
|
||
//20230512 修改保活机制处理逻辑,当我们配置nmea语句不输出时,不触发保活机制,以防止gnss反复重启
|
||
if((g_quec_gps_dev.worke_state & QUEC_NMEA_PASRE_STATE) && (gnss_config->nmea_handle_cfg.gps_nmea_type != 0)){
|
||
quec_rtos_timer_start(g_quec_gps_dev.gps_keep_alive_timer, HX_GPS_KEEPALIVE_CNT, 0, quec_keep_alive_timer, 0);
|
||
}
|
||
else
|
||
{
|
||
quec_rtos_timer_stop(g_quec_gps_dev.gps_keep_alive_timer);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
int quec_gps_start_parse(void)
|
||
{
|
||
QUEC_GPS_DEV_T * quec_gps = &g_quec_gps_dev;
|
||
QUEC_GPS_OPS * quec_ops = (QUEC_GPS_OPS *)g_quec_gps_dev.ops;
|
||
int ret = QUEC_GPS_ERROR;
|
||
if(!(quec_gps->worke_state & QUEC_NMEA_PASRE_STATE )){
|
||
GPS_COM_register_cb(quec_gps_nmea_data_cb);
|
||
quec_rtos_timer_start(g_quec_gps_dev.gps_keep_alive_timer, HX_GPS_KEEPALIVE_CNT, 0, quec_keep_alive_timer, 0);
|
||
quec_gps->worke_state |= QUEC_NMEA_PASRE_STATE;
|
||
ret = QUEC_GPS_NO_ERROR;
|
||
GPS_LOGI("start nmea parse %d",quec_gps->worke_state);
|
||
}
|
||
return ret ;
|
||
}
|
||
|
||
int quec_gps_stop_nmea_parse(void)
|
||
{
|
||
QUEC_GPS_DEV_T * quec_gps = &g_quec_gps_dev;
|
||
int ret = QUEC_GPS_ERROR;
|
||
if(quec_gps->worke_state & QUEC_NMEA_PASRE_STATE){
|
||
GPS_COM_register_cb(NULL);
|
||
quec_rtos_timer_stop(g_quec_gps_dev.gps_keep_alive_timer);
|
||
ret = QUEC_GPS_NO_ERROR;
|
||
quec_gps->worke_state &= ~QUEC_NMEA_PASRE_STATE;
|
||
}
|
||
return ret ;
|
||
}
|
||
|
||
int gps_open(void)
|
||
{
|
||
int ret = QUEC_GPS_NO_ERROR;
|
||
int i ;
|
||
g_quec_gps_dev.power_state = QUEC_POWER_OFF;
|
||
GPS_COM_register_cb(quec_gps_load_fw_cb);
|
||
for(i=0;i<=3;i++){
|
||
ret = hx_gnss_open();
|
||
if(ret == HX_L26_INIT_NO_ERROR){
|
||
break;
|
||
}
|
||
else{
|
||
GPS_LOGE("GPS UPDATE FAILED: %d",ret);
|
||
hx_gnss_close();
|
||
ret = QUEC_GPS_NOT_OPEN_ERROR;
|
||
}
|
||
}
|
||
GPS_COM_register_cb(NULL);
|
||
g_quec_gps_dev.power_state = QUEC_POWER_ON;
|
||
return ret;
|
||
}
|
||
|
||
int gps_close(void)
|
||
{
|
||
int ret = QUEC_GPS_NO_ERROR;
|
||
ret = hx_gnss_close();
|
||
g_quec_gps_dev.power_state = QUEC_POWER_OFF;
|
||
return ret;
|
||
}
|
||
|
||
extern QUEC_GPS_USER_CALLBACK quec_asr_gps_user_callback_init;
|
||
|
||
static void quec_gps_process_thread(void* argv)
|
||
{
|
||
unsigned int gps_flags = 0;
|
||
char nmea_r[256] = {0};
|
||
char pos = 0;
|
||
char aidtimeflag=0;
|
||
char agnss_delay=0;
|
||
QUEC_GPS_DEV_T * quec_gps = &g_quec_gps_dev;
|
||
QUEC_GPS_OPS * quec_ops = (QUEC_GPS_OPS *)g_quec_gps_dev.ops;
|
||
unsigned int buffer_len = 0;
|
||
char * rx_buf = NULL;
|
||
int ret = 0;
|
||
unsigned int cnt =0;
|
||
int i;
|
||
char overflow_flag = 0;
|
||
|
||
while(1){
|
||
quec_rtos_flag_wait(g_quec_gps_dev.gps_event_flag_ref, QUEC_GPS_EVENT_MASK, QUEC_FLAG_OR_CLEAR, &gps_flags,QUEC_WAIT_FOREVER);
|
||
|
||
if(gps_flags & QUEC_GPS_OPEN_EVENT){ /*gnss打开事件*/
|
||
/*step 1:gps 上电*/
|
||
ret = gps_open();
|
||
if(ret == QUEC_GPS_NO_ERROR){
|
||
/*step 2:开启agps定时器*/
|
||
quec_hx_agps_init();
|
||
/*step 3:初始化gps配置*/
|
||
quec_gnss_nmea_cnf();
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
//CC11系列1PPS有380ms的误差,需要使用原厂指令进行修正
|
||
quec_gnss_cmd_1pps_config();
|
||
#endif
|
||
/*step 4:初始化gps配置*/
|
||
|
||
if((1 == gnss_rom_type) ||(3 == gnss_rom_type))
|
||
{
|
||
/*step 4:初始化gps配置*/
|
||
quec_apflash_timer_init();
|
||
}
|
||
|
||
ret = quec_gps_start_parse();
|
||
if(quec_asr_gps_user_callback_init!=NULL)
|
||
quec_asr_gps_user_callback_init(QUEC_GPS_INITIAL_SUCCESS,NULL,0);
|
||
}
|
||
else
|
||
{
|
||
if(quec_asr_gps_user_callback_init!=NULL)
|
||
quec_asr_gps_user_callback_init(QUEC_GPS_INITIAL_FAILED,NULL,0);
|
||
}
|
||
if(ret == QUEC_GPS_NO_ERROR){
|
||
if(quec_gps->nmea_cb->open_gps_success_cb)
|
||
quec_gps->nmea_cb->open_gps_success_cb();
|
||
}
|
||
}
|
||
else if (gps_flags & QUEC_GPS_CLOSE_EVENT){/*gnss关闭事件*/
|
||
/*step 1:关闭nmea解析器*/
|
||
quec_gps_stop_nmea_parse();
|
||
/*step 2:gps下电*/
|
||
gps_close();
|
||
/*step 3:关串口,关闭串口操作要在stop_nmea_parse后面,否则可能关机时间和串口接收中断装上导致异常*/
|
||
GPS_COM_Deinit();
|
||
/*step 4:关闭agps定时器*/
|
||
quec_hx_agps_deinit();
|
||
|
||
if((1 == gnss_rom_type) ||(3 == gnss_rom_type))
|
||
{
|
||
quec_apflash_timer_deinit();
|
||
}
|
||
|
||
memset(&hx_loactiong_para,0,sizeof(hx_locationg_t));
|
||
quec_gps->worke_state = QUEC_GPS_INIT_STATE;
|
||
|
||
agnss_delay=0;
|
||
aidtimeflag=0;
|
||
if(quec_asr_gps_user_callback_init!=NULL)
|
||
quec_asr_gps_user_callback_init(QUEC_GPS_DEINIT_SUCCESS,NULL,0);
|
||
}
|
||
else if (gps_flags & QUEC_GPS_NMEA_PARSE_EVENT){/*nmea数据解析*/
|
||
if(g_quec_gps_dev.power_state == QUEC_POWER_ON){
|
||
GPS_LOGI("nmea data cnt %d\n",cnt++);
|
||
buffer_len=GPS_COM_GetByteStatus();
|
||
rx_buf = malloc(buffer_len);
|
||
memset(rx_buf,0,buffer_len);
|
||
GPS_COM_GetByte_Buffer((char*)rx_buf,buffer_len);
|
||
if(g_quec_gps_dev.nmea_cb->nmea_packets_cb){
|
||
g_quec_gps_dev.nmea_cb->nmea_packets_cb(rx_buf,buffer_len);
|
||
}
|
||
|
||
for(i=0;i<buffer_len;i++){
|
||
if (overflow_flag) { /*如果检测到前面buffer已经超出缓冲大小那么我们要检测到结束符\n再开始记录buffer*/
|
||
overflow_flag = (rx_buf[i] != '\n');
|
||
continue;
|
||
}
|
||
if (pos >= (int) sizeof(nmea_r)-1 ) { /*如果检测到超出缓冲区大小直接开始下一次*/
|
||
overflow_flag = 1;
|
||
pos = 0;
|
||
continue;
|
||
}
|
||
nmea_r[pos] = (char)rx_buf[i];
|
||
pos += 1;
|
||
if(rx_buf[i] == '\n'){
|
||
ret = quec_gnss_nmea_parse(nmea_r,pos);
|
||
pos = 0;
|
||
}
|
||
}
|
||
|
||
if((1 == gnss_rom_type) ||(3 == gnss_rom_type))
|
||
{
|
||
/*检查本地apflash数据是否需要更新*/
|
||
if(hx_loactiong_para.valid && ((g_quec_gps_dev.worke_state & QUEC_APFLASH_REQED)==0)){
|
||
if(quec_apflsh_data_need_update()){
|
||
quec_apflash_req_flag_set();/*第一次定位成功立即获取apflash数据*/
|
||
}
|
||
else {
|
||
quec_gps->worke_state |= QUEC_APFLASH_REQED;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
if(ret != QUEC_GPS_NO_ERROR)
|
||
GPS_LOGE("nmea data parse faile\n");
|
||
free(rx_buf);
|
||
if(GPS_GET_RTC_STATUS()==1 && !aidtimeflag){
|
||
quec_gnss_aidtime_msg_send();
|
||
aidtimeflag++;
|
||
}
|
||
/*开机到现在未同步过agps,可能是由于pdp尚未激活导致,这里查询到如果有pdp激活则会尝试请求一次*/
|
||
if(!quec_get_agps_status() && agnss_delay>=3){ //pony add 第一次开机等输出5s的nmea再注入agnss,过早注入可能导致agnss失效
|
||
/*如果有pdp激活,尝试同步一次agps*/
|
||
if(GPS_GET_NETIF_STATUS() && GPS_GET_RTC_STATUS()){
|
||
quec_agps_file_set_to_gps();
|
||
}
|
||
}
|
||
if(agnss_delay<6)
|
||
agnss_delay++;
|
||
|
||
if(quec_get_agps_status()&&aidtimeflag){
|
||
if(GPS_NW_DEACT) { /*删除网络监控线程节省资源*/
|
||
GPS_NW_DEACT();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#ifdef QUEC_HX_AGPS_TIMER
|
||
else if(gps_flags & QUEC_AGPS_DATA_REQ_EVENT)
|
||
{
|
||
quec_set_agps_status(0);
|
||
}
|
||
#endif
|
||
|
||
else if(gps_flags & QUEC_APFLSH_REQ_EVENT)
|
||
{
|
||
if(g_quec_gps_dev.power_state == QUEC_POWER_ON){
|
||
quec_gnss_apflash_data_request();
|
||
quec_gps->worke_state |= QUEC_APFLASH_REQED;
|
||
GPS_LOGI("GPS REQ APFLSH ");
|
||
}
|
||
}
|
||
else if(gps_flags & QUEC_GPS_APFLASH_EVENT)
|
||
{
|
||
if(g_quec_gps_dev.power_state == QUEC_POWER_ON){
|
||
GPS_LOGI("GPS RECV APFLSH");
|
||
ret = quec_gnss_apflash_recv(); /*接收gps数据*/
|
||
if(!ret){
|
||
GPS_LOGI("GPS RECV APFLSH not over");
|
||
}
|
||
}
|
||
}
|
||
|
||
else if(gps_flags & QUEC_GPS_RESTART)
|
||
{
|
||
/*step 0:关闭串口*/
|
||
GPS_COM_Deinit();
|
||
/*step 1:关闭nmea解析器*/
|
||
quec_gps_stop_nmea_parse();
|
||
/*step 2:gps下电*/
|
||
gps_close();
|
||
/*step 3:关闭agps定时器*/
|
||
quec_hx_agps_deinit();
|
||
|
||
if((1 == gnss_rom_type) ||(3 == gnss_rom_type))
|
||
{
|
||
/*step 3:关闭apflash定时器*/
|
||
quec_apflash_timer_deinit();
|
||
}
|
||
|
||
/*step 4:*/
|
||
memset(&hx_loactiong_para,0,sizeof(hx_locationg_t));
|
||
/*step 5:*/
|
||
g_quec_gps_dev.worke_state = QUEC_GPS_INIT_STATE;
|
||
/*step 1:gps 上电*/
|
||
gps_open();
|
||
/*step 2:开启agps定时器*/
|
||
quec_hx_agps_init();
|
||
/*step 3:初始化gps配置*/
|
||
quec_gnss_nmea_cnf();
|
||
#if defined (HX_GNSS_CC11_SUPPORT)
|
||
//CC11系列1PPS有380ms的误差,需要使用原厂指令进行修正
|
||
quec_gnss_cmd_1pps_config();
|
||
#endif
|
||
if((1 == gnss_rom_type) ||(3 == gnss_rom_type))
|
||
{
|
||
/*step 4:初始化gps配置*/
|
||
quec_apflash_timer_init();
|
||
}
|
||
|
||
quec_rtos_task_sleep_ms(10);
|
||
/*step 5:注入agps数据*/
|
||
quec_agps_file_set_to_gps();
|
||
/*step 6:检查导入的星历是否有效*/
|
||
quec_agps_check_vaild();
|
||
/*step 7:开启nmea解析器*/
|
||
quec_gps_start_parse();
|
||
if(quec_asr_gps_user_callback_init!=NULL)
|
||
quec_asr_gps_user_callback_init(QUEC_GPS_INITIAL_SUCCESS,NULL,0);
|
||
}
|
||
else {
|
||
GPS_LOGE("unknow gps event !!!\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
int quec_gps_status_get(void)
|
||
{
|
||
QUEC_GPS_DEV_T * quec_gps = &g_quec_gps_dev;
|
||
return quec_gps->power_state;
|
||
}
|
||
|
||
void quec_gps_dev_init(void)
|
||
{
|
||
g_quec_gps_ops.q_gps_open = quec_gps_open;
|
||
g_quec_gps_ops.q_gps_close = quec_gps_close;
|
||
g_quec_gps_ops.q_gps_reset = quec_gps_reset;
|
||
g_quec_gps_ops.q_reg_nmea_str_cb = quec_gps_register_nmea_str_cb;
|
||
g_quec_gps_ops.q_reg_location_update_cb = quec_gps_register_location_para_cb;
|
||
g_quec_gps_ops.q_reg_open_gps_success_cb = quec_gps_register_open_success_cb;
|
||
g_quec_gps_ops.q_reg_agps_sate_num_cb = quec_gps_register_agps_sate_cb;
|
||
g_quec_gps_ops.q_reg_nmea_packet_cb = quec_gps_register_nmea_packet_cb;
|
||
|
||
g_quec_gps_dev.gps_manufacturer = HX_GPS_MODULE;
|
||
g_quec_gps_dev.power_state = QUEC_POWER_OFF;
|
||
g_quec_gps_dev.worke_state = QUEC_GPS_INIT_STATE;
|
||
g_quec_gps_dev.gps_event_flag_ref = NULL;
|
||
g_quec_gps_dev.gps_task_ref = NULL;
|
||
g_quec_gps_dev.gps_keep_alive_timer = NULL;
|
||
g_quec_gps_dev.ops = &g_quec_gps_ops;
|
||
g_quec_gps_dev.nmea_cb = &g_quec_nmea_cb;
|
||
}
|
||
|
||
QUEC_GPS_DEV_T *quec_get_gps_dev(void)
|
||
{
|
||
return &g_quec_gps_dev;
|
||
}
|
||
|
||
static void sys_32k_init(void)
|
||
{
|
||
if(1)
|
||
{
|
||
#if defined (HX_GNSS_CC11_SUPPORT) && !defined (__QUECTEL_PROJECT_EG915NLA_GK__)
|
||
unsigned int temp = (*(volatile unsigned long *)(0xD401E32C));
|
||
temp = temp & ~0x07;
|
||
temp |= 0x01; // function 2, select 32K clock mode
|
||
(*(volatile unsigned long *)(0xD401E32C)) = temp;
|
||
#else
|
||
volatile unsigned int temp = 0;
|
||
unsigned int addr = 0xD401E000 + 50*4; // address of GPIO 122
|
||
|
||
temp = (*(volatile unsigned long *)(0xD4050038));
|
||
GPS_LOGI("SCCR register %08x\r\n", temp);
|
||
|
||
temp = (*(volatile unsigned long *)(addr));
|
||
temp = temp & ~0x07;
|
||
temp |= 0x02; // function 2, select 32K clock mode
|
||
(*(volatile unsigned long *)(addr)) = temp;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
GPS_LOGI("Pls Check DCS Mode!!");
|
||
}
|
||
}
|
||
|
||
|
||
void quec_gps_init(void)
|
||
{
|
||
/*STEP 2: gps主线程初始化*/
|
||
//20230807 兼容和芯gnss rom1 rom2处理,rom2需要输出32k
|
||
gnss_rom_type = quec_gnss_type_check();
|
||
int gnss_vbckp_select = quec_hx_bckp_get();
|
||
if((2==gnss_rom_type)&&(0 == gnss_vbckp_select)){
|
||
gnss_rom_type = 3;//20231011 add type 3:ROM2不接备电
|
||
}
|
||
if(2 == gnss_rom_type)
|
||
{
|
||
sys_32k_init();
|
||
}
|
||
|
||
quec_gps_dev_init();
|
||
quec_gnss_firm_init();
|
||
quec_rtos_flag_create(&g_quec_gps_dev.gps_event_flag_ref);
|
||
quec_rtos_task_create(&g_quec_gps_dev.gps_task_ref , QUEC_GPS_TASK_STACK_SIZE , 90, "qgps_task", quec_gps_process_thread, NULL, NULL);
|
||
quec_rtos_timer_create(&g_quec_gps_dev.gps_keep_alive_timer);/*gnss保活定时器*/
|
||
}
|
||
|
||
#ifdef HX_GNSS_CC11_SUPPORT
|
||
int read_gnss_id()
|
||
{
|
||
int ret = -1;
|
||
char ack_id[256]={0};
|
||
char cnt = 10;
|
||
int len = 0;
|
||
memset(ack_id,0,256);
|
||
while(cnt--)
|
||
{
|
||
if(select_read(200))
|
||
{
|
||
len = deal_read(ack_id+len,256-len);
|
||
//RTI_LOG("quec----,%s,%s",__func__,ack_id);
|
||
if(strstr((char *)ack_id, "CC1177W"))
|
||
{
|
||
ret=BEIDOU_ONLY;
|
||
break;
|
||
}
|
||
if(strstr((char *)ack_id, "CC1161W"))
|
||
{
|
||
ret=GNSS_SYS;
|
||
break;
|
||
}
|
||
len+=len;
|
||
if(len>=256)
|
||
break;
|
||
}
|
||
else
|
||
break;
|
||
}//读取超过256字节,退出循环判定硬件ID,防止没有读取到ID信息,一直接收导致数组越界或者硬件ID信息被截断,判定失败
|
||
return ret;
|
||
}
|
||
|
||
|
||
int quec_hxgnss_open_getid()
|
||
{
|
||
int i=0,reset_sucess=-1;
|
||
sys_32k_init();
|
||
quec_rtos_flag_create(&g_quec_gps_dev.gps_event_flag_ref);
|
||
g_quec_gps_dev.power_state = QUEC_POWER_OFF;
|
||
gps_channel_init();
|
||
GPS_COM_register_cb(quec_gps_load_fw_cb);
|
||
GPS_COM_Init();
|
||
GPS_COM_SetBaudRate(115200);
|
||
for(i=0;i<3;i++)
|
||
{
|
||
quec_gnss_power_on_off(0);
|
||
gps_delay_ms(50);
|
||
quec_gnss_power_on_off(1);
|
||
//读取GNSSID,-1:读取失败 0:CC1161W,1:CC1177W
|
||
reset_sucess =read_gnss_id();
|
||
if(reset_sucess!=-1)
|
||
break;
|
||
GPS_COM_PurgeFIFO();
|
||
}
|
||
quec_gnss_power_on_off(0);
|
||
GPS_COM_register_cb(NULL);
|
||
quec_rtos_flag_delete(g_quec_gps_dev.gps_event_flag_ref);
|
||
g_quec_gps_dev.gps_event_flag_ref = NULL;
|
||
g_quec_gps_dev.power_state = QUEC_POWER_ON;
|
||
GPS_COM_Deinit();
|
||
|
||
return reset_sucess;
|
||
|
||
}
|
||
|
||
|
||
|
||
#endif
|
||
|
||
|