/*************************** (C) COPYRIGHT 2017 CXHY ****************************
 * 文件名  ：gps.c
 * 描  述  ：GPS驱动代码     
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2017/03/05 
*********************************************************************************/
#include "gps.h" 
#include "delay.h" 						   
#include "usart4.h"
#include "timer.h"
#include "string.h"

nmeaGNGGA	gpsGNGGA;
nmeaGNRMC	gpsGNRMC;
nmeaINFO	gpsInfo;

uint8_t gpsConnectSta = 0;										//GPS模块硬件连接状态

void showChar(uint8_t num[], uint8_t n)
{
    uint8_t i;
		printf("\r\n");
    for(i=0; i<n; i++)
		{
      printf("%c",num[i]);
		}
		printf("\r\n");
}

void GPS_USART_SendFrameData(uint8_t pDataBuf[], uint16_t len)
{
	USART4_SendFrameData(pDataBuf, len);
}
		
void nmea_zero_GNGGA(nmeaGNGGA *pack)
{
    memset(pack, 0, sizeof(nmeaGNGGA));
    pack->ns = 'N';
    pack->ew = 'E';
    pack->elv_units = 'M';
    pack->diff_units = 'M';
}
		
void nmea_zero_GNRMC(nmeaGNRMC *pack)
{
    memset(pack, 0, sizeof(nmeaGNRMC));
    pack->status = 'V';
    pack->ns = 'N';
    pack->ew = 'E';
    pack->declin_ew = 'E';
		pack->mode = 'N';
}

/*
***********************************************************************
*	函 数 名: GPS_Init
*	功能说明: GPS初始化
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void GPS_Init(void)
{
	char gpsSendBuf[32] = {0};
	
	nmea_zero_GNGGA(&gpsGNGGA);
	nmea_zero_GNRMC(&gpsGNRMC);
	
// 	//设置GPS波特率为115200
// 	printf("\r\n设置波GPS波特率\r\n");
// 	USART2_Init(9600);
// 	delay_ms(500);
// 	sprintf(gpsSendBuf, "%s", "$PCAS01,5*19\r\n");
// 	GPS_USART_SendFrameData((uint8_t *)gpsSendBuf, strlen(gpsSendBuf));
// 	
// 	USART2_Init(115200);
// 	delay_ms(500);
// 	memset(gpsSendBuf, 0, 32);
// 	sprintf(gpsSendBuf, "%s", "$PCAS00*01\r\n");
// 	GPS_USART_SendFrameData((uint8_t *)gpsSendBuf, strlen(gpsSendBuf));
// 	delay_ms(500);
}
 
/**
 * \brief Convert NDEG (NMEA degree) to fractional degree
 */
double nmea_ndeg2degree(double val)
{
    double deg = ((int)(val / 100));
    val = deg + (val - deg * 100) / 60;
    return val;
}

/*
***********************************************************************
*	函 数 名: NMEA_GNGGA_Analysis
*	功能说明: 分析GNGGA信息（GPS定位信息）
*	形    参: *buf:接收到的GPS数据缓冲区首地址
*	返 回 值: 无
***********************************************************************
*/
void NMEA_GNGGA_Parse(uint8_t *buf)
{
	char* pStr = NULL;
	char gnrmcStr[128] = {0};
	uint16_t i = 0;
	
// 	printf("\r\nGNGGA Parse:\r\n");

	pStr = strstr((const char*)buf, "$GNGGA");
	if(pStr != NULL)
	{
		for(i=0; i<strlen(pStr); i++)
		{
			if(pStr[i] == '\n') break;
		}
		
		memcpy(gnrmcStr, pStr, i+1);
		
// 		printf("GPS_Info(%d): \r\n%s", i+1, gnrmcStr);

//		$GNGGA,015208.000,2241.22469,N,11413.40909,E,1,10,1.6,67.0,M,0.0,M,,*47
		sscanf((const char*)gnrmcStr,"$GNGGA,%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%d,%*[^,],%*[^,],%lf",
							&(gpsGNGGA.sig),
							&(gpsGNGGA.elv)
							);

		//转换成平台上传发送的数据格式
		gpsInfo.u_elv = gpsGNGGA.elv;
		
// 		printf("sig:%d\r\n", gpsGNGGA.sig);
// 		printf("elv:%f\r\n", gpsGNGGA.elv);
	}
}

/*
***********************************************************************
*	函 数 名: NMEA_GPRMC_Analysis
*	功能说明: 分析GPRMC信息（GPS推荐定位信息）
*	形    参: *buf:接收到的GPS数据缓冲区首地址
*	返 回 值: 无
***********************************************************************
*/
void NMEA_GNRMC_Parse(uint8_t *buf)
{
	char* pStr = NULL;
	char gnrmcStr[128] = {0};
	uint16_t i = 0;
	
// 	printf("\r\nGNRMC Parse:\r\n");
	
	pStr = strstr((const char*)buf, "$GNRMC");
	if(pStr != NULL)
	{
		for(i=0; i<strlen(pStr); i++)
		{
			if(pStr[i] == '\n') break;
		}
		
		memcpy(gnrmcStr, pStr, i+1);
		
// 		printf("GPS_Info(%d): \r\n%s", i+1, gnrmcStr);
		
		//$GNRMC,012919.000,A,2241.22546,N,11413.41048,E,0.00,325.89,030822,,,A*71
		sscanf((const char*)gnrmcStr,"$GNRMC,%*[^,],%c,%lf,%c,%lf,%c,%lf,%lf,%*[^,],%lf,%c,%c",
							&(gpsGNRMC.status),
							&(gpsGNRMC.lat),
							&(gpsGNRMC.ns),
							&(gpsGNRMC.lon),
							&(gpsGNRMC.ew),
							&(gpsGNRMC.speed),
							&(gpsGNRMC.direction),
							&(gpsGNRMC.declination),
							&(gpsGNRMC.declin_ew),
							&(gpsGNRMC.mode)
							);
		
		gpsInfo.lat = nmea_ndeg2degree(gpsGNRMC.lat);
		gpsInfo.lon = nmea_ndeg2degree(gpsGNRMC.lon);
		
		//转换成平台上传发送的数据格式
		gpsInfo.u_lat = gpsInfo.lat * 1000000;
		gpsInfo.u_lon = gpsInfo.lon * 1000000;
		
		if(gpsGNRMC.ns == 'N')
		{
			gpsInfo.u_ns = 0x00;
		}else{
			gpsInfo.u_ns = 0x01;
		}
		
		if(gpsGNRMC.ew == 'E')
		{
			gpsInfo.u_ew = 0x00;
		}else{
			gpsInfo.u_ew = 0x01;
		}
		
		gpsInfo.u_speed = gpsGNRMC.speed;
		gpsInfo.u_direction = gpsGNRMC.direction;
		
				
// 		printf("utc:%s\r\n", gpsInfo.utc);
// 		printf("mode:%c\r\n", gpsInfo.mode);
// 		printf("lat:%f\r\n", gpsInfo.lat);
// 		printf("latN/S:%c\r\n", gpsInfo.uLat);
// 		printf("lon:%f\r\n", gpsInfo.lon);
// 		printf("lonE/W:%c\r\n", gpsInfo.uLon);
// 		printf("speed:%f\r\n", gpsGNRMC.speed);
// 		printf("direction:%f\r\n", gpsGNRMC.direction);
// 		
// 		printf("lat:%f, lon:%f\r\n", gpsInfo.lat, gpsInfo.lon);
	}
}
/*
***********************************************************************
*	函 数 名: GPS_Parse
*	功能说明: GPS信息解析（提取NMEA-0183信息）
*	形    参: *gpsx:nmea信息结构体（输出的全局变量）
*						*buf:接收到的GPS数据缓冲区首地址
*	返 回 值: 无
***********************************************************************
*/
void GPS_Parse(uint8_t *buf)
{
	NMEA_GNGGA_Parse(buf);
	NMEA_GNRMC_Parse(buf);
}


void PrinterfGpsInfo(void)
{
	if(gpsConnectSta == 1)
	{
		printf("\r\nGPS硬件正常！\r\n");
		if(gpsGNGGA.sig == 1)
		{
			printf("已定位(%d)\r\n", gpsGNGGA.sig);
			
			printf("经度：%.6f %1c\r\n", (double)gpsInfo.u_lon/1000000, gpsGNRMC.ew);
			printf("纬度：%.6f %1c\r\n", (double)gpsInfo.u_lat/1000000, gpsGNRMC.ns);
			printf("高度：%d\r\n", gpsInfo.u_elv);
		}else{
			printf("未定位(%d)\r\n", gpsGNGGA.sig);
		}
	}else{
		printf("\r\nGPS硬件异常xx！\r\n");
	}
}

/*
***********************************************************************
*	函 数 名: GPS_Task
*	功能说明: GPS处理任务
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void GPS_Task(void)
{
	static uint8_t GPS_UploadStatus = 0x00;
	static uint8_t GPS_runningStatus = 0x00;
	
	static timer timer_01;	
	static timer timer_10min;							//10分钟定时器
	static timer timer_24h;								//24小时定时器
	static uint8_t timer_ok = 0;
	
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&timer_01, CLOCK_SECOND*10);															
// 		timer_set(&timer_10min, CLOCK_SECOND*10);												
//     timer_set(&timer_24h, CLOCK_SECOND*30);			
		timer_set(&timer_10min, CLOCK_SECOND*600);												
    timer_set(&timer_24h, CLOCK_SECOND*86400);
	}
	
	if(USART4_RX_STA & 0X8000)													//接收到一次数据了
	{
// 		printf("\r\nGPS data:(%d byte)\r\n", USART4_RX_STA & 0X7FFF);
		
		if(strstr((const char*)USART4_RX_BUF, "$GPTXT") != NULL)
		{
			gpsConnectSta = 1;															//标记硬件连接正常
// 			printf("\r\nGPS_Info: \r\n%s\r\n", USART4_RX_BUF);
			
			GPS_Parse((uint8_t *)USART4_RX_BUF);						//解析GPS数据
		}else{
			gpsConnectSta = 0;
		}
		
		USART4_RX_STA = 0;		   	//启动下一次接收
		memset(USART4_RX_BUF, 0, USART4_RECV_LEN);
	}
	
	if(timer_expired(&timer_01))
	{
		PrinterfGpsInfo();
		timer_restart(&timer_01);
	}
	
// 	switch(GPS_runningStatus)
// 	{
// 		case 0x00:
// 			if(timer_expired(&timer_10min))
// 			{
// 				GPS_PowerOFF();
// 				printf("\r\n关闭GPS定位\r\n");
// 				timer_restart(&timer_24h);				//启动24H定时
// 				GPS_runningStatus = 0x01;
// 			}
// 			break;
// 			
// 		case 0x01:
// 			if(timer_expired(&timer_24h))
// 			{
// 				GPS_PowerON();
// 				printf("\r\n打开GPS定位\r\n");
// 				timer_restart(&timer_10min);
// 				GPS_runningStatus = 0x00;
// 			}
// 			break;
// 			
// 		default:
// 			GPS_runningStatus = 0x00;
// 			break;
// 	}
	
}

/******************** (C) COPYRIGHT 2014 CHY *****END OF FILE*******************/
