Customer_controller/BSP/bsp_fdcan.c

233 lines
8.0 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bsp_fdcan.h"
/**
************************************************************************
* @brief: bsp_can_init(void)
* @param: void
* @retval: void
* @details: CAN 使能
************************************************************************
**/
void bsp_can_init(void)
{
can_filter_init();
HAL_FDCAN_Start(&hfdcan1); //开启FDCAN
// HAL_FDCAN_Start(&hfdcan2);
// HAL_FDCAN_Start(&hfdcan3);
// HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_WATERMARK, 0);
// HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO1_WATERMARK, 0);
// HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_BUFFER_NEW_MESSAGE, 0);
HAL_FDCAN_ActivateNotification(&hfdcan1,
0 | FDCAN_IT_RX_FIFO0_WATERMARK | FDCAN_IT_RX_FIFO0_WATERMARK
| FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY | FDCAN_IT_BUS_OFF
| FDCAN_IT_ARB_PROTOCOL_ERROR | FDCAN_IT_DATA_PROTOCOL_ERROR
| FDCAN_IT_ERROR_PASSIVE | FDCAN_IT_ERROR_WARNING,
0x00000F00);
}
/**
************************************************************************
* @brief: can_filter_init(void)
* @param: void
* @retval: void
* @details: CAN滤波器初始化
************************************************************************
**/
void can_filter_init(void)
{
FDCAN_FilterTypeDef fdcan_filter;
fdcan_filter.IdType = FDCAN_STANDARD_ID; //标准ID
fdcan_filter.FilterIndex = 0; //滤波器索引
fdcan_filter.FilterType = FDCAN_FILTER_MASK;
fdcan_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; //过滤器0关联到FIFO0
fdcan_filter.FilterID1 = 0x00;
fdcan_filter.FilterID2 = 0x00;
HAL_FDCAN_ConfigFilter(&hfdcan1,&fdcan_filter); //接收ID2
//拒绝接收匹配不成功的标准ID和扩展ID,不接受远程帧
HAL_FDCAN_ConfigGlobalFilter(&hfdcan1,FDCAN_REJECT,FDCAN_REJECT,FDCAN_REJECT_REMOTE,FDCAN_REJECT_REMOTE);
HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO0, 1);
// HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO1, 1);
// HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0);
}
void bsp_fdcan_set_baud(hcan_t *hfdcan, uint8_t mode, uint8_t baud)
{
uint32_t nom_brp=0, nom_seg1=0, nom_seg2=0, nom_sjw=0;
uint32_t dat_brp=0, dat_seg1=0, dat_seg2=0, dat_sjw=0;
/* nominal_baud = 80M/brp/(1+seg1+seg2)
sample point = (1+seg1)/(1+seg1+seg2)
sjw : 1-128
seg1: 2-256
seg2: 2-128
brp : 1-512 */
if(mode == CAN_CLASS)
{
switch (baud)
{
case CAN_BR_125K: nom_brp=4 ; nom_seg1=139; nom_seg2=20; nom_sjw=20; break; // sample point 87.5%
case CAN_BR_200K: nom_brp=2 ; nom_seg1=174; nom_seg2=25; nom_sjw=25; break; // sample point 87.5%
case CAN_BR_250K: nom_brp=2 ; nom_seg1=139; nom_seg2=20; nom_sjw=20; break; // sample point 87.5%
case CAN_BR_500K: nom_brp=1 ; nom_seg1=139; nom_seg2=20; nom_sjw=20; break; // sample point 87.5%
case CAN_BR_1M: nom_brp=1 ; nom_seg1=59 ; nom_seg2=20; nom_sjw=20; break; // sample point 75%
}
dat_brp=1 ; dat_seg1=29; dat_seg2=10; dat_sjw=10; // 数据域默认1M
hfdcan->Init.FrameFormat = FDCAN_FRAME_CLASSIC;
}
/* data_baud = 80M/brp/(1+seg1+seg2)
sample point = (1+seg1)/(1+seg1+seg2)
sjw : 1-16
seg1: 1-32
seg2: 2-16
brp : 1-32 */
if(mode == CAN_FD_BRS)
{
switch (baud)
{
case CAN_BR_2M: dat_brp=1 ; dat_seg1=29; dat_seg2=10; dat_sjw=10; break; // sample point 75%
case CAN_BR_2M5: dat_brp=1 ; dat_seg1=25; dat_seg2=6 ; dat_sjw=6 ; break; // sample point 81.25%
case CAN_BR_3M2: dat_brp=1 ; dat_seg1=19; dat_seg2=5 ; dat_sjw=5 ; break; // sample point 80%
case CAN_BR_4M: dat_brp=1 ; dat_seg1=14; dat_seg2=5 ; dat_sjw=5 ; break; // sample point 75%
case CAN_BR_5M: dat_brp=1 ; dat_seg1=13; dat_seg2=2 ; dat_sjw=2 ; break; // sample point 87.5%
}
nom_brp=1 ; nom_seg1=59 ; nom_seg2=20; nom_sjw=20; // 仲裁域默认1M
hfdcan->Init.FrameFormat = FDCAN_FRAME_FD_BRS;
}
HAL_FDCAN_DeInit(hfdcan);
hfdcan->Init.NominalPrescaler = nom_brp;
hfdcan->Init.NominalTimeSeg1 = nom_seg1;
hfdcan->Init.NominalTimeSeg2 = nom_seg2;
hfdcan->Init.NominalSyncJumpWidth = nom_sjw;
hfdcan->Init.DataPrescaler = dat_brp;
hfdcan->Init.DataTimeSeg1 = dat_seg1;
hfdcan->Init.DataTimeSeg2 = dat_seg2;
hfdcan->Init.DataSyncJumpWidth = dat_sjw;
HAL_FDCAN_Init(hfdcan);
}
/**
************************************************************************
* @brief: fdcanx_send_data(FDCAN_HandleTypeDef *hfdcan, uint16_t id, uint8_t *data, uint32_t len)
* @param: hfdcanFDCAN句柄
* @param: idCAN设备ID
* @param: data发送的数据
* @param: len发送的数据长度
* @retval: void
* @details: 发送数据
************************************************************************
**/
uint8_t fdcanx_send_data(hcan_t *hfdcan, uint16_t id, uint8_t *data, uint32_t len)
{
FDCAN_TxHeaderTypeDef pTxHeader;
pTxHeader.Identifier=id;
pTxHeader.IdType=FDCAN_STANDARD_ID;
pTxHeader.TxFrameType=FDCAN_DATA_FRAME;
if(len<=8)
pTxHeader.DataLength = len;
if(len==12)
pTxHeader.DataLength = FDCAN_DLC_BYTES_12;
if(len==16)
pTxHeader.DataLength = FDCAN_DLC_BYTES_16;
if(len==20)
pTxHeader.DataLength = FDCAN_DLC_BYTES_20;
if(len==24)
pTxHeader.DataLength = FDCAN_DLC_BYTES_24;
if(len==32)
pTxHeader.DataLength = FDCAN_DLC_BYTES_32;
if(len==48)
pTxHeader.DataLength = FDCAN_DLC_BYTES_48;
if(len==64)
pTxHeader.DataLength = FDCAN_DLC_BYTES_64;
pTxHeader.ErrorStateIndicator=FDCAN_ESI_ACTIVE;
pTxHeader.BitRateSwitch=FDCAN_BRS_ON;
pTxHeader.FDFormat=FDCAN_FD_CAN;
pTxHeader.TxEventFifoControl=FDCAN_NO_TX_EVENTS;
pTxHeader.MessageMarker=0;
if(HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, &pTxHeader, data)!=HAL_OK)
return 1;//发送
return 0;
}
/**
************************************************************************
* @brief: fdcanx_receive(FDCAN_HandleTypeDef *hfdcan, uint8_t *buf)
* @param: hfdcanFDCAN句柄
* @param: buf接收数据缓存
* @retval: 接收的数据长度
* @details: 接收数据
************************************************************************
**/
uint8_t fdcanx_receive(hcan_t *hfdcan, uint16_t *rec_id, uint8_t *buf)
{
FDCAN_RxHeaderTypeDef pRxHeader;
uint8_t len;
if(HAL_FDCAN_GetRxMessage(hfdcan,FDCAN_RX_FIFO0, &pRxHeader, buf)==HAL_OK)
{
*rec_id = pRxHeader.Identifier;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_8)
len = pRxHeader.DataLength;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_12)
len = 12;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_16)
len = 16;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_20)
len = 20;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_24)
len = 24;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_32)
len = 32;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_48)
len = 48;
if(pRxHeader.DataLength<=FDCAN_DLC_BYTES_64)
len = 64;
return len;//接收数据
}
return 0;
}
__weak void fdcan1_rx_callback(void)
{
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if (hfdcan == &hfdcan1)
{
fdcan1_rx_callback();
}
}
void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
{
if(ErrorStatusITs & FDCAN_IR_BO)
{
CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
}
if(ErrorStatusITs & FDCAN_IR_EP)
{
MX_FDCAN1_Init();
bsp_can_init();
}
}