You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
5.5 KiB
149 lines
5.5 KiB
/******************************************************************************
|
|
|
|
版权所有 (C), 2018-2099, Radkil
|
|
|
|
******************************************************************************
|
|
文 件 名 : bsp_CAN.c
|
|
版 本 号 : 初稿
|
|
作 者 : radkil
|
|
生成日期 : 2026年5月13日
|
|
最近修改 :
|
|
功能描述 : CAN总线中间层(H7系列使用FDCAN)
|
|
|
|
修改历史 :
|
|
1.日 期 : 2026年5月13日
|
|
作 者 : radkil
|
|
修改内容 : 创建文件
|
|
|
|
******************************************************************************/
|
|
#include "bsp_can.h"
|
|
#ifdef USE_CAN
|
|
/*----------------------------------------------*
|
|
* 外部变量说明 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 外部函数原型说明 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 内部函数原型说明 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 全局变量 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 模块级变量 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 常量定义 *
|
|
*----------------------------------------------*/
|
|
|
|
/*----------------------------------------------*
|
|
* 宏定义 *
|
|
*----------------------------------------------*/
|
|
|
|
TCANUserData *CAN_userdata_init(FDCAN_HandleTypeDef *_fdCAN, uint32_t _Size, int _iIsLoop)
|
|
{
|
|
if (NULL == _fdCAN || _Size <= 0) return NULL;
|
|
|
|
TCANUserData *ptCANUserData = (TCANUserData *)RD_CALLOC(1, sizeof(TCANUserData));
|
|
FDCAN_RxHeaderTypeDef *ptCANRxHeader = (FDCAN_RxHeaderTypeDef *)RD_CALLOC(1, sizeof(FDCAN_RxHeaderTypeDef));
|
|
FDCAN_TxHeaderTypeDef *ptCANTxHeader = (FDCAN_TxHeaderTypeDef *)RD_CALLOC(1, sizeof(FDCAN_TxHeaderTypeDef));
|
|
uint8_t *pBuffer = (uint8_t *)RD_CALLOC(1, _Size);
|
|
|
|
if (NULL == ptCANUserData || NULL == ptCANRxHeader || NULL == ptCANTxHeader || NULL == pBuffer) return NULL;
|
|
|
|
ptCANUserData->m_temp_size = _Size;
|
|
ptCANUserData->m_can = _fdCAN;
|
|
ptCANUserData->m_cantx = ptCANTxHeader;
|
|
ptCANUserData->m_canrx = ptCANRxHeader;
|
|
ptCANUserData->m_temp = pBuffer;
|
|
|
|
// 这里这个标志位是为0代表使用回环模式
|
|
if (0 == _iIsLoop)
|
|
{
|
|
_fdCAN->Init.Mode = FDCAN_MODE_NORMAL;
|
|
}
|
|
else
|
|
{
|
|
_fdCAN->Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
|
|
}
|
|
if (HAL_FDCAN_Init(_fdCAN) != HAL_OK)
|
|
{
|
|
Error_Handler();
|
|
}
|
|
|
|
return ptCANUserData;
|
|
}
|
|
|
|
void CAN_IT_init(TComCtrl *_ptComCtrl)
|
|
{
|
|
TCANUserData *ptCANUserData = (TCANUserData *)_ptComCtrl->m_pUserData;
|
|
|
|
FDCAN_FilterTypeDef filterConfig = {0};
|
|
|
|
// ================= 全通模式 =================
|
|
// 作用:接收所有标准帧和扩展帧的数据,专门用于排查“收不到数据”的问题
|
|
filterConfig.IdType = FDCAN_STANDARD_ID; // 过滤标准ID
|
|
filterConfig.FilterIndex = 0; // 使用第0号滤波器
|
|
filterConfig.FilterType = FDCAN_FILTER_MASK; // 掩码模式
|
|
filterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; // 匹配的数据放入 RXFIFO0
|
|
filterConfig.FilterID1 = 0x000; // 目标ID设为0
|
|
filterConfig.FilterID2 = 0x000; // 【关键】掩码设为0,代表不检查任何位,全部放行!
|
|
HAL_FDCAN_ConfigFilter(ptCANUserData->m_can, &filterConfig);
|
|
|
|
if (HAL_FDCAN_ActivateNotification(ptCANUserData->m_can, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
|
|
{
|
|
Error_Handler();
|
|
}
|
|
|
|
if (HAL_FDCAN_ActivateNotification(ptCANUserData->m_can, FDCAN_IT_BUS_OFF, 0) != HAL_OK)
|
|
{
|
|
Error_Handler();
|
|
}
|
|
|
|
HAL_FDCAN_Start(ptCANUserData->m_can);
|
|
}
|
|
|
|
void CAN_RX_IRQHandler(TComCtrl *_ptComCtrl)
|
|
{
|
|
TCANUserData *ptCANUserData = (TCANUserData *)_ptComCtrl->m_pUserData;
|
|
if (HAL_FDCAN_GetRxMessage(ptCANUserData->m_can, FDCAN_RX_FIFO0, ptCANUserData->m_canrx, ptCANUserData->m_temp) == HAL_OK)
|
|
{
|
|
// FD_CAN_1_Handler.ReceivedFrameID = (uint32_t) CAN_RX_HDR.Identifier;
|
|
#if NewCANSendVersion
|
|
uint32_t iRxLen = (uint32_t) ptCANUserData->m_canrx->DataLength;
|
|
#else
|
|
uint32_t iRxLen = (uint32_t) ptCANUserData->m_canrx->DataLength>>16;
|
|
#endif
|
|
if (iRxLen > 0 && iRxLen <= ptCANUserData->m_temp_size)
|
|
{
|
|
rd_ComRecvProc(_ptComCtrl, (const char*)ptCANUserData->m_temp, iRxLen);
|
|
}
|
|
}
|
|
}
|
|
|
|
int CAN_TX_FIFOQ(TComCtrl *_ptComCtrl, uint32_t _iFrameID, char *_pBuffer, uint32_t _iSize)
|
|
{
|
|
TCANUserData *ptCANUserData = (TCANUserData *)_ptComCtrl->m_pUserData;
|
|
ptCANUserData->m_cantx->BitRateSwitch = FDCAN_BRS_OFF;
|
|
|
|
#if NewCANSendVersion
|
|
ptCANUserData->m_cantx->DataLength = (uint32_t) _iSize;
|
|
#else
|
|
ptCANUserData->m_cantx->DataLength = (uint32_t) _iSize << 16; //数据长度大于8的话会有错误
|
|
#endif
|
|
ptCANUserData->m_cantx->FDFormat = FDCAN_CLASSIC_CAN;
|
|
ptCANUserData->m_cantx->IdType = FDCAN_STANDARD_ID;
|
|
ptCANUserData->m_cantx->Identifier = _iFrameID;
|
|
ptCANUserData->m_cantx->TxFrameType = FDCAN_DATA_FRAME;
|
|
HAL_FDCAN_AddMessageToTxFifoQ(ptCANUserData->m_can, ptCANUserData->m_cantx, (const uint8_t *)_pBuffer);
|
|
|
|
return ptCANUserData->m_cantx->DataLength;
|
|
}
|
|
|
|
#endif
|
|
|