/*********************************************************************** * @file name: canbusdrv.c * @create date: 2022-11-12 * @author * @version: V 1.0.0 * @remark: 这个模块对can外设进行统一管理,忽略MCU接口的不同,对外一个统一的接口 MCU的更换不涉及到这里 ************************************************************************/ #include #include #include "canbusdrv.h" #include "candrvctrl.h" /** * 这个模块对can外设进行统一管理,忽略MCU接口的不同,对外一个统一的接口 * MCU的更换不涉及到这里 */ /** * 模块统一完成,总线的中断收发,和异常处理 */ static st_cancb tpcb[2]; /***************************************************************************************** * can 接收发送队列的处理 *****************************************************************************************/ typedef struct{ bsp_can_cfg_t bsp_cfg; /* can 的配置 */ unsigned int open_flg; /* 打开标志 0 - 关闭 1-打开中 2-已打开*/ unsigned int sending; /* 正在发送的flag */ can_frame_t tmp_frame; /* 临时报文 */ }can_bus_t; static can_bus_t canbus[BSP_CAN_CHANNEL_NUM]={0}; static __inline void can_bus_ready_hook(unsigned char channel) { if (channel >= BSP_CAN_CHANNEL_NUM) { return; } } /** * @brief: 接收到消息的HOOK * * @param channel: 通道号 * @param pt_fram[IN]: 接收到的消息内容 * * @return: */ void bsp_can_msg_receive_hook(unsigned char channel, const can_frame_t * pt_fram) { if (channel >= BSP_CAN_CHANNEL_NUM) { return; } if(tpcb[channel].hdlFrmReceve != NULL) { tpcb[channel].hdlFrmReceve(channel,(pt_fram->IDE == CAN_ID_EXT)?pt_fram->ExtId:pt_fram->StdId, pt_fram->Data, pt_fram->DLC); } can_bus_ready_hook(channel); } /** * @brief: 发送消息完成的hook * * @param channel: 通道号 * @param fifo_id: 消息空的ID * @param success: true 发送成功, false 发送失败 * * @return: void * * @remark: 发送FIFO空的hook */ void bsp_can_msg_sent_hook(unsigned char channel, unsigned char fifo_id, bool success) { unsigned char ret_id; if (channel >= BSP_CAN_CHANNEL_NUM) { return; } /* 判断是否正在发送 */ if (canbus[channel].sending&(0x00000001<= BSP_CAN_CHANNEL_NUM) { return; } SYS_ENTER_CRITICAL(); if(tpcb[channel].BusOffCb != NULL) { tpcb[channel].BusOffCb(channel); } SYS_EXIT_CRITICAL(); if (canbus[channel].sending > 0) { /* 说明有发送失败的,针对发送失败的后续处理暂留 */ canbus[channel].sending = 0; } } /** * @brief: 总线切换错误消极回应状态hook函数 * * @param channel: can 通道, * * @return: void * * @remark: 当总线应答切换未消极应答时触发,一般是 */ void can_bus_err_passive_hook(unsigned char channel) { if (channel >= BSP_CAN_CHANNEL_NUM) { return; } if(tpcb[channel].BusErrorStsCb != NULL) { tpcb[channel].BusErrorStsCb(channel, canbus[channel].sending > 0?true:false); } } /** * @brief: 异步发送数据报文 * * @param chan: can 通道号 * @param canid: 报文ID * @param data[IN]: 数据内容 * @param len: 数据长度 * * @return 返回是否成功。 * true: 成功 false: 失败 */ bool can_bus_send(unsigned char chan,unsigned int canid,const unsigned char *data, unsigned char len) { can_frame_t tmp; if (chan >= BSP_CAN_CHANNEL_NUM) { return false; } CAN_FRAME_INIT(&tmp, canid, data, len); bsp_can_msg_sent_hook(chan, 0, true); return true; } /** * @brief: 立即发送数据报文 * * @param chan: can 通道号 * @param canid: 报文ID * @param data[IN]: 数据内容 * @param len: 数据长度 * * @return 返回标识号,0xFF 标识失败 */ unsigned char can_bus_send_rt(unsigned char chan,unsigned int canid,const unsigned char *data, unsigned char len) { unsigned char ret_id; if (chan >= BSP_CAN_CHANNEL_NUM || canbus[chan].open_flg != 2) { return false; } CAN_FRAME_INIT(&canbus[chan].tmp_frame, canid, data, len); ret_id = bsp_can_msg_send(chan, &canbus[chan].tmp_frame); if (ret_id != 0xFF) { canbus[chan].sending |= (0x00000001<= BSP_CAN_CHANNEL_NUM) { return false; } canbus[chan].open_flg = 1; canbus[chan].bsp_cfg.abom = false; canbus[chan].bsp_cfg.sleep = listen; canbus[chan].bsp_cfg.domain_h = highdomain; canbus[chan].bsp_cfg.krate = krate; canbus[chan].sending = 0; if (bsp_can_open(chan, &canbus[chan].bsp_cfg)) { canbus[chan].open_flg = 2; } else { canbus[chan].open_flg = 0; } return canbus[chan].open_flg == 2; } /** * @brief: 关闭接口 * * @return: * 返回结果: true - open 成功 false - open 失败 */ bool can_bus_close(unsigned char channel) { canbus[channel].open_flg = 0; bsp_can_close(channel); } static const st_canif tpchan[] = { { 0, //chan1 can_bus_open, //ConfigCan can_bus_send_rt, //canSend can_bus_close, //canClose NULL, //canHwPowerDown NULL, //canHwPowerUp NULL, //canBusFilterInit NULL, //canCloseFilter }, { 1, //chan2 can_bus_open, //ConfigCan can_bus_send_rt, //canSend can_bus_close, //canClose NULL, //canHwPowerDown NULL, //canHwPowerUp NULL, //canBusFilterInit NULL, //canCloseFilter }, }; void InitCanifToCanDrvCtrl(void) { st_cancb *pcb; memset(&canbus[0], 0x00, sizeof(canbus)); memset(&tpcb[0], 0x00, sizeof(tpcb)); pcb = RegisterCanIF(&tpchan[0]); if(pcb!=NULL) memcpy(&tpcb[0],pcb,sizeof(st_cancb)); /* 下标要与st_canif.chan 一致 */ pcb = RegisterCanIF(&tpchan[1]); if(pcb!=NULL) memcpy(&tpcb[1],pcb,sizeof(st_cancb)); /* 下标要与st_canif.chan 一致 */ } //#endif