📄 can_drv.c
字号:
/* wait until CANChip hardware reset status is not active ---------------*/ for (i = kWaitReset; (Can82527.u.named.u.ex.ucCPUIntf & kRstSt); i--) { if ( i == 0 ) /* while set: no access to 82527 possible */ { return kErrorInit; /* no access to CPU possible */ } } Can82527.u.named.u.ex.ucCPUIntf = CanInitObject.cpuInterfaceReg; /* The CPU-Interface-Register must be set before any other activity! */ for (i = kWaitTime1; i > 0; i--) { /*wait until 82527 internal state stable*/ }#endif#if defined ( C_ENABLE_HARDWARE_CHECK ) /* check for physical access to Can chip ----------------------------------*/ if( CanTestChip() != kCanTxOk) { return kErrorInit; /* exit with error message */ }#endif /* check for legal number of rx/tx-objects --------------------------------*/ if ( CanNumberOfRxFullCANObjects > 12) { return kIllNoObjects; /* exit with error message */ } /* start software initialization: set Init and ChangeConfigEnable-Bit */ Can82527.u.named.ucCntrlReg = (kCCE | kInit | /* SET INIT/CCE REG */ kEIE | kIE ); /* enable global interrupts */ /* and Error Interrupt */ /* disable StatusChangeIrpt */ /* (enabled only during */ /* sleep-mode) */#if CAN527internal /* no CPU interface with internal CAN */#else Can82527.u.named.u.ex.ucCPUIntf = CanInitCPUIntf[initObject];#ifdef C_ENABLE_USING_PORTS /* port registers (P1CONF - P2CONF) set on their default values */ Can82527.u.named.ucExP1CONF = CanInitExP1Conf[initObject]; Can82527.u.named.ucExP2CONF = CanInitExP2Conf[initObject];#endif#endif /* Global mask: always care for all bits */ Can82527.u.named.ucGlobalMaskStdHigh = CanInitGlMskHi[initObject]; Can82527.u.named.ucGlobalMaskStdLow = CanInitGlMskLo[initObject]; Can82527.u.named.ucMsg15MaskHigh = CanInitMsg15MskHi[initObject]; Can82527.u.named.ucMsg15MaskLow = CanInitMsg15MskLo[initObject];#if !CAN527internal Can82527.u.named.ucExCLKOUT = CanInitCLKOut[initObject]; Can82527.u.named.ucExBCR = CanInitBCR[initObject]; Can82527.u.named.ucExBt0Reg = CanInitBT0[initObject]; Can82527.u.named.ucExBt1Reg = CanInitBT1[initObject];#else#ifdef C_COMP_KEIL_C5X5C Can82527.u.named.u.in.ucBtReg0 = CanInitBT0[initObject]; Can82527.u.named.u.in.ucBtReg1 = CanInitBT1[initObject];#else Can82527.u.named.u.in.uiBtReg = CanInitBT0[initObject] | (CanInitBT1[initObject] << 8);#endif#endif /* init all msg objects with default parameters: */ for (i = 0; i < 15; i++) { pMsgObject = &Can82527.u.indexed.obj[i].sMsgObj; pMsgObject->ucCntrl0 = 0x55; /* reset: MsgVal,TXIE, RXIE, IntPnd */ pMsgObject->ucCntrl1 = 0x55; /* reset: RmtPnd,TxRqst,MsgLst,NewDat */ pMsgObject->ucMsgConf = 0x00; pMsgObject->aucArbitrFld[2] = 0x00; pMsgObject->aucArbitrFld[3] = 0x00; } /* clear all Tx queue flags: */ for (i=CanNumberOfTxObjects-1; i >= 0; i--) { #if defined( C_TMT_QUE_USED ) TxQueueFlags[i] = 0; #endif #if defined( C_ENABLE_VARIABLE_DLC ) TxDLC_RAM[i] = CanTxDLC[i]; /*Ra new 2.0, init RAM DLC-Table*/ #endif } #if defined( C_TMT_QUE_USED ) TxQueCnt = 0; #endif /* init saved Tx handles: */ Handle_curTxObj[0] = 0xFF; /*0xFF: MsgObj is free */ Handle_curTxObj[1] = 0xFF; /* init MObj1 and MObj2 as TxObjs: */ Can82527.u.named.sMsg1Obj.ucCntrl0 = 0x55; /* reset: MsgVal, TXIE, RXIE, IntPnd */ Can82527.u.named.sMsg1Obj.ucCntrl1 = 0x55; /* reset: RmtPnd, TxRqst, MsgLst, NewDat */ Can82527.u.named.sMsg2Obj.ucCntrl0 = 0x55; /* reset: MsgVal, TXIE, RXIE, IntPnd */ Can82527.u.named.sMsg2Obj.ucCntrl1 = 0x55; /* reset: RmtPnd, TxRqst, MsgLst, NewDat */ Can82527.u.named.sMsg1Obj.ucMsgConf = 0x08; /* set dir=tx */ Can82527.u.named.sMsg2Obj.ucMsgConf = 0x08; /* set dir=tx */ /* init full can receive msg objects: */ if (CanNumberOfRxFullCANObjects > 0 ) { for (i = CanNumberOfRxObjects -1; i >= (cansint8) CanNumberOfRxBasicCANObjects ;i--) { pMsgObject = &Can82527.u.indexed.obj[13-i+CanNumberOfRxBasicCANObjects].sMsgObj; pMsgObject->ucCntrl0 = 0x55; /* reset: MsgVal,TXIE, RXIE, IntPnd*/ pMsgObject->ucCntrl1 = 0x55; /* reset: RmtPnd,TxRqst,MsgLst,NewDat*/ pMsgObject->ucMsgConf = CanRxDLC[i]; pMsgObject->aucArbitrFld[0] = CanRxIdHi[i]; pMsgObject->aucArbitrFld[1] = CanRxIdLo[i]; pMsgObject->ucCntrl0 = kSetMsgVal & kSetRxIE; } } /* init basic can receive msg object: */ pMsgObject = &Can82527.u.indexed.obj[14].sMsgObj; pMsgObject->ucCntrl0 = 0x55; /* reset: MsgVal,TXIE, RXIE, IntPnd */ pMsgObject->ucCntrl1 = 0x55; /* reset: RmtPnd,TxRqst,MsgLst,NewDat */ pMsgObject->ucMsgConf = CanRxDLC[0]; pMsgObject->aucArbitrFld[0] = CanInitMsg15CodHi[initObject]; pMsgObject->aucArbitrFld[1] = CanInitMsg15CodLo[initObject]; pMsgObject->ucCntrl0 = kSetMsgVal & kSetRxIE; /* clear pending interrupts */#if CAN527internal i = Can82527.u.named.u.in.ucIntrReg; /* clear pending interrupts */#else i = Can82527.u.named.ucExIntrReg; /* clear pending interrupts */#endif Can82527.u.named.ucStatReg = 0; /* clear hanging status-bits */ /* chip initialization finished */ Can82527.u.named.ucCntrlReg &= (~kCCE & ~kInit);/* clear ChipConfiEnableBit*/ /* clear InitBit */ return kCanTxOk;} /* END OF CanInit *//****************************************************************************| NAME: CanInitPowerOn| PROTOTYPE: ErrorCode CanInitPowerOn( CanInitHandle iniObj )| CALLED BY: Application| PRECONDITIONS: This function must be called by the application before| any other CAN driver function| INPUT PARAMETERS: Handle to initstructure| RETURN VALUES: error code| DESCRIPTION: Initialization of the CAN chip| GLOBAL DATA:| STACK:| RUNTIME:****************************************************************************/#if defined( C_COMP_KEIL_C5X5C )#pragma NOAREGS#endifErrorCode CanInitPowerOn( CanInitHandle iniObj ){#if defined( C_ENABLE_ECU_SWITCH_PASS ) fCanIsPassive = 0; /* can transmit enabled */#endif gInterruptCounter = 0; fCanStatus = kCanTxOn;#if defined( C_COMP_KEIL_C5X5C ) initObject = iniObj; return CanInit();#else return CanInit( iniObj );#endif} /* END OF CanInitPowerOn *//****************************************************************************| NAME: CanTransmitVarDLC| PROTOTYPE: canuint8 CanTransmitVarDLC(CanTransmitHandle txStruct, canuint8 dlc)| CALLED BY: Netmanagement, application| PRECONDITIONS: Can driver must be initialized| INPUT PARAMETERS: Handle to Tx message, DLC of Tx message| RETURN VALUES: kCanTxFailed: transmit failed| kCanTxOk : transmit was succesful| DESCRIPTION: If the CAN driver is not ready for send, the application| decide, whether the transmit request is repeated or not.| GLOBAL DATA:| STACK:| RUNTIME:****************************************************************************/#if defined( C_ENABLE_VARIABLE_DLC )#if defined( C_COMP_KEIL_C5X5C )#pragma NOAREGS#endifcanuint8 CanTransmitVarDLC(CanTransmitHandle txStruct, canuint8 dlc){ TxDLC_RAM[ txStruct ] = MK_TX_DLC(dlc); return CanTransmit( txStruct );}#endif/****************************************************************************| NAME: CanTransmit| PROTOTYPE: canuint8 CanTransmitVarDLC(CanTransmitHandle txStruct)| CALLED BY: Netmanagement, application| PRECONDITIONS: Can driver must be initialized| INPUT PARAMETERS: Handle of the transmit object to be send| RETURN VALUES: kCanTxFailed: transmit failed| kCanTxOk : transmit was succesful| DESCRIPTION: If the CAN driver is not ready for send, the application| decide, whether the transmit request is repeated or not.| GLOBAL DATA:| STACK:| RUNTIME:****************************************************************************/#if defined( C_COMP_KEIL_C5X5C ) #pragma NOAREGS canuint8 CanTransmit(CanTransmitHandle txStruct) small#else canuint8 CanTransmit(CanTransmitHandle txStruct)#endif{#if defined( C_COMP_KEIL_C5X5C ) CanMsgObj CAN_CHIP_ADR_MODE *pMsgObject;#else CanMsgObj *pMsgObject;#endif register TxDataPtr src; ErrorCode rc; canuint8 NoTxObj;#if defined( C_ENABLE_INTCTRL_BY_APPL ) ApplInterruptDisable();#else CanInterruptDisable();#endif#if defined( C_COMP_KEIL_C5X5C ) #if defined( C_CAN_CHIP_PDATA ) XPAGE = 0xF7; /* 8 bit addressing of CAN */ #endif#endif src = CanTxDataPtr[txStruct]; rc = kCanTxOk; /* default return value */ pMsgObject = &Can82527.u.indexed.obj[0].sMsgObj; if ( fCanStatus == kCanTxOff ) /* transmit path switched off */ { #if defined( C_ENABLE_INTCTRL_BY_APPL ) ApplInterruptRestore(); #else CanInterruptRestore(); #endif return kCanTxFailed; }#if defined( C_ENABLE_ECU_SWITCH_PASS ) if ( fCanIsPassive ) { /* can transmit disabled by application =============================== */ #if defined ( C_ENABLE_CONFIRMATION_FLAG ) /* set transmit ready flag */ if ( CanConfirmationMask[txStruct] != 0 ) { /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* MEG - Karl-Fredrik Uhlander 2000-07-05: Fix to remove compiler warning. */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ //CanConfirmationFlags[CanConfirmationOffset[txStruct]] |= CanConfirmationMask[txStruct]; CanConfirmationFlags._c[CanConfirmationOffset[txStruct]] |= CanConfirmationMask[txStruct]; } #endif #if defined ( C_ENABLE_CONFIRMATION_FCT ) if ( CanTxApplConfirmationPtr[txStruct] != NULL ) { (CanTxApplConfirmationPtr[txStruct])(txStruct); /* call completion routine */ } #endif #if defined( C_ENABLE_INTCTRL_BY_APPL ) ApplInterruptRestore(); #else CanInterruptRestore(); #endif return kCanTxOk; }#endif /* can transmit enabled ================================================== */ /* check if id is already in a tx buffer and valid (don't send same id in 2 buffers at the same time): */ { if ((((Can82527.u.named.sMsg1Obj.ucCntrl0 & kTestMsgVal ) != 0) && (Can82527.u.named.sMsg1Obj.aucArbitrFld[0] == CanTxIdHi[txStruct]) && (Can82527.u.named.sMsg1Obj.aucArbitrFld[1] == CanTxIdLo[txStruct])) || (((Can82527.u.named.sMsg2Obj.ucCntrl0 & kTestMsgVal ) != 0) && (Can82527.u.named.sMsg2Obj.aucArbitrFld[0] == CanTxIdHi[txStruct]) && (Can82527.u.named.sMsg2Obj.aucArbitrFld[1] == CanTxIdLo[txStruct]))) { #if defined( C_TMT_QUE_USED ) /* id is valid in a msg obj -> 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++; /* increment counter */ } #else rc = kCanTxFailed; #endif #if defined( C_ENABLE_INTCTRL_BY_APPL ) ApplInterruptRestore(); #else CanInterruptRestore(); #endif return rc; /* quit function */ } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -