/***********************************************************************
 * Copyright (c)  2017 - 2022, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : can_protocol.c
 * Description : can protocol file
 * Author(s)   : Mason
 * version     : V1.0
 * Modify date : 2022-08-05
 ***********************************************************************/
#include "can_protocol.h"

S_Can_Tx_Msg can_tx_msg;
S_Can_Rx_Msg can_rx_msg;
S_Can_Filter_Msg can_filter_msg;

/************************************************************************
 * Function     : can_data_frame
 * Description  : can data frame,帧组包 
 * Input        : uint32_t *buff：tx buff data
 *                uint8_t mode：standard frame or extended frame
 *                uint8_t rtr：data frame or remote frame
 *                uint8_t len：data length
 * Return       : none
 ************************************************************************/
void can_data_frame(uint32_t *buff, uint8_t mode, uint8_t rtr, uint8_t len)
{
	uint32_t temp = 0;
	
	can_tx_msg.len = len;
	can_tx_msg.rtr = rtr; 
	
	if(mode)						                                    //29bits扩展格式
	{
		can_tx_msg.ide = 1;			                                    //扩展模式设置为1
		                                      
		temp |= can_tx_msg.len;                                         //设置长度
		
		temp |= (can_tx_msg.ide << 7);                                  //设置IDE
		
		temp |= (can_tx_msg.rtr << 6);                                  //设置RTR
		//设置ID
		temp |= ((can_tx_msg.ext_id & 0x1FE00000)>> 13) | ((can_tx_msg.ext_id & 0x1FE000)<< 3) | ((can_tx_msg.ext_id & 0x1FE0)<< 19);
		
		buff[0] = temp;
		
		if(can_tx_msg.rtr == 0)                                         //数据帧
		{
			buff[1] = (can_tx_msg.rtr << 2) | ((can_tx_msg.ext_id & 0x1F) << 3) | (can_tx_msg.data[0]<< 8) | (can_tx_msg.data[1]<< 16) | (can_tx_msg.data[2]<< 24);
			buff[2] = (can_tx_msg.data[3]) | (can_tx_msg.data[4]<< 8) | (can_tx_msg.data[5]<< 16) | (can_tx_msg.data[6]<< 24);
			buff[3] = (can_tx_msg.data[7]);
		}
		else                                                            //遥控帧
		{
			buff[1] = (can_tx_msg.rtr << 2) | ((can_tx_msg.ext_id & 0x1F) << 3);
		}
		
	}
	else							                                    //11bits标准格式
	{
		can_tx_msg.ide = 0;			                                    //标准模式设置为0
		
		temp |= (can_tx_msg.ide << 7);                                  //设置IDE
		
		temp |= (((can_tx_msg.std_id & 0x7F8)<< 5) | ((can_tx_msg.std_id & 0x7)<< 21));//设置ID
		
		temp |= (can_tx_msg.rtr << 6) | (can_tx_msg.rtr << 20) ;        //设置RTR
		
		temp |= can_tx_msg.len;                                         //设置长度
		
		if(can_tx_msg.rtr == 0)                                         //数据帧
		{
			temp |= (can_tx_msg.data[0]<< 24);
	
			buff[0] = temp;
			buff[1] = (can_tx_msg.data[1]) | (can_tx_msg.data[2]<<8) | (can_tx_msg.data[3]<<16) | (can_tx_msg.data[4] <<24);
			buff[2] = (can_tx_msg.data[5]) | (can_tx_msg.data[6]<<8) | (can_tx_msg.data[7]<<16);
		}
		else                                                            //遥控帧
		{
			buff[0] = temp;
		}
	}
}

/************************************************************************
 * Function     : can_filter_value
 * Description  : can filter value,获取不同配置的过滤值
 * Input        : uint32_t *filter_value：filter value
 *                uint8_t filter_mode：single filter or double filter
 *                uint8_t data_mode：standard frame or extended frame
 * Return       : none
 ************************************************************************/
void can_filter_value(uint32_t *filter_value, uint8_t filter_mode, uint8_t data_mode)
{
	if(filter_mode)
	{
		if(data_mode == 0)		                                        //标准格式
		{
			
			*filter_value |= ((can_filter_msg.std_id1 & 0x7)<<13) | ((can_filter_msg.std_id1 & 0x7f8)>>3);	//设置标准ID
			*filter_value |= (can_filter_msg.rtr &0x01) << 12;	        //设置RTR
		}
		else					                                        //扩展格式
		{
			*filter_value |= ((can_filter_msg.ext_id1 & 0x1FE00000) >> 21) | ((can_filter_msg.ext_id1 & 0x1FE000) >> 5) | ((can_filter_msg.ext_id1 & 0x1FE0) << 11) | ((can_filter_msg.ext_id1 & 0x1F) << 27); //设置扩展ID
			*filter_value |= (can_filter_msg.rtr &0x01) << 26;	        //设置RTR
		}
	}
	else
	{
		if(data_mode == 0)		                                        //标准格式
		{
			*filter_value |= ((can_filter_msg.std_id1 & 0x7F8) >> 3) | ((can_filter_msg.std_id1 & 0x7) << 13); 	//filter1
			*filter_value |= ((can_filter_msg.rtr &0x01) << 12);
			
			*filter_value |= ((can_filter_msg.std_id2 & 0x7F8) << 13) | ((can_filter_msg.std_id2 & 0x7) << 29);	//filter2
			*filter_value |= ((can_filter_msg.rtr &0x01) << 28);			
		}
		else					                                        //扩展格式
		{
			*filter_value |=  ((can_filter_msg.ext_id1 & 0x1FE00000) >> 21) | ((can_filter_msg.ext_id1 & 0x1FE000) >> 5) ;	//filter1 只比对ID的bit28-bit13
			*filter_value |=  ((can_filter_msg.ext_id2 & 0x1FE00000) >> 5) | ((can_filter_msg.ext_id2 & 0x1FE000) << 11) ;	//filter2 只比对ID的bit28-bit13	
		}
	
	}
}

/************************************************************************
 * Function     : can_read_data_pro
 * Description  : nanlyze the receive data frame
 * Input        : uint32_t *buff: receive data
 * Return       : none
 ************************************************************************/
void can_read_data_pro(uint32_t *buff)
{
	uint32_t rx_data;
	
	rx_data = buff[0];			                                        //读第一次RX FIFO

	if(can_rx_msg.ide)				                                    //扩展格式
	{
		can_rx_msg.ext_id = ((rx_data & 0xFF00)<<13) | ((rx_data & 0xFF0000)>>3) | ((rx_data & 0xFF000000)>>19); //获取id
		rx_data = buff[1];			                                    //读第二次RX FIFO
		can_rx_msg.ext_id |= ((rx_data & 0xF8)>>3);	                    //获取ID
		
		can_rx_msg.data[0] = (uint8_t)((rx_data & 0xFF00) >> 8);
		can_rx_msg.data[1] = (uint8_t)((rx_data & 0xFF0000) >> 16);
		can_rx_msg.data[2] = (uint8_t)((rx_data & 0xFF000000) >> 24);
		
		if(can_rx_msg.len >= 8)
		{
			rx_data = buff[2];		                                    //读第三次RX FIFO
			can_rx_msg.data[3] = (uint8_t)(rx_data);
			can_rx_msg.data[4] = (uint8_t)((rx_data & 0xFF00) >> 8);
			can_rx_msg.data[5] = (uint8_t)((rx_data & 0xFF0000) >> 16);
			can_rx_msg.data[6] = (uint8_t)((rx_data & 0xFF000000) >> 24);
			
			rx_data = buff[3];		                                    //读第四次RX FIFO
			can_rx_msg.data[7] = (uint8_t)(rx_data);
		}
		else if(can_rx_msg.len >= 4)
		{
			rx_data = buff[2];		                                    //读第三次RX FIFO
			can_rx_msg.data[3] = (uint8_t)(rx_data);
			can_rx_msg.data[4] = (uint8_t)((rx_data & 0xFF00) >> 8);
			can_rx_msg.data[5] = (uint8_t)((rx_data & 0xFF0000) >> 16);
			can_rx_msg.data[6] = (uint8_t)((rx_data & 0xFF000000) >> 24);
		}
	}
	else							                                    //标准格式
	{
		can_rx_msg.std_id = ((rx_data & 0xFF00)>>5) | ((rx_data & 0xE00000)>>21);	//获取id
		can_rx_msg.data[0] = (uint8_t)((rx_data & 0xFF000000) >> 24);
		
		if(can_rx_msg.len >= 6)
		{
			rx_data = buff[1];		                                    //读第二次RX FIFO
			can_rx_msg.data[1] = (uint8_t)((rx_data & 0xFF));
			can_rx_msg.data[2] = (uint8_t)(((rx_data >> 8) & 0xFF));
			can_rx_msg.data[3] = (uint8_t)(((rx_data >> 16) & 0xFF));
			can_rx_msg.data[4] = (uint8_t)(((rx_data >> 24) & 0xFF));
			
			rx_data = buff[2];		                                    //读第三次RX FIFO
			can_rx_msg.data[5] = (uint8_t)((rx_data & 0xFF));
			can_rx_msg.data[6] = (uint8_t)(((rx_data >> 8) & 0xFF));
			can_rx_msg.data[7] = (uint8_t)(((rx_data >> 16) & 0xFF));
		}
		else
		{
			rx_data = buff[1];		                                    //读第二次RX FIFO
			can_rx_msg.data[1] = (uint8_t)((rx_data & 0xFF));
			can_rx_msg.data[2] = (uint8_t)(((rx_data >> 8) & 0xFF));
			can_rx_msg.data[3] = (uint8_t)(((rx_data >> 16) & 0xFF));
			can_rx_msg.data[4] = (uint8_t)(((rx_data >> 24) & 0xFF));
		}
	}
}	
