3 /*----------------------------------------------------------------------------*/
\r
9 #include "core_cr4.h"
\r
10 #if defined(USE_DEM)
\r
15 //#include "EcuM_Cbk.h"
\r
16 #include "CanIf_Cbk.h"
\r
17 //#include "MemMap.h"
\r
23 #if !defined(USE_DEM)
\r
24 #define Dem_ReportErrorStatus(...)
\r
28 /*----------------------------------------------------------------------------*/
\r
29 /* Variable Definition */
\r
31 static Can_RegisterType* CanBase[]=
\r
47 INTERRUPT = 0x00000400,
\r
48 POLLING = 0x00000000
\r
57 uint16 MessageBoxCount;
\r
62 Can_PduType *PduPtr;
\r
65 } Controller_PreConfigType;
\r
68 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
69 /* Module is in uninitialized state */
\r
70 static Can_StateType ModuleState = CAN_UNINIT;
\r
72 static CanIf_ControllerModeType ControllerMode[CAN_CONTROLLER_COUNT];
\r
74 /* Used to switch between IF1 and IF2 of DCAN */
\r
75 static uint8 IfRegId = 0;
\r
77 /* Used to order Data Bytes according to hardware registers in DCAN */
\r
78 static const uint8 ElementIndex[] = {3, 2, 1, 0, 7, 6, 5, 4};
\r
80 /* To save pointer to the configuration set */
\r
81 static const Can_ConfigType *CurConfig;
\r
83 /* To save the PduData of transmission objects */
\r
84 static Can_PduType PduInfoArray_0[MAX_MESSAGEBOXES_0];
\r
85 /* To save pending Cancel Requests of transmission objects */
\r
86 static uint8 CancelRqstArray_0[MAX_MESSAGEBOXES_0];
\r
87 /* To save pending Transmit Requests of transmission objects */
\r
88 static uint8 TxRqstArray_0[MAX_MESSAGEBOXES_0];
\r
89 /* Array to save Filtermask references of MessageObjects */
\r
90 static uint32 FilterMaskRef_0[MESSAGEBOX_COUNT_0];
\r
92 #ifdef CanController_1
\r
93 static Can_PduType PduInfoArray_1[MAX_MESSAGEBOXES_1];
\r
94 static uint8 CancelRqstArray_1[MAX_MESSAGEBOXES_1];
\r
95 static uint8 TxRqstArray_1[MAX_MESSAGEBOXES_1];
\r
96 static uint32 FilterMaskRef_1[MESSAGEBOX_COUNT_1];
\r
99 /* Holds the Controller specific configuration */
\r
100 static Controller_PreConfigType ControllerConfig[] =
\r
103 BUSOFF_PROCESSING_0,
\r
106 WAKEUP_PROCESSING_0,
\r
107 MESSAGEBOX_COUNT_0,
\r
108 MAX_MESSAGEBOXES_0,
\r
116 #ifdef CanController_1
\r
118 BUSOFF_PROCESSING_1,
\r
121 WAKEUP_PROCESSING_1,
\r
122 MESSAGEBOX_COUNT_1,
\r
123 MAX_MESSAGEBOXES_1,
\r
134 /* Shadow Buffer is used for buffering of received data */
\r
135 static uint8 RxShadowBuf[8];
\r
137 /* Driver must know how often Can_DisableControllerInterrupts() has been called */
\r
138 static uint32 IntDisableCount[CAN_CONTROLLER_COUNT];
\r
141 /*----------------------------------------------------------------------------*/
\r
142 /* Function Name: Can1_InterruptHandler_0 */
\r
143 /* Description: CAN Node 1 Level 0 Interrupt Service Routine */
\r
144 /* Return Value: None */
\r
148 //#pragma INTERRUPT(CAN1_INTERRUPTHANDLER_0,IRQ)
\r
150 void CAN1_INTERRUPTHANDLER_0()
\r
156 uint8 DataByteIndex;
\r
159 //Can_DisableControllerInterrupts(0);
\r
161 ErrCounter = CAN_TIMEOUT_DURATION;
\r
163 uint32 ir = CanBase[0]->IR;
\r
167 uint32 sr = CanBase[0]->SR;
\r
168 /* WakeUp Pending */
\r
169 if(sr & 0x00000200) {
\r
170 /* Set Init Bit, so that Controller is in Stop state */
\r
171 CanBase[0]->CTL |= 0x1;
\r
172 // EcuM_CheckWakeUp(ControllerConfig[0].WakeupSrc);
\r
176 if(sr & 0x00000080) {
\r
177 Can_SetControllerMode(0, CAN_T_STOP); // CANIF272
\r
178 //CanIf_ControllerBusOff(0); // Not implemented in Arctic Core
\r
186 /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/
\r
187 CanBase[0]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;
\r
189 /* Wait until Busy Flag is 0 */
\r
190 while(CanBase[0]->IFx[IfRegId].COM & 0x8000)
\r
193 if(ErrCounter == 0)
\r
195 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
196 ErrCounter = CAN_TIMEOUT_DURATION;
\r
201 /* Transmit Object */
\r
202 if(CanBase[0]->IFx[IfRegId].ARB & 0x20000000)
\r
204 /* Reset TxRqst-Array Element */
\r
205 TxRqstArray_0[MsgNr - 1] = 0;
\r
206 /* A Message was successfully transmitted */
\r
207 CanIf_TxConfirmation(PduInfoArray_0[MsgNr - 1].swPduHandle);
\r
209 /* Receive Object */
\r
213 if(CanBase[0]->IFx[IfRegId].ARB & 0x40000000)
\r
215 /* Bring Id to standardized format (MSB marks extended Id) */
\r
216 MsgId = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;
\r
221 /* Bring Id to standardized format (MSB marks extended Id) */
\r
222 MsgId = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;
\r
225 MsgDlc = CanBase[0]->IFx[IfRegId].MC & 0x000F;
\r
230 /* Let SduPtr point to Shadow Buffer */
\r
231 SduPtr = RxShadowBuf;
\r
233 /* Copy Message Data to Shadow Buffer */
\r
234 for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)
\r
236 RxShadowBuf[DataByteIndex] = CanBase[0]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];
\r
238 /* Indicate successful Reception */
\r
239 CanIf_RxIndication(CurConfig->MessageBoxPtr[MsgNr - 1].ObjectId, MsgId, MsgDlc, SduPtr);
\r
242 //Can_EnableControllerInterrupts(0);
\r
247 /*----------------------------------------------------------------------------*/
\r
248 /* Function Name: Can_Init */
\r
249 /* Service Id: 0x00 */
\r
250 /* Execution: Synchronous */
\r
251 /* Re-entrant: No */
\r
252 /* Description: Initialize Can Driver */
\r
253 /* ConfigPtr: Pointer to initialization data */
\r
254 /* Return Value: None */
\r
257 void CAN_INIT(const Can_ConfigType *Config)
\r
262 Can_ControllerConfigType *CurControllerPtr;
\r
263 Can_MessageObjectType *MsgBoxPtr;
\r
264 uint32 *CurFilterMaskPtr;
\r
267 /* DET Error Check */
\r
268 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
269 if(ModuleState != CAN_UNINIT)
\r
271 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_TRANSITION);
\r
276 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_PARAM_POINTER);
\r
281 CurConfig = Config;
\r
282 /* Set Pointer to ControllerConfig */
\r
283 CurControllerPtr = Config->ControllerConfigPtr;
\r
284 /* Set Pointer to MessageObjects */
\r
285 MsgBoxPtr = CurConfig->MessageBoxPtr;
\r
287 for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)
\r
289 ErrCounter = CAN_TIMEOUT_DURATION;
\r
291 /* Init, IE, AutomaticRetransmission, ConfChangeEnable, ABO Off,Parity On, SIE and EIE depending on ControllerConfig */
\r
292 #if(CAN_WAKEUP_SUPPORT == STD_ON)
\r
293 CanBase[Controller]->CTL = 0x02001643 | (ControllerConfig[Controller].WakeupProc >> 8) | (ControllerConfig[Controller].BusOff >> 7);
\r
295 CanBase[Controller]->CTL = 0x00001643 | (ControllerConfig[Controller].WakeupProc >> 8) | (ControllerConfig[Controller].BusOff >> 7);
\r
297 /* LEC 7, TxOk, RxOk, PER */
\r
298 CanBase[Controller]->SR = 0x0000011F;
\r
300 /* Test Mode only for Development time: Silent Loopback */
\r
301 //CanBase[Controller]->CTL |= 0x00000080;
\r
302 //CanBase[Controller]->TR = 0x00000018;
\r
304 for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MaxBoxes; MsgNr++)
\r
306 /* Initialize the Arrays for Transmit and Cancellation handling */
\r
307 *(ControllerConfig[Controller].CancelPtr + MsgNr) = 0;
\r
308 *(ControllerConfig[Controller].TxPtr + MsgNr) = 0;
\r
310 /* Set the current FilterMaskPointer */
\r
311 CurFilterMaskPtr = CurControllerPtr->FilterMaskPtr;
\r
312 /* Wait until Busy Flag is 0 */
\r
313 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
316 if(ErrCounter == 0)
\r
318 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
319 ErrCounter = CAN_TIMEOUT_DURATION;
\r
323 /* Configure the post-build defined MessageObjects */
\r
324 if(MsgNr < ControllerConfig[Controller].MessageBoxCount)
\r
326 /* Check, if the next message object has the same values as the current, and if it is the last one */
\r
327 if((MsgNr < (ControllerConfig[Controller].MessageBoxCount - 1)) &&
\r
328 (MsgBoxPtr->Direction == CAN_RECEIVE ) &&
\r
329 (MsgBoxPtr->Direction == (MsgBoxPtr + 1)->Direction ) &&
\r
330 (MsgBoxPtr->IdType == (MsgBoxPtr + 1)->IdType ) &&
\r
331 (MsgBoxPtr->IdValue == (MsgBoxPtr + 1)->IdValue ) &&
\r
332 (MsgBoxPtr->FilterMaskIndex == (MsgBoxPtr + 1)->FilterMaskIndex) &&
\r
333 (MsgBoxPtr->HandleType == (MsgBoxPtr + 1)->HandleType )
\r
336 /* EndOfBlock Bit will not be set */
\r
341 /* EndOfBlock Bit will be set */
\r
344 /* DLC=8, Use Mask only for receive, Set RxIE/TxIE depending on pre-config settings, Eob */
\r
345 CanBase[Controller]->IFx[IfRegId].MC = 0x00001008 | ControllerConfig[Controller].RxProc | (ControllerConfig[Controller].TxProc << 1) | Eob & ~(MsgBoxPtr->Direction >> 17);
\r
347 if(MsgBoxPtr->IdType == CAN_STANDARD) /* Standard Identifiers */
\r
349 /* Only Standard-Ids are accepted, Set Mask */
\r
350 CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(CurFilterMaskPtr + MsgBoxPtr->FilterMaskIndex)) & 0x1FFFFFFF);
\r
351 /* Message valid, Id, Direction */
\r
352 CanBase[Controller]->IFx[IfRegId].ARB = 0x80000000 | ((MsgBoxPtr->IdValue & 0x7FF) << 18) | MsgBoxPtr->Direction;
\r
354 else if(MsgBoxPtr->IdType == CAN_EXTENDED) /* Extended Identifiers */
\r
356 /* Only Extended-Ids are accepted, Set Mask */
\r
357 CanBase[Controller]->IFx[IfRegId].MASK = 0x80000000 | ((*(CurFilterMaskPtr + MsgBoxPtr->FilterMaskIndex)) & 0x1FFFFFFF);
\r
358 /* Message valid, Id, Direction */
\r
359 CanBase[Controller]->IFx[IfRegId].ARB = 0xC0000000 | (MsgBoxPtr->IdValue & 0x1FFFFFFF) | MsgBoxPtr->Direction;
\r
361 else /* Mixed Identifiers */
\r
363 /* Standard- and Mixed-Ids are accepted, Set Mask */
\r
364 CanBase[Controller]->IFx[IfRegId].MASK = 0x00000000 | ((*(CurFilterMaskPtr + MsgBoxPtr->FilterMaskIndex)) & 0x1FFFFFF);
\r
365 /* Message valid, Id, Direction */
\r
366 CanBase[Controller]->IFx[IfRegId].ARB = 0xC0000000 | (MsgBoxPtr->IdValue & 0x1FFFFFF) | MsgBoxPtr->Direction;
\r
368 /* Start writing Mask, Arb, Control and Id bits */
\r
369 CanBase[Controller]->IFx[IfRegId].COM = 0x00F80000 | (MsgNr + 1);
\r
371 /* Save FilterMask reference of actual MessageObject */
\r
372 *(ControllerConfig[Controller].MaskRefPtr + MsgNr) = MsgBoxPtr->FilterMaskIndex;
\r
374 /* Increment Pointer to next MessageObject */
\r
377 else /* Configure all other MessageObjects to not valid */
\r
380 CanBase[Controller]->IFx[IfRegId].ARB = 0x00000000;
\r
381 /* Start writing Arbitration Bits */
\r
382 CanBase[Controller]->IFx[IfRegId].COM = 0x00A80000 | (MsgNr + 1);
\r
384 /* Use IFx[0] and IFx[1] alternating */
\r
387 /* Set Bit Timing Register */
\r
388 CanBase[Controller]->BTR = CurControllerPtr->CanTimeRegister;
\r
389 /* Reset CCE Bit */
\r
390 CanBase[Controller]->CTL &= ~0x00000040;
\r
392 /* Switch Controller pointer to next ConfigSet */
\r
393 CurControllerPtr++;
\r
395 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
396 /* Switch Controller State to CANIF_CS_STOPPED */
\r
397 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
400 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
401 /* Switch Module State to CAN_READY */
\r
402 ModuleState = CAN_READY;
\r
406 // ARC INSTALL HANDLERS
\r
408 tid = Os_Arc_CreateIsr(CAN1_INTERRUPTHANDLER_0, 2 ,"Can0Level0");
\r
409 Irq_AttachIsr2(tid, NULL, 16);
\r
411 tid = Os_Arc_CreateIsr(CAN1_INTERRUPTHANDLER_0, 2, "Can0Level1");
\r
412 Irq_AttachIsr2(tid, NULL, 29);
\r
418 /*----------------------------------------------------------------------------*/
\r
419 /* Function Name: Can_InitController */
\r
420 /* Service Id: 0x02 */
\r
421 /* Execution: Synchronous */
\r
422 /* Re-entrant: No */
\r
423 /* Description: Initializes only CAN cantroller specific settings */
\r
424 /* Controller: CAN controller to be initialized */
\r
425 /* Config: Pointer to controller configuration */
\r
426 /* Return Value: None */
\r
430 void CAN_INITCONTROLLER(uint8 Controller, const Can_ControllerConfigType* Config)
\r
432 uint32 *CurMaskRef;
\r
436 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
439 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_POINTER);
\r
442 if(ModuleState == CAN_UNINIT)
\r
444 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_UNINIT);
\r
447 if(Controller >= CAN_CONTROLLER_COUNT)
\r
449 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_CONTROLLER);
\r
452 if(ControllerMode[Controller] != CANIF_CS_STOPPED)
\r
454 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_TRANSITION);
\r
459 CurMaskRef = ControllerConfig[Controller].MaskRefPtr;
\r
460 ErrCounter = CAN_TIMEOUT_DURATION;
\r
462 for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)
\r
464 /* Wait until Busy Flag is 0 */
\r
465 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
468 if(ErrCounter == 0)
\r
470 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
471 ErrCounter = CAN_TIMEOUT_DURATION;
\r
475 /* Read actual MaskRegister value of MessageObject */
\r
476 CanBase[Controller]->IFx[IfRegId].COM = 0x004C0000 | (MsgNr + 1);
\r
478 /* Wait until Busy Flag is 0 */
\r
479 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
482 if(ErrCounter == 0)
\r
484 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
485 ErrCounter = CAN_TIMEOUT_DURATION;
\r
489 CanBase[Controller]->IFx[IfRegId].MASK &= 0xD0000000;
\r
491 CanBase[Controller]->IFx[IfRegId].MASK |= *(Config->FilterMaskPtr + *CurMaskRef) & 0x1FFFFFFF;
\r
492 /* Write new Mask to MaskRegister */
\r
493 CanBase[Controller]->IFx[IfRegId].COM = 0x00C80000 | (MsgNr + 1);
\r
499 /* Wait until Busy Flag is 0 */
\r
500 while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)
\r
503 if(ErrCounter == 0)
\r
505 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
506 ErrCounter = CAN_TIMEOUT_DURATION;
\r
510 /* Set CCE Bit to allow access to BitTiming Register (Init already set, in mode "stopped") */
\r
511 CanBase[Controller]->CTL |= 0x00000040;
\r
512 /* Set Bit Timing Register */
\r
513 CanBase[Controller]->BTR = Config->CanTimeRegister;
\r
514 /* Clear CCE Bit */
\r
515 CanBase[Controller]->CTL &= ~0x00000040;
\r
520 /*----------------------------------------------------------------------------*/
\r
521 /* Function Name: Can_SetControllerMode */
\r
522 /* Service Id: 0x03 */
\r
523 /* Execution: Asynchronous */
\r
524 /* Re-entrant: No */
\r
525 /* Descrpition: Performs software triggered state transitions */
\r
526 /* Controller: CAN controller for which the status shall be changed */
\r
527 /* Transition: Transition to be done */
\r
528 /* Return Value: - CAN_OK: transition initiated */
\r
529 /* - CAN_NOT_OK: error or wakeup during transition to 'sleep' */
\r
533 Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType Transition)
\r
535 Can_ReturnType Status = CAN_OK;
\r
536 uint32 ErrCounter = CAN_TIMEOUT_DURATION;
\r
539 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
540 if(ModuleState == CAN_UNINIT)
\r
542 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_UNINIT);
\r
545 if(Controller >= CAN_CONTROLLER_COUNT)
\r
547 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_PARAM_CONTROLLER);
\r
550 if(((Transition == CAN_T_START ) && (ControllerMode[Controller] != CANIF_CS_STOPPED)) ||
\r
551 ((Transition == CAN_T_STOP ) && (ControllerMode[Controller] != CANIF_CS_STARTED)) ||
\r
552 ((Transition == CAN_T_SLEEP ) && (ControllerMode[Controller] != CANIF_CS_STOPPED)) ||
\r
553 ((Transition == CAN_T_WAKEUP) && (ControllerMode[Controller] != CANIF_CS_SLEEP )))
\r
555 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_TRANSITION);
\r
563 /* Clear Init Bit */
\r
564 CanBase[Controller]->CTL &= ~0x00000001;
\r
565 /* Clear Status Register */
\r
566 CanBase[Controller]->SR = 0x0000011F;
\r
568 ControllerMode[Controller] = CANIF_CS_STARTED;
\r
569 Can_EnableControllerInterrupts(Controller);
\r
574 CanBase[Controller]->CTL |= 0x00000001;
\r
575 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
576 Can_DisableControllerInterrupts(Controller);
\r
581 CanBase[Controller]->CTL |= 0x01000000;
\r
582 /* Save actual Register status */
\r
583 RegBuf = CanBase[Controller]->CTL;
\r
584 /* Disable Status Interrupts and WUBA */
\r
585 CanBase[Controller]->CTL &= ~0x02000004;
\r
586 /* Wait until Local Power Down Mode acknowledged */
\r
587 while(!(CanBase[Controller]->SR & 0x00000400))
\r
589 /* Check if a WakeUp occurs */
\r
590 if(CanBase[Controller]->SR & 0x00000200)
\r
592 Status = CAN_NOT_OK;
\r
596 if(ErrCounter == 0)
\r
598 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
599 ErrCounter = CAN_TIMEOUT_DURATION;
\r
600 Status = CAN_NOT_OK;
\r
604 /* Reset Control Register */
\r
605 CanBase[Controller]->CTL = RegBuf;
\r
606 ControllerMode[Controller] = CANIF_CS_SLEEP;
\r
610 /* Clear PDR Bit */
\r
611 CanBase[Controller]->CTL &= ~0x01000000;
\r
612 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
616 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
617 /* Invalid Transition */
\r
618 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_TRANSITION);
\r
628 /*----------------------------------------------------------------------------*/
\r
629 /* Function Name: Can_DisableControllerInterrupts */
\r
630 /* Service Id: 0x04 */
\r
631 /* Execution: Synchronous */
\r
632 /* Re-entrant: Yes */
\r
633 /* Description: Disables all interrupts for this controller */
\r
634 /* Controller: CAN controller for which interrupts shall be disabled */
\r
635 /* Return Value: None */
\r
639 void Can_DisableControllerInterrupts(uint8 Controller)
\r
641 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
642 if(ModuleState == CAN_UNINIT)
\r
644 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_UNINIT);
\r
647 if(Controller >= CAN_CONTROLLER_COUNT)
\r
649 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_PARAM_CONTROLLER);
\r
654 CanBase[Controller]->CTL &= ~0x00000002;
\r
655 /* Increment Disable Counter */
\r
656 IntDisableCount[Controller]++;
\r
660 /*----------------------------------------------------------------------------*/
\r
661 /* Function Name: Can_EnableControllerInterrupts */
\r
662 /* Service Id: 0x05 */
\r
663 /* Execution: Synchronous */
\r
664 /* Re-entrant: Yes */
\r
665 /* Description: Enables all allowed interrupts for this controller */
\r
666 /* Controller: CAN controller for which interrupts shall be re-enabled */
\r
667 /* Return Value: None */
\r
671 void Can_EnableControllerInterrupts(uint8 Controller)
\r
673 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
674 if(ModuleState == CAN_UNINIT)
\r
676 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_UNINIT);
\r
679 if(Controller >= CAN_CONTROLLER_COUNT)
\r
681 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_PARAM_CONTROLLER);
\r
685 if(IntDisableCount[Controller] > 0)
\r
687 if(IntDisableCount[Controller] == 1)
\r
690 CanBase[Controller]->CTL |= 0x00000002;
\r
692 IntDisableCount[Controller]--;
\r
697 /*----------------------------------------------------------------------------*/
\r
698 /* Function Name: Can_Cbk_CheckWakeup */
\r
699 /* Service Id: 0x0b */
\r
700 /* Execution: Synchronous */
\r
701 /* Re-entrant: No */
\r
702 /* Description: Checks if a wakeup has occurred for the given controller */
\r
703 /* Controller: CAN controller to be checked for wakeup */
\r
704 /* Return Value: - E_OK: Wakeup was detected for given controller */
\r
705 /* - E_NOT_OK: No Wakeup was detected */
\r
709 void Can_Cbk_CheckWakeup(uint8 Controller)
\r
712 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
713 if(Controller >= CAN_CONTROLLER_COUNT)
\r
715 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0x0B, CAN_E_PARAM_CONTROLLER);
\r
719 // Check WakeUpPending
\r
720 if(CanBase[Controller]->SR & 0x00000200)
\r
732 /*----------------------------------------------------------------------------*/
\r
733 /* Function Name: Can_Write */
\r
734 /* Service Id: 0x06 */
\r
735 /* Execution: Synchronous */
\r
736 /* Re-entrant: Yes (thread-safe) */
\r
737 /* Description: -- */
\r
738 /* Hth: HW-transmit handle to be used for transmit */
\r
739 /* PduInfo: Pointer to SDU user memory, DLC and Identifier */
\r
740 /* Return Value: - CAN_OK: Write command has been accepted */
\r
741 /* - CAN_NOT_OK: Development error occured */
\r
742 /* - CAN_BUSY: No TX hw buffer available or preemptive call */
\r
746 Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)
\r
749 uint8 ControllerId;
\r
753 uint32 ArbRegValue;
\r
754 uint8 DataByteIndex;
\r
756 Can_PduType *CurPduArrayPtr;
\r
757 uint8 *CurCancelRqstPtr;
\r
758 uint8 *CurTxRqstPtr;
\r
759 Can_MessageObjectType *CurMsgBoxPtr;
\r
761 CurSduPtr = PduInfo->sdu;
\r
762 CurMsgBoxPtr = CurConfig->MessageBoxPtr + Hth;
\r
763 ErrCounter = CAN_TIMEOUT_DURATION;
\r
765 /* DET Error Check */
\r
766 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
767 if(PduInfo == NULL || PduInfo->sdu == NULL)
\r
769 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_POINTER);
\r
772 if(ModuleState == CAN_UNINIT)
\r
774 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_UNINIT);
\r
777 if(PduInfo->length > 8)
\r
779 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_DLC);
\r
780 return CAN_NOT_OK;
\r
782 if(CurMsgBoxPtr->Direction != CAN_TRANSMIT)
\r
784 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_HANDLE);
\r
789 ControllerId = CurMsgBoxPtr->Controller;
\r
791 MsgNr = Hth - ControllerConfig[ControllerId].FirstHandle;
\r
793 CurPduArrayPtr = ControllerConfig[ControllerId].PduPtr + MsgNr;
\r
794 CurCancelRqstPtr = ControllerConfig[ControllerId].CancelPtr + MsgNr;
\r
795 CurTxRqstPtr = ControllerConfig[ControllerId].TxPtr + MsgNr;
\r
797 /* Bring Id Value to appropriate format and set ArbRegValue */
\r
798 if(PduInfo->id & 0x80000000)
\r
800 /* MsgVal, Ext, Transmit, Extended Id */
\r
801 ArbRegValue = 0xD0000000 | (PduInfo->id & 0x1FFFFFFF);
\r
805 /* MsgVal, Std, Transmit, Standard Id */
\r
806 ArbRegValue = 0xA0000000 | ((PduInfo->id & 0x7FF) << 18);
\r
809 /* Check if TxRqst Bit of MsgObject is set */
\r
810 if(CanBase[ControllerId]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F)))
\r
813 #if(CAN_MULTIPLEXED_TRANSMISSION == STD_ON)
\r
815 CancelId = ArbRegValue & 0x1FFFFFFF;
\r
818 for(MsgNr = ControllerConfig[ControllerId].MessageBoxCount; MsgNr < ControllerConfig[ControllerId].MaxBoxes; MsgNr++)
\r
820 /* Read actual MessageObject status: Data, Arbitration, Control */
\r
821 CanBase[ControllerId]->IFx[IfRegId].COM = 0x00330000 | (MsgNr + 1);
\r
822 /* Wait until Busy Flag is 0 */
\r
823 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)
\r
826 if(ErrCounter == 0)
\r
828 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
829 ErrCounter = CAN_TIMEOUT_DURATION;
\r
834 /* If MessageObject is free, use it */
\r
835 if(!(CanBase[ControllerId]->IFx[IfRegId].MC & 0x00000100))
\r
837 CurPduArrayPtr = ControllerConfig[ControllerId].PduPtr + MsgNr;
\r
840 /* Check if Id of MessageObject is higher */
\r
841 if((CanBase[ControllerId]->IFx[IfRegId].ARB & 0x1FFFFFFF) > CancelId )
\r
843 /* Save the highest ID (low priority) */
\r
844 CancelId = CanBase[ControllerId]->IFx[IfRegId].ARB & 0x1FFFFFFF;
\r
845 /* and corresponding message number */
\r
849 if(MsgNr == ControllerConfig[ControllerId].MaxBoxes)
\r
851 #if(CAN_HW_TRANSMIT_CANCELLATION == STD_ON)
\r
853 CanBase[ControllerId]->IFx[IfRegId].MC &= ~0x00000100;
\r
854 /* Transfer Control bits to MessageObject */
\r
855 CanBase[ControllerId]->IFx[IfRegId].COM = 0x90000000 | (CancelNr + 1);
\r
857 if(ControllerConfig[ControllerId].TxProc == INTERRUPT)
\r
859 /* Set CurPduPtr to Pdu of object to cancel */
\r
860 CurPduArrayPtr = ControllerConfig[ControllerId].PduPtr + CancelNr;
\r
861 /* Wait until Busy Flag is 0 */
\r
862 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)
\r
865 if(ErrCounter == 0)
\r
867 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
868 ErrCounter = CAN_TIMEOUT_DURATION;
\r
872 /* Notification about cancellation of object */
\r
873 CanIf_CancelTxConfirmation((const Can_PduType *)CurPduArrayPtr);
\r
877 /* Set CancelPointer to Position of cancelled Object */
\r
878 CurCancelRqstPtr = ControllerConfig[ControllerId].CancelPtr + CancelNr;
\r
879 /* Set Arrayelement to 1 to indicate cancellation request */
\r
880 *CurCancelRqstPtr = 1;
\r
884 #elif(CAN_HW_TRANSMIT_CANCELLATION == STD_ON)
\r
886 /* Wait until Busy Flag is 0 */
\r
887 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)
\r
890 if(ErrCounter == 0)
\r
892 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
893 ErrCounter = CAN_TIMEOUT_DURATION;
\r
898 /* Read actual MessageObject status: Data, Arbitration, Control */
\r
899 CanBase[ControllerId]->IFx[IfRegId].COM = 0x00330000 | (MsgNr + 1);
\r
901 /* Wait until Busy Flag is 0 */
\r
902 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)
\r
905 if(ErrCounter == 0)
\r
907 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
908 ErrCounter = CAN_TIMEOUT_DURATION;
\r
913 /* Check if actual message has higher priority */
\r
914 if((ArbRegValue & 0x1FFFFFFF) < (CanBase[ControllerId]->IFx.ARB & 0x1FFFFFFF))
\r
917 CanBase[ControllerId]->IFx[IfRegId].MC &= ~0x00000100;
\r
918 /* Transfer Control bits to MessageObject */
\r
919 CanBase[ControllerId]->IFx[IfRegId].COM = 0x90000000 | (MsgNr + 1);
\r
921 if(ControllerConfig[ControllerId].TxProc == INTERRUPT)
\r
923 /* Wait until Busy Flag is 0 */
\r
924 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)
\r
927 if(ErrCounter == 0)
\r
929 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
930 ErrCounter = CAN_TIMEOUT_DURATION;
\r
934 /* Notification about cancellation of object */
\r
935 CanIf_CancelTxConfirmation((const Can_PduType *)CurPduArrayPtr);
\r
939 /* Set Arrayelement to 1 to indicate cancellation request */
\r
940 *CurCancelRqstPtr = 1;
\r
947 /* Wait until Busy Flag is 0 */
\r
948 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)
\r
951 if(ErrCounter == 0)
\r
953 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
954 ErrCounter = CAN_TIMEOUT_DURATION;
\r
959 /* Set NewDat, TxIE (dep on ControllerConfig), TxRqst, EoB and DLC */
\r
960 CanBase[ControllerId]->IFx[IfRegId].MC = 0x00000180 | (0x000F & PduInfo->length) | (ControllerConfig[ControllerId].TxProc << 1);
\r
962 /* Set ArbitrationRegister */
\r
963 CanBase[ControllerId]->IFx[IfRegId].ARB = ArbRegValue;
\r
965 /* Set Databytes */
\r
966 for(DataByteIndex = 0; DataByteIndex < PduInfo->length; DataByteIndex++)
\r
968 CanBase[ControllerId]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]] = *CurSduPtr++;
\r
971 /* Start transmission to MessageRAM */
\r
972 CanBase[ControllerId]->IFx[IfRegId].COM = 0x00BF0000 | (MsgNr + 1);
\r
974 /* Save the PduInfo in PduArray, so that messages can be identified later */
\r
975 *CurPduArrayPtr = *PduInfo;
\r
976 /* TxRqstArray-Elements are used to identifiy transmitted objects in polling mode */
\r
985 /*----------------------------------------------------------------------------*/
\r
986 /* Function Name: Can_MainFunction_Write */
\r
987 /* Service Id: 0x01 */
\r
988 /* Timing: FIXED_CYCLIC */
\r
989 /* Description: Polling of TX confirmation and TX cancellation confirmation */
\r
990 /* Return Value: None */
\r
994 void CAN_MAINFUNCTION_WRITE()
\r
999 Can_PduType *CurPduPtr;
\r
1001 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1002 if(ModuleState == CAN_UNINIT)
\r
1004 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 1, CAN_E_UNINIT);
\r
1008 /* Check all controllers */
\r
1009 for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)
\r
1011 /* Check all MessageObjects */
\r
1012 for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MaxBoxes; MsgNr++)
\r
1014 /* Check if a transmission was initiated for this MessageObject */
\r
1015 if(*(ControllerConfig[Controller].TxPtr + MsgNr) == 1)
\r
1017 /* Check if TxRqst Bit has already been reset */
\r
1018 if(!(CanBase[Controller]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))))
\r
1020 /* Reset swTxRqst */
\r
1021 *(ControllerConfig[Controller].TxPtr + MsgNr) = 0;
\r
1023 CurPduPtr = ControllerConfig[Controller].PduPtr + MsgNr;
\r
1024 /* A Message was successfully transmitted */
\r
1025 CanIf_TxConfirmation(CurPduPtr->swPduHandle);
\r
1028 /* Check if a cancellation was initiated for this MessageObject */
\r
1029 if(*(ControllerConfig[Controller].CancelPtr + MsgNr) == 1)
\r
1031 /* Check if TxRqst Bit has already been reset */
\r
1032 if(!(CanBase[Controller]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))))
\r
1034 /* Reset swCancelRqst */
\r
1035 *(ControllerConfig[Controller].CancelPtr + MsgNr) = 0;
\r
1037 CurPduPtr = ControllerConfig[Controller].PduPtr + MsgNr;
\r
1038 /* A Message was successfully transmitted */
\r
1039 CanIf_CancelTxConfirmation(CurPduPtr);
\r
1048 /*----------------------------------------------------------------------------*/
\r
1049 /* Function Name: Can_MainFunction_Read */
\r
1050 /* Service Id: 0x08 */
\r
1051 /* Timing: FIXED_CYCLIC */
\r
1052 /* Description: Polling of RX indications */
\r
1053 /* Return Value: None */
\r
1054 /* Remarks: -/- */
\r
1057 void CAN_MAINFUNCTION_READ()
\r
1062 Can_MessageObjectType *CurMsgBoxPtr;
\r
1064 uint32 Identifier;
\r
1065 uint8 DataByteIndex;
\r
1067 uint32 ErrCounter;
\r
1070 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1071 if(ModuleState == CAN_UNINIT)
\r
1073 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 8, CAN_E_UNINIT);
\r
1078 CurMsgBoxPtr = CurConfig->MessageBoxPtr;
\r
1080 for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)
\r
1082 for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)
\r
1084 /* Check if NewDat Bit is set and if MessageObject is Receive Object */
\r
1085 if((CanBase[Controller]->NDx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))) && (CurMsgBoxPtr->Direction == RECEIVE))
\r
1088 /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/
\r
1089 CanBase[Controller]->IFx[IfRegId].COM = 0x003F0000 | (MsgNr + 1);
\r
1091 ErrCounter = CAN_TIMEOUT_DURATION;
\r
1092 /* Wait until Busy Flag is 0 */
\r
1093 while(CanBase[Controller]->IFx[IfRegId].COM & 0x8000)
\r
1096 if(ErrCounter == 0)
\r
1098 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
1103 if(CanBase[0]->IFx[IfRegId].ARB & 0x40000000)
\r
1105 /* Bring Id to standardized format (MSB marks extended Id) */
\r
1106 Identifier = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;
\r
1111 /* Bring Id to standardized format (MSB marks extended Id) */
\r
1112 Identifier = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;
\r
1115 MsgDlc = CanBase[0]->IFx[IfRegId].MC & 0x000F;
\r
1120 /* Let SduPtr point to Shadow Buffer */
\r
1121 SduPtr = RxShadowBuf;
\r
1123 /* Copy Message Data to Shadow Buffer */
\r
1124 for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)
\r
1126 RxShadowBuf[DataByteIndex] = CanBase[0]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];
\r
1128 /* Indicate successful Reception */
\r
1129 CanIf_RxIndication(MsgNr, Identifier, MsgDlc, SduPtr);
\r
1138 /*----------------------------------------------------------------------------*/
\r
1139 /* Function Name: Can_MainFunction_BusOff */
\r
1140 /* Service Id: 0x09 */
\r
1141 /* Timing: FIXED_CYCLIC */
\r
1142 /* Description: Polling of bus-off events */
\r
1143 /* Return Value: None */
\r
1144 /* Remarks: -/- */
\r
1147 void CAN_MAINFUNCTION_BUSOFF()
\r
1151 /* DET Error Check */
\r
1152 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1153 if(ModuleState == CAN_UNINIT)
\r
1155 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 9, CAN_E_UNINIT);
\r
1160 for(Controller = 0 ; Controller < CAN_CONTROLLER_COUNT; Controller++)
\r
1163 if(CanBase[Controller]->SR & 0x00000080)
\r
1165 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1166 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
1168 CanIf_ControllerBusOff(Controller);
\r
1174 /*----------------------------------------------------------------------------*/
\r
1175 /* Function Name: Can_MainFunction_Wakeup */
\r
1176 /* Service Id: 0x0a */
\r
1177 /* Timing: FIXED_CYCLIC */
\r
1178 /* Description: Polling of wake-up events */
\r
1179 /* Return Value: None */
\r
1180 /* Remarks: -/- */
\r
1183 void CAN_MAINFUNCTION_WAKEUP()
\r
1187 /* DET Error Check */
\r
1188 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1189 if(ModuleState == CAN_UNINIT)
\r
1191 Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0xA, CAN_E_UNINIT);
\r
1196 for(Controller = 0 ; Controller < CAN_CONTROLLER_COUNT; Controller++)
\r
1198 /* Check WakeUp Pending */
\r
1199 if(CanBase[Controller]->SR & 0x200)
\r
1201 /* Set Init Bit, so that Controller is in Stop state */
\r
1202 CanBase[Controller]->CTL |= 0x1;
\r
1203 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1204 ControllerMode[Controller] = CANIF_CS_STOPPED;
\r
1206 //EcuM_CheckWakeUp(ControllerConfig[Controller].WakeupSrc);
\r
1214 /*----------------------------------------------------------------------------*/
\r
1215 /* Function Name: Can2_InterruptHandler_0 */
\r
1216 /* Description: CAN Node 2 Level 0 Interrupt Service Routine */
\r
1217 /* Return Value: None */
\r
1218 /* Remarks: -/- */
\r
1220 #ifdef CanController_1
\r
1221 //#pragma INTERRUPT(CAN2_INTERRUPTHANDLER_0,IRQ)
\r
1223 void CAN2_INTERRUPTHANDLER_0()
\r
1226 uint32 ErrCounter;
\r
1230 uint8 DataByteIndex;
\r
1233 ErrCounter = CAN_TIMEOUT_DURATION;
\r
1235 if(CanBase[1]->IR == 0x8000)
\r
1237 /* WakeUp Pending */
\r
1238 if(CanBase[1]->SR & 0x200)
\r
1240 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1241 ControllerMode[1] = CANIF_CS_STOPPED;
\r
1243 /* Set Init Bit, so that Controller is in Stop state */
\r
1244 CanBase[1]->CTL |= 0x1;
\r
1245 // EcuM_CheckWakeUp(ControllerConfig[1].WakeupSrc);
\r
1248 if(CanBase[1]->SR & 0x080)
\r
1250 #if(CAN_DEV_ERROR_DETECT == STD_ON)
\r
1251 ControllerMode[1] = CANIF_CS_STOPPED;
\r
1253 CanIf_ControllerBusOff(1);
\r
1258 MsgNr = CanBase[1]->IR;
\r
1260 /* Read Arbitration, Control and Data Bits and clear IntPnd */
\r
1261 CanBase[1]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;
\r
1263 /* Wait until Busy Flag is 0 */
\r
1264 while(CanBase[1]->IFx[IfRegId].COM & 0x8000)
\r
1267 if(ErrCounter == 0)
\r
1269 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
1270 ErrCounter = CAN_TIMEOUT_DURATION;
\r
1275 /* Transmit Object */
\r
1276 if(CanBase[1]->IFx[IfRegId].ARB & 0x20000000)
\r
1278 /* Reset TxRqst-Array Element */
\r
1279 TxRqstArray_1[MsgNr - 1] = 0;
\r
1280 /* A Message was successfully transmitted */
\r
1281 CanIf_TxConfirmation(PduInfoArray_1[MsgNr - 1].swPduHandle);
\r
1283 /* Receive Object */
\r
1287 if(CanBase[1]->IFx[IfRegId].ARB & 0x40000000)
\r
1289 /* Bring Id to standardized format (MSB marks extended Id) */
\r
1290 MsgId = (CanBase[1]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;
\r
1295 /* Bring Id to standardized format (MSB marks extended Id) */
\r
1296 MsgId = (CanBase[1]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;
\r
1299 MsgDlc = CanBase[1]->IFx[IfRegId].MC & 0x000F;
\r
1304 /* Let SduPtr point to Shadow Buffer */
\r
1305 SduPtr = RxShadowBuf;
\r
1307 /* Copy Message Data to Shadow Buffer */
\r
1308 for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)
\r
1310 RxShadowBuf[DataByteIndex] = CanBase[1]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];
\r
1312 /* Indicate successful Reception */
\r
1313 CanIf_RxIndication(MsgNr - 1, MsgId, MsgDlc, SduPtr);
\r