]> rtime.felk.cvut.cz Git - arc.git/commitdiff
Work on CAN driver for TMS570
authormaek <devnull@localhost>
Tue, 2 Nov 2010 07:26:01 +0000 (08:26 +0100)
committermaek <devnull@localhost>
Tue, 2 Nov 2010 07:26:01 +0000 (08:26 +0100)
arch/arm/arm_cr4/drivers/Can.c [new file with mode: 0644]
arch/arm/arm_cr4/drivers/Can_cortexr4.h [new file with mode: 0644]
arch/arm/arm_cr4/scripts/linkscript_gcc.ldf
include/Can.h

diff --git a/arch/arm/arm_cr4/drivers/Can.c b/arch/arm/arm_cr4/drivers/Can.c
new file mode 100644 (file)
index 0000000..6695a6f
--- /dev/null
@@ -0,0 +1,1318 @@
+\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
diff --git a/arch/arm/arm_cr4/drivers/Can_cortexr4.h b/arch/arm/arm_cr4/drivers/Can_cortexr4.h
new file mode 100644 (file)
index 0000000..a8cb7ac
--- /dev/null
@@ -0,0 +1,293 @@
+\r
+#ifndef CAN_H\r
+#define CAN_H\r
+\r
+/*\r
+// Include Files\r
+#include "ComStack_Types.h"\r
+#include "Can_Cfg.h"\r
+*/\r
+\r
+/*\r
+// Std_Types Version Check\r
+#if (STD_TYPES_AR_MAJOR_VERSION != 2)\r
+    #error Can.h: STD_TYPES_AR_MAJOR_VERSION of Std_Types.h is incompatible.\r
+#endif\r
+#if (STD_TYPES_AR_MINOR_VERSION != 1)\r
+    #error Can.h: STD_TYPES_AR_MINOR_VERSION of Std_Types.h is incompatible.\r
+#endif\r
+*/\r
+\r
+/*\r
+// CAN Published Information\r
+\r
+#define CAN_VENDOR_ID        44\r
+#define CAN_MODULE_ID       111\r
+#define CAN_AR_MAJOR_VERSION  3\r
+#define CAN_AR_MINOR_VERSION  1\r
+#define CAN_AR_PATCH_VERSION  0\r
+#define CAN_SW_MAJOR_VERSION  1\r
+#define CAN_SW_MINOR_VERSION  0\r
+#define CAN_SW_PATCH_VERSION  0\r
+\r
+\r
+\r
+// CAN Development Error Codes\r
+\r
+#define CAN_E_PARAM_POINTER              0x01\r
+#define CAN_E_PARAM_HANDLE               0x02\r
+#define CAN_E_PARAM_DLC                  0x03\r
+#define CAN_E_PARAM_CONTROLLER           0x04\r
+#define CAN_E_UNINIT                     0x05\r
+#define CAN_E_TRANSITION                 0x06\r
+*/\r
+\r
+\r
+/*\r
+// CAN register definition\r
+\r
+typedef volatile struct\r
+{\r
+    uint32   CTL;\r
+    uint32   SR;\r
+    unsigned     : 16;\r
+    unsigned REC :  8;\r
+    unsigned TEC :  8;\r
+    uint32   BTR;\r
+    uint32   IR;\r
+    uint32   TR;\r
+    unsigned : 32;\r
+    uint32   PEC;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+       unsigned : 32;\r
+       unsigned : 32;\r
+    uint32   ABOT;\r
+    uint32   TRX;\r
+    uint32   TRx[4];\r
+    uint32   NDX;\r
+    uint32   NDx[4];\r
+    uint32   IPX;\r
+    uint32   IPx[4];\r
+    uint32   MVX;\r
+    uint32   MVx[4];\r
+    unsigned : 32;\r
+    uint32   IPMx[4];\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+       unsigned : 32;\r
+    struct\r
+    {\r
+        uint32   COM;\r
+        uint32   MASK;\r
+        uint32   ARB;\r
+        uint32   MC;\r
+        uint8    DATx[8];\r
+        unsigned : 32;\r
+        unsigned : 32;\r
+    } IFx[3];\r
+    uint32   IF3UEy[4];\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+    unsigned : 32;\r
+       unsigned : 32;\r
+       unsigned : 32;\r
+       unsigned : 32;\r
+    uint32   IOTX;\r
+    uint32   IORX;\r
+} Can_RegisterType;\r
+\r
+#ifdef CAN_BASE_ADDRESS_0\r
+#define Can0_Base ((Can_RegisterType *)CAN_BASE_ADDRESS_0)\r
+#endif\r
+#ifdef CAN_BASE_ADDRESS_1\r
+#define Can1_Base ((Can_RegisterType *)CAN_BASE_ADDRESS_1)\r
+#endif\r
+*/\r
+\r
+/*----------------------------------------------------------------------------*/\r
+/* CAN Type Definitions                                                       */\r
+/*                                                                            */\r
+/* CanTimeRegister: - Bit0...Bit5: BRP (Baud Rate Prescaler)                  */\r
+/*                  - Bit6...Bit7: SJW (Synchronization Jump Width)           */\r
+/*                  - Bit8...Bit11: TSeg1                                     */\r
+/*                  - Bit12...Bit14: TSeg2                                    */\r
+/*                  - Bit16...Bit19: BRPE (Baud Rate Prescaler Extension)     */\r
+/*                                                                            */\r
+/*----------------------------------------------------------------------------*/\r
+//typedef uint32 Can_IdType;\r
+\r
+typedef enum\r
+{\r
+    CAN_RECEIVE  = 0x00000000,\r
+    CAN_TRANSMIT = 0x20000000\r
+} Can_ObjectType;\r
+\r
+typedef enum\r
+{\r
+    BASIC,\r
+       FULL\r
+} Can_HandleType;\r
+\r
+typedef enum\r
+{\r
+       CAN_EXTENDED,\r
+    CAN_MIXED,\r
+    CAN_STANDARD\r
+} Can_IdModeType;\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    Can_HandleType  HandleType;\r
+    Can_IdModeType  IdType;\r
+    Can_IdType      IdValue;\r
+       uint8           ObjectId;\r
+    Can_ObjectType  Direction;\r
+    uint8           Controller;\r
+    uint32          FilterMaskIndex;\r
+} Can_MessageObjectType;\r
+\r
+typedef struct \r
+{\r
+    uint32 CanTimeRegister;\r
+       uint32 *FilterMaskPtr;\r
+       uint8 CanControllerId;\r
+} Can_ControllerConfigType;\r
+\r
+typedef struct\r
+{\r
+    Can_ControllerConfigType *ControllerConfigPtr;\r
+    Can_MessageObjectType       *MessageBoxPtr;\r
+} Can_ConfigType;\r
+\r
+/** COPIED FROM ARC **/\r
+typedef enum {\r
+  CAN_ARC_HANDLE_TYPE_BASIC,\r
+  CAN_ARC_HANDLE_TYPE_FULL\r
+} Can_Arc_HohType;\r
+\r
+typedef enum {\r
+  CAN_HTH_A_1 = 0,\r
+  CAN_HTH_C_1,\r
+  NUM_OF_HTHS\r
+} Can_Arc_HTHType;\r
+\r
+typedef enum {\r
+  CAN_HRH_A_1 = 0,\r
+  CAN_HRH_C_1,\r
+  NUM_OF_HRHS\r
+} Can_Arc_HRHType;\r
+\r
+/** Container for callback configuration. */\r
+typedef struct {\r
+  void (*CancelTxConfirmation)( const Can_PduType *);               /**< Not supported. */\r
+  void (*RxIndication)( uint8 ,Can_IdType ,uint8 , const uint8 * ); /**< Called on successful reception of a PDU. */\r
+  void (*ControllerBusOff)(uint8);                                  /**< Called on BusOff. */\r
+  void (*TxConfirmation)(PduIdType);                                /**< Called on successful transmission of a PDU. */\r
+  void (*ControllerWakeup)(uint8);                                  /**< Not supported. */\r
+  void (*Arc_Error)(uint8,Can_Arc_ErrorType);                       /**< Called on HW error. */\r
+} Can_CallbackType;\r
+\r
+/** Container for controller parameters. */\r
+typedef struct {\r
+  const Can_ControllerConfigType *CanController;\r
+\r
+  // Callbacks( Extension )\r
+  const Can_CallbackType *CanCallbacks;\r
+} Can_ConfigSetType;\r
+\r
+/** Available HW controllers. */\r
+typedef enum {\r
+  CAN_CTRL_A = 0,\r
+  CAN_CTRL_B,\r
+  CAN_CTRL_C,\r
+  CAN_CTRL_D,\r
+  CAN_CTRL_E,\r
+  CAN_CTRL_F,\r
+  CAN_CONTROLLER_CNT\r
+}CanControllerIdType;\r
+\r
+/** Top level container for parameters. */\r
+extern const Can_ConfigType CanConfigData;\r
+/** For direct access to controller list */\r
+extern const Can_ControllerConfigType CanControllerConfigData[];\r
+/** Container for controller parameters. */\r
+extern const Can_ConfigSetType Can_ConfigSet;\r
+\r
+/** END COPIED FROM ARC **/\r
+\r
+\r
+/*\r
+// CAN Driver Function Prototypes\r
+\r
+extern void Can_Init(const Can_ConfigType *Config);\r
+extern void Can_InitController(uint8 Controller, const Can_ControllerConfigType *Config);\r
+extern Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType Transition);\r
+extern void Can_DisableControllerInterrupts(uint8 Controller);\r
+extern void Can_EnableControllerInterrupts(uint8 Controller);\r
+extern Std_ReturnType Can_Cbk_CheckWakeup(uint8 Controller);\r
+extern Can_ReturnType Can_Write(uint8 Hth, const Can_PduType *PduInfo);\r
+\r
+#if(CAN_VERSION_INFO_API == STD_ON)\r
+extern void Can_GetVersionInfo(Std_VersionInfoType *versioninfo);\r
+#endif\r
+\r
+extern void Can_MainFunction_Write();\r
+extern void Can_MainFunction_Read();\r
+extern void Can_MainFunction_BusOff();\r
+extern void Can_MainFunction_Wakeup();\r
+\r
+extern void Can1_InterruptHandler_0();\r
+extern void Can2_InterruptHandler_0();\r
+*/\r
+#endif /* CAN_H */\r
+\r
+/*----------------------------------------------------------------------------*/\r
index 97973478b953768d74aee02306392f66d9e96eae..874accbf39bf36dc3047ffd5e1858ef351f2c6d8 100644 (file)
@@ -62,6 +62,10 @@ SECTIONS
                *(.rodata .rodata.* .gnu.linkonce.r.*)\r
                _sidata = ALIGN(.,4);\r
        } > flash\r
+       \r
+       .cio ALIGN(0x10) : {\r
+       \r
+       } > ram\r
 \r
        .data : AT(ALIGN(LOADADDR(.rodata)+SIZEOF(.rodata),4)) {\r
                _sdata = ALIGN(.,4); \r
index f8cf9d5a66c59660f152430c5500cb2ad4541e1a..10e7171eecc4ee8dafd7945991fa55db0c7774d1 100644 (file)
@@ -50,6 +50,7 @@
 #include "Mcu.h"\r
 #endif\r
 \r
+\r
 typedef struct {\r
        uint32 txSuccessCnt;\r
        uint32 rxSuccessCnt;\r