]> rtime.felk.cvut.cz Git - arc.git/blobdiff - arch/arm/arm_cr4/drivers/Can.c
Added an example of CAN communication for the TMS570LS31x HDK
[arc.git] / arch / arm / arm_cr4 / drivers / Can.c
index 3ab545642cc5edd0bab5bd02be88ff074c8ead51..3f17ac90be9aefc49e5a4a7490308361774704d3 100644 (file)
@@ -22,8 +22,9 @@
 #include "Det.h"\r
 #include "CanIf_Cbk.h"\r
 #include "Os.h"\r
-#include "irq.h"\r
+#include "isr.h"\r
 #include "Mcu.h"\r
+#include "arc.h"\r
 \r
 #define DCAN1_MAX_MESSAGEBOXES 64\r
 #define DCAN2_MAX_MESSAGEBOXES 64\r
 #define CAN_TIMEOUT_DURATION   0xFFFFFFFF\r
 #define CAN_INSTANCE           0\r
 \r
+#define DCAN_IRQ_MASK          0x00000006\r
+\r
 \r
 #if !defined(USE_DEM)\r
+// If compiled without the DEM, calls to DEM are simply ignored.\r
 #define Dem_ReportErrorStatus(...)\r
 #endif\r
 \r
+static sint8 IfRegId = 0;\r
+\r
+/* Macro for waiting until busy flag is 0 */\r
+#define DCAN_WAIT_UNTIL_NOT_BUSY(ControllerId, IfRegId) \\r
+    { \\r
+               uint32 ErrCounter = CAN_TIMEOUT_DURATION; \\r
+               while(CanRegs[ControllerId]->IFx[IfRegId].COM & 0x00008000) { \\r
+                       ErrCounter--; \\r
+                       if(ErrCounter == 0) { \\r
+                               Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED); \\r
+                               ErrCounter = CAN_TIMEOUT_DURATION; \\r
+                               return CAN_NOT_OK; \\r
+                       } \\r
+               } \\r
+    }\r
+\r
+/* Macro for waiting until busy flag is 0 */\r
+#define DCAN_WAIT_UNTIL_NOT_BUSY_NO_RV(ControllerId, IfRegId) \\r
+       { \\r
+               uint32 ErrCounter = CAN_TIMEOUT_DURATION; \\r
+               while(CanRegs[ControllerId]->IFx[IfRegId].COM & 0x00008000) { \\r
+                       ErrCounter--; \\r
+                       if(ErrCounter == 0) { \\r
+                               Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED); \\r
+                               ErrCounter = CAN_TIMEOUT_DURATION; \\r
+                               return; \\r
+                       } \\r
+               } \\r
+       }\r
+\r
 \r
-/*----------------------------------------------------------------------------*/\r
-/* Variable Definition                                                        */\r
 \r
 // Array for easy access to DCAN register definitions.\r
-static Can_RegisterType* CanBase[]=\r
+static Can_RegisterType* CanRegs[]=\r
 {\r
        DCAN1_Base,\r
        DCAN2_Base,\r
@@ -74,7 +106,6 @@ static Can_StateType            ModuleState = CAN_UNINIT;
 static CanIf_ControllerModeType ControllerMode[CAN_ARC_CTRL_CONFIG_CNT];\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
@@ -173,102 +204,146 @@ static inline const Can_HardwareObjectType * Can_FindRxHoh(CanControllerIdType C
        return 0;\r
 }\r
 \r
+#define DCAN_MC_NEWDAT 15\r
+#define DCAN_MC_EOB            7\r
+\r
+uint32 usedRxBoxes[64] = {0};\r
+uint32 usedTxBoxes[64] = {0};\r
+\r
+static inline Can_ReturnType handleRxMsgObject(uint8 MsgNr, const Can_HardwareObjectType *hoh, CanControllerIdType controller) {\r
+       uint32  MsgId;\r
+       uint8   MsgDlc;\r
+       uint8   DataByteIndex;\r
+       uint8  *SduPtr;\r
+\r
+       /* Wait until Busy Flag is 0 */\r
+       DCAN_WAIT_UNTIL_NOT_BUSY(controller, IfRegId);\r
+\r
+       // Read message control\r
+       uint32 mc = CanRegs[controller]->IFx[IfRegId].MC;\r
+       uint32 arb = CanRegs[controller]->IFx[IfRegId].ARB;\r
+\r
+       // Is there a new message waiting?\r
+       if (!(mc & (1 << DCAN_MC_NEWDAT))) {\r
+               return CAN_NOT_OK; // Nothing more to be done.\r
+       }\r
+\r
+       // For debug\r
+       if (MsgNr == 0) {\r
+               usedRxBoxes[MsgNr]++;\r
+       } else {\r
+               usedRxBoxes[MsgNr]++;\r
+       }\r
+\r
+\r
+       /* Extended Id */\r
+       if(arb & 0x40000000) {\r
+               /* Bring Id to standardized format (MSB marks extended Id) */\r
+               MsgId = (arb & 0x1FFFFFFF) | 0x80000000;\r
+\r
+       } else { /* Standard Id */\r
+               /* Bring Id to standardized format (MSB marks extended Id) */\r
+               MsgId = (arb & 0x1FFC0000) >> 18;\r
+       }\r
+\r
+       /* DLC (Max 8) */\r
+       MsgDlc = mc & 0x000F;\r
+       if(MsgDlc > 8) {\r
+               MsgDlc = 8;\r
+       }\r
+\r
+       /* Let SduPtr point to Shadow Buffer */\r
+       SduPtr = RxShadowBuf[controller];\r
+\r
+       /* Copy Message Data to Shadow Buffer */\r
+       for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
+       {\r
+               SduPtr[DataByteIndex] = CanRegs[controller]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
+       }\r
+\r
+       /* Indicate successful Reception */\r
+       CanIf_RxIndication(hoh->CanObjectId, MsgId, MsgDlc, SduPtr);\r
+\r
+       // Is this the last message object of the FIFO?\r
+       if (mc & (1 << DCAN_MC_EOB)) {\r
+               return CAN_NOT_OK;\r
+       }\r
+\r
+       return CAN_OK;\r
+}\r
+\r
 \r
 void Can_InterruptHandler(CanControllerIdType controller)\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
+    uint32 ir = CanRegs[controller]->IR;\r
 \r
-    ErrCounter = CAN_TIMEOUT_DURATION;\r
 \r
-    uint32 ir = CanBase[controller]->IR;\r
+    if(ir == 0x8000) { // This is an error interrupt\r
 \r
-    if(ir == 0x8000)\r
-    {\r
-       uint32 sr = CanBase[controller]->SR;\r
-        /* WakeUp Pending */\r
-        if(sr & 0x00000200) {\r
+       uint32 sr = CanRegs[controller]->SR;\r
+\r
+        if(sr & 0x00000200) { /* WakeUp Pending */\r
             /* Set Init Bit, so that Controller is in Stop state */\r
-            CanBase[controller]->CTL |= 0x1;\r
+            CanRegs[controller]->CTL |= 0x1;\r
            // EcuM_CheckWakeUp(ControllerConfig[0].WakeupSrc);\r
 \r
         }\r
-        /* Bus Off */\r
-        if(sr & 0x00000080) {\r
+\r
+        if(sr & 0x00000080) { /* Bus Off */\r
                Can_SetControllerMode(controller, CAN_T_STOP); // CANIF272\r
             //CanIf_ControllerBusOff(0); // Not implemented in Arctic Core\r
 \r
         }\r
-    }\r
-    else\r
-    {\r
+\r
+    } else if (ir > 0 && ir < 0x8000){ // This interrupt is from a message object.\r
         MsgNr = ir;\r
 \r
-        /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/\r
-        CanBase[controller]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;\r
+        /* Read Arbitration and control */\r
+               CanRegs[controller]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;\r
 \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
-                ErrCounter = CAN_TIMEOUT_DURATION;\r
-                return;\r
-            }\r
-        }\r
+               /* Wait until Busy Flag is 0 */\r
+               DCAN_WAIT_UNTIL_NOT_BUSY_NO_RV(controller, IfRegId);\r
 \r
         /* Transmit Object */\r
-        if(CanBase[controller]->IFx[IfRegId].ARB & 0x20000000)\r
+        if(CanRegs[controller]->IFx[IfRegId].ARB & 0x20000000)\r
         {\r
+               // For debug\r
+               if (MsgNr == 0) {\r
+                       usedTxBoxes[MsgNr]++;\r
+               } else {\r
+                       usedTxBoxes[MsgNr]++;\r
+               }\r
+\r
             /* Reset TxRqst-Array Element */\r
                ControllerConfig[controller].TxPtr[MsgNr - 1] = 0;\r
             /* A Message was successfully transmitted */\r
             CanIf_TxConfirmation(ControllerConfig[controller].PduPtr[MsgNr - 1].swPduHandle);\r
-        }\r
-        /* Receive Object */\r
-        else\r
-        {\r
-            /* Extended Id */\r
-            if(CanBase[controller]->IFx[IfRegId].ARB & 0x40000000)\r
-            {\r
-                /* Bring Id to standardized format (MSB marks extended Id) */\r
-                MsgId = (CanBase[controller]->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[controller]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;\r
-            }\r
-            /* DLC (Max 8) */\r
-            MsgDlc = CanBase[controller]->IFx[IfRegId].MC & 0x000F;\r
-            if(MsgDlc > 8)\r
-            {\r
-                MsgDlc = 8;\r
-            }\r
-            /* Let SduPtr point to Shadow Buffer */\r
-            SduPtr = RxShadowBuf[controller];\r
 \r
-            /* Copy Message Data to Shadow Buffer */\r
-            for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
-            {\r
-               SduPtr[DataByteIndex] = CanBase[controller]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
-            }\r
-            /* Indicate successful Reception */\r
-            const Can_HardwareObjectType *hoh = Can_FindRxHoh(controller, MsgNr);\r
-            CanIf_RxIndication(hoh->CanObjectId, MsgId, MsgDlc, SduPtr);\r
+        /* Receive Object */\r
+        } else {\r
+\r
+               // Handle all of the message objects in this FIFO buffer.\r
+               const Can_HardwareObjectType *hoh = Can_FindRxHoh(controller, MsgNr);\r
+               for(; MsgNr < ControllerConfig[controller].MaxBoxes; MsgNr++) {\r
+                       if (!(hoh->Can_Arc_MbMask & (1 << (MsgNr - 1)))) {\r
+                               continue;\r
+                       }\r
+\r
+                       /* Read setup hardware to read arbitration, control and data Bits of the message object.\r
+                        * Clear IntPnd and Tx */\r
+                       if (MsgNr != ir) { // Don't do this the first time.\r
+                               CanRegs[controller]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;\r
+                       }\r
+\r
+                       if (handleRxMsgObject(MsgNr, hoh, controller) == CAN_NOT_OK) {\r
+                               break; // We have parsed the last object of this FIFO.\r
+                       }\r
+                       }\r
 \r
         }\r
     }\r
-    //Can_EnableControllerInterrupts(0);\r
 }\r
 \r
 void Can1_InterruptHandler() {\r
@@ -302,6 +377,7 @@ void Can_Init(const Can_ConfigType *Config)
     uint8                     MsgNr;\r
     uint32                    ErrCounter;\r
     uint32                    Eob;\r
+    imask_t state;\r
 \r
 /* DET Error Check */\r
 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
@@ -316,7 +392,9 @@ void Can_Init(const Can_ConfigType *Config)
         return;\r
     }\r
 #endif \r
-     \r
+\r
+    Irq_Save(state);\r
+\r
     // TODO This should be used instead of other variables in the Can_Lcfg file.\r
     CurConfig        = Config;\r
 \r
@@ -324,18 +402,19 @@ void Can_Init(const Can_ConfigType *Config)
     {\r
         ErrCounter = CAN_TIMEOUT_DURATION;\r
 \r
-        /* Init, IE, AutomaticRetransmission, ConfChangeEnable, ABO Off,Parity On, SIE and EIE depending on ControllerConfig */\r
+        /* Init, IE, AutomaticRetransmission, ConfChangeEnable, ABO Off,Parity On, SIE and EIE depending on ControllerConfig, loopback */\r
 #if(CAN_WAKEUP_SUPPORT == STD_ON)\r
-        CanBase[Controller]->CTL = 0x02001643;// | (CanControllerConfigData[Controller].CanWakeupProcessing >> 8) | (CanControllerConfigData[Controller].CanBusOffProcessing >> 7);\r
+        CanRegs[Controller]->CTL = 0x02001641 | DCAN_IRQ_MASK | (CanControllerConfigData[Controller].Can_Arc_Loopback << 7);// | (CanControllerConfigData[Controller].CanWakeupProcessing >> 8) | (CanControllerConfigData[Controller].CanBusOffProcessing >> 7);\r
 #else\r
-        CanBase[Controller]->CTL = 0x00001643;// | (CanControllerConfigData[Controller].CanWakeupProcessing >> 8) | (CanControllerConfigData[Controller].CanBusOffProcessing >> 7);\r
+        CanRegs[Controller]->CTL = 0x00001641 | DCAN_IRQ_MASK | (CanControllerConfigData[Controller].Can_Arc_Loopback << 7);// | (CanControllerConfigData[Controller].CanWakeupProcessing >> 8) | (CanControllerConfigData[Controller].CanBusOffProcessing >> 7);\r
 #endif        \r
         /* LEC 7, TxOk, RxOk, PER */\r
-        CanBase[Controller]->SR  = 0x0000011F;\r
+        CanRegs[Controller]->SR  = 0x0000011F;\r
 \r
         /* Test Mode only for Development time: Silent Loopback */\r
-        //CanBase[Controller]->CTL |= 0x00000080;\r
-        //CanBase[Controller]->TR   = 0x00000018;\r
+        if (CanControllerConfigData[Controller].Can_Arc_Loopback) {\r
+               CanRegs[Controller]->TR   = 0x00000018;\r
+        }\r
             \r
 \r
         // Basic message object initialization\r
@@ -344,23 +423,13 @@ void Can_Init(const Can_ConfigType *Config)
             *(ControllerConfig[Controller].CancelPtr + MsgNr) = 0;\r
             *(ControllerConfig[Controller].TxPtr     + MsgNr) = 0;\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
+            DCAN_WAIT_UNTIL_NOT_BUSY_NO_RV(Controller, IfRegId);\r
 \r
             // Initialize all message objects for this controller to invalid state.\r
             /* Valid = 0 */\r
-                       CanBase[Controller]->IFx[IfRegId].ARB = 0x00000000;\r
+                       CanRegs[Controller]->IFx[IfRegId].ARB = 0x00000000;\r
                        /* Start writing Arbitration Bits */\r
-                       CanBase[Controller]->IFx[IfRegId].COM = 0x00A80000 | (MsgNr + 1);\r
+                       CanRegs[Controller]->IFx[IfRegId].COM = 0x00A80000 | (MsgNr + 1);\r
 \r
                        /* Use IFx[0] and IFx[1] alternating */\r
                        IfRegId ^= 1;\r
@@ -399,31 +468,37 @@ void Can_Init(const Can_ConfigType *Config)
                                }\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 | CanControllerConfigData[Controller].CanRxProcessing | (CanControllerConfigData[Controller].CanTxProcessing << 1) | Eob & ~(hoh->CanObjectType >> 17);\r
+                               CanRegs[Controller]->IFx[IfRegId].MC =    0x00000008 // DLC = 8\r
+                                                                                                               | 0x00001000 // umask = ON\r
+                                                                                                               | CanControllerConfigData[Controller].CanRxProcessing // Rx interrupt enabled\r
+                                                                                                               | (CanControllerConfigData[Controller].CanTxProcessing << 1) // Tx confirmation interrupt enabled\r
+                                                                                                               | (Eob & ~(hoh->CanObjectType >> 22)); // Eob, only for Rx.\r
+\r
+                               //CanRegs[Controller]->IFx[IfRegId].MC = 0x00001008 | CanControllerConfigData[Controller].CanRxProcessing | (CanControllerConfigData[Controller].CanTxProcessing) | Eob & ~(hoh->CanObjectType >> 17);\r
 \r
                                if(hoh->CanIdType == CAN_ID_TYPE_STANDARD)      /* Standard Identifiers */\r
                                {\r
                                        /* Only Standard-Ids are accepted, Set Mask */\r
-                                       CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF);\r
+                                       CanRegs[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF);\r
                                        /* Message valid, Id, Direction */\r
-                                       CanBase[Controller]->IFx[IfRegId].ARB  = 0x80000000 | ((hoh->CanIdValue & 0x7FF) << 18) | hoh->CanObjectType;\r
+                                       CanRegs[Controller]->IFx[IfRegId].ARB  = 0x80000000 | ((hoh->CanIdValue & 0x7FF) << 18) | hoh->CanObjectType;\r
                                }\r
                                else if(hoh->CanIdType == CAN_ID_TYPE_EXTENDED) /* Extended Identifiers */\r
                                {\r
                                        /* Only Extended-Ids are accepted, Set Mask */\r
-                                       CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF);\r
+                                       CanRegs[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF);\r
                                        /* Message valid, Id, Direction */\r
-                                       CanBase[Controller]->IFx[IfRegId].ARB  = 0xC0000000 | (hoh->CanIdValue & 0x1FFFFFFF) | hoh->CanObjectType;\r
+                                       CanRegs[Controller]->IFx[IfRegId].ARB  = 0xC0000000 | (hoh->CanIdValue & 0x1FFFFFFF) | hoh->CanObjectType;\r
                                }\r
                                else /* Mixed Identifiers */\r
                                {\r
                                        /* Standard- and Mixed-Ids are accepted, Set Mask */\r
-                                       CanBase[Controller]->IFx[IfRegId].MASK = 0x00000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFF);\r
+                                       CanRegs[Controller]->IFx[IfRegId].MASK = 0x00000000 | ((*(hoh->CanFilterMaskRef)) & 0x1FFFFFF);\r
                                        /* Message valid, Id, Direction */\r
-                                       CanBase[Controller]->IFx[IfRegId].ARB  = 0xC0000000 | (hoh->CanIdValue & 0x1FFFFFF) | hoh->CanObjectType;\r
+                                       CanRegs[Controller]->IFx[IfRegId].ARB  = 0xC0000000 | (hoh->CanIdValue & 0x1FFFFFF) | hoh->CanObjectType;\r
                                }\r
                                /* Start writing Mask, Arb, Control and Id bits */\r
-                               CanBase[Controller]->IFx[IfRegId].COM  = 0x00F80000 | mbNr;\r
+                               CanRegs[Controller]->IFx[IfRegId].COM  = 0x00F80000 | mbNr;\r
 \r
                                /* Use IFx[0] and IFx[1] alternating */\r
                                IfRegId ^= 1;\r
@@ -433,10 +508,10 @@ void Can_Init(const Can_ConfigType *Config)
 \r
 \r
         /* Set Bit Timing Register */\r
-        CanBase[Controller]->BTR = Can_CalculateBTR(Controller);\r
+        CanRegs[Controller]->BTR = Can_CalculateBTR(Controller);\r
 \r
         /* Reset CCE Bit */\r
-        CanBase[Controller]->CTL &= ~0x00000040;\r
+        CanRegs[Controller]->CTL &= ~0x00000040;\r
 \r
 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
         /* Switch Controller State to CANIF_CS_STOPPED */\r
@@ -444,27 +519,17 @@ void Can_Init(const Can_ConfigType *Config)
 #endif\r
 \r
         // Install interrupt handlers\r
-               TaskType tid;\r
                if (CanControllerConfigData[Controller].CanControllerId == DCAN1) {\r
-                       tid = Os_Arc_CreateIsr(Can1_InterruptHandler, 2 ,"DCAN1Level0");\r
-                       Irq_AttachIsr2(tid, NULL, 16);\r
-\r
-                       tid = Os_Arc_CreateIsr(Can1_InterruptHandler, 2, "DCAN1Level1");\r
-                       Irq_AttachIsr2(tid, NULL, 29);\r
+                       ISR_INSTALL_ISR2("DCAN1Level0",Can1_InterruptHandler,CAN1_LEVEL_0,2,0);\r
+                       ISR_INSTALL_ISR2("DCAN1Level1",Can1_InterruptHandler,CAN1_LEVEL_1,2,0);\r
 \r
                } else if (CanControllerConfigData[Controller].CanControllerId == DCAN2) {\r
-                       tid = Os_Arc_CreateIsr(Can2_InterruptHandler, 2 ,"DCAN2Level0");\r
-                       Irq_AttachIsr2(tid, NULL, 35);\r
-\r
-                       tid = Os_Arc_CreateIsr(Can2_InterruptHandler, 2, "DCAN2Level1");\r
-                       Irq_AttachIsr2(tid, NULL, 42);\r
+                       ISR_INSTALL_ISR2("DCAN2Level0",Can2_InterruptHandler,CAN2_LEVEL_0,2,0);\r
+                       ISR_INSTALL_ISR2("DCAN2Level1",Can2_InterruptHandler,CAN2_LEVEL_1,2,0);\r
 \r
                } else if (CanControllerConfigData[Controller].CanControllerId == DCAN3) {\r
-                       tid = Os_Arc_CreateIsr(Can3_InterruptHandler, 2 ,"DCAN3Level0");\r
-                       Irq_AttachIsr2(tid, NULL, 45);\r
-\r
-                       tid = Os_Arc_CreateIsr(Can3_InterruptHandler, 2, "DCAN3Level1");\r
-                       Irq_AttachIsr2(tid, NULL, 55);\r
+                       ISR_INSTALL_ISR2("DCAN3Level0",Can3_InterruptHandler,CAN3_LEVEL_0,2,0);\r
+                       ISR_INSTALL_ISR2("DCAN3Level1",Can3_InterruptHandler,CAN3_LEVEL_1,2,0);\r
 \r
                }\r
 \r
@@ -474,8 +539,15 @@ void Can_Init(const Can_ConfigType *Config)
     ModuleState = CAN_READY;\r
 #endif\r
 \r
+    Irq_Restore(state);\r
 \r
+}\r
 \r
+// Unitialize the module\r
+void Can_DeInit()\r
+{\r
+\r
+  return;\r
 }\r
 \r
 \r
@@ -484,6 +556,7 @@ void Can_InitController(uint8 Controller, const Can_ControllerConfigType* Config
 {\r
     uint8   MsgNr;\r
     uint32  ErrCounter;\r
+    imask_t state;\r
 \r
 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
     if(Config == NULL)\r
@@ -508,6 +581,8 @@ void Can_InitController(uint8 Controller, const Can_ControllerConfigType* Config
     }\r
 #endif \r
 \r
+    Irq_Save(state);\r
+\r
     ErrCounter = CAN_TIMEOUT_DURATION;\r
     \r
     //for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)\r
@@ -519,65 +594,39 @@ void Can_InitController(uint8 Controller, const Can_ControllerConfigType* Config
 \r
        // For every message object in this hoh\r
        for(; mbMask != 0; mbMask >>= 1) {\r
+               MsgNr++;\r
                if (!(mbMask & 1)) {\r
                        // This message object is not part of this hoh.\r
                        continue;\r
                }\r
-               MsgNr++;\r
                nProcessedMb++;\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);\r
+               DCAN_WAIT_UNTIL_NOT_BUSY_NO_RV(Controller, IfRegId);\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
+               /* Read actual MaskRegister value of MessageObject */\r
+        CanRegs[Controller]->IFx[IfRegId].COM = 0x004C0000 | (MsgNr);\r
+\r
+        DCAN_WAIT_UNTIL_NOT_BUSY_NO_RV(Controller, IfRegId);\r
+\r
+        CanRegs[Controller]->IFx[IfRegId].MASK &= 0xD0000000;\r
         /* Set new Mask */\r
-        CanBase[Controller]->IFx[IfRegId].MASK |= (*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF;\r
+        CanRegs[Controller]->IFx[IfRegId].MASK |= (*(hoh->CanFilterMaskRef)) & 0x1FFFFFFF;\r
         /* Write new Mask to MaskRegister */\r
-        CanBase[Controller]->IFx[IfRegId].COM   = 0x00C80000 | (MsgNr);\r
+        CanRegs[Controller]->IFx[IfRegId].COM   = 0x00C80000 | (MsgNr);\r
 \r
         IfRegId ^= 1;\r
     }\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
+       DCAN_WAIT_UNTIL_NOT_BUSY_NO_RV(Controller, IfRegId);\r
+\r
     /* Set CCE Bit to allow access to BitTiming Register (Init already set, in mode "stopped") */\r
-    CanBase[Controller]->CTL |= 0x00000040;\r
+    CanRegs[Controller]->CTL |= 0x00000040;\r
     /* Set Bit Timing Register */\r
-    CanBase[Controller]->BTR = Can_CalculateBTR(Controller);\r
+    CanRegs[Controller]->BTR = Can_CalculateBTR(Controller);\r
     /* Clear CCE Bit */\r
-    CanBase[Controller]->CTL &= ~0x00000040;\r
+    CanRegs[Controller]->CTL &= ~0x00000040;\r
 \r
+    Irq_Restore(state);\r
 }\r
 \r
 \r
@@ -612,9 +661,9 @@ Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType T
     {\r
     case CAN_T_START:\r
         /* Clear Init Bit */\r
-        CanBase[Controller]->CTL  &= ~0x00000001;\r
+        CanRegs[Controller]->CTL  &= ~0x00000001;\r
         /* Clear Status Register */\r
-        CanBase[Controller]->SR    = 0x0000011F;\r
+        CanRegs[Controller]->SR    = 0x0000011F;\r
 \r
         ControllerMode[Controller] = CANIF_CS_STARTED;\r
         Can_EnableControllerInterrupts(Controller);\r
@@ -622,23 +671,23 @@ Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType T
 \r
     case CAN_T_STOP:\r
         /* Set Init Bit */\r
-        CanBase[Controller]->CTL  |=  0x00000001;\r
+        CanRegs[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
+        CanRegs[Controller]->CTL |=  0x01000000;\r
         /* Save actual Register status */\r
-        RegBuf = CanBase[Controller]->CTL;\r
+        RegBuf = CanRegs[Controller]->CTL;\r
         /* Disable Status Interrupts and WUBA */\r
-        CanBase[Controller]->CTL &= ~0x02000004;\r
+        CanRegs[Controller]->CTL &= ~0x02000004;\r
         /* Wait until Local Power Down Mode acknowledged */\r
-        while(!(CanBase[Controller]->SR & 0x00000400))\r
+        while(!(CanRegs[Controller]->SR & 0x00000400))\r
         {\r
             /* Check if a WakeUp occurs */\r
-            if(CanBase[Controller]->SR & 0x00000200)\r
+            if(CanRegs[Controller]->SR & 0x00000200)\r
             {\r
                 Status = CAN_NOT_OK;\r
                 break;\r
@@ -653,13 +702,13 @@ Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType T
             }\r
         }\r
         /* Reset Control Register */\r
-        CanBase[Controller]->CTL   = RegBuf;\r
+        CanRegs[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
+        CanRegs[Controller]->CTL  &= ~0x01000000;\r
         ControllerMode[Controller] = CANIF_CS_STOPPED;\r
         break;\r
 \r
@@ -691,7 +740,7 @@ void Can_DisableControllerInterrupts(uint8 Controller)
     }\r
 #endif \r
     /* Clear IE */\r
-    CanBase[Controller]->CTL &= ~0x00000002;\r
+    CanRegs[Controller]->CTL &= ~DCAN_IRQ_MASK;\r
     /* Increment Disable Counter */\r
     IntDisableCount[Controller]++;\r
 }\r
@@ -715,7 +764,7 @@ void Can_EnableControllerInterrupts(uint8 Controller)
         if(IntDisableCount[Controller] == 1)\r
         {\r
             /* Set IE */\r
-            CanBase[Controller]->CTL |= 0x00000002;\r
+            CanRegs[Controller]->CTL |= DCAN_IRQ_MASK;\r
         }\r
         IntDisableCount[Controller]--;\r
     }\r
@@ -733,7 +782,7 @@ void Can_Cbk_CheckWakeup(uint8 Controller)
     }\r
 #endif\r
     // Check WakeUpPending\r
-    if(CanBase[Controller]->SR & 0x00000200)\r
+    if(CanRegs[Controller]->SR & 0x00000200)\r
     {\r
         return E_OK;\r
     }\r
@@ -747,7 +796,6 @@ void Can_Cbk_CheckWakeup(uint8 Controller)
 \r
 Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)\r
 {\r
-    uint32                 ErrCounter;\r
     uint8                  ControllerId;\r
     uint8                  MsgNr;\r
     uint32                 ArbRegValue;\r
@@ -756,10 +804,11 @@ Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)
     Can_PduType           *CurPduArrayPtr;\r
     uint8                 *CurCancelRqstPtr;\r
     uint8                 *CurTxRqstPtr;\r
+    imask_t state;\r
 \r
     CurSduPtr       = PduInfo->sdu;\r
-    ErrCounter      = CAN_TIMEOUT_DURATION;\r
     \r
+\r
 /* DET Error Check */\r
 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
     if(PduInfo == NULL || PduInfo->sdu == NULL)\r
@@ -793,61 +842,62 @@ Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)
     uint64 mbMask = hoh->Can_Arc_MbMask;\r
     MsgNr = 0;\r
     for(; mbMask != 0; mbMask >>= 1) {\r
+       MsgNr++;\r
                if (!(mbMask & 1)) {\r
                        continue; // This message object is not part of this hoh.\r
                }\r
-               // Just use the first message object.\r
-               MsgNr++;\r
+               /* Check if TxRqst Bit of MsgObject is set */\r
+               if(CanRegs[ControllerId]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F)))\r
+               {\r
+                       continue;\r
+               }\r
+               break;\r
     }\r
 \r
+       /* Check if TxRqst Bit of MsgObject is set */\r
+       if(CanRegs[ControllerId]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F)))\r
+       {\r
+               return CAN_BUSY;\r
+       }\r
+\r
     CurPduArrayPtr   = ControllerConfig[ControllerId].PduPtr    + (MsgNr - 1);\r
     CurCancelRqstPtr = ControllerConfig[ControllerId].CancelPtr + (MsgNr - 1);\r
     CurTxRqstPtr     = ControllerConfig[ControllerId].TxPtr     + (MsgNr - 1);\r
     \r
     /* Bring Id Value to appropriate format and set ArbRegValue */\r
-    if(PduInfo->id & 0x80000000)\r
-    {\r
+    if( hoh->CanIdType == CAN_ID_TYPE_EXTENDED ) {\r
         /* MsgVal, Ext, Transmit, Extended Id */ \r
-        ArbRegValue = 0xD0000000 | (PduInfo->id & 0x1FFFFFFF);\r
-    }\r
-    else\r
-    {\r
+        ArbRegValue = 0xE0000000 | (PduInfo->id & 0x1FFFFFFF);\r
+    } else {\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
-        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
+    DCAN_WAIT_UNTIL_NOT_BUSY(ControllerId, IfRegId);\r
+\r
+    // We cannot allow an interrupt or other task to play with the COM, MC and ARB registers here.\r
+    Irq_Save(state);\r
+\r
 \r
     /* Set NewDat, TxIE (dep on ControllerConfig), TxRqst, EoB and DLC */\r
-    CanBase[ControllerId]->IFx[IfRegId].MC = 0x00000180 | (0x000F & PduInfo->length) | (CanControllerConfigData[ControllerId].CanTxProcessing << 1);\r
+    CanRegs[ControllerId]->IFx[IfRegId].MC =     0x00000100 // Tx request\r
+                                                                                       | 0x00000080 // Eob should be set to one for tx\r
+                                                                                       | (0x000F & PduInfo->length) // Set DLC\r
+                                                                                       | (CanControllerConfigData[ControllerId].CanTxProcessing << 1); // Tx confirmation interrupt enabled\r
 \r
     /* Set ArbitrationRegister */\r
-    CanBase[ControllerId]->IFx[IfRegId].ARB = ArbRegValue;\r
+    CanRegs[ControllerId]->IFx[IfRegId].ARB = ArbRegValue;\r
+\r
 \r
     /* Set Databytes */\r
     for(DataByteIndex = 0; DataByteIndex < PduInfo->length; DataByteIndex++)\r
     {\r
-        CanBase[ControllerId]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]] = *CurSduPtr++;\r
+        CanRegs[ControllerId]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]] = *CurSduPtr++;\r
     }\r
 \r
     /* Start transmission to MessageRAM */\r
-    CanBase[ControllerId]->IFx[IfRegId].COM = 0x00BF0000 | MsgNr;\r
+    CanRegs[ControllerId]->IFx[IfRegId].COM = 0x00BF0000 | MsgNr;\r
     \r
     /* Save the PduInfo in PduArray, so that messages can be identified later */\r
     *CurPduArrayPtr = *PduInfo;\r
@@ -856,6 +906,7 @@ Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)
     \r
     IfRegId ^= 1;\r
        \r
+    Irq_Restore(state);\r
     return CAN_OK;\r
 }\r
 \r