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