#include <stdarg.h>
#include "yc11xx.h"
#include "yc11xx_uart.h"
#include "yc11xx_gpio.h"
#include "yc_timer.h"
#include "ipc.h"
#include "yc_lpm.h"
#include "system.h"
#include "yc11xx_bt_interface.h"
#include "att.h"
#include "core_cm0.h"

#define LED_GPIO	19
#define adv_len 30
SYS_TIMER_TYPE gAdv_Timer;

void UartxInit(USART_TypeDef UARTx);

#define IO_TXA  19
#define IO_RXA  23
#define IO_TXB  6
#define IO_RXB  14
#define UARTBUFSIZE 256
void UartxInit(USART_TypeDef UARTx)
{
	USART_InitTypeDef USART_InitStruct ;
	
	USART_InitStruct.USART_BaudRate = UARTE_BAUDRATE_BAUDRATE_Baud921600;
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;	
	USART_InitStruct.USART_StopBits = USART_StopBits_1;
	USART_InitStruct.USART_Mode =USART_Mode_duplex;
	USART_InitStruct.USART_Parity = USART_Parity_Even ;
	USART_InitStruct.USART_RXLen = UARTBUFSIZE;
	USART_InitStruct.USART_TXLen = UARTBUFSIZE;

	if(UARTA == UARTx){
	GPIO_SetGpioMultFunction(IO_TXA,GPCFG_UART_TXD);
	GPIO_SetGpioMultFunction(IO_RXA,GPCFG_UART_RXD);
	}else if (UARTB == UARTx){
	GPIO_SetGpioMultFunction(IO_TXB,GPCFG_UARTB_TXD);
	GPIO_SetGpioMultFunction(IO_RXB,GPCFG_UARTB_RXD);
	}

	USART_Init(UARTx,&USART_InitStruct);
}


void LED_Run(uint8_t GPIO)
{
	static uint32_t times = 0;
	times++;

	if(times>0x5000)
	{
		times = 0;
		GPIO_CONFIG(GPIO) = (GPIO_CONFIG(GPIO)==GPCFG_OUTPUT_HIGH)? GPCFG_OUTPUT_LOW: GPCFG_OUTPUT_HIGH;
	} 
}

void Bt_StartAdv(int time_10ms,uint16_t gap){
	Bt_SetLeAdvInterval(gap);
	Lpm_Set_Interval(gap);
//	SYS_SetTimer(&gAdv_Timer,time_10ms,TIMER_SINGLE|TIMER_TYPE_BIT,Bt_stop_adv);
	Bt_SndCmdLeStartAdv();
}



void Bt_EvtCallBack(uint8_t len,uint8_t *dataPtr)
{
	BLE_Conn_param Ble_Conn_Param;
	switch(*dataPtr)
	{	
		case IPC_EVT_LE_DISCONNECTED:		//断连
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n***************IPC_EVT_LE_DISCONNECTED***************\r\n");
			#endif
			Bt_StartAdv(60,0x80);
			break;
		case IPC_EVT_LE_CONNECTED:			//连接
//			HWRITE(mem_local_mtu_size,527);
//			Bt_SndCmdLeUpdateAttMTU();
//			Ble_Conn_Param.min_interval=0x0006;
//			Ble_Conn_Param.max_interval=0x0012;
//			Ble_Conn_Param.latency=0x0010;
//			Ble_Conn_Param.timeout=0x258;
//			Bt_SndCmdLeUpdateConn(&Ble_Conn_Param);
			IPC_TxControlCmd(IPC_CMD_UPDATE_CONN);
			SYS_ReleaseTimer(&gAdv_Timer);
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n***************IPC_EVT_LE_CONNECTED***************\r\n");
			#endif
			break;
		case IPC_EVT_BB_CONNECTED:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_BB_CONNECTED*****************\r\n");
			#endif
			break;
		case IPC_EVT_SETUP_COMPLETE:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_SETUP_COMPLETE*****************\r\n");
			#endif
			break;
		case IPC_EVT_BT_PAIRING_SUCCESS:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_BT_PAIRING_SUCCESS*****************\r\n");
			#endif
			break;
		case IPC_EVT_LINKKEY_GENERATE:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_LINKKEY_GENERATE*****************\r\n");
			#endif
			break;
		case IPC_EVT_RESET:	//上电
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_RESET*****************\r\n");
			#endif
		//	Bt_Reset();	
			break;
		case IPC_EVT_WAKEUP:		//唤醒
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_WAKEUP*****************\r\n");
			#endif
//			SysTick_Config(SYSTEM_CLOCK/100); //each  systick interrupt is 10ms
			OS_EXIT_CRITICAL();		
			break;
		case IPC_EVT_LE_TK_GENERATE:
			#ifdef DEBUG_DRV_BT
			MyPrintf("\r\n****************IPC_EVT_LE_TK_GENERATE*****************\r\n");
			#endif			
			break;
		
		case IPC_EVT_LE_DISCONNECTED_ABNORMAL:
				#ifdef DEBUG_DRV_BT
				MyPrintf("\r\n******************IPC_EVT_LE_DISCONNECTED_ABNORMAL******************\r\n");
				#endif
				break;
		default:
			break;
	}
	return;
}
#define ATT_WRITE_REQUEST 0x12
#define ATT_PREPARE_WRITE_REQUEST	0x16
#define ATT_WRITE_COMMAND 0X52

void Bt_SndWriteResponse()
{
	IPC_TxControlCmd(IPC_CMD_SEND_WRITE_RESPONSE);
}

void Bt_BleCallBack(uint8_t len,uint8_t *dataPtr)
{
	uint16_t handle;
	uint8_t opcode;
	opcode = dataPtr[0];
	handle = dataPtr[1] +(dataPtr[2]<<8);
//	MyPrintf("opcode=%x\r\n",opcode);
//	MyPrintf("handle=%x\r\n",handle);
	switch(opcode) 
	{
		case ATT_WRITE_REQUEST:
			switch(handle)
			{
				case 0x0004:
					break;
				case 0x000e:
					break;
				case 0x0011:
					break;
			}
			Bt_SndWriteResponse();
			
			 break;
		case ATT_PREPARE_WRITE_REQUEST:
			switch(handle)
			{
				case 0x001c:
					break;
			}			
			 break;
		case ATT_WRITE_COMMAND:	
			switch(handle)
			{
				case 0x001c:
					USART_SendDataFromBuff(UARTB,dataPtr+3,len-3);
		//			Bt_SndBleData(0x001e,dataPtr+2,len-2);
				break;
			}	
				break;
	}
}

tIPCHandleCb gTIPCHandleCb[IPC_TYPE_NUM]=
{
	0,
	IpcDefaultCallBack,//cmd
	Bt_EvtCallBack,//evt					//evt回调函数,函数在drv_bt.c实现
	IpcDefaultCallBack,//hid
	IpcDefaultCallBack,//spp
	Bt_BleCallBack,//ble					//ble data回调函数,函数在drv_bt.c实现
	IpcDefaultCallBack,//24g
	IpcDefaultCallBack,//mesh
	IpcDefaultCallBack,
	IpcDefaultCallBack,//mesh
	IpcDefaultCallBack,//a2dp
	IpcDefaultCallBack,//hfp
	IpcDefaultCallBack
};



void Bt_Reset()
{
	uint8_t advD[22] = {0x02,0x01,0x06,0x05,0x03,0x12,0x18,0x0f,0x18,0x03,0x19,0x80,0x01,0x08,0x09,0x31,0x31,0x58,0x58,0x42,0x4c,0x45};
	uint8_t addr[6]  = {0xac,0x02,0x88,0x11,0x43,0Xac};
	uint8_t name[] = {"1121BLE_Test"};
	Bt_Renew_Le_AdvData(advD,22);
 	Bt_SetLeMac(addr);									//设置蓝牙地址
	Bt_Re_LeAdvName(name,12);
	Bt_Re_LeDeivcename(name,12);			
	Lpm_Set_Conn_Interval(0x1a0);
//	HWRITEW(mem_local_mtu_size,0x20f);
	Bt_SetLocalMtuSize(200);
	Bt_StartAdv(100,80);
}

int main(void)
{
	if(HREAD(mem_wake_flag)==POWERON_WAKE)
	{
			//初始化蓝牙回调函数
			IPC_init(&gTIPCHandleCb);			
			//初始化定时器
			SYS_TimerInit();
			UartxInit(UARTB);
			printport_init();
			// BLE profile init.
			Att_profile_Config();
			//clos lpm
			Lpm_exit();	
			//init
			Bt_Reset();	
			GPIO_SetOut(GPIO_19,OUT_HIGH);
	}
	else
	{
		SysTick_Config(SYSTEM_CLOCK/100); 
	}
	SYS_ClkTicks();	
	while(1)
	{
		switch (HREAD(IPC_MCU_STATE))
		{
			case IPC_MCU_STATE_RUNNING:
				IPC_HandleRxPacket();						//m0和bt交互数据类型判断,是evt还是ble data?并执行对应回调函数
				SYS_timerPolling();
				LED_Run(LED_GPIO);
				Lpm_LockLpm(M0_LPM_FLAG);		
				break;
			case IPC_MCU_STATE_LMP:			//lpm
				if (IPC_IsTxBuffEmpty())
				{
					OS_ENTER_CRITICAL();
					Bt_ActionBeforeLpm();
					HWRITE(IPC_MCU_STATE,IPC_MCU_STATE_STOP);
				}
				else{
					HWRITE(IPC_MCU_STATE,IPC_MCU_STATE_RUNNING);
				}
				break;
			case IPC_MCU_STATE_HIBERNATE:		//	HIBERNATE
				OS_ENTER_CRITICAL();
				Bt_ActionBeforeHibernate();
				HWRITE(IPC_MCU_STATE,IPC_MCU_STATE_STOP);
				break;
			case IPC_MCU_STATE_STOP:
				break;
		}		
	}
}