#include "viper.h"

osThreadId_t Viper_Handle;
const osThreadAttr_t Viper_attributes = {
	.name = "VIPER",
	.stack_size = 1024,
	.priority = (osPriority_t)osPriorityBelowNormal,
};

// 事件
osEventFlagsId_t Viper_EventHandle;
const osEventFlagsAttr_t Viper_Event_attributes = {
	.name = "Viper_Event"};

extern UART_HandleTypeDef huart1;
UART_HandleTypeDef *pViperUart = &huart1;

uint8_t Viper_SN_Command[8] = {0x01, 0x03, 0x00, 0x0A, 0x00, 0x05, 0xA5, 0xCB};

uint8_t Viper_Wavelength_Trans_Buf[3][8] = {
	// 01 03 08 36 00 7A 26 47    (2102  122)  register num ,122(0x7A)
	// 01 03 08 B0 00 7A C7 AE    (2224  122)
	// 01 03 09 2A 00 7A E6 7D    (2346  122)
	{0x01, 0x03, 0x08, 0x36, 0x00, 0x7A, 0x26, 0x47},
	{0x01, 0x03, 0x08, 0xB0, 0x00, 0x7A, 0xC7, 0xAE},
	{0x01, 0x03, 0x09, 0x2A, 0x00, 0x7A, 0xE6, 0x7D}};
uint8_t Viper_Data_Trans_Buf[3][8] = {
	// 01 03 0A 36 00 7A 27 FF    (2614  122)
	// 01 03 0A B0 00 7A C6 16    (2736  122)
	// 01 03 0B 2A 00 7A E7 C5    (2858  122)
	{0x01, 0x03, 0x0A, 0x36, 0x00, 0x7A, 0x27, 0xFF},
	{0x01, 0x03, 0x0A, 0xB0, 0x00, 0x7A, 0xC6, 0x16},
	{0x01, 0x03, 0x0B, 0x2A, 0x00, 0x7A, 0xE7, 0xC5}};
uint8_t Viper_sn_buf[15] = {0};

// uint8_t Viper_TEST_BUF[8]  ={0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09};
// uint8_t Viper_TEST_BUF2[8]  ={0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09};
// uint8_t Viper_TRANS_BUF[8]  ={0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09};
uint8_t Viper_RCV_BUF[1024] = {0};

UART_HELPER_TypeDef *Viper_uart_helper;

Viper_TypeDef viper = {
	Viper_Init,
	Viper_Port,
	Viper_Test,
	Viper_Start,
	Viper_Stop,
	NULL,
	0,	  // state
	0,	  // data_ok
	{0},  // buf
	0,	  // size_received
	0,	  // time base
	1000, // timeout ticks,  1000ms = 1S
	0,	  // event_flag
	0,	  // wavelength_ok
	NULL, // transRecord[3]
};

int Viper_Init()
{
	Viper_uart_helper = UART_HELPER_Init();

	if (Viper_uart_helper == NULL)
		return -1;

	// TODO 接口
	UART_HELPER_Set_Huart(Viper_uart_helper, pViperUart);
	UART_HELPER_Set_Interface_Type(Viper_uart_helper, Uart_Interface_Max3160_485);

	//  传输
	UART_HELPER_Setup_Trans_mode(Viper_uart_helper, Uart_Trans_DMA);
	// UART_HELPER_Setup_Rcv_mode( Viper_uart_helper, Uart_Trans_IT );
	UART_HELPER_Set_enable_idle(Viper_uart_helper, Uart_IDLE_IT_ENABLE);

	//  回调GPIO 操作 数据操作
	UART_HELPER_Set_trans_GPIO(Viper_uart_helper, Viper_Trans_GPIO); // enbale rcv
	UART_HELPER_Set_trans_cplt_GPIO(Viper_uart_helper, Viper_Trans_Cplt_GPIO);

	UART_HELPER_Set_Callback(Viper_uart_helper, &viper, Viper_CallBack);

	// 设置 Buf, 如果启用消息队列，不启用trans_buf
	UART_HELPER_Set_Rcv_Buf(Viper_uart_helper, Viper_RCV_BUF, sizeof(Viper_RCV_BUF));
	// UART_HELPER_Set_Trans_Buf(Viper_uart_helper, Viper_SN_Command, sizeof(Viper_SN_Command));

	//  GPIO 操作
	switch (Viper_uart_helper->interface_type)
	{
	case Uart_Interface_Default:
		break;
	case Uart_Interface_485:
		usart6_send_enable();
		break;
	case Uart_Interface_Max3160_232:
		Viper_MAX3160_232();
		break;
	case Uart_Interface_Max3160_485:
		max3160_485_receive_mode();
		break;
	default:
		break;
	}
	viper.state = Viper_State_Waiting;
	viper.timebase_ticks = osKernelGetTickCount();

	// TODO enable trans queue
	// 最大队列数 8, 消息类型， 值传递（内含的buf为指针，如何包含大空间的buf,可选择指针传递 ）
	viper.transQueue = osMessageQueueNew(8, sizeof(Record_Trans_Rcv_TypeDef), NULL);
}

void Viper_Port()
{
	Viper_Handle = osThreadNew(Viper_Task, NULL, &Viper_attributes);
	// Viper_EventHandle = osEventFlagsNew( &Viper_Event_attributes );
}

int Viper_Test()
{
	// 装载要发送的消息队列
	viper.transRecord[0].size = sizeof(Viper_SN_Command);
	viper.transRecord[0].buf = Viper_SN_Command;

	// log_i( "  viper.transRecord[0]  buf  %d,  addr %d " , viper.transRecord[0].buf[0], viper.transRecord[0].buf );
	// log_i( "  Viper_TEST_BUF  buf  %d,  addr  %d " ,Viper_TEST_BUF[0], Viper_TEST_BUF );
	osMessageQueuePut(viper.transQueue, (void *)&viper.transRecord[0], 0, osWaitForever);
	// 改变操作状态
	viper.state = Viper_State_Test; // 操作状态
	return 0;
}

void Viper_Wavelength()
{
	// 装载要发送的消息队列 , 注意队列大小及
	viper.transRecord[0].size = sizeof(Viper_SN_Command);
	viper.transRecord[0].buf = Viper_Wavelength_Trans_Buf[0];
	osMessageQueuePut(viper.transQueue, (void *)&viper.transRecord[0], 0, osWaitForever);

	viper.transRecord[1].size = sizeof(Viper_SN_Command);
	viper.transRecord[1].buf = Viper_Wavelength_Trans_Buf[1];
	osMessageQueuePut(viper.transQueue, (void *)&viper.transRecord[1], 0, osWaitForever);

	viper.transRecord[2].size = sizeof(Viper_SN_Command);
	viper.transRecord[2].buf = Viper_Wavelength_Trans_Buf[2];
	osMessageQueuePut(viper.transQueue, (void *)&viper.transRecord[2], 0, osWaitForever);

	// viper.state = Viper_State_Get_WAVELENGTH;  // 操作状态
	// osEventFlagsSet( Viper_EventHandle, Viper_Event_Get_Data );  // 事件
}

void Viper_Start()
{
	// 装载要发送的消息队列 , 注意队列大小及
	viper.transRecord[0].size = sizeof(Viper_SN_Command);
	viper.transRecord[0].buf = Viper_Data_Trans_Buf[0];
	osMessageQueuePut(viper.transQueue, (void *)&viper.transRecord[0], 0, osWaitForever);

	viper.transRecord[1].size = sizeof(Viper_SN_Command);
	viper.transRecord[1].buf = Viper_Data_Trans_Buf[1];
	osMessageQueuePut(viper.transQueue, (void *)&viper.transRecord[1], 0, osWaitForever);

	viper.transRecord[2].size = sizeof(Viper_SN_Command);
	viper.transRecord[2].buf = Viper_Data_Trans_Buf[2];
	osMessageQueuePut(viper.transQueue, (void *)&viper.transRecord[2], 0, osWaitForever);

	viper.state = Viper_State_Get_DATA; // 操作状态
	// osEventFlagsSet( Viper_EventHandle, Viper_Event_Get_Data );  // 事件
}

void Viper_Stop()
{
	viper.state = Viper_State_Stop;
	// TODO stop  task？
}

void Viper_Task()
{
	// log_i( " ph tran mode : %d ", viper.->trans_mode );
	// memset(  Viper_RCV_Buf, 0, 2*Viper_Rcv_Buf_Size );  /* ph*3 ph *2 否则内存泄漏 */
	viper.event_flag = 0;
	uint64_t ticks;
	int err_con = 0;
	int st;
	Record_Trans_Rcv_TypeDef msgQueue;  // 消息队列
	int queue_seq = 0;   // 队列的计数

	for (;;)
	{
		switch (viper.state)
		{
		case Viper_State_Waiting:
			log_d(" Viper task..... : %d    %d ", viper.state, viper.state);
			osDelay(20);
			break;

		case Viper_State_Test:
			// log_i( " temp test..... : %d  QueueGetCount  %d " , viper.state , osMessageQueueGetCount(viper.transQueue) );
			if (osMessageQueueGetCount(viper.transQueue) == 0)
			{
				viper.state = Viper_State_Error;
				break;
			}
			// 取队列  值传递, 第三个参数为NULL 否则为消息长度
			osMessageQueueGet( viper.transQueue, &msgQueue, sizeof(Record_Trans_Rcv_TypeDef), osWaitForever );
			// log_i(  " msgQueue  %d   %d " , msgQueue.size,  msgQueue.buf   );
			// log_i(  " msgQueue  %d  " , Viper_TEST_BUF  );
			viper.state = Viper_State_Test_Start;
			continue;

		case Viper_State_Test_Start:
			// log_i( " temp Viper_State_Test_Start..... : %d    %d " , viper.state , viper.state );
			ticks = osKernelGetTickCount();
			UART_HELPER_Set_Trans_Buf(Viper_uart_helper, msgQueue.buf, msgQueue.size);
			// HAL_UARTEx_ReceiveToIdle_DMA(&huart1, Viper_RCV_BUF,1024);
			Viper_Receive();
			Viper_Transmit();
			viper.state = Viper_State_SN_Getting;
			continue;

		case Viper_State_SN_Getting:
			log_d( " Viper_ State_SN_Getting..... : %d    %d " , viper.state , viper.state );
			if ( (osKernelGetTickCount() - ticks) > 2000 )
			{
				log_d( " Viper_ State_SN_Getting -> retry: %d   " , err_con++   );
				// err_con++;
				if (err_con > 5)
				{
					log_w(" Viper_ testing  ******** error ");
					viper.state = Viper_State_Error;
				}
				viper.state = Viper_State_Test_Start;   // 重新发送取出来的队列
			}
			osDelay(200);
			continue;

		case Viper_State_SN_OK:
			// SN 数据 拷贝
			memcpy( viper.vipersn_buf , viper.result_buf, viper.size_received );
			log_i("Viper_ SN :   %c %c %c %c" 
					, viper.vipersn_buf[9] , viper.vipersn_buf[10], viper.vipersn_buf[11], viper.vipersn_buf[12] );
				
			// 获得序列号 状态OK
			osEventFlagsSet(Viper_EventHandle, Viper_Event_Ready);

			// TODO 判断队列是否有元素
			if (osMessageQueueGetCount(viper.transQueue) == 0)
			{
				viper.state = Viper_State_Get_WAVELENGTH;
				// TODO 停止DMA
				if (Viper_uart_helper->rcv_mode == Uart_Trans_DMA)
				{
					HAL_UART_DMAStop(Viper_uart_helper->huart);
				}
				continue;
			}
			else
			{
				osMessageQueueGet(viper.transQueue, &msgQueue, sizeof(Record_Trans_Rcv_TypeDef), osWaitForever);
				// osEventFlagsClear( Viper_EventHandle, Viper_Event_Test_OK );
				viper.state = Viper_State_Test_Start;
				continue;
			}
			break;

		case Viper_State_Get_WAVELENGTH:
			log_i(" get wavelenth .....   ");
			if (viper.wavelength_ok == 1)
			{
				viper.state = Viper_State_Ready;
				break;
			}
			Viper_Wavelength();
			viper.state = Viper_State_Get_DATA;
			osDelay(1);
			continue;

		case Viper_State_Ready:
			// log_d( "  Viper_ State_Ready .....   "  );
			osDelay(1);
			continue;

		case Viper_State_Get_DATA:
			log_i("  Viper_ State_Get_DATA .....   ");
			viper.data_ok = 0;
			viper.size_received = 0;
			memset( viper.result_buf, 0, sizeof(viper.result_buf) );
			osEventFlagsClear(Viper_EventHandle, Viper_Event_Get_Data);

			// 队列是否有值
			if (osMessageQueueGetCount(viper.transQueue) == 0)
			{
				viper.state = Viper_State_Error;
				break;
			}
			osMessageQueueGet(viper.transQueue, &msgQueue, sizeof(Record_Trans_Rcv_TypeDef), osWaitForever);

			viper.state = Viper_State_Get_DATA_Trans;
			continue;
		case Viper_State_Get_DATA_Trans:
			log_i("  Viper_ State_Get_DATA Trans .....   ");
			ticks = osKernelGetTickCount();
			UART_HELPER_Set_Trans_Buf(Viper_uart_helper, msgQueue.buf, msgQueue.size);
			Viper_Receive();
			Viper_Transmit();
			viper.state = Viper_State_Get_DATA_Wait;
			continue;
		case Viper_State_Get_DATA_Wait:
			if (osKernelGetTickCount() - ticks > 2000)
			{
				err_con++;
				if (err_con > 3)
				{
					log_w(" Viper_  wait ....... error ");
					viper.state = Viper_State_Error;
				}
				viper.state = Viper_State_Get_DATA_Trans;
			}
			osDelay(1);
			continue;

		case Viper_State_Get_DATA_OK:
			log_d(" VIPER_ one_measurement data ok  ...  ");
			viper.data_ok = 0;
			viper.state = Viper_State_Get_DATA_Check;
			continue;

		case Viper_State_Get_DATA_Check:
			log_d(" VIPER_ data check  ********  ");

			// validate
			if ( Viper_Validate() != 1 )
			{
				viper.state = Viper_State_Error;
				break;
			}

			if (viper.wavelength_ok == 0)
			{
				// WL 数据 拷贝
				memcpy( viper.Viper_Wavelength_Buf[queue_seq], viper.result_buf, viper.size_received );
				viper.state = Viper_State_Get_Queue_MSG;
				break;
			}
			if (viper.wavelength_ok == 1)
			{
				// DATA 数据 拷贝
				memcpy( viper.Viper_Data_Buf[queue_seq], viper.result_buf, viper.size_received );
				viper.state = Viper_State_Get_Queue_MSG;
				break;
			}

			osDelay(10);
			continue;

		case Viper_State_Get_Queue_MSG:
			log_d(" VIPER_ State_Get_Queue_MSG ........ msg queue count: %d  msg_seq  %d", 
					osMessageQueueGetCount(viper.transQueue), queue_seq);
			//  处理DMA 相关事宜 ---DMA 

			// 队列是否有值
			if (osMessageQueueGetCount(viper.transQueue) > 0)
			{
				log_d("  Queue_MSG  count>0 ........ ");
				queue_seq++;
				viper.state = Viper_State_Get_DATA;
				break;
			}
			queue_seq = 0;
			viper.state = Viper_State_Ready;
			continue;

		case Viper_State_Stop:
			// log_d(" VIPER_ state  stop ..... ");
			osDelay(10);
			continue;

		case Viper_State_Timeout:
			log_e(" VIPER_ timeout ..... ");
			viper.state = Viper_State_Waiting;
			// TODO 停止DMA
			if ( Viper_uart_helper->rcv_mode == Uart_Trans_DMA )
			{
				HAL_UART_DMAStop( Viper_uart_helper->huart );
			}
			osDelay(5);
			break;

		case Viper_State_Error:
			log_e(" VIPER_ error ..... ");
			viper.state = Viper_State_Waiting;
			// TODO 停止DMA
			if ( Viper_uart_helper->rcv_mode == Uart_Trans_DMA )
			{
				HAL_UART_DMAStop( Viper_uart_helper->huart );
			}
			osDelay(5);
			break;
		}
		osDelay(20);
	}
}

void Viper_Trans_GPIO(void)
{
	// HAL_GPIO_WritePin(R_W_GPIO_Port,R_W_Pin, SET);
	// HAL_GPIO_WritePin(NULL,0, SET);
	HAL_GPIO_WritePin(SEL_232_485_GPIO_Port, SEL_232_485_Pin, SET);
	HAL_GPIO_WritePin(HDPLX_GPIO_Port, HDPLX_Pin, RESET);
	HAL_GPIO_WritePin(DE485_GPIO_Port, DE485_Pin, SET);
}

void Viper_Trans_Cplt_GPIO(void)
{
	// HAL_GPIO_WritePin(R_W_GPIO_Port,R_W_Pin, RESET);
	// HAL_GPIO_WritePin(NULL,0, RESET);
	HAL_GPIO_WritePin(SEL_232_485_GPIO_Port, SEL_232_485_Pin, SET);
	HAL_GPIO_WritePin(HDPLX_GPIO_Port, HDPLX_Pin, SET);
	HAL_GPIO_WritePin(DE485_GPIO_Port, DE485_Pin, RESET);
}

int Viper_Transmit()
{
	//  TODO 结合队列
	viper.size_received = 0;
	if (Viper_uart_helper->transferring == 0)
	{
		return UART_HELPER_Trans(Viper_uart_helper, Viper_uart_helper->trans_record->buf, Viper_uart_helper->trans_record->size);
	}
	return 0;
}

int Viper_Receive()
{
	return UART_HELPER_Start_Rcv(Viper_uart_helper, Viper_uart_helper->rcv_buf, Viper_uart_helper->rcv_size);
	// return 0;
}

void Viper_Set_Timeout_ms(uint64_t ms_ticks)
{
	viper.timeout_ticks = ms_ticks;
}

int Viper_Validate()
{
	return CRC16_Check(viper.result_buf ,viper.size_received);
}

int Viper_CallBack(Viper_TypeDef *pViper, uint8_t *buf, uint16_t size)
{
	log_d(" Viper_CallBack  -- state %d   size %d", viper.state, size);

	uint16_t size_tmp;
	size_tmp = size;
	switch (viper.state)
	{
	case Viper_State_SN_Getting:
		if (size == 0)  return 0;
 
		//  添加数据
		if ( (size + viper.size_received) >= sizeof(viper.result_buf) )
		{
			size_tmp = sizeof(viper.result_buf) - viper.size_received;
		}
		// // log_d(" copy sn  %d  %d ", size,size_tmp);
		memcpy((uint32_t)(viper.result_buf + viper.size_received), Viper_uart_helper->rcv_buf, size_tmp);
		viper.size_received += size_tmp;

		//  Modbus 最小长度5
		if ( viper.size_received < 5 )  return 0;		

		// Modbus 长度校验 
		if ( viper.size_received == ( viper.result_buf[2] + 5 ) )
		{
			viper.state++;
		}
		break;

	case Viper_State_Get_DATA_Wait:
		if ( size == 0 )  return 0;

		//  添加数据
		if ( (size + viper.size_received) >= sizeof(viper.result_buf) )
		{
			size_tmp = sizeof(viper.result_buf) - viper.size_received;
		}
		memcpy((uint32_t)(viper.result_buf + viper.size_received), Viper_uart_helper->rcv_buf, size_tmp);
		viper.size_received += size_tmp;;

		//  Modbus 最小长度5
		if (viper.size_received<5)  return 0;	

		// Modbus 长度校验 
		if ( viper.size_received == ( viper.result_buf[2] + 5 ) )
		{
			viper.state++;
		}

		// if (Viper_uart_helper->enable_idle_it == 0)
		// {
		// 	// Modbus 长度校验，拷贝数据？
		// 	if (viper.size_received == (viper.result_buf[2] + 5))
		// 	{
		// 		viper.state++;
		// 	}
		// 	return 0;
		// }
		// if (Viper_uart_helper->enable_idle_it == 1)
		// {
		// 	// 长度校验，拷贝数据？
		// 	if (viper.size_received == (viper.result_buf[2] + 5))
		// 	{
		// 		viper.state++;
		// 	}
		// 	return 0;
		// }
		break;
	default:
		break;
	}
	return 0;
}

// void Viper_Set_Interface( Viper_TypeDef *ph,  UartInterface_TypeDef * interface  )
// {
//     UartHelper_Set_Interface( viper.uarthelper,   interface );
// }
// void Viper_Set_Huart( Viper_TypeDef *ph,  UART_HandleTypeDef * huart  )
// {
//     viper.uarthelper->huart = huart;
//     // UartHelper_Set_Huart( viper.uarthelper,    huart  );
// }
// void Viper_Set_Interface_Type( Viper_TypeDef *ph,    Uart_Interface_Type_Typedef interface_type  )
// {
//     viper.interface_type = interface_type;
//     viper.uarthelper->interface_type = interface_type;
//     UartInterface_Setup_Interface_type( viper.uarthelper->interface ,viper.interface_type);
// }