]> rtime.felk.cvut.cz Git - arc.git/blob - communication/CanIf/CanIf.c
Merged in old bugfix
[arc.git] / communication / CanIf / CanIf.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 "Det.h"\r
24 #include "CanIf.h"\r
25 \r
26 #include "Can.h"\r
27 #include "CanIf_Cbk.h"\r
28 #include <string.h>\r
29 \r
30 #include "debug.h"\r
31 #include "PduR.h"\r
32 \r
33 #if defined(USE_CANTP)\r
34 #include "CanTp_Cbk.h"\r
35 #endif\r
36 \r
37 #if defined(USE_CANNM)\r
38 #include "CanNm.h"\r
39 #endif\r
40 \r
41 #if 0\r
42 // TODO: Include upper layer functions, See CANIF208 and CANIF233\r
43 #include "PduR_CanIf.h"\r
44 #include "CanNm.h"\r
45 #include "CanTp.h"\r
46 \r
47 #include "PduR_Cbk.h"\r
48 #include "CanNm_Cbk.h"\r
49 #include "CanTp_Cbk.h"\r
50 #endif\r
51 \r
52 #if  ( CANIF_DEV_ERROR_DETECT == STD_ON )\r
53 #define VALIDATE(_exp,_api,_err ) \\r
54         if( !(_exp) ) { \\r
55           Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \\r
56           return E_NOT_OK; \\r
57         }\r
58 \r
59 #define VALIDATE_NO_RV(_exp,_api,_err ) \\r
60   if( !(_exp) ) { \\r
61           Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \\r
62           return; \\r
63         }\r
64 #define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)\r
65 \r
66 #else\r
67 #define VALIDATE(_exp,_api,_err )\r
68 #define VALIDATE_NO_RV(_exp,_api,_err )\r
69 #define DET_REPORTERROR(_x,_y,_z,_q)\r
70 #endif\r
71 \r
72 \r
73 // Helper to get the Can Controller refered to by a CanIf Channel\r
74 #define ARC_GET_CHANNEL_CONTROLLER(_channel) \\r
75         CanIf_ConfigPtr->Arc_ChannelToControllerMap[channel]\r
76 \r
77 /* Global configure */\r
78 static const CanIf_ConfigType *CanIf_ConfigPtr;\r
79 \r
80 // Struct of controller private data.\r
81 typedef struct\r
82 {\r
83   CanIf_ControllerModeType  ControllerMode;\r
84   CanIf_ChannelGetModeType  PduMode;\r
85 } CanIf_ChannelPrivateType;\r
86 \r
87 typedef struct\r
88 {\r
89   boolean initRun;\r
90   CanIf_ChannelPrivateType channelData[CANIF_CHANNEL_CNT];\r
91 } CanIf_GlobalType;\r
92 \r
93 void CanIf_PreInit_InitController(uint8 Controller, uint8 ConfigurationIndex);\r
94 \r
95 static CanIf_Arc_ChannelIdType CanIf_Arc_FindHrhChannel( Can_Arc_HRHType hrh )\r
96 {\r
97   const CanIf_InitHohConfigType *hohConfig;\r
98   const CanIf_HrhConfigType *hrhConfig;\r
99 \r
100   // foreach(hoh){ foreach(hrh in hoh) {} }\r
101   hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;\r
102   hohConfig--;\r
103   do\r
104   {\r
105     hohConfig++;\r
106 \r
107     hrhConfig = hohConfig->CanIfHrhConfig;\r
108     hrhConfig--;\r
109     do\r
110     {\r
111       hrhConfig++;\r
112       if (hrhConfig->CanIfHrhIdSymRef == hrh){\r
113         return hrhConfig->CanIfCanControllerHrhIdRef;\r
114       }\r
115     } while(!hrhConfig->CanIf_Arc_EOL);\r
116   } while(!hohConfig->CanIf_Arc_EOL);\r
117 \r
118   DET_REPORTERROR(MODULE_ID_CANIF, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);\r
119 \r
120   return -1;\r
121 }\r
122 \r
123 // Global config\r
124 CanIf_GlobalType CanIf_Global;\r
125 \r
126 void CanIf_Init(const CanIf_ConfigType *ConfigPtr)\r
127 {\r
128   VALIDATE_NO_RV(ConfigPtr != 0, CANIF_INIT_ID, CANIF_E_PARAM_POINTER); // Only PostBuild case supported\r
129 \r
130   CanIf_ConfigPtr = ConfigPtr;\r
131 \r
132   for (uint8 i = 0; i < CANIF_CHANNEL_CNT; i++)\r
133   {\r
134     CanIf_Global.channelData[i].ControllerMode = CANIF_CS_STOPPED;\r
135     CanIf_Global.channelData[i].PduMode = CANIF_GET_OFFLINE;\r
136     CanIf_PreInit_InitController(i, CanIf_ConfigPtr->Arc_ChannelDefaultConfIndex[i]);\r
137   }\r
138 \r
139 \r
140   CanIf_Global.initRun = TRUE;\r
141 }\r
142 \r
143 \r
144 \r
145 \r
146 //-------------------------------------------------------------------\r
147 /*\r
148  * Controller :: CanIf_Arc_ChannelIdType (CanIf-specific id to abstract from Can driver/controllers)\r
149  * ConfigurationIndex :: CanIf_Arc_ConfigurationIndexType\r
150  */\r
151 void CanIf_InitController(uint8 Controller, uint8 ConfigurationIndex)\r
152 {\r
153   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
154   CanIf_Arc_ChannelIdType channel = Controller;\r
155   CanIf_ControllerModeType mode;\r
156 \r
157   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_INIT_CONTROLLER_ID, CANIF_E_UNINIT );\r
158   VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
159   VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_POINTER);\r
160 \r
161   if (CanIf_GetControllerMode(channel, &mode) == E_OK)\r
162   {\r
163     if (mode == CANIF_CS_STARTED)\r
164     {\r
165       CanIf_SetControllerMode(channel, CANIF_CS_STOPPED); // CANIF092\r
166     }\r
167     else if (mode != CANIF_CS_STOPPED)\r
168     {\r
169       VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE); // CANIF092\r
170     }\r
171   }\r
172   else\r
173   {\r
174     VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE);\r
175   }\r
176 \r
177   // CANIF293: ..Subsequently the CAN Interface calls the corresponding\r
178   //             CAN Driver initialization services.\r
179 \r
180   // CANIF066: The CAN Interface has access to the CAN Driver configuration data. All\r
181   // public CAN Driver configuration data are described in [8] Specification of CAN Driver.\r
182 \r
183   // Grab the configuration from the Can Controller\r
184   const Can_ControllerConfigType *canConfig;\r
185   const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);\r
186 \r
187   // Validate that the configuration at the index match the right channel\r
188   VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
189 \r
190   canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;\r
191 \r
192   // Validate that the CanIfControllerConfig points to configuration for the right Can Controller\r
193   VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
194 \r
195   Can_InitController(canControllerId, canConfig);\r
196 \r
197   // Set mode to stopped\r
198   CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);\r
199 }\r
200 \r
201 void CanIf_PreInit_InitController(uint8 Controller, uint8 ConfigurationIndex){\r
202         // We call this a CanIf channel. Hopefully makes it easier to follow.\r
203         CanIf_Arc_ChannelIdType channel = Controller;\r
204 \r
205         VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_ID, CANIF_E_PARAM_CONTROLLER);\r
206         VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_ID, CANIF_E_PARAM_POINTER);\r
207 \r
208 \r
209         const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);\r
210         // Validate that the configuration at the index match the right channel\r
211         VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
212         const Can_ControllerConfigType *canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;\r
213         // Validate that the CanIfControllerConfig points to configuration for the right Can Controller\r
214         VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);\r
215 \r
216         Can_InitController(canControllerId, canConfig);\r
217 }\r
218 \r
219 //-------------------------------------------------------------------\r
220 \r
221 Std_ReturnType CanIf_SetControllerMode(uint8 Controller,\r
222     CanIf_ControllerModeType ControllerMode)\r
223 {\r
224   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
225   CanIf_Arc_ChannelIdType channel = Controller;\r
226 \r
227 \r
228   CanIf_ControllerModeType oldMode;\r
229 \r
230   VALIDATE( CanIf_Global.initRun, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );\r
231   VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );\r
232 \r
233   oldMode = CanIf_Global.channelData[channel].ControllerMode;\r
234 \r
235   if (oldMode == CANIF_CS_UNINIT)\r
236   {\r
237     VALIDATE(FALSE, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT); // See figure 32, 33\r
238     return E_NOT_OK;\r
239   }\r
240   CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(Controller);\r
241   switch (ControllerMode)\r
242   {\r
243   case CANIF_CS_STARTED:   // Figure 32\r
244   {\r
245     switch (oldMode)\r
246     {\r
247       case CANIF_CS_SLEEP:\r
248         if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){\r
249           return E_NOT_OK;\r
250         }\r
251         CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;\r
252         break;\r
253       default:\r
254         // Just fall through\r
255         break;\r
256     }\r
257 \r
258     CanIf_SetPduMode(channel, CANIF_SET_ONLINE);\r
259     if (Can_SetControllerMode(canControllerId, CAN_T_START) == CAN_NOT_OK){\r
260       return E_NOT_OK;\r
261     }\r
262     CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STARTED;\r
263   }\r
264   break;\r
265 \r
266   case CANIF_CS_SLEEP: // Figure 33\r
267   {\r
268     switch (oldMode) {\r
269       case CANIF_CS_STARTED:\r
270         if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){\r
271           return E_NOT_OK;\r
272         }\r
273         CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;\r
274         break;\r
275       default:\r
276         // Just fall through for other cases\r
277         break;\r
278     }\r
279 \r
280     if (Can_SetControllerMode(canControllerId, CAN_T_SLEEP) == CAN_NOT_OK){\r
281       return E_NOT_OK;\r
282     }\r
283     CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_SLEEP;\r
284   }\r
285 \r
286   case CANIF_CS_STOPPED:\r
287   {\r
288     switch (oldMode)\r
289     {\r
290       case CANIF_CS_SLEEP:\r
291         if (Can_SetControllerMode(canControllerId, CAN_T_WAKEUP) == CAN_NOT_OK){\r
292           return E_NOT_OK;\r
293         }\r
294         break;\r
295       default:\r
296         // Just fall through for other cases\r
297         break;\r
298     }\r
299 \r
300     CanIf_SetPduMode(channel, CANIF_SET_OFFLINE);\r
301     if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){\r
302       return E_NOT_OK;\r
303     }\r
304     CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;\r
305     break;\r
306   }\r
307 \r
308   case CANIF_CS_UNINIT:\r
309     // Just fall through\r
310     break;\r
311   }\r
312   return E_OK;\r
313 }\r
314 \r
315 //-------------------------------------------------------------------\r
316 \r
317 Std_ReturnType CanIf_GetControllerMode(uint8 Controller,\r
318     CanIf_ControllerModeType *ControllerModePtr)\r
319 {\r
320   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
321   CanIf_Arc_ChannelIdType channel = Controller;\r
322 \r
323   VALIDATE(CanIf_Global.initRun, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );\r
324   VALIDATE(channel < CANIF_CHANNEL_CNT, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );\r
325   VALIDATE(ControllerModePtr != NULL, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_POINTER );\r
326 \r
327   *ControllerModePtr = CanIf_Global.channelData[channel].ControllerMode;\r
328 \r
329   return E_OK;\r
330 }\r
331 \r
332 //-------------------------------------------------------------------\r
333 /**\r
334  * Matches a Tx PDU id agaist the ones that are in the database.\r
335  *\r
336  * @returns Ptr a TxPdu\r
337  */\r
338 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )\r
339 CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)\r
340 #else\r
341 static const CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)\r
342 #endif\r
343 {\r
344         if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds) {\r
345                 return NULL;\r
346         } else {\r
347                 return &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[id];\r
348         }\r
349   }\r
350 \r
351 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )\r
352 CanIf_RxPduConfigType * CanIf_FindRxPduEntry(PduIdType id)\r
353 #else\r
354 static const CanIf_RxPduConfigType * CanIf_FindRxPduEntry(PduIdType id)
355 #endif\r
356 {
357         if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds) {
358                 return NULL;
359         } else {
360                 return &CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr[id];
361         }
362 }
363
364 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )
365 const CanIf_HrhConfigType* CanIf_Arc_GetReceiveHandler(CanIf_Arc_ChannelIdType Channel) {
366   const CanIf_InitHohConfigType *hohConfig;
367   const CanIf_HrhConfigType *hrhConfig;
368
369   // foreach(hoh){ foreach(hrh in hoh) {} }
370   hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
371   hohConfig--;
372   do
373   {
374         hohConfig++;
375
376         hrhConfig = hohConfig->CanIfHrhConfig;
377     hrhConfig--;
378     do
379     {
380       hrhConfig++;
381       if (hrhConfig->CanIfCanControllerHrhIdRef == Channel)
382         return hrhConfig;
383         } while(!hrhConfig->CanIf_Arc_EOL);
384
385   } while(!hohConfig->CanIf_Arc_EOL);
386
387   DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HRH);
388
389   return NULL;
390 }
391
392 const CanIf_HthConfigType* CanIf_Arc_GetTransmitHandler(CanIf_Arc_ChannelIdType Channel) {
393   const CanIf_InitHohConfigType *hohConfig;
394   const CanIf_HthConfigType *hthConfig;
395
396   // foreach(hoh){ foreach(hrh in hoh) {} }
397   hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
398   hohConfig--;
399   do
400   {
401         hohConfig++;
402
403         hthConfig = hohConfig->CanIfHthConfig;
404         hthConfig--;
405     do
406     {
407         hthConfig++;
408       if (hthConfig->CanIfCanControllerIdRef == Channel)
409         return hthConfig;
410         } while(!hthConfig->CanIf_Arc_EOL);
411
412   } while(!hohConfig->CanIf_Arc_EOL);
413
414   DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HTH);
415
416   return NULL;
417 }
418 #endif
419
420 //-------------------------------------------------------------------\r
421 \r
422 Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId,\r
423     const PduInfoType *PduInfoPtr)\r
424 {\r
425   Can_PduType canPdu;\r
426   const CanIf_TxPduConfigType *txEntry;\r
427   CanIf_ControllerModeType csMode;\r
428   CanIf_ChannelGetModeType pduMode;\r
429 \r
430   VALIDATE(CanIf_Global.initRun, CANIF_TRANSMIT_ID, CANIF_E_UNINIT );\r
431   VALIDATE((PduInfoPtr != 0), CANIF_TRANSMIT_ID, CANIF_E_PARAM_POINTER );\r
432 \r
433   // Get the controller from L-PDU handle\r
434   txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
435 \r
436   if (txEntry == 0)\r
437   {\r
438     VALIDATE(FALSE, CANIF_TRANSMIT_ID, CANIF_E_INVALID_TXPDUID);\r
439     return E_NOT_OK;\r
440   }\r
441 \r
442   CanIf_Arc_ChannelIdType channel = txEntry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef;\r
443 \r
444   // Get and verify the controller mode\r
445   if (CanIf_GetControllerMode(channel, &csMode) == E_NOT_OK){\r
446     return E_NOT_OK;\r
447   }\r
448 \r
449   if (csMode != CANIF_CS_STARTED){  // CANIF_161\r
450     return E_NOT_OK;\r
451   }\r
452 \r
453   // Get and verify the PDU channel mode control\r
454   if (CanIf_GetPduMode(channel, &pduMode) == E_NOT_OK){\r
455     return E_NOT_OK;\r
456   }\r
457 \r
458   if ((pduMode != CANIF_GET_TX_ONLINE) && (pduMode != CANIF_GET_ONLINE)){\r
459     return E_NOT_OK;\r
460   }\r
461 \r
462   canPdu.id = txEntry->CanIfCanTxPduIdCanId;\r
463 \r
464   canPdu.length = PduInfoPtr->SduLength;\r
465   canPdu.sdu = PduInfoPtr->SduDataPtr;\r
466   canPdu.swPduHandle = CanTxPduId;\r
467 \r
468   Can_ReturnType rVal = Can_Write(txEntry->CanIfCanTxPduHthRef->CanIfHthIdSymRef, &canPdu);\r
469 \r
470   if (rVal == CAN_NOT_OK){\r
471     return E_NOT_OK;\r
472   }\r
473 \r
474   if (rVal == CAN_BUSY)  // CANIF 082, CANIF 161\r
475   {\r
476     // Tx buffering not supported so just return.\r
477     return E_NOT_OK;\r
478   }\r
479 \r
480   return E_OK;\r
481 }\r
482 \r
483 //-------------------------------------------------------------------\r
484 \r
485 #if ( CANIF_READRXPDU_DATA_API == STD_ON )\r
486 Std_ReturnType CanIf_ReadRxPduData(PduIdType CanRxPduId,\r
487     PduInfoType *PduInfoPtr)\r
488 {\r
489   VALIDATE(FALSE, CANIF_READTXPDUDATA_ID, CANIF_E_NOK_NOSUPPORT);\r
490   VALIDATE(CanIf_Global.initRun == STD_ON, CANIF_READTXPDUDATA_ID, CANIF_E_UNINIT );\r
491   VALIDATE(PduInfoPtr != 0, CANIF_READTXPDUDATA_ID, CANIF_E_PARAM_POINTER );\r
492 \r
493   // This function is not supported\r
494 \r
495   return E_NOT_OK;\r
496 }\r
497 #endif\r
498 \r
499 //-------------------------------------------------------------------\r
500 \r
501 #if ( CANIF_READTXPDU_NOTIFY_STATUS_API == STD_ON )\r
502 CanIf_NotifStatusType CanIf_ReadTxNotifStatus(PduIdType CanTxPduId)\r
503 {\r
504   const CanIf_TxPduConfigType *txEntry;\r
505   VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);\r
506   VALIDATE(CanIf_Global.initRun, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_UNINIT );\r
507 \r
508   // Get the controller from L-PDU handle\r
509   txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
510 \r
511   if (txEntry == 0)\r
512   {\r
513     VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);\r
514     return CANIF_NO_NOTIFICATION;\r
515   }\r
516 \r
517   if (txEntry->CanIfReadTxPduNotifyStatus == FALSE)\r
518   {\r
519     VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);\r
520     return CANIF_NO_NOTIFICATION;\r
521   }\r
522 \r
523   // This function is not supported\r
524 \r
525   return CANIF_NO_NOTIFICATION;\r
526 }\r
527 #endif\r
528 \r
529 //-------------------------------------------------------------------\r
530 \r
531 #if ( CANIF_READRXPDU_NOTIFY_STATUS_API == STD_ON )\r
532 CanIf_NotifStatusType CanIf_ReadRxNotifStatus(PduIdType CanRxPduId)\r
533 {\r
534   VALIDATE(FALSE, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);\r
535   VALIDATE(CanIf_Global.initRun, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_UNINIT );\r
536 \r
537   return CANIF_NO_NOTIFICATION;\r
538 }\r
539 #endif\r
540 \r
541 //-------------------------------------------------------------------\r
542 \r
543 Std_ReturnType CanIf_SetPduMode(uint8 Controller,\r
544     CanIf_ChannelSetModeType PduModeRequest)\r
545 {\r
546   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
547   CanIf_Arc_ChannelIdType channel = Controller;\r
548 \r
549   VALIDATE( CanIf_Global.initRun, CANIF_SETPDUMODE_ID, CANIF_E_UNINIT );\r
550   VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );\r
551 \r
552   CanIf_ChannelGetModeType oldMode = CanIf_Global.channelData[channel].PduMode;\r
553 \r
554   switch(PduModeRequest)\r
555   {\r
556   case CANIF_SET_OFFLINE:\r
557     CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
558     break;\r
559   case CANIF_SET_RX_OFFLINE:\r
560     if (oldMode == CANIF_GET_RX_ONLINE){\r
561       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
562     } else if (oldMode == CANIF_GET_ONLINE){\r
563       CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
564     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE){\r
565       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
566     }\r
567 \r
568     // Other oldmodes don't care\r
569     break;\r
570   case CANIF_SET_RX_ONLINE:\r
571     if (oldMode == CANIF_GET_OFFLINE){\r
572       CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
573     } else if (oldMode == CANIF_GET_TX_ONLINE) {\r
574       CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
575     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE){\r
576       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
577     }\r
578 \r
579     // Other oldmodes don't care\r
580     break;\r
581   case CANIF_SET_TX_OFFLINE:\r
582     if (oldMode == CANIF_GET_TX_ONLINE){\r
583       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
584     } else if (oldMode == CANIF_GET_ONLINE) {\r
585       CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
586     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {\r
587       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
588     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {\r
589       CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
590     }\r
591 \r
592     // Other oldmodes don't care\r
593     break;\r
594   case CANIF_SET_TX_ONLINE:\r
595     if (oldMode == CANIF_GET_OFFLINE){\r
596       CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
597     } else if (oldMode == CANIF_GET_RX_ONLINE) {\r
598       CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
599     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {\r
600       CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
601     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {\r
602       CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
603     }\r
604 \r
605     // Other oldmodes don't care\r
606     break;\r
607   case CANIF_SET_ONLINE:\r
608     CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
609     break;\r
610 \r
611   case CANIF_SET_TX_OFFLINE_ACTIVE:\r
612     if (oldMode == CANIF_GET_OFFLINE) {\r
613       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
614     } else if (oldMode == CANIF_GET_RX_ONLINE) {\r
615       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
616     } else if (oldMode == CANIF_GET_TX_ONLINE) {\r
617       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
618     } else if (oldMode == CANIF_GET_ONLINE) {\r
619       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
620     }\r
621 \r
622     // Other oldmodes don't care\r
623     break;\r
624   }\r
625 \r
626   return E_OK;\r
627 }\r
628 \r
629 //-------------------------------------------------------------------\r
630 \r
631 Std_ReturnType CanIf_GetPduMode(uint8 Controller,\r
632     CanIf_ChannelGetModeType *PduModePtr)\r
633 {\r
634   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
635   CanIf_Arc_ChannelIdType channel = Controller;\r
636 \r
637   VALIDATE( CanIf_Global.initRun, CANIF_GETPDUMODE_ID, CANIF_E_UNINIT );\r
638   VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_GETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );\r
639 \r
640   *PduModePtr = CanIf_Global.channelData[channel].PduMode;\r
641 \r
642   return E_OK;\r
643 }\r
644 \r
645 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )
646 void CanIf_SetDynamicTxId(PduIdType CanTxPduId, Can_IdType CanId)\r
647 {\r
648   CanIf_TxPduConfigType *txEntry;\r
649   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_SETDYNAMICTX_ID, CANIF_E_UNINIT );\r
650 \r
651   // Get the controller from L-PDU handle\r
652   txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
653 \r
654   if (txEntry == 0)\r
655   {\r
656     VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);\r
657     return;\r
658   }\r
659 \r
660   // Check that this is a dymanic PDU\r
661   if (txEntry->CanIfCanTxPduType != ARC_PDU_TYPE_DYNAMIC)\r
662   {\r
663     VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);\r
664     return;\r
665   }\r
666 \r
667   // Check that this is an extended or standard id\r
668   if (((CanId & U0x80000000) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_29)) ||\r
669       (((CanId & U0x80000000) == 0) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_11)))\r
670   {\r
671     // Update the CanID\r
672     //txEntry->CanIfCanTxPduIdCanId = CanId;  // TODO How do we fix this from a const pointer\r
673 \r
674     // NOT SUPPORTED\r
675   }\r
676   else\r
677   {\r
678     // Inavlid Canid to configuration\r
679     VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_PARAM_CANID);\r
680   }\r
681 }\r
682 #endif\r
683 \r
684 #if ( CANIF_TRANSCEIVER_API == STD_ON )\r
685 Std_ReturnType CanIf_SetTransceiverMode(uint8 Transceiver,\r
686     CanIf_TransceiverModeType TransceiverMode)\r
687 {\r
688   VALIDATE(FALSE, CANIF_SET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
689 // Not supported\r
690 \r
691   return E_NOT_OK;\r
692 }\r
693 \r
694 Std_ReturnType CanIf_GetTransceiverMode(uint8 Transceiver,\r
695     CanIf_TransceiverModeType *TransceiverModePtr)\r
696 {\r
697   VALIDATE(FALSE, CANIF_GET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
698   // Not supported\r
699 \r
700   return E_NOT_OK;\r
701 }\r
702 \r
703 Std_ReturnType CanIf_GetTrcvWakeupReason(uint8 Transceiver,\r
704     CanIf_TrcvWakeupReasonType *TrcvWuReasonPtr)\r
705 {\r
706   VALIDATE(FALSE, CANIF_GET_TRCVMODEREASON_ID, CANIF_E_NOK_NOSUPPORT);\r
707   // Not supported\r
708 \r
709   return E_NOT_OK;\r
710 }\r
711 \r
712 Std_ReturnType CanIf_SetTransceiverWakeupMode(uint8 Transceiver,\r
713     CanIf_TrcvWakeupModeType *TrcvWakeupMode)\r
714 {\r
715   VALIDATE(FALSE, CANIF_SET_TRANSCEIVERWAKEMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
716   // Not supported\r
717 \r
718   return E_NOT_OK;\r
719 }\r
720 #endif\r
721 \r
722 #if ( CANIF_WAKEUP_EVENT_API == STD_ON )\r
723 Std_ReturnType CanIf_CheckWakeup(EcuM_WakeupSourceType WakeupSource)\r
724 {\r
725   VALIDATE(FALSE, CANIF_CHECKWAKEUP_ID, CANIF_E_NOK_NOSUPPORT);\r
726   // Not supported\r
727 \r
728   return E_NOT_OK;\r
729 }\r
730 \r
731 Std_ReturnType CanIf_CheckValidation(EcuM_WakeupSourceType WakeupSource)\r
732 {\r
733   VALIDATE(FALSE, CANIF_CHECKVALIDATION_ID, CANIF_E_NOK_NOSUPPORT);\r
734   // Not supported\r
735 \r
736   return E_NOT_OK;\r
737 }\r
738 #endif\r
739 \r
740 /*\r
741  * Callback interface from driver\r
742  */\r
743 void CanIf_TxConfirmation(PduIdType canTxPduId)\r
744 {\r
745   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_TXCONFIRMATION_ID, CANIF_E_UNINIT)\r
746   VALIDATE_NO_RV(canTxPduId < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);\r
747 \r
748   const CanIf_TxPduConfigType* entry =\r
749     &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[canTxPduId];\r
750 \r
751       if (entry->CanIfUserTxConfirmation != NULL)\r
752       {\r
753         CanIf_ChannelGetModeType mode;\r
754         CanIf_GetPduMode(entry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef, &mode);\r
755         if ((mode == CANIF_GET_TX_ONLINE) || (mode == CANIF_GET_ONLINE)\r
756             || (mode == CANIF_GET_OFFLINE_ACTIVE) || (mode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) )\r
757         {\r
758           entry->CanIfUserTxConfirmation(entry->CanIfTxPduId);  /* CANIF053 */\r
759         }\r
760       }\r
761       return;\r
762 }\r
763 \r
764 void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc,\r
765               const uint8 *CanSduPtr)\r
766 {\r
767   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_RXINDICATION_ID, CANIF_E_UNINIT);\r
768   VALIDATE_NO_RV(CanSduPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);\r
769 \r
770   /* Check PDU mode before continue processing */\r
771   CanIf_ChannelGetModeType mode;\r
772   CanIf_Arc_ChannelIdType channel = CanIf_Arc_FindHrhChannel(Hrh);\r
773   if (channel == -1)  // Invalid HRH\r
774   {\r
775     return;\r
776   }\r
777 \r
778   if (CanIf_GetPduMode(channel, &mode) == E_OK)\r
779   {\r
780     if ( (mode == CANIF_GET_OFFLINE) || (mode == CANIF_GET_TX_ONLINE) ||\r
781         (mode == CANIF_GET_OFFLINE_ACTIVE) )\r
782     {\r
783       // Receiver path is disabled so just drop it\r
784       return;\r
785     }\r
786   }\r
787   else\r
788   {\r
789     return;  // No mode so just return\r
790   }\r
791 \r
792   const CanIf_RxPduConfigType *entry = CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr;\r
793 \r
794   /* Find the CAN id in the RxPduList */\r
795   for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds; i++)\r
796   {\r
797     if (entry->CanIfCanRxPduHrhRef->CanIfHrhIdSymRef == Hrh)\r
798     {\r
799       // Software filtering\r
800       if (entry->CanIfCanRxPduHrhRef->CanIfHrhType == CAN_ARC_HANDLE_TYPE_BASIC)\r
801       {\r
802         if (entry->CanIfCanRxPduHrhRef->CanIfSoftwareFilterHrh)\r
803         {\r
804           if (entry->CanIfSoftwareFilterType == CANIF_SOFTFILTER_TYPE_MASK)\r
805           {\r
806             if ((CanId & entry->CanIfCanRxPduCanIdMask ) ==\r
807                 ( entry->CanIfCanRxPduCanId & entry->CanIfCanRxPduCanIdMask))\r
808             {\r
809               // We found a pdu so call higher layers\r
810             }\r
811             else\r
812             {\r
813               entry++;\r
814               continue; // Go to next entry
815             }\r
816           }\r
817           else\r
818           {\r
819             DET_REPORTERROR(MODULE_ID_CAN, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);\r
820             continue; // Not a supported filter type, so just drop the frame\r
821           }\r
822         }\r
823       }\r
824 \r
825 #if (CANIF_DLC_CHECK == STD_ON)\r
826       if (CanDlc < entry->CanIfCanRxPduDlc)\r
827       {\r
828         VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_DLC);\r
829         return;\r
830       }\r
831 #endif\r
832 \r
833       switch (entry->CanIfRxUserType)\r
834       {\r
835         case CANIF_USER_TYPE_CAN_SPECIAL:\r
836         {\r
837           ( (CanIf_FuncTypeCanSpecial)(entry->CanIfUserRxIndication) )(
838             entry->CanIfCanRxPduHrhRef->CanIfCanControllerHrhIdRef,
839             entry->CanIfCanRxPduId,
840             CanSduPtr,
841             CanDlc,
842             CanId);
843
844             return;\r
845         }\r
846         break;\r
847 \r
848         case CANIF_USER_TYPE_CAN_NM:\r
849 #if defined(USE_CANNM)\r
850                 CanNm_RxIndication(entry->CanIfCanRxPduId,CanSduPtr);\r
851                 return;\r
852 #endif\r
853                 break;\r
854 \r
855         case CANIF_USER_TYPE_CAN_PDUR:\r
856             // Send Can frame to PDU router\r
857 #if defined(USE_PDUR)\r
858             PduR_CanIfRxIndication(entry->CanIfCanRxPduId,CanSduPtr);\r
859             return;\r
860 #endif\r
861             break;\r
862 \r
863         case CANIF_USER_TYPE_CAN_TP:\r
864           // Send Can frame to CAN TP\r
865 #if defined(USE_CANTP)\r
866             {\r
867                     PduInfoType CanTpRxPdu;\r
868                     CanTpRxPdu.SduLength = CanDlc;\r
869                     CanTpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;\r
870                 CanTp_RxIndication(entry->CanIfCanRxPduId, &CanTpRxPdu);\r
871             }\r
872             return;\r
873 #endif\r
874             break;\r
875       }\r
876     }\r
877 \r
878     entry++;\r
879   }\r
880 \r
881   // Did not find the PDU, something is wrong\r
882   VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_LPDU);\r
883 }\r
884 \r
885 #if ( CANIF_TRANSMIT_CANCELLATION == STD_ON )\r
886 void CanIf_CancelTxConfirmation(const Can_PduType *PduInfoPtr)\r
887 {\r
888   VALIDATE(FALSE, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_NOK_NOSUPPORT);\r
889   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_UNINIT);\r
890   VALIDATE_NO_RV(PduInfoPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);\r
891 \r
892   const CanIf_TxPduConfigType *entry =\r
893     CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr;\r
894 \r
895   // Not supported\r
896 \r
897   // Did not find the PDU, something is wrong\r
898   VALIDATE_NO_RV(FALSE, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);\r
899 }\r
900 #endif\r
901 \r
902 void CanIf_ControllerBusOff(uint8 Controller)\r
903 {\r
904   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
905   CanIf_Arc_ChannelIdType channel = Controller;\r
906 \r
907   VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_UNINIT );\r
908   VALIDATE_NO_RV( Controller < CANIF_CHANNEL_CNT, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_PARAM_CONTROLLER );\r
909 \r
910   // According to figure 35 in canif spec this should be done in\r
911   // Can driver but it is better to do it here\r
912   CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);\r
913 \r
914   if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)\r
915   {\r
916     CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);\r
917   }\r
918 }\r
919 \r
920 void CanIf_SetWakeupEvent(uint8 Controller)\r
921 {\r
922 #if  ( CANIF_DEV_ERROR_DETECT == STD_ON )\r
923   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
924   CanIf_Arc_ChannelIdType channel = Controller;\r
925 #endif\r
926 \r
927   VALIDATE_NO_RV(FALSE, CANIF_SETWAKEUPEVENT_ID, CANIF_E_NOK_NOSUPPORT);\r
928   VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_SETWAKEUPEVENT_ID, CANIF_E_UNINIT );\r
929   VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_SETWAKEUPEVENT_ID, CANIF_E_PARAM_CONTROLLER );\r
930 \r
931   // Not supported\r
932 }\r
933 \r
934 void CanIf_Arc_Error(uint8 Controller, Can_Arc_ErrorType Error)\r
935 {\r
936 #if  ( CANIF_DEV_ERROR_DETECT == STD_ON )\r
937   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
938   CanIf_Arc_ChannelIdType channel = Controller;\r
939 #endif\r
940 \r
941   VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_ARCERROR_ID, CANIF_E_UNINIT );\r
942   VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_ARCERROR_ID, CANIF_E_PARAM_CONTROLLER );\r
943 \r
944   if (CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton != NULL)\r
945   {\r
946     CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton(Controller, Error);\r
947   }\r
948 }\r
949 uint8 CanIf_Arc_GetChannelDefaultConfIndex(CanIf_Arc_ChannelIdType Channel)
950 {
951         return CanIf_Config.Arc_ChannelDefaultConfIndex[Channel];
952 };
953