1.5wuling_zhuanjietou/HARDWARE/CAN/CanDrvCtrl.c

846 lines
21 KiB
C
Raw Normal View History

2024-10-17 01:06:51 +00:00
/***********************************************************************
* @file name: candrvctrl.c
* @create date: 2022-11-19
* @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>
************************************************************************/
/*********************************************************************************************************************
//CANDRVCTRL <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD>can<61><6E><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><E3A3AC>Ϊһ<CEAA><D2BB>Ŧ<EFBFBD><C5A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
//////////////////////////////////////////////////////////////////////////////////////////////////////
// CAN<41><4E><EFBFBD><EFBFBD><------> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//////////////////////////////////////////////////////////////////////////////////////////////////////
//canͨ<6E><CDA8>id<69><64>can<61><6E>Ϣ֡id<69><64><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD>canid<69><64><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>׳<EFBFBD><D7B3>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>chan<61><6E>ʾcanͨ<6E><CDA8>
// <20><>frmid<69><64>ʾcan<61><6E>Ϣ֡id
//
//
//can<61><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3BDAB>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƵĽӿ<C4BD>ͨ<EFBFBD><CDA8>st_cancb * RegisterCanIF(st_canif *if) <20>ӿڴ<D3BF><DAB4><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>
//st_cancb * RegisterCanIF(st_canif *if) <09><><EFBFBD><EFBFBD><EFBFBD>㽫ij<E3BDAB>ӿڵĿ<DAB5><C4BF><EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>CanDrvCtrlģ<6C><C4A3>
//<2F><><EFBFBD><EFBFBD>st_canif <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD>CanDrvCtrl <20>Ľӿ<C4BD><D3BF>б<EFBFBD>,<2C><><EFBFBD><EFBFBD>ConfigCan ,canSend<6E><64>canid<69><64><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD>ػص<D8BB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>
*********************************************************************************************************************/
#include "porting.h"
#include "candrvctrl.h"
#if 0
#define M_DEBUGF printf
#else
#define M_DEBUGF(...) ;
#endif
#define MAX_CAN_IF_NUM 2
#define PROTOCOL_VALID(PL) (PL.prompt[0] !=0) //<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Э<EFBFBD>鰲װ<E9B0B2><D7B0>ij<EFBFBD><C4B3><EFBFBD>ӿڣ<D3BF>ͨ<EFBFBD><CDA8>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SET_PROTOCOL_INVALID(PL) (PL.prompt[0] =0)
typedef enum
{
e_step_send_idle=0, //<2F><><EFBFBD>еȴ<D0B5><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA3AC><EFBFBD><EFBFBD>e_step_send,ͨ<><CDA8><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
e_step_send, //<2F><><EFBFBD>з<EFBFBD><D0B7><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>e_step_waitack<63>ȴ<EFBFBD><C8B4><EFBFBD> //ͨ<><CDA8><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
e_step_waitack, //ͨ<><CDA8><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
e_step_resend, //<2F><><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD>,<2C><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD><EFBFBD><EFBFBD><ECB3A3>ʱ<EFBFBD><CAB1>
e_step_fail, //<2F>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
e_step_suc, //<2F><><EFBFBD>ͳɹ<CDB3>
}st_sendstep;
typedef struct
{
unsigned int frmid; //can<61><6E>Ϣid
unsigned char sendindex;
unsigned char datalen;
unsigned char data[8];
unsigned int msgident;
void(*cb)(unsigned int msgident,unsigned int result);
}st_senditem;
typedef struct
{
unsigned int frmid; //can<61><6E>Ϣid
unsigned char datalen;
unsigned char data[8];
}st_recitem;
typedef struct
{
unsigned char stimes;
st_sendstep step;
st_senditem sending; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD>ڷ<EFBFBD><DAB7>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
unsigned char waittime; //<2F>ȴ<EFBFBD><C8B4><EFBFBD>ʱ<EFBFBD><CAB1>
unsigned char retrytimes;
}st_sendmsg;
typedef struct
{
st_canif canif;
st_pl pl;
unsigned char linkSts;
st_fifo_t rec;
st_fifo_t send;
unsigned char *prec;
unsigned char *psend;
st_sendmsg smsg; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
}st_if;
static void hdlIfSendSuccessCb(unsigned char chan,unsigned int index);
static void hdlIfBusErrorCb(unsigned char chan,bool sending);
static void hdlIfBusErrorStsCb(unsigned char chan,bool sending);
static bool hdlIfFrmReceve(unsigned char chan,unsigned int canid,const unsigned char *data,unsigned char len);
static void HdlSendMsgSuccess(st_if* pif,unsigned char index);
static void hdlIfBusOffCb(unsigned char chan);
static st_if CanIF[MAX_CAN_IF_NUM];
static st_cancb canifcb ={
hdlIfSendSuccessCb,
hdlIfBusErrorCb,
hdlIfBusErrorStsCb,
hdlIfBusOffCb,
hdlIfFrmReceve};
static st_if* GetIfFromChanel(unsigned char chan)
{
unsigned char i;
for(i=0;(i<NELEMENTS(CanIF))&&(CanIF[i].canif.chan != 0xFF);i++)
{
if(CanIF[i].canif.chan == chan)
{
return &CanIF[i];
}
}
return NULL;
}
static void hdlIfSendSuccessCb(unsigned char chan,unsigned int index)
{
st_if* pif=GetIfFromChanel(chan);
if(pif != NULL)
{
HdlSendMsgSuccess(pif,index);
}
}
static void hdlIfBusErrorCb(unsigned char chan,bool sending)
{
st_if* pif;
pif=GetIfFromChanel(chan);
if(pif != NULL)
{
if(pif->linkSts <= e_sts_closed)
{
if(pif->canif.canClose != NULL) pif->canif.canClose(chan);
}
else if(pif->linkSts == e_err_sending && sending)
{
M_DEBUGF("[CDCtrl]hdlIfBusErrorStsCb: <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD>߷<EFBFBD><DFB7><EFBFBD><EFBFBD>쳣!\n");
pif->linkSts = e_err_sending;
can_kill( E_CAN_MSG_SIG,e_err_sending,chan);
}
else if(pif->linkSts != e_err_sending && sending == false)
{
M_DEBUGF("[CDCtrl]hdlIfBusErrorStsCb: <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD>쳣!\n");
pif->linkSts = e_err_receive;
can_kill( E_CAN_MSG_SIG,e_err_receive,chan);
}
else
{
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
}
}
}
static void hdlIfBusErrorStsCb(unsigned char chan,bool sending)
{
hdlIfBusErrorCb(chan,sending);
}
static void hdlIfBusOffCb(unsigned char chan)
{
st_if* pif;
pif=GetIfFromChanel(chan);
if(pif != NULL)
{
if(pif->linkSts <= e_sts_closed)
{
if(pif->canif.canClose != NULL) pif->canif.canClose(chan);
}
else
{
M_DEBUGF("[CDCtrl]hdlIfBusOffCb: <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD>BUSOFF!\n");
pif->linkSts = e_err_bussoff;
can_kill( E_CAN_MSG_SIG,e_err_bussoff,chan);
}
}
}
static st_recitem tmpRItem;
static bool hdlIfFrmReceve(unsigned char chan,unsigned int canid,const unsigned char *data,unsigned char len)
{
st_if* pif;
pif = GetIfFromChanel(chan);
if(pif != NULL && pif->linkSts >= e_sts_working)
{
if(e_err_receive == pif->linkSts)
{
pif->linkSts=e_sts_working;
}
if(pif->pl.flg&CAN_FLG_SYNCRECEIVE)
{
if(pif->pl.hdlRecCanMsg!=NULL) pif->pl.hdlRecCanMsg(canid,data,len);
}
else
{
tmpRItem.frmid = canid;
tmpRItem.datalen = len;
if(tmpRItem.datalen > 0 && tmpRItem.datalen<=8) CAN_COPY(tmpRItem.data,data,tmpRItem.datalen);
sfifo_write(&pif->rec,&tmpRItem);
if(sfifo_full(&pif->rec))
{
M_DEBUGF("[CDCtrl]hdlIfFrmReceve: <20><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
pif->linkSts=e_err_overfllow;
can_kill( E_CAN_MSG_SIG,e_err_overfllow,chan);
}
}
}
return true;
}
//ע<><D7A2>ͨ<EFBFBD>Žӿںͳ<DABA>ʼ<EFBFBD><CABC>
st_cancb * RegisterCanIF(const st_canif *IF)
{
unsigned char i;
if(IF == NULL || IF->ConfigCan == NULL || IF->canSend==NULL ) return NULL;
for(i=0;i<NELEMENTS(CanIF);i++)
{
if(CanIF[i].canif.chan == IF->chan) return NULL;
}
for(i=0;i<NELEMENTS(CanIF);i++)
{
if(CanIF[i].canif.chan == 0xFF)
{
CAN_COPY((void*)&(CanIF[i].canif),(void*)IF,sizeof(st_canif));
CanIF[i].linkSts = e_sts_unused;
return &canifcb;
}
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><CDB9><EFBFBD>
/////////////////////////////////////////////////////////////////////////////////////////////////////
//<2F>ط<EFBFBD>
static TIMER waitSendAck=0;
#define WAIT_ACK_TIME 2
#define WAIT_ACK_INTERVAL 10
static void waitSendMsgAck(TIMER tmr_id)
{
unsigned char i;
for(i=0;i<MAX_CAN_IF_NUM;i++)
{
if(CanIF[i].linkSts < e_sts_working)
{
continue;
}
//<2F><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>Լ10ms<6D><73><EFBFBD>·<EFBFBD><C2B7><EFBFBD>
if(CanIF[i].smsg.step == e_step_send) can_kill( E_CAN_MSG_SIG,e_sts_needsend,CanIF[i].canif.chan);
if(CanIF[i].smsg.step == e_step_waitack)
{
CanIF[i].smsg.waittime++;
if(CanIF[i].smsg.waittime>= WAIT_ACK_TIME)
{
CanIF[i].smsg.step = e_step_resend;
can_kill( E_CAN_MSG_SIG,e_sts_needsend,CanIF[i].canif.chan);
}
}
}
}
static void StartResendMsgTmr(void)
{
if(waitSendAck == 0) waitSendAck = can_timer_create(waitSendMsgAck);
if(can_timer_switch(waitSendAck) == false) can_timer_start(waitSendAck, WAIT_ACK_INTERVAL);
}
static void HdlAllSengMsgSts(st_if* pif)
{
bool flg = false;
#if CAN_SEND_FASET_MODE > 0
do {
flg = false;
#endif
switch(pif->smsg.step)
{
case e_step_send_idle: //<2F><><EFBFBD>еȴ<D0B5><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA3AC><EFBFBD><EFBFBD>e_step_send,ͨ<><CDA8><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(pif->linkSts >= e_sts_working)
{
if(sfifo_empty(&(pif->send))==false)
{
if(sfifo_read(&(pif->send),&(pif->smsg.sending)))
{
pif->smsg.step=e_step_send;
pif->smsg.stimes = 0;
pif->smsg.waittime = 0;
}
flg = true;
}
}
break;
case e_step_send: //<2F><><EFBFBD>з<EFBFBD><D0B7><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>e_step_waitack<63>ȴ<EFBFBD><C8B4><EFBFBD> //ͨ<><CDA8><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
pif->smsg.sending.sendindex = pif->canif.canSend(pif->canif.chan,pif->smsg.sending.frmid,pif->smsg.sending.data,pif->smsg.sending.datalen);
pif->smsg.stimes++;
if(pif->smsg.sending.sendindex != 0xFF)
{
pif->smsg.step=e_step_waitack;
pif->smsg.waittime = 0;
flg = true;
if(pif->linkSts == e_err_sending) pif->linkSts = e_sts_working;
}
else
{
if(pif->smsg.stimes >= pif->pl.resendTimes)
{
pif->smsg.step=e_step_fail;
flg = true;
}
}
break;
#if 1
case e_step_waitack: //ͨ<><CDA8><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
break;
case e_step_resend: //<2F><><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD>,<2C><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD><EFBFBD><EFBFBD><ECB3A3>ʱ<EFBFBD><CAB1>
if(pif->smsg.stimes >= pif->pl.resendTimes)
{
pif->smsg.step=e_step_fail;
}
else
{
pif->smsg.step=e_step_send;
}
flg = true;
break;
case e_step_fail: //<2F>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
pif->smsg.step=e_step_send_idle;
if(pif->smsg.sending.cb != NULL) {pif->smsg.sending.cb(pif->smsg.sending.msgident,_FAILURE);}
else if (pif->pl.hdlCommSent != NULL) {pif->pl.hdlCommSent(pif->smsg.sending.msgident,_FAILURE);}
flg = true;
break;
case e_step_suc: //<2F><><EFBFBD>ͳɹ<CDB3>
pif->smsg.step=e_step_send_idle;
#if CAN_SEND_FASET_MODE > 0
if(pif->smsg.sending.cb != NULL) {can_kill(E_CAN_MSG_CB_SIG, (unsigned int)(pif->smsg.sending.cb),pif->smsg.sending.msgident);}
else if (pif->pl.hdlCommSent != NULL) {can_kill(E_CAN_MSG_CB_SIG, (unsigned int)(pif->pl.hdlCommSent),pif->smsg.sending.msgident);}
#else
if(pif->smsg.sending.cb != NULL) {pif->smsg.sending.cb(pif->smsg.sending.msgident,_SUCCESS);}
else if (pif->pl.hdlCommSent != NULL) {pif->pl.hdlCommSent(pif->smsg.sending.msgident,_SUCCESS);}
#endif
flg = true;
break;
#endif
}
#if CAN_SEND_FASET_MODE > 0
}while(flg == true && (pif->smsg.step != e_step_fail));
#endif
if(flg) can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
}
static void HdlSendMsgError(st_if* pif)
{
if(pif->smsg.step == e_step_waitack)
{
M_DEBUGF("[CDCtrl]chan%d<><64>%d(%d)<29>η<EFBFBD><CEB7><EFBFBD>ʧ<EFBFBD><CAA7>\n",pif->canif.chan,pif->smsg.stimes,pif->pl.resendTimes);
if(pif->smsg.stimes >= pif->pl.resendTimes)
{
pif->smsg.step = e_step_fail;
}
else
{
pif->smsg.step = e_step_resend;
}
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
}
else
{
M_DEBUGF("[CDCtrl]HdlSendError,<2C><>ǰ<EFBFBD><C7B0><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD>%d!=%d\n",pif->smsg.step,e_step_waitack);
}
}
static void HdlSendMsgSuccess(st_if* pif,unsigned char index)
{
//M_DEBUGF("[CDCtrl]chan=%d,%o sendOK(%d)\n",pif->canif.chan,index,pif->smsg.step);
if(pif->smsg.step == e_step_waitack||pif->smsg.step ==e_step_resend)
{
if(pif->smsg.sending.sendindex == index)
{
pif->smsg.step = e_step_suc;
#if CAN_SEND_FASET_MODE > 0
if(pif->linkSts >= e_sts_working) HdlAllSengMsgSts(pif);
#else
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
#endif
}
else
{
M_DEBUGF("[CDCtrl]chan %d,index :%o#%o\n",pif->canif.chan,index,pif->smsg.sending.sendindex);
}
}
}
/*********************************************************************************************************************
//CANDRVCTRL <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>Э<EFBFBD><D0AD><EFBFBD><EFBFBD>can<61><6E><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><E3A3AC>Ϊһ<CEAA><D2BB>Ŧ<EFBFBD><C5A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
//////////////////////////////////////////////////////////////////////////////////////////////////////
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><------> <20><><EFBFBD><EFBFBD>Э<EFBFBD><D0AD> **************************
//////////////////////////////////////////////////////////////////////////////////////////////////////
//bool InstallProtocalToIF(unsigned char canid, st_pl* pif, st_cl * pcanif); <20><>ij<EFBFBD><C4B3><EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD>Э<EFBFBD><D0AD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ͬһʱ<D2BB>һ<E4A3AC><D2BB><EFBFBD>ӿڽ<D3BF><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>st_pl<70><6C> <20><>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>Ľӿڣ<D3BF><DAA3><EFBFBD>Щ<EFBFBD><D0A9>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>CANDRVCTRL<52><4C><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>st_cl, <09><>CANDRVCTRL <20><EFBFBD>Ľӿڣ<D3BF> Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>Щ<EFBFBD>ӿڽ<D3BF><DABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7>͵<EFBFBD>
*********************************************************************************************************************/
static bool plSend(unsigned char chan,unsigned int frmid,unsigned char *data,unsigned char len,unsigned int msgident,void(*cb)(unsigned int msgident,unsigned int result))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0<CEAA><30><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>Զ<EFBFBD><D4B6>֡<EFBFBD><D6A1>
{
st_senditem send;
st_if* pif=NULL;
pif=GetIfFromChanel(chan);
if(pif ==NULL ||pif->linkSts<=e_sts_closed|| len>8 || sfifo_full(&pif->send)) return false;
SYS_ENTER_CRITICAL();
if (pif->linkSts == e_err_bussoff || pif->linkSts < e_sts_working)
{
SYS_EXIT_CRITICAL();
return false;
}
send.cb = cb;
send.frmid = frmid;
send.datalen = len;
send.msgident = msgident;
if(data == NULL) send.datalen = 0;
if(send.datalen>0 && send.datalen<=8) CAN_COPY(send.data,data,send.datalen);
send.sendindex = 0xFF;
sfifo_write(&pif->send,&send);
if(pif->smsg.step == e_step_send_idle)
{
#if CAN_SEND_FASET_MODE > 0
HdlAllSengMsgSts(pif);
#else
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
#endif
}
SYS_EXIT_CRITICAL();
return true;
}
static bool plReceive(unsigned char chan,unsigned int* frmid,unsigned char *data,unsigned char* len)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0<CEAA><30><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>Զ<EFBFBD><D4B6>֡<EFBFBD><D6A1>
{
st_recitem rec;
st_if* pif=GetIfFromChanel(chan);
if(pif ==NULL ||pif->linkSts<=e_sts_closed || data==NULL || (pif->pl.flg&CAN_FLG_SYNCRECEIVE)) return false;
if(sfifo_empty(&pif->rec)) return false;
if(sfifo_read(&pif->rec,&rec)==0) return false;
*frmid = rec.frmid;
*len = rec.datalen;
if(rec.datalen > 0 && rec.datalen<=8) CAN_COPY(data,rec.data,rec.datalen);
if (pif->linkSts == e_err_overfllow)
{
pif->linkSts = e_sts_working;
}
return true;
}
static unsigned int plGetCurrentLinkSts(unsigned char chan) //<2F><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0>״̬
{
st_if* pif=NULL;
pif=GetIfFromChanel(chan);
if(pif !=NULL) return pif->linkSts;
return 0;
}
static bool plConfigBus(unsigned char chan,unsigned short krate, bool highdomain,bool listen)
{
st_if* pif=GetIfFromChanel(chan);
if(pif ==NULL ||pif->linkSts<=e_sts_unused) return false;
if(pif->canif.ConfigCan != NULL)
{
if(pif->canif.ConfigCan(chan,krate,highdomain,listen))
{
if(pif->psend != NULL)
{
sfifo_init(&pif->send,pif->psend,sizeof(st_senditem),pif->pl.msgNumber);
}
if((pif->pl.flg&CAN_FLG_SYNCRECEIVE)==0 && (pif->prec != NULL))
{
sfifo_init(&pif->rec,pif->prec,sizeof(st_recitem),pif->pl.msgNumber);
}
pif->linkSts = e_sts_working;
return true;
}
}
return false;
}
static bool plcanBusFilterInit(unsigned char chan,unsigned int *filterID_array, unsigned short filterID_total)
{
return false;
}
static bool plCloseLink(unsigned char chan)
{
st_if* pif=GetIfFromChanel(chan);
if(pif ==NULL ||pif->linkSts<=e_sts_closed) return false;
pif->linkSts = e_sts_closed;
if(pif->canif.canClose != NULL) pif->canif.canClose(chan);
if(pif->smsg.step != e_step_send_idle)
{
if(pif->smsg.sending.cb != NULL)
{
if(pif->smsg.step == e_step_suc)
{
pif->smsg.sending.cb(pif->smsg.sending.msgident,_SUCCESS);
}
else if(pif->smsg.step == e_step_fail)
{
pif->smsg.sending.cb(pif->smsg.sending.msgident,_FAILURE);
}
else
{
pif->smsg.sending.cb(pif->smsg.sending.msgident,_ABANDON);
}
}
else if (pif->pl.hdlCommSent != NULL)
{
if(pif->smsg.step == e_step_suc)
{
pif->pl.hdlCommSent(pif->smsg.sending.msgident,_SUCCESS);
}
else if(pif->smsg.step == e_step_fail)
{
pif->pl.hdlCommSent(pif->smsg.sending.msgident,_FAILURE);
}
else
{
pif->pl.hdlCommSent(pif->smsg.sending.msgident,_ABANDON);
}
}
}
while(sfifo_empty(&(pif->send))==false)
{
if(sfifo_read(&(pif->send),&(pif->smsg.sending)))
{
if(pif->smsg.sending.cb != NULL) pif->smsg.sending.cb(pif->smsg.sending.msgident,_ABANDON);
else if (pif->pl.hdlCommSent != NULL) {pif->pl.hdlCommSent(pif->smsg.sending.msgident,_ABANDON);}
}
}
memset(&pif->smsg,0x00,sizeof(pif->smsg));
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////
//CanDrvCtrl ģ<><C4A3><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
////////////////////////////////////////////////////////////////////////////////////////////
static void hdlCanCtrlMsg(e_link_sts msg,unsigned char chan)
{
st_if* pif=GetIfFromChanel(chan);
if(pif == NULL) return;
switch(msg)
{
case e_sts_needsend:
if(pif->linkSts >= e_sts_working) HdlAllSengMsgSts(pif);
break;
case e_err_overfllow:
if(pif->linkSts >= e_sts_working && pif->pl.hdlBusError!= NULL)
{
pif->pl.hdlBusError(e_err_overfllow);
}
break;
case e_err_receive:
if(pif->linkSts >= e_sts_working && pif->pl.hdlBusError!= NULL)
{
pif->pl.hdlBusError(e_err_receive);
}
break;
case e_err_sending:
if(pif->linkSts >= e_sts_working)
{
HdlSendMsgError(pif);
if(pif->pl.hdlBusError!= NULL)pif->pl.hdlBusError(e_err_sending);
}
break;
case e_err_bussoff:
if(pif->linkSts >= e_sts_working)
{
if(pif->smsg.step == e_step_waitack)
{
pif->smsg.step = e_step_fail;
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
}
if(pif->pl.hdlBusError!= NULL)
{
pif->pl.hdlBusError(e_err_bussoff);
}
else
{
plCloseLink(pif->canif.chan);
plConfigBus(pif->canif.chan, 0, 0, 0);
}
}
break;
default:
//<2F><EFBFBD><EFB5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
break;
}
}
static void CAN_MSG_SIG_FUNC(unsigned int signal, int para1, int para2)
{
hdlCanCtrlMsg(para1, para2);
}
static void CAN_MSG_CB_SIG_FUNC(unsigned int signal, int para1, int para2)
{
void (*hdlCommSent)(unsigned int canid, unsigned int result);
hdlCommSent = (void *)para1;
if (hdlCommSent != NULL)
{
hdlCommSent(para2, _SUCCESS);
}
}
//Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>ܽӿ<DCBD>
bool InstallProtocalToIF(unsigned char chan, st_pl* ppl, st_cl * pcl)
{
st_if* pif = NULL;
st_pl *p_pl;
pif=GetIfFromChanel(chan);
if(pif == NULL || ppl == NULL||pcl==NULL) return false;
if(ppl->prompt[0]== 0 || pif->linkSts != e_sts_unused)
{
M_DEBUGF("[CDCtrl]InstallProtocalToIF:Э<><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ջ<EFBFBD><D5BB>ӿ<EFBFBD><D3BF>Ѱ<EFBFBD>װ<EFBFBD><D7B0>Э<EFBFBD><D0AD>(%d)\n",pif->linkSts);
return false;
}
if((ppl->flg&CAN_FLG_SYNCRECEIVE) && ppl->hdlRecCanMsg == NULL)
{
M_DEBUGF("[CDCtrl]InstallProtocalToIF: δ<>ṩhdlRecCanMsg <20>ӿ<EFBFBD>\n");
return false;
}
pif->pl.msgNumber = ppl->msgNumber;
if(pif->pl.msgNumber == 0) pif->pl.msgNumber=50; //Ĭ<><C4AC><EFBFBD><EFBFBD>50
pif->psend = CAN_MALLOC(sizeof(st_senditem)*pif->pl.msgNumber);
if(pif->psend != NULL)
{
sfifo_init(&pif->send,pif->psend,sizeof(st_senditem),pif->pl.msgNumber);
}
else
{
M_DEBUGF("[CDCtrl]InstallProtocalToIF:<3A>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4>ռ<EFBFBD>%d*%d\n",sizeof(st_senditem),pif->pl.msgNumber);
return false;
}
if((ppl->flg&CAN_FLG_SYNCRECEIVE)==0)
{
pif->prec = CAN_MALLOC(sizeof(st_recitem)*pif->pl.msgNumber);
if(pif->prec != NULL)
{
sfifo_init(&pif->rec,pif->prec,sizeof(st_recitem),pif->pl.msgNumber);
}
else
{
CAN_FREE(pif->psend);
pif->psend = NULL;
M_DEBUGF("[CDCtrl]InstallProtocalToIF:<3A>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4>ռ<EFBFBD>%d*%d\n",sizeof(st_senditem),pif->pl.msgNumber);
return false;
}
}
pif->pl.flg = ppl->flg;
p_pl = &(pif->pl);
memset(p_pl->prompt,0x00,sizeof(ppl->prompt));
CAN_COPY(p_pl->prompt,ppl->prompt,sizeof(ppl->prompt)-1);
p_pl->hdlBusError = ppl->hdlBusError;
p_pl->hdlRecCanMsg= ppl->hdlRecCanMsg;
p_pl->resendTimes = ppl->resendTimes;
p_pl->hdlCommSent = ppl->hdlCommSent;
pcl->canBusFilterInit = plcanBusFilterInit;
pcl->ConfigBus = plConfigBus;
pcl->GetCurrentLinkSts = plGetCurrentLinkSts;
pcl->REC = plReceive;
pcl->SEND = plSend;
pcl->CloseLink = plCloseLink;
pif->linkSts = e_sts_closed;
return true;
}
bool UninstallProtocalToIF(unsigned char chan, st_pl* ppl)
{
st_if* pif=NULL;
pif=GetIfFromChanel(chan);
if(ppl == NULL || pif == NULL) return false;
if(CAN_CMPY(ppl->prompt,pif->pl.prompt,sizeof(ppl->prompt)-1) != 0)
{
M_DEBUGF("Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>ָ<EFBFBD>벻ƥ<EFBFBD><EFBFBD>\n");
return false;
}
//<2F><>״̬<D7B4>л<EFBFBD><D0BB><EFBFBD>δʹ<CEB4><CAB9>״̬
pif->linkSts = e_sts_unused;
if(pif->canif.canCloseFilter != NULL)
{
pif->canif.canCloseFilter(chan);
}
if(pif->canif.canClose != NULL)
{
pif->canif.canClose(chan);
}
//<2F>ͷſռ<C5BF>
if((pif->pl.flg&CAN_FLG_SYNCRECEIVE)==0 && pif->prec != NULL)
{
CAN_FREE(pif->prec);
pif->prec = NULL;
}
if(pif->psend != NULL)
{
CAN_FREE(pif->psend);
pif->psend = NULL;
}
memset(&pif->pl,0x00,sizeof(st_pl));
memset(&pif->smsg,0x00,sizeof(st_sendmsg));
return true;
}
void InitCanDrvCtrlMode(void)
{
unsigned char i;
for(i=0;i<NELEMENTS(CanIF);i++)
{
memset(&CanIF[i],0x00,sizeof(st_if));
CanIF[i].canif.chan = 0xFF;
}
StartResendMsgTmr();
can_signal(E_CAN_MSG_SIG, CAN_MSG_SIG_FUNC);
can_signal(E_CAN_MSG_CB_SIG, CAN_MSG_CB_SIG_FUNC);
}
//#if DBG_CANCTRL > 0
#if 0
const static char* stsprompt[]={
"e_sts_empty",
"e_sts_unused",
"e_sts_closed",
"e_sts_working",
};
const static char* errprompt[]={
"e_err_receive",
"e_err_sending",
"e_err_overfllow",
};
void DprintCanDrvCtrl(void)
{
unsigned char i;
for(i=0;i<NELEMENTS(CanIF);i++)
{
M_DEBUGF("[%d]:%d:%s\n",i,CanIF[i].canif.chan,(CanIF[i].linkSts<80)?stsprompt[CanIF[i].linkSts]:errprompt[CanIF[i].linkSts-80]);
if(CanIF[i].linkSts > e_sts_unused)
{
M_DEBUGF("\tprotocol:%s\n",CanIF[i].pl.prompt);
}
M_DEBUGF("\tMsg Step:%d\n",CanIF[i].smsg.step);
}
}
#endif