#include "main.h"
#include "fdcan.h"
#include "fdcan_task.h"
#include "HW_test_task.h"

#define CAN_STANDARD_ID 	0x0301//0x07FF
#define CAN_EXTEND_ID 		0x155c6aa6//0x1FFFFFFF

//FIFO0回调函数
FDCAN_RxHeaderTypeDef FDCAN_RxHeader;
FDCAN_TxHeaderTypeDef FDCAN_TxHeader;

can_info_struct can_handle;

void fdcan_test_task(void);

void can_sent(can_info_struct * can_handle)
{
	FDCAN_HandleTypeDef * p_fdcan_handle;
	FDCAN_TxHeaderTypeDef * p_fdcan_tx_handle;
	
	if(can_handle->tx_len > 8)return;
	
	p_fdcan_handle = &hfdcan2;
	p_fdcan_tx_handle = &FDCAN_TxHeader;
	
/*##-4- Start the Transmission process #####################################*/
	if(READ_BIT(p_fdcan_handle->Instance->CCCR, FDCAN_CCCR_DAR)){
		HAL_FDCAN_Stop(p_fdcan_handle);
		CLEAR_BIT(p_fdcan_handle->Instance->CCCR, FDCAN_CCCR_DAR);//AUTO retransmission
		HAL_FDCAN_Start(p_fdcan_handle);
	}
	
	p_fdcan_tx_handle->Identifier = can_handle->tx_cmd;             //32位ID
	p_fdcan_tx_handle->IdType = FDCAN_EXTENDED_ID;                  
	p_fdcan_tx_handle->TxFrameType = FDCAN_DATA_FRAME;              //数据帧
	p_fdcan_tx_handle->DataLength = (can_handle->tx_len<<16);       //数据长度
	p_fdcan_tx_handle->ErrorStateIndicator = FDCAN_ESI_ACTIVE;            
	p_fdcan_tx_handle->BitRateSwitch = FDCAN_BRS_OFF;               //关闭速率切换
	p_fdcan_tx_handle->FDFormat = FDCAN_CLASSIC_CAN;                //传统的CAN模式
	p_fdcan_tx_handle->TxEventFifoControl = FDCAN_NO_TX_EVENTS;     //无发送事件
	p_fdcan_tx_handle->MessageMarker = 0;
	
  /* Request transmission */
  if(HAL_FDCAN_AddMessageToTxFifoQ(p_fdcan_handle, p_fdcan_tx_handle, can_handle->tx_buf) != HAL_OK)
  {
    /* Transmission request Error */
    //Error_Handler();
  }
  
  /* Wait transmission complete */
  //while(HAL_CAN_GetTxMailboxesFreeLevel(&CanHandle) != 3)
	//{
		//__nop();
	//}
}

void can_send_time_handle(void)//100ms
{
	if(0 == can_handle.tx_complete){
		can_handle.tx_timer_count++;
		if(can_handle.tx_timer_count > 2){
			can_handle.tx_timer_count = 0;
			can_handle.tx_complete = 1;
			
			HAL_FDCAN_Stop(&hfdcan2); 
			FDCAN2_Reinit();	
			/*
			HAL_Delay(5);
			HAL_FDCAN_Start(&hfdcan2);
			
			if(!READ_BIT(hfdcan2.Instance->CCCR, FDCAN_CCCR_DAR)){ 
				SET_BIT(hfdcan2.Instance->CCCR, FDCAN_CCCR_DAR);//NO AUTO retransmission
			}
			*/
		}
	}
}

void can_tx_task(void)
{
	if(can_handle.tx_msg_falg){
		if(can_handle.tx_complete){
			can_handle.tx_complete = 0;
			
			can_sent(&can_handle);
			
			can_handle.tx_msg_falg = 0;
		}
	}
}

void can_task(void)
{
	can_tx_task();
	
	fdcan_test_task();
}

void can_prm_init(void)
{
	can_handle.rx_complete = 0;
	
	can_handle.tx_msg_falg = 0;
	can_handle.tx_complete = 1;
}

void can_send_test(void)
{
	can_handle.tx_msg_falg = 1;
	
	can_handle.tx_cmd = CAN_EXTEND_ID;
	
	can_handle.tx_buf[0] = 0x01;
	can_handle.tx_buf[1] = 0x06;
	can_handle.tx_buf[2] = 0xF0;
	can_handle.tx_buf[3] = 0x55;
	can_handle.tx_buf[4] = 0xaa;
	can_handle.tx_buf[5] = 0xc0;
	can_handle.tx_buf[6] = 0x40;
	can_handle.tx_buf[7] = 0x88;
	
	can_handle.tx_len = 8;
	can_handle.tx_timer_count = 0;
}

unsigned int internal_can_send_data(unsigned int head, unsigned char * pdata, unsigned int len)
{
	unsigned int i = 0;
	if(len > 8)return 1;
	if(can_handle.tx_msg_falg)return 1;
	//if(!can_handle.tx_complete)return 1;
	if(!can_handle.tx_complete_delay_flag)return 1;
	
	can_handle.tx_msg_falg = 1;
	can_handle.tx_cmd = head;
	for(i=0;i<len;i++)
		can_handle.tx_buf[i] = pdata[i];
	
	can_handle.tx_complete_delay_tick = 0;
	can_handle.tx_complete_delay_flag = 0;
	
	can_handle.tx_len = len;
	can_handle.tx_timer_count = 0;
	return 0;
}

unsigned int get_can_tx_complete(void)
{
	//return can_handle.tx_complete;
	return can_handle.tx_complete_delay_flag;
}

unsigned int get_can_tx_complete_delay_flag(void)
{
	return can_handle.tx_complete_delay_flag;
}

void can_tx_complete_delay(void)//1ms
{
	if(can_handle.tx_complete){
		if(0 == can_handle.tx_complete_delay_flag){
			can_handle.tx_complete_delay_tick++;
			if(can_handle.tx_complete_delay_tick > 2){
				can_handle.tx_complete_delay_tick = 0;
				can_handle.tx_complete_delay_flag = 1;
			}
		}
	}
}

void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
{
	if(hfdcan == (&hfdcan2)){
		can_handle.tx_complete = 1;
	}
}

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
	unsigned int i=0;
	unsigned char rxdata[8];
	
	if(hfdcan == (&hfdcan2)){
		if((RxFifo0ITs&FDCAN_IT_RX_FIFO0_NEW_MESSAGE)!=RESET)   //FIFO1新数据中断
		{
			//提取FIFO0中接收到的数据
			HAL_FDCAN_GetRxMessage(hfdcan,FDCAN_RX_FIFO0,&FDCAN_RxHeader,can_handle.rx_buf);
			
			if(FDCAN_EXTENDED_ID == FDCAN_RxHeader.IdType){
				can_handle.rx_len = FDCAN_RxHeader.DataLength>>16;
				if(can_handle.rx_len <= 8){
					can_handle.rx_complete = 1;
					can_handle.rx_cmd = FDCAN_RxHeader.Identifier;
					LoadInnerCanRxMsg(can_handle.rx_cmd, can_handle.rx_buf, can_handle.rx_len);
					
					if(hw_test_mode){
						if(0xFA == (can_handle.rx_cmd & 0xFF)){
							if(0x23 == can_handle.rx_buf[3]){
								rx_text_buf[31] = 0xA5;
							}
						}
					}
				}
			}
			
			//HAL_FDCAN_ActivateNotification(hfdcan,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);
		}
	}
}

void fdcan_test_task(void)
{
	if(hw_test_mode){
		if(get_can_tx_complete_delay_flag()){
			if(0xA5 == rx_text_buf[31]){
				rx_text_buf[31] = 0;
				rx_text_buf[0] = 0xA0;
				rx_text_buf[1] = 0x02;
				rx_text_buf[2] = 0;
				rx_text_buf[3] = 0x23;
				rx_text_buf[4] = 1;
				internal_can_send_data(0xFA, rx_text_buf, 5);
			}
		}
	}
}

