#include "flexcan_init.h" #include "IAP_Task.h" #include #include #include #define TX_PADDING_VAL (0xA5) static uint8_t g_rxFifoDataBuf[8]; static flexcan_frame_t g_frameBuf; bool busoff_occur_flag = false;//busoff标志 void flexcan_config_rx_fifo(flexcan_handle_t *handle, flexcan_rx_fifo_config_t *config) { flexcan_frame_t *rx_fifo_frame = &g_frameBuf; rx_fifo_frame->dataBuffer = &g_rxFifoDataBuf[0]; flexcan_set_rx_fifo_config(handle, config); for (uint8_t i = 0; i < USED_MB_FOR_FIFO; i++) { flexcan_set_rx_individual_mask(handle, i, config->filter_tab[i].filter_mask); } /* rx by interrupt */ flexcan_fifo_transfer_t Xfer = {rx_fifo_frame}; flexcan_receive_fifo_nonblocking(handle, &Xfer); } /********************************************************************* * @fn CAN_Send_Msg * * @brief CAN Transmit function. * * @param CANx- CAN1 or CAN2 * ID - Message ID * IDE - CAN_Id_Standard or CAN_Id_Extended * RTR - CAN_RTR_Data or CAN_RTR_Remote * msg - Transmit data buffer. * len - Data length. * * @return 0 - Send successful. * 1 - Send failed. */ uint8_t CAN_Send_Msg( flexcan_handle_t *handle, uint32_t ID, flexcan_frame_format_e ide, flexcan_frame_type_e rtr, uint8_t *msg, uint8_t len, uint8_t tx_index) { uint16_t i = 0; //------------------------------------------------------------------------------ flexcan_frame_t frame = {.id = ID, .length = len, .type = rtr, .format = ide, .dataBuffer = msg}; flexcan_mb_transfer_t xfer = {&frame, tx_index}; while( ( flexcan_get_mb_state(handle, tx_index) != FLEXCAN_StateIdle ) && (i < 0xFFF) ) { i++; } if( i == 0xFFF ) { return 1; } else { flexcan_send_nonblocking(handle, &xfer, TX_PADDING_VAL); return 0; } } /********************************************************************* * @fn flexcan_transfer_callback * * @brief erase Data-Flash block, minimal block is 256B * * @param Page_Address - the address of the page being erased. * Length - Erased data length * * @return none */ uint32_t debugaa = 0; void flexcan_transfer_callback(flexcan_handle_t *handle, flexcan_status_e status, uint32_t result, void *userData) { // uint8_t ip_addr[4] = {0,0,0,0}; // uint16_t i = 0; uint16_t FrameHeader = 0; // uint16_t canAddr = 0; flexcan_frame_t *buf = (flexcan_frame_t *)userData; // uint32_t Rgflexcan_transferCRC = 0; static uint8_t canCmdSTT = 0; // static uint32_t CANFlashNowLen1 = 0; // static uint32_t CANFlashNowLen2 = 0; // uint32_t debugARR1[2] = {0,0}; //-------------------------------------------------------------- // ssdk_printf(SSDK_CRIT, "status:0x%x\r\n",status); switch (status) { case FLEXCAN_RX_IDLE: break; case FLEXCAN_RX_FIFO_IDLE: if(OTA_CANRxID == (buf->id))//ID为1 { g_canRxMsgFlag = 1; FrameHeader = ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) ); // ssdk_printf(SSDK_CRIT, "FrameHeader:0x%x\r\n",FrameHeader); switch(canCmdSTT) { case 0: if(FrameHeader == CRC_UPDATE )//CRC指令 { memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//复制数据 Flash_RxBuf_1.Download_Mode = DOWNLOAD_CAN; if( (FlashBufInitial == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_1.Flash_RxBufSta)) )//初始状态,写完成,crc错误重发 { Flash_RxBuf_1.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC Flash_RxBuf_1.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//帧长度 Flash_RxBuf_1.Flash_RxBufLenNow = 0; Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//切换状态 canCmdSTT = 10; } else if( (FlashBufInitial == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_2.Flash_RxBufSta)) )//初始状态,写完成,crc错误重发 { Flash_RxBuf_2.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC Flash_RxBuf_2.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//帧长度 Flash_RxBuf_2.Flash_RxBufLenNow = 0; Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//切换状态 canCmdSTT = 20; } else{} } else//其他指令 { memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//复制数据 canCmdSTT = 0; } break; case 10://读取flash ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//高位 手动添加ID,方便后面判断 ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE); memcpy(&Flash_RxBuf_1.RxData[Flash_RxBuf_1.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//复制数据 Flash_RxBuf_1.Flash_RxBufLenNow = (Flash_RxBuf_1.Flash_RxBufLenNow) + (buf->length); if( (Flash_RxBuf_1.Flash_RxBufLenNow) >= (Flash_RxBuf_1.Flash_RxBufLen) )//接收长度满足要求 { Flash_RxBuf_1.Flash_RxBufSta = FlashBufComplete;//切换状态 canCmdSTT = 0; } else { Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//切换状态 canCmdSTT = 10; } break; case 20://缓存2 ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//高位 手动添加ID,方便后面判断 ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE); memcpy(&Flash_RxBuf_2.RxData[Flash_RxBuf_2.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//复制数据 Flash_RxBuf_2.Flash_RxBufLenNow = (Flash_RxBuf_2.Flash_RxBufLenNow) + (buf->length); if( (Flash_RxBuf_2.Flash_RxBufLenNow) >= (Flash_RxBuf_2.Flash_RxBufLen) )//接收长度满足要求 { Flash_RxBuf_2.Flash_RxBufSta = FlashBufComplete;//切换状态 canCmdSTT = 0; } else { Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//切换状态 canCmdSTT = 20; } break; } } else if(WDT_CANRxID == (buf->id))//WDT 的ID { FrameHeader = ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) ); if(WDT_Refresh == FrameHeader)//喂狗 { WDTReFresh_flag = true;//接收到帧就更新 ssdk_printf(SSDK_CRIT, "WDT_Refresh:0x%x\r\n", WDTReFresh_flag); } } else{} break; case FLEXCAN_TX_IDLE: break; case FLEXCAN_WAKEUP_TIMEOUT: break; case FLEXCAN_WAKEUP_MATCH: break; case FLEXCAN_ERROR_STATUS: busoff_occur_flag = true; break; default: break; } } /* reinitialize the controller. */ void flexcan_busoff_recovery_demo(flexcan_handle_t *handle) { flexcan_deinit(handle); flexcan_init(handle, &g_flexcan_config); flexcan_enable_interrupts(handle, FLEXCAN_BusOffInterruptEnable); /* assign fifo only for rx. */ flexcan_config_rx_fifo(handle, &flexcan_fifo_cfg); /* assign mailbox14-20 for tx. */ for (uint8_t i = TX_MB_INDEX; i < (TX_MB_INDEX + TX_MAILBOX_NUM); i++) { flexcan_set_tx_mb_config(handle, i, true); } }