KT24-1110_65E-HA-651B/apps/common/device/gps/atk1218_bd.c
2024-11-10 18:44:17 +08:00

766 lines
26 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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