#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
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
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
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
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
{\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
*(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
}\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
\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
#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
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
{\r
uint8 MsgNr;\r
uint32 ErrCounter;\r
+ imask_t state;\r
\r
#if(CAN_DEV_ERROR_DETECT == STD_ON)\r
if(Config == NULL)\r
}\r
#endif \r
\r
+ Irq_Save(state);\r
+\r
ErrCounter = CAN_TIMEOUT_DURATION;\r
\r
//for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)\r
\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
{\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
\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
}\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
}\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
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
}\r
#endif\r
// Check WakeUpPending\r
- if(CanBase[Controller]->SR & 0x00000200)\r
+ if(CanRegs[Controller]->SR & 0x00000200)\r
{\r
return E_OK;\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 ArbRegValue;\r
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
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
\r
IfRegId ^= 1;\r
\r
+ Irq_Restore(state);\r
return CAN_OK;\r
}\r
\r