766 lines
26 KiB
C
766 lines
26 KiB
C
|
#include "app_config.h"
|
|||
|
#include "asm/clock.h"
|
|||
|
#include "system/timer.h"
|
|||
|
#include "asm/uart_dev.h"
|
|||
|
#include "atk1218_bd.h"
|
|||
|
#include "asm/cpu.h"
|
|||
|
#include "generic/gpio.h"
|
|||
|
|
|||
|
#if defined(TCFG_GPS_DEV_ENABLE) && TCFG_GPS_DEV_ENABLE
|
|||
|
|
|||
|
#undef LOG_TAG_CONST
|
|||
|
#define LOG_TAG "[gps]"
|
|||
|
#define LOG_ERROR_ENABLE
|
|||
|
#define LOG_INFO_ENABLE
|
|||
|
#include "debug.h"
|
|||
|
|
|||
|
|
|||
|
#define UT2_MAX_RECV_LEN 1024 //最大接收缓存字节数
|
|||
|
u8 ut2_rx_buf[UT2_MAX_RECV_LEN] = {0}; //接收缓冲,最大UT2_MAX_RECV_LEN个字节.
|
|||
|
uart_bus_t *ut2_gps = NULL;
|
|||
|
volatile u8 ut2_rx_sta = 0;
|
|||
|
|
|||
|
u8 ut2_rx_gpsdata[UT2_MAX_RECV_LEN] = {0};
|
|||
|
const u32 _BAUD_id[9] = {4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600}; //模块支持波特率数组
|
|||
|
|
|||
|
//从buf里面得到第cx个逗号所在的位置
|
|||
|
//返回值:0~0XFE,代表逗号所在位置的偏移.
|
|||
|
// 0XFF,代表不存在第cx个逗号
|
|||
|
static u8 nmea_comma_pos(u8 *buf, u8 cx)
|
|||
|
{
|
|||
|
u8 *p = buf;
|
|||
|
while (cx) {
|
|||
|
if (*buf == '*' || *buf < ' ' || *buf > 'z') {
|
|||
|
return 0XFF; //遇到'*'或者非法字符,则不存在第cx个逗号
|
|||
|
}
|
|||
|
if (*buf == ',') {
|
|||
|
cx--;
|
|||
|
}
|
|||
|
buf++;
|
|||
|
}
|
|||
|
return buf - p;
|
|||
|
}
|
|||
|
//m^n函数
|
|||
|
//返回值:m^n次方.
|
|||
|
static u32 nmea_pow(u8 m, u8 n)
|
|||
|
{
|
|||
|
u32 result = 1;
|
|||
|
while (n--) {
|
|||
|
result *= m;
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
//str转换为数字,以','或者'*'结束
|
|||
|
//buf:数字存储区
|
|||
|
//dx:小数点位数,返回给调用函数
|
|||
|
//返回值:转换后的数值
|
|||
|
static int nmea_str2num(u8 *buf, u8 *dx)
|
|||
|
{
|
|||
|
u8 *p = buf;
|
|||
|
u32 ires = 0, fres = 0;
|
|||
|
u8 ilen = 0, flen = 0, i;
|
|||
|
u8 mask = 0;
|
|||
|
int res;
|
|||
|
while (1) {
|
|||
|
if (*p == '-') { //负数
|
|||
|
mask |= 0X02;
|
|||
|
p++;
|
|||
|
}
|
|||
|
if (*p == ',' || (*p == '*')) { //结束
|
|||
|
break;
|
|||
|
}
|
|||
|
if (*p == '.') {
|
|||
|
mask |= 0X01;
|
|||
|
p++;
|
|||
|
} else if (*p > '9' || (*p < '0')) { //非法字符
|
|||
|
ilen = 0;
|
|||
|
flen = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (mask & 0X01) {
|
|||
|
flen++;
|
|||
|
} else {
|
|||
|
ilen++;
|
|||
|
}
|
|||
|
p++;
|
|||
|
}
|
|||
|
if (mask & 0X02) {
|
|||
|
buf++;
|
|||
|
}
|
|||
|
for (i = 0; i < ilen; i++) { //整数部分数据
|
|||
|
ires += nmea_pow(10, ilen - 1 - i) * (buf[i] - '0');
|
|||
|
}
|
|||
|
if (flen > 5) {
|
|||
|
flen = 5;
|
|||
|
}
|
|||
|
*dx = flen; //小数点位数
|
|||
|
for (i = 0; i < flen; i++) { //小数部分数据
|
|||
|
fres += nmea_pow(10, flen - 1 - i) * (buf[ilen + 1 + i] - '0');
|
|||
|
}
|
|||
|
res = ires * nmea_pow(10, flen) + fres;
|
|||
|
if (mask & 0X02) {
|
|||
|
res = -res;
|
|||
|
}
|
|||
|
return res;
|
|||
|
}
|
|||
|
//分析GPGSV信息
|
|||
|
//gpsx:nmea信息结构体
|
|||
|
//buf:接收到的GPS数据缓冲区首地址
|
|||
|
static void nmea_gpgsv_analysis(nmea_msg_t *gpsx, u8 *buf)
|
|||
|
{
|
|||
|
u8 *p, *p1, dx;
|
|||
|
u8 len, i, j, slx = 0;
|
|||
|
u8 posx;
|
|||
|
p = buf;
|
|||
|
p1 = (u8 *)strstr((const char *)p, "$GPGSV");
|
|||
|
if (p1 == NULL) {
|
|||
|
log_info("no GPGSV!\n");
|
|||
|
return;
|
|||
|
} else {
|
|||
|
/* log_info("receive GPGSV!\n"); */
|
|||
|
}
|
|||
|
len = p1[7] - '0'; //GPGSV的条数
|
|||
|
posx = nmea_comma_pos(p1, 3); //可见卫星总数
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->svnum = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
for (i = 0; i < len; i++) {
|
|||
|
p1 = (u8 *)strstr((const char *)p, "$GPGSV");
|
|||
|
for (j = 0; j < 4; j++) {
|
|||
|
posx = nmea_comma_pos(p1, 4 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->slmsg[slx].num = nmea_str2num(p1 + posx, &dx); //卫星编号
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 5 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->slmsg[slx].eledeg = nmea_str2num(p1 + posx, &dx); //卫星仰角
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 6 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->slmsg[slx].azideg = nmea_str2num(p1 + posx, &dx); //卫星方位角
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 7 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->slmsg[slx].sn = nmea_str2num(p1 + posx, &dx); //卫星信噪比
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
slx++;
|
|||
|
}
|
|||
|
p = p1 + 1; //切换到下一个GPGSV信息
|
|||
|
}
|
|||
|
}
|
|||
|
//分析BDGSV信息
|
|||
|
//gpsx:nmea信息结构体
|
|||
|
//buf:接收到的GPS数据缓冲区首地址
|
|||
|
static void nmea_bdgsv_analysis(nmea_msg_t *gpsx, u8 *buf)
|
|||
|
{
|
|||
|
u8 *p, *p1, dx;
|
|||
|
u8 len, i, j, slx = 0;
|
|||
|
u8 posx;
|
|||
|
p = buf;
|
|||
|
p1 = (u8 *)strstr((const char *)p, "$BDGSV");
|
|||
|
if (p1 == NULL) {
|
|||
|
log_info("no BDGSV!\n");
|
|||
|
return;
|
|||
|
} else {
|
|||
|
/* log_info("receive BDGSV!\n"); */
|
|||
|
}
|
|||
|
len = p1[7] - '0'; //BDGSV的条数
|
|||
|
posx = nmea_comma_pos(p1, 3); //可见北斗卫星总数
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->beidou_svnum = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
for (i = 0; i < len; i++) {
|
|||
|
p1 = (u8 *)strstr((const char *)p, "$BDGSV");
|
|||
|
for (j = 0; j < 4; j++) {
|
|||
|
posx = nmea_comma_pos(p1, 4 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->beidou_slmsg[slx].num = nmea_str2num(p1 + posx, &dx); //卫星编号
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 5 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->beidou_slmsg[slx].eledeg = nmea_str2num(p1 + posx, &dx); //卫星仰角
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 6 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->beidou_slmsg[slx].azideg = nmea_str2num(p1 + posx, &dx); //卫星方位角
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 7 + j * 4);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->beidou_slmsg[slx].sn = nmea_str2num(p1 + posx, &dx); //卫星信噪比
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
slx++;
|
|||
|
}
|
|||
|
p = p1 + 1; //切换到下一个BDGSV信息
|
|||
|
}
|
|||
|
}
|
|||
|
//分析GNGGA信息
|
|||
|
//gpsx:nmea信息结构体
|
|||
|
//buf:接收到的GPS数据缓冲区首地址
|
|||
|
static void nmea_gngga_analysis(nmea_msg_t *gpsx, u8 *buf)
|
|||
|
{
|
|||
|
u8 *p1, dx;
|
|||
|
u8 posx;
|
|||
|
p1 = (u8 *)strstr((const char *)buf, "$GNGGA");
|
|||
|
if (p1 == NULL) {
|
|||
|
log_info("no GNGGA!\n");
|
|||
|
return;
|
|||
|
} else {
|
|||
|
/* log_info("receive GNGGA!\n"); */
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 6); //GPS状态
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->gpssta = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 7); //用于定位的卫星数
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->posslnum = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 9); //海拔高度
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->altitude = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
}
|
|||
|
//分析GNGSA信息
|
|||
|
//gpsx:nmea信息结构体
|
|||
|
//buf:接收到的GPS数据缓冲区首地址
|
|||
|
static void nmea_gngsa_analysis(nmea_msg_t *gpsx, u8 *buf)
|
|||
|
{
|
|||
|
u8 *p1, dx;
|
|||
|
u8 posx;
|
|||
|
u8 i;
|
|||
|
p1 = (u8 *)strstr((const char *)buf, "$GNGSA");
|
|||
|
if (p1 == NULL) {
|
|||
|
log_info("no GNGSA!\n");
|
|||
|
return;
|
|||
|
} else {
|
|||
|
/* log_info("receive GNGSA!\n"); */
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 2); //定位类型
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->fixmode = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
for (i = 0; i < 12; i++) { //定位卫星编号
|
|||
|
posx = nmea_comma_pos(p1, 3 + i);
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->possl[i] = nmea_str2num(p1 + posx, &dx);
|
|||
|
} else {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 15); //PDOP位置精度因子
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->pdop = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 16); //HDOP位置精度因子
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->hdop = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 17); //VDOP位置精度因子
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->vdop = nmea_str2num(p1 + posx, &dx);
|
|||
|
}
|
|||
|
}
|
|||
|
//分析GNRMC信息
|
|||
|
//gpsx:nmea信息结构体
|
|||
|
//buf:接收到的GPS数据缓冲区首地址
|
|||
|
static void nmea_gnrmc_analysis(nmea_msg_t *gpsx, u8 *buf)
|
|||
|
{
|
|||
|
u8 *p1, dx;
|
|||
|
u8 posx;
|
|||
|
u32 temp;
|
|||
|
float rs;
|
|||
|
p1 = (u8 *)strstr((const char *)buf, "$GNRMC"); //"$GNRMC",经常有&和GNRMC分开的情况,故只判断GPRMC.
|
|||
|
if (p1 == NULL) {
|
|||
|
log_info("no GNRMC!\n");
|
|||
|
return;
|
|||
|
} else {
|
|||
|
/* log_info("receive GNRMC!\n"); */
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 1); //UTC时间
|
|||
|
if (posx != 0XFF) {
|
|||
|
temp = nmea_str2num(p1 + posx, &dx) / nmea_pow(10, dx); //UTC时间,去掉ms
|
|||
|
gpsx->utc.hour = temp / 10000;
|
|||
|
gpsx->utc.min = (temp / 100) % 100;
|
|||
|
gpsx->utc.sec = temp % 100;
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 3); //纬度
|
|||
|
if (posx != 0XFF) {
|
|||
|
temp = nmea_str2num(p1 + posx, &dx);
|
|||
|
gpsx->latitude = temp / nmea_pow(10, dx + 2); //得到°
|
|||
|
rs = temp % nmea_pow(10, dx + 2); //得到'
|
|||
|
gpsx->latitude = gpsx->latitude * nmea_pow(10, 5) + (rs * nmea_pow(10, 5 - dx)) / 60; //转换为°
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 4); //南纬还是北纬
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->nshemi = *(p1 + posx);
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 5); //得到经度
|
|||
|
if (posx != 0XFF) {
|
|||
|
temp = nmea_str2num(p1 + posx, &dx);
|
|||
|
gpsx->longitude = temp / nmea_pow(10, dx + 2); //得到°
|
|||
|
rs = temp % nmea_pow(10, dx + 2); //得到'
|
|||
|
gpsx->longitude = gpsx->longitude * nmea_pow(10, 5) + (rs * nmea_pow(10, 5 - dx)) / 60; //转换为°
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 6); //东经还是西经
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->ewhemi = *(p1 + posx);
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 9); //得到UTC日期
|
|||
|
if (posx != 0XFF) {
|
|||
|
temp = nmea_str2num(p1 + posx, &dx); //得到UTC日期
|
|||
|
gpsx->utc.date = temp / 10000;
|
|||
|
gpsx->utc.month = (temp / 100) % 100;
|
|||
|
gpsx->utc.year = 2000 + temp % 100;
|
|||
|
}
|
|||
|
}
|
|||
|
//分析GNVTG信息
|
|||
|
//gpsx:nmea信息结构体
|
|||
|
//buf:接收到的GPS数据缓冲区首地址
|
|||
|
static void nmea_gnvtg_analysis(nmea_msg_t *gpsx, u8 *buf)
|
|||
|
{
|
|||
|
u8 *p1, dx;
|
|||
|
u8 posx;
|
|||
|
p1 = (u8 *)strstr((const char *)buf, "$GNVTG");
|
|||
|
if (p1 == NULL) {
|
|||
|
log_info("no GNVGT!\n");
|
|||
|
return;
|
|||
|
} else {
|
|||
|
/* log_info("receive GNVGT!\n"); */
|
|||
|
}
|
|||
|
posx = nmea_comma_pos(p1, 7); //得到地面速率
|
|||
|
if (posx != 0XFF) {
|
|||
|
gpsx->speed = nmea_str2num(p1 + posx, &dx);
|
|||
|
if (dx < 3) {
|
|||
|
gpsx->speed *= nmea_pow(10, 3 - dx); //确保扩大1000倍
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
//提取NMEA-0183信息
|
|||
|
//gpsx:nmea信息结构体
|
|||
|
//buf:接收到的GPS数据缓冲区首地址
|
|||
|
static void gps_analysis(nmea_msg_t *gpsx, u8 *buf)
|
|||
|
{
|
|||
|
nmea_gpgsv_analysis(gpsx, buf); //GPGSV解析
|
|||
|
nmea_bdgsv_analysis(gpsx, buf); //BDGSV解析
|
|||
|
nmea_gngga_analysis(gpsx, buf); //GNGGA解析
|
|||
|
nmea_gngsa_analysis(gpsx, buf); //GPNSA解析
|
|||
|
nmea_gnrmc_analysis(gpsx, buf); //GPNMC解析
|
|||
|
nmea_gnvtg_analysis(gpsx, buf); //GPNTG解析
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/////////////////////////////// 配置代码////////////////////////////////
|
|||
|
//检查CFG配置执行情况
|
|||
|
//返回值:0,ACK成功
|
|||
|
// 1,接收超时错误
|
|||
|
// 2,没有找到同步字符
|
|||
|
// 3,接收到NACK应答
|
|||
|
// 4,数据错位
|
|||
|
static u8 skytra_cfg_ack_check(void)
|
|||
|
{
|
|||
|
u16 len = 0, i, time = 2;
|
|||
|
u8 rval = 0;
|
|||
|
u32 time_out = 400;
|
|||
|
while (time--) {
|
|||
|
rval = 0;
|
|||
|
while ((ut2_rx_sta) == 0 && len < 50) { //等待接收到应答
|
|||
|
len++;
|
|||
|
os_time_dly(1);//10ms //等待发送完成
|
|||
|
}
|
|||
|
if (len < 50) { //超时错误.
|
|||
|
len = ut2_gps->read(ut2_rx_gpsdata, sizeof(ut2_rx_gpsdata) - 1, time_out); //接收数据长度
|
|||
|
if (len == 9) { //串口接收错位处理
|
|||
|
/* log_info_hexdump(ut2_rx_gpsdata,9); */
|
|||
|
if (ut2_rx_gpsdata[0] == 0x0a) {
|
|||
|
ut2_gps->kfifo.buf_out++;
|
|||
|
ut2_gps->kfifo.buf_in++;
|
|||
|
} else if (ut2_rx_gpsdata[0] != 0xa0) {
|
|||
|
rval = 4;//数据错位
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
for (i = 0; i < len; i++) {
|
|||
|
if (ut2_rx_gpsdata[i] == 0X83) {
|
|||
|
break;
|
|||
|
} else if (ut2_rx_gpsdata[i] == 0X84) {
|
|||
|
rval = 3;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (i == len) {
|
|||
|
rval = 2; //没有找到同步字符
|
|||
|
}
|
|||
|
} else {
|
|||
|
rval = 1; //接收超时错误
|
|||
|
}
|
|||
|
/* log_info(".....ack:%x....time:%d....len:%d\n",rval,time,len); */
|
|||
|
len = 0;
|
|||
|
ut2_rx_sta = 0; //清除接收
|
|||
|
if (rval == 0) {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return rval;
|
|||
|
}
|
|||
|
//发送一批数据给Ublox NEO-6M,这里通过串口2发送
|
|||
|
//dbuf:数据缓存首地址
|
|||
|
//len:要发送的字节数
|
|||
|
static void skytra_send_date(u8 *dbuf, u16 len)
|
|||
|
{
|
|||
|
ut2_gps->write(dbuf, len);
|
|||
|
}
|
|||
|
|
|||
|
//配置SkyTra_GPS/北斗模块波特率
|
|||
|
//返回值:0,执行成功;其他,执行失败
|
|||
|
static u8 skytra_cfg_prt(u32 baud_id)
|
|||
|
{
|
|||
|
u16 wait_cnt = 30;
|
|||
|
skytra_baudrate_t *cfg_prt = (skytra_baudrate_t *)ut2_rx_gpsdata;
|
|||
|
cfg_prt->sos = 0XA1A0;
|
|||
|
cfg_prt->pl = 0X0400; //有效数据长度(小端模式)
|
|||
|
cfg_prt->id = 0X05; //配置波特率的ID
|
|||
|
cfg_prt->com_port = 0X00; //操作串口1
|
|||
|
cfg_prt->baud_id = baud_id; ////波特率对应编号
|
|||
|
cfg_prt->attributes = 1; //保存到SRAM&FLASH
|
|||
|
cfg_prt->cs = cfg_prt->id ^ cfg_prt->com_port ^ cfg_prt->baud_id ^ cfg_prt->attributes;
|
|||
|
cfg_prt->end = 0X0A0D; //发送结束符(小端模式)
|
|||
|
skytra_send_date((u8 *)cfg_prt, sizeof(skytra_baudrate_t));
|
|||
|
ut2_rx_sta = 0; //清除接收
|
|||
|
os_time_dly(1);//10ms
|
|||
|
/* log_info_hexdump((u8 *)ut2_rx_gpsdata,sizeof(skytra_baudrate_t)); */
|
|||
|
while ((!ut2_rx_sta) && wait_cnt--) {
|
|||
|
os_time_dly(1);
|
|||
|
}
|
|||
|
ut2_gps->set_baud(_BAUD_id[baud_id]); //重新初始化串口2
|
|||
|
return skytra_cfg_ack_check();
|
|||
|
}
|
|||
|
//配置SkyTra_GPS/北斗模块的时钟脉冲宽度
|
|||
|
//width:脉冲宽度1~100000(us)
|
|||
|
//返回值:0,发送成功;其他,发送失败.
|
|||
|
static u8 skytra_cfg_pps(u32 width)
|
|||
|
{
|
|||
|
u32 temp = width;
|
|||
|
skytra_pps_width_t *cfg_tp = (skytra_pps_width_t *)ut2_rx_gpsdata;
|
|||
|
temp = (width >> 24) | ((width >> 8) & 0X0000FF00) | ((width << 8) & 0X00FF0000) | ((width << 24) & 0XFF000000); //小端模式
|
|||
|
cfg_tp->sos = 0XA1A0;
|
|||
|
cfg_tp->pl = 0X0700;
|
|||
|
cfg_tp->id = 0X65 ;
|
|||
|
cfg_tp->sub_id = 0X01;
|
|||
|
cfg_tp->width = temp; //脉冲宽度,us
|
|||
|
cfg_tp->attributes = 0X01; //保存到SRAM&FLASH
|
|||
|
cfg_tp->cs = cfg_tp->id ^ cfg_tp->sub_id ^ (cfg_tp->width >> 24) ^ (cfg_tp->width >> 16) & 0XFF ^ (cfg_tp->width >> 8) & 0XFF ^ cfg_tp->width & 0XFF ^ cfg_tp->attributes;
|
|||
|
cfg_tp->end = 0X0A0D;
|
|||
|
skytra_send_date((u8 *)cfg_tp, sizeof(skytra_pps_width_t));
|
|||
|
ut2_rx_sta = 0; //清除接收
|
|||
|
os_time_dly(6);//60ms //等待发送完成
|
|||
|
return skytra_cfg_ack_check();
|
|||
|
}
|
|||
|
//配置SkyTraF8-BD的更新速率
|
|||
|
//Frep:(取值范围:1,2,4,5,8,10,20)测量时间间隔,单位为Hz,最大不能大于50Hz
|
|||
|
//返回值:0,发送成功;其他,发送失败.
|
|||
|
static u8 skytra_cfg_rate(u8 Frep)
|
|||
|
{
|
|||
|
skytra_posrate_t *cfg_rate = (skytra_posrate_t *)ut2_rx_gpsdata;
|
|||
|
cfg_rate->sos = 0XA1A0;
|
|||
|
cfg_rate->pl = 0X0300;
|
|||
|
cfg_rate->id = 0X0E;
|
|||
|
cfg_rate->rate = Frep;
|
|||
|
cfg_rate->attributes = 0X01;
|
|||
|
cfg_rate->cs = cfg_rate->id ^ cfg_rate->rate ^ cfg_rate->attributes;
|
|||
|
cfg_rate->end = 0X0A0D;
|
|||
|
skytra_send_date((u8 *)cfg_rate, sizeof(skytra_posrate_t));
|
|||
|
ut2_rx_sta = 0; //清除接收
|
|||
|
os_time_dly(7);//70ms //等待发送完成
|
|||
|
return skytra_cfg_ack_check();
|
|||
|
}
|
|||
|
//配置SkyTra_GPS/北斗模块消息输出间隔
|
|||
|
//返回值:0,执行成功;其他,执行失败
|
|||
|
u8 skytra_cfg_message_interval()
|
|||
|
{
|
|||
|
u16 wait_cnt = 30;
|
|||
|
skytra_message_interval_t *cfg_msg = (skytra_message_interval_t *)ut2_rx_gpsdata;
|
|||
|
cfg_msg->sos = 0XA1A0;
|
|||
|
cfg_msg->pl = 0X0F00; //有效数据长度(小端模式)
|
|||
|
cfg_msg->id = 0X64; //固定
|
|||
|
cfg_msg->sub_id = 0X02; //固定
|
|||
|
cfg_msg->gga_interval = 0X01; //see skytra_message_interval_t结构体
|
|||
|
cfg_msg->gsa_interval = 0X01;
|
|||
|
cfg_msg->gsv_interval = 0X03;
|
|||
|
cfg_msg->gll_interval = 0X01;
|
|||
|
cfg_msg->rmc_interval = 0X01;
|
|||
|
cfg_msg->vtg_interval = 0X01;
|
|||
|
cfg_msg->zda_interval = 0X01;
|
|||
|
cfg_msg->gns_interval = 0X00;
|
|||
|
cfg_msg->gbs_interval = 0X00;
|
|||
|
cfg_msg->grs_interval = 0X00;
|
|||
|
cfg_msg->dtm_interval = 0X00;
|
|||
|
cfg_msg->gst_interval = 0X00;
|
|||
|
cfg_msg->attributes = 1; //保存到SRAM&FLASH
|
|||
|
cfg_msg->cs = cfg_msg->id ^ cfg_msg->sub_id ^ cfg_msg->gga_interval ^ cfg_msg->gsa_interval ^ cfg_msg->gsv_interval ^ cfg_msg->gll_interval ^ cfg_msg->rmc_interval ^ cfg_msg->vtg_interval ^ cfg_msg->zda_interval ^ cfg_msg->gns_interval ^ cfg_msg->gbs_interval ^ cfg_msg->grs_interval ^ cfg_msg->dtm_interval ^ cfg_msg->gst_interval ^ cfg_msg->attributes;
|
|||
|
cfg_msg->end = 0X0A0D;
|
|||
|
skytra_send_date((u8 *)cfg_msg, sizeof(skytra_message_interval_t));
|
|||
|
ut2_rx_sta = 0; //清除接收
|
|||
|
os_time_dly(1);//10ms
|
|||
|
while ((!ut2_rx_sta) && wait_cnt--) {
|
|||
|
os_time_dly(1);
|
|||
|
}
|
|||
|
return skytra_cfg_ack_check();
|
|||
|
}
|
|||
|
//配置SkyTra_GPS/北斗模块消息类型
|
|||
|
//type: 00:no output; 01:NMEA message; 02:binary message
|
|||
|
//返回值:0,执行成功;其他,执行失败
|
|||
|
u8 skytra_cfg_message_type(u8 type)
|
|||
|
{
|
|||
|
u16 wait_cnt = 30;
|
|||
|
skytra_message_type_t *cfg_msg_type = (skytra_message_type_t *)ut2_rx_gpsdata;
|
|||
|
cfg_msg_type->sos = 0XA1A0;
|
|||
|
cfg_msg_type->pl = 0X0300; //有效数据长度(小端模式)
|
|||
|
cfg_msg_type->id = 0X09;
|
|||
|
cfg_msg_type->type = type;
|
|||
|
cfg_msg_type->attributes = 1;
|
|||
|
cfg_msg_type->cs = cfg_msg_type->id ^ cfg_msg_type->type ^ cfg_msg_type->attributes;
|
|||
|
cfg_msg_type->end = 0X0A0D;
|
|||
|
skytra_send_date((u8 *)cfg_msg_type, sizeof(skytra_message_type_t));
|
|||
|
ut2_rx_sta = 0; //清除接收
|
|||
|
os_time_dly(1);//10ms
|
|||
|
while ((!ut2_rx_sta) && wait_cnt--) {
|
|||
|
os_time_dly(1);
|
|||
|
}
|
|||
|
return skytra_cfg_ack_check();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据
|
|||
|
static void uart2_isr_cbfun(uart_bus_t *uart2, u8 isr_state)
|
|||
|
{
|
|||
|
static u32 last_rx_cnt[2] = {0, 0};
|
|||
|
/* static u16 time_cnt=0; */
|
|||
|
if (isr_state == UT_TX) {
|
|||
|
|
|||
|
} else if (isr_state == UT_RX) {
|
|||
|
last_rx_cnt[0] = last_rx_cnt[1];
|
|||
|
last_rx_cnt[1] = uart2->kfifo.buf_in;
|
|||
|
uart2->kfifo.buf_out = last_rx_cnt[0];
|
|||
|
} else if (isr_state == UT_RX_OT) {
|
|||
|
ut2_rx_sta = 1;
|
|||
|
/* time_cnt++; */
|
|||
|
/* JL_UART2->RXCNT = uart2->frame_length; */
|
|||
|
JL_UART2->CON0 |= BIT(7);
|
|||
|
u32 _len = JL_UART2->HRXCNT;
|
|||
|
last_rx_cnt[0] = last_rx_cnt[1];
|
|||
|
last_rx_cnt[1] = uart2->kfifo.buf_in;
|
|||
|
if (uart2->kfifo.buf_out - last_rx_cnt[0] == 1) {
|
|||
|
last_rx_cnt[0]++; //串口接收错位处理
|
|||
|
}
|
|||
|
uart2->kfifo.buf_out = last_rx_cnt[0];
|
|||
|
if (uart2->kfifo.buf_out > uart2->kfifo.buf_size) {
|
|||
|
uart2->kfifo.buf_in = uart2->kfifo.buf_in & (uart2->kfifo.buf_size - 1);
|
|||
|
uart2->kfifo.buf_out = uart2->kfifo.buf_out & (uart2->kfifo.buf_size - 1);
|
|||
|
last_rx_cnt[0] = uart2->kfifo.buf_out;
|
|||
|
last_rx_cnt[1] = uart2->kfifo.buf_in;
|
|||
|
}
|
|||
|
/* log_info("cnt:%d,time:%d",last_rx_cnt[1]-last_rx_cnt[0],time_cnt); */
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void uart_gps_init()
|
|||
|
{
|
|||
|
u8 baud_id = 0, gps_init_flg = 1, fail_cnt = 0;
|
|||
|
u32 temp_cnt = 0;
|
|||
|
struct uart_platform_data_t arg;
|
|||
|
arg.tx_pin = IO_PORTA_03; //IO_PORTA_02;
|
|||
|
arg.rx_pin = IO_PORTA_04; //IO_PORT_DP;
|
|||
|
arg.rx_cbuf = ut2_rx_buf;
|
|||
|
arg.rx_cbuf_size = sizeof(ut2_rx_buf);
|
|||
|
arg.frame_length = 1024;
|
|||
|
arg.rx_timeout = 5;//随波特率修改
|
|||
|
arg.isr_cbfun = uart2_isr_cbfun; //
|
|||
|
arg.argv = JL_UART2;
|
|||
|
arg.is_9bit = 0;
|
|||
|
arg.baud = 9600;
|
|||
|
ut2_rx_sta = 0;
|
|||
|
__restart_init:
|
|||
|
if (!(JL_UART2->CON0 & BIT(0))) {
|
|||
|
ut2_gps = uart_dev_open(&arg);
|
|||
|
JL_UART2->CON0 |= BIT(1);
|
|||
|
JL_UART2->CON0 |= BIT(7); //DMA模式
|
|||
|
if (ut2_gps == 0) {
|
|||
|
log_error("------uart2 init fail!--------\n");
|
|||
|
} else {
|
|||
|
log_info("------uart2 init ok!--------\n");
|
|||
|
gps_init_flg = skytra_cfg_rate(5);
|
|||
|
os_time_dly(3);
|
|||
|
while (gps_init_flg != 0) {
|
|||
|
if (baud_id >= 9) {
|
|||
|
baud_id = 0;
|
|||
|
log_error("gps init fail!\n");
|
|||
|
JL_UART2->CON0 &= ~BIT(0);
|
|||
|
fail_cnt++;
|
|||
|
if (fail_cnt == 5) {
|
|||
|
log_error("*******gps init fail!*******!\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
goto __restart_init;
|
|||
|
/* break; */
|
|||
|
}
|
|||
|
JL_UART2->CON0 |= BIT(7);
|
|||
|
temp_cnt = JL_UART2->HRXCNT;
|
|||
|
JL_UART2->CON0 |= BIT(7);
|
|||
|
temp_cnt = JL_UART2->HRXCNT;
|
|||
|
ut2_gps->kfifo.buf_in += temp_cnt;
|
|||
|
log_error("gps init ---temp:%d---rxcnt:%d~~~~~baud:%d", temp_cnt, JL_UART2->HRXCNT, baud_id);
|
|||
|
ut2_gps->set_baud(_BAUD_id[baud_id]); //重新初始化串口2
|
|||
|
os_time_dly(3);
|
|||
|
gps_init_flg = skytra_cfg_prt(GPS_SET_BAUD);//设置波特率115200
|
|||
|
baud_id++;
|
|||
|
}
|
|||
|
os_time_dly(8);//配置完波特率后至少80ms才能配置其它参数
|
|||
|
if (baud_id <= 9) {
|
|||
|
if (skytra_cfg_pps(GPS_SET_PPS_WIDTH) == 0) {
|
|||
|
os_time_dly(8);
|
|||
|
gps_init_flg = skytra_cfg_rate(GPS_SET_FREP);
|
|||
|
if (gps_init_flg != 0) {
|
|||
|
baud_id = 0;
|
|||
|
log_error("gps init fail2!\n");
|
|||
|
JL_UART2->CON0 &= ~BIT(0);
|
|||
|
goto __restart_init;
|
|||
|
}
|
|||
|
log_info("flag:%d------gps init ok!\n", gps_init_flg);
|
|||
|
sys_s_hi_timer_add(NULL, get_gps_message, 1000); //定时1s获取GPS数据
|
|||
|
} else {
|
|||
|
baud_id = 0;
|
|||
|
log_error("gps init fail3!\n");
|
|||
|
JL_UART2->CON0 &= ~BIT(0);
|
|||
|
goto __restart_init;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
log_info("~~~~~~~~~uart2 is busy!\n");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const u8 *fixmode_str[4] = {"fail", "fail", " 2D ", " 3D "}; //fix mode字符串
|
|||
|
//打印GPS定位信息
|
|||
|
static void gps_msg_show(nmea_msg_t *new_gps_data)
|
|||
|
{
|
|||
|
u32 temp = 0;
|
|||
|
int temp1 = 0;
|
|||
|
temp = new_gps_data->longitude;
|
|||
|
log_info("longitude*100000:%d %1c ", temp, new_gps_data->ewhemi); //经度字符串
|
|||
|
temp = new_gps_data->latitude;
|
|||
|
log_info("latitude*100000:%d %1c ", temp, new_gps_data->nshemi); //纬度字符串
|
|||
|
temp1 = new_gps_data->altitude;
|
|||
|
log_info("altitude*10:%dm ", temp1); //高度字符串
|
|||
|
temp = new_gps_data->speed;
|
|||
|
log_info("speed*1000:%dkm/h", temp); //速度字符串
|
|||
|
if (new_gps_data->fixmode <= 3) { //定位状态
|
|||
|
log_info("fix mode:%s", fixmode_str[new_gps_data->fixmode]);
|
|||
|
}
|
|||
|
log_info("GPS+BD valid satellite:%02d", new_gps_data->posslnum); //用于定位的GPS卫星数
|
|||
|
log_info("GPS visible satellite:%02d", new_gps_data->svnum % 100); //可见GPS卫星数
|
|||
|
|
|||
|
log_info("BD visible satellite:%02d", new_gps_data->beidou_svnum % 100); //可见北斗卫星数
|
|||
|
|
|||
|
log_info("UTC date:%04d/%02d/%02d ", new_gps_data->utc.year, new_gps_data->utc.month, new_gps_data->utc.date); //显示UTC日期
|
|||
|
log_info("UTC time:%02d:%02d:%02d ", new_gps_data->utc.hour, new_gps_data->utc.min, new_gps_data->utc.sec); //显示UTC时间
|
|||
|
}
|
|||
|
|
|||
|
nmea_msg_t new_gps_data;
|
|||
|
void get_gps_message()
|
|||
|
{
|
|||
|
u16 len = 0;
|
|||
|
if (ut2_rx_sta) {
|
|||
|
len = ut2_gps->read(ut2_rx_gpsdata, sizeof(ut2_rx_gpsdata) - 1, 400); //接收数据长度
|
|||
|
/* log_info("rx data:\n%s\n",ut2_rx_gpsdata); */
|
|||
|
gps_analysis(&new_gps_data, ut2_rx_gpsdata);
|
|||
|
gps_msg_show(&new_gps_data);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if 0
|
|||
|
void uart1_readgps_test()
|
|||
|
{
|
|||
|
//uart0无DMA。uart1支持DMA收发。
|
|||
|
//常变量CONFIG_UART1_ENABLE_TX_DMA控制DMA发送开关(1:开DMA;0:关DMA)
|
|||
|
//当开启DMA接收时(给rx_cbuf结构体成员赋值会打开DMA接收),个数rx_cbuf_size 必须设为2的n次方
|
|||
|
u8 write_buf[64] = "1bcde2bcde3bcde4bcde5bcde6bcde7bcde8bcde9bcde0bcde12345678901234";
|
|||
|
u8 read_data[800] = {0}, rx_cnt = 0;
|
|||
|
u32 i = 0, time_out = 0;
|
|||
|
struct uart_platform_data_t arg;
|
|||
|
|
|||
|
arg.tx_pin = IO_PORTA_03; //IO_PORT_DM; //IO_PORTA_02;
|
|||
|
arg.rx_pin = IO_PORTA_04; //IO_PORT_DP;
|
|||
|
arg.rx_cbuf = ut2_rx_buf;
|
|||
|
arg.rx_cbuf_size = sizeof(ut2_rx_buf);
|
|||
|
arg.frame_length = 1024;
|
|||
|
arg.rx_timeout = 10;
|
|||
|
arg.isr_cbfun = NULL;//uart2_isr_cbfun; //
|
|||
|
arg.argv = JL_UART2;
|
|||
|
arg.is_9bit = 0;
|
|||
|
arg.baud = 115200;
|
|||
|
log_info("----uart1 test!----\n");
|
|||
|
/* if (uart_dev_close(&uart1) == 0) { */
|
|||
|
/* log_error("~~~~~~~~~uart1 close fail!~~~~~~~~~~\n"); */
|
|||
|
/* } */
|
|||
|
ut2_gps = uart_dev_open(&arg);
|
|||
|
if (ut2_gps == 0) {
|
|||
|
log_error("------uart1 init fail!--------\n");
|
|||
|
} else {
|
|||
|
log_info("------uart1 init ok!--------\n");
|
|||
|
//发送
|
|||
|
ut2_gps->putbyte(write_buf[0]);
|
|||
|
ut2_gps->putbyte('\n');
|
|||
|
ut2_gps->write(write_buf, sizeof(write_buf));
|
|||
|
u8 temp1[] = "\nTwo serial ports are required!\n";
|
|||
|
printf("\nuart1 wait for time \n");
|
|||
|
ut2_gps->write(temp1, sizeof(temp1));
|
|||
|
//接收
|
|||
|
log_info("\nuart1 wait for time !\n");
|
|||
|
time_out = 400;
|
|||
|
rx_cnt = 5;
|
|||
|
while (rx_cnt) {
|
|||
|
u32 lenlen = ut2_gps->read(read_data, sizeof(read_data), time_out);
|
|||
|
if (lenlen) {
|
|||
|
log_info("get buf: ");
|
|||
|
log_info_hexdump(read_data, lenlen);
|
|||
|
for (i = 0; i < sizeof(read_data); i++) {
|
|||
|
read_data[i] = 0;
|
|||
|
}
|
|||
|
rx_cnt--;
|
|||
|
} else {
|
|||
|
log_info("receive buf fail!\t");
|
|||
|
log_info("please send some characters!\n");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#endif
|