325 lines
6.8 KiB
C
325 lines
6.8 KiB
C
|
/***********************************************************************
|
|||
|
* @file name: canbusdrv.c
|
|||
|
* @create date: 2022-11-12
|
|||
|
* @author
|
|||
|
* @version: V 1.0.0
|
|||
|
* @remark:
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>can<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MCU<EFBFBD>ӿڵIJ<EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ͳһ<EFBFBD>Ľӿ<EFBFBD>
|
|||
|
MCU<EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>漰<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
************************************************************************/
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdbool.h>
|
|||
|
#include "canbusdrv.h"
|
|||
|
#include "candrvctrl.h"
|
|||
|
|
|||
|
/**
|
|||
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>can<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MCU<EFBFBD>ӿڵIJ<EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ͳһ<EFBFBD>Ľӿ<EFBFBD>
|
|||
|
* MCU<EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>漰<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
/**
|
|||
|
* ģ<EFBFBD><EFBFBD>ͳһ<EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD>շ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
|
|||
|
static st_cancb tpcb[2];
|
|||
|
|
|||
|
/*****************************************************************************************
|
|||
|
* can <EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD>еĴ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*****************************************************************************************/
|
|||
|
|
|||
|
|
|||
|
typedef struct{
|
|||
|
bsp_can_cfg_t bsp_cfg; /* can <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
unsigned int open_flg; /* <20><EFBFBD>־ 0 - <20>ر<EFBFBD> 1-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2-<2D>Ѵ<EFBFBD><D1B4><EFBFBD>*/
|
|||
|
unsigned int sending; /* <20><><EFBFBD>ڷ<EFBFBD><DAB7>͵<EFBFBD>flag */
|
|||
|
can_frame_t tmp_frame; /* <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
|
|||
|
}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: <EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>HOOK
|
|||
|
*
|
|||
|
* @param channel: ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param pt_fram[IN]: <EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @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: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>hook
|
|||
|
*
|
|||
|
* @param channel: ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param fifo_id: <EFBFBD><EFBFBD>Ϣ<EFBFBD>յ<EFBFBD>ID
|
|||
|
* @param success: true <EFBFBD><EFBFBD><EFBFBD>ͳɹ<EFBFBD><EFBFBD><EFBFBD> false <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @return: void
|
|||
|
*
|
|||
|
* @remark: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>FIFO<EFBFBD>յ<EFBFBD>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;
|
|||
|
}
|
|||
|
|
|||
|
/* <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD> */
|
|||
|
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);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/***************************************************************************
|
|||
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
**************************************************************************/
|
|||
|
|
|||
|
/**
|
|||
|
* @brief: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>BUS OFF<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hook<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @param channel: can ͨ<EFBFBD><EFBFBD>, Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> CAN1_CHANNEL <EFBFBD><EFBFBD><EFBFBD><EFBFBD> CAN2_CHANNEL
|
|||
|
*
|
|||
|
* @return: void
|
|||
|
*
|
|||
|
* @remark: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴɹ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
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)
|
|||
|
{
|
|||
|
/* ˵<><CBB5><EFBFBD>з<EFBFBD><D0B7><EFBFBD>ʧ<EFBFBD>ܵģ<DCB5><C4A3><EFBFBD><EFBFBD>Է<EFBFBD><D4B7><EFBFBD>ʧ<EFBFBD>ܵĺ<DCB5><C4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
canbus[channel].sending = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ״̬hook<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @param channel: can ͨ<EFBFBD><EFBFBD>,
|
|||
|
*
|
|||
|
* @return: void
|
|||
|
*
|
|||
|
* @remark: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
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: <EFBFBD>첽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @param chan: can ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param canid: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
|
|||
|
* @param data[IN]: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param len: <EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* true: <EFBFBD>ɹ<EFBFBD> false: ʧ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
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: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @param chan: can ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param canid: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
|
|||
|
* @param data[IN]: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param len: <EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @return <EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD>ʶ<EFBFBD>ţ<EFBFBD>0xFF <EFBFBD><EFBFBD>ʶʧ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
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: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*
|
|||
|
* @param chan: canͨ<EFBFBD><EFBFBD>
|
|||
|
* @param krate: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param highdomain: <EFBFBD>ߵ<EFBFBD>ƽ<EFBFBD>ź<EFBFBD>
|
|||
|
* @param listen: <EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
|||
|
*
|
|||
|
* @return:
|
|||
|
* true: <EFBFBD>ɹ<EFBFBD> false ʧ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
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: <EFBFBD>رսӿ<EFBFBD>
|
|||
|
*
|
|||
|
* @return:
|
|||
|
* <EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><EFBFBD><EFBFBD>: true - open <EFBFBD>ɹ<EFBFBD> false - open ʧ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
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)); /* <20>±<EFBFBD>Ҫ<EFBFBD><D2AA>st_canif.chan һ<><D2BB> */
|
|||
|
|
|||
|
pcb = RegisterCanIF(&tpchan[1]);
|
|||
|
if(pcb!=NULL)
|
|||
|
memcpy(&tpcb[1],pcb,sizeof(st_cancb)); /* <20>±<EFBFBD>Ҫ<EFBFBD><D2AA>st_canif.chan һ<><D2BB> */
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//#endif
|
|||
|
|