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