302 lines
13 KiB
C
302 lines
13 KiB
C
|
|
/**
|
||
|
|
*******************************************************************************************************
|
||
|
|
* @file fm33lg0xx_fl_can.c
|
||
|
|
* @author FMSH Application Team
|
||
|
|
* @brief Src file of VAN fL Module
|
||
|
|
*******************************************************************************************************
|
||
|
|
* @attention
|
||
|
|
*
|
||
|
|
* Copyright (c) [2021] [Fudan Microelectronics]
|
||
|
|
* THIS SOFTWARE is licensed under Mulan PSL v2.
|
||
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
||
|
|
* http://license.coscl.org.cn/MulanPSL2
|
||
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||
|
|
* See the Mulan PSL v2 for more details.
|
||
|
|
*
|
||
|
|
*******************************************************************************************************
|
||
|
|
*/
|
||
|
|
/* 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 ***********************/
|