1.5wuling_zhuanjietou/HARDWARE/CAN/CanBusDrv.c
2024-10-17 09:06:51 +08:00

325 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***********************************************************************
* @file name: canbusdrv.c
* @create date: 2022-11-12
* @author
* @version: V 1.0.0
* @remark:
这个模块对can外设进行统一管理忽略MCU接口的不同对外一个统一的接口
MCU的更换不涉及到这里
************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#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<<fifo_id))
{
canbus[channel].sending &= ~(0x00000001<<fifo_id);
can_bus_ready_hook(channel);
if(tpcb[channel].SendSuccessCb != NULL)
{
tpcb[channel].SendSuccessCb(channel,fifo_id);
}
}
}
/***************************************************************************
* 下面是对总线异常的处理
**************************************************************************/
/**
* @brief: 总线BUS OFF错误的hook函数
*
* @param channel: can 通道, 应该是 CAN1_CHANNEL 或者 CAN2_CHANNEL
*
* @return: void
*
* @remark: 当总线打开成功时被调用
*/
void can_bus_off_hook(unsigned char channel)
{
if (channel >= 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<<ret_id);
}
return ret_id;
}
/**
* @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)
{
if (chan >= 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