]> rtime.felk.cvut.cz Git - arc.git/blob - arch/hc1x/hcs12d/drivers/Can.c
7c8720043a00bfaa754f757bc63afdd30c0c3f58
[arc.git] / arch / hc1x / hcs12d / drivers / Can.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 \r
18 \r
19 \r
20 \r
21 \r
22 \r
23 #include "Can.h"\r
24 \r
25 #ifndef USE_CAN_STUB\r
26 #include "regs.h"\r
27 #include "Cpu.h"\r
28 #include "Mcu.h"\r
29 #include "CanIf_Cbk.h"\r
30 #include "Det.h"\r
31 #if defined(USE_DEM)\r
32 #include "Dem.h"\r
33 #endif\r
34 #include <assert.h>\r
35 #include <stdlib.h>\r
36 #include <string.h>\r
37 #include "Os.h"\r
38 #include "isr.h"\r
39 #include "arc.h"\r
40 \r
41 #define USE_CAN_STATISTICS      STD_OFF\r
42 \r
43 // bits in CANxCTL0:\r
44 #define BM_INITRQ       0x01\r
45 #define BM_SLPRQ        0x02\r
46 #define BM_WUPE         0x04\r
47 \r
48 // bits in CANxCTL1:\r
49 #define BM_INITAK       0x01\r
50 #define BM_SLPAK        0x02\r
51 #define BM_WUPM         0x04\r
52 #define BM_LISTEN       0x10\r
53 #define BM_LOOPB        0x20\r
54 #define BM_CLKSRC       0x40\r
55 #define BM_CANE         0x80\r
56 \r
57 // bits in CANxRFLG:\r
58 // bits in CANxRIER:\r
59 #define BM_WUPI         0x80\r
60 #define BM_CSCI         0x40\r
61 #define BM_RSTAT1       0x20\r
62 #define BM_RSTAT0       0x10\r
63 #define BM_TSTAT1       0x08\r
64 #define BM_TSTAT0       0x04\r
65 #define BM_OVRI         0x02\r
66 #define BM_RXF          0x01\r
67 \r
68 // bits in CANxTFLG:\r
69 // bits in CANxTBSEL:\r
70 #define BM_TX2          0x04\r
71 #define BM_TX1          0x02\r
72 #define BM_TX0          0x01\r
73 \r
74 typedef struct{\r
75         volatile uint8_t   idr0; // Identifier Register 0\r
76         volatile uint8_t   idr1;\r
77         volatile uint8_t   idr2;\r
78         volatile uint8_t   idr3;\r
79         volatile uint8_t   ds0; // Data Segment Register 0\r
80         volatile uint8_t   ds1;\r
81         volatile uint8_t   ds2;\r
82         volatile uint8_t   ds3;\r
83         volatile uint8_t   ds4;\r
84         volatile uint8_t   ds5;\r
85         volatile uint8_t   ds6;\r
86         volatile uint8_t   ds7;\r
87         volatile uint8_t   dlr;  // Data Length Register\r
88         volatile uint8_t   tbpr; // Transmit Buffer Priority Register\r
89         volatile uint8_t   tsr_hb; // Time Stamp Register (High Byte)\r
90         volatile uint8_t   tsr_lb; // Time Stamp Register (Low Byte)\r
91 } RxTxBuf_t;\r
92 \r
93 /*\r
94 IDR0 : ID28 ID27 ID26 ID25 ID24 ID23 ID22 ID21\r
95 IDR1 : ID20 ID19 ID18 SRR  IDE  ID17 ID16 ID15\r
96 IDR2 : ID14 ID13 ID12 ID11 ID10 ID9  ID8  ID7\r
97 IDR3 : ID6  ID5  ID4  ID3  ID2  ID1  ID0  RTR\r
98 */\r
99 typedef union {\r
100         volatile uint8_t R[4];\r
101     struct {\r
102                 volatile uint8_t id28to21;\r
103                 volatile uint8_t id20to18:3;\r
104                 volatile uint8_t SRR:1;\r
105                 volatile uint8_t IDE:1;\r
106                 volatile uint8_t id17to15:3;\r
107                 volatile uint8_t id14to7;\r
108                 volatile uint8_t id6to0:7;\r
109                 volatile uint8_t RTR:1;\r
110     } Bit;\r
111 } IdrType;\r
112 \r
113 \r
114 typedef struct{\r
115         volatile uint8_t   CTL0; /*   control register 0 */\r
116         volatile uint8_t   CTL1; /*   control register 1 */\r
117         volatile uint8_t   BTR0; /*   bus timing register 0 */\r
118         volatile uint8_t   BTR1; /*   bus timing register 1 */\r
119         volatile uint8_t   RFLG; /*   receiver flag register */\r
120         volatile uint8_t   RIER; /*   receiver interrupt reg */\r
121         volatile uint8_t   TFLG; /*   transmitter flag reg */\r
122         volatile uint8_t   TIER; /*   transmitter control reg */\r
123         volatile uint8_t   TARQ; /*   transmitter abort request */\r
124         volatile uint8_t   TAAK; /*   transmitter abort acknowledge */\r
125         volatile uint8_t   TBSEL; /*   transmit buffer selection */\r
126         volatile uint8_t   IDAC; /*   identifier acceptance */\r
127         volatile uint8_t   NOTUSED1;\r
128         volatile uint8_t   NOTUSED2;\r
129         volatile uint8_t   RXERR; /*   receive error counter */\r
130         volatile uint8_t   TXERR; /*   transmit error counter */\r
131         volatile uint8_t   IDAR0; /*   id acceptance reg 0 */\r
132         volatile uint8_t   IDAR1; /*   id acceptance reg 1 */\r
133         volatile uint8_t   IDAR2; /*   id acceptance reg 2 */\r
134         volatile uint8_t   IDAR3; /*   id acceptance reg 3 */\r
135         volatile uint8_t   IDMR0; /*   id mask register 0 */\r
136         volatile uint8_t   IDMR1; /*   id mask register 1 */\r
137         volatile uint8_t   IDMR2; /*   id mask register 2 */\r
138         volatile uint8_t   IDMR3; /*   id mask register 3 */\r
139         volatile uint8_t   IDAR4; /*   id acceptance reg 4 */\r
140         volatile uint8_t   IDAR5; /*   id acceptance reg 5 */\r
141         volatile uint8_t   IDAR6; /*   id acceptance reg 6 */\r
142         volatile uint8_t   IDAR7; /*   id acceptance reg 7 */\r
143         volatile uint8_t   IDMR4; /*   id mask register 4 */\r
144         volatile uint8_t   IDMR5; /*   id mask register 5 */\r
145         volatile uint8_t   IDMR6; /*   id mask register 6 */\r
146         volatile uint8_t   IDMR7; /*   id mask register 7 */\r
147         volatile RxTxBuf_t   RXFG; /*   receive buffer */\r
148         volatile RxTxBuf_t   TXFG; /*   transmit buffer */\r
149 } CAN_HW_t;\r
150 \r
151 /* CONFIGURATION NOTES\r
152  * ------------------------------------------------------------------\r
153  * - CanHandleType must be CAN_ARC_HANDLE_TYPE_BASIC\r
154  *   i.e. CanHandleType=CAN_ARC_HANDLE_TYPE_FULL NOT supported\r
155  *   i.e CanIdValue is NOT supported\r
156  * - All CanXXXProcessing must be CAN_ARC_PROCESS_TYPE_INTERRUPT\r
157  *   ie CAN_ARC_PROCESS_TYPE_POLLED not supported\r
158  * - HOH's for Tx are global and Rx are for each controller\r
159  */\r
160 \r
161 /* IMPLEMENTATION NOTES\r
162  * -----------------------------------------------\r
163  * - A HOH us unique for a controller( not a config-set )\r
164  * - Hrh's are numbered for each controller from 0\r
165  * - Only one transmit mailbox is used because otherwise\r
166  *   we cannot use tx_confirmation since there is no way to know\r
167  *   which mailbox caused the tx interrupt. TP will need this feature.\r
168  * - Sleep,wakeup not fully implemented since other modules lack functionality\r
169  */\r
170 \r
171 /* ABBREVATIONS\r
172  *  -----------------------------------------------\r
173  * - Can Hardware unit - One or multiple Can controllers of the same type.\r
174  * - Hrh - HOH with receive definitions\r
175  * - Hth - HOH with transmit definitions\r
176  *\r
177  */\r
178 \r
179 //-------------------------------------------------------------------\r
180 \r
181 #define GET_CONTROLLER_CONFIG(_controller)      \\r
182                                                 &Can_Global.config->CanConfigSet->CanController[(_controller)]\r
183 \r
184 #define GET_CALLBACKS() \\r
185                                                         (Can_Global.config->CanConfigSet->CanCallbacks)\r
186 \r
187 #define GET_PRIVATE_DATA(_controller) \\r
188                                                                         &CanUnit[_controller]\r
189 \r
190 #define GET_CONTROLLER_CNT() (CAN_CONTROLLER_CNT)\r
191 \r
192 //-------------------------------------------------------------------\r
193 \r
194 #if ( CAN_DEV_ERROR_DETECT == STD_ON )\r
195 #define VALIDATE(_exp,_api,_err ) \\r
196         if( !(_exp) ) { \\r
197           Det_ReportError(MODULE_ID_CAN,0,_api,_err); \\r
198           return CAN_NOT_OK; \\r
199         }\r
200 \r
201 #define VALIDATE_NO_RV(_exp,_api,_err ) \\r
202         if( !(_exp) ) { \\r
203           Det_ReportError(MODULE_ID_CAN,0,_api,_err); \\r
204           return; \\r
205         }\r
206 \r
207 #define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)\r
208 #else\r
209 #define VALIDATE(_exp,_api,_err )\r
210 #define VALIDATE_NO_RV(_exp,_api,_err )\r
211 #define DET_REPORTERROR(_x,_y,_z,_q)\r
212 #endif\r
213 \r
214 #if defined(USE_DEM)\r
215 #define VALIDATE_DEM_NO_RV(_exp,_err ) \\r
216         if( !(_exp) ) { \\r
217           Dem_ReportErrorStatus(_err, DEM_EVENT_STATUS_FAILED); \\r
218           return; \\r
219         }\r
220 #else\r
221 #define VALIDATE_DEM_NO_RV(_exp,_err )\r
222 #endif\r
223 \r
224 //-------------------------------------------------------------------\r
225 \r
226 typedef enum\r
227 {\r
228   CAN_UNINIT = 0,\r
229   CAN_READY\r
230 } Can_DriverStateType;\r
231 \r
232 // Mapping between HRH and Controller//HOH\r
233 typedef struct Can_Arc_ObjectHOHMapStruct\r
234 {\r
235   CanControllerIdType CanControllerRef;    // Reference to controller\r
236   const Can_HardwareObjectType* CanHOHRef;       // Reference to HOH.\r
237 } Can_Arc_ObjectHOHMapType;\r
238 \r
239 /* Type for holding global information used by the driver */\r
240 typedef struct {\r
241   Can_DriverStateType initRun;\r
242 \r
243   // Our config\r
244   const Can_ConfigType *config;\r
245 \r
246   // One bit for each channel that is configured.\r
247   // Used to determine if validity of a channel\r
248   // 1 - configured\r
249   // 0 - NOT configured\r
250   uint32  configured;\r
251   // Maps the a channel id to a configured channel id\r
252   uint8   channelMap[CAN_CONTROLLER_CNT];\r
253 \r
254   // This is a map that maps the HTH:s with the controller and Hoh. It is built\r
255   // during Can_Init and is used to make things faster during a transmit.\r
256   Can_Arc_ObjectHOHMapType CanHTHMap[NUM_OF_HTHS];\r
257 } Can_GlobalType;\r
258 \r
259 // Global config\r
260 Can_GlobalType Can_Global =\r
261 {\r
262   .initRun = CAN_UNINIT,\r
263 };\r
264 \r
265 /* Type for holding information about each controller */\r
266 typedef struct {\r
267   CanIf_ControllerModeType state;\r
268   uint8         lock_cnt;\r
269 \r
270   // Statistics\r
271 #if (USE_CAN_STATISTICS == STD_ON)\r
272     Can_Arc_StatisticsType stats;\r
273 #endif\r
274 \r
275   // Data stored for Txconfirmation callbacks to CanIf\r
276   PduIdType swPduHandle; //\r
277 } Can_UnitType;\r
278 \r
279 Can_UnitType CanUnit[CAN_CONTROLLER_CNT] =\r
280 {\r
281   {\r
282     .state = CANIF_CS_UNINIT,\r
283   },{\r
284     .state = CANIF_CS_UNINIT,\r
285   },{\r
286     .state = CANIF_CS_UNINIT,\r
287   },{\r
288     .state = CANIF_CS_UNINIT,\r
289   },{\r
290     .state = CANIF_CS_UNINIT,\r
291   },\r
292 };\r
293 \r
294 //-------------------------------------------------------------------\r
295 \r
296 static CAN_HW_t * GetController(int unit)\r
297 {\r
298         CAN_HW_t *res = 0;\r
299 \r
300         if(unit == CAN_CTRL_0)\r
301         {\r
302                 res = (CAN_HW_t *)CAN0_BASE;\r
303         }\r
304         else if(unit == CAN_CTRL_1)\r
305         {\r
306                 res = (CAN_HW_t *)CAN1_BASE;\r
307         }\r
308         else if(unit == CAN_CTRL_2)\r
309         {\r
310                 res = (CAN_HW_t *)CAN2_BASE;\r
311         }\r
312         else if(unit == CAN_CTRL_3)\r
313         {\r
314                 res = (CAN_HW_t *)CAN3_BASE;\r
315         }\r
316         else if(unit == CAN_CTRL_4)\r
317         {\r
318                 res = (CAN_HW_t *)CAN4_BASE;\r
319         }\r
320 \r
321         return res;\r
322 }\r
323 \r
324 //-------------------------------------------------------------------\r
325 /**\r
326  * Function that finds the Hoh( HardwareObjectHandle ) from a Hth\r
327  * A HTH may connect to one or several HOH's. Just find the first one.\r
328  *\r
329  * @param hth The transmit handle\r
330  * @returns Ptr to the Hoh\r
331  */\r
332 static const Can_HardwareObjectType * Can_FindHoh( Can_Arc_HTHType hth , uint32* controller)\r
333 {\r
334   const Can_HardwareObjectType *hohObj;\r
335   const Can_Arc_ObjectHOHMapType *map;\r
336   const Can_ControllerConfigType *canHwConfig;\r
337 \r
338   map = &Can_Global.CanHTHMap[hth];\r
339 \r
340   // Verify that this is the correct map\r
341   if (map->CanHOHRef->CanObjectId != hth)\r
342   {\r
343     DET_REPORTERROR(MODULE_ID_CAN, 0, 0x6, CAN_E_PARAM_HANDLE);\r
344   }\r
345 \r
346   canHwConfig= GET_CONTROLLER_CONFIG(Can_Global.channelMap[map->CanControllerRef]);\r
347 \r
348   hohObj = map->CanHOHRef;\r
349 \r
350   // Verify that this is the correct Hoh type\r
351   if ( hohObj->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)\r
352   {\r
353     *controller = map->CanControllerRef;\r
354     return hohObj;\r
355   }\r
356 \r
357   DET_REPORTERROR(MODULE_ID_CAN, 0, 0x6, CAN_E_PARAM_HANDLE);\r
358 \r
359   return NULL;\r
360 }\r
361 \r
362 //-------------------------------------------------------------------\r
363 \r
364 static void Can_RxIsr( int unit );\r
365 static void Can_TxIsr( int unit );\r
366 static void Can_ErrIsr( int unit );\r
367 static void Can_WakeIsr( int unit );\r
368 \r
369 void Can_0_RxIsr( void  ) {     Can_RxIsr(CAN_CTRL_0); }\r
370 void Can_1_RxIsr( void  ) {     Can_RxIsr(CAN_CTRL_1); }\r
371 void Can_2_RxIsr( void  ) {     Can_RxIsr(CAN_CTRL_2); }\r
372 void Can_3_RxIsr( void  ) {     Can_RxIsr(CAN_CTRL_3); }\r
373 void Can_4_RxIsr( void  ) {     Can_RxIsr(CAN_CTRL_4); }\r
374 \r
375 void Can_0_TxIsr( void  ) {     Can_TxIsr(CAN_CTRL_0); }\r
376 void Can_1_TxIsr( void  ) {     Can_TxIsr(CAN_CTRL_1); }\r
377 void Can_2_TxIsr( void  ) {     Can_TxIsr(CAN_CTRL_2); }\r
378 void Can_3_TxIsr( void  ) {     Can_TxIsr(CAN_CTRL_3); }\r
379 void Can_4_TxIsr( void  ) {     Can_TxIsr(CAN_CTRL_4); }\r
380 \r
381 void Can_0_ErrIsr( void  ) {    Can_ErrIsr(CAN_CTRL_0); }\r
382 void Can_1_ErrIsr( void  ) {    Can_ErrIsr(CAN_CTRL_1); }\r
383 void Can_2_ErrIsr( void  ) {    Can_ErrIsr(CAN_CTRL_2); }\r
384 void Can_3_ErrIsr( void  ) {    Can_ErrIsr(CAN_CTRL_3); }\r
385 void Can_4_ErrIsr( void  ) {    Can_ErrIsr(CAN_CTRL_4); }\r
386 \r
387 void Can_0_WakeIsr( void  ) {   Can_WakeIsr(CAN_CTRL_0); }\r
388 void Can_1_WakeIsr( void  ) {   Can_WakeIsr(CAN_CTRL_1); }\r
389 void Can_2_WakeIsr( void  ) {   Can_WakeIsr(CAN_CTRL_2); }\r
390 void Can_3_WakeIsr( void  ) {   Can_WakeIsr(CAN_CTRL_3); }\r
391 void Can_4_WakeIsr( void  ) {   Can_WakeIsr(CAN_CTRL_4); }\r
392 \r
393 //-------------------------------------------------------------------\r
394 \r
395 // Uses 25.4.5.1 Transmission Abort Mechanism\r
396 static void Can_AbortTx( CAN_HW_t *canHw, Can_UnitType *canUnit ) {\r
397         uint8_t mask = 0;\r
398 \r
399         // Disable Transmit irq\r
400         canHw->TIER = 0;\r
401 \r
402         // check if mb's empty\r
403         if((canHw->TFLG & BM_TX0) == 0){mask |= BM_TX0;}\r
404         if((canHw->TFLG & BM_TX1) == 0){mask |= BM_TX1;}\r
405         if((canHw->TFLG & BM_TX2) == 0){mask |= BM_TX2;}\r
406 \r
407         canHw->TARQ = mask; // Abort all pending mb's\r
408 \r
409         // Wait for mb's being emptied\r
410         int i=0;\r
411         while(canHw->TFLG != (BM_TX0 | BM_TX1 | BM_TX2)){\r
412                 i++;\r
413                 if(i > 100)\r
414                 {\r
415                         break;\r
416                 }\r
417         }\r
418 }\r
419 \r
420 /**\r
421  * Hardware wake ISR for CAN\r
422  *\r
423  * @param unit CAN controller number( from 0 )\r
424  */\r
425 static void Can_WakeIsr( int unit ) {\r
426         if (GET_CALLBACKS()->ControllerWakeup != NULL)\r
427         {\r
428                 GET_CALLBACKS()->ControllerWakeup(unit);\r
429         }\r
430         // 269,270,271\r
431         Can_SetControllerMode(unit, CAN_T_STOP);\r
432 \r
433         // TODO EcuM_CheckWakeup();\r
434 }\r
435 \r
436 /**\r
437  * Hardware error ISR for CAN\r
438  *\r
439  * @param unit CAN controller number( from 0 )\r
440  */\r
441 static void Can_ErrIsr( int unit ) {\r
442   CAN_HW_t *canHw = GetController(unit);\r
443   Can_UnitType *canUnit = GET_PRIVATE_DATA(unit);\r
444   Can_Arc_ErrorType err;\r
445   err.R = 0;\r
446   uint8_t rflg = canHw->RFLG;\r
447 \r
448   if((rflg & BM_OVRI) == BM_OVRI){\r
449     err.B.FRMERR = 1;\r
450 \r
451     // Clear ERRINT\r
452     canHw->RFLG = BM_OVRI;\r
453   }\r
454 \r
455   if((rflg & BM_CSCI) == BM_CSCI){\r
456     if( ((rflg & (BM_RSTAT0 | BM_RSTAT0)) == (BM_RSTAT0 | BM_RSTAT1)) ||\r
457         ((rflg & (BM_TSTAT0 | BM_TSTAT0)) == (BM_TSTAT0 | BM_TSTAT1)) )\r
458     {\r
459 #if (USE_CAN_STATISTICS == STD_ON)\r
460         canUnit->stats.boffCnt++;\r
461 #endif\r
462       if (GET_CALLBACKS()->ControllerBusOff != NULL)\r
463       {\r
464         GET_CALLBACKS()->ControllerBusOff(unit);\r
465       }\r
466         Can_SetControllerMode(unit, CAN_T_STOP); // CANIF272\r
467 \r
468         Can_AbortTx( canHw, canUnit ); // CANIF273\r
469       }\r
470 \r
471       // Clear ERRINT\r
472       canHw->RFLG = BM_CSCI;\r
473   }\r
474 \r
475   if (err.R != 0)\r
476   {\r
477     if (GET_CALLBACKS()->Arc_Error != NULL)\r
478     {\r
479       GET_CALLBACKS()->Arc_Error( unit, err );\r
480     }\r
481   }\r
482 }\r
483 \r
484 //-------------------------------------------------------------------\r
485 \r
486 /**\r
487  * ISR for CAN. Normal Rx/operation\r
488  *\r
489  * @param unit CAN controller number( from 0 )\r
490  */\r
491 static void Can_RxIsr(int unit) {\r
492 \r
493   CAN_HW_t *canHw= GetController(unit);\r
494   const Can_ControllerConfigType *canHwConfig= GET_CONTROLLER_CONFIG(Can_Global.channelMap[unit]);\r
495 #if (USE_CAN_STATISTICS == STD_ON)\r
496   Can_UnitType *canUnit = GET_PRIVATE_DATA(unit);\r
497 #endif\r
498   const Can_HardwareObjectType *hohObj;\r
499 \r
500   // Loop over all the Hoh's\r
501   hohObj= canHwConfig->Can_Arc_Hoh;\r
502   --hohObj;\r
503   do {\r
504     ++hohObj;\r
505 \r
506     if (hohObj->CanObjectType == CAN_OBJECT_TYPE_RECEIVE)\r
507     {\r
508         Can_IdType id=0;\r
509         IdrType *idr;\r
510         idr = (IdrType *)&canHw->RXFG.idr0;\r
511 \r
512         // According to autosar MSB shuould be set if extended\r
513         if (idr->Bit.IDE == 1) {\r
514           id = ((uint32)idr->Bit.id28to21 << 21) | ((uint32)idr->Bit.id20to18 << 18) | ((uint32)idr->Bit.id17to15 << 15) |\r
515                 ((uint32)idr->Bit.id14to7 << 7) | idr->Bit.id6to0;\r
516           id |= 0x80000000;\r
517         } else {\r
518           id = ((uint32)idr->Bit.id28to21 << 3) | (uint32)idr->Bit.id20to18;\r
519         }\r
520 \r
521         if (GET_CALLBACKS()->RxIndication != NULL)\r
522         {\r
523           GET_CALLBACKS()->RxIndication(hohObj->CanObjectId,\r
524                                         id,\r
525                                         canHw->RXFG.dlr & 0x0f,\r
526                                         (uint8 *)&canHw->RXFG.ds0 ); // Next layer will copy\r
527         }\r
528 #if (USE_CAN_STATISTICS == STD_ON)\r
529         // Increment statistics\r
530         canUnit->stats.rxSuccessCnt++;\r
531 #endif\r
532 \r
533         // Clear interrupt\r
534         canHw->RFLG = BM_RXF;                                   // clear RX flag\r
535     }\r
536   } while ( !hohObj->Can_Arc_EOL);\r
537 }\r
538 \r
539 /**\r
540  * ISR for CAN. Normal Tx operation\r
541  *\r
542  * @param unit CAN controller number( from 0 )\r
543  */\r
544 static void Can_TxIsr(int unit) {\r
545   CAN_HW_t *canHw= GetController(unit);\r
546   const Can_ControllerConfigType *canHwConfig= GET_CONTROLLER_CONFIG(Can_Global.channelMap[unit]);\r
547   Can_UnitType *canUnit = GET_PRIVATE_DATA(unit);\r
548   const Can_HardwareObjectType *hohObj;\r
549 \r
550   // Loop over all the Hoh's\r
551   hohObj= canHwConfig->Can_Arc_Hoh;\r
552   --hohObj;\r
553   do {\r
554     ++hohObj;\r
555 \r
556     if (hohObj->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)\r
557     {\r
558         if (GET_CALLBACKS()->TxConfirmation != NULL)\r
559         {\r
560           GET_CALLBACKS()->TxConfirmation(canUnit->swPduHandle);\r
561         }\r
562         canUnit->swPduHandle = 0;  // Is this really necessary ??\r
563 \r
564         // Disable Tx interrupt\r
565         canHw->TIER = 0;\r
566     }\r
567   } while ( !hohObj->Can_Arc_EOL);\r
568 }\r
569 \r
570 //-------------------------------------------------------------------\r
571 \r
572 #define INSTALL_HANDLERS(_can_name,_err,_wake,_rx,_tx) \\r
573   do { \\r
574     ISR_INSTALL_ISR2("Can",_can_name ## _ErrIsr,_err,2,0); \\r
575         ISR_INSTALL_ISR2("Can",_can_name ## _WakeIsr,_wake,2,0); \\r
576         ISR_INSTALL_ISR2("Can",_can_name ## _RxIsr,_rx,2,0); \\r
577         ISR_INSTALL_ISR2("Can",_can_name ## _TxIsr,_tx,2,0); \\r
578   } while(0);\r
579 \r
580 // This initiates ALL can controllers\r
581 void Can_Init( const Can_ConfigType *config ) {\r
582   Can_UnitType *canUnit;\r
583   const Can_ControllerConfigType *canHwConfig;\r
584   uint8 ctlrId;\r
585 \r
586   VALIDATE_NO_RV( (Can_Global.initRun == CAN_UNINIT), 0x0, CAN_E_TRANSITION );\r
587   VALIDATE_NO_RV( (config != NULL ), 0x0, CAN_E_PARAM_POINTER );\r
588 \r
589   // Save config\r
590   Can_Global.config = config;\r
591   Can_Global.initRun = CAN_READY;\r
592 \r
593   for (int configId=0; configId < CAN_ARC_CTRL_CONFIG_CNT; configId++) {\r
594     canHwConfig = GET_CONTROLLER_CONFIG(configId);\r
595     ctlrId = canHwConfig->CanControllerId;\r
596 \r
597     // Assign the configuration channel used later..\r
598     Can_Global.channelMap[canHwConfig->CanControllerId] = configId;\r
599     Can_Global.configured |= (1<<ctlrId);\r
600 \r
601     canUnit = GET_PRIVATE_DATA(ctlrId);\r
602     canUnit->state = CANIF_CS_STOPPED;\r
603 \r
604     canUnit->lock_cnt = 0;\r
605 \r
606     // Clear stats\r
607 #if (USE_CAN_STATISTICS == STD_ON)\r
608     memset(&canUnit->stats, 0, sizeof(Can_Arc_StatisticsType));\r
609 #endif\r
610 \r
611     // Note!\r
612     // Could install handlers depending on HW objects to trap more errors\r
613     // in configuration\r
614     if( canHwConfig->CanControllerId  == CAN_CTRL_0) {\r
615       INSTALL_HANDLERS(Can_0, IRQ_TYPE_CAN0_ERR, IRQ_TYPE_CAN0_WAKE, IRQ_TYPE_CAN0_RX, IRQ_TYPE_CAN0_TX);\r
616     }\r
617     else if( canHwConfig->CanControllerId  == CAN_CTRL_1) {\r
618       INSTALL_HANDLERS(Can_1, IRQ_TYPE_CAN1_ERR, IRQ_TYPE_CAN1_WAKE, IRQ_TYPE_CAN1_RX, IRQ_TYPE_CAN1_TX);\r
619     }\r
620     else if( canHwConfig->CanControllerId  == CAN_CTRL_2) {\r
621       INSTALL_HANDLERS(Can_2, IRQ_TYPE_CAN2_ERR, IRQ_TYPE_CAN2_WAKE, IRQ_TYPE_CAN2_RX, IRQ_TYPE_CAN2_TX);\r
622     }\r
623     else if( canHwConfig->CanControllerId  == CAN_CTRL_3) {\r
624       INSTALL_HANDLERS(Can_3, IRQ_TYPE_CAN3_ERR, IRQ_TYPE_CAN3_WAKE, IRQ_TYPE_CAN3_RX, IRQ_TYPE_CAN3_TX);\r
625     }\r
626     else if( canHwConfig->CanControllerId  == CAN_CTRL_4) {\r
627       INSTALL_HANDLERS(Can_4, IRQ_TYPE_CAN4_ERR, IRQ_TYPE_CAN4_WAKE, IRQ_TYPE_CAN4_RX, IRQ_TYPE_CAN4_TX);\r
628     }\r
629 \r
630     Can_InitController(ctlrId, canHwConfig);\r
631 \r
632     // Loop through all Hoh:s and map them into the HTHMap\r
633     const Can_HardwareObjectType* hoh;\r
634     hoh = canHwConfig->Can_Arc_Hoh;\r
635     hoh--;\r
636     do\r
637     {\r
638       hoh++;\r
639 \r
640       if (hoh->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)\r
641       {\r
642         Can_Global.CanHTHMap[hoh->CanObjectId].CanControllerRef = canHwConfig->CanControllerId;\r
643         Can_Global.CanHTHMap[hoh->CanObjectId].CanHOHRef = hoh;\r
644       }\r
645     } while (!hoh->Can_Arc_EOL);\r
646   }\r
647   return;\r
648 }\r
649 \r
650 // Unitialize the module\r
651 void Can_DeInit()\r
652 {\r
653   Can_UnitType *canUnit;\r
654   const Can_ControllerConfigType *canHwConfig;\r
655   uint32 ctlrId;\r
656 \r
657   for (int configId=0; configId < CAN_ARC_CTRL_CONFIG_CNT; configId++) {\r
658     canHwConfig = GET_CONTROLLER_CONFIG(configId);\r
659     ctlrId = canHwConfig->CanControllerId;\r
660 \r
661     canUnit = GET_PRIVATE_DATA(ctlrId);\r
662     canUnit->state = CANIF_CS_UNINIT;\r
663 \r
664     Can_DisableControllerInterrupts(ctlrId);\r
665 \r
666     canUnit->lock_cnt = 0;\r
667 \r
668     // Clear stats\r
669 #if (USE_CAN_STATISTICS == STD_ON)\r
670     memset(&canUnit->stats, 0, sizeof(Can_Arc_StatisticsType));\r
671 #endif\r
672   }\r
673 \r
674   Can_Global.config = NULL;\r
675   Can_Global.initRun = CAN_UNINIT;\r
676 \r
677   return;\r
678 }\r
679 \r
680 void Can_InitController( uint8 controller, const Can_ControllerConfigType *config)\r
681 {\r
682   CAN_HW_t *canHw;\r
683   uint8_t tq;\r
684   uint8_t tqSync;\r
685   uint8_t tq1;\r
686   uint8_t tq2;\r
687   uint32_t clock;\r
688   Can_UnitType *canUnit;\r
689   uint8 cId = controller;\r
690   const Can_ControllerConfigType *canHwConfig;\r
691   const Can_HardwareObjectType *hohObj;\r
692 \r
693   VALIDATE_NO_RV( (Can_Global.initRun == CAN_READY), 0x2, CAN_E_UNINIT );\r
694   VALIDATE_NO_RV( (config != NULL ), 0x2,CAN_E_PARAM_POINTER);\r
695   VALIDATE_NO_RV( (controller < GET_CONTROLLER_CNT()), 0x2, CAN_E_PARAM_CONTROLLER );\r
696 \r
697   canUnit = GET_PRIVATE_DATA(controller);\r
698 \r
699   VALIDATE_NO_RV( (canUnit->state==CANIF_CS_STOPPED), 0x2, CAN_E_TRANSITION );\r
700 \r
701   canHw = GetController(cId);\r
702   canHwConfig = GET_CONTROLLER_CONFIG(Can_Global.channelMap[cId]);\r
703 \r
704   // Start this baby up\r
705   canHw->CTL0 = BM_INITRQ;                              // request Init Mode\r
706   while((canHw->CTL1 & BM_INITAK) == 0) ;   // wait until Init Mode is established\r
707 \r
708   // set CAN enable bit, deactivate listen-only mode,\r
709   // use Bus Clock as clock source and select loop back mode on/off\r
710   canHw->CTL1 = BM_CANE | BM_CLKSRC | (config->Can_Arc_Loopback ? BM_LOOPB : 0x00);\r
711 \r
712   // acceptance filters\r
713    hohObj = canHwConfig->Can_Arc_Hoh;\r
714    --hohObj;\r
715    do {\r
716      ++hohObj;\r
717      if (hohObj->CanObjectType == CAN_OBJECT_TYPE_RECEIVE)\r
718      {\r
719         canHw->IDAC = hohObj->CanFilterMaskRef->idam;\r
720         canHw->IDAR0 = hohObj->CanFilterMaskRef->idar[0];\r
721         canHw->IDAR1 = hohObj->CanFilterMaskRef->idar[1];\r
722         canHw->IDAR2 = hohObj->CanFilterMaskRef->idar[2];\r
723         canHw->IDAR3 = hohObj->CanFilterMaskRef->idar[3];\r
724         canHw->IDAR4 = hohObj->CanFilterMaskRef->idar[4];\r
725         canHw->IDAR5 = hohObj->CanFilterMaskRef->idar[5];\r
726         canHw->IDAR6 = hohObj->CanFilterMaskRef->idar[6];\r
727         canHw->IDAR7 = hohObj->CanFilterMaskRef->idar[7];\r
728         canHw->IDMR0 = hohObj->CanFilterMaskRef->idmr[0];\r
729         canHw->IDMR1 = hohObj->CanFilterMaskRef->idmr[1];\r
730         canHw->IDMR2 = hohObj->CanFilterMaskRef->idmr[2];\r
731         canHw->IDMR3 = hohObj->CanFilterMaskRef->idmr[3];\r
732         canHw->IDMR4 = hohObj->CanFilterMaskRef->idmr[4];\r
733         canHw->IDMR5 = hohObj->CanFilterMaskRef->idmr[5];\r
734         canHw->IDMR6 = hohObj->CanFilterMaskRef->idmr[6];\r
735         canHw->IDMR7 = hohObj->CanFilterMaskRef->idmr[7];\r
736      }\r
737    }while( !hohObj->Can_Arc_EOL );\r
738 \r
739   // Clock calucation\r
740   // -------------------------------------------------------------------\r
741   //\r
742   // * 1 TQ = Sclk period( also called SCK )\r
743   // * Ftq = Fcanclk / ( PRESDIV + 1 ) = Sclk\r
744   //   ( Fcanclk can come from crystal or from the peripheral dividers )\r
745   //\r
746   // -->\r
747   // TQ = 1/Ftq = (PRESDIV+1)/Fcanclk --> PRESDIV = (TQ * Fcanclk - 1 )\r
748   // TQ is between 8 and 25\r
749   clock = McuE_GetSystemClock()/2;\r
750 \r
751   tqSync = config->CanControllerPropSeg + 1;\r
752   tq1 = config->CanControllerSeg1 + 1;\r
753   tq2 = config->CanControllerSeg2 + 1;\r
754   tq = tqSync + tq1 + tq2;\r
755 \r
756   // Check TQ limitations..\r
757   VALIDATE_DEM_NO_RV(( (tq1>=1) && (tq1<=16)), CAN_E_TIMEOUT );\r
758   VALIDATE_DEM_NO_RV(( (tq2>=1) && (tq2<=8)), CAN_E_TIMEOUT );\r
759   VALIDATE_DEM_NO_RV(( (tq>=3) && (tq<25 )), CAN_E_TIMEOUT );\r
760 \r
761   canHw->BTR0 = (config->CanControllerPropSeg << 6) | (uint8)(clock/(config->CanControllerBaudRate*1000*tq) - 1); // Prescaler\r
762   canHw->BTR1 = (config->CanControllerSeg2 << 4) | config->CanControllerSeg1;\r
763 \r
764   canHw->CTL0 &= ~BM_INITRQ;                            // exit Init Mode\r
765   while((canHw->CTL1 & BM_INITAK) != 0) ;// wait until Normal Mode is established\r
766 \r
767   canHw->TBSEL = BM_TX0;                                        // use (only) TX buffer 0\r
768 \r
769   canUnit->state = CANIF_CS_STOPPED;\r
770   Can_EnableControllerInterrupts(cId);\r
771 \r
772   return;\r
773 }\r
774 \r
775 \r
776 Can_ReturnType Can_SetControllerMode( uint8 controller, Can_StateTransitionType transition ) {\r
777   imask_t state;\r
778   CAN_HW_t *canHw;\r
779   Can_ReturnType rv = CAN_OK;\r
780   VALIDATE( (controller < GET_CONTROLLER_CNT()), 0x3, CAN_E_PARAM_CONTROLLER );\r
781 \r
782   Can_UnitType *canUnit = GET_PRIVATE_DATA(controller);\r
783 \r
784   VALIDATE( (canUnit->state!=CANIF_CS_UNINIT), 0x3, CAN_E_UNINIT );\r
785   canHw = GetController(controller);\r
786 \r
787   switch(transition )\r
788   {\r
789   case CAN_T_START:\r
790     canUnit->state = CANIF_CS_STARTED;\r
791     Irq_Save(state);\r
792     if (canUnit->lock_cnt == 0){   // REQ CAN196\r
793       Can_EnableControllerInterrupts(controller);\r
794     }\r
795     Irq_Restore(state);\r
796     break;\r
797   case CAN_T_WAKEUP:\r
798         VALIDATE(canUnit->state == CANIF_CS_SLEEP, 0x3, CAN_E_TRANSITION);\r
799         canHw->CTL0 &= ~BM_SLPRQ; // Clear Sleep request\r
800         canHw->CTL0 &= ~BM_WUPE; // Clear Wake up enable\r
801         canUnit->state = CANIF_CS_STOPPED;\r
802         break;\r
803   case CAN_T_SLEEP:  //CAN258, CAN290\r
804     // Should be reported to DEM but DET is the next best\r
805     VALIDATE(canUnit->state == CANIF_CS_STOPPED, 0x3, CAN_E_TRANSITION);\r
806         canHw->CTL0 |= BM_WUPE; // Set wake up enable\r
807         canHw->CTL0 |= BM_SLPRQ; // Set sleep request\r
808         canHw->RIER |= BM_WUPI; // Enable wake up irq\r
809         canUnit->state = CANIF_CS_SLEEP;\r
810         break;\r
811   case CAN_T_STOP:\r
812     // Stop\r
813     canUnit->state = CANIF_CS_STOPPED;\r
814     Can_AbortTx( canHw, canUnit ); // CANIF282\r
815     break;\r
816   default:\r
817     // Should be reported to DEM but DET is the next best\r
818     VALIDATE(canUnit->state == CANIF_CS_STOPPED, 0x3, CAN_E_TRANSITION);\r
819     break;\r
820   }\r
821 \r
822   return rv;\r
823 }\r
824 \r
825 void Can_DisableControllerInterrupts( uint8 controller )\r
826 {\r
827   imask_t state;\r
828   Can_UnitType *canUnit;\r
829   CAN_HW_t *canHw;\r
830 \r
831   VALIDATE_NO_RV( (controller < GET_CONTROLLER_CNT()), 0x4, CAN_E_PARAM_CONTROLLER );\r
832 \r
833   canUnit = GET_PRIVATE_DATA(controller);\r
834 \r
835   VALIDATE_NO_RV( (canUnit->state!=CANIF_CS_UNINIT), 0x4, CAN_E_UNINIT );\r
836 \r
837   Irq_Save(state);\r
838   if(canUnit->lock_cnt > 0 )\r
839   {\r
840     // Interrupts already disabled\r
841     canUnit->lock_cnt++;\r
842     Irq_Restore(state);\r
843     return;\r
844   }\r
845   canUnit->lock_cnt++;\r
846   Irq_Restore(state);\r
847 \r
848   /* Don't try to be intelligent, turn everything off */\r
849   canHw = GetController(controller);\r
850 \r
851   /* Turn off the tx interrupt mailboxes */\r
852   canHw->TIER = 0;\r
853 \r
854   /* Turn off the bus off/tx warning/rx warning and error and rx  */\r
855   canHw->RIER = 0;\r
856  }\r
857 \r
858 void Can_EnableControllerInterrupts( uint8 controller ) {\r
859   imask_t state;\r
860   Can_UnitType *canUnit;\r
861   CAN_HW_t *canHw;\r
862   const Can_ControllerConfigType *canHwConfig;\r
863   VALIDATE_NO_RV( (controller < GET_CONTROLLER_CNT()), 0x5, CAN_E_PARAM_CONTROLLER );\r
864 \r
865   canUnit = GET_PRIVATE_DATA(controller);\r
866 \r
867   VALIDATE_NO_RV( (canUnit->state!=CANIF_CS_UNINIT), 0x5, CAN_E_UNINIT );\r
868 \r
869   Irq_Save(state);\r
870   if( canUnit->lock_cnt > 1 )\r
871   {\r
872     // IRQ should still be disabled so just decrement counter\r
873     canUnit->lock_cnt--;\r
874     Irq_Restore(state);\r
875     return;\r
876   } else if (canUnit->lock_cnt == 1)\r
877   {\r
878     canUnit->lock_cnt = 0;\r
879   }\r
880   Irq_Restore(state);\r
881 \r
882   canHw = GetController(controller);\r
883 \r
884   canHwConfig = GET_CONTROLLER_CONFIG(Can_Global.channelMap[controller]);\r
885 \r
886   if( canHwConfig->CanRxProcessing == CAN_ARC_PROCESS_TYPE_INTERRUPT ) {\r
887     /* Turn on the rx interrupt */\r
888       canHw->RIER |= BM_RXF;\r
889   }\r
890 \r
891   // BusOff here represents all errors and warnings\r
892   if( canHwConfig->CanBusOffProcessing == CAN_ARC_PROCESS_TYPE_INTERRUPT ) {\r
893     /* Turn off the bus off/tx warning/rx warning and error and rx  */\r
894     canHw->RIER |= BM_WUPI | BM_CSCI | BM_OVRI | BM_RXF | BM_RSTAT0 | BM_TSTAT0;\r
895   }\r
896 \r
897   return;\r
898 }\r
899 \r
900 static IdrType ConstructIdBytes(Can_IdType id, Can_IdTypeType idType)\r
901 {\r
902     IdrType idr;\r
903 \r
904     idr.R[3] = idr.R[2] = idr.R[1] = idr.R[0] = 0;\r
905 \r
906     if(idType == CAN_ID_TYPE_EXTENDED) {\r
907       idr.Bit.SRR = 1;\r
908       idr.Bit.RTR = 0;\r
909       idr.Bit.IDE = 1;\r
910       idr.Bit.id28to21 = id>>21;\r
911       idr.Bit.id20to18 = id>>18 & 0x07;\r
912       idr.Bit.id17to15 = id>>15 & 0x07;\r
913       idr.Bit.id14to7  = id>>7;\r
914       idr.Bit.id6to0   = id & 0x7F;\r
915     } else if (idType == CAN_ID_TYPE_STANDARD) {\r
916       idr.R[0] = id>>3;\r
917       idr.R[1] = id<<5 & 0xE0;\r
918     } else {\r
919       // No support for mixed in this processor\r
920       assert(0);\r
921     }\r
922 \r
923     return idr;\r
924 }\r
925 \r
926 Can_ReturnType Can_Write( Can_Arc_HTHType hth, Can_PduType *pduInfo ) {\r
927   Can_ReturnType rv = CAN_OK;\r
928   CAN_HW_t *canHw;\r
929   const Can_HardwareObjectType *hohObj;\r
930   const Can_ControllerConfigType *canHwConfig;\r
931   uint32 controller;\r
932   imask_t state;\r
933   IdrType idr;\r
934 \r
935   VALIDATE( (Can_Global.initRun == CAN_READY), 0x6, CAN_E_UNINIT );\r
936   VALIDATE( (pduInfo != NULL), 0x6, CAN_E_PARAM_POINTER );\r
937   VALIDATE( (pduInfo->length <= 8), 0x6, CAN_E_PARAM_DLC );\r
938   VALIDATE( (hth < NUM_OF_HTHS ), 0x6, CAN_E_PARAM_HANDLE );\r
939 \r
940   hohObj = Can_FindHoh(hth, &controller);\r
941   if (hohObj == NULL)\r
942     return CAN_NOT_OK;\r
943 \r
944   Can_UnitType *canUnit = GET_PRIVATE_DATA(controller);\r
945 \r
946   canHw = GetController(controller);\r
947   Irq_Save(state);\r
948 \r
949   // check for any free box\r
950   if((canHw->TFLG & BM_TX0) == BM_TX0) {\r
951     canHw->TBSEL = BM_TX0; // Select mb0\r
952 \r
953     idr = ConstructIdBytes(pduInfo->id, hohObj->CanIdType);\r
954 \r
955     canHw->TXFG.idr0 = idr.R[0];\r
956     canHw->TXFG.idr1 = idr.R[1];\r
957     canHw->TXFG.idr2 = idr.R[2];\r
958     canHw->TXFG.idr3 = idr.R[3];\r
959 \r
960     memcpy((uint8 *)&canHw->TXFG.ds0, pduInfo->sdu, pduInfo->length);\r
961     canHw->TXFG.dlr = pduInfo->length;\r
962     canHw->TXFG.tbpr = 0; // Highest prio\r
963 \r
964     // Send\r
965     canHw->TFLG = BM_TX0;\r
966 \r
967     canHwConfig = GET_CONTROLLER_CONFIG(Can_Global.channelMap[controller]);\r
968 \r
969     if( (canHwConfig->CanTxProcessing == CAN_ARC_PROCESS_TYPE_INTERRUPT) &&\r
970         (canUnit->lock_cnt == 0) ) {\r
971           /* Turn on the tx interrupt mailboxes */\r
972       canHw->TIER = BM_TX0; // We only use TX0\r
973     }\r
974 \r
975     // Increment statistics\r
976 #if (USE_CAN_STATISTICS == STD_ON)\r
977     canUnit->stats.txSuccessCnt++;\r
978 #endif\r
979 \r
980     // Store pdu handle in unit to be used by TxConfirmation\r
981     canUnit->swPduHandle = pduInfo->swPduHandle;\r
982   } else {\r
983     rv = CAN_BUSY;\r
984   }\r
985   Irq_Restore(state);\r
986 \r
987   return rv;\r
988 }\r
989 \r
990 void Can_MainFunction_Read( void ) {\r
991 \r
992         /* NOT SUPPORTED */\r
993 }\r
994 \r
995 void Can_MainFunction_BusOff( void ) {\r
996   /* Bus-off polling events */\r
997 \r
998         /* NOT SUPPORTED */\r
999 }\r
1000 \r
1001 void Can_MainFunction_Wakeup( void ) {\r
1002   /* Wakeup polling events */\r
1003 \r
1004         /* NOT SUPPORTED */\r
1005 }\r
1006 \r
1007 \r
1008 void Can_MainFunction_Write( void ) {\r
1009     /* NOT SUPPORTED */\r
1010 }\r
1011 \r
1012 void Can_MainFunction_Error( void ) {\r
1013     /* NOT SUPPORTED */\r
1014 }\r
1015 \r
1016 \r
1017 /**\r
1018  * Get send/receive/error statistics for a controller\r
1019  *\r
1020  * @param controller The controller\r
1021  * @param stats Pointer to data to copy statistics to\r
1022  */\r
1023 \r
1024 #if (USE_CAN_STATISTICS == STD_ON)\r
1025 void Can_Arc_GetStatistics( uint8 controller, Can_Arc_StatisticsType *stats)\r
1026 {\r
1027   Can_UnitType *canUnit = GET_PRIVATE_DATA(controller);\r
1028   *stats = canUnit->stats;\r
1029 }\r
1030 #endif\r
1031 \r
1032 #else // Stub all functions for use in simulator environment\r
1033 \r
1034 #include "debug.h"\r
1035 \r
1036 void Can_Init( const Can_ConfigType *Config )\r
1037 {\r
1038   // Do initial configuration of layer here\r
1039 }\r
1040 \r
1041 void Can_InitController( uint8 controller, const Can_ControllerConfigType *config)\r
1042 {\r
1043         // Do initialisation of controller here.\r
1044 }\r
1045 \r
1046 Can_ReturnType Can_SetControllerMode( uint8 Controller, Can_StateTransitionType transition )\r
1047 {\r
1048         // Turn on off controller here depending on transition\r
1049         return E_OK;\r
1050 }\r
1051 \r
1052 Can_ReturnType Can_Write( Can_Arc_HTHType hth, Can_PduType *pduInfo )\r
1053 {\r
1054         // Write to mailbox on controller here.\r
1055         DEBUG(DEBUG_MEDIUM, "Can_Write(stub): Received data ");\r
1056         for (int i = 0; i < pduInfo->length; i++) {\r
1057                 DEBUG(DEBUG_MEDIUM, "%d ", pduInfo->sdu[i]);\r
1058         }\r
1059         DEBUG(DEBUG_MEDIUM, "\n");\r
1060 \r
1061         return E_OK;\r
1062 }\r
1063 \r
1064 extern void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc, const uint8 *CanSduPtr);\r
1065 Can_ReturnType Can_ReceiveAFrame()\r
1066 {\r
1067         // This function is not part of autosar but needed to feed the stack with data\r
1068         // from the mailboxes. Normally this is an interrup but probably not in the PCAN case.\r
1069         uint8 CanSduData[] = {1,2,1,0,0,0,0,0};\r
1070         CanIf_RxIndication(CAN_HRH_0_1, 3, 8, CanSduData);\r
1071 \r
1072         return E_OK;\r
1073 }\r
1074 \r
1075 void Can_DisableControllerInterrupts( uint8 controller )\r
1076 {\r
1077 }\r
1078 \r
1079 void Can_EnableControllerInterrupts( uint8 controller )\r
1080 {\r
1081 }\r
1082 \r
1083 \r
1084 // Hth - for Flexcan, the hardware message box number... .We don't care\r
1085 void Can_Cbk_CheckWakeup( uint8 controller ){}\r
1086 \r
1087 void Can_MainFunction_Write( void ){}\r
1088 void Can_MainFunction_Read( void ){}\r
1089 void Can_MainFunction_Error( void ){}\r
1090 void Can_MainFunction_BusOff( void ){}\r
1091 void Can_MainFunction_Wakeup( void ){}\r
1092 \r
1093 void Can_Arc_GetStatistics( uint8 controller, Can_Arc_StatisticsType * stat){}\r
1094 \r
1095 #endif\r
1096 \r
1097 \r