--- /dev/null
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Include Files */\r
+\r
+\r
+\r
+#include "Can.h"\r
+#include "core_cr4.h"\r
+#if defined(USE_DEM)\r
+#include "Dem.h"\r
+#endif\r
+#include "Det.h"\r
+//#include "Spi.h"\r
+//#include "EcuM_Cbk.h"\r
+#include "CanIf_Cbk.h"\r
+//#include "MemMap.h"\r
+#include "Os.h"\r
+#include "irq.h"\r
+\r
+\r
+\r
+#if !defined(USE_DEM)\r
+#define Dem_ReportErrorStatus(...)\r
+#endif\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Variable Definition */\r
+\r
+static Can_RegisterType* CanBase[]=\r
+{\r
+ Can0_Base,\r
+#ifdef Can1_Base\r
+ Can1_Base\r
+#endif\r
+};\r
+\r
+typedef enum\r
+{\r
+ CAN_UNINIT,\r
+ CAN_READY\r
+} Can_StateType;\r
+\r
+typedef enum\r
+{\r
+ INTERRUPT = 0x00000400,\r
+ POLLING = 0x00000000\r
+} OpMode;\r
+\r
+typedef struct\r
+{\r
+ OpMode BusOff;\r
+ OpMode RxProc;\r
+ OpMode TxProc;\r
+ OpMode WakeupProc;\r
+ uint16 MessageBoxCount;\r
+ uint16 MaxBoxes;\r
+ uint8 FirstHandle;\r
+ uint32 WakeupSrc;\r
+ uint32 *MaskRefPtr;\r
+ Can_PduType *PduPtr;\r
+ uint8 *CancelPtr;\r
+ uint8 *TxPtr; \r
+} Controller_PreConfigType;\r
+\r
+\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+/* Module is in uninitialized state */\r
+static Can_StateType ModuleState = CAN_UNINIT;\r
+#endif\r
+static CanIf_ControllerModeType ControllerMode[CAN_CONTROLLER_COUNT];\r
+\r
+/* Used to switch between IF1 and IF2 of DCAN */\r
+static uint8 IfRegId = 0;\r
+\r
+/* Used to order Data Bytes according to hardware registers in DCAN */\r
+static const uint8 ElementIndex[] = {3, 2, 1, 0, 7, 6, 5, 4};\r
+\r
+/* To save pointer to the configuration set */\r
+static const Can_ConfigType *CurConfig;\r
+\r
+/* To save the PduData of transmission objects */\r
+static Can_PduType PduInfoArray_0[MAX_MESSAGEBOXES_0];\r
+/* To save pending Cancel Requests of transmission objects */\r
+static uint8 CancelRqstArray_0[MAX_MESSAGEBOXES_0];\r
+/* To save pending Transmit Requests of transmission objects */\r
+static uint8 TxRqstArray_0[MAX_MESSAGEBOXES_0];\r
+/* Array to save Filtermask references of MessageObjects */\r
+static uint32 FilterMaskRef_0[MESSAGEBOX_COUNT_0];\r
+\r
+#ifdef CanController_1\r
+static Can_PduType PduInfoArray_1[MAX_MESSAGEBOXES_1];\r
+static uint8 CancelRqstArray_1[MAX_MESSAGEBOXES_1];\r
+static uint8 TxRqstArray_1[MAX_MESSAGEBOXES_1];\r
+static uint32 FilterMaskRef_1[MESSAGEBOX_COUNT_1];\r
+#endif\r
+\r
+/* Holds the Controller specific configuration */ \r
+static Controller_PreConfigType ControllerConfig[] =\r
+{\r
+ {\r
+ BUSOFF_PROCESSING_0,\r
+ RX_PROCESSING_0,\r
+ TX_PROCESSING_0,\r
+ WAKEUP_PROCESSING_0,\r
+ MESSAGEBOX_COUNT_0,\r
+ MAX_MESSAGEBOXES_0,\r
+ FIRST_HANDLE_0,\r
+ WAKEUP_SRC_REF_0,\r
+ FilterMaskRef_0,\r
+ PduInfoArray_0,\r
+ CancelRqstArray_0,\r
+ TxRqstArray_0\r
+ },\r
+#ifdef CanController_1\r
+ {\r
+ BUSOFF_PROCESSING_1,\r
+ RX_PROCESSING_1,\r
+ TX_PROCESSING_1,\r
+ WAKEUP_PROCESSING_1,\r
+ MESSAGEBOX_COUNT_1,\r
+ MAX_MESSAGEBOXES_1,\r
+ FIRST_HANDLE_1,\r
+ WAKEUP_SRC_REF_1,\r
+ FilterMaskRef_1,\r
+ PduInfoArray_1,\r
+ CancelRqstArray_1,\r
+ TxRqstArray_1\r
+ }\r
+#endif\r
+};\r
+\r
+/* Shadow Buffer is used for buffering of received data */ \r
+static uint8 RxShadowBuf[8];\r
+\r
+/* Driver must know how often Can_DisableControllerInterrupts() has been called */\r
+static uint32 IntDisableCount[CAN_CONTROLLER_COUNT];\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can1_InterruptHandler_0 */\r
+/* Description: CAN Node 1 Level 0 Interrupt Service Routine */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+//#pragma INTERRUPT(CAN1_INTERRUPTHANDLER_0,IRQ)\r
+\r
+void CAN1_INTERRUPTHANDLER_0()\r
+{\r
+ uint32 ErrCounter;\r
+ uint32 MsgNr;\r
+ uint32 MsgId;\r
+ uint8 MsgDlc;\r
+ uint8 DataByteIndex;\r
+ uint8 *SduPtr;\r
+\r
+ //Can_DisableControllerInterrupts(0);\r
+\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+\r
+ uint32 ir = CanBase[0]->IR;\r
+\r
+ if(ir == 0x8000)\r
+ {\r
+ uint32 sr = CanBase[0]->SR;\r
+ /* WakeUp Pending */\r
+ if(sr & 0x00000200) {\r
+ /* Set Init Bit, so that Controller is in Stop state */\r
+ CanBase[0]->CTL |= 0x1;\r
+ // EcuM_CheckWakeUp(ControllerConfig[0].WakeupSrc);\r
+\r
+ }\r
+ /* Bus Off */\r
+ if(sr & 0x00000080) {\r
+ Can_SetControllerMode(0, CAN_T_STOP); // CANIF272\r
+ //CanIf_ControllerBusOff(0); // Not implemented in Arctic Core\r
+\r
+ }\r
+ }\r
+ else\r
+ {\r
+ MsgNr = ir;\r
+\r
+ /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/\r
+ CanBase[0]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;\r
+\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[0]->IFx[IfRegId].COM & 0x8000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return;\r
+ }\r
+ }\r
+\r
+ /* Transmit Object */\r
+ if(CanBase[0]->IFx[IfRegId].ARB & 0x20000000)\r
+ {\r
+ /* Reset TxRqst-Array Element */\r
+ TxRqstArray_0[MsgNr - 1] = 0;\r
+ /* A Message was successfully transmitted */\r
+ CanIf_TxConfirmation(PduInfoArray_0[MsgNr - 1].swPduHandle);\r
+ }\r
+ /* Receive Object */\r
+ else\r
+ {\r
+ /* Extended Id */\r
+ if(CanBase[0]->IFx[IfRegId].ARB & 0x40000000)\r
+ {\r
+ /* Bring Id to standardized format (MSB marks extended Id) */\r
+ MsgId = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;\r
+ }\r
+ /* Standard Id */\r
+ else\r
+ {\r
+ /* Bring Id to standardized format (MSB marks extended Id) */\r
+ MsgId = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;\r
+ }\r
+ /* DLC (Max 8) */\r
+ MsgDlc = CanBase[0]->IFx[IfRegId].MC & 0x000F;\r
+ if(MsgDlc > 8)\r
+ {\r
+ MsgDlc = 8;\r
+ }\r
+ /* Let SduPtr point to Shadow Buffer */\r
+ SduPtr = RxShadowBuf;\r
+\r
+ /* Copy Message Data to Shadow Buffer */\r
+ for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
+ {\r
+ RxShadowBuf[DataByteIndex] = CanBase[0]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
+ }\r
+ /* Indicate successful Reception */\r
+ CanIf_RxIndication(CurConfig->MessageBoxPtr[MsgNr - 1].ObjectId, MsgId, MsgDlc, SduPtr);\r
+ }\r
+ }\r
+ //Can_EnableControllerInterrupts(0);\r
+}\r
+\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_Init */\r
+/* Service Id: 0x00 */\r
+/* Execution: Synchronous */\r
+/* Re-entrant: No */\r
+/* Description: Initialize Can Driver */\r
+/* ConfigPtr: Pointer to initialization data */\r
+/* Return Value: None */\r
+/* Remarks: */\r
+/* */\r
+void CAN_INIT(const Can_ConfigType *Config)\r
+{\r
+ uint32 Controller;\r
+ uint8 MsgNr;\r
+ uint32 ErrCounter;\r
+ Can_ControllerConfigType *CurControllerPtr;\r
+ Can_MessageObjectType *MsgBoxPtr;\r
+ uint32 *CurFilterMaskPtr;\r
+ uint32 Eob;\r
+\r
+/* DET Error Check */\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(ModuleState != CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_TRANSITION);\r
+ return;\r
+ }\r
+ if(Config == NULL)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_PARAM_POINTER);\r
+ return;\r
+ }\r
+#endif \r
+ \r
+ CurConfig = Config;\r
+ /* Set Pointer to ControllerConfig */\r
+ CurControllerPtr = Config->ControllerConfigPtr; \r
+ /* Set Pointer to MessageObjects */\r
+ MsgBoxPtr = CurConfig->MessageBoxPtr;\r
+\r
+ for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
+ {\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+\r
+ /* Init, IE, AutomaticRetransmission, ConfChangeEnable, ABO Off,Parity On, SIE and EIE depending on ControllerConfig */\r
+#if(CAN_WAKEUP_SUPPORT == STD_ON)\r
+ CanBase[Controller]->CTL = 0x02001643 | (ControllerConfig[Controller].WakeupProc >> 8) | (ControllerConfig[Controller].BusOff >> 7);\r
+#else\r
+ CanBase[Controller]->CTL = 0x00001643 | (ControllerConfig[Controller].WakeupProc >> 8) | (ControllerConfig[Controller].BusOff >> 7);\r
+#endif \r
+ /* LEC 7, TxOk, RxOk, PER */\r
+ CanBase[Controller]->SR = 0x0000011F;\r
+\r
+ /* Test Mode only for Development time: Silent Loopback */\r
+ //CanBase[Controller]->CTL |= 0x00000080;\r
+ //CanBase[Controller]->TR = 0x00000018;\r
+ \r
+ for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MaxBoxes; MsgNr++)\r
+ {\r
+ /* Initialize the Arrays for Transmit and Cancellation handling */\r
+ *(ControllerConfig[Controller].CancelPtr + MsgNr) = 0;\r
+ *(ControllerConfig[Controller].TxPtr + MsgNr) = 0;\r
+ \r
+ /* Set the current FilterMaskPointer */\r
+ CurFilterMaskPtr = CurControllerPtr->FilterMaskPtr;\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return;\r
+ }\r
+ }\r
+ /* Configure the post-build defined MessageObjects */\r
+ if(MsgNr < ControllerConfig[Controller].MessageBoxCount)\r
+ { \r
+ /* Check, if the next message object has the same values as the current, and if it is the last one */ \r
+ if((MsgNr < (ControllerConfig[Controller].MessageBoxCount - 1)) &&\r
+ (MsgBoxPtr->Direction == CAN_RECEIVE ) &&\r
+ (MsgBoxPtr->Direction == (MsgBoxPtr + 1)->Direction ) &&\r
+ (MsgBoxPtr->IdType == (MsgBoxPtr + 1)->IdType ) &&\r
+ (MsgBoxPtr->IdValue == (MsgBoxPtr + 1)->IdValue ) &&\r
+ (MsgBoxPtr->FilterMaskIndex == (MsgBoxPtr + 1)->FilterMaskIndex) &&\r
+ (MsgBoxPtr->HandleType == (MsgBoxPtr + 1)->HandleType )\r
+ )\r
+ {\r
+ /* EndOfBlock Bit will not be set */\r
+ Eob = 0x00000000;\r
+ }\r
+ else\r
+ {\r
+ /* EndOfBlock Bit will be set */\r
+ Eob = 0x00000080;\r
+ }\r
+ /* DLC=8, Use Mask only for receive, Set RxIE/TxIE depending on pre-config settings, Eob */\r
+ CanBase[Controller]->IFx[IfRegId].MC = 0x00001008 | ControllerConfig[Controller].RxProc | (ControllerConfig[Controller].TxProc << 1) | Eob & ~(MsgBoxPtr->Direction >> 17);\r
+ \r
+ if(MsgBoxPtr->IdType == CAN_STANDARD) /* Standard Identifiers */\r
+ {\r
+ /* Only Standard-Ids are accepted, Set Mask */\r
+ CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(CurFilterMaskPtr + MsgBoxPtr->FilterMaskIndex)) & 0x1FFFFFFF);\r
+ /* Message valid, Id, Direction */\r
+ CanBase[Controller]->IFx[IfRegId].ARB = 0x80000000 | ((MsgBoxPtr->IdValue & 0x7FF) << 18) | MsgBoxPtr->Direction;\r
+ }\r
+ else if(MsgBoxPtr->IdType == CAN_EXTENDED) /* Extended Identifiers */\r
+ {\r
+ /* Only Extended-Ids are accepted, Set Mask */\r
+ CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(CurFilterMaskPtr + MsgBoxPtr->FilterMaskIndex)) & 0x1FFFFFFF);\r
+ /* Message valid, Id, Direction */\r
+ CanBase[Controller]->IFx[IfRegId].ARB = 0xC0000000 | (MsgBoxPtr->IdValue & 0x1FFFFFFF) | MsgBoxPtr->Direction; \r
+ }\r
+ else /* Mixed Identifiers */\r
+ {\r
+ /* Standard- and Mixed-Ids are accepted, Set Mask */\r
+ CanBase[Controller]->IFx[IfRegId].MASK = 0x00000000 | ((*(CurFilterMaskPtr + MsgBoxPtr->FilterMaskIndex)) & 0x1FFFFFF);\r
+ /* Message valid, Id, Direction */\r
+ CanBase[Controller]->IFx[IfRegId].ARB = 0xC0000000 | (MsgBoxPtr->IdValue & 0x1FFFFFF) | MsgBoxPtr->Direction;\r
+ }\r
+ /* Start writing Mask, Arb, Control and Id bits */\r
+ CanBase[Controller]->IFx[IfRegId].COM = 0x00F80000 | (MsgNr + 1);\r
+ \r
+ /* Save FilterMask reference of actual MessageObject */\r
+ *(ControllerConfig[Controller].MaskRefPtr + MsgNr) = MsgBoxPtr->FilterMaskIndex;\r
+\r
+ /* Increment Pointer to next MessageObject */\r
+ MsgBoxPtr++;\r
+ }\r
+ else /* Configure all other MessageObjects to not valid */\r
+ {\r
+ /* Valid = 0 */\r
+ CanBase[Controller]->IFx[IfRegId].ARB = 0x00000000;\r
+ /* Start writing Arbitration Bits */\r
+ CanBase[Controller]->IFx[IfRegId].COM = 0x00A80000 | (MsgNr + 1);\r
+ }\r
+ /* Use IFx[0] and IFx[1] alternating */\r
+ IfRegId ^= 1;\r
+ }\r
+ /* Set Bit Timing Register */\r
+ CanBase[Controller]->BTR = CurControllerPtr->CanTimeRegister;\r
+ /* Reset CCE Bit */\r
+ CanBase[Controller]->CTL &= ~0x00000040;\r
+\r
+ /* Switch Controller pointer to next ConfigSet */\r
+ CurControllerPtr++;\r
+\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ /* Switch Controller State to CANIF_CS_STOPPED */\r
+ ControllerMode[Controller] = CANIF_CS_STOPPED;\r
+#endif\r
+ }\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ /* Switch Module State to CAN_READY */\r
+ ModuleState = CAN_READY;\r
+#endif\r
+\r
+\r
+ // ARC INSTALL HANDLERS\r
+ TaskType tid;\r
+ tid = Os_Arc_CreateIsr(CAN1_INTERRUPTHANDLER_0, 2 ,"Can0Level0");\r
+ Irq_AttachIsr2(tid, NULL, 16);\r
+\r
+ tid = Os_Arc_CreateIsr(CAN1_INTERRUPTHANDLER_0, 2, "Can0Level1");\r
+ Irq_AttachIsr2(tid, NULL, 29);\r
+\r
+}\r
+\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_InitController */\r
+/* Service Id: 0x02 */\r
+/* Execution: Synchronous */\r
+/* Re-entrant: No */\r
+/* Description: Initializes only CAN cantroller specific settings */\r
+/* Controller: CAN controller to be initialized */\r
+/* Config: Pointer to controller configuration */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void CAN_INITCONTROLLER(uint8 Controller, const Can_ControllerConfigType* Config)\r
+{\r
+ uint32 *CurMaskRef;\r
+ uint8 MsgNr;\r
+ uint32 ErrCounter;\r
+\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(Config == NULL)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_POINTER);\r
+ return;\r
+ }\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_UNINIT);\r
+ return;\r
+ }\r
+ if(Controller >= CAN_CONTROLLER_COUNT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_CONTROLLER);\r
+ return;\r
+ }\r
+ if(ControllerMode[Controller] != CANIF_CS_STOPPED)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_TRANSITION);\r
+ return;\r
+ }\r
+#endif \r
+\r
+ CurMaskRef = ControllerConfig[Controller].MaskRefPtr;\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ \r
+ for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)\r
+ {\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return;\r
+ }\r
+ }\r
+ /* Read actual MaskRegister value of MessageObject */\r
+ CanBase[Controller]->IFx[IfRegId].COM = 0x004C0000 | (MsgNr + 1);\r
+\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return;\r
+ }\r
+ }\r
+ CanBase[Controller]->IFx[IfRegId].MASK &= 0xD0000000;\r
+ /* Set new Mask */\r
+ CanBase[Controller]->IFx[IfRegId].MASK |= *(Config->FilterMaskPtr + *CurMaskRef) & 0x1FFFFFFF;\r
+ /* Write new Mask to MaskRegister */\r
+ CanBase[Controller]->IFx[IfRegId].COM = 0x00C80000 | (MsgNr + 1); \r
+ \r
+ CurMaskRef++;\r
+\r
+ IfRegId ^= 1;\r
+ }\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return;\r
+ }\r
+ } \r
+ /* Set CCE Bit to allow access to BitTiming Register (Init already set, in mode "stopped") */\r
+ CanBase[Controller]->CTL |= 0x00000040;\r
+ /* Set Bit Timing Register */\r
+ CanBase[Controller]->BTR = Config->CanTimeRegister;\r
+ /* Clear CCE Bit */\r
+ CanBase[Controller]->CTL &= ~0x00000040;\r
+\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_SetControllerMode */\r
+/* Service Id: 0x03 */\r
+/* Execution: Asynchronous */\r
+/* Re-entrant: No */\r
+/* Descrpition: Performs software triggered state transitions */\r
+/* Controller: CAN controller for which the status shall be changed */\r
+/* Transition: Transition to be done */\r
+/* Return Value: - CAN_OK: transition initiated */\r
+/* - CAN_NOT_OK: error or wakeup during transition to 'sleep' */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType Transition)\r
+{\r
+ Can_ReturnType Status = CAN_OK;\r
+ uint32 ErrCounter = CAN_TIMEOUT_DURATION;\r
+ uint32 RegBuf;\r
+ \r
+#if(CAN_DEV_ERROR_DETECT == STD_ON) \r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_UNINIT);\r
+ return CAN_NOT_OK;\r
+ }\r
+ if(Controller >= CAN_CONTROLLER_COUNT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_PARAM_CONTROLLER);\r
+ return CAN_NOT_OK;\r
+ }\r
+ if(((Transition == CAN_T_START ) && (ControllerMode[Controller] != CANIF_CS_STOPPED)) ||\r
+ ((Transition == CAN_T_STOP ) && (ControllerMode[Controller] != CANIF_CS_STARTED)) ||\r
+ ((Transition == CAN_T_SLEEP ) && (ControllerMode[Controller] != CANIF_CS_STOPPED)) ||\r
+ ((Transition == CAN_T_WAKEUP) && (ControllerMode[Controller] != CANIF_CS_SLEEP )))\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_TRANSITION);\r
+ return CAN_NOT_OK;\r
+ }\r
+#endif \r
+\r
+ switch(Transition)\r
+ {\r
+ case CAN_T_START:\r
+ /* Clear Init Bit */\r
+ CanBase[Controller]->CTL &= ~0x00000001;\r
+ /* Clear Status Register */\r
+ CanBase[Controller]->SR = 0x0000011F;\r
+\r
+ ControllerMode[Controller] = CANIF_CS_STARTED;\r
+ Can_EnableControllerInterrupts(Controller);\r
+ break;\r
+\r
+ case CAN_T_STOP:\r
+ /* Set Init Bit */\r
+ CanBase[Controller]->CTL |= 0x00000001;\r
+ ControllerMode[Controller] = CANIF_CS_STOPPED;\r
+ Can_DisableControllerInterrupts(Controller);\r
+ break;\r
+\r
+ case CAN_T_SLEEP:\r
+ /* Set PDR Bit */\r
+ CanBase[Controller]->CTL |= 0x01000000;\r
+ /* Save actual Register status */\r
+ RegBuf = CanBase[Controller]->CTL;\r
+ /* Disable Status Interrupts and WUBA */\r
+ CanBase[Controller]->CTL &= ~0x02000004;\r
+ /* Wait until Local Power Down Mode acknowledged */\r
+ while(!(CanBase[Controller]->SR & 0x00000400))\r
+ {\r
+ /* Check if a WakeUp occurs */\r
+ if(CanBase[Controller]->SR & 0x00000200)\r
+ {\r
+ Status = CAN_NOT_OK;\r
+ break;\r
+ }\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ Status = CAN_NOT_OK;\r
+ break;\r
+ }\r
+ }\r
+ /* Reset Control Register */\r
+ CanBase[Controller]->CTL = RegBuf;\r
+ ControllerMode[Controller] = CANIF_CS_SLEEP;\r
+ break;\r
+\r
+ case CAN_T_WAKEUP:\r
+ /* Clear PDR Bit */\r
+ CanBase[Controller]->CTL &= ~0x01000000;\r
+ ControllerMode[Controller] = CANIF_CS_STOPPED;\r
+ break;\r
+\r
+ default:\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ /* Invalid Transition */\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_TRANSITION);\r
+ return CAN_NOT_OK;\r
+#endif\r
+ break;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_DisableControllerInterrupts */\r
+/* Service Id: 0x04 */\r
+/* Execution: Synchronous */\r
+/* Re-entrant: Yes */\r
+/* Description: Disables all interrupts for this controller */\r
+/* Controller: CAN controller for which interrupts shall be disabled */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void Can_DisableControllerInterrupts(uint8 Controller)\r
+{\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_UNINIT);\r
+ return;\r
+ }\r
+ if(Controller >= CAN_CONTROLLER_COUNT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_PARAM_CONTROLLER);\r
+ return;\r
+ }\r
+#endif \r
+ /* Clear IE */\r
+ CanBase[Controller]->CTL &= ~0x00000002;\r
+ /* Increment Disable Counter */\r
+ IntDisableCount[Controller]++;\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_EnableControllerInterrupts */\r
+/* Service Id: 0x05 */\r
+/* Execution: Synchronous */\r
+/* Re-entrant: Yes */\r
+/* Description: Enables all allowed interrupts for this controller */\r
+/* Controller: CAN controller for which interrupts shall be re-enabled */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void Can_EnableControllerInterrupts(uint8 Controller)\r
+{\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_UNINIT);\r
+ return;\r
+ }\r
+ if(Controller >= CAN_CONTROLLER_COUNT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_PARAM_CONTROLLER);\r
+ return;\r
+ }\r
+#endif \r
+ if(IntDisableCount[Controller] > 0)\r
+ {\r
+ if(IntDisableCount[Controller] == 1)\r
+ {\r
+ /* Set IE */\r
+ CanBase[Controller]->CTL |= 0x00000002;\r
+ }\r
+ IntDisableCount[Controller]--;\r
+ }\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_Cbk_CheckWakeup */\r
+/* Service Id: 0x0b */\r
+/* Execution: Synchronous */\r
+/* Re-entrant: No */\r
+/* Description: Checks if a wakeup has occurred for the given controller */\r
+/* Controller: CAN controller to be checked for wakeup */\r
+/* Return Value: - E_OK: Wakeup was detected for given controller */\r
+/* - E_NOT_OK: No Wakeup was detected */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void Can_Cbk_CheckWakeup(uint8 Controller)\r
+{\r
+ /*\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(Controller >= CAN_CONTROLLER_COUNT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0x0B, CAN_E_PARAM_CONTROLLER);\r
+ return CAN_NOT_OK;\r
+ }\r
+#endif\r
+ // Check WakeUpPending\r
+ if(CanBase[Controller]->SR & 0x00000200)\r
+ {\r
+ return E_OK;\r
+ }\r
+ else\r
+ {\r
+ return E_NOT_OK;\r
+ }\r
+ */\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_Write */\r
+/* Service Id: 0x06 */\r
+/* Execution: Synchronous */\r
+/* Re-entrant: Yes (thread-safe) */\r
+/* Description: -- */\r
+/* Hth: HW-transmit handle to be used for transmit */\r
+/* PduInfo: Pointer to SDU user memory, DLC and Identifier */\r
+/* Return Value: - CAN_OK: Write command has been accepted */\r
+/* - CAN_NOT_OK: Development error occured */\r
+/* - CAN_BUSY: No TX hw buffer available or preemptive call */ \r
+/* Remarks: -/- */\r
+/* */\r
+\r
+Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)\r
+{\r
+ uint32 ErrCounter;\r
+ uint8 ControllerId;\r
+ uint8 MsgNr;\r
+ uint32 CancelId;\r
+ uint8 CancelNr; \r
+ uint32 ArbRegValue;\r
+ uint8 DataByteIndex;\r
+ uint8 *CurSduPtr;\r
+ Can_PduType *CurPduArrayPtr;\r
+ uint8 *CurCancelRqstPtr;\r
+ uint8 *CurTxRqstPtr;\r
+ Can_MessageObjectType *CurMsgBoxPtr;\r
+\r
+ CurSduPtr = PduInfo->sdu;\r
+ CurMsgBoxPtr = CurConfig->MessageBoxPtr + Hth;\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ \r
+/* DET Error Check */\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(PduInfo == NULL || PduInfo->sdu == NULL)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_POINTER);\r
+ return CAN_NOT_OK;\r
+ }\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_UNINIT);\r
+ return CAN_NOT_OK;\r
+ }\r
+ if(PduInfo->length > 8)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_DLC);\r
+ return CAN_NOT_OK; \r
+ }\r
+ if(CurMsgBoxPtr->Direction != CAN_TRANSMIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_HANDLE);\r
+ return CAN_NOT_OK;\r
+ } \r
+#endif\r
+\r
+ ControllerId = CurMsgBoxPtr->Controller;\r
+ \r
+ MsgNr = Hth - ControllerConfig[ControllerId].FirstHandle;\r
+\r
+ CurPduArrayPtr = ControllerConfig[ControllerId].PduPtr + MsgNr;\r
+ CurCancelRqstPtr = ControllerConfig[ControllerId].CancelPtr + MsgNr;\r
+ CurTxRqstPtr = ControllerConfig[ControllerId].TxPtr + MsgNr;\r
+ \r
+ /* Bring Id Value to appropriate format and set ArbRegValue */\r
+ if(PduInfo->id & 0x80000000)\r
+ {\r
+ /* MsgVal, Ext, Transmit, Extended Id */ \r
+ ArbRegValue = 0xD0000000 | (PduInfo->id & 0x1FFFFFFF);\r
+ }\r
+ else\r
+ {\r
+ /* MsgVal, Std, Transmit, Standard Id */ \r
+ ArbRegValue = 0xA0000000 | ((PduInfo->id & 0x7FF) << 18);\r
+ }\r
+\r
+ /* Check if TxRqst Bit of MsgObject is set */\r
+ if(CanBase[ControllerId]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F)))\r
+ {\r
+\r
+#if(CAN_MULTIPLEXED_TRANSMISSION == STD_ON)\r
+\r
+ CancelId = ArbRegValue & 0x1FFFFFFF;\r
+ CancelNr = MsgNr;\r
+\r
+ for(MsgNr = ControllerConfig[ControllerId].MessageBoxCount; MsgNr < ControllerConfig[ControllerId].MaxBoxes; MsgNr++)\r
+ {\r
+ /* Read actual MessageObject status: Data, Arbitration, Control */\r
+ CanBase[ControllerId]->IFx[IfRegId].COM = 0x00330000 | (MsgNr + 1); \r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return CAN_NOT_OK;\r
+ }\r
+ }\r
+\r
+ /* If MessageObject is free, use it */\r
+ if(!(CanBase[ControllerId]->IFx[IfRegId].MC & 0x00000100))\r
+ {\r
+ CurPduArrayPtr = ControllerConfig[ControllerId].PduPtr + MsgNr;\r
+ break;\r
+ }\r
+ /* Check if Id of MessageObject is higher */\r
+ if((CanBase[ControllerId]->IFx[IfRegId].ARB & 0x1FFFFFFF) > CancelId )\r
+ {\r
+ /* Save the highest ID (low priority) */\r
+ CancelId = CanBase[ControllerId]->IFx[IfRegId].ARB & 0x1FFFFFFF;\r
+ /* and corresponding message number */\r
+ CancelNr = MsgNr;\r
+ }\r
+ }\r
+ if(MsgNr == ControllerConfig[ControllerId].MaxBoxes)\r
+ {\r
+#if(CAN_HW_TRANSMIT_CANCELLATION == STD_ON)\r
+ /* Clear TxRqst */\r
+ CanBase[ControllerId]->IFx[IfRegId].MC &= ~0x00000100;\r
+ /* Transfer Control bits to MessageObject */\r
+ CanBase[ControllerId]->IFx[IfRegId].COM = 0x90000000 | (CancelNr + 1);\r
+ \r
+ if(ControllerConfig[ControllerId].TxProc == INTERRUPT)\r
+ {\r
+ /* Set CurPduPtr to Pdu of object to cancel */ \r
+ CurPduArrayPtr = ControllerConfig[ControllerId].PduPtr + CancelNr;\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return CAN_NOT_OK;\r
+ }\r
+ }\r
+ /* Notification about cancellation of object */\r
+ CanIf_CancelTxConfirmation((const Can_PduType *)CurPduArrayPtr);\r
+ }\r
+ else\r
+ {\r
+ /* Set CancelPointer to Position of cancelled Object */\r
+ CurCancelRqstPtr = ControllerConfig[ControllerId].CancelPtr + CancelNr;\r
+ /* Set Arrayelement to 1 to indicate cancellation request */\r
+ *CurCancelRqstPtr = 1;\r
+ }\r
+#endif\r
+ }\r
+#elif(CAN_HW_TRANSMIT_CANCELLATION == STD_ON)\r
+ \r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return CAN_NOT_OK;\r
+ }\r
+ }\r
+\r
+ /* Read actual MessageObject status: Data, Arbitration, Control */\r
+ CanBase[ControllerId]->IFx[IfRegId].COM = 0x00330000 | (MsgNr + 1);\r
+\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return CAN_NOT_OK;\r
+ }\r
+ } \r
+ \r
+ /* Check if actual message has higher priority */\r
+ if((ArbRegValue & 0x1FFFFFFF) < (CanBase[ControllerId]->IFx.ARB & 0x1FFFFFFF))\r
+ {\r
+ /* Clear TxRqst */\r
+ CanBase[ControllerId]->IFx[IfRegId].MC &= ~0x00000100;\r
+ /* Transfer Control bits to MessageObject */\r
+ CanBase[ControllerId]->IFx[IfRegId].COM = 0x90000000 | (MsgNr + 1);\r
+ \r
+ if(ControllerConfig[ControllerId].TxProc == INTERRUPT)\r
+ {\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return CAN_NOT_OK;\r
+ }\r
+ } \r
+ /* Notification about cancellation of object */\r
+ CanIf_CancelTxConfirmation((const Can_PduType *)CurPduArrayPtr);\r
+ }\r
+ else\r
+ {\r
+ /* Set Arrayelement to 1 to indicate cancellation request */\r
+ *CurCancelRqstPtr = 1;\r
+ }\r
+ }\r
+#endif\r
+ return CAN_BUSY;\r
+ }\r
+\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return CAN_NOT_OK;\r
+ }\r
+ }\r
+\r
+ /* Set NewDat, TxIE (dep on ControllerConfig), TxRqst, EoB and DLC */\r
+ CanBase[ControllerId]->IFx[IfRegId].MC = 0x00000180 | (0x000F & PduInfo->length) | (ControllerConfig[ControllerId].TxProc << 1);\r
+\r
+ /* Set ArbitrationRegister */\r
+ CanBase[ControllerId]->IFx[IfRegId].ARB = ArbRegValue;\r
+\r
+ /* Set Databytes */\r
+ for(DataByteIndex = 0; DataByteIndex < PduInfo->length; DataByteIndex++)\r
+ {\r
+ CanBase[ControllerId]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]] = *CurSduPtr++;\r
+ }\r
+\r
+ /* Start transmission to MessageRAM */\r
+ CanBase[ControllerId]->IFx[IfRegId].COM = 0x00BF0000 | (MsgNr + 1);\r
+ \r
+ /* Save the PduInfo in PduArray, so that messages can be identified later */\r
+ *CurPduArrayPtr = *PduInfo;\r
+ /* TxRqstArray-Elements are used to identifiy transmitted objects in polling mode */\r
+ *CurTxRqstPtr = 1;\r
+ \r
+ IfRegId ^= 1;\r
+ \r
+ return CAN_OK;\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_MainFunction_Write */\r
+/* Service Id: 0x01 */\r
+/* Timing: FIXED_CYCLIC */\r
+/* Description: Polling of TX confirmation and TX cancellation confirmation */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void CAN_MAINFUNCTION_WRITE()\r
+{\r
+#if 0\r
+ uint8 Controller;\r
+ uint8 MsgNr;\r
+ Can_PduType *CurPduPtr;\r
+\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 1, CAN_E_UNINIT);\r
+ return;\r
+ }\r
+#endif \r
+ /* Check all controllers */\r
+ for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
+ {\r
+ /* Check all MessageObjects */\r
+ for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MaxBoxes; MsgNr++)\r
+ {\r
+ /* Check if a transmission was initiated for this MessageObject */\r
+ if(*(ControllerConfig[Controller].TxPtr + MsgNr) == 1)\r
+ {\r
+ /* Check if TxRqst Bit has already been reset */\r
+ if(!(CanBase[Controller]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))))\r
+ {\r
+ /* Reset swTxRqst */\r
+ *(ControllerConfig[Controller].TxPtr + MsgNr) = 0;\r
+ \r
+ CurPduPtr = ControllerConfig[Controller].PduPtr + MsgNr;\r
+ /* A Message was successfully transmitted */\r
+ CanIf_TxConfirmation(CurPduPtr->swPduHandle);\r
+ }\r
+ }\r
+ /* Check if a cancellation was initiated for this MessageObject */\r
+ if(*(ControllerConfig[Controller].CancelPtr + MsgNr) == 1)\r
+ {\r
+ /* Check if TxRqst Bit has already been reset */\r
+ if(!(CanBase[Controller]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))))\r
+ {\r
+ /* Reset swCancelRqst */\r
+ *(ControllerConfig[Controller].CancelPtr + MsgNr) = 0;\r
+ \r
+ CurPduPtr = ControllerConfig[Controller].PduPtr + MsgNr;\r
+ /* A Message was successfully transmitted */\r
+ CanIf_CancelTxConfirmation(CurPduPtr); \r
+ }\r
+ }\r
+ }\r
+ }\r
+#endif\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_MainFunction_Read */\r
+/* Service Id: 0x08 */\r
+/* Timing: FIXED_CYCLIC */\r
+/* Description: Polling of RX indications */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void CAN_MAINFUNCTION_READ()\r
+{\r
+#if 0\r
+ uint8 Controller;\r
+ uint8 MsgNr;\r
+ Can_MessageObjectType *CurMsgBoxPtr;\r
+ uint8 MsgDlc;\r
+ uint32 Identifier;\r
+ uint8 DataByteIndex;\r
+ uint8 *SduPtr;\r
+ uint32 ErrCounter; \r
+ \r
+\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 8, CAN_E_UNINIT);\r
+ return;\r
+ }\r
+#endif\r
+\r
+ CurMsgBoxPtr = CurConfig->MessageBoxPtr;\r
+ \r
+ for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
+ {\r
+ for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)\r
+ {\r
+ /* Check if NewDat Bit is set and if MessageObject is Receive Object */\r
+ if((CanBase[Controller]->NDx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))) && (CurMsgBoxPtr->Direction == RECEIVE))\r
+ {\r
+ \r
+ /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/\r
+ CanBase[Controller]->IFx[IfRegId].COM = 0x003F0000 | (MsgNr + 1);\r
+ \r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[Controller]->IFx[IfRegId].COM & 0x8000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ return;\r
+ }\r
+ }\r
+ /* Extended Id */\r
+ if(CanBase[0]->IFx[IfRegId].ARB & 0x40000000)\r
+ {\r
+ /* Bring Id to standardized format (MSB marks extended Id) */\r
+ Identifier = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;\r
+ }\r
+ /* Standard Id */\r
+ else\r
+ {\r
+ /* Bring Id to standardized format (MSB marks extended Id) */\r
+ Identifier = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;\r
+ }\r
+ /* DLC (Max 8) */\r
+ MsgDlc = CanBase[0]->IFx[IfRegId].MC & 0x000F;\r
+ if(MsgDlc > 8)\r
+ {\r
+ MsgDlc = 8;\r
+ }\r
+ /* Let SduPtr point to Shadow Buffer */\r
+ SduPtr = RxShadowBuf;\r
+\r
+ /* Copy Message Data to Shadow Buffer */\r
+ for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
+ {\r
+ RxShadowBuf[DataByteIndex] = CanBase[0]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
+ }\r
+ /* Indicate successful Reception */\r
+ CanIf_RxIndication(MsgNr, Identifier, MsgDlc, SduPtr);\r
+ } \r
+ CurMsgBoxPtr++;\r
+ }\r
+ }\r
+#endif\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_MainFunction_BusOff */\r
+/* Service Id: 0x09 */\r
+/* Timing: FIXED_CYCLIC */\r
+/* Description: Polling of bus-off events */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void CAN_MAINFUNCTION_BUSOFF()\r
+{\r
+ uint8 Controller;\r
+\r
+/* DET Error Check */\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 9, CAN_E_UNINIT);\r
+ return;\r
+ } \r
+#endif\r
+ \r
+ for(Controller = 0 ; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
+ {\r
+ /* Bus Off */\r
+ if(CanBase[Controller]->SR & 0x00000080)\r
+ {\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ ControllerMode[Controller] = CANIF_CS_STOPPED;\r
+#endif\r
+ CanIf_ControllerBusOff(Controller);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can_MainFunction_Wakeup */\r
+/* Service Id: 0x0a */\r
+/* Timing: FIXED_CYCLIC */\r
+/* Description: Polling of wake-up events */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+\r
+void CAN_MAINFUNCTION_WAKEUP()\r
+{\r
+ uint8 Controller;\r
+\r
+/* DET Error Check */\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ if(ModuleState == CAN_UNINIT)\r
+ {\r
+ Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0xA, CAN_E_UNINIT);\r
+ return;\r
+ } \r
+#endif\r
+\r
+ for(Controller = 0 ; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
+ {\r
+ /* Check WakeUp Pending */\r
+ if(CanBase[Controller]->SR & 0x200)\r
+ {\r
+ /* Set Init Bit, so that Controller is in Stop state */\r
+ CanBase[Controller]->CTL |= 0x1;\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ ControllerMode[Controller] = CANIF_CS_STOPPED;\r
+#endif\r
+ //EcuM_CheckWakeUp(ControllerConfig[Controller].WakeupSrc);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* Function Name: Can2_InterruptHandler_0 */\r
+/* Description: CAN Node 2 Level 0 Interrupt Service Routine */\r
+/* Return Value: None */\r
+/* Remarks: -/- */\r
+/* */\r
+#ifdef CanController_1\r
+//#pragma INTERRUPT(CAN2_INTERRUPTHANDLER_0,IRQ)\r
+\r
+void CAN2_INTERRUPTHANDLER_0()\r
+{\r
+\r
+ uint32 ErrCounter;\r
+ uint32 MsgNr;\r
+ uint32 MsgId;\r
+ uint8 MsgDlc;\r
+ uint8 DataByteIndex;\r
+ uint8 *SduPtr; \r
+\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ \r
+ if(CanBase[1]->IR == 0x8000)\r
+ {\r
+ /* WakeUp Pending */\r
+ if(CanBase[1]->SR & 0x200)\r
+ {\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ ControllerMode[1] = CANIF_CS_STOPPED;\r
+#endif\r
+ /* Set Init Bit, so that Controller is in Stop state */\r
+ CanBase[1]->CTL |= 0x1;\r
+ // EcuM_CheckWakeUp(ControllerConfig[1].WakeupSrc);\r
+ }\r
+ /* Bus Off */\r
+ if(CanBase[1]->SR & 0x080)\r
+ {\r
+#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
+ ControllerMode[1] = CANIF_CS_STOPPED;\r
+#endif\r
+ CanIf_ControllerBusOff(1);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ MsgNr = CanBase[1]->IR;\r
+ \r
+ /* Read Arbitration, Control and Data Bits and clear IntPnd */\r
+ CanBase[1]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;\r
+ \r
+ /* Wait until Busy Flag is 0 */\r
+ while(CanBase[1]->IFx[IfRegId].COM & 0x8000)\r
+ {\r
+ ErrCounter--;\r
+ if(ErrCounter == 0)\r
+ {\r
+ Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
+ ErrCounter = CAN_TIMEOUT_DURATION;\r
+ return;\r
+ }\r
+ }\r
+ \r
+ /* Transmit Object */\r
+ if(CanBase[1]->IFx[IfRegId].ARB & 0x20000000)\r
+ {\r
+ /* Reset TxRqst-Array Element */\r
+ TxRqstArray_1[MsgNr - 1] = 0;\r
+ /* A Message was successfully transmitted */\r
+ CanIf_TxConfirmation(PduInfoArray_1[MsgNr - 1].swPduHandle);\r
+ } \r
+ /* Receive Object */\r
+ else\r
+ {\r
+ /* Extended Id */\r
+ if(CanBase[1]->IFx[IfRegId].ARB & 0x40000000)\r
+ {\r
+ /* Bring Id to standardized format (MSB marks extended Id) */\r
+ MsgId = (CanBase[1]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;\r
+ }\r
+ /* Standard Id */\r
+ else\r
+ {\r
+ /* Bring Id to standardized format (MSB marks extended Id) */\r
+ MsgId = (CanBase[1]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;\r
+ }\r
+ /* DLC (Max 8) */\r
+ MsgDlc = CanBase[1]->IFx[IfRegId].MC & 0x000F;\r
+ if(MsgDlc > 8)\r
+ {\r
+ MsgDlc = 8;\r
+ }\r
+ /* Let SduPtr point to Shadow Buffer */\r
+ SduPtr = RxShadowBuf;\r
+\r
+ /* Copy Message Data to Shadow Buffer */\r
+ for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
+ {\r
+ RxShadowBuf[DataByteIndex] = CanBase[1]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
+ }\r
+ /* Indicate successful Reception */\r
+ CanIf_RxIndication(MsgNr - 1, MsgId, MsgDlc, SduPtr);\r
+ }\r
+ }\r
+\r
+}\r
+#endif\r