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.
357 lines
9.2 KiB
357 lines
9.2 KiB
2 days ago
|
/*
|
||
|
* bsp_FDCAN.c
|
||
|
*
|
||
|
* Created on: Oct 26, 2023
|
||
|
* Author: shiya
|
||
|
*/
|
||
|
#include "bsp_FDCAN.h"
|
||
|
#include "main.h"
|
||
|
#include <stdlib.h>
|
||
|
#include "bsp_Error.pb.h"
|
||
|
#include "msp_TI5MOTOR.h"
|
||
|
|
||
|
FDCANHandler FD_CAN_1_Handler; //自定义结构体
|
||
|
FDCANHandler FD_CAN_2_Handler;
|
||
|
|
||
|
FDCAN_RxHeaderTypeDef CAN_RX_HDR;
|
||
|
uint8_t CAN_Buf[8];
|
||
|
uint8_t CAN_Buf_2[8];
|
||
|
|
||
|
int32_t CAN_ID;
|
||
|
int32_t CAN_ID_2;
|
||
|
|
||
|
uint8_t GF_BSP_FDCAN_Init(void)
|
||
|
{
|
||
|
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
|
||
|
0) != HAL_OK)
|
||
|
{
|
||
|
Error_Handler();
|
||
|
}
|
||
|
|
||
|
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_BUS_OFF, 0) != HAL_OK)
|
||
|
{
|
||
|
Error_Handler();
|
||
|
}
|
||
|
|
||
|
HAL_FDCAN_Start(&hfdcan1);
|
||
|
|
||
|
if (HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
|
||
|
0) != HAL_OK)
|
||
|
{
|
||
|
Error_Handler();
|
||
|
}
|
||
|
|
||
|
if (HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_BUS_OFF, 0) != HAL_OK)
|
||
|
{
|
||
|
Error_Handler();
|
||
|
}
|
||
|
|
||
|
HAL_FDCAN_Start(&hfdcan2);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan,
|
||
|
uint32_t ErrorStatusITs)
|
||
|
{
|
||
|
if (hfdcan->Instance == FDCAN1)
|
||
|
{
|
||
|
MX_FDCAN1_Init();
|
||
|
}
|
||
|
if (hfdcan->Instance == FDCAN2)
|
||
|
{
|
||
|
MX_FDCAN2_Init();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
|
||
|
{
|
||
|
if (hfdcan->Instance == FDCAN1)
|
||
|
{
|
||
|
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &CAN_RX_HDR, CAN_Buf)
|
||
|
== HAL_OK)
|
||
|
{
|
||
|
CAN_ID = FD_CAN_1_Handler.ReceivedFrameID =
|
||
|
(uint32_t) CAN_RX_HDR.Identifier;
|
||
|
|
||
|
#if NewCANSendVersion
|
||
|
FD_CAN_1_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength;
|
||
|
#else
|
||
|
FD_CAN_1_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength>>16;
|
||
|
#endif
|
||
|
|
||
|
if (FD_CAN_1_Handler.CAN_Decode != NULL )
|
||
|
{
|
||
|
FD_CAN_1_Handler.CAN_Decode(FD_CAN_1_Handler.ReceivedFrameID,
|
||
|
CAN_Buf, FD_CAN_1_Handler.ReceivedLength);
|
||
|
}
|
||
|
GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_FDCAN1_RxFifo0Callback);
|
||
|
}
|
||
|
|
||
|
} else if (hfdcan->Instance == FDCAN2)
|
||
|
{
|
||
|
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &CAN_RX_HDR,
|
||
|
CAN_Buf_2) == HAL_OK)
|
||
|
{
|
||
|
CAN_ID_2 = FD_CAN_2_Handler.ReceivedFrameID =
|
||
|
(uint32_t) CAN_RX_HDR.Identifier;
|
||
|
|
||
|
#if NewCANSendVersion
|
||
|
FD_CAN_2_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength;
|
||
|
#else
|
||
|
FD_CAN_2_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength>>16;
|
||
|
#endif
|
||
|
|
||
|
if (FD_CAN_2_Handler.CAN_Decode != NULL)
|
||
|
{
|
||
|
FD_CAN_2_Handler.CAN_Decode(FD_CAN_2_Handler.ReceivedFrameID,
|
||
|
CAN_Buf_2, FD_CAN_2_Handler.ReceivedLength);
|
||
|
}
|
||
|
GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_FDCAN2_RxFifo0Callback);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FDCAN_TxHeaderTypeDef TXHeader1;
|
||
|
FDCAN_TxHeaderTypeDef TXHeader2;
|
||
|
void GF_BSP_FDCAN_Senddata(uint8_t FDCAN_CH, uint32_t FrameID,
|
||
|
uint8_t DataLength, uint8_t *Txdata)
|
||
|
{
|
||
|
if (DataLength > 8)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if (FDCAN_CH == 1)
|
||
|
{
|
||
|
|
||
|
TXHeader1.BitRateSwitch = FDCAN_BRS_OFF;
|
||
|
#if NewCANSendVersion
|
||
|
TXHeader1.DataLength = (uint32_t) DataLength;
|
||
|
#else
|
||
|
TXHeader1.DataLength = (uint32_t) DataLength << 16;
|
||
|
#endif
|
||
|
// FDCAN_DLC_BYTES_8//数据长度大于8的话会有错误
|
||
|
|
||
|
// FDCAN_DLC_BYTES_8//数据长度大于8的话会有错误
|
||
|
TXHeader1.FDFormat = FDCAN_CLASSIC_CAN;
|
||
|
TXHeader1.IdType = FDCAN_STANDARD_ID;
|
||
|
TXHeader1.Identifier = FrameID;
|
||
|
TXHeader1.TxFrameType = FDCAN_DATA_FRAME;
|
||
|
HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TXHeader1, Txdata);
|
||
|
} else if (FDCAN_CH == 2)
|
||
|
{
|
||
|
TXHeader2.BitRateSwitch = FDCAN_BRS_OFF;
|
||
|
|
||
|
#if NewCANSendVersion
|
||
|
TXHeader2.DataLength = (uint32_t) DataLength;
|
||
|
#else
|
||
|
TXHeader2.DataLength = (uint32_t) DataLength << 16;
|
||
|
#endif
|
||
|
//TXHeader2.DataLength = (uint32_t) DataLength << 16; //数据长度大于8的话会有错误
|
||
|
TXHeader2.FDFormat = FDCAN_CLASSIC_CAN;
|
||
|
TXHeader2.IdType = FDCAN_STANDARD_ID;
|
||
|
TXHeader2.Identifier = FrameID;
|
||
|
TXHeader2.TxFrameType = FDCAN_DATA_FRAME;
|
||
|
HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TXHeader2, Txdata);
|
||
|
}
|
||
|
}
|
||
|
void GF_BSP_CANHandler_Init(int can1_sendListPeriod, int can1_DispacherPeriod,
|
||
|
int can2_sendListPeriod, int can2_DispacherPeriod)
|
||
|
{
|
||
|
|
||
|
|
||
|
GF_BSP_CANHandler_Init_CAN(&FD_CAN_1_Handler, &hfdcan1, can1_sendListPeriod,
|
||
|
can1_DispacherPeriod);
|
||
|
GF_BSP_CANHandler_Init_CAN(&FD_CAN_2_Handler, &hfdcan2, can2_sendListPeriod,
|
||
|
can2_DispacherPeriod);
|
||
|
|
||
|
GF_BSP_Interrupt_Add_CallBack(
|
||
|
DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, GF_BSP_CAN_Timer);
|
||
|
}
|
||
|
|
||
|
void GF_BSP_CANHandler_Init_CAN(FDCANHandler *handler,
|
||
|
FDCAN_HandleTypeDef *canfd, int sendListPeriod, int DispacherPeriod)
|
||
|
{
|
||
|
handler->canfd = canfd;
|
||
|
handler->dispacherController = (DispacherController*) malloc(
|
||
|
sizeof(DispacherController));
|
||
|
|
||
|
|
||
|
handler->dispacherController->pHead = NULL;
|
||
|
handler->dispacherController->pTail = NULL;
|
||
|
handler->dispacherController->Dispacher_Enable = 1;
|
||
|
handler->dispacherController->DispacherCallTime = DispacherPeriod ; // call the function every 50 ms
|
||
|
handler->dispacherController->Dispacher_Counter = 0;
|
||
|
handler->dispacherController->DispacherNumber = 0;
|
||
|
handler->dispacherController->Add_Dispatcher_List = Dispatcher_List_Add_t;
|
||
|
handler->dispacherController->Dispatcher_Run = Dispatch_t;
|
||
|
|
||
|
handler->timeSpan = 2;
|
||
|
handler->SendList_time_Count = 0;
|
||
|
handler->AddCANSendList = CANHandlerAddTxList;
|
||
|
handler->SendList_Period = sendListPeriod;
|
||
|
|
||
|
handler->CAN_Send = CAN_Send_t;
|
||
|
handler->CAN_Send_Data = CAN_Send_Data_t;
|
||
|
|
||
|
}
|
||
|
|
||
|
DispacherController *can_dispacherController;
|
||
|
HardWareController *can_HardWareController;
|
||
|
void GF_BSP_CAN_Timer() //2ms一次
|
||
|
{
|
||
|
can_dispacherController = FD_CAN_1_Handler.dispacherController;
|
||
|
|
||
|
if (FD_CAN_1_Handler.pCurrentCANSendHadler != NULL)
|
||
|
{
|
||
|
GF_CAN_Send_List_Send(&FD_CAN_1_Handler);
|
||
|
|
||
|
} else
|
||
|
{
|
||
|
can_dispacherController = FD_CAN_1_Handler.dispacherController;
|
||
|
can_dispacherController->Dispatcher_Run(can_dispacherController);
|
||
|
}
|
||
|
if (FD_CAN_2_Handler.pCurrentCANSendHadler != NULL)
|
||
|
{
|
||
|
GF_CAN_Send_List_Send(&FD_CAN_2_Handler);
|
||
|
} else
|
||
|
{
|
||
|
|
||
|
can_dispacherController = FD_CAN_2_Handler.dispacherController;
|
||
|
can_dispacherController->Dispatcher_Run(can_dispacherController);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void GF_CAN_Send_List_Send(FDCANHandler *handler)
|
||
|
{
|
||
|
|
||
|
handler->SendList_time_Count++;
|
||
|
if (handler->timeSpan * handler->SendList_time_Count
|
||
|
>= handler->SendList_Period)
|
||
|
{
|
||
|
handler->SendList_time_Count = 0;
|
||
|
handler->SendListExists = 1;
|
||
|
if (handler->pCurrentCANSendHadler != NULL)
|
||
|
{
|
||
|
//拷贝数据到相关的代码中,然后发送
|
||
|
|
||
|
handler->SendFrameID=handler->pCurrentCANSendHadler->CAN_ID;
|
||
|
//handler->CAN_Decode = handler->pCurrentCANSendHadler->CAN_Decode; //
|
||
|
memcpy(handler->Tx_Buf, handler->pCurrentCANSendHadler->Tx_Buf,
|
||
|
handler->pCurrentCANSendHadler->SendLength);
|
||
|
handler->SendList_Period=handler->pCurrentCANSendHadler->SendListTimePeriod;
|
||
|
handler->SendLength = handler->pCurrentCANSendHadler->SendLength;
|
||
|
handler->CAN_Send_Data(handler);
|
||
|
|
||
|
if (handler->pCurrentCANSendHadler->pNext != NULL)
|
||
|
{
|
||
|
CANSendHandler *temp = handler->pCurrentCANSendHadler->pNext;
|
||
|
free(handler->pCurrentCANSendHadler); //清除内存
|
||
|
handler->pCurrentCANSendHadler = temp;
|
||
|
} else
|
||
|
{
|
||
|
free(handler->pCurrentCANSendHadler); //清除内存
|
||
|
handler->pCurrentCANSendHadler = NULL;
|
||
|
}
|
||
|
|
||
|
} else
|
||
|
{
|
||
|
handler->SendListExists = 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void CAN_Send_t(struct _FDCANHandler *fd, uint32_t FrameID, uint8_t DataLength,
|
||
|
uint8_t *Txdata)
|
||
|
{
|
||
|
|
||
|
Function_code=Txdata[0];
|
||
|
|
||
|
if (DataLength > 8)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if (fd->canfd == &hfdcan1)
|
||
|
{
|
||
|
TXHeader1.BitRateSwitch = FDCAN_BRS_OFF;
|
||
|
|
||
|
#if NewCANSendVersion
|
||
|
TXHeader1.DataLength = (uint32_t) DataLength ;
|
||
|
#else
|
||
|
TXHeader1.DataLength = (uint32_t) DataLength << 16; //数据长度大于8的话会有错误
|
||
|
#endif
|
||
|
|
||
|
|
||
|
TXHeader1.FDFormat = FDCAN_CLASSIC_CAN;
|
||
|
TXHeader1.IdType = FDCAN_STANDARD_ID;
|
||
|
TXHeader1.Identifier = FrameID;
|
||
|
TXHeader1.TxFrameType = FDCAN_DATA_FRAME;
|
||
|
HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TXHeader1, Txdata);
|
||
|
} else if (fd->canfd == &hfdcan2)
|
||
|
{
|
||
|
TXHeader2.BitRateSwitch = FDCAN_BRS_OFF;
|
||
|
|
||
|
#if NewCANSendVersion
|
||
|
TXHeader2.DataLength = (uint32_t) DataLength ;
|
||
|
#else
|
||
|
TXHeader2.DataLength = (uint32_t) DataLength << 16; //数据长度大于8的话会有错误
|
||
|
#endif
|
||
|
//TXHeader2.DataLength = (uint32_t) DataLength << 16; //数据长度大于8的话会有错误
|
||
|
TXHeader2.FDFormat = FDCAN_CLASSIC_CAN;
|
||
|
TXHeader2.IdType = FDCAN_STANDARD_ID;
|
||
|
TXHeader2.Identifier = FrameID;
|
||
|
TXHeader2.TxFrameType = FDCAN_DATA_FRAME;
|
||
|
HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TXHeader2, Txdata);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CAN_Send_Data_t(struct _FDCANHandler *fd)
|
||
|
{
|
||
|
CAN_Send_t(fd, fd->SendFrameID, fd->SendLength, fd->Tx_Buf);
|
||
|
}
|
||
|
|
||
|
void CANHandlerAddTxList(FDCANHandler *handler, uint32_t CAN_ID,
|
||
|
uint8_t SendLength, uint8_t *Tx_Buf,uint32_t sendListTimePeriod,
|
||
|
void (*CAN_Decode)(uint32_t, uint8_t*, uint32_t))
|
||
|
{
|
||
|
|
||
|
CANSendHandler *pTmp = NULL; //临时指针
|
||
|
|
||
|
//临时指针2用于逐个申请内存
|
||
|
pTmp = (CANSendHandler*) malloc(sizeof(CANSendHandler));
|
||
|
memcpy(pTmp->Tx_Buf, Tx_Buf, SendLength);
|
||
|
pTmp->pNext = NULL;
|
||
|
pTmp->CAN_ID=CAN_ID;
|
||
|
pTmp->SendLength = SendLength;
|
||
|
//pTmp->CAN_Decode = CAN_Decode;
|
||
|
pTmp->SendListTimePeriod=sendListTimePeriod;
|
||
|
|
||
|
|
||
|
//if NULL, call intialize one
|
||
|
if (handler->pCurrentCANSendHadler == NULL)
|
||
|
{
|
||
|
handler->pCurrentCANSendHadler = pTmp; //空链表
|
||
|
} else
|
||
|
{
|
||
|
char i = 0;
|
||
|
//插到尾部
|
||
|
CANSendHandler *phead = NULL;
|
||
|
phead = handler->pCurrentCANSendHadler;
|
||
|
while (phead->pNext != NULL)
|
||
|
{
|
||
|
i++;
|
||
|
phead = phead->pNext;
|
||
|
}
|
||
|
phead->pNext = pTmp;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|