/*********************************************************************** * @file name: canbusdrv.h * @create date: 2022-11-12 * @author * @version: V 1.0.0 * @remark: 定义了与MCU can接口之间的接口 ************************************************************************/ #ifndef __CANBUSDRV_H__ #define __CANBUSDRV_H__ /*************************************************************************** * Can 驱动的配置信息 **************************************************************************/ /* 支持的最多can MCU */ #define BSP_CAN_CHANNEL_NUM (2) /* 数据报文的最大长度 */ #define BSP_CAN_DATA_LENGTH_MAX (8) /*************************************************************************** * 所有使用的类型定义 **************************************************************************/ /* 与MCU相关的类型定义 */ #include "porting.h" #include "string.h" /* 定义类型,并且定义从一般信息转换为此结构的函数 */ typedef CanTxMsg can_frame_t; static __inline void CAN_FRAME_INIT(can_frame_t * pt_frame, unsigned int canid,const unsigned char *data, unsigned char len) { if (pt_frame != NULL) { pt_frame->IDE = 0; pt_frame->StdId = 0; pt_frame->ExtId = 0; if (canid >= 0x800) { pt_frame->IDE = CAN_ID_EXT; pt_frame->ExtId = canid; } else { pt_frame->IDE = CAN_ID_STD; pt_frame->StdId = canid; } if (len == 0 || data == NULL) { pt_frame->DLC = 0; pt_frame->RTR = CAN_RTR_REMOTE; } else { pt_frame->RTR = CAN_RTR_DATA; pt_frame->DLC = len; memcpy(pt_frame->Data, data, len); } } } #if 0 /* 定义can报文类型 */ typedef enum { E_CAN_FRAME_STD_MASK = 0x01, E_CAN_FRAME_EXT_MASK = 0x02, E_CAN_FRAME_RTR_MASK = 0x04, } can_frame_mask_e; /* 定义统一的can消息报文 */ typedef struct { unsigned int id; can_frame_mask_e frame_type; #if BSP_CAN_DATA_LENGTH_MAX > 255 unsigned short data_len; #else unsigned char data_len; #endif unsigned char data[BSP_CAN_DATA_LENGTH_MAX]; } can_frame_t; static __inline void CAN_FRAME_INIT(can_frame_t * pt_frame, unsigned int canid,const unsigned char *data, unsigned char len) { if (pt_frame != NULL) { pt_frame->id = canid; pt_frame->frame_type = 0; pt_frame->frame_type |= (canid >= 0x800)?E_CAN_FRAME_EXT_MASK:E_CAN_FRAME_STD_MASK; if (len ==0 || data == NULL) { pt_frame->frame_type |= E_CAN_FRAME_RTR_MASK; pt_frame->data_len = 0; } else { pt_frame->data_len = (len>BSP_CAN_DATA_LENGTH_MAX)?BSP_CAN_DATA_LENGTH_MAX:len; memcpy(pt_frame->data, data, pt_frame->data_len); } } } #endif /*************************************************************************** * 与具体MCU CAN 硬件相关的接口 **************************************************************************/ /** * 底层MCU 必须实现的接口 */ typedef struct { unsigned short krate; /* can的速率 */ bool listen; /* 是否监听模式打开, true 监听, false 非监听 */ bool domain_h; /* 显性为高,还是低, true 为高, false 为低 */ bool sleep; /* 睡眠模式, true 为休眠, false 为非休眠 */ bool abom; /* 总线是否恢复, true 为自动恢复 false 为非自动恢复 */ }bsp_can_cfg_t; /** * @brief: 接口的配置信息 * * @param channel: can 通道号, 不大于MCU_CAN_CHANNEL_NUM * @param pt_bsp_cfg[IN]: 总线自动配置 * * @return: * 返回结果: true - open 成功 false - open 失败 */ bool bsp_can_open(unsigned char channel, const bsp_can_cfg_t * pt_bsp_cfg); /** * @brief: 关闭接口 * * @return: * 返回结果: true - open 成功 false - open 失败 */ bool bsp_can_close(unsigned char channel); #define BSP_CAN_SEND_FAIL (0xFF) /** * @brief: 发送接口 * * @param channel: 通道号 * @param pt_fram[IN]: 发送的消息内容 * * @return: * 返回结果: 发送成功(填充到寄存器)的FIFO id * 失败返回0xFF */ unsigned char bsp_can_msg_send(unsigned char channel, const can_frame_t * pt_fram); /** * @brief: 接收到消息的HOOK * * @param channel: 通道号 * @param pt_fram[IN]: 接收到的消息内容 * * @return: */ void bsp_can_msg_receive_hook(unsigned char channel, const can_frame_t * pt_fram); /** * @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); /** * @brief: 总线PASSIVE hook * * @param channel: 通道号 * * @return: void */ void bsp_can_passive_err_hook(unsigned char channel); /** * @brief: 总线切换错误消极回应状态hook函数 * * @param channel: can 通道, * * @return: void * * @remark: 当总线应答切换未消极应答时触发,一般是 */ void can_bus_err_passive_hook(unsigned char channel); /*************************************************************************** * 对外接口 **************************************************************************/ /** * @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); /** * @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); /** * @brief: 打开总线 * * @param chan: can通道 * @param krate: 速率 * @param highdomain: 高电平信号 * @param listen: 是否为监听模式 * * @return: * true: 成功 false 失败 */ bool can_bus_open(unsigned char chan,unsigned short krate, bool highdomain, bool listen); /** * @brief: 跟can总线有关的所有处理入口 */ void can_bus_handle(void); #endif