

/**
 ******************************************************************************
 *
 * @file        MG32_CAN_Init.c
 * @brief       MG32 CAN configure C Code. 
 *
 * @par         Project
 *              MG32
 * @version     V1.05
 * @date        2025/07/04
 * @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_CAN_Init.h"
#include "RTE_Components.h"
#if defined(IRQHandler_Middleware_Level_)
#include "MG32_CAN_MID.h"
#endif

/* Cofigure Common Related----------------------------------------------------*/

#define CAN_CR0_TST_MDS_shift_w   4
#define CAN_CLK_CK_SEL_shift_w    2


#define CONF_CAN_RBUF_SEL_TWO     0
#define CONF_CAN_RBUF_SEL_ONE     1

#define CONF_CAN_AFn_FSEL_FIFO0   0
#define CONF_CAN_AFn_FSEL_FIFO1   1


#define CONF_CAN_INT    0
#define CONF_CAN_CLK    1
#define CONF_CAN_CR0    2
#define CONF_CAN_CR1    3
#define CONF_CAN_CR3    4
#define CONF_CAN_AFC0   5
#define CONF_CAN_AFC1   6
#define CONF_CAN_AFn    7


#define CONF_CAN_AFn_INDEX    0
#define CONF_CAN_AFnR0        1
#define CONF_CAN_AFnR1        2


/* CAN0 Related Configure-----------------------------------------------------*/

#if defined(CAN0_Base) && CONF_CAN0_INIT_EN == 1
static const uint32_t CONF_CAN0_FL[] = 
{
    #if CONF_CAN0_AF0_EN == 1
        0,
        #if (CONF_CAN0_AF0_CFGMDS == CAN_FILTER_MODE_32BIT_MASK)
            (CONF_CAN0_AF0_32MSKAF0), 
            (CONF_CAN0_AF0_32MSKAF1),
        #endif
        #if (CONF_CAN0_AF0_CFGMDS == CAN_FILTER_MODE_16BIT_MASK)
            (CONF_CAN0_AF0_16MSKAF00 | CONF_CAN0_AF0_16MSKAF01),
            (CONF_CAN0_AF0_16MSKAF10 | CONF_CAN0_AF0_16MSKAF11),
        #endif
        #if (CONF_CAN0_AF0_CFGMDS == CAN_FILTER_MODE_32BIT_LIST)
            (CONF_CAN0_AF0_32LISTAF0),
            (CONF_CAN0_AF0_32LISTAF1),
        #endif
        #if (CONF_CAN0_AF0_CFGMDS == CAN_FILTER_MODE_16BIT_LIST)
            (CONF_CAN0_AF0_16LISTAF00 | CONF_CAN0_AF0_16LISTAF01),
            (CONF_CAN0_AF0_16LISTAF10 | CONF_CAN0_AF0_16LISTAF11),
        #endif
    #endif
    #if CONF_CAN0_AF1_EN == 1
        1,
        #if (CONF_CAN0_AF1_CFGMDS == CAN_FILTER_MODE_32BIT_MASK)
            (CONF_CAN0_AF1_32MSKAF0), 
            (CONF_CAN0_AF1_32MSKAF1),
        #endif
        #if (CONF_CAN0_AF1_CFGMDS == CAN_FILTER_MODE_16BIT_MASK)
            (CONF_CAN0_AF1_16MSKAF00 | CONF_CAN0_AF1_16MSKAF01),
            (CONF_CAN0_AF1_16MSKAF10 | CONF_CAN0_AF1_16MSKAF11),
        #endif
        #if (CONF_CAN0_AF1_CFGMDS == CAN_FILTER_MODE_32BIT_LIST)
            (CONF_CAN0_AF1_32LISTAF0),
            (CONF_CAN0_AF1_32LISTAF1),
        #endif
        #if (CONF_CAN0_AF1_CFGMDS == CAN_FILTER_MODE_16BIT_LIST)
            (CONF_CAN0_AF1_16LISTAF00 | CONF_CAN0_AF1_16LISTAF01),
            (CONF_CAN0_AF1_16LISTAF10 | CONF_CAN0_AF1_16LISTAF11),
        #endif        
    #endif
    #if CONF_CAN0_AF2_EN == 1
        2,
        #if (CONF_CAN0_AF2_CFGMDS == CAN_FILTER_MODE_32BIT_MASK)
            (CONF_CAN0_AF2_32MSKAF0), 
            (CONF_CAN0_AF2_32MSKAF1),
        #endif
        #if (CONF_CAN0_AF2_CFGMDS == CAN_FILTER_MODE_16BIT_MASK)
            (CONF_CAN0_AF2_16MSKAF00 | CONF_CAN0_AF2_16MSKAF01),
            (CONF_CAN0_AF2_16MSKAF10 | CONF_CAN0_AF2_16MSKAF11),
        #endif
        #if (CONF_CAN0_AF2_CFGMDS == CAN_FILTER_MODE_32BIT_LIST)
            (CONF_CAN0_AF2_32LISTAF0),
            (CONF_CAN0_AF2_32LISTAF1),
        #endif
        #if (CONF_CAN0_AF2_CFGMDS == CAN_FILTER_MODE_16BIT_LIST)
            (CONF_CAN0_AF2_16LISTAF00 | CONF_CAN0_AF2_16LISTAF01),
            (CONF_CAN0_AF2_16LISTAF10 | CONF_CAN0_AF2_16LISTAF11),
        #endif      
    #endif
    #if CONF_CAN0_AF3_EN == 1
        3,
        #if (CONF_CAN0_AF3_CFGMDS == CAN_FILTER_MODE_32BIT_MASK)
            (CONF_CAN0_AF3_32MSKAF0), 
            (CONF_CAN0_AF3_32MSKAF1),
        #endif
        #if (CONF_CAN0_AF3_CFGMDS == CAN_FILTER_MODE_16BIT_MASK)
            (CONF_CAN0_AF3_16MSKAF00 | CONF_CAN0_AF3_16MSKAF01),
            (CONF_CAN0_AF3_16MSKAF10 | CONF_CAN0_AF3_16MSKAF11),
        #endif
        #if (CONF_CAN0_AF3_CFGMDS == CAN_FILTER_MODE_32BIT_LIST)
            (CONF_CAN0_AF3_32LISTAF0),
            (CONF_CAN0_AF3_32LISTAF1),
        #endif
        #if (CONF_CAN0_AF3_CFGMDS == CAN_FILTER_MODE_16BIT_LIST)
            (CONF_CAN0_AF3_16LISTAF00 | CONF_CAN0_AF3_16LISTAF01),
            (CONF_CAN0_AF3_16LISTAF10 | CONF_CAN0_AF3_16LISTAF11),
        #endif      
    #endif
    #if CONF_CAN0_AF4_EN == 1
        4,
        #if (CONF_CAN0_AF4_CFGMDS == CAN_FILTER_MODE_32BIT_MASK)
            (CONF_CAN0_AF4_32MSKAF0), 
            (CONF_CAN0_AF4_32MSKAF1),
        #endif
        #if (CONF_CAN0_AF4_CFGMDS == CAN_FILTER_MODE_16BIT_MASK)
            (CONF_CAN0_AF4_16MSKAF00 | CONF_CAN0_AF4_16MSKAF01),
            (CONF_CAN0_AF4_16MSKAF10 | CONF_CAN0_AF4_16MSKAF11),
        #endif
        #if (CONF_CAN0_AF4_CFGMDS == CAN_FILTER_MODE_32BIT_LIST)
            (CONF_CAN0_AF4_32LISTAF0),
            (CONF_CAN0_AF4_32LISTAF1),
        #endif
        #if (CONF_CAN0_AF4_CFGMDS == CAN_FILTER_MODE_16BIT_LIST)
            (CONF_CAN0_AF4_16LISTAF00 | CONF_CAN0_AF4_16LISTAF01),
            (CONF_CAN0_AF4_16LISTAF10 | CONF_CAN0_AF4_16LISTAF11),
        #endif     
    #endif
    #if CONF_CAN0_AF5_EN == 1
        5,
        #if (CONF_CAN0_AF5_CFGMDS == CAN_FILTER_MODE_32BIT_MASK)
            (CONF_CAN0_AF5_32MSKAF0), 
            (CONF_CAN0_AF5_32MSKAF1),
        #endif
        #if (CONF_CAN0_AF5_CFGMDS == CAN_FILTER_MODE_16BIT_MASK)
            (CONF_CAN0_AF5_16MSKAF00 | CONF_CAN0_AF5_16MSKAF01),
            (CONF_CAN0_AF5_16MSKAF10 | CONF_CAN0_AF5_16MSKAF11),
        #endif
        #if (CONF_CAN0_AF5_CFGMDS == CAN_FILTER_MODE_32BIT_LIST)
            (CONF_CAN0_AF5_32LISTAF0),
            (CONF_CAN0_AF5_32LISTAF1),
        #endif
        #if (CONF_CAN0_AF5_CFGMDS == CAN_FILTER_MODE_16BIT_LIST)
            (CONF_CAN0_AF5_16LISTAF00 | CONF_CAN0_AF5_16LISTAF01),
            (CONF_CAN0_AF5_16LISTAF10 | CONF_CAN0_AF5_16LISTAF11),
        #endif     
    #endif
    #if CONF_CAN0_AF0_EN == 0 && CONF_CAN0_AF1_EN == 0 && CONF_CAN0_AF2_EN == 0 && CONF_CAN0_AF3_EN == 0 && CONF_CAN0_AF4_EN == 0 && CONF_CAN0_AF5_EN == 0
        0x00,
    #endif
};

static const uint32_t CONF_CAN0[] = 
{
    /*Interrupt register*/
    #if 1
        ((CONF_CAN0_TX2_IE    * CAN_INT_TX2_IE_mask_w)    | 
         (CONF_CAN0_TX1_IE    * CAN_INT_TX1_IE_mask_w)    |
         (CONF_CAN0_TX0_IE    * CAN_INT_TX0_IE_mask_w)    |
         (CONF_CAN0_RPEND1_IE * CAN_INT_RPEND1_IE_mask_w) |
         (CONF_CAN0_ROVR1_IE  * CAN_INT_ROVR1_IE_mask_w)  |
         (CONF_CAN0_RFUL1_IE  * CAN_INT_RFUL1_IE_mask_w)  |
         (CONF_CAN0_RX1_IE    * CAN_INT_RX1_IE_mask_w)    |
         (CONF_CAN0_RPEND0_IE * CAN_INT_RPEND0_IE_mask_w) |
         (CONF_CAN0_ROVR0_IE  * CAN_INT_ROVR0_IE_mask_w)  |
         (CONF_CAN0_RFUL0_IE  * CAN_INT_RFUL0_IE_mask_w)  |
         (CONF_CAN0_RX0_IE    * CAN_INT_RX0_IE_mask_w)    |
         (CONF_CAN0_BERR_IE   * CAN_INT_BERR_IE_mask_w)   |
         (CONF_CAN0_ALOS_IE   * CAN_INT_ALOS_IE_mask_w)   |
         (CONF_CAN0_EP_IE     * CAN_INT_EP_IE_mask_w)     |
         (CONF_CAN0_WUP_IE    * CAN_INT_WUP_IE_mask_w)    |
         (CONF_CAN0_EW_IE     * CAN_INT_EW_IE_mask_w)     |
         (CONF_CAN0_BUS_IE    * CAN_INT_BUS_IE_mask_w)    |
         (CONF_CAN0_IEA       * CAN_INT_IEA_mask_w)),
    #endif
    /*Clock source register*/
    #if 1
        (((CONF_CAN0_BRP - 1) << CAN_CLK_BRP_shift_w) | 
         (CONF_CAN0_SEL       << CAN_CLK_CK_SEL_shift_w)),
    #endif
    /*Control register 0*/
    #if 1
        ((CONF_CAN0_TX_PRI   * CAN_CR0_TX_PRI_mask_w)   |
         (CONF_CAN0_RBUF_SEL * CAN_CR0_RBUF_SEL_mask_w) |
         (CONF_CAN0_ROVR_MDS * CAN_CR0_ROVR_MDS_mask_w) |
         (CONF_CAN0_TXE_MDS  * CAN_CR0_TXE_MDS_mask_w)  |
         #if CONF_CAN0_FDT_MDS == 1
             (CONF_CAN0_EDF_MDS * CAN_CR0_EDF_MDS_mask_w) | 
         #endif
         (CONF_CAN0_FDT_MDS  * CAN_CR0_FDT_MDS_mask_w)  |
         (CONF_CAN0_IO_SWP   *CAN_CR0_IO_SWP_mask_w)    |
         (1                  *CAN_CR0_OS_MDS_one_w)     |
         (CONF_CAN0_TST_MDS  <<CAN_CR0_TST_MDS_shift_w) |
         (CONF_CAN0_WUP_MDS  *CAN_CR0_WUP_MDS_mask_w)   |
         (CAN_CR0_INIT_EN_enable_w)                     |
         (CAN_CR0_EN_enable_w)),
    #endif
    /*Control register 1*/
    #if 1
        ((CONF_CAN0_TSEG1 << CAN_CR1_TSEG1_shift_w) | 
         (CONF_CAN0_TSEG2 << CAN_CR1_TSEG2_shift_w) |
         (CONF_CAN0_SJW   << CAN_CR1_SJW_shift_w)),
    #endif
    /*Control register 3*/
    #if 1
        (CONF_CAN0_EW_LIM << CAN_CR3_EW_LIM_shift_w),
    #endif
    /*Acceptance filter control register 0*/
    #if 1
        (
        #if CONF_CAN0_AF0_EN == 1
            #if (CONF_CAN0_RBUF_SEL == CONF_CAN_RBUF_SEL_ONE) && (CONF_CAN0_AF0_FSEL == CONF_CAN_AFn_FSEL_FIFO1)
                #error Acceptance filter use FIFO1 error because FIFO mode only one FIFO.
            #else
                ((CONF_CAN0_AF0_FSEL * CAN_AFC0_AF0_FSEL_mask_w) | CAN_AFC0_AF0_EN_enable_w) |
            #endif
        #endif
        #if CONF_CAN0_AF1_EN == 1
            #if (CONF_CAN0_RBUF_SEL == CONF_CAN_RBUF_SEL_ONE) && (CONF_CAN0_AF1_FSEL == CONF_CAN_AFn_FSEL_FIFO1)
                #error Acceptance filter use FIFO1 error because FIFO mode only one FIFO.
            #else
                ((CONF_CAN0_AF1_FSEL * CAN_AFC0_AF1_FSEL_mask_w) | CAN_AFC0_AF1_EN_enable_w) |
            #endif
        #endif
        #if CONF_CAN0_AF2_EN == 1
            #if (CONF_CAN0_RBUF_SEL == CONF_CAN_RBUF_SEL_ONE) && (CONF_CAN0_AF2_FSEL == CONF_CAN_AFn_FSEL_FIFO1)
                #error Acceptance filter use FIFO1 error because FIFO mode only one FIFO.
            #else
                ((CONF_CAN0_AF2_FSEL * CAN_AFC0_AF2_FSEL_mask_w) | CAN_AFC0_AF2_EN_enable_w) |
            #endif
        #endif
        #if CONF_CAN0_AF3_EN == 1
            #if (CONF_CAN0_RBUF_SEL == CONF_CAN_RBUF_SEL_ONE) && (CONF_CAN0_AF3_FSEL == CONF_CAN_AFn_FSEL_FIFO1)
                #error Acceptance filter use FIFO1 error because FIFO mode only one FIFO.
            #else
                ((CONF_CAN0_AF3_FSEL * CAN_AFC0_AF3_FSEL_mask_w) | CAN_AFC0_AF3_EN_enable_w) |
            #endif
        #endif
        #if CONF_CAN0_AF4_EN == 1
            #if (CONF_CAN0_RBUF_SEL == CONF_CAN_RBUF_SEL_ONE) && (CONF_CAN0_AF4_FSEL == CONF_CAN_AFn_FSEL_FIFO1)
                #error Acceptance filter use FIFO1 error because FIFO mode only one FIFO.
            #else
                ((CONF_CAN0_AF4_FSEL * CAN_AFC0_AF4_FSEL_mask_w) | CAN_AFC0_AF4_EN_enable_w) |
            #endif
        #endif
        #if CONF_CAN0_AF5_EN == 1
            #if (CONF_CAN0_RBUF_SEL == CONF_CAN_RBUF_SEL_ONE) && (CONF_CAN0_AF5_FSEL == CONF_CAN_AFn_FSEL_FIFO1)
                #error Acceptance filter use FIFO1 error because FIFO mode only one FIFO.
            #else
                ((CONF_CAN0_AF5_FSEL * CAN_AFC0_AF5_FSEL_mask_w) | CAN_AFC0_AF5_EN_enable_w) |
            #endif
        #endif
        (0x00000000)),
    #endif
    /*Acceptance filter control register 1*/
    #if 1
        (
        #if CONF_CAN0_AF0_EN == 1
            ((uint32_t)(CONF_CAN0_AF0_CFGMDS << 0)) |
        #endif
        #if CONF_CAN0_AF1_EN == 1
            ((uint32_t)(CONF_CAN0_AF1_CFGMDS << 1)) |
        #endif
        #if CONF_CAN0_AF2_EN == 1
            ((uint32_t)(CONF_CAN0_AF2_CFGMDS << 2)) |
        #endif
        #if CONF_CAN0_AF3_EN == 1
            ((uint32_t)(CONF_CAN0_AF3_CFGMDS << 3)) |
        #endif
        #if CONF_CAN0_AF4_EN == 1
            ((uint32_t)(CONF_CAN0_AF4_CFGMDS << 4)) |
        #endif
        #if CONF_CAN0_AF5_EN == 1
            ((uint32_t)(CONF_CAN0_AF5_CFGMDS << 5)) |
        #endif
        (0x00000000)),
    #endif
    /*Which Acceptance filter need to set*/
    #if 1
        (sizeof(CONF_CAN0_FL)/12),
    #endif
};



#endif

/* Private variables ---------------------------------------------------------*/
#if defined(IRQHandler_Middleware_Level_)
    CAN_HandleTypeDef  mCAN0;
#endif


/* Private function prototypes -----------------------------------------------*/
#if defined(CAN0_Base) && CONF_CAN0_INIT_EN == 1 
static void CANx_Config(CAN_Struct* CANx_Module, const uint32_t *CANn_Setting, const uint32_t *CANn_FL_Setting);
#endif

/**
 *******************************************************************************
 * @brief	     CAN configure function.
 * @details                                           
 * @param[in]  CANx_Module: CAN Module.
 * @param[in]  CANn_Setting: Setting table pointer.
 * @param[in]  CANn_FL_Setting : CANn Filter setting table pointer
 * @return     
 * @exception   
 * @note        
 *******************************************************************************
 */
#if defined(CAN0_Base) && CONF_CAN0_INIT_EN == 1 
    static void CANx_Config(CAN_Struct* CANx_Module, const uint32_t *CANn_Setting, const uint32_t *CANn_FL_Setting)
    {
             uint8_t   CANx_Config_Tmp;
        __IO uint32_t  *CANx_Config_FLReg;
    
        
        /*CAN module into initial mode*/
        CANx_Module->CR0.W = (CAN_CR0_INIT_EN_mask_w | CAN_CR0_EN_mask_w);
        
        /*Bit rate configure*/
        CANx_Module->CLK.W = CANn_Setting[CONF_CAN_CLK];
        CANx_Module->CR1.W = CANn_Setting[CONF_CAN_CR1];
        
        /*Mode related configure*/
        CANx_Module->CR0.W = CANn_Setting[CONF_CAN_CR0];
        
        /*Error related configure*/
        CANx_Module->CR3.W = CANn_Setting[CONF_CAN_CR3];
        
        /*Filter configure*/
        CANx_Module->AFC0.W = CANn_Setting[CONF_CAN_AFC0];
        CANx_Module->AFC1.W = CANn_Setting[CONF_CAN_AFC1];
        
        for( CANx_Config_Tmp = 0; CANx_Config_Tmp < CANn_Setting[CONF_CAN_AFn]; CANx_Config_Tmp++)
        {
            CANx_Config_FLReg  =  (&CANx_Module->AF0R0.W);
            CANx_Config_FLReg  += (2 * CANn_FL_Setting[((3 * CANx_Config_Tmp) + CONF_CAN_AFn_INDEX)]);
            *CANx_Config_FLReg =  CANn_FL_Setting[((3 * CANx_Config_Tmp) + CONF_CAN_AFnR0)];
            CANx_Config_FLReg++;
            *CANx_Config_FLReg = CANn_FL_Setting[((3 * CANx_Config_Tmp) + CONF_CAN_AFnR1)];
        }
    
        /*CAN Interupt configure*/
        CANx_Module->INT.W = CANn_Setting[CONF_CAN_INT];
        
    
    }
#endif

/**
 *******************************************************************************
 * @brief	  CAN inital function.  
 * @details                                                    
 * @return      
 * @exception   
 * @note        
 *******************************************************************************
 */
void CAN_Init(void)
{
    #if defined(CAN0_Base) && CONF_CAN0_INIT_EN == 1 
        #if defined(IRQHandler_Middleware_Level_)
            mCAN0.Instance           = CAN0;
            mCAN0.ErrorCode          = MID_CAN_ERROR_NONE;
            mCAN0.BusErrorCode       = 0;
            mCAN0.ArbitrationLostBit = 0;
            mCAN0.State              = MID_CAN_STATE_RESET;    
        #endif
        CANx_Config(CAN0,CONF_CAN0,CONF_CAN0_FL);
        #if defined(IRQHandler_Middleware_Level_)
            mCAN0.State = MID_CAN_STATE_READY;
        #endif
        CAN0_Init_CpltCallback();
    #endif
}

/**
 *******************************************************************************
 * @brief	  CAN inital complete callback function.  
 * @details                                                    
 * @return    
 * @exception   
 * @note        
 *******************************************************************************
 */
#if defined(CAN0_Base) && CONF_CAN0_INIT_EN == 1 
__WEAK void CAN0_Init_CpltCallback(void)
{
    //=========================================================
    //Note : This function should not be modified, when the function
    //       is needed, the function can be implemented in the user file.
}
#endif








