#include "bsp_UART.h"
#include "main.h"
#include <stdlib.h>
#include "bsp_com_helper.h"
//#include "DLTuc.h"
void GF_UART_Send_List_Send(struct UARTHandler *handler);
void Dispatcher_List_Add(struct UARTHandler *uartHandler,
		void (*dispache)(void));



void UARTHandlerAddTxList(struct UARTHandler *uartHandler, uint8_t *data,
		uint16_t length, uint32_t txListTimePeriod, void (*UART_Decode)(uint8_t*, uint16_t));

//Store all the data in these buffer
uint8_t RS485_1_RxMA_buf[UART_Receive_MAX_NUM];
uint8_t RS485_2_RxDMA_buf[UART_Receive_MAX_NUM];
uint8_t RS485_3_RxDMA_buf[UART_Receive_MAX_NUM];
uint8_t RS485_4_RxDMA_buf[UART_Receive_MAX_NUM];
uint8_t Debug_RxDMA_buf[UART_Receive_MAX_NUM];
uint8_t ExternSerial_RxDMA_buf[UART_Receive_MAX_NUM];

uint8_t RS485_1_TxDMA_buf[UART_Transmit_MAX_NUM];
uint8_t RS485_2_TxDMA_buf[UART_Transmit_MAX_NUM];
uint8_t RS485_3_TxDMA_buf[UART_Transmit_MAX_NUM];
uint8_t RS485_4_TxDMA_buf[UART_Transmit_MAX_NUM];
uint8_t Debug_TxDMA_buf[UART_Transmit_MAX_NUM];
uint8_t ExternSerial_TxDMA_buf[UART_Transmit_MAX_NUM];



struct UARTHandler RS_485_1_UART_Handler;
struct UARTHandler RS_485_2_UART_Handler;
struct UARTHandler RS_485_3_UART_Handler;

#if defined (hlpuart1Exit)

	#define LPUART1UART hlpuart1
	struct UARTHandler LPUART1_UART_Handler;

#endif

void GF_BSP_UARTHandlers_Intialize(
		int32_t RS485_1_WaitTime,
		int32_t RS485_2_WaitTime,
		int32_t RS485_3_WaitTime,
		int32_t RS485_4_WaitTime,
		int32_t LTE_7S0_Serial_WaitTime,
		int32_t InterCall_DEBUG_WaitTime,
		int32_t E28_SBUS_WaitTime,
		int32_t LPUART1_UART_WaitTime,
		int32_t RS485_1_Dispacher_Time,
		int32_t RS485_2_Dispacher_Time,
		int32_t RS485_3_Dispacher_Time,
		int32_t RS485_4_Dispacher_Time,
		int32_t LTE_7S0_Serial_Dispacher_Time,
		int32_t InterCall_DEBUG_Dispacher_Time,
		int32_t E28_SBUS_Dispacher_Time,
		int32_t LPUART1_UART_Dispacher_Time
)
{

	IntializeUARTHandler(&RS_485_1_UART_Handler, &RS485_1_UART, RS485_1_WaitTime, 2,RS485_1_Dispacher_Time);
	IntializeUARTHandler(&RS_485_2_UART_Handler, &RS485_2_UART, RS485_2_WaitTime, 2,RS485_2_Dispacher_Time);
	IntializeUARTHandler(&RS_485_3_UART_Handler, &RS485_3_UART, RS485_3_WaitTime, 2,RS485_2_Dispacher_Time);



	HAL_UART_Receive_IT((RS_485_1_UART_Handler.uart),
			(uint8_t*) &RS_485_1_UART_Handler.tmp_Rx_Buf, 1);
	HAL_UART_Receive_IT((RS_485_2_UART_Handler.uart),
			(uint8_t*) &RS_485_2_UART_Handler.tmp_Rx_Buf, 1);
	HAL_UART_Receive_IT((RS_485_3_UART_Handler.uart),
			(uint8_t*) &RS_485_3_UART_Handler.tmp_Rx_Buf, 1);


#if defined (hlpuart1Exit)
	IntializeUARTHandler(&LPUART1_UART_Handler, &LPUART1UART, LPUART1_UART_WaitTime, 2,LPUART1_UART_Dispacher_Time); //10ms 剩余2ms
	HAL_UART_Receive_IT((LPUART1_UART_Handler.uart),
					(uint8_t*) &LPUART1_UART_Handler.tmp_Rx_Buf, 1);

#endif
	//这一句代码是关键，每2ms调用GF_BSP_UART_Timer，执行解析串口数据的函数和向串口发送数据的函数
	GF_BSP_Interrupt_Add_CallBack(DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback,
								  GF_BSP_UART_Timer);
}

//Count Every 2 ms
void GF_BSP_UART_Timer()
{
	Counting(&RS_485_1_UART_Handler);
	Counting(&RS_485_2_UART_Handler);


#if defined (hlpuart1Exit)
 	Counting(&LPUART1_UART_Handler);
#endif

}

void UARTHandlerAddTxList(struct UARTHandler *uartHandler,
						  uint8_t *data,
						  uint16_t length,
						  uint32_t txListTimePeriod,
						  void (*UART_Decode)(uint8_t*, uint16_t))
{

	UARTSendHandler *pTmp = NULL; //临时指针
	//临时指针2用于逐个申请内存
	pTmp = (UARTSendHandler*) malloc(sizeof(UARTSendHandler));
	memcpy(pTmp->Tx_Buf, data, length);
	pTmp->pNext = NULL;
	pTmp->SendListTimePeriod=txListTimePeriod;
	pTmp->SendLength = length;
	pTmp->UART_Decode = UART_Decode;

//if NULL, call intialize one
	if (uartHandler->pCurrentUARTSendHadler == NULL)
	{
		uartHandler->pCurrentUARTSendHadler = pTmp; //空链表
	} else
	{
		char i = 0;
		//插到尾部
		UARTSendHandler *phead = NULL;
		phead = uartHandler->pCurrentUARTSendHadler;
		while (phead->pNext != NULL)
		{
			i++;
			phead = phead->pNext;
		}
		phead->pNext = pTmp;

	}

}

void UARTHandlerTx(struct UARTHandler *uartHandler)
{

	if (uartHandler->uart == NULL)
	{
//		LOGFF(DL_ERROR,
//				"the UART Hardware did  not intialize,check the setting");
		return;
	}

	uartHandler->RxCount=0;//设定RxCount为0
#if defined (hlpuart1Exit)
		if(uartHandler->uart->Instance == LPUART1)
		{

			HAL_UART_Transmit(uartHandler->uart, uartHandler->Tx_Buf,
						uartHandler->TxCount,100);
		}else
		{
#endif

		if (uartHandler->uart->Instance == UART4)			//**DEBUG
			{

			} else if (uartHandler->uart->Instance == USART1)		//**RS485_1
			{
				//将对应的 RS485 方向控制引脚置高，使能发送
				HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin, GPIO_PIN_SET);

			} else if (uartHandler->uart->Instance == USART3)		//**RS485_2
			{

				HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin, GPIO_PIN_SET);

			}
//			else if (uartHandler->uart->Instance == USART6)		//**RS485_3
//			{
//
//				HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port, RS485_3_DIR_Pin, GPIO_PIN_SET);
//
//			}
//			else if (uartHandler->uart->Instance == UART7)		//**RS485_4
//			{
//				HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port, RS485_4_DIR_Pin, GPIO_PIN_SET);
//
//			}
			else if (uartHandler->uart->Instance == USART2)//**E22	// External serial port
			{

			}
//			else if (uartHandler->uart->Instance == UART5)	//**E28	// SBUS
//			{
//
//			}

//			SCB_CleanInvalidateDCache_by_Addr((uint32_t*) uartHandler->Tx_Buf,
//											   uartHandler->TxCount);          //清除数据缓存

			HAL_UART_Transmit_DMA(uartHandler->uart, uartHandler->Tx_Buf,      //将串口Tx_Buf中的数据发送出去
								  uartHandler->TxCount);
#if defined (hlpuart1Exit)
		}
#endif


	if (uartHandler->uart == UART4)			//**DEBUG
	{

	} else if (uartHandler->uart == USART1)		//**RS485_1
	{
		HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin,
				GPIO_PIN_RESET);
	} else if (uartHandler->uart == USART3)		//**RS485_2
	{
		HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin,
				GPIO_PIN_RESET);
	}
//	else if (uartHandler->uart == USART6)		//**RS485_3
//	{
//		HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port,
//		RS485_3_DIR_Pin, GPIO_PIN_RESET);
//	}
//	else if (uartHandler->uart == UART7)		//**RS485_4
//	{
//		HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port,
//		RS485_4_DIR_Pin, GPIO_PIN_RESET);
//	}
//	else if (uartHandler->uart == USART2)	//**E22	// External serial port
//	{
//
//	}
//	else if (uartHandler->uart == UART5)	//**E28	// SBUS
//	{
//
//	}
}
void UARTHandlerRX(struct UARTHandler *uartHandler)
{
	if (uartHandler->startCountFlag == 0)
	{
		uartHandler->startCountFlag = 1;
		uartHandler->RxCount = 0;
	}

	uartHandler->Rx_Buf[uartHandler->RxCount] = uartHandler->tmp_Rx_Buf[0];
	uartHandler->RxCount++;

	HAL_UART_Receive_IT(uartHandler->uart, uartHandler->tmp_Rx_Buf, 1);

	uartHandler->Wait_Time_Count = 0;
	if(uartHandler->RxCount>=1024)//接收数据过多，直接抛弃
	{
		uartHandler->RxCount=0;
	}
}

void IntializeUARTHandler(struct UARTHandler *uartHandler,
						  UART_HandleTypeDef *uart,
						  int32_t WaitTime,
						  unsigned char timeSpan,
						  int32_t Dispacher_Time)
{
	uartHandler->Wait_Time_Count = 0;
	uartHandler->Wait_time = WaitTime;

	uartHandler->uart = uart;
	uartHandler->UART_Rx = UARTHandlerRX;
	uartHandler->UART_Tx = UARTHandlerTx;                                      //
	uartHandler->AddSendList = UARTHandlerAddTxList;

	uartHandler->dispacherController = (DispacherController*) malloc(
										sizeof(DispacherController));

	uartHandler->dispacherController->pHead = NULL;
	uartHandler->dispacherController->pTail = NULL;
	uartHandler->dispacherController->Dispacher_Enable = 0;          //只有使能打开时才能够执行调度控制器中的函数
	uartHandler->dispacherController->DispacherCallTime = Dispacher_Time;   // call the function every 50 ms
	uartHandler->dispacherController->Dispacher_Counter = 0;
	uartHandler->dispacherController->DispacherNumber = 0;
	uartHandler->dispacherController->Add_Dispatcher_List = Dispatcher_List_Add_t;   //向调度控制器链表中添加调度函数
	uartHandler->dispacherController->Dispatcher_Run = Dispatch_t;   //执行添加到调度控制器中的函数

	uartHandler->timeSpan = 2;
	uartHandler->SendList_time_Count = 0;
	uartHandler->SendList_Period = 100;

}

void Counting(struct UARTHandler *uartHandler)             //先执行解析函数，然后执行调度控制器链表中的函数
{
	if (uartHandler->UART_Decode == NULL)                  //不解析，直接返回true
	{
		uartHandler->decode_finished = 1;
	}
	else
	{
		if (uartHandler->startCountFlag == 1)
		{
			uartHandler->Wait_Time_Count++;
			if (uartHandler->timeSpan * uartHandler->Wait_Time_Count
				>= uartHandler->Wait_time)
			{
				uartHandler->Wait_Time_Count = 0;
				uartHandler->startCountFlag = 0;

				if (uartHandler->RxCount >= 1)             //启动解析函数
				{
					uartHandler->UART_Decode(uartHandler->Rx_Buf,
											 uartHandler->RxCount);
					uartHandler->RxCount = 0;
				}
			}
		}
	}

	if (uartHandler->pCurrentUARTSendHadler != NULL)
	{
		GF_UART_Send_List_Send(uartHandler);     /*不理解这句话，为什么不直接执行调度函数，
												要先发送串口链表里的Tx_Buf，到目前为止没看到向串口链表Tx_Buf存数据的位置*/
	} else
	{
		uartHandler->dispacherController->Dispatcher_Run(uartHandler->dispacherController);  //执行调度函数
	}
}
//_weak
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)		 //**RS485_1
	{
		//GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_RS485_1_RxCpltCallback);

		UARTHandlerRX(&RS_485_1_UART_Handler);
	} else if (huart->Instance == USART3)		 //**RS485_2
	{
		//GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_RS485_2_RxCpltCallback);

		UARTHandlerRX(&RS_485_2_UART_Handler);

	}


 #if defined (hlpuart1Exit)
	 if (huart->Instance == LPUART1)		//**E28	// SBUS
		{
			UARTHandlerRX(&LPUART1_UART_Handler);
		}


 #endif
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{

	if (huart->Instance == UART4)			//**DEBUG
	{

	} else if (huart->Instance == USART1)		//**RS485_1
	{
		HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin,
				GPIO_PIN_RESET);
	} else if (huart->Instance == USART3)		//**RS485_2
	{
		HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin,
				GPIO_PIN_RESET);
	}
//	else if (huart->Instance == USART6)		//**RS485_3
//	{
//		HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port,
//		RS485_3_DIR_Pin, GPIO_PIN_RESET);
//	}
//	else if (huart->Instance == UART7)		//**RS485_4
//	{
//		HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port,
//		RS485_4_DIR_Pin, GPIO_PIN_RESET);
//	}
//	else if (huart->Instance == USART2)	//**E22	// External serial port
//	{
//
//	}
//	else if (huart->Instance == UART5)	//**E28	// SBUS
//	{
//
//	}

}

//RS485_Index:1-4 RS485; 5 ExternSerial; 6 Debug;
void GF_BSP_UART_Transmit(const uint8_t RS485_Index, const uint8_t *pData,
		uint16_t Size)
{
	UART_HandleTypeDef *huart;
	if (Size > UART_Transmit_MAX_NUM)
		Size = UART_Transmit_MAX_NUM;

	switch (RS485_Index)
	{
		case 1:
			huart = &huart1;
			HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin,
					GPIO_PIN_SET);
			memcpy(RS485_1_TxDMA_buf, pData, Size);
			SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_1_TxDMA_buf,
					Size);
			HAL_UART_Transmit_DMA(huart, RS485_1_TxDMA_buf, Size);
			//HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);

			break;
		case 2:
			huart = &huart3;
			HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin,
					GPIO_PIN_SET);
			memcpy(RS485_2_TxDMA_buf, pData, Size);
			SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_2_TxDMA_buf,
					Size);
			HAL_UART_Transmit_DMA(huart, RS485_2_TxDMA_buf, Size);
			break;
		case 3:
//			huart = &huart6;
//			HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port, RS485_3_DIR_Pin,
//					GPIO_PIN_SET);
//			memcpy(RS485_3_TxDMA_buf, pData, Size);
//			SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_3_TxDMA_buf,
//					Size);
//			HAL_UART_Transmit_DMA(huart, RS485_3_TxDMA_buf, Size);
			break;
		case 4:
//			huart = &huart7;
//			HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port, RS485_4_DIR_Pin,
//					GPIO_PIN_SET);
//			memcpy(RS485_4_TxDMA_buf, pData, Size);
//			SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_4_TxDMA_buf,
//					Size);
//			HAL_UART_Transmit_DMA(huart, RS485_4_TxDMA_buf, Size);
			break;
		case 5:
			huart = &huart2;
			memcpy(ExternSerial_TxDMA_buf, pData, Size);
			SCB_CleanInvalidateDCache_by_Addr(
					(uint32_t*) ExternSerial_TxDMA_buf, Size);
			HAL_UART_Transmit_DMA(huart, ExternSerial_TxDMA_buf, Size);
			break;
		default:
//			huart = &huart4;
//			memcpy(Debug_TxDMA_buf, pData, Size);
//			SCB_CleanInvalidateDCache_by_Addr((uint32_t*) Debug_TxDMA_buf,
//					Size);
//			HAL_UART_Transmit_DMA(huart, Debug_TxDMA_buf, Size);
			break;
	}
}

void GF_UART_Send_List_Send(struct UARTHandler *handler)
{

	handler->SendList_time_Count++;
	if (handler->timeSpan * handler->SendList_time_Count
			>= handler->SendList_Period)
	{
		handler->SendList_time_Count = 0;
		handler->SendListExists = 1;
		if (handler->pCurrentUARTSendHadler != NULL)
		{
			//拷贝数据到相关的代码中，然后发送
			memcpy(handler->Tx_Buf, handler->pCurrentUARTSendHadler->Tx_Buf,
					handler->pCurrentUARTSendHadler->SendLength);
			handler->SendList_Period =
					handler->pCurrentUARTSendHadler->SendListTimePeriod;
			handler->TxCount = handler->pCurrentUARTSendHadler->SendLength;
			handler->UART_Tx(handler);                               //将数据发送出去

			if (handler->pCurrentUARTSendHadler->pNext != NULL)
			{
				UARTSendHandler *temp = handler->pCurrentUARTSendHadler->pNext;
				free(handler->pCurrentUARTSendHadler);               //清除内存
				handler->pCurrentUARTSendHadler = temp;
			} else
			{
				free(handler->pCurrentUARTSendHadler);               //清除内存
				handler->pCurrentUARTSendHadler = NULL;
			}

		} else
		{
			handler->SendListExists = 0;

		}

	}

}
