/*
 * can_comm.c
 *
 *  Created on: Jun 28, 2022
 *      Author: LUBI
 */



/**************INCLUDE BLOCK**************/
#include "can.h"
#include "can_comm.h"
#include "usart.h"


/***********INCLUDE BLOCK END*************/


/***** Data Type, Constant, and Macro Definitions *****/

/* Global variables*/

CAN_RxHeaderTypeDef rx_header, rx_header2;
uint8_t rx_msg[20], error_isolation[10], error_status[10], can2_rx_msg[10];
uint8_t can2TX_msg[8], can2TX_msg_2[8], tx_can2flag = 0;
uint16_t txmsg[16];

volatile uint8_t relaysts_ac02sts = 0;
uint16_t IMD_temperature = 0;
uint8_t AC02_stop_flag = 0, Authentication_done;
uint8_t chargestart = 0,fanstart = 0;
volatile char exfault = 0;
uint32_t HVposRes = 0, HVnegRes = 0;
uint32_t HVposRes_1 = 0, HVnegRes_1 = 0;
struct chargersts chrgsts;
/* Extern Data Declarations */
extern volatile uint8_t temp_min, temp_max;
extern volatile uint8_t starttimeouttick, timeoutflag;
//extern int fantimcntr;
extern uint8_t fantimflag;
extern volatile char imd1_timeouttick, imd2_timeouttick; /*imd1_errorFlag,imd2_errorFlag,*/
extern volatile uint8_t Emergency_stop;
uint8_t onstarttimeouttick;
/* Static Data Declarations */
//union
//{
//	unsigned short int word;
//	uint32_t dword;
//	float dfloat;
//	unsigned char byte[4];
//}split_int;
//static volatile char debug_buffer[40]={0};
#define C_ON 0xA5
#define C_OFF 0x5A

/***** Data Type, Constant, and Macro Definitions END *****/



/***** Public Function Bodies *****/



/***** Public Function Bodies END *****/

/**
 * @brief Sends Maxwell test CAN messages based on the provided ID.
 *
 * @param id Identifier for selecting the CAN message to send.
 * @return None
 */

/*
void maxwellTest(char id)
{
	CAN_TxHeaderTypeDef tx_header;
	uint8_t boot[]={0x03,0x00,0x00,0x30,0x00,0x00,0x00,0x00};
	uint8_t boot2[]={0x03,0x00,0X00,0x21,0x43,0x48,0x00,0x00};
	tx_header.DLC=8;
	tx_header.IDE = CAN_ID_EXT;
	tx_header.RTR = CAN_RTR_DATA;
	uint32_t mailbox;
	switch (id)
	{
	case 0:

//	tx_header.ExtId=0x06080780;
		tx_header.ExtId=0x0607FF80;

	if(HAL_CAN_AddTxMessage(&hcan2, &tx_header, boot, &mailbox) != HAL_OK)
	{
		Error_Handler();
	}
	break;
	case 1:

		//tx_header.ExtId=0x06080F80;

		tx_header.ExtId=0X060c1781; //82

		if(HAL_CAN_AddTxMessage(&hcan2, &tx_header, boot2, &mailbox) != HAL_OK)
		{
			Error_Handler();
		}
		break;

	case 2:


			//tx_header.ExtId=0x06081780;
			tx_header.ExtId=0X060c0781; //80




			if(HAL_CAN_AddTxMessage(&hcan2, &tx_header, boot2, &mailbox) != HAL_OK)
			{
				Error_Handler();
			}
			break;
	case 3:

			tx_header.ExtId=0x06081F80;



			if(HAL_CAN_AddTxMessage(&hcan2, &tx_header, boot, &mailbox) != HAL_OK)
			{
				Error_Handler();
			}
			break;
	case 4:


			tx_header.ExtId=0x06082780;




			if(HAL_CAN_AddTxMessage(&hcan2, &tx_header, boot, &mailbox) != HAL_OK)
			{
				Error_Handler();
			}
			break;
	case 5:

			tx_header.ExtId=0x06082F80;


			if(HAL_CAN_AddTxMessage(&hcan2, &tx_header, boot, &mailbox) != HAL_OK)
			{
				Error_Handler();
			}
			break;
	case 6:


			tx_header.ExtId=0x06083780;

			if(HAL_CAN_AddTxMessage(&hcan2, &tx_header, boot, &mailbox) != HAL_OK)
			{
				Error_Handler();
			}
			break;

	}
}
*/

/**
 * @brief Sends a CAN message containing temperature data.
 *
 * @return None
 */
#if imd == syn
void can_tx_temperature(void)
{

	CAN_TxHeaderTypeDef tx_header;
	tx_header.DLC=1;
	tx_header.ExtId=0xA100101;
	tx_header.IDE = CAN_ID_EXT;
	tx_header.RTR = CAN_RTR_DATA;

	uint32_t mailbox;
	uint8_t message = 0x80;

	if(HAL_CAN_AddTxMessage(&hcan1, &tx_header, &message, &mailbox) != HAL_OK)
	{
		Error_Handler();
	}
//	while( HAL_CAN_IsTxMessagePending(&hcan1, mailbox));


//	while( HAL_CAN_IsTxMessagePending(&hcan1, mailbox));

//	HAL_UART_Transmit(&huart2, "TX OK", 5, 1000);
}

/**
 * @brief Sends a CAN message to perform a reset.
 *
 * @return None
 */
void can_tx_reset()
{
		CAN_TxHeaderTypeDef tx_header;
		tx_header.DLC=5;
		tx_header.ExtId=0xA100101;
		tx_header.IDE = CAN_ID_EXT;
		tx_header.RTR = CAN_RTR_DATA;

		uint32_t mailbox;
	uint8_t restart[]={0xc1,0x01,0x23,0x45,0x67};

		if(HAL_CAN_AddTxMessage(&hcan1, &tx_header, restart, &mailbox) != HAL_OK)
		{
			Error_Handler();
		}
//		while( HAL_CAN_IsTxMessagePending(&hcan1, mailbox));

//		while(!HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0));
//
//		if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rx_header, rx_msg) != HAL_OK)
//		{
//				Error_Handler();
//		}
}

/**
 * @brief Sends a CAN message containing vb_max data.
 *
 * @return None
 */
void can_tx_vbmax()
{
	uint8_t vb_max[]={0xf0,0x02,0xf8};
	CAN_TxHeaderTypeDef tx_header;
	tx_header.DLC=3;
	tx_header.ExtId=0xA100101;
	tx_header.IDE = CAN_ID_EXT;
	tx_header.RTR = CAN_RTR_DATA;


	uint32_t mailbox;


		if(HAL_CAN_AddTxMessage(&hcan1, &tx_header, vb_max, &mailbox) != HAL_OK)
		{
			Error_Handler();
		}
		while( HAL_CAN_IsTxMessagePending(&hcan1, mailbox));

//		while(!HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0));
//
//			if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rx_header, rx_msg) != HAL_OK)
//			{
//					Error_Handler();
//			}
}

/**
 * @brief Sends a CAN message containing isolation state data.
 *
 * @return None
 */
void can_tx_Isolation_State()
{
	CAN_TxHeaderTypeDef tx_header;
		tx_header.DLC=1;
		tx_header.ExtId=0xA100101;
		tx_header.IDE = CAN_ID_EXT;
		tx_header.RTR = CAN_RTR_DATA;

		uint8_t message = 0xE0;
		uint32_t mailbox;

		if(HAL_CAN_AddTxMessage(&hcan1, &tx_header, &message, &mailbox) != HAL_OK)
		{
			Error_Handler();
		}
//		while( HAL_CAN_IsTxMessagePending(&hcan1, mailbox));

//		while(!HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0));
//
//			if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rx_header, error_isolation) != HAL_OK)
//			{
//					Error_Handler();
//			}
}

/**
 * @brief Sends a CAN message containing error flag data.
 *
 * @return None
 */
void can_tx_Error_Flag()
{
	CAN_TxHeaderTypeDef tx_header;
	tx_header.DLC=1;
	tx_header.ExtId=0xA100101;
	tx_header.IDE = CAN_ID_EXT;
	tx_header.RTR = CAN_RTR_DATA;

	uint8_t message = 0xE5;

	uint32_t mailbox;

	if(HAL_CAN_AddTxMessage(&hcan1, &tx_header, &message, &mailbox) != HAL_OK)
	{
		Error_Handler();
	}
//	while( HAL_CAN_IsTxMessagePending(&hcan1, mailbox));

//	while(!HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0));
//
//		if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rx_header, error_status) != HAL_OK)
//		{
//				Error_Handler();
//		}
}
#endif
/**
 * @brief Sends a CAN message using CAN2.
 *
 * @return None
 */
void can2_tx_frame(void)
{
	CAN_TxHeaderTypeDef tx_header1;
	tx_header1.DLC = 8;
	tx_header1.ExtId = 0xA105695;
	tx_header1.IDE = CAN_ID_EXT;
	tx_header1.RTR = CAN_RTR_DATA;
	uint32_t mailbox;

		if(HAL_CAN_AddTxMessage(&hcan2, &tx_header1, can2TX_msg, &mailbox) != HAL_OK)
		{
			Error_Handler();
		}
}

void can2_tx_frame_2(void)
{
	CAN_TxHeaderTypeDef tx_header1;
	tx_header1.DLC = 8;
	tx_header1.ExtId = 0xA100100; // CHANGED ACCORDING TO FIRMWARE
	tx_header1.IDE = CAN_ID_EXT;
	tx_header1.RTR = CAN_RTR_DATA;
	uint32_t mailbox;


	if(HAL_CAN_AddTxMessage(&hcan2, &tx_header1, can2TX_msg_2, &mailbox) != HAL_OK)
	{
		Error_Handler();
	}
//		while( HAL_CAN_IsTxMessagePending(&hcan2, mailbox));

//		while(!HAL_CAN_GetRxFifoFillLevel(&hcan2, CAN_RX_FIFO1));
//
//		if(HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO1, &rx_header2, can2_rx_msg) != HAL_OK)
//		{
//		Error_Handler();
//		}
}

/**
 * @brief Configures CAN filter.
 *
 * @return None
 */

void can_filterconfig(void)
{
	/*This filter will allow all messages through, regardless of the ID (because the mask is all zeros and all bits are ignored).*/
	CAN_FilterTypeDef canfilter;
	canfilter.FilterActivation = CAN_FILTER_ENABLE;
	canfilter.FilterBank = 0;
	canfilter.FilterFIFOAssignment = CAN_RX_FIFO0;
	canfilter.FilterIdHigh = 0X0000;
	canfilter.FilterIdLow = 0X0000;
	canfilter.FilterMaskIdHigh = 0X0000;
	canfilter.FilterMaskIdLow = 0X0000;
	canfilter.FilterMode = CAN_FILTERMODE_IDMASK;
	canfilter.FilterScale = CAN_FILTERSCALE_32BIT;

	if( HAL_CAN_ConfigFilter(&hcan1, &canfilter) != HAL_OK)
	{
		Error_Handler();
	}

//	canfilter.FilterBank = 0;
//	canfilter.FilterFIFOAssignment = CAN_RX_FIFO1;
//	if( HAL_CAN_ConfigFilter(&hcan2, &canfilter) != HAL_OK)
//	{
//		Error_Handler();
//	}
}
#if imd == syn

void can_filterconfig(void)
{
	CAN_FilterTypeDef canfilter;

	// Convert 29-bit CAN ID to the 32-bit format used by the filter
	    uint32_t can_id_1 = 0x18FF5050 << 3;
	    uint32_t can_id_2 = 0x18FF5051 << 3;

	canfilter.FilterActivation = CAN_FILTER_ENABLE;
	canfilter.FilterBank = 0;
	canfilter.FilterFIFOAssignment = CAN_RX_FIFO0;
	 // Set the FilterId to the first CAN ID
	canfilter.FilterIdHigh = (uint16_t)(can_id_1 >> 16);
	canfilter.FilterIdLow = (uint16_t)(can_id_1 & 0xFFFF);

	// Set the mask to allow the last bit to differ
	canfilter.FilterMaskIdHigh = 0xFFFF;
	canfilter.FilterMaskIdLow = 0xFFF8; // Accept both 0x18FF5050 and 0x18FF5051

	canfilter.FilterMode = CAN_FILTERMODE_IDMASK;
	canfilter.FilterScale = CAN_FILTERSCALE_32BIT;

	if( HAL_CAN_ConfigFilter(&hcan1, &canfilter) != HAL_OK)
	{
		Error_Handler();
	}

//	canfilter.FilterBank = 0;
//	canfilter.FilterFIFOAssignment = CAN_RX_FIFO1;
//	if( HAL_CAN_ConfigFilter(&hcan2, &canfilter) != HAL_OK)
//	{
//		Error_Handler();
//	}
}
#endif
/**
 * @brief Configures CAN2 filter.
 *
 * @return None
 */
void can2_filterconfig(void)
{
	/*
	 * This filter is configured to allow only messages with an extended identifier (29-bit) that matches the mask and ID criteria to pass through.
	 * The ExtId (0xA105695) specifies the base identifier.
	 * CAN_ID_EXT sets the IDE flag (the bit that signals the use of an extended identifier in CAN)
	 */
	CAN_FilterTypeDef canfilter2;
	uint32_t ExtId = 0xA105695;
	canfilter2.FilterActivation = CAN_FILTER_ENABLE;
	canfilter2.FilterBank = 14;
	canfilter2.FilterFIFOAssignment = CAN_RX_FIFO0;
	canfilter2.FilterIdHigh = ((ExtId << 3) >> 16) & 0xffff;	//makes the filter sensitive to the upper portion of the ExtId
	canfilter2.FilterIdLow = ((ExtId << 3) & 0xffff) | CAN_ID_EXT;	//makes the filter specifically target extended identifiers (29-bit) rather than standard (11-bit) identifiers
	canfilter2.FilterMaskIdHigh = 0x1FFF;	//filter will require an exact match for the upper 13 bits
	canfilter2.FilterMaskIdLow = 0XFFFF;	//filter will require an exact match for lower 16 bits
//	canfilter2.FilterMaskIdHigh = ((ExtId << 3) >> 16) &0xffff;
//	canfilter2.FilterMaskIdLow = (ExtId << 3) &0xffff| CAN_ID_EXT;
	canfilter2.FilterMode = CAN_FILTERMODE_IDMASK;
	canfilter2.FilterScale = CAN_FILTERSCALE_32BIT;

	if( HAL_CAN_ConfigFilter(&hcan2, &canfilter2) != HAL_OK)
		Error_Handler();
}

/**
 * @brief Callback function invoked when a message is pending in CAN1 RX FIFO0.
 *
 * @param hcan Pointer to a CAN_HandleTypeDef structure that contains the configuration information for the specified CAN.
 * @return None
 */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{

	if(hcan->Instance == CAN1)
	{
		if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rx_header, rx_msg) != HAL_OK)
			Error_Handler();

		if(rx_header.ExtId == 0xA105695)
		{
				// RECIEVE ACK.
			txmsg[3] = 0xff;  // imd comm
		}
	}
	else if(hcan->Instance==CAN2)
	{
		if(HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO0, &rx_header2, can2_rx_msg) != HAL_OK)
		{
			Error_Handler();
		}

	}
}

/**
 * @brief Callback function invoked when a CAN error occurs.
 *
 * @param hcan Pointer to a CAN_HandleTypeDef structure that contains the configuration information for the specified CAN.
 * @return None
 */
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
{


}
