📄 can_drv.c
字号:
/* check for transmit message object free ---------------------------------*/ NoTxObj = 0; /* default: MObj1 */ if ( (((pMsgObject->ucCntrl1) & kTestTxRqst) != 0) || (Handle_curTxObj[NoTxObj] != 0xFF) ) /* MsgObj1 used? */ { pMsgObject++; /*point to 2nd msg object*/ NoTxObj = 1; /* MObj2 */ if ( (((pMsgObject->ucCntrl1) & kTestTxRqst) != 0) || (Handle_curTxObj[NoTxObj] != 0xFF) ) /*MsgObj2 used?*/ { #if defined( C_TMT_QUE_USED ) /* all tx objs used -> set msg in queue: ----------------------------*/ if (TxQueueFlags[txStruct] != 0) /* msg already in queue?*/ { rc = kCanTxFailed; /* yes, quit with error message*/ } else { TxQueueFlags[txStruct] = 1; /* set message in queue */ TxQueCnt++; } #else rc = kCanTxFailed; #endif #if defined( C_ENABLE_INTCTRL_BY_APPL ) ApplInterruptRestore(); #else CanInterruptRestore(); #endif return rc; } } /* Obj, pMsgObject points to is free, transmit msg object: ----------------*/ pMsgObject->ucCntrl0 = kResetMsgVal; #if defined(C_ENABLE_VARIABLE_DLC) pMsgObject->ucMsgConf = TxDLC_RAM[txStruct]; /* init DLC, RAM */ #else pMsgObject->ucMsgConf = CanTxDLC[txStruct]; /* init DLC, ROM */ #endif pMsgObject->aucArbitrFld[0] = CanTxIdHi[txStruct]; pMsgObject->aucArbitrFld[1] = CanTxIdLo[txStruct]; Handle_curTxObj[NoTxObj] = txStruct;/* Save hdl of msgObj to be transmitted*/#if defined( C_ENABLE_PRETRANSMIT_FCT ) /* Is there a PreTransmit function ? ------------------------------------- */ if ( CanTxApplPreTransmitPtr[txStruct] != NULL ) // if PreTransmit exists { if ( (CanTxApplPreTransmitPtr[txStruct]) (&(pMsgObject->aucCanData(0))) == kCanNoCopyData) { /* Don't copy the data - already done by the PreTransmit-function */ /* --- start transmission --- */ pMsgObject->ucCntrl0 = kSetMsgVal & kSetTxIE; pMsgObject->ucCntrl1 = kInitTmt; #if defined( C_ENABLE_INTCTRL_BY_APPL ) ApplInterruptRestore(); #else CanInterruptRestore(); #endif return (kCanTxOk); } }#endif#if defined( C_OPTIMIZE_CODE ) /* copy via index in MsgObj data field --------------------------*/ { register canuint8 n; #if defined(C_ENABLE_VARIABLE_DLC) register canuint8 len = ((TxDLC_RAM[txStruct] >> 4) & 0x0F); /*RAM*/ #else register canuint8 len = ((CanTxDLC[txStruct] >> 4) & 0x0F); /*ROM*/ #endif for (n= 0; n < len; n++) { pMsgObject->aucCanData(n) = *src++; } }#else /* C_OPTIMIZE_SPEED */ { /*-- copy always 8 data bytes ( no loop ! )-----------------------*/#if defined( C_COMP_KEIL_C5X5C ) register volatile canuint8 CAN_CHIP_ADR_MODE *dst;#else register volatile canuint8 *dst;#endif dst = &(pMsgObject->aucCanData(0)); *(dst ) = *(src ); *(dst+1) = *(src+1); *(dst+2) = *(src+2); *(dst+3) = *(src+3); *(dst+4) = *(src+4); *(dst+5) = *(src+5); *(dst+6) = *(src+6); *(dst+7) = *(src+7); }#endif pMsgObject->ucCntrl0 = kSetMsgVal & kSetTxIE; pMsgObject->ucCntrl1 = kInitTmt; #if defined( C_ENABLE_INTCTRL_BY_APPL ) ApplInterruptRestore(); #else CanInterruptRestore(); #endif return rc;}/****************************************************************************| NAME: CanTransmitQueuedObj| PROTOTYPE: static void CanTransmitQueuedObj(void)| CALLED BY: Can82527Isr()| PRECONDITIONS: Can driver must be initialized| INPUT PARAMETERS: Handle of the transmit object to be send| RETURN VALUES: none| DESCRIPTION: check for next msg object in queue and transmit it| GLOBAL DATA:| STACK:| RUNTIME:****************************************************************************/#if defined( C_TMT_QUE_USED )static void CanTransmitQueuedObj(void){ cansint8 i;#ifdef _DEBUG_ { canuint8 cnt=0; for (i = CanNumberOfTxObjects-1; i >= 0; i--) /* count objs in queue */ { if (TxQueueFlags[i] != 0) { cnt++; } } assertCan((cnt == TxQueCnt),0x90); /* compare with TxQueCnt */ }#endif if (TxQueCnt != 0) { for (i = CanNumberOfTxObjects-1; i >= 0; i--) /*look for obj ready to transmit*/ { if (TxQueueFlags[i] != 0) { TxQueueFlags[i] = 0; /* remove msg from queue */ TxQueCnt--; CanTransmit(i); } } }}#endif // C_TMT_QUE_USED/****************************************************************************| NAME: Can82527Isr| PROTOTYPE: void Can82527Isr(void)| CALLED BY:| PRECONDITIONS:| INPUT PARAMETERS: none| RETURN VALUES: none| DESCRIPTION: - check for the interrupt reason ( interrupt source )| - work appropriate interrupt:| + status interrupt (busoff, wakeup, error warning)| + basic can receive| + full can receive| + full can transmit| GLOBAL DATA:| STACK:| RUNTIME:****************************************************************************//*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* MEG - Karl-Fredrik Uhlander 1999-12-06: Trap number change. *//*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* Interrupt trap number change. */#if defined( C_COMP_TASKING_C16x ) #if defined( C_ENABLE_OSEK ) #if !qTaskRegBank #pragma noframe /* Intern: 0x4B */ interrupt(CAN_2_TRAP_NR) using(osek_sys_rb) void Can82527Isr(void) #else interrupt(CAN_2_TRAP_NR) using(scanRegs) void Can82527Isr(void) #endif #else /* Intern: 0x4B */ interrupt(CAN_2_TRAP_NR) using(CANISR_rb) void Can82527Isr(void) #endif /* C_ENABLE_OSEK */#endif /* C_COMP_TASKING_C16x *//*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/#if defined( C_COMP_KEIL_C16x ) /* Intern: 64 (0x40) Extern: 28 (0x1C) */ #if CAN527internal void Can82527Isr(void) interrupt 0x40 using CANISR_rb #else void Can82527Isr(void) interrupt 0x1c using CANISR_rb #endif#endif /* C_COMP_KEIL_C16x */#if defined( C_COMP_KEIL_C5X5C ) #pragma NOAREGS#if defined( C_ENABLE_INTCTRL_BY_APPL )#ifdef C_PROCESSOR_SIEMENS_C505C void Can82527Isr(void) small interrupt 9 /* CAN Int Vector 9 at 004BH */#endif#ifdef C_PROCESSOR_SIEMENS_C515C void Can82527Isr(void) small interrupt 17 /* CAN Int Vector 17 at 008BH */#endif#else#ifdef C_PROCESSOR_SIEMENS_C505C void Can82527Isr(void) small interrupt 9 using 1 /* CAN Int Vector 9 at 004BH; Reg Bank 1 */#endif#ifdef C_PROCESSOR_SIEMENS_C515C void Can82527Isr(void) small interrupt 17 using 1 /* CAN Int Vector 17 at 008BH; Reg Bank 1 */#endif#endif /* C_ENABLE_INTCTRL_BY_APPL */#endif /* C_COMP_KEIL_C5X5C *//* start of function */{#if defined( C_COMP_KEIL_C5X5C ) static CanMsgObj CAN_CHIP_ADR_MODE *pMsgObject; /* msg object on chip */#else static CanMsgObj *pMsgObject; /* msg object on chip */#endif static canuint8 irptId; /* interrupt Id */ static canuint8 len; static RxDataPtr dst;#if defined( C_ENABLE_TP_SUPPORT ) static canuint16 id;#endif static cansint8 i;#if defined( C_COMP_KEIL_C5X5C ) #if defined( C_CAN_CHIP_PDATA ) XPAGE = 0xF7; // 8 bit addressing of CAN #endif#endif /* NOTE!!! after acknowledging the interrupt -----------------------------*/ /* another interrupt might have occured !!! */#if CAN527internal while ((irptId = Can82527.u.named.u.in.ucIntrReg) != 0)#else while ((irptId = Can82527.u.named.ucExIntrReg) != 0)#endif { /*determine source of interrupt*/ /*assertChip((irptId <= 0x10), kIllIrptNumber);+++*/ /* check legal intr no */ /*====================================== STATUS INTERRUPT ============*/ if ( irptId == 1 ) { /* check for status register (bus error)--*/ irptId = Can82527.u.named.ucStatReg; if ( irptId & kErrBusOff ) { /*==BUS OFF ERROR=========================*/ #if defined( C__NM_OSEK ) NmCanError(); // inform nwm #else ApplCanError(); // call application specific function #endif } if ( irptId & kErrWarn ) { /* no action */ }#if !CAN527internal if ( irptId & kWakeUp ) { ApplCanWakeUp(); // call application function }#endif /*====================================== BCAN RECEIVE INTERRUPT ======*/ } else if ( irptId == 2 ) { CC_BusoffCounter = 0; /* Clear busoff counter when message received */ /* check for bcan receive ----------------*/ if ((Can82527.u.named.sMsg15Obj.ucCntrl0 & kTestIntPnd) == 0) { continue; /* no valid IRQ pending(!?), check for another interrupt */ } /* search the received id in ROM table: */ for (i = CanNumberOfRxBasicCANObjects-1; i >= 0 ;i--) { if ( (Can82527.u.named.sMsg15Obj.aucArbitrFld[1] == CanRxIdLo[i]) && (Can82527.u.named.sMsg15Obj.aucArbitrFld[0] == CanRxIdHi[i]) ) { break; /*exit loop with index i */ } } if (i >= 0) /* if msg exists in ROM table */ { /* msg found in rom table ------------------------------------*/ if ( CanRxApplPrecopyPtr[i] != NULL ) /*precopy routine */ { #ifdef C_ENABLE_CANID_ACCESS CanEcuNumber = /* CanEcuNumber = lower 8 bits of ID */ ( ( ( Can82527.u.named.sMsg15Obj.aucArbitrFld[0] ) << 3 ) | ( ( Can82527.u.named.sMsg15Obj.aucArbitrFld[1] ) >> 5 ) ); #endif #if defined( C_ENABLE_VARIABLE_DLC ) CanRxActualDLC = (Can82527.u.named.sMsg15Obj.ucMsgConf>>4); #endif if ( CanRxApplPrecopyPtr[i](&Can82527.u.named.sMsg15Obj.aucCanData(0))==kCanNoCopyData ) { Can82527.u.named.sMsg15Obj.ucCntrl0 = kResetIntPnd; /* reset pending interrupt */ Can82527.u.named.sMsg15Obj.ucCntrl1 = kResetNewDat; continue; /* precopy routine returns true: */ } /* don't copy data check next irpt */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -