#include "stdio.h"
|
#include "stdarg.h"
|
#include "stdlib.h"
|
#include "string.h"
|
#include "stm32h7xx_hal.h"
|
#include "math.h"
|
#include "HIDO_Util.h"
|
#include "HIDO_Debug.h"
|
#include "HIDO_Timer.h"
|
#include "FreeRTOS.h"
|
#include "task.h"
|
#include "GPS.h"
|
#include "DBG.h"
|
#include "GPIO.h"
|
#include "Uart.h"
|
#include "UDPClient.h"
|
// #include "global_param.h"
|
|
#include "TTS.h"
|
|
#define GPS_DBG(level, fmt, ...) HIDO_Debug(fmt, __VA_ARGS__)
|
|
#define GPS_UART_RX_BUF_SIZE 1024
|
#define GPS_UART_TX_BUF_SIZE (2048 + 512)
|
|
typedef enum
|
{
|
GPS_RECV_STATE_IDLE = 0,
|
GPS_RECV_STATE_HEAD,
|
GPS_RECV_STATE_CR,
|
GPS_RECV_STATE_LF,
|
} E_GPSRecvState;
|
|
typedef struct
|
{
|
E_GPSRecvState m_eState;
|
HIDO_CHAR m_acHeader[10], m_acHeader2[10], m_acHeader3[10], m_acHeader4[10], m_acHeader5[10];
|
HIDO_UINT32 m_u32HeaderLen, m_u32Header2Len, m_u32Header3Len, m_u32Header4Len, m_u32Header5Len;
|
|
HIDO_CHAR m_acRecvBuf[256]; // 增大缓冲区以容纳GPRMI的23个字段
|
HIDO_UINT32 m_u32RecvLen;
|
} ST_GPSRecv;
|
|
static HIDO_UINT8 l_au8GPSUartRxBuf[GPS_UART_RX_BUF_SIZE];
|
static HIDO_UINT8 l_au8GPSUartTxBuf[GPS_UART_TX_BUF_SIZE];
|
|
static ST_GPIO l_astGPSPin[GPS_PIN_LAST];
|
static ST_GPSRecv l_stGPSRecv;
|
|
static HIDO_UINT8 l_u8PosState = 0;
|
static HIDO_UINT8 l_u8GPS_HZ = 0;
|
static HIDO_BOOL l_bGPSConfig = HIDO_FALSE;
|
static HIDO_UINT32 l_u32QXTick = 0;
|
HIDO_UINT32 getRTK_Tick = 0;
|
|
/* 存储最新的GPRMI和GPIMU数据 */
|
static ST_GPRMI l_stGPRMI;
|
static ST_GPIMU l_stGPIMU;
|
/* GPS���� */
|
static HIDO_UINT8 l_au8CmdSave[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x31, 0xBF};
|
static HIDO_UINT8 l_au8CmdRate1Hz[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xE8, 0x03, 0x01, 0x00, 0x01, 0x00, 0x01, 0x39};
|
static HIDO_UINT8 l_au8CmdRate2Hz[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xF4, 0x01, 0x01, 0x00, 0x01, 0x00, 0x0B, 0x77};
|
static HIDO_UINT8 l_au8CmdRate5Hz[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xC8, 0x00, 0x01, 0x00, 0x01, 0x00, 0xDE, 0x6A};
|
static HIDO_UINT8 l_au8CmdRate10Hz[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0x64, 0x00, 0x01, 0x00, 0x01, 0x00, 0x7A, 0x12};
|
|
/*******************************************************************************
|
* Function Name : GPS_RateConfig
|
* Description : GPS�������� ֧��1HZ��2HZ��5HZ��10HZ
|
* Input : _u8Rate ����
|
* Output : None
|
* Return : HIDO_OK �ɹ�, HIDO_ERR ʧ��
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��5��07��
|
*******************************************************************************/
|
static HIDO_INT32 GPS_RateConfig(HIDO_UINT8 _u8Rate)
|
{
|
l_u8GPS_HZ = _u8Rate;
|
|
switch (_u8Rate)
|
{
|
case 1:
|
{
|
Uart_Send(UART_ID_GPS, l_au8CmdRate1Hz, sizeof(l_au8CmdRate1Hz));
|
Uart_Send(UART_ID_GPS, l_au8CmdSave, sizeof(l_au8CmdSave));
|
break;
|
}
|
case 2:
|
{
|
Uart_Send(UART_ID_GPS, l_au8CmdRate2Hz, sizeof(l_au8CmdRate2Hz));
|
Uart_Send(UART_ID_GPS, l_au8CmdSave, sizeof(l_au8CmdSave));
|
break;
|
}
|
case 5:
|
{
|
Uart_Send(UART_ID_GPS, l_au8CmdRate5Hz, sizeof(l_au8CmdRate5Hz));
|
Uart_Send(UART_ID_GPS, l_au8CmdSave, sizeof(l_au8CmdSave));
|
break;
|
}
|
case 10:
|
{
|
Uart_Send(UART_ID_GPS, l_au8CmdRate10Hz, sizeof(l_au8CmdRate10Hz));
|
Uart_Send(UART_ID_GPS, l_au8CmdSave, sizeof(l_au8CmdSave));
|
break;
|
}
|
default:
|
{
|
break;
|
}
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_DataCheck
|
* Description : GPS���ݸ�ʽ���
|
* Input : _pcData GPS����
|
* : _u32Len GPS���ݳ���
|
* Output : None
|
* Return : HIDO_OK �ɹ�, HIDO_ERR ʧ��
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��5��07��
|
*******************************************************************************/
|
static HIDO_INT32 GPS_DataCheck(HIDO_CHAR *_pcData, HIDO_UINT32 _u32Len)
|
{
|
HIDO_DataStruct stData;
|
HIDO_DataStruct stCheckValue;
|
HIDO_UINT8 u8CheckValue = 0;
|
HIDO_UINT8 u8CalcValue = 0;
|
HIDO_UINT32 i = 0;
|
|
if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len, "$%p*%p\r\n", &stData, &stCheckValue) != 2)
|
{
|
return HIDO_ERR;
|
}
|
|
u8CheckValue = HIDO_UtilHexStrBufToInt((HIDO_CHAR *)stCheckValue.m_pData, stCheckValue.m_u32Len);
|
u8CalcValue = ((HIDO_UINT8 *)stData.m_pData)[0];
|
for (i = 1; i < stData.m_u32Len; i++)
|
{
|
u8CalcValue ^= ((HIDO_UINT8 *)stData.m_pData)[i];
|
}
|
|
if (u8CalcValue != u8CheckValue)
|
{
|
return HIDO_ERR;
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_ParseGGA
|
* Description : GPS GGA���ݽ���(����������Ƿ���Ч)
|
* Input : _pcData GGA����
|
* : _u32Len GGA���ݳ���
|
* Output : None
|
* Return : HIDO_OK �ɹ�, HIDO_ERR ʧ��
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��5��07��
|
*******************************************************************************/
|
static HIDO_INT32 GPS_ParseGGA(HIDO_CHAR *_pcData, HIDO_UINT32 _u32Len)
|
{
|
ST_GPS stGPS;
|
HIDO_DataStruct stPosState;
|
|
memset(&stGPS, 0, sizeof(ST_GPS));
|
if (GPS_DataCheck(_pcData, _u32Len) != HIDO_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len, "$%*,%*,%*,%*,%*,%*,%p,%*,%*,%*,%*,%*,%*,%*,%**", &stPosState) != 15)
|
{
|
return HIDO_ERR;
|
}
|
|
l_u8PosState = atoi((HIDO_CHAR *)stPosState.m_pData);
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_ParseGPRMI
|
* Description : 解析GPRMI数据包
|
* Input : _pcData GPRMI数据
|
* : _u32Len GPRMI数据长度
|
* Output : None
|
* Return : HIDO_OK 成功, HIDO_ERR 失败
|
* Author : www.hido-studio.com
|
* Modified Date: : 2025年11月11日
|
*******************************************************************************/
|
static HIDO_INT32 GPS_ParseGPRMI(HIDO_CHAR *_pcData, HIDO_UINT32 _u32Len)
|
{
|
HIDO_DataStruct astFields[23];
|
|
memset(&l_stGPRMI, 0, sizeof(ST_GPRMI));
|
l_stGPRMI.m_bValid = HIDO_FALSE;
|
|
// 检查数据格式校验
|
if (GPS_DataCheck(_pcData, _u32Len) != HIDO_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
// 解析23个字段: $GPRMI,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>,<15>,<16>,<17>,<18>,<19>,<20>,<21>,<22>,<23>*<CR><LF>
|
if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len,
|
"$%*,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p*%**",
|
&astFields[0], &astFields[1], &astFields[2], &astFields[3], &astFields[4],
|
&astFields[5], &astFields[6], &astFields[7], &astFields[8], &astFields[9],
|
&astFields[10], &astFields[11], &astFields[12], &astFields[13], &astFields[14],
|
&astFields[15], &astFields[16], &astFields[17], &astFields[18], &astFields[19],
|
&astFields[20], &astFields[21], &astFields[22]) != 25)
|
{
|
return HIDO_ERR;
|
}
|
|
// 解析各字段
|
l_stGPRMI.m_u32UTCTime = (HIDO_UINT32)(atof((HIDO_CHAR *)astFields[0].m_pData) * 100); // 转换为整数
|
l_stGPRMI.m_u16WeekNumber = (HIDO_UINT16)atoi((HIDO_CHAR *)astFields[1].m_pData);
|
l_stGPRMI.m_u32TimeOfWeek = (HIDO_UINT32)(atof((HIDO_CHAR *)astFields[2].m_pData) * 1000); // 转换为毫秒
|
l_stGPRMI.m_dLatitude = atof((HIDO_CHAR *)astFields[3].m_pData);
|
l_stGPRMI.m_dLongitude = atof((HIDO_CHAR *)astFields[4].m_pData);
|
l_stGPRMI.m_fAltitude = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[5].m_pData);
|
l_stGPRMI.m_fEastStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[6].m_pData);
|
l_stGPRMI.m_fNorthStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[7].m_pData);
|
l_stGPRMI.m_fAltStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[8].m_pData);
|
l_stGPRMI.m_fEastVelocity = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[9].m_pData);
|
l_stGPRMI.m_fNorthVelocity = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[10].m_pData);
|
l_stGPRMI.m_fUpVelocity = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[11].m_pData);
|
l_stGPRMI.m_fEastVelStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[12].m_pData);
|
l_stGPRMI.m_fNorthVelStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[13].m_pData);
|
l_stGPRMI.m_fUpVelStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[14].m_pData);
|
l_stGPRMI.m_fRollAngle = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[15].m_pData);
|
l_stGPRMI.m_fPitchAngleStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[16].m_pData);
|
l_stGPRMI.m_fRollAngleStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[17].m_pData);
|
l_stGPRMI.m_fHeadingAngleStdDev = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[18].m_pData);
|
l_stGPRMI.m_fBaselineDistance = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[19].m_pData);
|
l_stGPRMI.m_u8SatelliteCount = (HIDO_UINT8)atoi((HIDO_CHAR *)astFields[20].m_pData);
|
l_stGPRMI.m_u8ReservedFlags = (HIDO_UINT8)atoi((HIDO_CHAR *)astFields[21].m_pData);
|
l_stGPRMI.m_u8PositionQuality = (HIDO_UINT8)atoi((HIDO_CHAR *)astFields[22].m_pData);
|
|
l_stGPRMI.m_bValid = HIDO_TRUE;
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_ParseGPIMU
|
* Description : 解析GPIMU数据包
|
* Input : _pcData GPIMU数据
|
* : _u32Len GPIMU数据长度
|
* Output : None
|
* Return : HIDO_OK 成功, HIDO_ERR 失败
|
* Author : www.hido-studio.com
|
* Modified Date: : 2025年11月11日
|
*******************************************************************************/
|
static HIDO_INT32 GPS_ParseGPIMU(HIDO_CHAR *_pcData, HIDO_UINT32 _u32Len)
|
{
|
HIDO_DataStruct astFields[9];
|
HIDO_UINT8 u8CalcChecksum = 0;
|
HIDO_UINT32 i = 0;
|
HIDO_CHAR *pCheckStart = HIDO_NULL;
|
HIDO_CHAR *pCheckEnd = HIDO_NULL;
|
|
memset(&l_stGPIMU, 0, sizeof(ST_GPIMU));
|
l_stGPIMU.m_bValid = HIDO_FALSE;
|
|
// 解析9个字段: $GPIMU,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>*<CR><LF>
|
if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len,
|
"$GPIMU,%p,%p,%p,%p,%p,%p,%p,%p,%p*%**",
|
&astFields[0], &astFields[1], &astFields[2], &astFields[3],
|
&astFields[4], &astFields[5], &astFields[6], &astFields[7],
|
&astFields[8]) < 10)
|
{
|
return HIDO_ERR;
|
}
|
|
// 计算异或校验: 从第一个字段到第9个字段的异或和
|
// 示例数据: $GPIMU, 054752.002, 0.000, 0.007, -1.032, -0.003, 0.053, -0.016,26.00@59
|
// 格式说明: 语句示例中的异或校验和为0@59 (十六进制59)
|
pCheckStart = strchr(_pcData, ','); // 找到第一个逗号
|
pCheckEnd = strrchr(_pcData, '*'); // 找到最后一个星号
|
|
if (pCheckStart != HIDO_NULL && pCheckEnd != HIDO_NULL && pCheckEnd > pCheckStart)
|
{
|
// 计算从第一个逗号后到星号前的所有字符的异或
|
for (i = 0; pCheckStart + i < pCheckEnd; i++)
|
{
|
u8CalcChecksum ^= (HIDO_UINT8)(pCheckStart[i]);
|
}
|
}
|
|
// 解析各字段
|
l_stGPIMU.m_u32UTCTime = (HIDO_UINT32)(atof((HIDO_CHAR *)astFields[0].m_pData) * 1000); // 转换为毫秒
|
l_stGPIMU.m_fAccelX = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[1].m_pData);
|
l_stGPIMU.m_fAccelY = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[2].m_pData);
|
l_stGPIMU.m_fAccelZ = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[3].m_pData);
|
l_stGPIMU.m_fGyroX = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[4].m_pData);
|
l_stGPIMU.m_fGyroY = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[5].m_pData);
|
l_stGPIMU.m_fGyroZ = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[6].m_pData);
|
l_stGPIMU.m_fTemperature = (HIDO_FLOAT)atof((HIDO_CHAR *)astFields[7].m_pData);
|
|
// 第9个字段是异或校验,直接解析
|
l_stGPIMU.m_u8Checksum = (HIDO_UINT8)atoi((HIDO_CHAR *)astFields[8].m_pData);
|
|
// 验证校验和 (根据文档,这是异或校验)
|
// 注意: 文档中显示校验值在最后,需要根据实际协议确定是否验证
|
|
l_stGPIMU.m_bValid = HIDO_TRUE;
|
|
return HIDO_OK;
|
}
|
u16 g_spsum, g_snum;
|
static HIDO_INT32 GPS_ParseGSV(HIDO_CHAR *_pcData, HIDO_UINT32 _u32Len)
|
{
|
ST_GPS stGPS;
|
HIDO_DataStruct spower[4];
|
|
memset(&stGPS, 0, sizeof(ST_GPS));
|
// if (GPS_DataCheck(_pcData, _u32Len) != HIDO_OK)
|
// {
|
// return HIDO_ERR;
|
// }
|
|
if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len, "$%*,%*,%*,%*,%*,%*,%*,%p,%*,%*,%*,%p,%*,%*,%*,%p,%*,%*,%*,%p,%**", &spower[0], &spower[1], &spower[2], &spower[3]) == 21)
|
{
|
g_snum += 4;
|
g_spsum += atoi((HIDO_CHAR *)spower[0].m_pData) + atoi((HIDO_CHAR *)spower[1].m_pData) + atoi((HIDO_CHAR *)spower[2].m_pData) + atoi((HIDO_CHAR *)spower[3].m_pData);
|
}
|
else if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len, "$%*,%*,%*,%*,%*,%*,%*,%p,%*,%*,%*,%p,%*,%*,%*,%p,%**", &spower[0], &spower[1], &spower[2]) == 17)
|
{
|
g_snum += 3;
|
g_spsum += atoi((HIDO_CHAR *)spower[0].m_pData) + atoi((HIDO_CHAR *)spower[1].m_pData) + atoi((HIDO_CHAR *)spower[2].m_pData);
|
}
|
else if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len, "$%*,%*,%*,%*,%*,%*,%*,%p,%*,%*,%*,%p,%**", &spower[0], &spower[1]) == 13)
|
{
|
g_snum += 2;
|
g_spsum += atoi((HIDO_CHAR *)spower[0].m_pData) + atoi((HIDO_CHAR *)spower[1].m_pData);
|
}
|
else if (HIDO_UtilParseFormat((HIDO_UINT8 *)_pcData, _u32Len, "$%*,%*,%*,%*,%*,%*,%*,%p,%**", &spower[0]) == 9)
|
{
|
g_snum += 1;
|
g_spsum += atoi((HIDO_CHAR *)spower[0].m_pData);
|
}
|
// l_u8PosState = atoi((HIDO_CHAR *)stPosState.m_pData);
|
|
return HIDO_OK;
|
}
|
/*******************************************************************************
|
* Function Name : GPS_RecvFsm
|
* Description : GPS ���ݽ���״̬��
|
* Input : _u8RecvChar һ�������ַ�
|
* Output : None
|
* Return : one
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��5��07��
|
*******************************************************************************/
|
static HIDO_VOID GPS_RecvFsm(HIDO_UINT8 _u8RecvChar)
|
{
|
static int LastRTK = 0;
|
|
HIDO_CHAR GPS_1[10] = "�豸����";
|
HIDO_CHAR GPS_4[10] = "�豸�̶�";
|
HIDO_CHAR GPS_5[10] = "�豸����";
|
|
switch (l_stGPSRecv.m_eState)
|
{
|
case GPS_RECV_STATE_IDLE:
|
{
|
if ('$' == _u8RecvChar)
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_HEAD;
|
l_stGPSRecv.m_u32RecvLen = 0;
|
l_stGPSRecv.m_acRecvBuf[l_stGPSRecv.m_u32RecvLen++] = _u8RecvChar;
|
}
|
break;
|
}
|
case GPS_RECV_STATE_HEAD:
|
{
|
l_stGPSRecv.m_acRecvBuf[l_stGPSRecv.m_u32RecvLen++] = _u8RecvChar;
|
if (l_stGPSRecv.m_u32RecvLen >= l_stGPSRecv.m_u32HeaderLen)
|
{
|
if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader, l_stGPSRecv.m_u32HeaderLen) == 0)
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_CR;
|
}
|
else if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader2, l_stGPSRecv.m_u32Header2Len) == 0)
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_CR;
|
}
|
else if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader3, l_stGPSRecv.m_u32Header3Len) == 0)
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_CR;
|
}
|
else if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader4, l_stGPSRecv.m_u32Header4Len) == 0)
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_CR;
|
}
|
else if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader5, l_stGPSRecv.m_u32Header5Len) == 0)
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_CR;
|
}
|
else
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_IDLE;
|
}
|
}
|
|
break;
|
}
|
case GPS_RECV_STATE_CR:
|
{
|
l_stGPSRecv.m_acRecvBuf[l_stGPSRecv.m_u32RecvLen++] = _u8RecvChar;
|
|
if (l_stGPSRecv.m_u32RecvLen >= (sizeof(l_stGPSRecv.m_acRecvBuf) - 1))
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_IDLE;
|
break;
|
}
|
|
if ('\r' == _u8RecvChar)
|
{
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_LF;
|
}
|
|
break;
|
}
|
case GPS_RECV_STATE_LF:
|
{
|
static u8 gpsled_state = 0;
|
l_stGPSRecv.m_acRecvBuf[l_stGPSRecv.m_u32RecvLen++] = _u8RecvChar;
|
if ('\n' == _u8RecvChar)
|
{
|
|
/* ����GPS HZ */
|
// g_com_map[GPS_HZ] = 10;
|
//if (l_bGPSConfig || l_u8GPS_HZ != g_com_map[GPS_HZ])
|
{
|
l_bGPSConfig = HIDO_FALSE;
|
//GPS_RateConfig(g_com_map[GPS_HZ]);
|
}
|
|
if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader3, l_stGPSRecv.m_u32Header3Len) == 0)
|
{
|
GPS_ParseGSV(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_u32RecvLen);
|
}
|
else if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader4, l_stGPSRecv.m_u32Header4Len) == 0)
|
{
|
// 解析GPRMI数据
|
GPS_ParseGPRMI(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_u32RecvLen);
|
}
|
else if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader5, l_stGPSRecv.m_u32Header5Len) == 0)
|
{
|
// 解析GPIMU数据
|
GPS_ParseGPIMU(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_u32RecvLen);
|
}
|
|
if (memcmp(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_acHeader, l_stGPSRecv.m_u32HeaderLen) == 0)
|
{
|
static uint32_t gps_uploadtimer = 0;
|
GPS_ParseGGA(l_stGPSRecv.m_acRecvBuf, l_stGPSRecv.m_u32RecvLen);
|
l_stGPSRecv.m_acRecvBuf[l_stGPSRecv.m_u32RecvLen - 2] = '\0';
|
//if (HIDO_TimerGetTick() - gps_uploadtimer > g_com_map[GPSUPLOADTIME_INDEX] * 1000)
|
{
|
gps_uploadtimer = HIDO_TimerGetTick();
|
UDPClient_UploadGPS(l_stGPSRecv.m_acRecvBuf);
|
}
|
}
|
if ((HIDO_TimerGetTick() - l_u32QXTick) >= 1000)
|
{
|
l_u32QXTick = HIDO_TimerGetTick();
|
#ifdef __USE_QXWZ__
|
qxwz_app_upload_gga(l_stGPSRecv.m_acRecvBuf);
|
#endif
|
}
|
}
|
|
l_stGPSRecv.m_eState = GPS_RECV_STATE_IDLE;
|
break;
|
}
|
default:
|
{
|
break;
|
}
|
}
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_Rest
|
* Description : GPS��λ
|
* Input : None
|
* Output : None
|
* Return : None
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��1��8��
|
*******************************************************************************/
|
static HIDO_VOID GPS_Rest(void)
|
{
|
GPIO_SET(&l_astGPSPin[GPS_PIN_REST]);
|
vTaskDelay(pdMS_TO_TICKS(10));
|
GPIO_RESET(&l_astGPSPin[GPS_PIN_REST]);
|
vTaskDelay(pdMS_TO_TICKS(10));
|
GPIO_SET(&l_astGPSPin[GPS_PIN_REST]);
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_PowerOn
|
* Description : GPS�ϵ�
|
* Input : None
|
* Output : None
|
* Return : None
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��1��8��
|
*******************************************************************************/
|
static HIDO_VOID GPS_PowerOn(void)
|
{
|
GPIO_SET(&l_astGPSPin[GPS_PIN_EN]);
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_PowerOff
|
* Description : GPS����
|
* Input : None
|
* Output : None
|
* Return : None
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��1��8��
|
*******************************************************************************/
|
HIDO_VOID GPS_PowerOff(void)
|
{
|
GPIO_RESET(&l_astGPSPin[GPS_PIN_EN]);
|
}
|
|
/*******************************************************************************
|
* Global Function *
|
*******************************************************************************/
|
|
/*******************************************************************************
|
* Function Name : GPS_GetState
|
* Description : ��ȡGPS��λ״̬
|
* Input : None
|
* Output : None
|
* Return : ��λ״̬ 0 1 2 3
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��1��8��
|
*******************************************************************************/
|
HIDO_UINT8 GPS_GetState(HIDO_VOID)
|
{
|
return l_u8PosState;
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_PinRegister
|
* Description : GPSģ��ܽ�ע��
|
* Input : _ePin �ܽŶ���
|
* : _pstGPIOx GPIOx
|
* : _u16GPIOPin GPIO_PIN_x
|
* Output : None
|
* Return : None
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��1��8��
|
*******************************************************************************/
|
HIDO_VOID GPS_PinRegister(E_GPSPin _ePin, GPIO_TypeDef *_pstGPIOx, HIDO_UINT16 _u16GPIOPin)
|
{
|
l_astGPSPin[_ePin].m_pstGPIOx = _pstGPIOx;
|
l_astGPSPin[_ePin].m_u16GPIOPin = _u16GPIOPin;
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_Poll
|
* Description : GPS��ѯ����
|
* Input : None
|
* Output : None
|
* Return : None
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��1��8��
|
*******************************************************************************/
|
HIDO_VOID GPS_Poll(void)
|
{
|
static HIDO_UINT8 l_u8GPSBuff[512];
|
static HIDO_UINT32 l_u8GPSLen = 0;
|
static HIDO_UINT32 l_u8GPSRecvTick = 0;
|
|
volatile HIDO_INT32 i32Result = HIDO_OK;
|
HIDO_UINT8 u8RecvChar = 0;
|
UART_HandleTypeDef *pstUartHandle = HIDO_NULL;
|
|
Uart_GetHandle(UART_ID_DBG, (HIDO_VOID **)&pstUartHandle);
|
|
while ((i32Result = Uart_GetChar(UART_ID_GPS, &u8RecvChar)) == HIDO_OK)
|
{
|
#if 0
|
if (DBG_GetMode() == DBG_MODE_GPS || DBG_GetMode() == DBG_MODE_CFG)
|
{
|
HAL_UART_Transmit(pstUartHandle, &u8RecvChar, 1, 1000);
|
}
|
#endif
|
GPS_RecvFsm(u8RecvChar);
|
l_u8GPSBuff[l_u8GPSLen++] = u8RecvChar;
|
if (l_u8GPSLen >= sizeof(l_u8GPSBuff))
|
{
|
#ifdef __USE_TCP_RTCM__
|
RTKClient_ReportData(l_u8GPSBuff, l_u8GPSLen);
|
#endif
|
#ifdef __USE_NTRIP__
|
NTRIPApp_ReportGGA(l_u8GPSBuff, l_u8GPSLen);
|
#endif
|
l_u8GPSLen = 0;
|
}
|
|
l_u8GPSRecvTick = HIDO_TimerGetTick();
|
}
|
|
if (l_u8GPSLen > 0)
|
{
|
if ((HIDO_TimerGetTick() - l_u8GPSRecvTick) > 50)
|
{
|
#ifdef __USE_TCP_RTCM__
|
RTKClient_ReportData(l_u8GPSBuff, l_u8GPSLen);
|
#endif
|
#ifdef __USE_NTRIP__
|
NTRIPApp_ReportGGA(l_u8GPSBuff, l_u8GPSLen);
|
#endif
|
l_u8GPSLen = 0;
|
}
|
}
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_Init
|
* Description : GPSģ���ʼ��
|
* Input : None
|
* Output : None
|
* Return : None
|
* Author : www.hido-studio.com
|
* Modified Date: : 2021��1��8��
|
*******************************************************************************/
|
HIDO_VOID GPS_Init(void)
|
{
|
uint32_t gpsbaudrate;
|
GPS_PowerOn();
|
GPS_Rest();
|
|
ST_UartInit stInit;
|
|
stInit.m_eRxMode = UART_RX_MODE_DMA;
|
stInit.m_eTxMode = UART_TX_MODE_DMA;
|
stInit.m_pu8RxBuf = l_au8GPSUartRxBuf;
|
stInit.m_u32RxBufSize = GPS_UART_RX_BUF_SIZE;
|
stInit.m_pu8TxBuf = l_au8GPSUartTxBuf;
|
stInit.m_u32TxBufSize = GPS_UART_TX_BUF_SIZE;
|
stInit.m_u32TxQueueMemberCnt = 2;
|
Uart_Init(UART_ID_GPS, &stInit);
|
|
HIDO_UtilBzero(&l_stGPSRecv, sizeof(ST_GPSRecv));
|
l_stGPSRecv.m_u32HeaderLen = HIDO_UtilSnprintf(l_stGPSRecv.m_acHeader, sizeof(l_stGPSRecv.m_acHeader), "$GNGGA");
|
l_stGPSRecv.m_u32Header2Len = HIDO_UtilSnprintf(l_stGPSRecv.m_acHeader2, sizeof(l_stGPSRecv.m_acHeader2), "$GPGSV");
|
l_stGPSRecv.m_u32Header3Len = HIDO_UtilSnprintf(l_stGPSRecv.m_acHeader3, sizeof(l_stGPSRecv.m_acHeader3), "$GBGSV");
|
l_stGPSRecv.m_u32Header4Len = HIDO_UtilSnprintf(l_stGPSRecv.m_acHeader4, sizeof(l_stGPSRecv.m_acHeader4), "$GPRMI");
|
l_stGPSRecv.m_u32Header5Len = HIDO_UtilSnprintf(l_stGPSRecv.m_acHeader5, sizeof(l_stGPSRecv.m_acHeader5), "$GPIMU");
|
l_bGPSConfig = HIDO_TRUE;
|
//gpsbaudrate = (g_com_map[GPSBAUDRATE1_INDEX] << 8) | g_com_map[GPSBAUDRATE2_INDEX];
|
if (gpsbaudrate > 921600 || gpsbaudrate < 9600)
|
{
|
gpsbaudrate = 115200;
|
}
|
Uart_ReConfigBaudRate(UART_ID_GPS, gpsbaudrate);
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_GetGPRMI
|
* Description : 获取最新的GPRMI数据
|
* Input : _pstGPRMI - 存储GPRMI数据的结构体指针
|
* Output : None
|
* Return : HIDO_OK - 成功, HIDO_ERR - 失败或数据无效
|
* Author : www.hido-studio.com
|
* Modified Date: : 2025年11月11日
|
*******************************************************************************/
|
HIDO_INT32 GPS_GetGPRMI(ST_GPRMI *_pstGPRMI)
|
{
|
if (_pstGPRMI == HIDO_NULL)
|
{
|
return HIDO_ERR;
|
}
|
|
if (l_stGPRMI.m_bValid == HIDO_FALSE)
|
{
|
return HIDO_ERR;
|
}
|
|
memcpy(_pstGPRMI, &l_stGPRMI, sizeof(ST_GPRMI));
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : GPS_GetGPIMU
|
* Description : 获取最新的GPIMU数据
|
* Input : _pstGPIMU - 存储GPIMU数据的结构体指针
|
* Output : None
|
* Return : HIDO_OK - 成功, HIDO_ERR - 失败或数据无效
|
* Author : www.hido-studio.com
|
* Modified Date: : 2025年11月11日
|
*******************************************************************************/
|
HIDO_INT32 GPS_GetGPIMU(ST_GPIMU *_pstGPIMU)
|
{
|
if (_pstGPIMU == HIDO_NULL)
|
{
|
return HIDO_ERR;
|
}
|
|
if (l_stGPIMU.m_bValid == HIDO_FALSE)
|
{
|
return HIDO_ERR;
|
}
|
|
memcpy(_pstGPIMU, &l_stGPIMU, sizeof(ST_GPIMU));
|
|
return HIDO_OK;
|
}
|