#include "esp8266.h"
#include "timer.h"
#include "usart.h"
#include "led.h"
#include "bsp.h"

u8 sendDataFlag=0;

/*ESP8266 模块接线图
TXD    ---  PA3/USART2_RX
RXD    ---  PA2/USART2_TX
RST    ---  PA0/IO控制硬件复位
EN     ---  PA1/IO控制模块掉电;0表示掉电,1表示正常上电工作
GPIO15 ---  PAx//接地或IO控制为低,不用
GPIO2  ---  PAx/接3.3V或IO驱动为高,不用
GPIO0  ---  PAx/IO控制启动模式;0代表进入系统升级,1表示正常引导用户程序(AT指令)
VCC    ---  3.3(供电)
GND    ---  GND
模块缺省波特率 115200;支持的范围：110~460800bps
*/

//配置GPIO
void ESP_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_CH_PD | RCC_RESET,ENABLE);//打开GPIO时钟

	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式

	GPIO_InitStructure.GPIO_Pin = PIN_CH_PD;
	GPIO_Init(PORT_CH_PD,&GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_RESET;
	GPIO_Init(PORT_RESET,&GPIO_InitStructure);

	ESP_CH_PD_0();
	ESP_RESET_0();
}

//ESP8266上电
void ESP_PowerOn(void)
{
	ESP_CH_PD_1();
}

//ESP8266关机
void ESP_PowerOff(void)
{
	ESP_CH_PD_0();
}

void ESP_SetSendDataFlag(u8 val)
{
	sendDataFlag=val;
}

u8 ESP_GetSendDataFlag(void)
{
	return sendDataFlag;
}

//ESP8266硬件复位
void ESP_HardReset(void)
{
	ESP_RESET_0();
	Delay10Ms(100);//1秒
	ESP_RESET_1();
	if(ESP_WaitResponse("ready",500))//5秒
	{
		ESP_SendString("ATE0\r\n");//串口2DMA发送
		if(ESP_WaitResponse("OK",500))//5秒
		{
			printf("\r\nESP8266 READY\r\nCLOSE ATE\r\n");
		}
		Delay10Ms(30);//300毫秒
		ESP_SendString("AT+CWMODE=1\r\n");//link is builded
		if(ESP_WaitResponse("OK",500))//5秒
		{
			printf("\r\nSET CWMODE=1\r\n");
		}
		Delay10Ms(30);
	}
	else
	{
		SetLed(0xff,20,20);
		printf("\r\nESP8266模块不存在或已损坏\r\n");
	}
}

//ESP8266软件复位
void ESP_SoftReset(void)
{
	ESP_SendString("AT+RST\r\n");
	if(ESP_WaitResponse("ready",500))//5秒
	{
		ESP_SendString("ATE0\r\n");//串口2DMA发送
		if(ESP_WaitResponse("OK",500))//5秒
		{
			printf("\r\nESP8266 READY\r\nCLOSE ATE\r\n");
		}
		Delay10Ms(30);
	}
}

//等待ESP8266返回指定的应答字符串,可以包含任意字符
//AckStr:应答的字符串; timeout:超时时间,单位10ms; 返回,1成功,0失败
u8 ESP_WaitResponse(char *AckStr,u16 timeout)
{
	u32 start;

	start = Get_RunTime();
	while (Get_RunTime()-start<timeout)
	{
		Idle();
		if(USART2_Recv_Flag)
		{
			USART2_Recv_Flag=0;
			//printf("%s",USART2_Recv_Buff);
			USART1_DMA_SendStr(USART2_Recv_Buff);//串口1DMA发送程序
			if(strstr(USART2_Recv_Buff,AckStr))
			{
				return TRUE;
			}
			//else
			//{
			//	return FALSE;
			//}
		}
	}
	return FALSE;
}

//加入AP;ssid:AP名,pwd:密码,timeout:超时时间,单位10ms;返回1,0K,0失败
u8 ESP_JoinAP(char *ssid,char *pwd,u16 timeout)
{
	u32 start;
	char buf[64]={0};

	sprintf(buf,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pwd);
	ESP_SendString(buf);
	start = Get_RunTime();
	while(Get_RunTime()-start<timeout)
	{
		Idle();
		if(USART2_Recv_Flag)
		{
			USART2_Recv_Flag=0;
			printf("%s",USART2_Recv_Buff);
			if(strstr(USART2_Recv_Buff,"WIFI GOT IP"))//ALREADY CONNECTED
			{
				return TRUE;
			}
			if(strstr(USART2_Recv_Buff,"ERROR")||strstr(USART2_Recv_Buff,"FAIL"))
			{
				return FALSE;
			}
		}
	}
	return FALSE;
}

//建立tcp链接或者注册UDP端口号(单路模式)必须在连接到AP之后
//addr:服务器地址或IP; port:TCP 端口号
//timeout:超时时间,单位10ms; 返回0失败,1tcp链接成功
u8 ESP_StartMux(u8 type,char *addr,u16 port,u16 timeout)
{
	u32 start;
	char cmd_buf[64]={0};

	if(type==TCP) 
	{
		sprintf(cmd_buf,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",addr,port);
	}
	if(type==UDP)
	{
		sprintf(cmd_buf,"AT+CIPSTART=\"UDP\",\"%s\",%d\r\n",addr,port);
	}
	//printf(cmd_buf);
	ESP_SendString(cmd_buf);
	start = Get_RunTime();
	while(Get_RunTime()-start<timeout)
	{
		Idle();
		if(USART2_Recv_Flag)
		{
			USART2_Recv_Flag=0;
			printf("%s",USART2_Recv_Buff);
			if(strstr(USART2_Recv_Buff,"CONNECT")||strstr(USART2_Recv_Buff,"ALREADY CONNECTED"))
			{
				return TRUE;
			}
			if(strstr(USART2_Recv_Buff,"ERROR")||strstr(USART2_Recv_Buff,"link is not valid"))//no ip没有连接到AP
			{
				return FALSE;
			}
		}
	}
	return FALSE;
}

//单路连接时(+CIPMUX=0)发送TCP或UDP数据包
u8 ESP_SendTcpUdp(char *senddata,u16 timeout)
{
	u8 find=0;
	u16 len;
	u32 start;
	char buf[32]={0};

	len=strlen(senddata);
	sprintf(buf,"AT+CIPSEND=%d\r\n",len);
	ESP_SendString(buf);
	if(ESP_WaitResponse(">",300))//3秒
	{
		find=1;
	}
	if(find) 
	{
		Delay10Ms(1);//10毫秒
		ESP_SendString(senddata);
	}
	else 
	{
		return FALSE;
	}

	start = Get_RunTime();
	while(Get_RunTime()-start<timeout)
	{
		Idle();
		if(USART2_Recv_Flag)
		{
			USART2_Recv_Flag=0;
			printf("%s",USART2_Recv_Buff);
			if(strstr(USART2_Recv_Buff,"SEND OK"))
			{
				if(strstr(USART2_Recv_Buff," ok"))
				{
					sendDataFlag=1;//防止服务器返回数据过快(小于10毫秒)不能识别
				}
				return TRUE;
			}
			if(strstr(USART2_Recv_Buff,"CLOSED")||strstr(USART2_Recv_Buff,"SEND FAIL"))
			{
				return FALSE;
			}
		}
	}
	return FALSE;
}

//多路连接时(+CIPMUX=1)发送TCP数据包
u8 ESP_SendTcpMux(u8 chid,char *senddata,u16 timeout)
{
	u8 find=FALSE;
	u16 len;
	u32 start;
	char buf[32]={0};

	len = strlen(senddata);
	sprintf(buf,"AT+CIPSEND=%d,%d\r\n",chid,len);
	ESP_SendString(buf);
	if(ESP_WaitResponse(">",300))//3秒
	{
		find = TRUE;
	}
	if(find) 
	{
		Delay10Ms(1);//10毫秒
		ESP_SendString(senddata);
	}
	else 
	{
		return FALSE;
	}

	start = Get_RunTime();
	while(Get_RunTime()-start<timeout)
	{
		Idle();
		if(USART2_Recv_Flag)
		{
			USART2_Recv_Flag=0;
			printf("%s",USART2_Recv_Buff);
			if(strstr(USART2_Recv_Buff,"SEND OK"))
			{
				sprintf(buf,"AT+CIPCLOSE=%d\r\n",chid);
				ESP_SendString(buf);
				if(ESP_WaitResponse("OK",300))//3秒
				{
					//sendDataFlag=1;
					return TRUE;
				}
				return FALSE;
			}
			if(strstr(USART2_Recv_Buff,"CLOSED")||strstr(USART2_Recv_Buff,"SEND FAIL"))
			{
				return FALSE;
			}
		}
	}
	return FALSE;
}

u8 ESP_SendData(char *ser,u16 port,char *SendStr)
{
	u8 link_cnt=2;

	while(link_cnt)//连接失败重连，重连失败退出
	{
		Idle();
		if(ESP_StartMux(TCP,ser,port,300))//建立tcp链接//3秒超时
		{
			if(ESP_SendTcpUdp(SendStr,1500))//15秒超时
			{
				return TRUE;
			}
			return FALSE;
		}
		Delay10Ms(30);//300毫秒
		link_cnt--;
	}
	return FALSE;
}

//配置为TCP服务器,当有client接入会自动按顺序占用一个连接
//AT+CIPMUX=1时才能开启TCP服务器
u8 ESP_StartServer(u16 port)
{
	char cmd_buf[32]={0};
	u32 start;
	u8 num=3;
	
	Delay10Ms(30);//300毫秒
	ESP_SendString("AT+CWMODE=2\r\n");//
	if(ESP_WaitResponse("OK",300))//3秒超时
	{
		Delay10Ms(30);//0.3秒
		while(num)
		{
			Idle();
			ESP_SendString("AT+CIPMUX=1\r\n");//
			start = Get_RunTime();
			while(Get_RunTime()-start<300)//3秒
			{
				Idle();
				if(USART2_Recv_Flag)
				{
					USART2_Recv_Flag=0;
					printf("%s",USART2_Recv_Buff);
					if(strstr(USART2_Recv_Buff,"OK"))
					{
						Delay10Ms(30);//0.3秒
						sprintf(cmd_buf,"AT+CIPSERVER=1,%d\r\n",port);//开启TCP服务器
						ESP_SendString(cmd_buf);
						if(ESP_WaitResponse("OK",300))//3秒
						{
							Delay10Ms(30);//300毫秒
							ESP_SendString("AT+CIPSTO=5\r\n");//设置超时=5秒
							if(ESP_WaitResponse("OK",300))//3秒
							{
								printf("\r\nStart Server\r\n");
								return TRUE;
							}
						}
					}
					if(strstr(USART2_Recv_Buff,"ERROR")||strstr(USART2_Recv_Buff,"link is builded"))
					{
						break;
					}
				}
			}
			Delay10Ms(30);//300毫秒
			num--;
		}
	}
	return FALSE;
}

//关闭server(新版不需要重启)
u8 ESP_CloseServer(void)
{
	Delay10Ms(30);//300毫秒
	ESP_SendString("AT+CIPSERVER=0\r\n");
	if(ESP_WaitResponse("OK",300))//3秒
	{
		Delay10Ms(30);//300毫秒
		ESP_SendString("AT+CIPMUX=0\r\n");
		if(ESP_WaitResponse("OK",300))//3秒
		{
			Delay10Ms(30);//300毫秒
			ESP_SendString("AT+CWMODE=1\r\n");//link is builded
			if(ESP_WaitResponse("OK",300))//3秒
			{
				printf("\r\nClose Server\r\n");
				return TRUE;
			}
		}
	}
	return FALSE;
}
