]> rtime.felk.cvut.cz Git - arc.git/blob - communication/CanIf/CanIf.c
Fixed unused function warning when not using runtime configuration of pdu ids in...
[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 (CanIf_Arc_ChannelIdType) -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 = (CanIf_Arc_ChannelIdType) 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 = (CanIf_Arc_ChannelIdType) 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 = (CanIf_Arc_ChannelIdType) 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 = (CanIf_Arc_ChannelIdType) 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
352 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )\r
353 CanIf_RxPduConfigType * CanIf_FindRxPduEntry(PduIdType id) {\r
354         if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds) {\r
355                 return NULL;\r
356         } else {\r
357                 return &CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr[id];\r
358         }\r
359 }\r
360
361 const CanIf_HrhConfigType* CanIf_Arc_GetReceiveHandler(CanIf_Arc_ChannelIdType Channel) {
362   const CanIf_InitHohConfigType *hohConfig;
363   const CanIf_HrhConfigType *hrhConfig;
364
365   // foreach(hoh){ foreach(hrh in hoh) {} }
366   hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
367   hohConfig--;
368   do
369   {
370         hohConfig++;
371
372         hrhConfig = hohConfig->CanIfHrhConfig;
373     hrhConfig--;
374     do
375     {
376       hrhConfig++;
377       if (hrhConfig->CanIfCanControllerHrhIdRef == Channel)
378         return hrhConfig;
379         } while(!hrhConfig->CanIf_Arc_EOL);
380
381   } while(!hohConfig->CanIf_Arc_EOL);
382
383   DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HRH);
384
385   return NULL;
386 }
387
388 const CanIf_HthConfigType* CanIf_Arc_GetTransmitHandler(CanIf_Arc_ChannelIdType Channel) {
389   const CanIf_InitHohConfigType *hohConfig;
390   const CanIf_HthConfigType *hthConfig;
391
392   // foreach(hoh){ foreach(hrh in hoh) {} }
393   hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
394   hohConfig--;
395   do
396   {
397         hohConfig++;
398
399         hthConfig = hohConfig->CanIfHthConfig;
400         hthConfig--;
401     do
402     {
403         hthConfig++;
404       if (hthConfig->CanIfCanControllerIdRef == Channel)
405         return hthConfig;
406         } while(!hthConfig->CanIf_Arc_EOL);
407
408   } while(!hohConfig->CanIf_Arc_EOL);
409
410   DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HTH);
411
412   return NULL;
413 }
414 #endif
415
416 //-------------------------------------------------------------------\r
417 \r
418 Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId,\r
419     const PduInfoType *PduInfoPtr)\r
420 {\r
421   Can_PduType canPdu;\r
422   const CanIf_TxPduConfigType *txEntry;\r
423   CanIf_ControllerModeType csMode;\r
424   CanIf_ChannelGetModeType pduMode;\r
425 \r
426   VALIDATE(CanIf_Global.initRun, CANIF_TRANSMIT_ID, CANIF_E_UNINIT );\r
427   VALIDATE((PduInfoPtr != 0), CANIF_TRANSMIT_ID, CANIF_E_PARAM_POINTER );\r
428 \r
429   // Get the controller from L-PDU handle\r
430   txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
431 \r
432   if (txEntry == 0)\r
433   {\r
434     VALIDATE(FALSE, CANIF_TRANSMIT_ID, CANIF_E_INVALID_TXPDUID);\r
435     return E_NOT_OK;\r
436   }\r
437 \r
438   CanIf_Arc_ChannelIdType channel = txEntry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef;\r
439 \r
440   // Get and verify the controller mode\r
441   if (CanIf_GetControllerMode(channel, &csMode) == E_NOT_OK){\r
442     return E_NOT_OK;\r
443   }\r
444 \r
445   if (csMode != CANIF_CS_STARTED){  // CANIF_161\r
446     return E_NOT_OK;\r
447   }\r
448 \r
449   // Get and verify the PDU channel mode control\r
450   if (CanIf_GetPduMode(channel, &pduMode) == E_NOT_OK){\r
451     return E_NOT_OK;\r
452   }\r
453 \r
454   if ((pduMode != CANIF_GET_TX_ONLINE) && (pduMode != CANIF_GET_ONLINE)){\r
455     return E_NOT_OK;\r
456   }\r
457 \r
458   canPdu.id = txEntry->CanIfCanTxPduIdCanId;\r
459 \r
460   canPdu.length = PduInfoPtr->SduLength;\r
461   canPdu.sdu = PduInfoPtr->SduDataPtr;\r
462   canPdu.swPduHandle = CanTxPduId;\r
463 \r
464   Can_ReturnType rVal = Can_Write(txEntry->CanIfCanTxPduHthRef->CanIfHthIdSymRef, &canPdu);\r
465 \r
466   if (rVal == CAN_NOT_OK){\r
467     return E_NOT_OK;\r
468   }\r
469 \r
470   if (rVal == CAN_BUSY)  // CANIF 082, CANIF 161\r
471   {\r
472     // Tx buffering not supported so just return.\r
473     return E_NOT_OK;\r
474   }\r
475 \r
476   return E_OK;\r
477 }\r
478 \r
479 //-------------------------------------------------------------------\r
480 \r
481 #if ( CANIF_READRXPDU_DATA_API == STD_ON )\r
482 Std_ReturnType CanIf_ReadRxPduData(PduIdType CanRxPduId,\r
483     PduInfoType *PduInfoPtr)\r
484 {\r
485   VALIDATE(FALSE, CANIF_READTXPDUDATA_ID, CANIF_E_NOK_NOSUPPORT);\r
486   VALIDATE(CanIf_Global.initRun == STD_ON, CANIF_READTXPDUDATA_ID, CANIF_E_UNINIT );\r
487   VALIDATE(PduInfoPtr != 0, CANIF_READTXPDUDATA_ID, CANIF_E_PARAM_POINTER );\r
488 \r
489   // This function is not supported\r
490 \r
491   return E_NOT_OK;\r
492 }\r
493 #endif\r
494 \r
495 //-------------------------------------------------------------------\r
496 \r
497 #if ( CANIF_READTXPDU_NOTIFY_STATUS_API == STD_ON )\r
498 CanIf_NotifStatusType CanIf_ReadTxNotifStatus(PduIdType CanTxPduId)\r
499 {\r
500   const CanIf_TxPduConfigType *txEntry;\r
501   VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);\r
502   VALIDATE(CanIf_Global.initRun, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_UNINIT );\r
503 \r
504   // Get the controller from L-PDU handle\r
505   txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
506 \r
507   if (txEntry == 0)\r
508   {\r
509     VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);\r
510     return CANIF_NO_NOTIFICATION;\r
511   }\r
512 \r
513   if (txEntry->CanIfReadTxPduNotifyStatus == FALSE)\r
514   {\r
515     VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);\r
516     return CANIF_NO_NOTIFICATION;\r
517   }\r
518 \r
519   // This function is not supported\r
520 \r
521   return CANIF_NO_NOTIFICATION;\r
522 }\r
523 #endif\r
524 \r
525 //-------------------------------------------------------------------\r
526 \r
527 #if ( CANIF_READRXPDU_NOTIFY_STATUS_API == STD_ON )\r
528 CanIf_NotifStatusType CanIf_ReadRxNotifStatus(PduIdType CanRxPduId)\r
529 {\r
530   VALIDATE(FALSE, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);\r
531   VALIDATE(CanIf_Global.initRun, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_UNINIT );\r
532 \r
533   return CANIF_NO_NOTIFICATION;\r
534 }\r
535 #endif\r
536 \r
537 //-------------------------------------------------------------------\r
538 \r
539 Std_ReturnType CanIf_SetPduMode(uint8 Controller,\r
540     CanIf_ChannelSetModeType PduModeRequest)\r
541 {\r
542   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
543   CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
544 \r
545   VALIDATE( CanIf_Global.initRun, CANIF_SETPDUMODE_ID, CANIF_E_UNINIT );\r
546   VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );\r
547 \r
548   CanIf_ChannelGetModeType oldMode = CanIf_Global.channelData[channel].PduMode;\r
549 \r
550   switch(PduModeRequest)\r
551   {\r
552   case CANIF_SET_OFFLINE:\r
553     CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
554     break;\r
555   case CANIF_SET_RX_OFFLINE:\r
556     if (oldMode == CANIF_GET_RX_ONLINE){\r
557       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
558     } else if (oldMode == CANIF_GET_ONLINE){\r
559       CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
560     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE){\r
561       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
562     }\r
563 \r
564     // Other oldmodes don't care\r
565     break;\r
566   case CANIF_SET_RX_ONLINE:\r
567     if (oldMode == CANIF_GET_OFFLINE){\r
568       CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
569     } else if (oldMode == CANIF_GET_TX_ONLINE) {\r
570       CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
571     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE){\r
572       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
573     }\r
574 \r
575     // Other oldmodes don't care\r
576     break;\r
577   case CANIF_SET_TX_OFFLINE:\r
578     if (oldMode == CANIF_GET_TX_ONLINE){\r
579       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
580     } else if (oldMode == CANIF_GET_ONLINE) {\r
581       CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
582     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {\r
583       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;\r
584     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {\r
585       CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;\r
586     }\r
587 \r
588     // Other oldmodes don't care\r
589     break;\r
590   case CANIF_SET_TX_ONLINE:\r
591     if (oldMode == CANIF_GET_OFFLINE){\r
592       CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
593     } else if (oldMode == CANIF_GET_RX_ONLINE) {\r
594       CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
595     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {\r
596       CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;\r
597     } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {\r
598       CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
599     }\r
600 \r
601     // Other oldmodes don't care\r
602     break;\r
603   case CANIF_SET_ONLINE:\r
604     CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;\r
605     break;\r
606 \r
607   case CANIF_SET_TX_OFFLINE_ACTIVE:\r
608     if (oldMode == CANIF_GET_OFFLINE) {\r
609       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
610     } else if (oldMode == CANIF_GET_RX_ONLINE) {\r
611       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
612     } else if (oldMode == CANIF_GET_TX_ONLINE) {\r
613       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;\r
614     } else if (oldMode == CANIF_GET_ONLINE) {\r
615       CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;\r
616     }\r
617 \r
618     // Other oldmodes don't care\r
619     break;\r
620   }\r
621 \r
622   return E_OK;\r
623 }\r
624 \r
625 //-------------------------------------------------------------------\r
626 \r
627 Std_ReturnType CanIf_GetPduMode(uint8 Controller,\r
628     CanIf_ChannelGetModeType *PduModePtr)\r
629 {\r
630   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
631   CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
632 \r
633   VALIDATE( CanIf_Global.initRun, CANIF_GETPDUMODE_ID, CANIF_E_UNINIT );\r
634   VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_GETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );\r
635 \r
636   *PduModePtr = CanIf_Global.channelData[channel].PduMode;\r
637 \r
638   return E_OK;\r
639 }\r
640 \r
641 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )
642 void CanIf_SetDynamicTxId(PduIdType CanTxPduId, Can_IdType CanId)\r
643 {\r
644   CanIf_TxPduConfigType *txEntry;\r
645   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_SETDYNAMICTX_ID, CANIF_E_UNINIT );\r
646 \r
647   // Get the controller from L-PDU handle\r
648   txEntry = CanIf_FindTxPduEntry(CanTxPduId);\r
649 \r
650   if (txEntry == 0)\r
651   {\r
652     VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);\r
653     return;\r
654   }\r
655 \r
656   // Check that this is a dymanic PDU\r
657   if (txEntry->CanIfCanTxPduType != ARC_PDU_TYPE_DYNAMIC)\r
658   {\r
659     VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);\r
660     return;\r
661   }\r
662 \r
663   // Check that this is an extended or standard id\r
664   if (((CanId & U0x80000000) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_29)) ||\r
665       (((CanId & U0x80000000) == 0) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_11)))\r
666   {\r
667     // Update the CanID\r
668     //txEntry->CanIfCanTxPduIdCanId = CanId;  // TODO How do we fix this from a const pointer\r
669 \r
670     // NOT SUPPORTED\r
671   }\r
672   else\r
673   {\r
674     // Inavlid Canid to configuration\r
675     VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_PARAM_CANID);\r
676   }\r
677 }\r
678 #endif\r
679 \r
680 #if ( CANIF_TRANSCEIVER_API == STD_ON )\r
681 Std_ReturnType CanIf_SetTransceiverMode(uint8 Transceiver,\r
682     CanIf_TransceiverModeType TransceiverMode)\r
683 {\r
684   VALIDATE(FALSE, CANIF_SET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
685 // Not supported\r
686 \r
687   return E_NOT_OK;\r
688 }\r
689 \r
690 Std_ReturnType CanIf_GetTransceiverMode(uint8 Transceiver,\r
691     CanIf_TransceiverModeType *TransceiverModePtr)\r
692 {\r
693   VALIDATE(FALSE, CANIF_GET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
694   // Not supported\r
695 \r
696   return E_NOT_OK;\r
697 }\r
698 \r
699 Std_ReturnType CanIf_GetTrcvWakeupReason(uint8 Transceiver,\r
700     CanIf_TrcvWakeupReasonType *TrcvWuReasonPtr)\r
701 {\r
702   VALIDATE(FALSE, CANIF_GET_TRCVMODEREASON_ID, CANIF_E_NOK_NOSUPPORT);\r
703   // Not supported\r
704 \r
705   return E_NOT_OK;\r
706 }\r
707 \r
708 Std_ReturnType CanIf_SetTransceiverWakeupMode(uint8 Transceiver,\r
709     CanIf_TrcvWakeupModeType *TrcvWakeupMode)\r
710 {\r
711   VALIDATE(FALSE, CANIF_SET_TRANSCEIVERWAKEMODE_ID, CANIF_E_NOK_NOSUPPORT);\r
712   // Not supported\r
713 \r
714   return E_NOT_OK;\r
715 }\r
716 #endif\r
717 \r
718 #if ( CANIF_WAKEUP_EVENT_API == STD_ON )\r
719 Std_ReturnType CanIf_CheckWakeup(EcuM_WakeupSourceType WakeupSource)\r
720 {\r
721   VALIDATE(FALSE, CANIF_CHECKWAKEUP_ID, CANIF_E_NOK_NOSUPPORT);\r
722   // Not supported\r
723 \r
724   return E_NOT_OK;\r
725 }\r
726 \r
727 Std_ReturnType CanIf_CheckValidation(EcuM_WakeupSourceType WakeupSource)\r
728 {\r
729   VALIDATE(FALSE, CANIF_CHECKVALIDATION_ID, CANIF_E_NOK_NOSUPPORT);\r
730   // Not supported\r
731 \r
732   return E_NOT_OK;\r
733 }\r
734 #endif\r
735 \r
736 /*\r
737  * Callback interface from driver\r
738  */\r
739 void CanIf_TxConfirmation(PduIdType canTxPduId)\r
740 {\r
741   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_TXCONFIRMATION_ID, CANIF_E_UNINIT)\r
742   VALIDATE_NO_RV(canTxPduId < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);\r
743 \r
744   const CanIf_TxPduConfigType* entry =\r
745     &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[canTxPduId];\r
746 \r
747       if (entry->CanIfUserTxConfirmation != NULL)\r
748       {\r
749         CanIf_ChannelGetModeType mode;\r
750         CanIf_GetPduMode(entry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef, &mode);\r
751         if ((mode == CANIF_GET_TX_ONLINE) || (mode == CANIF_GET_ONLINE)\r
752             || (mode == CANIF_GET_OFFLINE_ACTIVE) || (mode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) )\r
753         {\r
754           entry->CanIfUserTxConfirmation(entry->CanIfTxPduId);  /* CANIF053 */\r
755         }\r
756       }\r
757       return;\r
758 }\r
759 \r
760 void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc,\r
761               const uint8 *CanSduPtr)\r
762 {\r
763   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_RXINDICATION_ID, CANIF_E_UNINIT);\r
764   VALIDATE_NO_RV(CanSduPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);\r
765 \r
766   /* Check PDU mode before continue processing */\r
767   CanIf_ChannelGetModeType mode;\r
768   CanIf_Arc_ChannelIdType channel = CanIf_Arc_FindHrhChannel( (Can_Arc_HRHType) Hrh);\r
769   if (channel == -1)  // Invalid HRH\r
770   {\r
771     return;\r
772   }\r
773 \r
774   if (CanIf_GetPduMode(channel, &mode) == E_OK)\r
775   {\r
776     if ( (mode == CANIF_GET_OFFLINE) || (mode == CANIF_GET_TX_ONLINE) ||\r
777         (mode == CANIF_GET_OFFLINE_ACTIVE) )\r
778     {\r
779       // Receiver path is disabled so just drop it\r
780       return;\r
781     }\r
782   }\r
783   else\r
784   {\r
785     return;  // No mode so just return\r
786   }\r
787 \r
788   const CanIf_RxPduConfigType *entry = CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr;\r
789 \r
790   /* Find the CAN id in the RxPduList */\r
791   for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds; i++)\r
792   {\r
793     if (entry->CanIfCanRxPduHrhRef->CanIfHrhIdSymRef == Hrh)\r
794     {\r
795       // Software filtering\r
796       if (entry->CanIfCanRxPduHrhRef->CanIfHrhType == CAN_ARC_HANDLE_TYPE_BASIC)\r
797       {\r
798         if (entry->CanIfCanRxPduHrhRef->CanIfSoftwareFilterHrh)\r
799         {\r
800           if (entry->CanIfSoftwareFilterType == CANIF_SOFTFILTER_TYPE_MASK)\r
801           {\r
802             if ((CanId & entry->CanIfCanRxPduCanIdMask ) ==\r
803                 ( entry->CanIfCanRxPduCanId & entry->CanIfCanRxPduCanIdMask))\r
804             {\r
805               // We found a pdu so call higher layers\r
806             }\r
807             else\r
808             {\r
809               entry++;\r
810               continue; // Go to next entry
811             }\r
812           }\r
813           else\r
814           {\r
815             DET_REPORTERROR(MODULE_ID_CAN, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);\r
816             continue; // Not a supported filter type, so just drop the frame\r
817           }\r
818         }\r
819       }\r
820 \r
821 #if (CANIF_DLC_CHECK == STD_ON)\r
822       if (CanDlc < entry->CanIfCanRxPduDlc)\r
823       {\r
824         VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_DLC);\r
825         return;\r
826       }\r
827 #endif\r
828 \r
829       switch (entry->CanIfRxUserType)\r
830       {\r
831         case CANIF_USER_TYPE_CAN_SPECIAL:\r
832         {\r
833           ( (CanIf_FuncTypeCanSpecial)(entry->CanIfUserRxIndication) )(
834             entry->CanIfCanRxPduHrhRef->CanIfCanControllerHrhIdRef,
835             entry->CanIfCanRxPduId,
836             CanSduPtr,
837             CanDlc,
838             CanId);
839
840             return;\r
841         }\r
842         break;\r
843 \r
844         case CANIF_USER_TYPE_CAN_NM:\r
845 #if defined(USE_CANNM)\r
846                 CanNm_RxIndication(entry->CanIfCanRxPduId,CanSduPtr);\r
847                 return;\r
848 #endif\r
849                 break;\r
850 \r
851         case CANIF_USER_TYPE_CAN_PDUR:\r
852             // Send Can frame to PDU router\r
853 #if defined(USE_PDUR)\r
854                 {\r
855                         PduInfoType pduInfo;\r
856                         pduInfo.SduLength = CanDlc;\r
857                         pduInfo.SduDataPtr = (uint8 *)CanSduPtr;\r
858                 PduR_CanIfRxIndication(entry->CanIfCanRxPduId,&pduInfo);\r
859                 }\r
860             return;\r
861 #endif\r
862             break;\r
863 \r
864         case CANIF_USER_TYPE_CAN_TP:\r
865           // Send Can frame to CAN TP\r
866 #if defined(USE_CANTP)\r
867             {\r
868                     PduInfoType CanTpRxPdu;\r
869                     CanTpRxPdu.SduLength = CanDlc;\r
870                     CanTpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;\r
871                 CanTp_RxIndication(entry->CanIfCanRxPduId, &CanTpRxPdu);\r
872             }\r
873             return;\r
874 #endif\r
875             break;\r
876       }\r
877     }\r
878 \r
879     entry++;\r
880   }\r
881 \r
882   // Did not find the PDU, something is wrong\r
883   VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_LPDU);\r
884 }\r
885 \r
886 #if ( CANIF_TRANSMIT_CANCELLATION == STD_ON )\r
887 void CanIf_CancelTxConfirmation(const Can_PduType *PduInfoPtr)\r
888 {\r
889   VALIDATE(FALSE, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_NOK_NOSUPPORT);\r
890   VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_UNINIT);\r
891   VALIDATE_NO_RV(PduInfoPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);\r
892 \r
893   const CanIf_TxPduConfigType *entry =\r
894     CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr;\r
895 \r
896   // Not supported\r
897 \r
898   // Did not find the PDU, something is wrong\r
899   VALIDATE_NO_RV(FALSE, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);\r
900 }\r
901 #endif\r
902 \r
903 void CanIf_ControllerBusOff(uint8 Controller)\r
904 {\r
905   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
906   CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
907 \r
908   VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_UNINIT );\r
909   VALIDATE_NO_RV( Controller < CANIF_CHANNEL_CNT, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_PARAM_CONTROLLER );\r
910 \r
911   // According to figure 35 in canif spec this should be done in\r
912   // Can driver but it is better to do it here\r
913   CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);\r
914 \r
915   if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)\r
916   {\r
917     CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);\r
918   }\r
919 }\r
920 \r
921 void CanIf_SetWakeupEvent(uint8 Controller)\r
922 {\r
923 #if  ( CANIF_DEV_ERROR_DETECT == STD_ON )\r
924   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
925   CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;\r
926 #else\r
927   (void)Controller;\r
928 #endif\r
929 \r
930   VALIDATE_NO_RV(FALSE, CANIF_SETWAKEUPEVENT_ID, CANIF_E_NOK_NOSUPPORT);\r
931   VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_SETWAKEUPEVENT_ID, CANIF_E_UNINIT );\r
932   VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_SETWAKEUPEVENT_ID, CANIF_E_PARAM_CONTROLLER );\r
933 \r
934   // Not supported\r
935 }\r
936 \r
937 void CanIf_Arc_Error(uint8 Controller, Can_Arc_ErrorType Error)\r
938 {\r
939 #if  ( CANIF_DEV_ERROR_DETECT == STD_ON )\r
940   // We call this a CanIf channel. Hopefully makes it easier to follow.\r
941   CanIf_Arc_ChannelIdType channel = Controller;\r
942 #endif\r
943 \r
944   VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_ARCERROR_ID, CANIF_E_UNINIT );\r
945   VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_ARCERROR_ID, CANIF_E_PARAM_CONTROLLER );\r
946 \r
947   if (CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton != NULL)\r
948   {\r
949     CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton(Controller, Error);\r
950   }\r
951 }\r
952 \r
953 uint8 CanIf_Arc_GetChannelDefaultConfIndex(CanIf_Arc_ChannelIdType Channel)
954 {
955         return CanIf_Config.Arc_ChannelDefaultConfIndex[Channel];
956 }
957