 /** 
  *******************************************************************************************************
  * @file    fm33lg0xx_fl_can.c
  * @author  FMSH Application Team
  * @brief   Src file of VAN fL Module
  *******************************************************************************************************
  * @attention
  *   
  * Copyright (c) 2022, SHANGHAI FUDAN MICROELECTRONICS GROUP CO., LTD.(FUDAN MICROELECTRONICS./ FUDAN MICRO.)    
  * All rights reserved.    
  *    
  * Processor:                   FM33LG0xxA    
  * http:                        http://www.fmdevelopers.com.cn/    
  *    
  * Redistribution and use in source and binary forms, with or without    
  * modification, are permitted provided that the following conditions are met    
  *    
  * 1. Redistributions of source code must retain the above copyright notice,    
  *    this list of conditions and the following disclaimer.    
  *    
  * 2. Redistributions in binary form must reproduce the above copyright notice,    
  *    this list of conditions and the following disclaimer in the documentation    
  *    and/or other materials provided with the distribution.    
  *    
  * 3. Neither the name of the copyright holder nor the names of its contributors    
  *    may be used to endorse or promote products derived from this software    
  *    without specific prior written permission.    
  *    
  * 4. To provide the most up-to-date information, the revision of our documents     
  *    on the World Wide Web will be the most Current. Your printed copy may be      
  *    an earlier revision. To verify you have the latest information avaliable,    
  *    refer to: http://www.fmdevelopers.com.cn/.    
  *    
  * THIS SOFTWARE IS PROVIDED BY FUDAN MICRO "AS IS" AND ANY EXPRESSED     
  * ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES     
  * OF MERCHANTABILITY NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE    
  * ARE DISCLAIMED.IN NO EVENT SHALL FUDAN MICRO OR ITS CONTRIBUTORS BE LIABLE     
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL     
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS     
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER    
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,     
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY WAY OUT OF THE     
  * USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE.    
 */    

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

/** @addtogroup FM33LG0XX_FL_Driver
  * @{
  */

/** @addtogroup CAN
  * @{
  */

#ifdef FL_CAN_DRIVER_ENABLED

/* Private macros ------------------------------------------------------------*/
/** @addtogroup CAN_FL_Private_Macros
  * @{
  */
#define IS_CAN_SJW(__VALUE__)  (((__VALUE__) == FL_CAN_SJW_1Tq) \
                                                             || ((__VALUE__) == FL_CAN_SJW_2Tq) \
                                                             || ((__VALUE__) == FL_CAN_SJW_3Tq) \
                                                             || ((__VALUE__) == FL_CAN_SJW_4Tq))


#define IS_CAN_TS1(__VALUE__)    (((__VALUE__) == FL_CAN_TS1_1Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_2Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_3Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_4Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_5Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_6Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_7Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_8Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_9Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_10Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_11Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_12Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_13Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_14Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_15Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS1_16Tq))



#define IS_CAN_TS2(__VALUE__)    (((__VALUE__) == FL_CAN_TS2_1Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS2_2Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS2_3Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS2_4Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS2_5Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS2_6Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS2_7Tq) \
                                                                 || ((__VALUE__) == FL_CAN_TS2_8Tq))


#define IS_CAN_FILTER_EN(__VALUE__)    (((__VALUE__) == FL_ENABLE) \
                                                                 || ((__VALUE__) == FL_DISABLE))


#define IS_CAN_AFx(__VALUE__)    (((__VALUE__) == FL_CAN_FILTER1) \
                                                                 || ((__VALUE__) == FL_CAN_FILTER2) \
                                                                 || ((__VALUE__) == FL_CAN_FILTER3) \
                                                                 || ((__VALUE__) == FL_CAN_FILTER4))


#define IS_CAN_MODE(__VALUE__)    (((__VALUE__) == FL_CAN_MODE_NORMAL) \
                                                                 || ((__VALUE__) == FL_CAN_MODE_LOOPBACK) \
                                                                 || ((__VALUE__) == FL_CAN_MODE_CONFIG))


#define IS_CAN_CLK(__VALUE__)    (((__VALUE__) == FL_CMU_CAN_CLK_SOURCE_RCHF) \
                                                                 || ((__VALUE__) == FL_CMU_CAN_CLK_SOURCE_XTHF) \
                                                                 || ((__VALUE__) == FL_CMU_CAN_CLK_SOURCE_PLL) \
                                                                 || ((__VALUE__) == FL_CMU_CAN_CLK_SOURCE_APBCLK))






#define IS_CAN_SRR(__VALUE__)     (((__VALUE__)==FL_CAN_SRR_BIT_LOW) ||((__VALUE__)==FL_CAN_SRR_BIT_HIGH))
#define IS_CAN_IDE(__VALUE__)     (((__VALUE__)==FL_CAN_IDE_BIT_LOW) ||((__VALUE__)==FL_CAN_IDE_BIT_HIGH))
#define IS_CAN_RTR(__VALUE__)     (((__VALUE__)==FL_CAN_RTR_BIT_LOW) ||((__VALUE__)==FL_CAN_RTR_BIT_HIGH))

#define IS_CAN_ID18_MASK(__VALUE__)         (__VALUE__<=262143U)
#define IS_CAN_ID11_MASK(__VALUE__)         (__VALUE__<=2047U)

#define IS_CAN_SRR_MASK(__VALUE__)          (((__VALUE__) == FL_ENABLE) \
                                                                 || ((__VALUE__) == FL_DISABLE))

#define IS_CAN_IDE_MASK(__VALUE__)          (((__VALUE__) == FL_ENABLE) \
                                                                 || ((__VALUE__) == FL_DISABLE))

#define IS_CAN_RTR_MASK(__VALUE__)          (((__VALUE__) == FL_ENABLE) \
                                                                 || ((__VALUE__) == FL_DISABLE))
/**
  * @}
  */

/* Exported functions --------------------------------------------------------*/
/** @addtogroup CAN_FL_EF_Init
  * @{
  */

/**
  * @brief  CAN初始化
  * @param  CANx外设入口地址
  * @param  CAN_InitStruct 指向一个@ref FL_CAN_InitTypeDef  结构体的指针
  * @retval 错误状态可能值
  *         -FL_FAIL 配置过程发生错误
  *         -FL_PASS 配置成功
  */
FL_ErrorStatus FL_CAN_Init(CAN_Type *CANx, FL_CAN_InitTypeDef *CAN_InitStruct)
{
    /*参数检查*/
    assert_param(IS_CAN_SJW(CAN_InitStruct->SJW));
    assert_param(IS_CAN_TS1(CAN_InitStruct->TS1));
    assert_param(IS_CAN_TS2(CAN_InitStruct->TS2));
    assert_param(IS_CAN_CLK(CAN_InitStruct->clockSource));
    /*时钟总线配置*/
    FL_CMU_EnableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_CAN);
    FL_CMU_EnableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_CAN);
    /*CAN时钟源选择*/
    FL_CMU_SetCANClockSource(CAN_InitStruct->clockSource);
    /*复位CAN模块*/
    FL_CAN_SetSoftwareReset(CANx, FL_CAN_SOFTWARE_RESET);
    /*设置同步段*/
    FL_CAN_WriteSyncJumpWidth(CANx, CAN_InitStruct->SJW);
    /*设置时间段1*/
    FL_CAN_WriteTimeSegment1Length(CANx, CAN_InitStruct->TS1);
    /*设置时间段2*/
    FL_CAN_WriteTimeSegment2Length(CANx, CAN_InitStruct->TS2);
    /*设置波特率*/
    FL_CAN_WriteBaudRatePrescaler(CANx, CAN_InitStruct->BRP);
    if(CAN_InitStruct->mode == FL_CAN_MODE_NORMAL)
    {
        FL_CAN_DisableLoopBackMode(CANx);    /* Normal模式 */
        FL_CAN_Enable(CANx);
    }
    else
        if(CAN_InitStruct->mode == FL_CAN_MODE_LOOPBACK)
        {
            FL_CAN_EnableLoopBackMode(CANx);    /* Loop Back模式 */
            FL_CAN_Enable(CANx);
        }
        else
        {
            FL_CAN_Disable(CANx);    /* Configuration模式 */
        }
    return FL_PASS;
}

/**
  * @brief  设置 CAN_InitStruct 为默认配置
  * @param  CAN_InitStruct 指向需要将值设置为默认配置的结构体 @ref FL_CAN_InitTypeDef 结构体
  *
  * @retval None
  */
void FL_CAN_StructInit(FL_CAN_InitTypeDef *CAN_InitStruct)
{
    CAN_InitStruct->mode = FL_CAN_MODE_NORMAL;
    CAN_InitStruct->BRP = 0;
    CAN_InitStruct->clockSource = FL_CMU_CAN_CLK_SOURCE_RCHF;
    CAN_InitStruct->SJW = FL_CAN_SJW_1Tq;
    CAN_InitStruct->TS1 = FL_CAN_TS1_5Tq;
    CAN_InitStruct->TS2 = FL_CAN_TS2_4Tq;
}

/**
  * @brief  CAN滤波器初始化
  * @param  CANx外设入口地址
  * @param  filterX This parameter can be one of the following values:
  *         @arg @ref  FL_CAN_FILTER1
  *         @arg @ref  FL_CAN_FILTER2
  *         @arg @ref  FL_CAN_FILTER3
  *         @arg @ref  FL_CAN_FILTER4
  * @param  CAN_InitFilterStruct 指向一个@ref FL_CAN_FilterInitTypeDef  结构体的指针
  * @retval 错误状态可能值
  *         -FL_FAIL 配置过程发生错误
  *         -FL_PASS 配置成功
  */
FL_ErrorStatus FL_CAN_FilterInit(CAN_Type *CANx, FL_CAN_FilterInitTypeDef *CAN_FilterInitStruct, uint32_t filterX)
{
    uint32_t counter =0;
    uint32_t filterstatus;
    assert_param(IS_CAN_SRR(CAN_FilterInitStruct->filterIdSRR));
    assert_param(IS_CAN_IDE(CAN_FilterInitStruct->filterIdIDE));
    assert_param(IS_CAN_RTR(CAN_FilterInitStruct->filterIdRTR));
    assert_param(IS_CAN_FILTER_EN(CAN_FilterInitStruct->filterEn));
    assert_param(IS_CAN_ID18_MASK(CAN_FilterInitStruct->filterMaskIdLow));
    assert_param(IS_CAN_ID11_MASK(CAN_FilterInitStruct->filterMaskIdHigh));
    assert_param(IS_CAN_SRR_MASK(CAN_FilterInitStruct->filterMaskIdSRR));
    assert_param(IS_CAN_IDE_MASK(CAN_FilterInitStruct->filterMaskIdIDE));
    assert_param(IS_CAN_RTR_MASK(CAN_FilterInitStruct->filterMaskIdRTR));
    assert_param(IS_CAN_AFx(filterX));
    do
    {
        filterstatus = FL_CAN_IsActiveFlag_FilterBusy(CANx);
        counter++;
    }while((filterstatus != 0U) && (counter != CAN_TIMEOUT));
    if(CAN_FilterInitStruct->filterIdIDE == FL_CAN_IDE_BIT_HIGH)
    {
        FL_CAN_Filter_WriteIDCompare(CANx, filterX, ((CAN_FilterInitStruct->filterIdExtend) >> 18) & 0X7FF);
        FL_CAN_Filter_WriteEXTIDCompare(CANx, filterX, (CAN_FilterInitStruct->filterIdExtend) & 0X3FFFF);
    }
    else
    {
        FL_CAN_Filter_WriteIDCompare(CANx, filterX, (CAN_FilterInitStruct->filterIdStandard) & 0X7FF);
    }
    if((CAN_FilterInitStruct->filterMaskIdSRR) == FL_ENABLE)    /* SRR参与滤波器比较 */
    {
        FL_CAN_Filter_EnableSRRCompare(CANx, filterX);
    }
    else
    {
        FL_CAN_Filter_DisableSRRCompare(CANx, filterX);
    }
    if((CAN_FilterInitStruct->filterMaskIdIDE) == FL_ENABLE)    /* IDE位参与滤波器比较 */
    {
        FL_CAN_Filter_EnableIDECompare(CANx, filterX);
    }
    else
    {
        FL_CAN_Filter_DisableIDECompare(CANx, filterX);
    }
    if((CAN_FilterInitStruct->filterMaskIdRTR) == FL_ENABLE)    /* RTR位参与滤波器比较 */
    {
        FL_CAN_Filter_EnableRTRCompare(CANx, filterX);
    }
    else
    {
        FL_CAN_Filter_DisableRTRCompare(CANx, filterX);
    }
    FL_CAN_Filter_WriteIDCompareMask(CANx, filterX, CAN_FilterInitStruct->filterMaskIdHigh);    /* 滤波器掩码配置 */
    FL_CAN_Filter_WriteEXTIDCompareMask(CANx, filterX, CAN_FilterInitStruct->filterMaskIdLow);
    FL_CAN_Filter_SetSRRCompare(CANx, filterX, CAN_FilterInitStruct->filterIdSRR);
    FL_CAN_Filter_SetIDECompare(CANx, filterX, CAN_FilterInitStruct->filterIdIDE);    /* 滤波器ID配置 */
    FL_CAN_Filter_SetRTRCompare(CANx, filterX, CAN_FilterInitStruct->filterIdRTR);
    if((CAN_FilterInitStruct->filterEn) == FL_ENABLE)    /* 滤波器使能 */
    {
        FL_CAN_Filter_Enable(CANx, filterX);
    }
    else
    {
        FL_CAN_Filter_Disable(CANx, filterX);
    }
    return FL_PASS;
}
/**
  * @brief  设置 CAN_FilterInitStruct 为默认配置
  * @param  CAN_FilterInitStruct 指向需要将值设置为默认配置的结构体 @ref FL_CAN_FilterInitTypeDef 结构体
  *
  * @retval None
  */
void FL_CAN_StructFilterInit(FL_CAN_FilterInitTypeDef *CAN_FilterInitStruct)
{
    CAN_FilterInitStruct->filterEn = FL_DISABLE;
    CAN_FilterInitStruct->filterIdExtend = 0;
    CAN_FilterInitStruct->filterMaskIdHigh = 0x7FF;
    CAN_FilterInitStruct->filterIdIDE = FL_CAN_IDE_BIT_LOW;
    CAN_FilterInitStruct->filterMaskIdIDE = FL_DISABLE;
    CAN_FilterInitStruct->filterMaskIdLow = 0X3FFFF;
    CAN_FilterInitStruct->filterIdRTR = FL_CAN_RTR_BIT_LOW;
    CAN_FilterInitStruct->filterMaskIdRTR = FL_DISABLE;
    CAN_FilterInitStruct->filterIdSRR = FL_CAN_SRR_BIT_LOW;
    CAN_FilterInitStruct->filterMaskIdSRR = FL_DISABLE;
    CAN_FilterInitStruct->filterIdStandard = 0;
}

/**
  * @}
  */

#endif /* FL_CAN_DRIVER_ENABLED */

/**
  * @}
  */

/**
  * @}
  */

/********************** (C) COPYRIGHT Fudan Microelectronics **** END OF FILE ***********************/
