/**
  **********************************************************************************
             Copyright(c) 2021 China Core Co. Ltd.
                      All Rights Reserved
  **********************************************************************************
  *@file    can_drv.c
  *@author  Product application department
  *@version V1.0
  *@date    2021.09.27
  *@brief   CAN模块DRV层驱动.
  *
  @verbatim
  ===================================================================================
                                  ##### 更新 #####
  ===================================================================================
  [..] 更新时间:
  [..] 更新人:
  [..] 更新内容:
        1. nothing.
  @endverbatim
*/

#include "can_drv.h"
#include "debug.h"

#define CAN_RX_MAX_MSG   10//8

/*** 全局变量定义 ***************************************************************/
/**@ volatile
  *@{
  */
volatile UINT32 gCanErrFlag = 0;
volatile UINT32 gCanIFlag1  = 0;
volatile UINT32 gCanIFlag2  = 0;
volatile UINT32 gCanFifoEnable = 0;
volatile CanRxMsgTypeDef gCanRxmsg[CAN_RX_MAX_MSG];
volatile UINT32 gCanFifoRxLen = 0;

u8 canDataBuf[8];
CanRxBufStruct gCantRx;
volatile CanRxMsgTypeDef gCantRxMsg;

/**@
  *@}
  */
/**@ static
  *@{
  */
/*global array for bitrate parameters*/
static can_timeseg a_TimeSegments[18] = {
    {1, 2, 1},  /* 0: total 8 timequanta */
    {1, 2, 2},  /* 1: total 9 timequanta */
    {2, 2, 2},  /* 2: total 10 timequanta */
    {2, 2, 3},  /* 3: total 11 timequanta */
    {2, 3, 3},  /* 4: total 12 timequanta */
    {3, 3, 3},  /* 5: total 13 timequanta */
    {3, 3, 4},  /* 6: total 14 timequanta */
    {3, 4, 4}, 	/* 7: total 15 timequanta */
    {4, 4, 4}, 	/* 8: total 16 timequanta */
    {4, 4, 5}, 	/* 9: total 17 timequanta */
    {4, 5, 5}, 	/* 10: total 18 timequanta */
    {5, 5, 5}, 	/* 11: total 19 timequanta */
    {5, 5, 6}, 	/* 12: total 20 timequanta */
    {5, 6, 6}, 	/* 13: total 21 timequanta */
    {6, 6, 6}, 	/* 14: total 22 timequanta */
    {6, 6, 7}, 	/* 15: total 23 timequanta */
    {6, 7, 7}, 	/* 16: total 24 timequanta */
    {7, 7, 7} 	/* 17: total 25 timequanta */
};

/**@
  *@}
  */
/*** 常量定义 *******************************************************************/
/**@ const
  *@{
  */

/**@
  *@}
  */
/**
  *@brief CAN software reset
  *
  *@param[in] 
  *@param[in] 
  *@return 无
  *@note 
  */	
DRV_CAN_StatusTypeDef DRV_CAN_SoftReset(CAN_TypeDef *pcan)
{
  _can_en_soft_rst(pcan);   
	while((pcan->CAN_MCR & CAN_MCR_SOFT_RST) != 0);
	return(DRV_CAN_OK);
}

/**
 *@brief 管脚切换为SPI功能
 *
 *@param[in] pspi 指向CAN_TypeDef的指针;
 *@return  无;
 */
void DRV_CAN_FuncSwap(CAN_TypeDef *pcan)
{
    if (pcan == CAN1)
    {
        //_ioctrl_swap4cr_swap_dis(IOCTRL_SWAP7);//0 = swap disable.(uart function enable.)
			  //_ioctrl_swap4cr_swap_dis(IOCTRL_SWAP8);//0 = swap disable.(uart function enable.)
			  _ioctrl_swapcr_swap_en(IOCTRL_SWAP24); //1 = swap enable.(can_tx function enable.)
			  _ioctrl_swapcr_swap_en(IOCTRL_SWAP25); //1 = swap enable.(can_tx function enable.)	  
    }
    else 
			return;
}

/**
 *@brief 恢复CAN为默认设置.
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@return  无;
 */
void DRV_CAN_DeInit(CAN_TypeDef *pcan)
{
    uint8_t i,j;
    pcan->CAN_MCR = 0x5980000F;
    pcan->CAN_CR = 0;
    pcan->CAN_ECR = 0;
    pcan->CAN_ESR = 0;
    pcan->CAN_FRT = 0;
    pcan->CAN_IF1R = 0;
    pcan->CAN_IF2R = 0;
    pcan->CAN_IM1R = 0;
    pcan->CAN_IM2R = 0;
    pcan->CAN_RXGM = 0xFFFFFFFF;
    pcan->CAN_RX14M = 0xFFFFFFFF;
    pcan->CAN_RX15M = 0xFFFFFFFF;
    for (i = 0; i < 63; i++)
    {
        pcan->CAN_MB[0].MB_CS = 0;
        pcan->CAN_MB[0].MB_ID = 0;
        for (j = 0; j < 8; j++)
        {
            pcan->CAN_MB[0].MB_DATA[0] = 0;
        }
    }
		gCanIFlag1 = 0;
		gCanIFlag2 = 0;
		gCanFifoRxLen = 0;
		gCanFifoEnable = 0;
}


/**
 *@brief 初始化CAN模块.
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@param[in] Init 指向SPI_InitTypeDef的指针;
 *@return  初始化结果; @ref DRV_CAN_StatusTypeDef
 */
DRV_CAN_StatusTypeDef DRV_CAN_Init(CAN_TypeDef *pcan, CAN_InitTypeDef *Init)
{
    uint8_t  ucIndex0 = 0;
    uint8_t  ucIndex1 = 0;
    uint32_t i = 0;
    uint32_t ulRegTmp = 0;
    uint8_t  ucPresDiv = 0;
		can_timeseg* pTimeSeg = 0;
    uint32_t clk_ratio = Init->IPSFreq/Init->BitRate;
    CAN_RxIndividualMask_TypeDef *pCanRxMaskRegs;

    DRV_CAN_FuncSwap(pcan);

    if (pcan == CAN1)
    {
        pCanRxMaskRegs = (CAN_RxIndividualMask_TypeDef*)(CAN1_BASE_ADDR + CAN_RXIMR_ADDR_OFFSET);
    }
    else
    {
        return DRV_CAN_ERROR;
    }
		if (Init->FEN == ENABLE)
			gCanFifoEnable = 1;
		else
			gCanFifoEnable = 0;
    gCanFifoRxLen = 0;	
    /* select peripheral clock */
    _can_select_peripheral_clock(pcan);
		
		/*exit module disable mode*/
    _can_dis_module_disable_mode(pcan);
		
		DRV_CAN_SoftReset(pcan);
  
    _can_select_normal_mode(pcan);
    /* enable the generation of transmit and receive warning */
    _can_en_generate_wrn_int_flag(pcan);
    /* support backwards compatibility */
    _can_en_support_previous_versions(pcan);
		
    /* enable all the MBs */
    _can_en_all_message_buffers(pcan);

    if (Init->FEN == ENABLE)
    {
        _can_en_fifo(pcan);
    }
    else
    {
        _can_dis_fifo(pcan);
    }
    
    /*clear all the MBs and their mask to 0*/
	for (ucIndex0 = 0; ucIndex0 < CAN_BUFFER_NUM; ucIndex0++)
	{
		if (ucIndex0 < 32)
    {
        pcan->CAN_MB[ucIndex0].MB_CS = 0;
    }
		else
    {
        pcan->CAN_MB[ucIndex0].MB_CS = 0x08000000;
    }
    pcan->CAN_MB[ucIndex0].MB_ID = 0;
		for (ucIndex1 = 0; ucIndex1 < 8; ucIndex1++)
		{
			pcan->CAN_MB[ucIndex0].MB_DATA[ucIndex1] = 0;
		}
		pCanRxMaskRegs->CAN_RXIMR[ucIndex0] = 0;
	}
    
 	for (i = 8; i <= 25; i++)
	{
		if (0 == (clk_ratio % i))
		{
			pTimeSeg = &a_TimeSegments[i-8];
			ucPresDiv =  clk_ratio / i - 1;
			break;
		}
	}   
    
	if (i >= 26)
	{
	   return DRV_CAN_ERROR;
	}
    
	ulRegTmp     = pcan->CAN_CR;
	ulRegTmp    &= CAN_TIMING_MASK;
	pcan->CAN_CR = ulRegTmp | (ucPresDiv << 24) |(pTimeSeg->m_pseg1 << 19) | (pTimeSeg->m_pseg2 << 16) | (pTimeSeg->m_propseg);    
  
	gCanIFlag1 = 0;
	gCanIFlag2 = 0;
	
  return DRV_CAN_OK;
}


/**
 *@brief CAN发送数据
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@param[in] pBuf 数据指针;
 *@param[in] Size 送数据长度;
 *@return 操作结果; @ref DRV_CAN_StatusTypeDef
 */
DRV_CAN_StatusTypeDef DRV_CAN_TransmitBytes(CAN_TypeDef *pcan, CanTxMsgTypeDef *pTxmsg, uint32_t Timeout)
{
	uint8_t ucIndex;
  uint8_t ucMBID = 0;
	uint32_t ulWaitCnt = 0;


	 /* check MB is valid or not
	 * if valid, clear the flag;if not, Wait for some time
	 * */
    for (ucMBID = 0; ucMBID < 32; ucMBID++)
    {
        if (((pcan->CAN_MB[ucMBID + 32].MB_CS & 0x0f000000) == CAN_TXCODE_INACT))
        {
            break;
        }
        else
        {
            ucMBID++;
        }
        
        if (ucMBID >= 32)
        {
            ucMBID = 0;
            if (Timeout != 0)
            {
                ulWaitCnt++;
                if (ulWaitCnt > Timeout)
                {
                    return DRV_CAN_TIMEOUT;
                }
            }
        }
    }
    
    /*clear the MB interrupt flag*/
    pcan->CAN_IF2R |= 1 << ucMBID;
    
    /*disable the MB interrupt*/
    pcan->CAN_IM2R &= ~(1 << ucMBID);

		/*store data in the MB*/
		for(ucIndex = 0; ucIndex < pTxmsg->DLC; ucIndex++)
		{
			pcan->CAN_MB[ucMBID + 32].MB_DATA[ucIndex] = pTxmsg->Data[ucIndex];
		}

		/*configure the MB to send an extended data frame*/
		if(pTxmsg->IDE == DRV_CAN_ID_EXT)
		{
			pcan->CAN_MB[ucMBID + 32].MB_ID = pTxmsg->ExtId;
			pcan->CAN_MB[ucMBID + 32].MB_CS = CAN_TXCODE_ONCE | pTxmsg->RTR | CAN_MBS_IDE | CAN_MBS_SRR | (pTxmsg->DLC << 16);
		}
		/*configure the MB to send an standard data frame*/
		else
		{
			pcan->CAN_MB[ucMBID + 32].MB_ID = pTxmsg->StdId << 18;
			pcan->CAN_MB[ucMBID + 32].MB_CS = CAN_TXCODE_ONCE | pTxmsg->RTR | (pTxmsg->DLC << 16);
		}

		/*exit Freeze Mode*/
		pcan->CAN_MCR &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);
		

		/*wait trans done*/
		while((pcan->CAN_IF2R &= 1 << ucMBID) != 1 << ucMBID);
		
		pcan->CAN_IF2R |= 1 << ucMBID;
			
		/*send successfully*/
		return DRV_CAN_OK;
}

/**
 *@brief CAN中断发送数据
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@param[in] pBuf 数据指针;
 *@param[in] Size 送数据长度;
 *@return 操作结果; @ref DRV_CAN_StatusTypeDef
 */
DRV_CAN_StatusTypeDef DRV_CAN_TransmitBytesIT(CAN_TypeDef *pcan, CanTxMsgTypeDef *pTxmsg, uint32_t Timeout)
{
	uint8_t ucIndex;
  uint8_t ucMBID = 0;
	uint32_t ulWaitCnt = 0;


	 /* check MB is valid or not
	 * if valid, clear the flag;if not, Wait for some time
	 * */
    for (ucMBID = 0; ucMBID < 32; ucMBID++)
    {
        if (((pcan->CAN_MB[ucMBID + 32].MB_CS & 0x0f000000) == CAN_TXCODE_INACT))
        {
            break;
        }
        else
        {
            ucMBID++;
        }
        
        if (ucMBID >= 32)
        {
            ucMBID = 0;
            if (Timeout != 0)
            {
                ulWaitCnt++;
                if (ulWaitCnt > Timeout)
                {
                    return DRV_CAN_TIMEOUT;
                }
            }
        }
    }
    
    /*clear the MB interrupt flag*/
    pcan->CAN_IF2R |= 1 << ucMBID;
    
    /*disable the MB interrupt*/
    pcan->CAN_IM2R &= ~(1 << ucMBID);

		/*store data in the MB*/
		for(ucIndex = 0; ucIndex < pTxmsg->DLC; ucIndex++)
		{
			pcan->CAN_MB[ucMBID + 32].MB_DATA[ucIndex] = pTxmsg->Data[ucIndex];
		}

		/*configure the MB to send an extended data frame*/
		if(pTxmsg->IDE == DRV_CAN_ID_EXT)
		{
			pcan->CAN_MB[ucMBID + 32].MB_ID = pTxmsg->ExtId;
			pcan->CAN_MB[ucMBID + 32].MB_CS = CAN_TXCODE_ONCE | pTxmsg->RTR | CAN_MBS_IDE | CAN_MBS_SRR | (pTxmsg->DLC << 16);
		}
		/*configure the MB to send an standard data frame*/
		else
		{
			pcan->CAN_MB[ucMBID + 32].MB_ID = pTxmsg->StdId << 18;
			pcan->CAN_MB[ucMBID + 32].MB_CS = CAN_TXCODE_ONCE | pTxmsg->RTR | (pTxmsg->DLC << 16);
		}

		/*enable the MB interrupt*/
    pcan->CAN_IM2R |= (1 << ucMBID);
		
		/*exit Freeze Mode*/
		pcan->CAN_MCR &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);
		


		/*wait trans done*/
		//while((pcan->CAN_IF2R &= 1 << ucMBID) != 1 << ucMBID);
		while((gCanIFlag2 &= 1 << ucMBID) != 1 << ucMBID);	
		gCanIFlag2 |= 1 << ucMBID;
			
		/*send successfully*/
		return DRV_CAN_OK;
}


/**
 *@brief CAN接收数据
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@param[in] pBuf 数据指针;
 *@param[in] Size 送数据长度;
 *@return 操作结果; @ref DRV_CAN_StatusTypeDef
 */
DRV_CAN_StatusTypeDef DRV_CAN_ReceiveBytes(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg, uint32_t rx_num, uint32_t Timeout)
{
	uint8_t ucIndex;
   uint32_t i;
	//uint32_t ulWaitCnt = 0;
   CAN_RxIndividualMask_TypeDef *pCanRxMaskRegs;
//   CAN_RxFifoIDTable_TypeDef *pCanFifoIDtable;
    
    if (pcan == CAN1)
    {
//        pCanRxMaskRegs = (CAN_RxIndividualMask_TypeDef *)(CAN1_BASE_ADDR + CAN_RXIMR_ADDR_OFFSET);
//        pCanFifoIDtable = (CAN_RxFifoIDTable_TypeDef *)(CAN1_BASE_ADDR + CAN_FIFO_ID_TABLE_ADDR_OFFSET);
    }
    else
    {
        return DRV_CAN_ERROR;
    }

	/*Can must enter freeze mode before updating RX individual mask*/
	pcan->CAN_MCR |= CAN_MCR_HALT;
	while((pcan->CAN_MCR & CAN_MCR_FRZ_ACK) == 0){};
    
	/*set RX individual mask*/
	pCanRxMaskRegs->CAN_RXIMR[pRxmsg->MBID] = pRxmsg->RXIM;
    
    /*clear the MB interrupt flag  */
    pcan->CAN_IF1R |= 1 << pRxmsg->MBID;  
        
    /*disable the MB interrupt*/
    pcan->CAN_IM1R &= ~(1 << pRxmsg->MBID);
    
    /*configure the MB to send an extended data frame*/
    if(pRxmsg->IDE == DRV_CAN_ID_EXT)
    {
        pcan->CAN_MB[pRxmsg->MBID].MB_ID = pRxmsg->ExtId;
        pcan->CAN_MB[pRxmsg->MBID].MB_CS = CAN_RXCODE_EMPTY | CAN_MBS_IDE | CAN_MBS_SRR;
    }
    /*configure the MB to send an standard data frame*/
    else
    {
        pcan->CAN_MB[pRxmsg->MBID].MB_ID = pRxmsg->StdId << 18;
        pcan->CAN_MB[pRxmsg->MBID].MB_CS = CAN_RXCODE_EMPTY;
    }     

    /*exit Freeze Mode*/
    pcan->CAN_MCR &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);

    for (i = 0; i < rx_num; i++)
    {
        /*wait the MB interrupt flag */
        while((pcan->CAN_IF1R & (1 << pRxmsg->MBID)) != (1 << pRxmsg->MBID));
        pcan->CAN_IF1R |= 1 << pRxmsg->MBID; 
        
        if (pRxmsg->IDE == DRV_CAN_ID_STD)
        {
            pRxmsg->StdId = pcan->CAN_MB[pRxmsg->MBID].MB_ID >> 18;
        }
        else
        {
            pRxmsg->ExtId = pcan->CAN_MB[pRxmsg->MBID].MB_ID;
        }
        
        pRxmsg->DLC = (pcan->CAN_MB[pRxmsg->MBID].MB_CS >> 16)&0x0f;
        /*read data in the MB*/
        for(ucIndex = 0; ucIndex < pRxmsg->DLC; ucIndex++)
        {
            pRxmsg->Data[ucIndex] = pcan->CAN_MB[pRxmsg->MBID].MB_DATA[ucIndex];
        }         
    }
 
	/*recieve successfully*/
	return DRV_CAN_OK;
}


/**
 *@brief CAN中断接收数据
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@param[in] pBuf 数据指针;
 *@param[in] Size 送数据长度;
 *@return 操作结果; @ref DRV_CAN_StatusTypeDef
 */
DRV_CAN_StatusTypeDef DRV_CAN_ReceiveBytesIT(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg, uint32_t rx_num, uint32_t Timeout)
{
		uint8_t ucIndex;
    uint32_t i;
	//	uint32_t ulWaitCnt = 0;
    CAN_RxIndividualMask_TypeDef *pCanRxMaskRegs;
    CAN_RxFifoIDTable_TypeDef *pCanFifoIDtable;
    
    if (pcan == CAN1)
    {
        pCanRxMaskRegs = (CAN_RxIndividualMask_TypeDef *)(CAN1_BASE_ADDR + CAN_RXIMR_ADDR_OFFSET);
        pCanFifoIDtable = (CAN_RxFifoIDTable_TypeDef *)(CAN1_BASE_ADDR + CAN_FIFO_ID_TABLE_ADDR_OFFSET);
    }
    else
    {
        return DRV_CAN_ERROR;
    }

		/*Can must enter freeze mode before updating RX individual mask*/
		pcan->CAN_MCR |= CAN_MCR_HALT;
		while((pcan->CAN_MCR & CAN_MCR_FRZ_ACK) == 0){};
			
		/*set RX individual mask*/
		pCanRxMaskRegs->CAN_RXIMR[pRxmsg->MBID] = pRxmsg->RXIM;
    
    /*clear the MB interrupt flag  */
    pcan->CAN_IF1R |= 1 << pRxmsg->MBID;  
        
    /*disable the MB interrupt*/
    pcan->CAN_IM1R &= ~(1 << pRxmsg->MBID);
    
    /*configure the MB to send an extended data frame*/
    if(pRxmsg->IDE == DRV_CAN_ID_EXT)
    {
        pcan->CAN_MB[pRxmsg->MBID].MB_ID = pRxmsg->ExtId;
        pcan->CAN_MB[pRxmsg->MBID].MB_CS = CAN_RXCODE_EMPTY | CAN_MBS_IDE | CAN_MBS_SRR;
    }
    /*configure the MB to send an standard data frame*/
    else
    {
        pcan->CAN_MB[pRxmsg->MBID].MB_ID = pRxmsg->StdId << 18;
        pcan->CAN_MB[pRxmsg->MBID].MB_CS = CAN_RXCODE_EMPTY;
    }     

		/*enable the MB interrupt*/
    pcan->CAN_IM1R |= (1 << pRxmsg->MBID);
		
    /*exit Freeze Mode*/
    pcan->CAN_MCR &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);

    for (i = 0; i < rx_num; i++)
    {
        /*wait the MB interrupt flag */
			  while((gCanIFlag1& (1 << pRxmsg->MBID)) != (1 << pRxmsg->MBID)){};
        gCanIFlag1 &= ~(1 << pRxmsg->MBID); 
        
        if (pRxmsg->IDE == DRV_CAN_ID_STD)
        {
            pRxmsg->StdId = pcan->CAN_MB[pRxmsg->MBID].MB_ID >> 18;
        }
        else
        {
            pRxmsg->ExtId = pcan->CAN_MB[pRxmsg->MBID].MB_ID;
        }
        
        pRxmsg->DLC = (pcan->CAN_MB[pRxmsg->MBID].MB_CS >> 16)&0x0f;
        /*read data in the MB*/
        for(ucIndex = 0; ucIndex < pRxmsg->DLC; ucIndex++)
        {
            pRxmsg->Data[ucIndex] = pcan->CAN_MB[pRxmsg->MBID].MB_DATA[ucIndex];
        }         
    }
 
	/*recieve successfully*/
	return DRV_CAN_OK;
}


/**
 *@brief CAN接收数据
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@param[in] pBuf 数据指针;
 *@param[in] Size 送数据长度;
 *@return 操作结果; @ref DRV_CAN_StatusTypeDef
 */
DRV_CAN_StatusTypeDef DRV_CAN_FIFO_ReceiveBytes(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg,uint32_t rx_num ,uint32_t Timeout)
{
	  uint8_t ucIndex;
	uint32_t i;
//	  uint32_t ulWaitCnt = 0;
    CAN_RxIndividualMask_TypeDef *pCanRxMaskRegs;
    CAN_RxFifoIDTable_TypeDef *pCanFifoIDtable;
    
    if (pcan == CAN1)
    {
        pCanRxMaskRegs = (CAN_RxIndividualMask_TypeDef *)(CAN1_BASE_ADDR + CAN_RXIMR_ADDR_OFFSET);
        pCanFifoIDtable = (CAN_RxFifoIDTable_TypeDef *)(CAN1_BASE_ADDR + CAN_FIFO_ID_TABLE_ADDR_OFFSET);
    }
    else
    {
        return DRV_CAN_ERROR;
    }

		/*Can must enter freeze mode before updating RX individual mask*/
		pcan->CAN_MCR |= CAN_MCR_HALT;
		while((pcan->CAN_MCR & CAN_MCR_FRZ_ACK) == 0){};
			
		/*set RX individual mask*/
		pCanRxMaskRegs->CAN_RXIMR[pRxmsg[0].MBID] = pRxmsg->RXIM;

    /*clear the FIFO interrupt flag  */
    pcan->CAN_IF1R |=  CAN_IF1R_RX_FIFO_FLAG;   
			
    /*disable FIFO interrupt*/
    pcan->CAN_IM1R &= CAN_IM1R_RX_FIFO_INT_MASK;
    
    /*configure FIFO to receive extended frames*/
    if(pRxmsg[0].IDE == DRV_CAN_ID_EXT)
    {
        pCanFifoIDtable->ID_TABLE[pRxmsg[0].MBID] = (pRxmsg[0].ExtId << 1) | CAN_FIFO_EXT_MSK;
    }
    /*configure FIFO to receive standard frames*/
    else
    {
        pCanFifoIDtable->ID_TABLE[pRxmsg[0].MBID] = (pRxmsg[0].StdId << 19);
    }
    /*exit Freeze Mode*/
    pcan->CAN_MCR &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);

    for (i = 0; i < rx_num; i++)
    {    
        /*wait the MB interrupt flag */
        while((pcan->CAN_IF1R & CAN_IF1R_RX_FIFO_FLAG) != CAN_IF1R_RX_FIFO_FLAG);
        
        pRxmsg[i].IDE = (pcan->CAN_MB[0].MB_CS >> 21)&0x1;
        
        if (pRxmsg[i].IDE == DRV_CAN_ID_STD)
        {
            pRxmsg[i].StdId = pcan->CAN_MB[0].MB_ID >> 18;
        }
        else
        {
             pRxmsg[i].ExtId = pcan->CAN_MB[0].MB_ID;
        }
        
         pRxmsg[i].DLC = (pcan->CAN_MB[0].MB_CS >> 16)&0x0f;
        /*read data in the MB*/
        for(ucIndex = 0; ucIndex < pRxmsg[i].DLC; ucIndex++)
        {
             pRxmsg[i].Data[ucIndex] = pcan->CAN_MB[0].MB_DATA[ucIndex];
        }         
         
        /*clear the FIFO interrupt flag  */
        pcan->CAN_IF1R |=  CAN_IF1R_RX_FIFO_FLAG;
    }
         
	/*recieve successfully*/
	return DRV_CAN_OK;
}

/**
 *@brief CAN接收数据
 *
 *@param[in] pcan 指向CAN_TypeDef的指针;
 *@param[in] pBuf 数据指针;
 *@param[in] Size 送数据长度;
 *@return 操作结果; @ref DRV_CAN_StatusTypeDef
 */
DRV_CAN_StatusTypeDef DRV_CAN_FIFO_ReceiveBytesIT(CAN_TypeDef *pcan, CanRxMsgTypeDef *pRxmsg,uint32_t rx_num ,uint32_t Timeout)
{
    CAN_RxIndividualMask_TypeDef *pCanRxMaskRegs;
    CAN_RxFifoIDTable_TypeDef *pCanFifoIDtable;
    
    if (rx_num > CAN_RX_MAX_MSG)	
			  rx_num = CAN_RX_MAX_MSG;
	
    if (pcan == CAN1)
    {
        pCanRxMaskRegs = (CAN_RxIndividualMask_TypeDef *)(CAN1_BASE_ADDR + CAN_RXIMR_ADDR_OFFSET);
        pCanFifoIDtable = (CAN_RxFifoIDTable_TypeDef *)(CAN1_BASE_ADDR + CAN_FIFO_ID_TABLE_ADDR_OFFSET);
    }
    else
    {
        return DRV_CAN_ERROR;
    }

		/*Can must enter freeze mode before updating RX individual mask*/
		pcan->CAN_MCR |= CAN_MCR_HALT;
		while((pcan->CAN_MCR & CAN_MCR_FRZ_ACK) == 0){};
			
	  
			
		/*set RX individual mask*/
		pCanRxMaskRegs->CAN_RXIMR[pRxmsg[0].MBID] = pRxmsg->RXIM;

    /*clear the FIFO interrupt flag  */
    pcan->CAN_IF1R |=  CAN_IF1R_RX_FIFO_FLAG;   
			
    /*disable FIFO interrupt*/
    pcan->CAN_IM1R &= CAN_IM1R_RX_FIFO_INT_MASK;
    
    /*configure FIFO to receive extended frames*/
    if(pRxmsg[0].IDE == DRV_CAN_ID_EXT)
    {
        pCanFifoIDtable->ID_TABLE[pRxmsg[0].MBID] = (pRxmsg[0].ExtId << 1) | CAN_FIFO_EXT_MSK;
    }
    /*configure FIFO to receive standard frames*/
    else
    {
        pCanFifoIDtable->ID_TABLE[pRxmsg[0].MBID] = (pRxmsg[0].StdId << 19);
    }
		/*enable FIFO interrupt*/
    pcan->CAN_IM1R |= CAN_IM1R_RX_FIFO_INT;
    /*exit Freeze Mode*/
    pcan->CAN_MCR &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);
		
		/*等待接收完成*/
		//while(gCanFifoRxLen < rx_num){}
#if 1
		memcpy((void *)pRxmsg, (void *)gCanRxmsg, sizeof(gCanRxmsg));
#else
    for (i = 0; i < rx_num; i++)
    {    		  
				pRxmsg[i].IDE   = gCanRxmsg[i].IDE;
        pRxmsg[i].StdId = gCanRxmsg[i].StdId ;
        pRxmsg[i].ExtId = gCanRxmsg[i].ExtId;
        pRxmsg[i].DLC   = gCanRxmsg[i].DLC;
        /*read data in the MB*/
        for(ucIndex = 0; ucIndex < gCanRxmsg[i].DLC; ucIndex++)
        {
            pRxmsg[i].Data[ucIndex] = gCanRxmsg[i].Data[ucIndex];
        } 

    }
#endif
	/*recieve successfully*/
	return DRV_CAN_OK;
}
/**
 *@brief CAN MB0~3中断服务函数
 *
 *@param[in] NONE
 *@return 操作结果; NONE
 */
void DRV_CAN0_3_Handler(void)
{
	volatile uint32_t status1;
	volatile uint32_t im_flg;
	volatile uint8_t  i;
	
	status1 = CAN1->CAN_IF1R;
	
	im_flg = CAN1->CAN_IM1R;
	for (i = 0; i <= 3; i++)
	{
		if (im_flg&(1<<i))
		{
			if (status1&(1<<i))
				gCanIFlag1 |= (1<<i);
		}
	}
	CAN1->CAN_IF1R = (im_flg&0x0000000f);
}

#if 1 //By Jason
/**
 *@brief CAN MB4~7中断服务函数
 *
 *@param[in] NONE
 *@return 操作结果; NONE
 */
//void DRV_CAN4_7_Handler(void)
//{
//	volatile uint32_t status1;
//	volatile uint32_t im_flg;
//	volatile uint8_t  i;
//	
//	status1 = CAN1->CAN_IF1R;
//	
//	im_flg = CAN1->CAN_IM1R;
//	for (i = 4; i <= 7; i++)
//	{
//		if (im_flg&(1<<i))
//		{
//			if (status1&(1<<i))
//			{
//				gCanIFlag1 |= (1<<i);
//				if ((gCanFifoEnable == 1)&&(i == 5))
//                { 
//                    gCantRxMsg.IDE = (CAN1->CAN_MB[0].MB_CS >> 21)&0x1;
//                    if (gCantRxMsg.IDE == DRV_CAN_ID_STD)
//                    {
//                        gCantRxMsg.StdId = CAN1->CAN_MB[0].MB_ID >> 18;
//                    }
//                    else
//                    {
//                        gCantRxMsg.ExtId = CAN1->CAN_MB[0].MB_ID;
//                    }

//                    gCantRxMsg.DLC = (CAN1->CAN_MB[0].MB_CS >> 16)&0x0f;
//                    /*read data in the MB*/
//                    for(UINT8 ucIndex = 0; ucIndex < gCantRxMsg.DLC; ucIndex++)
//                    {
//                        canDataBuf[ucIndex]= CAN1->CAN_MB[0].MB_DATA[ucIndex];
//                    }
//                    if(gCantRxMsg.DLC==8)
//                    {
//                        u8 ii;
//                        for(ii=0;ii<4;ii++)
//                        {
//                            gCantRx.dat[gCantRx.wp]=canDataBuf[3-ii];
//                            gCantRx.wp += 1;
//                            if (gCantRx.wp >= CAN_RX_MAX_LEN)
//                                gCantRx.wp = 0;
//                        }
//                        for(ii=4;ii<8;ii++)
//                        {
//                            gCantRx.dat[gCantRx.wp]=canDataBuf[11-ii];
//                            gCantRx.wp += 1;
//                            if (gCantRx.wp >= CAN_RX_MAX_LEN)
//                                gCantRx.wp = 0;
//                        }
//                    } 				
//                }
//				
//			}
//		}
//	}
//	CAN1->CAN_IF1R = (gCanIFlag1&0x000000f0);
//}
u8 CanRecieved(void)
{
	if (gCantRx.wp !=gCantRx.rp)
	{
		return TRUE;
	}
	return FALSE;
}
u8 CanRecvByte(UINT8 *dat)
{
	if (gCantRx.wp != gCantRx.rp)
	{
		*dat = gCantRx.dat[gCantRx.rp];
		gCantRx.rp += 1;
		if (gCantRx.rp >= CAN_RX_MAX_LEN)
			gCantRx.rp = 0;
		return TRUE;
	}
	return FALSE;
}
#else
/**
 *@brief CAN MB4~7中断服务函数
 *
 *@param[in] NONE
 *@return 操作结果; NONE
 */
void DRV_CAN4_7_Handler(void)
{
	volatile uint32_t status1;
	volatile uint32_t im_flg;
	volatile uint8_t  i;
	
	status1 = CAN1->CAN_IF1R;
	
	im_flg = CAN1->CAN_IM1R;

	for (i = 4; i <= 7; i++)
	{
		if (im_flg&(1<<i))
		{
			if (status1&(1<<i))
			{
				gCanIFlag1 |= (1<<i);
				if ((gCanFifoEnable == 1)&&(i == 5))
				{ 
					if (gCanFifoRxLen < CAN_RX_MAX_MSG)
					{
						gCanRxmsg[gCanFifoRxLen].IDE = (CAN1->CAN_MB[0].MB_CS >> 21)&0x1;
						if (gCanRxmsg[gCanFifoRxLen].IDE == DRV_CAN_ID_STD)
						{
								gCanRxmsg[gCanFifoRxLen].StdId = CAN1->CAN_MB[0].MB_ID >> 18;
						}
						else
						{
								 gCanRxmsg[gCanFifoRxLen].ExtId = CAN1->CAN_MB[0].MB_ID;
						}

						gCanRxmsg[gCanFifoRxLen].DLC = (CAN1->CAN_MB[0].MB_CS >> 16)&0x0f;
						/*read data in the MB*/
						for(UINT8 ucIndex = 0; ucIndex < gCanRxmsg[gCanFifoRxLen].DLC; ucIndex++)
						{
								 gCanRxmsg[gCanFifoRxLen].Data[ucIndex] = CAN1->CAN_MB[0].MB_DATA[ucIndex];
						}
					}
					gCanFifoRxLen++;
					if (gCanFifoRxLen >= CAN_RX_MAX_MSG)
						gCanFifoRxLen = CAN_RX_MAX_MSG;
				}
				
			}
		}
	}
	CAN1->CAN_IF1R = (gCanIFlag1&0x000000f0);
}
#endif
/**
 *@brief CAN MB8~11中断服务函数
 *
 *@param[in] NONE
 *@return 操作结果; NONE
 */
void DRV_CAN8_11_Handler(void)
{
	volatile uint32_t status1;
	volatile uint32_t im_flg;
	volatile uint8_t  i;
	
	status1 = CAN1->CAN_IF1R;
	
	im_flg = CAN1->CAN_IM1R;
	for (i = 8; i <= 11; i++)
	{
		if (im_flg&(1<<i))
		{
			if (status1&(1<<i))
				gCanIFlag1 |= (1<<i);
		}
	}
	CAN1->CAN_IF1R = (gCanIFlag1&0x00000f00);
}

/**
 *@brief CAN MB12~15中断服务函数
 *
 *@param[in] NONE
 *@return 操作结果; NONE
 */
void DRV_CAN12_15_Handler(void)
{
	volatile uint32_t status1;
	volatile uint32_t im_flg;
	volatile uint8_t  i;
	
	status1 = CAN1->CAN_IF1R;
	
	im_flg = CAN1->CAN_IM1R;
	for (i = 12; i <= 15; i++)
	{
		if (im_flg&(1<<i))
		{
			if (status1&(1<<i))
				gCanIFlag1 |= (1<<i);
		}
	}
	CAN1->CAN_IF1R = (gCanIFlag1&0x0000f000);
}

/**
 *@brief CAN MB16~31中断服务函数
 *
 *@param[in] NONE
 *@return 操作结果; NONE
 */
void DRV_CAN16_31_Handler(void)
{
	volatile uint32_t status1;
	volatile uint32_t im_flg;
	volatile uint8_t  i;
	
	status1 = CAN1->CAN_IF1R;
	
	im_flg = CAN1->CAN_IM1R;
	for (i = 16; i <= 31; i++)
	{
		if (im_flg&(1<<i))
		{
			if (status1&(1<<i))
				gCanIFlag1 |= (1<<i);
			
		}
	}
	CAN1->CAN_IF1R = (gCanIFlag1&0xffff0000);
}

/**
 *@brief CAN MB32~63中断服务函数
 *
 *@param[in] NONE
 *@return 操作结果; NONE
 */
void DRV_CAN32_63_Handler(void)
{
	volatile uint32_t status;
	volatile uint32_t im_flg;
	volatile uint8_t  i;
	
	status = CAN1->CAN_IF2R;
	
	im_flg = CAN1->CAN_IM2R;
	for (i = 0; i <= 31; i++)
	{
		if (im_flg&(1<<i))
		{
			if (status&(1<<i))
				gCanIFlag2 |= (1<<i);
		}
	}
	CAN1->CAN_IF2R = gCanIFlag2;
}


/************************ (C) COPYRIGHT C*Core *****END OF FILE**********************/
