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