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