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