KT24-1110_65E-HA-651B/apps/common/device/gps/atk1218_bd.c

766 lines
26 KiB
C
Raw Normal View History

2024-11-10 10:44:17 +00:00
#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:开DMA0:关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