/* * bsp_FDCAN.c * * Created on: Oct 26, 2023 * Author: shiya */ #include "bsp_FDCAN.h" #include "main.h" #include #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; } }