/*
 * AppTaskCan.c
 *
 *  Created on: 2022年2月8日
 *      Author: QiXiang_CHENJIE
 */
#include "AppTaskCan.h"
static void CanDataDecode(uint32 DataCanID, uint8 CanData[]);
static void CanDataAsk(QueueDataTrans_Type AskData);
static void CanCirSendMess(void);
static void GropPack_CANID(uint8 DataPtr[], uint32 CAN_ID);

uint8 DataPackCounter[21] = {1,1,7,5,16,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

static void vCanRxCallback(TimerHandle_t pxTimer)
{
	uint32 ulTimerID;
	ulTimerID = (uint32)pvTimerGetTimerID(pxTimer);
	if(ulTimerID==0)
	{
		Can_MainFunction_Read();
	}
}
     
void CanTask(void *data)
{
	(void)data;
	CanRecvQueueHandle   = xQueueCreate(16, sizeof(Can_Msg_Type_Data));  // CAN获取消息队列创建:CAN接收队列,接收EBC的CAN报文

	Uart2ToCanDataHandle = xQueueCreate(2, sizeof(QueueDataTrans_Type)); // CAN数据查询队列创建:CAN发送队列,发送CAN报文给EBC

	CanToUart2DataHandle = xQueueCreate(1, sizeof(QueueDataTrans_Type)); // CAN数据回复队列创建:从机的WIFI通讯的发送队列
	uint8 CanState = 0;
	CanIf_bRxFlag = false;
	Can_Msg_Type_Data CanRxMsg;
	QueueDataTrans_Type CanAskData={0,NULL};

	TimerHandle_t monitorTimer1ms;
	monitorTimer1ms = xTimerCreate("monitor1ms",1,pdTRUE,(void *)0,vCanRxCallback);
	xTimerStart(monitorTimer1ms,0);

	while (TRUE)
	{
		switch (CanState)
		{
			case 0:
			{
				CanState = 1;
				break;
			}
			case 1:
			{
				memset(&CanRxMsg, 0, sizeof(CanRxMsg));
				BaseType_t ret = xQueueReceive(CanRecvQueueHandle, &CanRxMsg, 0);
				/* 处理来自Can总线的消息 */
				if(pdPASS == ret)
				{
					CanDataDecode(CanRxMsg.id, CanRxMsg.data);
				}
				/* 接收处理来自串口线程的消息 */
				BaseType_t ret2 = xQueueReceive(Uart2ToCanDataHandle,&CanAskData,10);//带有校验码
				if (ret2 == pdPASS)
				{
					CanDataAsk(CanAskData);
				}
				/* 循环发送的数据 */
				CanCirSendMess();
				break;
			}
		}
	}
}
static void CanDataDecode(uint32 DataCanID, uint8 CanData[])
{

	if(IsJumptoBootloader(DataCanID, CanData))
	{
		/* 升级 */
		DoRoutinePositiveAnswer();
		RequestEnterBootloader();
		DoResetECU();
		return;
	}

	switch (DataCanID)
	{
		case 0x1C00EBEC:
		{
			/* 连接蓝牙，断开蓝牙 从机状态暂时只考虑主动断开*/
			BleConnectControl = CanData[2];
			BlePwrControl = CanData[3];
			WiFiConnectControl = CanData[4];
			WiFiPwrControl = CanData[5];
			break;
		}
		case 0x1C01EBEC:
		{
			EBC_State          = CanData[0];
			EBC_ExchangeMode   = CanData[1];
			EBC_LockMode       = CanData[2];
			EBC_ExchangeKind   = CanData[3];
			EBC_AExchangeCheck = CanData[4];
			break;
		}
		case 0x1C02EBEC:
		{
			UnlockCheck        = CanData[0];
			LockCheck          = CanData[1];
			BatPlace   	       = CanData[2];
			UnlockSensorSignal = CanData[3];
			LockSensorSignal   = CanData[4];
			BaseSensorSignal   = CanData[5];
			InterlockSignal    = CanData[6];
			SolValActuSt       = CanData[7];
			break;
		}
		case 0x1C12EBEC:
		{
			AirPrValue         = CanData[0];
			TheManFluid        = CanData[1];
			break;
		}
		case 0x1C03EBEC:
		{
			WholeVehComState   = CanData[0];
			KeySignal          = CanData[1];
			VehicleState   	   = CanData[2];
			BrakeSignal        = CanData[3];
			GearSignal         = CanData[4];
			TurnSignal         = CanData[5];
			FrontAxleValue     = CanData[6];
			RearAxleValue	   = CanData[7];
			break;
		}
		case 0x1C04EBEC:
		{
			BatComState        = CanData[0];
			BatBMS_State       = CanData[1];
			MContactorsState   = CanData[2];
			SOC                = CanData[3];
			BatValtage         = CanData[4];
			SOH                = CanData[5];
			break;
		}
		case 0x1C05EBEC:
		{
			ErrorLevel         = CanData[0];
			ErrorCode          = CanData[1];
			break;
		}
		case 0x1C06EBEC:
		{
			/* CAN ID顺序从0开始1 */
			uint8 CanIndex = 1;
			for(uint8 i = CanData[0] * 7; CanIndex < 8  && i < 26; i++)
			{
				BatSN[i] = CanData[CanIndex++];
			}
			break;
		}
		case 0x1C07EBEC:
		{
			/* CAN ID顺序从0开始1 */
			uint8 CANDATA_Viwer = 1;
			for(uint8 i = CanData[0] * 7; CANDATA_Viwer < 8  && i < 17; i++)
			{
				VehicleVin[i] = CanData[CANDATA_Viwer];
				CANDATA_Viwer++;
			}
			break;
		}
		case 0x1C08EBEC:
		{
			AccruedChargeAh = *(uint32 *)CanData;
			AccruedChargeKwh = *((uint32*)CanData + 1);
			break;
		}
		case 0x1C09EBEC:
		{
			AccruedDischargeAh = *(uint32 *)CanData;
			AccruedDischargeKwh = *((uint32*)CanData + 1);
			break;
		}
		case 0x1C0AEBEC:
		{
			SingleChargeAh  = *(uint16 *)CanData;    	/* 单次充电Ah数 Ah 0.1 */
			SingleChargeKwh = *((uint16*)CanData + 1);   	/* 单次充电kwh数 kwh 0.1 */
			AccruedMileage  = *((uint32*)CanData + 1); 	  	/* 累计行驶里程 km 0.1 */
			break;
		}
		case 0x1C0BEBEC:
		{
			SS_AccruedChargeAh  = *((uint32*)CanData);	/* 累计换电站充入Ah数 Ah 0.1 */
			SS_AccruedChargeKwh = *((uint32*)CanData + 1);	/* 累计换电站充入kwh数 kwh 0.1 */
			break;
		}
		case 0x1C0CEBEC:
		{
			IG_AccruedChargeAh  = *((uint32*)CanData); 	/* 累计插枪充入Ah数 Ah 0.1 */
			IG_AccruedChargeKwh = *((uint32*)CanData + 1); /* 累计插枪充入kwh数 kwh 0.1 */
			break;
		}
		case 0x1C0DEBEC:
		{
			AFE_AccruedChargeAh  = *((uint32*)CanData); /* 累计动能回馈Ah数 */
			AFE_AccruedChargeKwh = *((uint32*)CanData + 1);/* 累计动能回馈kwh数 */
			break;
		}
		case 0x1C0EEBEC:
		{
			ExchangeNum    = *((uint16*)CanData); 		/* 换电次数 */
			ExchangeNumSuc = *((uint16*)CanData + 1); 		/* 换电成功次数 */
			break;
		}
		case 0x1C0FEBEC:
		{
			BatteryCurrent = *((uint16*)CanData);;      /* 电池电流 */
			BatRateRnergy  = *((uint16*)CanData + 1);      /* 电池额定能量 */
			break;
		}
		default:
			break;

	}
}
static void CanDataAsk(QueueDataTrans_Type AskData)
{
	Can_Msg_Type CanTxMsg;
	uint16 CrcGet = 0x00;
	uint16 CrcCal = 0xff;
	if(AskData.RealLen==10)
	{
		CrcGet = (*(AskData.DataPtr + AskData.RealLen - 2)<<0 )| (*(AskData.DataPtr + AskData.RealLen - 1)<<8 );
		CrcCal = CRC16_Modbus(AskData.DataPtr,AskData.RealLen-2);
		if(CrcGet==CrcCal)
		{
			CanTxMsg.id = 0X1CEF0000;
			CanTxMsg.idFrame = CAN_EXTENDED_ID_TYPE;
			CanTxMsg.sdu = AskData.DataPtr;
			CanTxMsg.length = 8;
			CanIf_SendMessage(0, CanTxMsg);
		}
	}
	else if(1 == AskData.RealLen)//从机连接与断开，主动给EBC发送一帧状态
	{
		CanTxMsg.id = 0X1CEF0002;
		CanTxMsg.idFrame = CAN_EXTENDED_ID_TYPE;
		CanTxMsg.sdu = AskData.DataPtr;
		CanTxMsg.length = 8;
		CanIf_SendMessage(0, CanTxMsg);
	}

	if(NULL != AskData.DataPtr)
	{
		free(AskData.DataPtr);
	}
	AskData.DataPtr = NULL;
}
/* CAN循环发送数据 */
static void CanCirSendMess(void)
{
	static uint32 can_last_tickcount00_100ms = 0;

	if(xTaskGetTickCount() - can_last_tickcount00_100ms >= pdMS_TO_TICKS(100))
	{

		can_last_tickcount00_100ms = xTaskGetTickCount();
		Can_Msg_Type CanTxMsg;
		uint8 DataPtr[8] = {0};

		CanTxMsg.idFrame = CAN_EXTENDED_ID_TYPE;
		CanTxMsg.sdu = DataPtr;
		CanTxMsg.length = 8;

		GropPack_CANID(DataPtr, 0x1C00ECEB);
		CanTxMsg.id = 0x1C00ECEB;
		CanIf_SendMessage(0, CanTxMsg);

		GropPack_CANID(DataPtr, 0x1C01ECEB);
		CanTxMsg.id = 0x1C01ECEB;
		CanIf_SendMessage(0, CanTxMsg);

	}

}
static void GropPack_CANID(uint8 DataPtr[], uint32 CAN_ID)
{
	static uint8 LifeSignal00 = 0;
	static uint8 LifeSignal01 = 0;
	switch(CAN_ID)
	{
		case 0x1C00ECEB:
			DataPtr[0] = 0;
			DataPtr[1] = LifeSignal00++;
			if(LifeSignal00 > 14)
				LifeSignal00 = 0;
			if(1 == BleStateFlg)
			{
				BLEConFed = 1;
			}
			else
			{
				BLEConFed = 2;
			}
			DataPtr[2] = BLEConFed;

			if(2 == BleStateFlg)
				BLEPWRFed = 1;
			else
				BLEPWRFed = 2;
			DataPtr[3] = BLEPWRFed;

			if(1 == tcp_server_process_status)
				WiFiConFed = 1;
			else
				WiFiConFed = 2;
			DataPtr[4] = WiFiConFed;

			if(2 == tcp_server_process_status)
				WiFiPWRFed = 1;
			else
				WiFiPWRFed = 2;
			DataPtr[5] = WiFiPWRFed;

			DataPtr[6] = EffectiveDataFed;

			break;
		case 0x1C01ECEB:
			DataPtr[0] = 0;
			DataPtr[1] = LifeSignal01++;
			if(LifeSignal01 > 14)
				LifeSignal01 = 0;
			DataPtr[2] = EmeStopSta;
			DataPtr[3] = LockSta;
			DataPtr[4] = UnlockSta;
			DataPtr[5] = AutoLockSta;
			DataPtr[6] = AutoUnlockSta;
			DataPtr[7] = StateSwitch;
			break;
		default:
			break;
	}
}
