]> rtime.felk.cvut.cz Git - arc.git/blob - arch/arm/arm_cr4/drivers/Can.c
Work on CAN driver for TMS570
[arc.git] / arch / arm / arm_cr4 / drivers / Can.c
1 \r
2 \r
3 /*----------------------------------------------------------------------------*/\r
4 /* Include Files                                                              */\r
5 \r
6 \r
7 \r
8 #include "Can.h"\r
9 #include "core_cr4.h"\r
10 #if defined(USE_DEM)\r
11 #include "Dem.h"\r
12 #endif\r
13 #include "Det.h"\r
14 //#include "Spi.h"\r
15 //#include "EcuM_Cbk.h"\r
16 #include "CanIf_Cbk.h"\r
17 //#include "MemMap.h"\r
18 #include "Os.h"\r
19 #include "irq.h"\r
20 \r
21 \r
22 \r
23 #if !defined(USE_DEM)\r
24 #define Dem_ReportErrorStatus(...)\r
25 #endif\r
26 \r
27 \r
28 /*----------------------------------------------------------------------------*/\r
29 /* Variable Definition                                                        */\r
30 \r
31 static Can_RegisterType* CanBase[]=\r
32 {\r
33     Can0_Base,\r
34 #ifdef Can1_Base\r
35     Can1_Base\r
36 #endif\r
37 };\r
38 \r
39 typedef enum\r
40 {\r
41     CAN_UNINIT,\r
42     CAN_READY\r
43 } Can_StateType;\r
44 \r
45 typedef enum\r
46 {\r
47     INTERRUPT = 0x00000400,\r
48     POLLING   = 0x00000000\r
49 } OpMode;\r
50 \r
51 typedef struct\r
52 {\r
53     OpMode       BusOff;\r
54     OpMode       RxProc;\r
55     OpMode       TxProc;\r
56     OpMode       WakeupProc;\r
57     uint16       MessageBoxCount;\r
58     uint16       MaxBoxes;\r
59     uint8        FirstHandle;\r
60     uint32       WakeupSrc;\r
61     uint32      *MaskRefPtr;\r
62     Can_PduType *PduPtr;\r
63     uint8       *CancelPtr;\r
64     uint8       *TxPtr;    \r
65 } Controller_PreConfigType;\r
66 \r
67 \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
71 #endif\r
72 static CanIf_ControllerModeType ControllerMode[CAN_CONTROLLER_COUNT];\r
73 \r
74 /* Used to switch between IF1 and IF2 of DCAN */\r
75 static uint8 IfRegId = 0;\r
76 \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
79 \r
80 /* To save pointer to the configuration set */\r
81 static const Can_ConfigType *CurConfig;\r
82 \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
91 \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
97 #endif\r
98 \r
99 /* Holds the Controller specific configuration */ \r
100 static Controller_PreConfigType ControllerConfig[] =\r
101 {\r
102     {\r
103         BUSOFF_PROCESSING_0,\r
104         RX_PROCESSING_0,\r
105         TX_PROCESSING_0,\r
106         WAKEUP_PROCESSING_0,\r
107         MESSAGEBOX_COUNT_0,\r
108         MAX_MESSAGEBOXES_0,\r
109         FIRST_HANDLE_0,\r
110         WAKEUP_SRC_REF_0,\r
111         FilterMaskRef_0,\r
112         PduInfoArray_0,\r
113         CancelRqstArray_0,\r
114         TxRqstArray_0\r
115     },\r
116 #ifdef CanController_1\r
117     {\r
118         BUSOFF_PROCESSING_1,\r
119         RX_PROCESSING_1,\r
120         TX_PROCESSING_1,\r
121         WAKEUP_PROCESSING_1,\r
122         MESSAGEBOX_COUNT_1,\r
123         MAX_MESSAGEBOXES_1,\r
124         FIRST_HANDLE_1,\r
125         WAKEUP_SRC_REF_1,\r
126         FilterMaskRef_1,\r
127         PduInfoArray_1,\r
128         CancelRqstArray_1,\r
129         TxRqstArray_1\r
130     }\r
131 #endif\r
132 };\r
133 \r
134 /* Shadow Buffer is used for buffering of received data */ \r
135 static uint8 RxShadowBuf[8];\r
136 \r
137 /* Driver must know how often Can_DisableControllerInterrupts() has been called */\r
138 static uint32 IntDisableCount[CAN_CONTROLLER_COUNT];\r
139 \r
140 \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
145 /* Remarks:       -/-                                                         */\r
146 /*                                                                            */\r
147 \r
148 //#pragma INTERRUPT(CAN1_INTERRUPTHANDLER_0,IRQ)\r
149 \r
150 void CAN1_INTERRUPTHANDLER_0()\r
151 {\r
152     uint32  ErrCounter;\r
153     uint32  MsgNr;\r
154     uint32  MsgId;\r
155     uint8   MsgDlc;\r
156     uint8   DataByteIndex;\r
157     uint8  *SduPtr;\r
158 \r
159     //Can_DisableControllerInterrupts(0);\r
160 \r
161     ErrCounter = CAN_TIMEOUT_DURATION;\r
162 \r
163     uint32 ir = CanBase[0]->IR;\r
164 \r
165     if(ir == 0x8000)\r
166     {\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
173 \r
174         }\r
175         /* Bus Off */\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
179 \r
180         }\r
181     }\r
182     else\r
183     {\r
184         MsgNr = ir;\r
185 \r
186         /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/\r
187         CanBase[0]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;\r
188 \r
189         /* Wait until Busy Flag is 0 */\r
190         while(CanBase[0]->IFx[IfRegId].COM & 0x8000)\r
191         {\r
192             ErrCounter--;\r
193             if(ErrCounter == 0)\r
194             {\r
195                 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
196                 ErrCounter = CAN_TIMEOUT_DURATION;\r
197                 return;\r
198             }\r
199         }\r
200 \r
201         /* Transmit Object */\r
202         if(CanBase[0]->IFx[IfRegId].ARB & 0x20000000)\r
203         {\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
208         }\r
209         /* Receive Object */\r
210         else\r
211         {\r
212             /* Extended Id */\r
213             if(CanBase[0]->IFx[IfRegId].ARB & 0x40000000)\r
214             {\r
215                 /* Bring Id to standardized format (MSB marks extended Id) */\r
216                 MsgId = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;\r
217             }\r
218             /* Standard Id */\r
219             else\r
220             {\r
221                 /* Bring Id to standardized format (MSB marks extended Id) */\r
222                 MsgId = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;\r
223             }\r
224             /* DLC (Max 8) */\r
225             MsgDlc = CanBase[0]->IFx[IfRegId].MC & 0x000F;\r
226             if(MsgDlc > 8)\r
227             {\r
228                 MsgDlc = 8;\r
229             }\r
230             /* Let SduPtr point to Shadow Buffer */\r
231             SduPtr = RxShadowBuf;\r
232 \r
233             /* Copy Message Data to Shadow Buffer */\r
234             for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
235             {\r
236                 RxShadowBuf[DataByteIndex] = CanBase[0]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
237             }\r
238             /* Indicate successful Reception */\r
239             CanIf_RxIndication(CurConfig->MessageBoxPtr[MsgNr - 1].ObjectId, MsgId, MsgDlc, SduPtr);\r
240         }\r
241     }\r
242     //Can_EnableControllerInterrupts(0);\r
243 }\r
244 \r
245 \r
246 \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
255 /* Remarks:                                                                   */\r
256 /*                                                                            */\r
257 void CAN_INIT(const Can_ConfigType *Config)\r
258 {\r
259     uint32                    Controller;\r
260     uint8                     MsgNr;\r
261     uint32                    ErrCounter;\r
262     Can_ControllerConfigType *CurControllerPtr;\r
263     Can_MessageObjectType    *MsgBoxPtr;\r
264     uint32                   *CurFilterMaskPtr;\r
265     uint32                    Eob;\r
266 \r
267 /* DET Error Check */\r
268 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
269     if(ModuleState != CAN_UNINIT)\r
270     {\r
271         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_TRANSITION);\r
272         return;\r
273     }\r
274     if(Config == NULL)\r
275     {\r
276         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0, CAN_E_PARAM_POINTER);\r
277         return;\r
278     }\r
279 #endif \r
280      \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
286 \r
287     for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
288     {\r
289         ErrCounter = CAN_TIMEOUT_DURATION;\r
290 \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
294 #else\r
295         CanBase[Controller]->CTL = 0x00001643 | (ControllerConfig[Controller].WakeupProc >> 8) | (ControllerConfig[Controller].BusOff >> 7);\r
296 #endif        \r
297         /* LEC 7, TxOk, RxOk, PER */\r
298         CanBase[Controller]->SR  = 0x0000011F;\r
299 \r
300         /* Test Mode only for Development time: Silent Loopback */\r
301         //CanBase[Controller]->CTL |= 0x00000080;\r
302         //CanBase[Controller]->TR   = 0x00000018;\r
303             \r
304         for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MaxBoxes; MsgNr++)\r
305         {\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
309             \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
314             {\r
315                 ErrCounter--;\r
316                 if(ErrCounter == 0)\r
317                 {\r
318                     Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
319                     ErrCounter = CAN_TIMEOUT_DURATION;\r
320                     return;\r
321                 }\r
322             }\r
323             /* Configure the post-build defined MessageObjects */\r
324             if(MsgNr < ControllerConfig[Controller].MessageBoxCount)\r
325             {   \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
334                   )\r
335                 {\r
336                     /* EndOfBlock Bit will not be set */\r
337                     Eob = 0x00000000;\r
338                 }\r
339                 else\r
340                 {\r
341                     /* EndOfBlock Bit will be set */\r
342                     Eob = 0x00000080;\r
343                 }\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
346                 \r
347                 if(MsgBoxPtr->IdType == CAN_STANDARD)      /* Standard Identifiers */\r
348                 {\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
353                 }\r
354                 else if(MsgBoxPtr->IdType == CAN_EXTENDED) /* Extended Identifiers */\r
355                 {\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
360                 }\r
361                 else /* Mixed Identifiers */\r
362                 {\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
367                 }\r
368                 /* Start writing Mask, Arb, Control and Id bits */\r
369                 CanBase[Controller]->IFx[IfRegId].COM  = 0x00F80000 | (MsgNr + 1);\r
370                 \r
371                 /* Save FilterMask reference of actual MessageObject */\r
372                 *(ControllerConfig[Controller].MaskRefPtr + MsgNr) = MsgBoxPtr->FilterMaskIndex;\r
373 \r
374                 /* Increment Pointer to next MessageObject */\r
375                 MsgBoxPtr++;\r
376             }\r
377             else /* Configure all other MessageObjects to not valid */\r
378             {\r
379                 /* Valid = 0 */\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
383             }\r
384             /* Use IFx[0] and IFx[1] alternating */\r
385             IfRegId ^= 1;\r
386         }\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
391 \r
392         /* Switch Controller pointer to next ConfigSet */\r
393         CurControllerPtr++;\r
394 \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
398 #endif\r
399     }\r
400 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
401     /* Switch Module State to CAN_READY */\r
402     ModuleState = CAN_READY;\r
403 #endif\r
404 \r
405 \r
406     // ARC INSTALL HANDLERS\r
407     TaskType tid;\r
408     tid = Os_Arc_CreateIsr(CAN1_INTERRUPTHANDLER_0, 2 ,"Can0Level0");\r
409     Irq_AttachIsr2(tid, NULL, 16);\r
410 \r
411     tid = Os_Arc_CreateIsr(CAN1_INTERRUPTHANDLER_0, 2, "Can0Level1");\r
412     Irq_AttachIsr2(tid, NULL, 29);\r
413 \r
414 }\r
415 \r
416 \r
417 \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
427 /* Remarks:       -/-                                                         */\r
428 /*                                                                            */\r
429 \r
430 void CAN_INITCONTROLLER(uint8 Controller, const Can_ControllerConfigType* Config)\r
431 {\r
432     uint32 *CurMaskRef;\r
433     uint8   MsgNr;\r
434     uint32  ErrCounter;\r
435 \r
436 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
437     if(Config == NULL)\r
438     {\r
439         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_POINTER);\r
440         return;\r
441     }\r
442     if(ModuleState == CAN_UNINIT)\r
443     {\r
444         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_UNINIT);\r
445         return;\r
446     }\r
447     if(Controller >= CAN_CONTROLLER_COUNT)\r
448     {\r
449         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_PARAM_CONTROLLER);\r
450         return;\r
451     }\r
452     if(ControllerMode[Controller] != CANIF_CS_STOPPED)\r
453     {\r
454         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 2, CAN_E_TRANSITION);\r
455         return;\r
456     }\r
457 #endif \r
458 \r
459     CurMaskRef = ControllerConfig[Controller].MaskRefPtr;\r
460     ErrCounter = CAN_TIMEOUT_DURATION;\r
461     \r
462     for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)\r
463     {\r
464         /* Wait until Busy Flag is 0 */\r
465         while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)\r
466         {\r
467             ErrCounter--;\r
468             if(ErrCounter == 0)\r
469             {\r
470                 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
471                 ErrCounter = CAN_TIMEOUT_DURATION;\r
472                 return;\r
473             }\r
474         }\r
475         /* Read actual MaskRegister value of MessageObject */\r
476         CanBase[Controller]->IFx[IfRegId].COM = 0x004C0000 | (MsgNr + 1);\r
477 \r
478         /* Wait until Busy Flag is 0 */\r
479         while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)\r
480         {\r
481             ErrCounter--;\r
482             if(ErrCounter == 0)\r
483             {\r
484                 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
485                 ErrCounter = CAN_TIMEOUT_DURATION;\r
486                 return;\r
487             }\r
488         }\r
489         CanBase[Controller]->IFx[IfRegId].MASK &= 0xD0000000;\r
490         /* Set new Mask */\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
494         \r
495         CurMaskRef++;\r
496 \r
497         IfRegId ^= 1;\r
498     }\r
499     /* Wait until Busy Flag is 0 */\r
500     while(CanBase[Controller]->IFx[IfRegId].COM & 0x00008000)\r
501     {\r
502         ErrCounter--;\r
503         if(ErrCounter == 0)\r
504         {\r
505             Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
506             ErrCounter = CAN_TIMEOUT_DURATION;\r
507             return;\r
508         }\r
509     }   \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
516 \r
517 }\r
518 \r
519 \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
530 /* Remarks:       -/-                                                         */\r
531 /*                                                                            */\r
532 \r
533 Can_ReturnType Can_SetControllerMode(uint8 Controller, Can_StateTransitionType Transition)\r
534 {\r
535     Can_ReturnType Status     = CAN_OK;\r
536     uint32         ErrCounter = CAN_TIMEOUT_DURATION;\r
537     uint32         RegBuf;\r
538     \r
539 #if(CAN_DEV_ERROR_DETECT == STD_ON)    \r
540     if(ModuleState == CAN_UNINIT)\r
541     {\r
542         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_UNINIT);\r
543         return CAN_NOT_OK;\r
544     }\r
545     if(Controller >= CAN_CONTROLLER_COUNT)\r
546     {\r
547         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_PARAM_CONTROLLER);\r
548         return CAN_NOT_OK;\r
549     }\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
554     {\r
555         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 3, CAN_E_TRANSITION);\r
556         return CAN_NOT_OK;\r
557     }\r
558 #endif \r
559 \r
560     switch(Transition)\r
561     {\r
562     case CAN_T_START:\r
563         /* Clear Init Bit */\r
564         CanBase[Controller]->CTL  &= ~0x00000001;\r
565         /* Clear Status Register */\r
566         CanBase[Controller]->SR    = 0x0000011F;\r
567 \r
568         ControllerMode[Controller] = CANIF_CS_STARTED;\r
569         Can_EnableControllerInterrupts(Controller);\r
570         break;\r
571 \r
572     case CAN_T_STOP:\r
573         /* Set Init Bit */\r
574         CanBase[Controller]->CTL  |=  0x00000001;\r
575         ControllerMode[Controller] = CANIF_CS_STOPPED;\r
576         Can_DisableControllerInterrupts(Controller);\r
577         break;\r
578 \r
579     case CAN_T_SLEEP:\r
580         /* Set PDR  Bit */\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
588         {\r
589             /* Check if a WakeUp occurs */\r
590             if(CanBase[Controller]->SR & 0x00000200)\r
591             {\r
592                 Status = CAN_NOT_OK;\r
593                 break;\r
594             }\r
595             ErrCounter--;\r
596             if(ErrCounter == 0)\r
597             {\r
598                 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
599                 ErrCounter = CAN_TIMEOUT_DURATION;\r
600                 Status     = CAN_NOT_OK;\r
601                 break;\r
602             }\r
603         }\r
604         /* Reset Control Register */\r
605         CanBase[Controller]->CTL   = RegBuf;\r
606         ControllerMode[Controller] = CANIF_CS_SLEEP;\r
607         break;\r
608 \r
609     case CAN_T_WAKEUP:\r
610         /* Clear PDR Bit */\r
611         CanBase[Controller]->CTL  &= ~0x01000000;\r
612         ControllerMode[Controller] = CANIF_CS_STOPPED;\r
613         break;\r
614 \r
615     default:\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
619         return CAN_NOT_OK;\r
620 #endif\r
621         break;\r
622     }\r
623 \r
624     return Status;\r
625 }\r
626 \r
627 \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
636 /* Remarks:       -/-                                                         */\r
637 /*                                                                            */\r
638 \r
639 void Can_DisableControllerInterrupts(uint8 Controller)\r
640 {\r
641 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
642     if(ModuleState == CAN_UNINIT)\r
643     {\r
644         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_UNINIT);\r
645         return;\r
646     }\r
647     if(Controller >= CAN_CONTROLLER_COUNT)\r
648     {\r
649         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 4, CAN_E_PARAM_CONTROLLER);\r
650         return;\r
651     }\r
652 #endif \r
653     /* Clear IE */\r
654     CanBase[Controller]->CTL &= ~0x00000002;\r
655     /* Increment Disable Counter */\r
656     IntDisableCount[Controller]++;\r
657 }\r
658 \r
659 \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
668 /* Remarks:       -/-                                                         */\r
669 /*                                                                            */\r
670 \r
671 void Can_EnableControllerInterrupts(uint8 Controller)\r
672 {\r
673 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
674     if(ModuleState == CAN_UNINIT)\r
675     {\r
676         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_UNINIT);\r
677         return;\r
678     }\r
679     if(Controller >= CAN_CONTROLLER_COUNT)\r
680     {\r
681         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 5, CAN_E_PARAM_CONTROLLER);\r
682         return;\r
683     }\r
684 #endif    \r
685     if(IntDisableCount[Controller] > 0)\r
686     {\r
687         if(IntDisableCount[Controller] == 1)\r
688         {\r
689             /* Set IE */\r
690             CanBase[Controller]->CTL |= 0x00000002;\r
691         }\r
692         IntDisableCount[Controller]--;\r
693     }\r
694 }\r
695 \r
696 \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
706 /* Remarks:       -/-                                                         */\r
707 /*                                                                            */\r
708 \r
709 void Can_Cbk_CheckWakeup(uint8 Controller)\r
710 {\r
711         /*\r
712 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
713     if(Controller >= CAN_CONTROLLER_COUNT)\r
714     {\r
715         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0x0B, CAN_E_PARAM_CONTROLLER);\r
716         return CAN_NOT_OK;\r
717     }\r
718 #endif\r
719     // Check WakeUpPending\r
720     if(CanBase[Controller]->SR & 0x00000200)\r
721     {\r
722         return E_OK;\r
723     }\r
724     else\r
725     {\r
726         return E_NOT_OK;\r
727     }\r
728     */\r
729 }\r
730 \r
731 \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
743 /* Remarks:       -/-                                                         */\r
744 /*                                                                            */\r
745 \r
746 Can_ReturnType Can_Write(Can_Arc_HTHType Hth, Can_PduType *PduInfo)\r
747 {\r
748     uint32                 ErrCounter;\r
749     uint8                  ControllerId;\r
750     uint8                  MsgNr;\r
751     uint32                 CancelId;\r
752     uint8                  CancelNr;  \r
753     uint32                 ArbRegValue;\r
754     uint8                  DataByteIndex;\r
755     uint8                 *CurSduPtr;\r
756     Can_PduType           *CurPduArrayPtr;\r
757     uint8                 *CurCancelRqstPtr;\r
758     uint8                 *CurTxRqstPtr;\r
759     Can_MessageObjectType *CurMsgBoxPtr;\r
760 \r
761     CurSduPtr       = PduInfo->sdu;\r
762     CurMsgBoxPtr    = CurConfig->MessageBoxPtr + Hth;\r
763     ErrCounter      = CAN_TIMEOUT_DURATION;\r
764     \r
765 /* DET Error Check */\r
766 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
767     if(PduInfo == NULL || PduInfo->sdu == NULL)\r
768     {\r
769         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_POINTER);\r
770         return CAN_NOT_OK;\r
771     }\r
772     if(ModuleState == CAN_UNINIT)\r
773     {\r
774         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_UNINIT);\r
775         return CAN_NOT_OK;\r
776     }\r
777     if(PduInfo->length > 8)\r
778     {\r
779         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_DLC);\r
780         return CAN_NOT_OK;        \r
781     }\r
782     if(CurMsgBoxPtr->Direction != CAN_TRANSMIT)\r
783     {\r
784         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 6, CAN_E_PARAM_HANDLE);\r
785         return CAN_NOT_OK;\r
786     }      \r
787 #endif\r
788 \r
789     ControllerId     = CurMsgBoxPtr->Controller;\r
790     \r
791     MsgNr            = Hth - ControllerConfig[ControllerId].FirstHandle;\r
792 \r
793     CurPduArrayPtr   = ControllerConfig[ControllerId].PduPtr    + MsgNr;\r
794     CurCancelRqstPtr = ControllerConfig[ControllerId].CancelPtr + MsgNr;\r
795     CurTxRqstPtr     = ControllerConfig[ControllerId].TxPtr     + MsgNr;\r
796     \r
797     /* Bring Id Value to appropriate format and set ArbRegValue */\r
798     if(PduInfo->id & 0x80000000)\r
799     {\r
800         /* MsgVal, Ext, Transmit, Extended Id */ \r
801         ArbRegValue = 0xD0000000 | (PduInfo->id & 0x1FFFFFFF);\r
802     }\r
803     else\r
804     {\r
805         /* MsgVal, Std, Transmit, Standard Id */ \r
806         ArbRegValue = 0xA0000000 | ((PduInfo->id & 0x7FF) << 18);\r
807     }\r
808 \r
809     /* Check if TxRqst Bit of MsgObject is set */\r
810     if(CanBase[ControllerId]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F)))\r
811     {\r
812 \r
813 #if(CAN_MULTIPLEXED_TRANSMISSION == STD_ON)\r
814 \r
815         CancelId = ArbRegValue & 0x1FFFFFFF;\r
816         CancelNr = MsgNr;\r
817 \r
818         for(MsgNr = ControllerConfig[ControllerId].MessageBoxCount; MsgNr < ControllerConfig[ControllerId].MaxBoxes; MsgNr++)\r
819         {\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
824             {\r
825                 ErrCounter--;\r
826                 if(ErrCounter == 0)\r
827                 {\r
828                     Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
829                     ErrCounter = CAN_TIMEOUT_DURATION;\r
830                     return CAN_NOT_OK;\r
831                 }\r
832             }\r
833 \r
834             /* If MessageObject is free, use it */\r
835             if(!(CanBase[ControllerId]->IFx[IfRegId].MC & 0x00000100))\r
836             {\r
837                 CurPduArrayPtr   = ControllerConfig[ControllerId].PduPtr + MsgNr;\r
838                 break;\r
839             }\r
840             /* Check if Id of MessageObject is higher */\r
841             if((CanBase[ControllerId]->IFx[IfRegId].ARB & 0x1FFFFFFF) > CancelId )\r
842             {\r
843                 /* Save the highest ID (low priority) */\r
844                 CancelId = CanBase[ControllerId]->IFx[IfRegId].ARB & 0x1FFFFFFF;\r
845                 /* and corresponding message number */\r
846                 CancelNr = MsgNr;\r
847             }\r
848         }\r
849         if(MsgNr == ControllerConfig[ControllerId].MaxBoxes)\r
850         {\r
851 #if(CAN_HW_TRANSMIT_CANCELLATION == STD_ON)\r
852              /* Clear TxRqst */\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
856                         \r
857             if(ControllerConfig[ControllerId].TxProc == INTERRUPT)\r
858             {\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
863                 {\r
864                     ErrCounter--;\r
865                     if(ErrCounter == 0)\r
866                     {\r
867                         Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
868                         ErrCounter = CAN_TIMEOUT_DURATION;\r
869                         return CAN_NOT_OK;\r
870                     }\r
871                 }\r
872                 /* Notification about cancellation of object */\r
873                 CanIf_CancelTxConfirmation((const Can_PduType *)CurPduArrayPtr);\r
874             }\r
875             else\r
876             {\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
881             }\r
882 #endif\r
883         }\r
884 #elif(CAN_HW_TRANSMIT_CANCELLATION == STD_ON)\r
885     \r
886         /* Wait until Busy Flag is 0 */\r
887         while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
888         {\r
889             ErrCounter--;\r
890             if(ErrCounter == 0)\r
891             {\r
892                 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
893                 ErrCounter = CAN_TIMEOUT_DURATION;\r
894                 return CAN_NOT_OK;\r
895             }\r
896         }\r
897 \r
898         /* Read actual MessageObject status: Data, Arbitration, Control */\r
899         CanBase[ControllerId]->IFx[IfRegId].COM = 0x00330000 | (MsgNr + 1);\r
900 \r
901         /* Wait until Busy Flag is 0 */\r
902         while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
903         {\r
904             ErrCounter--;\r
905             if(ErrCounter == 0)\r
906             {\r
907                 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
908                 ErrCounter = CAN_TIMEOUT_DURATION;\r
909                 return CAN_NOT_OK;\r
910             }\r
911         }  \r
912           \r
913         /* Check if actual message has higher priority */\r
914         if((ArbRegValue & 0x1FFFFFFF) < (CanBase[ControllerId]->IFx.ARB & 0x1FFFFFFF))\r
915         {\r
916             /* Clear TxRqst */\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
920             \r
921             if(ControllerConfig[ControllerId].TxProc == INTERRUPT)\r
922             {\r
923                 /* Wait until Busy Flag is 0 */\r
924                 while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
925                 {\r
926                     ErrCounter--;\r
927                     if(ErrCounter == 0)\r
928                     {\r
929                         Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
930                         ErrCounter = CAN_TIMEOUT_DURATION;\r
931                         return CAN_NOT_OK;\r
932                     }\r
933                 } \r
934                 /* Notification about cancellation of object */\r
935                 CanIf_CancelTxConfirmation((const Can_PduType *)CurPduArrayPtr);\r
936             }\r
937             else\r
938             {\r
939                 /* Set Arrayelement to 1 to indicate cancellation request */\r
940                 *CurCancelRqstPtr = 1;\r
941             }\r
942         }\r
943 #endif\r
944         return CAN_BUSY;\r
945     }\r
946 \r
947     /* Wait until Busy Flag is 0 */\r
948     while(CanBase[ControllerId]->IFx[IfRegId].COM & 0x00008000)\r
949     {\r
950         ErrCounter--;\r
951         if(ErrCounter == 0)\r
952         {\r
953             Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
954             ErrCounter = CAN_TIMEOUT_DURATION;\r
955             return CAN_NOT_OK;\r
956         }\r
957     }\r
958 \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
961 \r
962     /* Set ArbitrationRegister */\r
963     CanBase[ControllerId]->IFx[IfRegId].ARB = ArbRegValue;\r
964 \r
965     /* Set Databytes */\r
966     for(DataByteIndex = 0; DataByteIndex < PduInfo->length; DataByteIndex++)\r
967     {\r
968         CanBase[ControllerId]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]] = *CurSduPtr++;\r
969     }\r
970 \r
971     /* Start transmission to MessageRAM */\r
972     CanBase[ControllerId]->IFx[IfRegId].COM = 0x00BF0000 | (MsgNr + 1);\r
973     \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
977     *CurTxRqstPtr   = 1;\r
978     \r
979     IfRegId ^= 1;\r
980        \r
981     return CAN_OK;\r
982 }\r
983 \r
984 \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
991 /* Remarks:       -/-                                                         */\r
992 /*                                                                            */\r
993 \r
994 void CAN_MAINFUNCTION_WRITE()\r
995 {\r
996 #if 0\r
997     uint8        Controller;\r
998     uint8        MsgNr;\r
999     Can_PduType *CurPduPtr;\r
1000 \r
1001 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
1002     if(ModuleState == CAN_UNINIT)\r
1003     {\r
1004         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 1, CAN_E_UNINIT);\r
1005         return;\r
1006     }\r
1007 #endif       \r
1008     /* Check all controllers */\r
1009     for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
1010     {\r
1011         /* Check all MessageObjects */\r
1012         for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MaxBoxes; MsgNr++)\r
1013         {\r
1014             /* Check if a transmission was initiated for this MessageObject */\r
1015             if(*(ControllerConfig[Controller].TxPtr + MsgNr) == 1)\r
1016             {\r
1017                 /* Check if TxRqst Bit has already been reset */\r
1018                 if(!(CanBase[Controller]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))))\r
1019                 {\r
1020                     /* Reset swTxRqst */\r
1021                     *(ControllerConfig[Controller].TxPtr + MsgNr) = 0;\r
1022                     \r
1023                     CurPduPtr = ControllerConfig[Controller].PduPtr + MsgNr;\r
1024                     /* A Message was successfully transmitted */\r
1025                     CanIf_TxConfirmation(CurPduPtr->swPduHandle);\r
1026                 }\r
1027             }\r
1028             /* Check if a cancellation was initiated for this MessageObject */\r
1029             if(*(ControllerConfig[Controller].CancelPtr + MsgNr) == 1)\r
1030             {\r
1031                 /* Check if TxRqst Bit has already been reset */\r
1032                 if(!(CanBase[Controller]->TRx[MsgNr >> 5] & (1 << (MsgNr & 0x1F))))\r
1033                 {\r
1034                     /* Reset swCancelRqst */\r
1035                     *(ControllerConfig[Controller].CancelPtr + MsgNr) = 0;\r
1036                     \r
1037                     CurPduPtr = ControllerConfig[Controller].PduPtr + MsgNr;\r
1038                     /* A Message was successfully transmitted */\r
1039                      CanIf_CancelTxConfirmation(CurPduPtr);     \r
1040                 }\r
1041             }\r
1042         }\r
1043     }\r
1044 #endif\r
1045 }\r
1046 \r
1047 \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
1055 /*                                                                            */\r
1056 \r
1057 void CAN_MAINFUNCTION_READ()\r
1058 {\r
1059 #if 0\r
1060     uint8                  Controller;\r
1061     uint8                  MsgNr;\r
1062     Can_MessageObjectType *CurMsgBoxPtr;\r
1063     uint8                  MsgDlc;\r
1064     uint32                 Identifier;\r
1065     uint8                  DataByteIndex;\r
1066     uint8                 *SduPtr;\r
1067     uint32                 ErrCounter;    \r
1068    \r
1069 \r
1070 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
1071     if(ModuleState == CAN_UNINIT)\r
1072     {\r
1073         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 8, CAN_E_UNINIT);\r
1074         return;\r
1075     }\r
1076 #endif\r
1077 \r
1078     CurMsgBoxPtr = CurConfig->MessageBoxPtr;\r
1079     \r
1080     for(Controller = 0; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
1081     {\r
1082         for(MsgNr = 0; MsgNr < ControllerConfig[Controller].MessageBoxCount; MsgNr++)\r
1083         {\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
1086             {\r
1087             \r
1088                 /* Read Arbitration, Control and Data Bits and clear IntPnd and NewDat*/\r
1089                 CanBase[Controller]->IFx[IfRegId].COM = 0x003F0000 | (MsgNr + 1);\r
1090                 \r
1091                 ErrCounter = CAN_TIMEOUT_DURATION;\r
1092                 /* Wait until Busy Flag is 0 */\r
1093                 while(CanBase[Controller]->IFx[IfRegId].COM & 0x8000)\r
1094                 {\r
1095                     ErrCounter--;\r
1096                     if(ErrCounter == 0)\r
1097                     {\r
1098                         Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
1099                         return;\r
1100                     }\r
1101                 }\r
1102                 /* Extended Id */\r
1103                 if(CanBase[0]->IFx[IfRegId].ARB & 0x40000000)\r
1104                 {\r
1105                     /* Bring Id to standardized format (MSB marks extended Id) */\r
1106                     Identifier = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;\r
1107                 }\r
1108                 /* Standard Id */\r
1109                 else\r
1110                 {\r
1111                     /* Bring Id to standardized format (MSB marks extended Id) */\r
1112                     Identifier = (CanBase[0]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;\r
1113                 }\r
1114                 /* DLC (Max 8) */\r
1115                 MsgDlc = CanBase[0]->IFx[IfRegId].MC & 0x000F;\r
1116                 if(MsgDlc > 8)\r
1117                 {\r
1118                     MsgDlc = 8;\r
1119                 }\r
1120                 /* Let SduPtr point to Shadow Buffer */\r
1121                 SduPtr = RxShadowBuf;\r
1122 \r
1123                 /* Copy Message Data to Shadow Buffer */\r
1124                 for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
1125                 {\r
1126                     RxShadowBuf[DataByteIndex] = CanBase[0]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
1127                 }\r
1128                 /* Indicate successful Reception */\r
1129                 CanIf_RxIndication(MsgNr, Identifier, MsgDlc, SduPtr);\r
1130             }     \r
1131             CurMsgBoxPtr++;\r
1132         }\r
1133     }\r
1134 #endif\r
1135 }\r
1136 \r
1137 \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
1145 /*                                                                            */\r
1146 \r
1147 void CAN_MAINFUNCTION_BUSOFF()\r
1148 {\r
1149     uint8  Controller;\r
1150 \r
1151 /* DET Error Check */\r
1152 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
1153     if(ModuleState == CAN_UNINIT)\r
1154     {\r
1155         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 9, CAN_E_UNINIT);\r
1156         return;\r
1157     }    \r
1158 #endif\r
1159     \r
1160     for(Controller = 0 ; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
1161     {\r
1162         /* Bus Off */\r
1163         if(CanBase[Controller]->SR & 0x00000080)\r
1164         {\r
1165 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
1166             ControllerMode[Controller] = CANIF_CS_STOPPED;\r
1167 #endif\r
1168             CanIf_ControllerBusOff(Controller);\r
1169         }\r
1170     }\r
1171 }\r
1172 \r
1173 \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
1181 /*                                                                            */\r
1182 \r
1183 void CAN_MAINFUNCTION_WAKEUP()\r
1184 {\r
1185     uint8 Controller;\r
1186 \r
1187 /* DET Error Check */\r
1188 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
1189     if(ModuleState == CAN_UNINIT)\r
1190     {\r
1191         Det_ReportError(CAN_MODULE_ID, CAN_INSTANCE, 0xA, CAN_E_UNINIT);\r
1192         return;\r
1193     }    \r
1194 #endif\r
1195 \r
1196     for(Controller = 0 ; Controller < CAN_CONTROLLER_COUNT; Controller++)\r
1197     {\r
1198         /* Check WakeUp Pending */\r
1199         if(CanBase[Controller]->SR & 0x200)\r
1200         {\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
1205 #endif\r
1206             //EcuM_CheckWakeUp(ControllerConfig[Controller].WakeupSrc);\r
1207         }\r
1208     }\r
1209 }\r
1210 \r
1211 \r
1212 \r
1213 \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
1219 /*                                                                            */\r
1220 #ifdef CanController_1\r
1221 //#pragma INTERRUPT(CAN2_INTERRUPTHANDLER_0,IRQ)\r
1222 \r
1223 void CAN2_INTERRUPTHANDLER_0()\r
1224 {\r
1225 \r
1226     uint32  ErrCounter;\r
1227     uint32  MsgNr;\r
1228     uint32  MsgId;\r
1229     uint8   MsgDlc;\r
1230     uint8   DataByteIndex;\r
1231     uint8  *SduPtr; \r
1232 \r
1233     ErrCounter = CAN_TIMEOUT_DURATION;\r
1234     \r
1235     if(CanBase[1]->IR == 0x8000)\r
1236     {\r
1237         /* WakeUp Pending */\r
1238         if(CanBase[1]->SR & 0x200)\r
1239         {\r
1240 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
1241             ControllerMode[1] = CANIF_CS_STOPPED;\r
1242 #endif\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
1246         }\r
1247         /* Bus Off */\r
1248         if(CanBase[1]->SR & 0x080)\r
1249         {\r
1250 #if(CAN_DEV_ERROR_DETECT == STD_ON)\r
1251             ControllerMode[1] = CANIF_CS_STOPPED;\r
1252 #endif\r
1253             CanIf_ControllerBusOff(1);\r
1254         }\r
1255     }\r
1256     else\r
1257     {\r
1258         MsgNr = CanBase[1]->IR;\r
1259         \r
1260         /* Read Arbitration, Control and Data Bits and clear IntPnd */\r
1261         CanBase[1]->IFx[IfRegId].COM = 0x003F0000 | MsgNr;\r
1262         \r
1263         /* Wait until Busy Flag is 0 */\r
1264         while(CanBase[1]->IFx[IfRegId].COM & 0x8000)\r
1265         {\r
1266             ErrCounter--;\r
1267             if(ErrCounter == 0)\r
1268             {\r
1269                 Dem_ReportErrorStatus(CAN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);\r
1270                 ErrCounter = CAN_TIMEOUT_DURATION;\r
1271                 return;\r
1272             }\r
1273         }\r
1274         \r
1275         /* Transmit Object */\r
1276         if(CanBase[1]->IFx[IfRegId].ARB & 0x20000000)\r
1277         {\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
1282         }        \r
1283         /* Receive Object */\r
1284         else\r
1285         {\r
1286             /* Extended Id */\r
1287             if(CanBase[1]->IFx[IfRegId].ARB & 0x40000000)\r
1288             {\r
1289                 /* Bring Id to standardized format (MSB marks extended Id) */\r
1290                 MsgId = (CanBase[1]->IFx[IfRegId].ARB & 0x1FFFFFFF) | 0x80000000;\r
1291             }\r
1292             /* Standard Id */\r
1293             else\r
1294             {\r
1295                 /* Bring Id to standardized format (MSB marks extended Id) */\r
1296                 MsgId = (CanBase[1]->IFx[IfRegId].ARB & 0x1FFC0000) >> 18;\r
1297             }\r
1298             /* DLC (Max 8) */\r
1299             MsgDlc = CanBase[1]->IFx[IfRegId].MC & 0x000F;\r
1300             if(MsgDlc > 8)\r
1301             {\r
1302                 MsgDlc = 8;\r
1303             }\r
1304             /* Let SduPtr point to Shadow Buffer */\r
1305             SduPtr = RxShadowBuf;\r
1306 \r
1307             /* Copy Message Data to Shadow Buffer */\r
1308             for(DataByteIndex = 0; DataByteIndex < MsgDlc; DataByteIndex++)\r
1309             {\r
1310                 RxShadowBuf[DataByteIndex] = CanBase[1]->IFx[IfRegId].DATx[ElementIndex[DataByteIndex]];\r
1311             }\r
1312             /* Indicate successful Reception */\r
1313             CanIf_RxIndication(MsgNr - 1, MsgId, MsgDlc, SduPtr);\r
1314         }\r
1315     }\r
1316 \r
1317 }\r
1318 #endif\r