#include "common.h"
#include "drv_can.h"

//********************************************************CAN-START**********************************************************
static uint8_t can_tx_buf[CAN_TX_BUF_MAX];
static uint8_t can_rx_buf[CAN_RX_BUF_MAX];
static uint16_t tx_count = 0,rx_count = 0,tx_buf_size = 0;

static uint16_t can_filter_id_array[CAN_FILTER_ID_MAX];


static void Reset_Can_Rx_Buffer(void)
{
    memset(can_rx_buf,0x00,sizeof(can_rx_buf));
    rx_count = 0;
}

uint16_t Get_Data_Can(uint8_t * dbuf,uint16_t dbuf_len)
{
    if(dbuf == NULL || dbuf_len < rx_count)
        return 0;

    memcpy(dbuf,can_rx_buf,rx_count);
    dbuf_len = rx_count;
    Reset_Can_Rx_Buffer();

    return dbuf_len;
    
}

uint8_t Send_One_Frame_Can(uint8_t *data,uint8_t data_len)
{
	CanTxMsg TxMessage;
	
	if(data == NULL || data_len == 0 || data_len > 8)
		return 0;

	/* Transmit */
    TxMessage.StdId = SUR_ID;
    TxMessage.ExtId = 0x00;
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.IDE = CAN_ID_STD;
    TxMessage.DLC = data_len;
	memcpy(TxMessage.Data,data,data_len);

	return CAN_Transmit(CAN1,&TxMessage);
		
}

#define test_1
int8_t Send_Data_Can(uint8_t *data,uint16_t size)
{
   
#ifdef test_1
	if(data == NULL ||size == 0 || size > sizeof(can_tx_buf))
	    return 0;

	memset(can_tx_buf,0xFA,CAN_FRAME_START_LEN);
	Send_One_Frame_Can(can_tx_buf,(uint8_t)CAN_FRAME_START_LEN);
	
	memcpy(can_tx_buf,data,size);
	tx_count = 0;
	tx_buf_size = size;
	CAN_ITConfig(CAN1, CAN_IT_TME,ENABLE);
	
#else
	if(data == NULL ||size == 0 || size + CAN_FRAME_START_LEN > sizeof(can_tx_buf))
	    return 0;

	memset(can_tx_buf,0xFA,CAN_FRAME_START_LEN);
	memcpy(&can_tx_buf[CAN_FRAME_START_LEN],data,size);
	tx_count = 0;
	tx_buf_size = size + CAN_FRAME_START_LEN;
	CAN_ITConfig(CAN1, CAN_IT_TME,ENABLE);
#endif


    

    return 1;
    
}
static void Can_NVIC_Config(void)
{
	NVIC_InitTypeDef  NVIC_InitStructure;

	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;

	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

static int8_t CAN_Set_Filter(uint16_t f_id)
{
	uint8_t f_index;
	CAN_FilterInitTypeDef  CAN_FilterInitStructure;

	if(f_id == 0)
		return 0;

	for(f_index = 0; f_index < CAN_FILTER_ID_MAX;f_index++)
	{
		if(can_filter_id_array[f_index] == 0)
		{
			can_filter_id_array[f_index] = f_id;
			break;
		}
	}

	if(f_index >= CAN_FILTER_ID_MAX)
		return 0;
	
	/* CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = f_index;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = (can_filter_id_array[f_index]<<5);
    CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;//0xFFFF;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;//0xFFFF;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

	return 1;
	
}

void CAN_GPIO_Initial(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    /* Configure CAN pin: RX */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* Configure CAN pin: TX */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
   // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);

		//cs
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
	Silent_Enable(0);
	
}

void CAN_Initial(void)
{
	CAN_InitTypeDef        CAN_InitStructure;

	 /* GPIO clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
 
    /* CANx Periph clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);


    /* CAN register init */
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    /* CAN cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

    /* CAN Baudrate = 1MBps*/
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
    CAN_InitStructure.CAN_Prescaler = 4;
    CAN_Init(CAN1, &CAN_InitStructure);
	
}
/**
  * @brief  Configures the CAN.
  * @param  None
  * @retval None
  */
void CAN_Config(void)
{   
	//nt8_t f_index = 0;
	//nt16_t f_id = 2;
	#if 1
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    /* Configure CAN pin: RX */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* Configure CAN pin: TX */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
   // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);

	//cs
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
	Silent_Enable(0);
#else
	//CAN_GPIO_Initial();
#endif
	//CAN_Initial();

	CAN_InitTypeDef        CAN_InitStructure;

	 /* GPIO clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
 
    /* CANx Periph clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);


    /* CAN register init */
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    /* CAN cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

    /* CAN Baudrate = 1MBps*/
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
    CAN_InitStructure.CAN_Prescaler = 4;
    CAN_Init(CAN1, &CAN_InitStructure);
#if 0
	//memset(can_filter_id_array,0x00,sizeof(can_filter_id_array));
    //CAN_Set_Filter(2);
    //uint8_t f_index = 0;
	//uint16_t f_id = 2;
	CAN_FilterInitTypeDef  CAN_FilterInitStructure;

	/*if(f_id == 0)
		return ;

	for(f_index = 0; f_index < CAN_FILTER_ID_MAX;f_index++)
	{
		if(can_filter_id_array[f_index] == 0)
		{
			can_filter_id_array[f_index] = f_id;
			break;
		}
	}

	if(f_index >= CAN_FILTER_ID_MAX)
		return ;*/
	
	/* CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = (2<<5);
    CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;//0xFFFF;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;//0xFFFF;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
#else
	CAN_FilterInitTypeDef  CAN_FilterInitStructure;
	/* CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = (DIS_ID<<5);
    CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

	CAN_FilterInitStructure.CAN_FilterNumber = 1;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = (2<<5);
    CAN_FilterInitStructure.CAN_FilterIdLow = (CAN_ID_STD|CAN_RTR_DATA);
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
#endif
	

    Can_NVIC_Config();

    CAN_ITConfig(CAN1, CAN_IT_FMP0,ENABLE);
    

	
    
}


void USB_HP_CAN1_TX_IRQHandler(void)
{
	uint8_t data[8];
	uint16_t data_len;
	
	if(CAN_GetITStatus(CAN1,CAN_IT_TME) != RESET)
	{
		CAN_ClearITPendingBit(CAN1,CAN_IT_TME);

        if(tx_count >= tx_buf_size)
        {
			memset(data,0xFB,CAN_FRAME_END_LEN);
            Send_One_Frame_Can(data,CAN_FRAME_END_LEN);
		    CAN_ITConfig(CAN1, CAN_IT_TME,DISABLE);
			return;
        }

#ifdef test_1

		data_len = tx_buf_size - tx_count;
		if(data_len > sizeof(data))
		{
			data_len = sizeof(data);
		}
#else
		if(tx_count == 0)
			data_len = CAN_FRAME_START_LEN;
		else
		{
			data_len = tx_buf_size - tx_count;
			if(data_len > sizeof(data))
			{
				data_len = sizeof(data);
			}
		}
#endif		
		memcpy(data,&can_tx_buf[tx_count],data_len);
		Send_One_Frame_Can(data,(uint8_t)data_len);
		tx_count += data_len;
		
	}
}

void USB_LP_CAN1_RX0_IRQHandler(void)
{
	CanRxMsg Rxmessage;
	uint8_t data[8];
	
	CAN_Receive(CAN1, CAN_FIFO0, &Rxmessage);

	if(Rxmessage.DLC == CAN_FRAME_START_LEN)
	{
		memset(data,0xFA,CAN_FRAME_START_LEN);
		if(memcmp(Rxmessage.Data,data,CAN_FRAME_START_LEN) == 0)
		{
			rx_count = 0;
			return;
		}
	}

	if(Rxmessage.DLC == CAN_FRAME_END_LEN)
	{
		memset(data,0xFB,CAN_FRAME_END_LEN);
		if(memcmp(Rxmessage.Data,data,CAN_FRAME_END_LEN) == 0)
		{
			g_event |= EVENT_CAN_RECEIVE_FINISH;
			return;
		}
	}

	if(rx_count + Rxmessage.DLC >= sizeof(can_rx_buf))
	{
		return;
	}
	memcpy(&can_rx_buf[rx_count],Rxmessage.Data,Rxmessage.DLC);
	rx_count += Rxmessage.DLC;
	
}








//********************************************************CAN-END**********************************************************







