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