

/**
 ******************************************************************************
 *
 * @file        MG32_CAN_DRV.c
 * @brief       The code is CAN driver C file.
 *
 * @par         Project
 *              MG32
 * @version     V1.04
 * @date        2025/06/24
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 * 
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/
#include "MG32.h"

#if defined(ModuleExist_CAN0) && defined(CAN_TYPE)


#include "MG32_CAN_DRV.h"


/**
 * @name Interrupt and event flag related
 *             
 */ 
///@{
/**
 *******************************************************************************
 * @brief	  CAN local interrupt enable or disable.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_IT:
 *   @arg\b   CAN_IT_BUS    : CAN bus-off interrupt.
 *   @arg\b   CAN_IT_EW     : CAN error warning interrupt.
 *   @arg\b   CAN_IT_WUP    : CAN wake up from CAN low-power state.
 *   @arg\b   CAN_IT_EP     : CAN error passive interrupt.
 *   @arg\b   CAN_IT_ALOS   : CAN arbitration loss interrupt. 
 *   @arg\b   CAN_IT_BERR   : CAN bus error interrupt.
 *   @arg\b   CAN_IT_RX0    : CAN data receive message FIFO-0 interrupt.
 *   @arg\b   CAN_IT_RX1    : CAN data receive message FIFO-1 interrupt.
 *   @arg\b   CAN_IT_RFUL0  : CAN receive message FIFO-0 full interrupt.
 *   @arg\b   CAN_IT_RFUL1  : CAN receive message FIFO-1 full interrupt.
 *   @arg\b   CAN_IT_ROVR0  : CAN receive message FIFO-0 overrun interrupt.
 *   @arg\b   CAN_IT_ROVR1  : CAN receive message FIFO-1 overrun interrupt.
 *   @arg\b   CAN_IT_RPEND0 : CAN receive message FIFO-0 remained pending interrupt.
 *   @arg\b   CAN_IT_RPEND1 : CAN receive message FIF0-1 remained pending interrupt.
 *   @arg\b   CAN_IT_TX0    : CAN data transmit request complete interrupt for TX message buffer 0.
 *   @arg\b   CAN_IT_TX1    : CAN data transmit request complete interrupt for TX message buffer 1.
 *   @arg\b   CAN_IT_TX2    : CAN data transmit request complete interrupt for TX message buffer 2.
 * @param[in] CAN_IT_State:
 * 	@arg\b    ENABLE : Enable interrupt of URT_IT.
 *  @arg\b    DISABLE: Disable interrupt of URT_IT.
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
    CAN_IT_Config(CAN0,(CAN_IT_RX0 | CAN_IT_TX0),ENABLE);
    
    or
    
    URT_IT_Config(URT0, 0x00001100 , ENABLE);
 * @endcode             
 *******************************************************************************
 */
void CAN_IT_Config( CAN_Struct* CANx, uint32_t CAN_IT, FunctionalState CAN_IT_State)
{
    CANx->INT.W = (( CANx->INT.W & (~CAN_IT)) | ( CAN_IT * CAN_IT_State));
}

/**
 *******************************************************************************
 * @brief	  Read CANx interrupt enable register. 
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.   
 * @return    CANx interrupt enable register value.
 * @exception No
 * @note      
 * @par       Example
 * @code
     CANx_INT_Tmp = CAN_GetITStatus( CAN0);
 * @endcode             
 *******************************************************************************
 */
uint32_t CAN_GetITStatus( CAN_Struct* CANx)
{
    return( CANx->INT.W);
}
/**
 *******************************************************************************
 * @brief	  CANx global all interrupt event are enable or disable control.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.  
 * @param[in] CAN_ITEA_State:
 * 	@arg\b    ENABLE : Enable CANx global all interrupt event. 
 *  @arg\b    DISABLE: Disable CANx global all interrupt event.
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_ITEA_Cmd(CAN0, ENABLE);
 * @endcode            
 *******************************************************************************
 */
void CAN_ITEA_Cmd( CAN_Struct* CANx, FunctionalState CAN_ITEA_State)
{
    CANx->INT.W = ((CANx->INT.W & (~CAN_INT_IEA_mask_w))| ( CAN_INT_IEA_mask_w * CAN_ITEA_State));
}

/**
 *******************************************************************************
 * @brief	  Read all CANx interrupt flag
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.  
 * @return    CANx all interrupt flag status.   
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_STAITFlagTmp = CAN_GetITAllFlagStatus(CAN0);
 * @endcode             
 *******************************************************************************
 */
uint32_t CAN_GetITAllFlagStatus( CAN_Struct* CANx)
{
    return((CANx->STA.W & CAN_IT_ALL));
}

/**
 *******************************************************************************
 * @brief	  Read single CANx interrupt flag status.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CAN_ITFlag:
 *   @arg\b   CAN_IT_BUS    : CAN bus-off interrupt flag.
 *   @arg\b   CAN_IT_EW     : CAN error warning interrupt flag.
 *   @arg\b   CAN_IT_WUP    : CAN wake up from CAN low-power state flag.
 *   @arg\b   CAN_IT_EP     : CAN error passive interrupt flag.
 *   @arg\b   CAN_IT_ALOS   : CAN arbitration loss interrupt flag. 
 *   @arg\b   CAN_IT_BERR   : CAN bus error interrupt flag.
 *   @arg\b   CAN_IT_RX0    : CAN data receive message FIFO-0 interrupt flag.
 *   @arg\b   CAN_IT_RX1    : CAN data receive message FIFO-1 interrupt flag.
 *   @arg\b   CAN_IT_RFUL0  : CAN receive message FIFO-0 full interrupt flag.
 *   @arg\b   CAN_IT_RFUL1  : CAN receive message FIFO-1 full interrupt flag.
 *   @arg\b   CAN_IT_ROVR0  : CAN receive message FIFO-0 overrun interrupt flag.
 *   @arg\b   CAN_IT_ROVR1  : CAN receive message FIFO-1 overrun interrupt flag.
 *   @arg\b   CAN_IT_RPEND0 : CAN receive message FIFO-0 remained pending interrupt flag.
 *   @arg\b   CAN_IT_RPEND1 : CAN receive message FIF0-1 remained pending interrupt flag.
 *   @arg\b   CAN_IT_TX0    : CAN data transmit request complete interrupt for TX message buffer 0 flag.
 *   @arg\b   CAN_IT_TX1    : CAN data transmit request complete interrupt for TX message buffer 1 flag.
 *   @arg\b   CAN_IT_TX2    : CAN data transmit request complete interrupt for TX message buffer 2 flag.
 * @return    Single interrupt flag whether happened or not.
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_STAITFlagTmp = CAN_GetITSingleFlagStatus( CAN0, CAN_IT_RX0);
 * @endcode             
 *******************************************************************************
 */
DRV_Return CAN_GetITSingleFlagStatus( CAN_Struct* CANx, uint32_t CAN_ITFlag)
{
    if(( CAN_ITFlag & (~((uint32_t)CAN_IT_ALL)))!=0)
    {
        return(DRV_UnHappened);
    }
    if((CANx->STA.W & CAN_ITFlag)==0)
    {
        return(DRV_UnHappened);
    }
    return(DRV_Happened);
}

/**
 *******************************************************************************
 * @brief	  Clear CANx interrupt flag.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_ITFlag:
 *   @arg\b   CAN_IT_BUS    : CAN bus-off interrupt flag.
 *   @arg\b   CAN_IT_EW     : CAN error warning interrupt flag.
 *   @arg\b   CAN_IT_WUP    : CAN wake up from CAN low-power state flag.
 *   @arg\b   CAN_IT_EP     : CAN error passive interrupt flag.
 *   @arg\b   CAN_IT_ALOS   : CAN arbitration loss interrupt flag. 
 *   @arg\b   CAN_IT_BERR   : CAN bus error interrupt flag.
 *   @arg\b   CAN_IT_RX0    : CAN data receive message FIFO-0 interrupt flag.
 *   @arg\b   CAN_IT_RX1    : CAN data receive message FIFO-1 interrupt flag.
 *   @arg\b   CAN_IT_RFUL0  : CAN receive message FIFO-0 full interrupt flag.
 *   @arg\b   CAN_IT_RFUL1  : CAN receive message FIFO-1 full interrupt flag.
 *   @arg\b   CAN_IT_ROVR0  : CAN receive message FIFO-0 overrun interrupt flag.
 *   @arg\b   CAN_IT_ROVR1  : CAN receive message FIFO-1 overrun interrupt flag.
 *   @arg\b   CAN_IT_RPEND0 : CAN receive message FIFO-0 remained pending interrupt flag.
 *   @arg\b   CAN_IT_RPEND1 : CAN receive message FIF0-1 remained pending interrupt flag.
 *   @arg\b   CAN_IT_TX0    : CAN data transmit request complete interrupt for TX message buffer 0 flag.
 *   @arg\b   CAN_IT_TX1    : CAN data transmit request complete interrupt for TX message buffer 1 flag.
 *   @arg\b   CAN_IT_TX2    : CAN data transmit request complete interrupt for TX message buffer 2 flag.
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
    CAN_ClearITFlag(CAN0,(CAN_IT_RX0 | CAN_IT_TX0));
    
    or
    
    CAN_ClearITFlag(URT0, 0x00001100);     
 * @endcode            
 *******************************************************************************
 */
void CAN_ClearITFlag( CAN_Struct* CANx, uint32_t CAN_ITFlag) 
{
    CANx->STA.W = ( CAN_ITFlag & CAN_IT_ALL);
}

/**
 *******************************************************************************
 * @brief	  Get current CANx operation mode state.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.  
 * @return    CANx operation mode state
 *   @arg\b   CAN_INITIAL_MODE : CANx module currently is in initial mode. 
 *   @arg\b   CAN_NORMAL_MODE  : CANx module currently is in normal mode.
 *   @arg\b   CAN_LOWPOWER_MODE: CANx module currently in in low power mode.
 * @exception No
 * @note      
 * @par       Example
 * @code
     CANx_OperationModeTmp = CAN_GetOperationMode( CAN0); // If CANx_OperationModeTmp = CAN_INITIAL_MODE the CAN module operation mode is initial mode.
                                                          // If CANx_OperationModeTmp = CAN_NORMAL_MODE the CAN module operation mode is normal mode.    
                                                          // If CANx_OperationModeTmp = CAN_LOWPOWER_MODE the CAN module operation mode is low power mode.
 * @endcode             
 *******************************************************************************
 */
uint32_t CAN_GetOperationMode( CAN_Struct* CANx)
{
    return((CANx->STA.W & ( CAN_STA_LP_STA_mask_w | CAN_STA_INIT_STA_mask_w)));
}

/**
 *******************************************************************************
 * @brief	  Get current CANx fault confinement state.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.     
 * @return    CANx fault confinement state.
 *   @arg\b   CAN_ERROR_ACTIVE  : Fault confinement state is error active.
 *   @arg\b   CAN_ERROR_PASSIVE : Fault confinement state is error passive.
 *   @arg\b   CAN_BUS_OFF       : Fault confinement state is bus off.
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_FaultConfinementStateTmp = CAN_GetFaultConfinementState( CAN0);   // If CAN_FaultConfinementStateTmp = CAN_ERROR_ACTIVE the CAN module Fault Confinement state is error active.
                                                                           // If CAN_FaultConfinementStateTmp = CAN_ERROR_PASSIVE the CAN module Fault Confinement state is error passive.
                                                                           // If CAN_FaultConfinementStateTmp = CAN_BUS_OFF the CAN module Fault Confinement state is bus off.
 * @endcode             
 *******************************************************************************
 */
uint32_t CAN_GetFaultConfinementState( CAN_Struct* CANx)
{
    return((CANx->STA.W & (CAN_STA_BUS_STA_mask_w |  CAN_STA_EP_STA_mask_w)));
}

/**
 *******************************************************************************
 * @brief	  Get current error warning compare result.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.    
 * @return    CANx error warning compare result.
 *   @arg\b   CAN_WARNING_OVER : Now error count is more than the error warning limit value.
 *   @arg\b   CAN_WARNING_UNDER: Now error count is under than the error warning limit value. 
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_EWFStatusTmp = CAN_GetWarningStatus( CAN0);
 * @endcode              
 *******************************************************************************
 */
uint32_t CAN_GetWarningStatus( CAN_Struct* CANx)
{
    return((CANx->STA.W & (CAN_STA_EW_STA_mask_w)));
}

/**
 *******************************************************************************
 * @brief	  Get TX message buffer status for this time triggered transmit.
 * @details    
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_TxBuf_Index:
 *   @arg\b   CAN_Tx_Buf0: TX message buffer 0 of the CANx module.
 *   @arg\b   CAN_Tx_Buf1: TX message buffer 1 of the CANx module.
 *   @arg\b   CAN_Tx_Buf2: TX message buffer 2 of the CANx module.
 * @return    TX message buffer status for this time triggered transmit.
 *   @arg\b   CAN_TRANSMIT_STATE_BUSY   : This trigger transmit not completed.
 *   @arg\b   CAN_TRANSMIT_STATE_FAILURE: This trigger transmit is failure.
 *   @arg\b   CAN_TRANSMIT_STATE_SUCCESS: This trigger transmit is success.
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_TXMessageBufferStateTmp =  CAN_GetTXBufferStatus( CAN0, CAN_Tx_Buf0);  // Get TX message buffer 0 of CAN0 transmit status.
 * @endcode              
 *******************************************************************************
 */
uint32_t CAN_GetTXBufferStatus( CAN_Struct* CANx, CAN_TXIndex_TypeDef CAN_TxBuf_Index)
{
    uint32_t CAN_GetTXBufStatusTmp;
    
    CAN_GetTXBufStatusTmp = ((CANx->STA2.W >> CAN_TxBuf_Index) & (CAN_STA2_TC0_STA_mask_w | CAN_STA2_TB0_STA_mask_w));
    
    return( CAN_GetTXBufStatusTmp);
}
/**
 *******************************************************************************
 * @brief	  Get RX message FIFO remained message number. 
 * @details     
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.  
 * @param[in] CAN_RXFIFO_Index:
 *   @arg\b   CAN_Rx_FIFO0: RX message FIFO 0 of the CANx module.
 *   @arg\b   CAN_Rx_FIFO1: RX message FIFO 1 of the CANx module.
 * @return    The RX message FIFO remained message number.
 * @exception No
 * @note 
 * @par       Example
 * @code
       CAN_RXMessageFIFO_RemainedTmp = CAN_GetRXFIFOMessageNumber( CAN0, CAN_Rx_FIFO0);
 * @endcode              
 *******************************************************************************
 */
uint8_t CAN_GetRXFIFOMessageNumber( CAN_Struct* CANx, CAN_RXFIFOIndex_TypeDef CAN_RXFIFO_Index)
{
    return(((CANx->STA2.B[3] >> (CAN_STA2_RX1_NUM_shift_b3 * CAN_RXFIFO_Index)) & CAN_STA2_RX0_NUM_mask_b3));
}

/**
 *******************************************************************************
 * @brief	  Get RX message FIFO status
 * @details     
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.  
 * @param[in] CAN_RXFIFO_Index:
 *   @arg\b   CAN_Rx_FIFO0: RX message FIFO 0 of the CANx module.
 *   @arg\b   CAN_Rx_FIFO1: RX message FIFO 1 of the CANx module.
 * @return    The RX message FIFO status.
 *   @arg\b   CAN_RXFIFO_STATE_EMPTY    : RX message FIFO state is empty.
 *   @arg\b   CAN_RXFIFO_STATE_PENDING  : RX message FIFO state is  remained pending message but not full.
 *   @arg\b   CAN_RXFIFO_STATE_FULL     : RX message FIFO state is full.
 *   @arg\b   CAN_RXFIFO_STATE_RXOVERRUN: RX message FIFO state is overrun.
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_RXMessageFIFO_StateTmp = CAN_GetRXFIFOStatus( CAN0, CAN_Rx_FIFO0);
 * @endcode              
 *******************************************************************************
 */
uint32_t CAN_GetRXFIFOStatus( CAN_Struct* CANx, CAN_RXFIFOIndex_TypeDef CAN_RXFIFO_Index)
{
    uint32_t CAN_GetRXFIFOStatusTmp;
    
    CAN_GetRXFIFOStatusTmp = (CANx->STA2.W & ((CAN_STA2_ROVR0_STA_mask_w | CAN_STA2_RFUL0_STA_mask_w) >> CAN_RXFIFO_Index));
    
    if( CAN_GetRXFIFOStatusTmp !=0)
    {
        return(CAN_GetRXFIFOStatusTmp);
    }
    else if((CANx->STA2.B[3] >> (CAN_STA2_RX1_NUM_shift_b3 * CAN_RXFIFO_Index) & CAN_STA2_RX0_NUM_mask_b3)==0)
    {
        return(CAN_RXFIFO_STATE_EMPTY);
    }
    else
    {
        return(CAN_RXFIFO_STATE_PENDING);
    }
}

/**
 *******************************************************************************
 * @brief	  Get the CANx module transmission status.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.  
 * @return    This return can be any combination of the following values.
 *   @arg\b   CAN_TRANSMISSION_STATE_IDLE: The CANx module is idle.
 *   @arg\b   CAN_TRANSMISSION_STATE_TX  : The CANx module is transmitting.
 *   @arg\b   CAN_TRANSMISSION_STATE_RX  : The CANx module is receiving.
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_TransmssionStatusTmp =  CAN_GetTransmissionStatus( CAN0);
 * @endcode             
 *******************************************************************************
 */
uint32_t CAN_GetTransmissionStatus( CAN_Struct* CANx)
{
    return( CANx->STA2.W & ( CAN_STA2_RX_STA_mask_w | CAN_STA2_TX_STA_mask_w));
}
///@}

/**
 * @name Mode related
 *             
 */ 
///@{
/**
 *******************************************************************************
 * @brief	  CAN function enable or disable.
 * @details   
 * @param[in] CANx:
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_EN:  
 *  @arg\b    DISABLE: CAN function disable.
 *  @arg\b    ENABLE : CAN function enable.
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_Cmd(CAN0, ENABLE);
 * @endcode            
 *******************************************************************************
 */
void CAN_Cmd( CAN_Struct* CANx, FunctionalState  CAN_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_EN_mask_w)) | (CAN_CR0_EN_mask_w * CAN_EN));
}

/**
 *******************************************************************************
 * @brief	  CAN operation mode select.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_OPMode:
 *   @arg\b   CAN_Initial_Mode : CAN module into initial mode.
 *   @arg\b   CAN_Normal_Mode  : CAN module into normal mode.
 *   @arg\b   CAN_LowPower_Mode: CAN module into low power mode.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_OperationMode_Select( CAN0, CAN_Normal_Mode);
 * @endcode             
 *******************************************************************************
 */
void CAN_OperationMode_Select( CAN_Struct* CANx, CAN_SetOpMode_TypeDef CAN_OPMode)
{
    CANx->CR0.W = ((CANx->CR0.W & (~(CAN_CR0_LP_EN_mask_w|CAN_CR0_INIT_EN_mask_w))) | CAN_OPMode);
}

/**
 *******************************************************************************
 * @brief	  TX message buffer process priority mode select.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CAN_TXPriority_Mode:
 *   @arg\b   CAN_TXPriority_ID : message identifier (0 ~ 2) ( High ~ low)
 *   @arg\b   CAN_TXPriority_SEQ: request sequence order.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_TXPriorityMode_Select( CAN0, CAN_TXPriority_SEQ);
 * @endcode             
 *******************************************************************************
 */
void CAN_TXPriorityMode_Select( CAN_Struct* CANx, CAN_TXPRI_TypeDef CAN_TXPriority_Mode)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_TX_PRI_mask_w)) | CAN_TXPriority_Mode);
}

/**
 *******************************************************************************
 * @brief	  Selet CAN module into which test mode.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.   
 * @param[in] CAN_TestMode:
 *   @arg\b   CAN_TestMode_Disable           : CAN module no go into test mode. 
 *   @arg\b   CAN_TestMode_Silent            : CAN module go into silent mode (listen only mode)
 *   @arg\b   CAN_TestMode_Loopback          : CAN module go into loop back mode.
 *   @arg\b   CAN_TestMode_LoopBackWithSilent: CAN module go into loop back combined with silent mode.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_TestMode_Select( CAN0, CAN_TestMode_Silent);
 * @endcode             
 *******************************************************************************
 */
void CAN_TestMode_Select(CAN_Struct* CANx, CAN_TSTMode_TypeDef CAN_TestMode)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_TST_MDS_mask_w)) | CAN_TestMode);
}

/**
 *******************************************************************************
 * @brief	  Receive message FIFO type select.
 * @details   
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_RBUF_SEL:
 *   @arg\b   CAN_RXFIFO_Two: Two FIFO structure.
 *   @arg\b   CAN_RXFIFO_One: One FIFO structure.
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_RXFIFOType_Select( CAN0, CAN_RXFIFO_One); 
 * @endcode              
 *******************************************************************************
 */
void CAN_RXFIFOType_Select(CAN_Struct* CANx, CAN_RXFIFO_TypeDef CAN_RBUF_SEL)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_RBUF_SEL_mask_w)) | CAN_RBUF_SEL);
}

/**
 *******************************************************************************
 * @brief	  Receive message buffer overrun mode select.
 * @details   
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_RXOverrunMode:
 *   @arg\b   CAN_RXOverrun_Overwrite: Once a receive FIFO is full the next incoming message will overwrite the previous one.
 *   @arg\b   CAN_RXOverrun_Keep     : Once a receive FIFO is full the next incoming message will be discarded.  
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_RXOverrunMode_Select( CAN0, CAN_RXOverrun_Keep);
 * @endcode             
 *******************************************************************************
 */
void CAN_RXOverrunMode_Select( CAN_Struct* CANx, CAN_ROVR_TypeDef CAN_RXOverrunMode)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_ROVR_MDS_mask_w)) | CAN_RXOverrunMode);
}

/**
 *******************************************************************************
 * @brief	  Automatic retransmission disable or enable. 
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_AutoTX_EN:
 *   @arg\b   DISABLE: A message will be transmitted only once.                      
 *   @arg\b   ENABLE : The CAN hardware will automatically retransmit the message until it has been 
 *       \n            successfully transmitted according to the CAN stannard.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_AutoRetransmit_Cmd(CAN0, ENABLE);
 * @endcode            
 *******************************************************************************
 */
void CAN_AutoRetransmit_Cmd( CAN_Struct* CANx, FunctionalState CAN_AutoTX_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_TXE_MDS_mask_w)) | \
                                  ((~CAN_AutoTX_EN & 0x01) *CAN_CR0_TXE_MDS_mask_w)); 
}

/**
 *******************************************************************************
 * @brief	  FD tolerant fufnction disable or enable.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.  
 * @param[in] CAN_FDTolerant_EN:
 *   @arg\b   DISABLE: Disable FD tolerant function.
 *   @arg\b   ENABLE : Enable FD tolerant function.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_FDTolerant_Cmd( CAN0, DISABLE);
 * @endcode             
 *******************************************************************************
 */
void CAN_FDTolerant_Cmd( CAN_Struct* CANx, FunctionalState CAN_FDTolerant_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_FDT_MDS_mask_w)) | (CAN_FDTolerant_EN * CAN_CR0_FDT_MDS_mask_w));
}

/**
 *******************************************************************************
 * @brief	  Edge filter enable or disable after FDF bit is detected.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_FDTolerant_EdgeFL_EN:
 *   @arg\b   DISABLE: Disable edge filter after FDF bit is detected.
 *   @arg\b   ENABLE : Enable edge filter after FDF bit is detected.
 * @return      
 * @exception No
 * @note      The function only active in FD tolerant function enables.
 * @par       Example
 * @code
     CAN_FDTolerantEdgeFilter_Cmd( CAN0, DISABLE);
 * @endcode             
 *******************************************************************************
 */
void CAN_FDTolerantEdgeFilter_Cmd( CAN_Struct* CANx, FunctionalState CAN_FDTolerant_EdgeFL_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_EDF_MDS_mask_w)) | (CAN_CR0_EDF_MDS_mask_w * CAN_FDTolerant_EdgeFL_EN));
    
}

/**
 *******************************************************************************
 * @brief	  Wake up mode select.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_LPWakeup_Mode:
 *   @arg\b   CAN_LowPowerWakeup_OnlySoftware: Only software can wake up from CAN module low power mode.
 *   @arg\b   CAN_LowPowerWakeup_BusActive   : Software or Bus active can wake up from CAN module low power mode.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_LowpowerWakeupMode_Select( CAN0, CAN_LowPowerWakeup_OnlySoftware);
 * @endcode             
 *******************************************************************************
 */
void CAN_LowpowerWakeupMode_Select( CAN_Struct* CANx, CAN_LPWakeup_TypeDef CAN_LPWakeup_Mode)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_WUP_MDS_mask_w)) | CAN_LPWakeup_Mode);
}

/**
 *******************************************************************************
 * @brief	  RX data oversampling mode select.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_RXOS_Mode:
 *   @arg\b   CAN_RXOversampling_One  : RX sample once time.
 *   @arg\b   CAN_RXOversampling_Three: RX sample three time.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_RXOversamplingMode_Select( CAN0, CAN_RXOversampling_One);
 * @endcode              
 *******************************************************************************
 */
void CAN_RXOversamplingMode_Select( CAN_Struct* CANx, CAN_RXOS_TypeDef CAN_RXOS_Mode)
{
    CANx->CR0.W = (( CANx->CR0.W & (~CAN_CR0_OS_MDS_mask_w)) | CAN_RXOS_Mode);
}

/**
 *******************************************************************************
 * @brief	  Transmitted and received simultaneously mode enable or disable.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CAN_SRR_EN:
 *   @arg\b   DISABLE: In transmitting no simultaneously receive. 
 *   @arg\b   ENABLE : In transmitting simultaneously receive.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_SelfReceptionMode_Cmd( CAN0, DISABLE);
 * @endcode             
 *******************************************************************************
 */
void CAN_SelfReceptionMode_Cmd( CAN_Struct* CANx, FunctionalState CAN_SRR_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_SRR_EN_mask_w)) | (CAN_CR0_SRR_EN_mask_w * CAN_SRR_EN));
}
///@}


/**
 * @name Bit-time related
 *             
 */ 
///@{
/**
 *******************************************************************************
 * @brief	  CAN bit time clock source select.	    
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_ClockSource:
 *   @arg\b   CAN_Clock_PROC  : Clock source from CK_CAN_PR
 *   @arg\b   CAN_Clock_NCO_P0: Clock source from NCO_P0
 *   @arg\b   CAN_Clock_LS    : Clock source from CK_LS
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_ClockSource_Select( CAN0, CAN_Clock_PROC);
 * @endcode             
 *******************************************************************************
 */
void CAN_ClockSource_Select(CAN_Struct* CANx, CAN_Clock_TypeDef CAN_ClockSource)
{
    CANx->CLK.W = ((CANx->CLK.W & (~CAN_CLK_CK_SEL_mask_w)) | CAN_ClockSource);
}

/**
 *******************************************************************************
 * @brief	  Bit time configure.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CAN_Bittime:
 *   @arg\b   prescaler: (1 ~ 1023)
 *   @arg\b   TimeSeg1 : (1 ~ 15) It includes the Prop_Seg and Phase_Seg1 of the CAN standard. 
 *   @arg\b   TimeSeg2 : (1 ~ 7) Phase_Seg2
 *   @arg\b   
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code

    //Bit time = f(Bit time clock source) / ((prescaler + 1) * (1 + (TimeSeg1 + 1) * (TimeSeg2 + 1)))
    CAN_Bittime_TypeDef   CAN_Bit;
    
    CAN_Bit.CTR.MBIT.prescaler     = 1;
    CAN_Bit.CTR.MBIT.TimeSeg1      = 1;
    CAN_Bit.CTR.MBIT.TimeSeg2      = 1;
    CAN_Bit.CTR.MBIT.SyncJumpWidth = 0;
    CAN_BitTime_Config( CAN0, &CAN_Bit);
 * @endcode            
 *******************************************************************************
 */
void CAN_BitTime_Config( CAN_Struct *CANx , CAN_Bittime_TypeDef* CAN_Bittime)
{
    CANx->CR1.W = CAN_Bittime->CTR.W[0];
    CANx->CLK.W = ((CANx->CLK.W & (~CAN_CLK_BRP_mask_w)) | (CAN_Bittime->CTR.W[1] & CAN_CLK_BRP_mask_w));
    
}

///@}



/**
 * @name Data Control Related.
 *             
 */ 
///@{
/**
 *******************************************************************************
 * @brief	  CAN transmit message
 * @details   
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CAN_TXBuf_Index: (Trigger which TX message buffer)
 *   @arg\b   CAN_Tx_Buf0: TX message buffer 0 of the CANx module.
 *   @arg\b   CAN_Tx_Buf1: TX message buffer 1 of the CANx module.
 *   @arg\b   CAN_Tx_Buf2: TX message buffer 2 of the CANx module.
 * @param[in] CAN_TXMailbox: (Transmit message source pointer)
 *   @arg\b   EID: Extended ID
 *   @arg\b   SID: Base ID
 *   @arg\b   RTR: Remote transmission request bit
 *   @arg\b   IDE: Identifier extension bit
 *   @arg\b   DLC: Data length code
 *   @arg\b   Data[0] ~ Data[7]: Data Field
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_TXBuf_TypeDef    CAN_TX_Frame;
     
     //CBFF (Classical Base Frame Format (Data frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 0;
     CAN_TX_Frame.Format.Field.RTR     = 0;
     CAN_TX_Frame.Format.Field.DLC     = 1;
     CAN_TX_Frame.Format.Field.Data[0] = 0x00; 
     CAN_SendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
     
     //CBFF (Classical Base Frame Format (Remote frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 0;
     CAN_TX_Frame.Format.Field.RTR     = 1;
     CAN_TX_Frame.Format.Field.DLC     = 4;
     CAN_SendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
     
     //CEFF (Classical Extended Frame Format) (Data frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 1;
     CAN_TX_Frame.Format.Field.EID     = 0x00000;
     CAN_TX_Frame.Format.Field.RTR     = 0;
     CAN_TX_Frame.Format.Field.DLC     = 1;
     CAN_TX_Frame.Format.Field.Data[0] = 0x00; 
     CAN_SendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
     
     //CEFF (Classical Extended Frame Format) (Remote frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 1;
     CAN_TX_Frame.Format.Field.EID     = 0x00000;
     CAN_TX_Frame.Format.Field.RTR     = 1;
     CAN_TX_Frame.Format.Field.RTR     = 8;
     CAN_SendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
 * @endcode            
 *******************************************************************************
 */
void CAN_SendFrame( CAN_Struct *CANx, CAN_TXIndex_TypeDef CAN_TXBuf_Index, CAN_TXBuf_TypeDef *CAN_TXMailbox)
{
    CAN_TXBuf_TypeDef* CANx_TXBufx;
    
    CANx_TXBufx = (CAN_TXBuf_TypeDef*)(((uint32_t)(CANx) + CAN_TXBUF_SHIFT) + (CAN_TXBUFX_SHIFT * CAN_TXBuf_Index));
    
    CANx_TXBufx->Format.W[0] = CAN_TXMailbox->Format.W[0];
    CANx_TXBufx->Format.W[1] = CAN_TXMailbox->Format.W[1];
    CANx_TXBufx->Format.W[2] = CAN_TXMailbox->Format.W[2];
    CANx_TXBufx->Format.W[3] = CAN_TXMailbox->Format.W[3];
    
    CANx_TXBufx->Format.W[1] |= CAN_TDAT01_TX0_REQ_mask_w;     // Trigger transmission request.
}

/**
 *******************************************************************************
 * @brief	  CAN transmit message (single shot)
 * @details   At this time transmit trigger the message will be transmitted only once. 
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CAN_sTXBuf_Index: (Trigger which TX message buffer)
 *   @arg\b   CAN_Tx_Buf0: TX message buffer 0 of the CANx module.
 *   @arg\b   CAN_Tx_Buf1: TX message buffer 1 of the CANx module.
 *   @arg\b   CAN_Tx_Buf2: TX message buffer 2 of the CANx module.
 * @param[in] CAN_sTXMailbox: (Transmit message source pointer)
 *   @arg\b   EID: Extended ID
 *   @arg\b   SID: Base ID
 *   @arg\b   RTR: Remote Transmission Request Bit
 *   @arg\b   IDE: Identifier Extension Bit
 *   @arg\b   DLC: Data Length Code
 *   @arg\b   Data[0] ~ Data[7]: Data Field
 * @return    
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_TXBuf_TypeDef    CAN_TX_Frame;
     
     //CBFF (Classical Base Frame Format (Data frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 0;
     CAN_TX_Frame.Format.Field.RTR     = 0;
     CAN_TX_Frame.Format.Field.DLC     = 1;
     CAN_TX_Frame.Format.Field.Data[0] = 0x00; 
     CAN_SingleShotSendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
     
     //CBFF (Classical Base Frame Format (Remote frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 0;
     CAN_TX_Frame.Format.Field.RTR     = 1;
     CAN_SingleShotSendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
     
     //CEFF (Classical Extended Frame Format) (Data frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 1;
     CAN_TX_Frame.Format.Field.EID     = 0x00000;
     CAN_TX_Frame.Format.Field.RTR     = 0;
     CAN_TX_Frame.Format.Field.DLC     = 1;
     CAN_TX_Frame.Format.Field.Data[0] = 0x00; 
     CAN_SingleShotSendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
     
     //CEFF (Classical Extended Frame Format) (Remote frame)
     CAN_TX_Frame.Format.Field.SID     = 0x000;
     CAN_TX_Frame.Format.Field.IDE     = 1;
     CAN_TX_Frame.Format.Field.EID     = 0x00000;
     CAN_TX_Frame.Format.Field.RTR     = 1;
     CAN_SingleShotSendFrame(CAN0,CAN_Tx_Buf0,&CAN_TX_Frame);
 * @endcode             
 *******************************************************************************
 */
void CAN_SingleShotSendFrame( CAN_Struct *CANx, CAN_TXIndex_TypeDef CAN_sTXBuf_Index, CAN_TXBuf_TypeDef *CAN_sTXMailbox)
{
    CAN_TXBuf_TypeDef* CANx_sTXBufx;
    
    CANx_sTXBufx = (CAN_TXBuf_TypeDef*)(((uint32_t)(CANx) + CAN_TXBUF_SHIFT) + (CAN_TXBUFX_SHIFT * CAN_sTXBuf_Index));
    
    CANx_sTXBufx->Format.W[0] = CAN_sTXMailbox->Format.W[0];
    CANx_sTXBufx->Format.W[1] = CAN_sTXMailbox->Format.W[1];
    CANx_sTXBufx->Format.W[2] = CAN_sTXMailbox->Format.W[2];
    CANx_sTXBufx->Format.W[3] = CAN_sTXMailbox->Format.W[3];
    
    CANx_sTXBufx->Format.W[1]  |= (CAN_TDAT01_TX0_REQ_mask_w | CAN_TDAT01_TX0_STOP_mask_w);  // Trigger transmission request.
}

/**
 *******************************************************************************
 * @brief	  Abort TX message buffer transmit request.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CAN_aTXBuf_Index: (Trigger which TX message buffer)
 *   @arg\b   CAN_Tx_Buf0: TX message buffer 0 of the CANx module.
 *   @arg\b   CAN_Tx_Buf1: TX message buffer 1 of the CANx module.
 *   @arg\b   CAN_Tx_Buf2: TX message buffer 2 of the CANx module.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_AbortTXRequest( CAN0, CAN_Tx_Buf0);
 * @endcode             
 *******************************************************************************
 */
void CAN_AbortTXRequest( CAN_Struct *CANx, CAN_TXIndex_TypeDef CAN_aTXBuf_Index)
{
    CAN_TXBuf_TypeDef* CANx_aTXBufx;
    
    CANx_aTXBufx = (CAN_TXBuf_TypeDef*)(((uint32_t)(CANx) + CAN_TXBUF_SHIFT) + (CAN_TXBUFX_SHIFT * CAN_aTXBuf_Index));
    
    CANx_aTXBufx->Format.W[1] |= CAN_TDAT01_TX0_STOP_mask_w;
}

/**
 *******************************************************************************
 * @brief	  Read receive message FIFO data.  
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_RXFIFO_Index: 
 *   @arg\b   CAN_Rx_FIFO0: RX message FIFO 0 of the CANx module.
 *   @arg\b   CAN_Rx_FIFO1: RX message FIFO 1 of the CANx module.
 * @param[in] CAN_RXMessage: (Receive data store destination pointer) 
 *   @arg\b   EID: Extended ID
 *   @arg\b   SID: Base ID
 *   @arg\b   RTR: Remote Transmission Request Bit
 *   @arg\b   IDE: Identifier Extension Bit
 *   @arg\b   DLC: Data Length Code
 *   @arg\b   Data[0] ~ Data[7]: Data Field  
 * @return      
 * @exception No
 * @note      
 * @par       Example
 * @code
     CAN_RXBuf_TypeDef   CAN_RX_Frame;
    
     CAN_ReceiveFrame( CAN0, CAN_Rx_FIFO0, &CAN_RX_Frame);
 * @endcode             
 *******************************************************************************
 */
void CAN_ReceiveFrame( CAN_Struct* CANx, CAN_RXFIFOIndex_TypeDef CAN_RXFIFO_Index, CAN_RXBuf_TypeDef *CAN_RXMessage)
{
    CAN_RXBuf_TypeDef* CANx_RXFIFOx;
    
    CANx_RXFIFOx = (CAN_RXBuf_TypeDef*)(((uint32_t)CANx + CAN_RXFIFO_SHIFT) + (CAN_RXFIFOX_SHIFT * CAN_RXFIFO_Index));
    
    CAN_RXMessage->Format.W[0] = CANx_RXFIFOx->Format.W[0]; 
    CAN_RXMessage->Format.W[1] = CANx_RXFIFOx->Format.W[1];
    CAN_RXMessage->Format.W[2] = CANx_RXFIFOx->Format.W[2];
    CAN_RXMessage->Format.W[3] = CANx_RXFIFOx->Format.W[3];
    
    CANx_RXFIFOx->Format.W[1] |= CAN_RDAT01_RX0_CLR_mask_w;     // Release RX FIFO.
}

/**
 *******************************************************************************
 * @brief	  Reset receive message FIFO.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_rRXFIFO_Index: 
 *   @arg\b   CAN_Rx_FIFO0: RX message FIFO 0 of the CANx module.
 *   @arg\b   CAN_Rx_FIFO1: RX message FIFO 1 of the CANx module.  
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_ResetRXFIFO( CAN0, CAN_Rx_FIFO0);
 * @endcode             
 *******************************************************************************
 */
void CAN_ResetRXFIFO( CAN_Struct* CANx, CAN_RXFIFOIndex_TypeDef CAN_rRXFIFO_Index)
{
    CAN_RXBuf_TypeDef* CANx_rRXFIFOx;
    
    CANx_rRXFIFOx = (CAN_RXBuf_TypeDef*)(((uint32_t)CANx + CAN_RXFIFO_SHIFT) + (CAN_RXFIFOX_SHIFT * CAN_rRXFIFO_Index));
    
    CANx_rRXFIFOx->Format.W[1] |= CAN_RDAT01_RX0_RST_mask_w;
}
///@}


/**
 * @name Filter Related.
 *             
 */ 
///@{
/**
 *******************************************************************************
 * @brief	  Filter mode configure
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CANx_FL_Index:
 *   @arg\b   CAN_Filter0: 1st bank filter of the CANx.
 *   @arg\b   CAN_Filter1: 2nd bank filter of the CANx.
 *   @arg\b   CAN_Filter2: 3rd bank filter of the CANx.
 *   @arg\b   CAN_Filter3: 4th bank filter of the CANx.
 *   @arg\b   CAN_Filter4: 5th bank filter of the CANx.
 *   @arg\b   CAN_Filter5: 6th bank filter of the CANx.
 * @param[in] CANx_FL_Mode:
 *   @arg\b   CAN_Filter_32bitMask: 32 bit Mask mode.
 *   @arg\b   CAN_Filter_32bitList: 32 bit LIST mode.
 *   @arg\b   CAN_Filter_16bitMask: 16 bit MASK mode.
 *   @arg\b   CAN_Filter_16bitList: 16 bit LIST mode.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_AcceptanceFilterMode_Config( CAN0, CAN_Filter0, CAN_Filter_32bitMask);
 * @endcode             
 *******************************************************************************
 */
void CAN_AcceptanceFilterMode_Config( CAN_Struct* CANx, CAN_FilterIndex_TypeDef CANx_FL_Index, CAN_FilterMode_TypeDef CANx_FL_Mode)
{
    CANx->AFC1.W = ((CANx->AFC1.W & (~((CAN_AFC1_AF0_MDS_mask_w | CAN_AFC1_AF0_CFG_mask_w) << CANx_FL_Index))) | \
                    (CANx_FL_Mode << CANx_FL_Index));   
}

/**
 *******************************************************************************
 * @brief	  Filter FIFO select.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CANx_FL_Index:
 *   @arg\b   CAN_Filter0: 1st bank filter of the CANx.
 *   @arg\b   CAN_Filter1: 2nd bank filter of the CANx.
 *   @arg\b   CAN_Filter2: 3rd bank filter of the CANx.
 *   @arg\b   CAN_Filter3: 4th bank filter of the CANx.
 *   @arg\b   CAN_Filter4: 5th bank filter of the CANx.
 *   @arg\b   CAN_Filter5: 6th bank filter of the CANx.
 * @param[in] CANx_FL_FIFO:
 *   @arg\b   CAN_Filter_FIFO0: The message pass the filter store to FIFO 0.
 *   @arg\b   CAN_Filter_FIFO1: The message pass the filter store to FIFO 1.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_AcceptanceFilterFIFO_Select( CAN0, CAN_Filter0, CAN_Filter_FIFO0);
 * @endcode             
 *******************************************************************************
 */
void CAN_AcceptanceFilterFIFO_Select( CAN_Struct* CANx, CAN_FilterIndex_TypeDef CANx_FL_Index, CAN_FilterFIFO_TypeeDef CANx_FL_FIFO)
{
    CANx->AFC0.W = ((CANx->AFC0.W & (~(CAN_AFC0_AF0_FSEL_mask_w << CANx_FL_Index))) | \
                    ((uint32_t)(CANx_FL_FIFO << CANx_FL_Index)));
}

/**
 *******************************************************************************
 * @brief	  The filter of the CANx enable or disable.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CANx_FL_Index:
 *   @arg\b   CAN_Filter0: 1st bank filter of the CANx.
 *   @arg\b   CAN_Filter1: 2nd bank filter of the CANx.
 *   @arg\b   CAN_Filter2: 3rd bank filter of the CANx.
 *   @arg\b   CAN_Filter3: 4th bank filter of the CANx.
 *   @arg\b   CAN_Filter4: 5th bank filter of the CANx.
 *   @arg\b   CAN_Filter5: 6th bank filter of the CANx.
 * @param[in] CANx_FL_Cmd:
 *   @arg\b   DISABLE: Disable the filter.
 *   @arg\b   ENABLE : Enable the filter.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_AcceptanceFilter_Cmd( CAN0, CAN_Filter0, ENABLE);
 * @endcode
 *******************************************************************************
 */
void CAN_AcceptanceFilter_Cmd( CAN_Struct* CANx, CAN_FilterIndex_TypeDef CANx_FL_Index, FunctionalState CANx_FL_Cmd)
{
    CANx->AFC0.W = ((CANx->AFC0.W & (~(CAN_AFC0_AF0_EN_mask_w << CANx_FL_Index))) | \
                    ((CAN_AFC0_AF0_EN_mask_w * CANx_FL_Cmd) << CANx_FL_Index));
}

/**
 *******************************************************************************
 * @brief	  Configure conditions that pass the filter.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control. 
 * @param[in] CANx_FL_Index:
 *   @arg\b   CAN_Filter0: 1st bank filter of the CANx.
 *   @arg\b   CAN_Filter1: 2nd bank filter of the CANx.
 *   @arg\b   CAN_Filter2: 3rd bank filter of the CANx.
 *   @arg\b   CAN_Filter3: 4th bank filter of the CANx.
 *   @arg\b   CAN_Filter4: 5th bank filter of the CANx.
 *   @arg\b   CAN_Filter5: 6th bank filter of the CANx.
 * @param[in] CAN_Filter_Config: Pass conditions.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
 *   CAN_Filter_TypeDef   CAN_Filter;
    
     //If the filter bank mode is a 32 bit Mask mode
     CAN_Filter.AFnR.Mask32.ID.SID          = 0x000;   // Compare ID's SID (Base ID)
     CAN_Filter.AFnR.Mask32.ID.EID          = 0x00000; // Compare ID's EID (ID extension)
     CAN_Filter.AFnR.Mask32.ID.IDE          = 0;       // Compare ID's IDE
     CAN_Filter.AFnR.Mask32.ID.RTR          = 0;       // Compare ID's RTR
                                                       
     CAN_Filter.AFnR.Mask32.Mask.SID        = 0x000;   // Mask ID's SID (Base ID) (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask32.Mask.EID        = 0x00000; // Mask ID's EID (ID extension) (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask32.Mask.IDE        = 1;       // Mask ID's IDE (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask32.Mask.RTR        = 1;       // Mask ID's RTR (0: Don't care, 1: Must match)
     CAN_AccptanceFilter_Config(CAN0,CAN_Filter0,&CAN_Filter);
     
     //If the filter bank mode is a 32 bit List mode
     CAN_Filter.AFnR.List32.List0.SID       = 0x000;   // List0 ID's SID  (Base ID)
     CAN_Filter.AFnR.List32.List0.EID       = 0x00000; // List0 ID's EID  (ID extension)
     CAN_Filter.AFnR.List32.List0.IDE       = 0;       // List0 ID's IDE  (IDE)
     CAN_Filter.AFnR.List32.List0.RTR       = 0;       // List0 ID's RTR  (RTR)
                                            
     CAN_Filter.AFnR.List32.List1.SID       = 0x000;   // List1 ID's SID  (Base ID)
     CAN_Filter.AFnR.List32.List1.EID       = 0x00000; // List1 ID's EID  (ID extension)
     CAN_Filter.AFnR.List32.List1.IDE       = 0;       // List1 ID's IDE  (IDE)
     CAN_Filter.AFnR.List32.List1.RTR       = 0;       // List1 ID's RTR  (RTR)
     CAN_AccptanceFilter_Config(CAN0,CAN_Filter1,&CAN_Filter);
     
     //If the filter bank mode is a 16 bit Mask mode
     CAN_Filter.AFnR.Mask16.ID0.SID         = 0x000;   // Compare0 ID's SID (Base ID)
     CAN_Filter.AFnR.Mask16.ID0.EID_17_15   = 0x00000; // Compare0 ID's EID (ID extension)
     CAN_Filter.AFnR.Mask16.ID0.IDE         = 0;       // Compare0 ID's IDE
     CAN_Filter.AFnR.Mask16.ID0.RTR         = 0;       // Compare0 ID's RTR
                                                       
     CAN_Filter.AFnR.Mask16.Mask0.SID       = 0x000;   // Mask0 ID's SID (Base ID) (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask16.Mask0.EID_17_15 = 0x00000; // Mask0 ID's EID (ID extension ID17 to ID15) (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask16.Mask0.IDE       = 1;       // Mask0 ID's IDE (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask16.Mask0.RTR       = 1;       // Mask0 ID's RTR (0: Don't care, 1: Must match)
     
     CAN_Filter.AFnR.Mask16.ID1.SID         = 0x000;   // Compare1 ID's SID (Base ID)
     CAN_Filter.AFnR.Mask16.ID1.EID_17_15   = 0x00000; // Compare1 ID's EID (ID extension)
     CAN_Filter.AFnR.Mask16.ID1.IDE         = 0;       // Compare1 ID's IDE
     CAN_Filter.AFnR.Mask16.ID1.RTR         = 0;       // Compare1 ID's RTR
                                                       
     CAN_Filter.AFnR.Mask16.Mask1.SID       = 0x000;   // Mask1 ID's SID (Base ID) (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask16.Mask1.EID_17_15 = 0x00000; // Mask1 ID's EID (ID extension ID17 to ID15) (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask16.Mask1.IDE       = 1;       // Mask1 ID's IDE (0: Don't care, 1: Must match)
     CAN_Filter.AFnR.Mask16.Mask1.RTR       = 1;       // Mask1 ID's RTR (0: Don't care, 1: Must match)
     CAN_AccptanceFilter_Config(CAN0,CAN_Filter2,&CAN_Filter);
     
     //If the filter bank mode is a 16 bit List mode
     CAN_Filter.AFnR.List16.List0.SID       = 0x000;   // List0 ID's SID  (Base ID)
     CAN_Filter.AFnR.List16.List0.EID_17_15 = 0x0;     // List0 ID's EID  (ID extension ID17 to ID15)
     CAN_Filter.AFnR.List16.List0.IDE       = 0;       // List0 ID's IDE  (IDE)
     CAN_Filter.AFnR.List16.List0.RTR       = 0;       // List0 ID's RTR  (RTR)
     
     CAN_Filter.AFnR.List16.List1.SID       = 0x000;   // List1 ID's SID  (Base ID)
     CAN_Filter.AFnR.List16.List1.EID_17_15 = 0x00000; // List1 ID's EID  (ID extension ID17 to ID15)
     CAN_Filter.AFnR.List16.List1.IDE       = 0;       // List1 ID's IDE  (IDE)
     CAN_Filter.AFnR.List16.List1.RTR       = 0;       // List1 ID's RTR  (RTR)
     
     CAN_Filter.AFnR.List16.List2.SID       = 0x000;   // List2 ID's SID  (Base ID)
     CAN_Filter.AFnR.List16.List2.EID_17_15 = 0x00000; // List2 ID's EID  (ID extension ID17 to ID15)
     CAN_Filter.AFnR.List16.List2.IDE       = 0;       // List2 ID's IDE  (IDE)
     CAN_Filter.AFnR.List16.List2.RTR       = 0;       // List2 ID's RTR  (RTR)
     
     CAN_Filter.AFnR.List16.List3.SID       = 0x000;   // List3 ID's SID  (Base ID) 
     CAN_Filter.AFnR.List16.List3.EID_17_15 = 0x00000; // List3 ID's EID  (ID extension ID17 to ID15)
     CAN_Filter.AFnR.List16.List3.IDE       = 0;       // List3 ID's IDE  (IDE)
     CAN_Filter.AFnR.List16.List3.RTR       = 0;       // List3 ID's RTR  (RTR)
     CAN_AccptanceFilter_Config(CAN0,CAN_Filter3,&CAN_Filter);
 * @endcode           
 *******************************************************************************
 */
void CAN_AccptanceFilter_Config( CAN_Struct* CANx, CAN_FilterIndex_TypeDef CANx_FL_Index, CAN_Filter_TypeDef* CAN_Filter_Config)
{
    CAN_Filter_TypeDef* CANx_FLx;
    
    CANx_FLx = (CAN_Filter_TypeDef*)((((uint32_t)CANx) + CAN_FILTER_SHIFT) + \
                                     (CAN_FILTERX_SHIFT * CANx_FL_Index));
    
    CANx_FLx->AFnR.W[0] = CAN_Filter_Config->AFnR.W[0];
    CANx_FLx->AFnR.W[1] = CAN_Filter_Config->AFnR.W[1];

}

///@}



/**
 * @name Error related
 *             
 */ 
///@{
/**
 *******************************************************************************
 * @brief	  Get transmit error counter.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.   
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_TransmitErrorCounterTmp = CAN_GetTXErrorCounter(CAN0);
 * @endcode            
 *******************************************************************************
 */
uint8_t CAN_GetTXErrorCounter( CAN_Struct* CANx)
{
    return( CANx->CR3.MBIT.TXERR_CNT);
}

/**
 *******************************************************************************
 * @brief	  Get receive error counter.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.   
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_ReceiveErrorCounterTmp = CAN_GetRXErrorCounter(CAN0);
 * @endcode            
 *******************************************************************************
 */
uint8_t CAN_GetRXErrorCounter( CAN_Struct* CANx)
{
    return( CANx->CR3.MBIT.TXERR_CNT);
}

/**
 *******************************************************************************
 * @brief	  Receive error counter mode select
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.   
 * @param[in] CAN_RxErr_Mode:
 *   @arg\b   CAN_RXErrorMode_Normal : Receive error counter increased if receive error counter next value less than 255.
 *   @arg\b   CAN_RXErrorMode_Passive: Receive error counter increased until fault confinement state is error passive.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_RXErrorCounterMode_Select( CAN0, CAN_RXError_Mode_Normal);
 * @endcode            
 *******************************************************************************
 */
void CAN_RXErrorCounterMode_Select( CAN_Struct* CANx, CAN_RxErrorCounterMode_TypeDef CAN_RxErr_Mode)
{
    CANx->CR3.B[3] =  ((CANx->CR3.B[3] & ((~CAN_CR3_RXERR_MDS_mask_b3))) | CAN_RxErr_Mode);
    
}

/**
 *******************************************************************************
 * @brief	  Set error warning limit compare value.   
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.  
 * @param[in] CAN_EW_Limit: 1 ~ 255
 * @return      
 * @exception No
 * @note      When error count pass the setting value(from more than the value to less than the value and vice versa)
              will setting EWF flag.  
 * @par       Example
 * @code
     CAN_SetErrorWarningLimit( CAN0, 100);
 * @endcode             
 *******************************************************************************
 */
void CAN_SetErrorWarningLimit( CAN_Struct *CANx, uint8_t CAN_EW_Limit)
{
    CANx->CR3.B[0] = ((CANx->CR3.B[0] & (~CAN_CR3_EW_LIM_mask_b0)) | CAN_EW_Limit);
}
/**
 *******************************************************************************
 * @brief	  Set receive error counter value.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_RXError_Counter: (0~255)
 * @return      
 * @exception No
 * @note      
 *   \n       *.The function is only used in operation mode is initial mode.
 *   \n       *.When receive error counter be set equals or exceeds 128 the CAN module into "error passive" state.        
 * @par       Example
 * @code
     CAN_SetRXErrorCounter( CAN0, 48);
 * @endcode             
 *******************************************************************************
 */
void CAN_SetRXErrorCounter( CAN_Struct *CANx, uint8_t CAN_RXError_Counter)
{
    CANx->CR3.B[1] = ((CANx->CR3.B[1] & (~CAN_CR3_RXERR_CNT_mask_b1)) | CAN_RXError_Counter);
}
/**
 *******************************************************************************
 * @brief	  Set transmit error counter value.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_TXError_Counter: (0~255)   
 * @return      
 * @exception No
 * @note
 *   \n      *.The function is only used in operation mode is initial mode.
 *   \n      *.When transmit error counter be set 128 ~ 254 the CAN module into "error passive" state.   
 *   \n      *.When transmit error counter be set equals 255 the CAN module into "bus off" state.
 * @par      Example
 * @code
     CAN_SetTXErrorCounter( CAN0, 28);
 * @endcode             
 *******************************************************************************
 */
void CAN_SetTXErrorCounter( CAN_Struct *CANx, uint8_t CAN_TXError_Counter)
{
    CANx->CR3.B[2] = ((CANx->CR3.B[2] & (~CAN_CR3_TXERR_CNT_mask_b2)) | CAN_TXError_Counter);
}


/**
 *******************************************************************************
 * @brief	  Get Error Code
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.  
 * @return    Last error code 
 * @exception No
 * @note      The error code define can refer to CAN_ErrorCode.
 *   \n Bit 10..8 : Error Code:
 *   \n             - CAN_ERR_CODE_BIT   : Bit error
 *   \n             - CAN_ERR_CODE_FORM  : Form error
 *   \n             - CAN_ERR_CODE_STUFF : Stuff error
 *   \n             - CAN_ERR_CODE_CRC   : CRC error
 *   \n             - CAN_ERR_CODE_OTHER : the other error
 *   \n Bit 7     : Error Direction:
 *   \n             - CAN_ERR_DIR_TX     : The error occurred during reception.
 *   \n             - CAN_ERR_DIR_RX     : The error occurred during transmission.
 *   \n Bit 4..0  : Error Segment Code:
 *   \n             - CAN_ERR_SCODE_ID28_ID21     : ID28 to ID21
 *   \n             - CAN_ERR_SCODE_SOF           : Start of frame
 *   \n             - CAN_ERR_SCODE_SRTR          : SRTR bit
 *   \n             - CAN_ERR_SCODE_IDE           : IDE bit
 *   \n             - CAN_ERR_SCODE_ID20_ID18     : ID20 to ID18
 *   \n             - CAN_ERR_SCODE_ID17_ID13     : ID17 to ID13
 *   \n             - CAN_ERR_SCODE_CRC           : CRC sequence
 *   \n             - CAN_ERR_SCODE_RESBIT0       : Reserved bit 0
 *   \n             - CAN_ERR_SCODE_DATAFIELD     : Data Field
 *   \n             - CAN_ERR_SCODE_DLC           : Data Length Code
 *   \n             - CAN_ERR_SCODE_RTR           : RTR bit
 *   \n             - CAN_ERR_SCODE_RESBIT1       : Reserved bit 1
 *   \n             - CAN_ERR_SCODE_ID4_ID0       : ID4 to ID0
 *   \n             - CAN_ERR_SCODE_ID12_ID5      : ID12 to ID5
 *   \n             - CAN_ERR_SCODE_AERROR        : Active error flag
 *   \n             - CAN_ERR_SCODE_INTERMISSION  : Intermission
 *   \n             - CAN_ERR_SCODE_TOLERATE      : Tolerate dominant bits
 *   \n             - CAN_ERR_SCODE_PERROR        : Passive error flag
 *   \n             - CAN_ERR_SCODE_ERRORDELIMITER: Error delimiter
 *   \n             - CAN_ERR_SCODE_CRCDELIMITER  : CRC delimiter
 *   \n             - CAN_ERR_SCODE_ACK           : Acknowledge
 *   \n             - CAN_ERR_SCODE_EOF           : End of frame
 *   \n             - CAN_ERR_SCODE_ACKDELIMITER  : Acknowledge delimiter
 *   \n             - CAN_ERR_SCODE_OVERLOADFRAME : Overload frame
 * @par       Example
 * @code
     CAN_IT_Flag = CAN_GetITAllFlagStatus(CAN0);
     
     if( CAN_IT_Flag & CAN_IT_BERR)
     {
         CAN_ErrorCodeTmp = CAN_GetErrorCode(CAN0);
     }
 * @endcode            
 *******************************************************************************
 */
uint16_t CAN_GetErrorCode( CAN_Struct* CANx)
{
    return( CANx->STA3.H[0]);
}

/**
 *******************************************************************************
 * @brief	  Get arbitration lost bit position. 
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.    
 * @return      
 * @exception No
 * @note      The arbitration lost bit position define can refer to CAN_ArbitrationLostCode. 
 * @par       Example
 * @code
     CAN_IT_Flag = CAN_GetITAllFlagStatus(CAN0);

     if( CAN_IT_Flag & CAN_IT_ALOS)
     {
         CAN_ArbitrationLostTmp = CAN_GetArbitrationLostBit(CAN0);
     } 
 * @endcode            
 *******************************************************************************
 */
uint8_t  CAN_GetArbitrationLostBit( CAN_Struct* CANx)
{
    return(CANx->STA3.B[2]);
}
///@}


/**
 * @name Signal related
 *             
 */ 
///@{
/**
 *******************************************************************************
 * @brief	  CAN TX output signal inverse enable or disable.  
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_TXInv_EN:
 *   @arg\b   DISABLE: CAN TX output signal no inverse.
 *   @arg\b   ENABLE : CAN TX output signal inverse.
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_TXInverse_Cmd( CAN0, DISABLE);
 * @endcode             
 *******************************************************************************
 */
void CAN_TXInverse_Cmd( CAN_Struct* CANx, FunctionalState CAN_TXInv_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_TX_INV_mask_w)) | (CAN_CR0_TX_INV_mask_w * CAN_TXInv_EN));
}

/**
 *******************************************************************************
 * @brief	  CAN RX input signal inverse enable or disable.
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_RXInv_EN:
 *   @arg\b   DISABLE: CAN RX input signal no inverse.
 *   @arg\b   ENABLE : CAN RX input signal inverse.  
 * @return      
 * @exception   No
 * @note 
 * @par         Example
 * @code
     CAN_RXInverse_Cmd( CAN0, DISABLE);
 * @endcode              
 *******************************************************************************
 */
void CAN_RXInverse_Cmd( CAN_Struct* CANx, FunctionalState CAN_RXInv_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_RX_INV_mask_w)) | (CAN_CR0_RX_INV_mask_w * CAN_RXInv_EN));
}

/**
 *******************************************************************************
 * @brief	  CAN_TX pin and CAN_RX pin swap enable or disable.  
 * @details     
 * @param[in] CANx: 
 *   @arg\b   CAN0: CAN0 module control.
 * @param[in] CAN_RxTxSwap_EN:
 *   @arg\b   DISABLE: CAN_TX and CAN_RX pin no swap.
 *   @arg\b   ENABLE : CAN_TX and CAN_RX pin swap.  
 * @return      
 * @exception No
 * @note 
 * @par       Example
 * @code
     CAN_RxTxSwap_Cmd(CAN0,ENABLE);
 * @endcode             
 *******************************************************************************
 */
void CAN_RxTxSwap_Cmd( CAN_Struct* CANx, FunctionalState CAN_RxTxSwap_EN)
{
    CANx->CR0.W = ((CANx->CR0.W & (~CAN_CR0_IO_SWP_mask_w)) | ( CAN_CR0_IO_SWP_mask_w * CAN_RxTxSwap_EN));
}

///@}





#endif
























