1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\r
6 * This source code is free software; you can redistribute it and/or modify it
\r
7 * under the terms of the GNU General Public License version 2 as published by the
\r
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
\r
10 * This program is distributed in the hope that it will be useful, but
\r
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
\r
14 * -------------------------------- Arctic Core ------------------------------*/
\r
27 #include "CanIf_Cbk.h"
\r
33 #if defined(USE_CANTP)
\r
34 #include "CanTp_Cbk.h"
\r
37 #if defined(USE_J1939TP)
\r
38 #include "J1939Tp_Cbk.h"
\r
41 #if defined(USE_CANNM)
\r
46 // TODO: Include upper layer functions, See CANIF208 and CANIF233
\r
47 #include "PduR_CanIf.h"
\r
51 #include "PduR_Cbk.h"
\r
52 #include "CanNm_Cbk.h"
\r
53 #include "CanTp_Cbk.h"
\r
56 #if ( CANIF_DEV_ERROR_DETECT == STD_ON )
\r
57 #define VALIDATE(_exp,_api,_err ) \
\r
59 Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \
\r
63 #define VALIDATE_NO_RV(_exp,_api,_err ) \
\r
65 Det_ReportError(MODULE_ID_CANIF, 0, _api, _err); \
\r
68 #define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)
\r
71 #define VALIDATE(_exp,_api,_err )
\r
72 #define VALIDATE_NO_RV(_exp,_api,_err )
\r
73 #define DET_REPORTERROR(_x,_y,_z,_q)
\r
77 // Helper to get the Can Controller refered to by a CanIf Channel
\r
78 #define ARC_GET_CHANNEL_CONTROLLER(_channel) \
\r
79 CanIf_ConfigPtr->Arc_ChannelToControllerMap[_channel]
\r
81 /* Global configure */
\r
82 static const CanIf_ConfigType *CanIf_ConfigPtr;
\r
84 // Struct of controller private data.
\r
87 CanIf_ControllerModeType ControllerMode;
\r
88 CanIf_ChannelGetModeType PduMode;
\r
89 } CanIf_ChannelPrivateType;
\r
94 CanIf_ChannelPrivateType channelData[CANIF_CHANNEL_CNT];
\r
97 void CanIf_PreInit_InitController(uint8 Controller, uint8 ConfigurationIndex);
\r
99 static CanIf_Arc_ChannelIdType CanIf_Arc_FindHrhChannel( Can_Arc_HRHType hrh )
\r
101 const CanIf_InitHohConfigType *hohConfig;
\r
102 const CanIf_HrhConfigType *hrhConfig;
\r
104 // foreach(hoh){ foreach(hrh in hoh) {} }
\r
105 hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
\r
111 hrhConfig = hohConfig->CanIfHrhConfig;
\r
116 if (hrhConfig->CanIfHrhIdSymRef == hrh){
\r
117 return hrhConfig->CanIfCanControllerHrhIdRef;
\r
119 } while(!hrhConfig->CanIf_Arc_EOL);
\r
120 } while(!hohConfig->CanIf_Arc_EOL);
\r
122 DET_REPORTERROR(MODULE_ID_CANIF, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);
\r
124 return (CanIf_Arc_ChannelIdType) -1;
\r
128 CanIf_GlobalType CanIf_Global;
\r
130 void CanIf_Init(const CanIf_ConfigType *ConfigPtr)
\r
132 VALIDATE_NO_RV(ConfigPtr != 0, CANIF_INIT_ID, CANIF_E_PARAM_POINTER); // Only PostBuild case supported
\r
134 CanIf_ConfigPtr = ConfigPtr;
\r
136 for (uint8 i = 0; i < CANIF_CHANNEL_CNT; i++)
\r
138 CanIf_Global.channelData[i].ControllerMode = CANIF_CS_STOPPED;
\r
139 CanIf_Global.channelData[i].PduMode = CANIF_GET_OFFLINE;
\r
140 CanIf_PreInit_InitController(i, CanIf_ConfigPtr->Arc_ChannelDefaultConfIndex[i]);
\r
144 CanIf_Global.initRun = TRUE;
\r
150 //-------------------------------------------------------------------
\r
152 * Controller :: CanIf_Arc_ChannelIdType (CanIf-specific id to abstract from Can driver/controllers)
\r
153 * ConfigurationIndex :: CanIf_Arc_ConfigurationIndexType
\r
155 void CanIf_InitController(uint8 Controller, uint8 ConfigurationIndex)
\r
157 // We call this a CanIf channel. Hopefully makes it easier to follow.
\r
158 CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;
\r
159 CanIf_ControllerModeType mode;
\r
161 VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_INIT_CONTROLLER_ID, CANIF_E_UNINIT );
\r
162 VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
\r
163 VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_POINTER);
\r
165 if (CanIf_GetControllerMode(channel, &mode) == E_OK)
\r
167 if (mode == CANIF_CS_STARTED)
\r
169 CanIf_SetControllerMode(channel, CANIF_CS_STOPPED); // CANIF092
\r
171 else if (mode != CANIF_CS_STOPPED)
\r
173 VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE); // CANIF092
\r
178 VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE);
\r
181 // CANIF293: ..Subsequently the CAN Interface calls the corresponding
\r
182 // CAN Driver initialization services.
\r
184 // CANIF066: The CAN Interface has access to the CAN Driver configuration data. All
\r
185 // public CAN Driver configuration data are described in [8] Specification of CAN Driver.
\r
187 // Grab the configuration from the Can Controller
\r
188 const Can_ControllerConfigType *canConfig;
\r
189 const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);
\r
191 // Validate that the configuration at the index match the right channel
\r
192 VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
\r
194 canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;
\r
196 // Validate that the CanIfControllerConfig points to configuration for the right Can Controller
\r
197 VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
\r
199 Can_InitController(canControllerId, canConfig);
\r
201 // Set mode to stopped
\r
202 CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);
\r
205 void CanIf_PreInit_InitController(uint8 Controller, uint8 ConfigurationIndex){
\r
206 // We call this a CanIf channel. Hopefully makes it easier to follow.
\r
207 CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;
\r
209 VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_ID, CANIF_E_PARAM_CONTROLLER);
\r
210 VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_ID, CANIF_E_PARAM_POINTER);
\r
213 const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);
\r
214 // Validate that the configuration at the index match the right channel
\r
215 VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
\r
216 const Can_ControllerConfigType *canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;
\r
217 // Validate that the CanIfControllerConfig points to configuration for the right Can Controller
\r
218 VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
\r
220 Can_InitController(canControllerId, canConfig);
\r
223 //-------------------------------------------------------------------
\r
225 Std_ReturnType CanIf_SetControllerMode(uint8 Controller,
\r
226 CanIf_ControllerModeType ControllerMode)
\r
228 // We call this a CanIf channel. Hopefully makes it easier to follow.
\r
229 CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;
\r
232 CanIf_ControllerModeType oldMode;
\r
234 VALIDATE( CanIf_Global.initRun, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );
\r
235 VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );
\r
237 oldMode = CanIf_Global.channelData[channel].ControllerMode;
\r
239 if (oldMode == CANIF_CS_UNINIT)
\r
241 VALIDATE(FALSE, CANIF_SET_CONTROLLER_MODE_ID, CANIF_E_UNINIT); // See figure 32, 33
\r
244 CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(Controller);
\r
245 switch (ControllerMode)
\r
247 case CANIF_CS_STARTED: // Figure 32
\r
251 case CANIF_CS_SLEEP:
\r
252 if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){
\r
255 CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;
\r
258 // Just fall through
\r
262 CanIf_SetPduMode(channel, CANIF_SET_ONLINE);
\r
263 if (Can_SetControllerMode(canControllerId, CAN_T_START) == CAN_NOT_OK){
\r
266 CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STARTED;
\r
270 case CANIF_CS_SLEEP: // Figure 33
\r
273 case CANIF_CS_STARTED:
\r
274 if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){
\r
277 CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;
\r
280 // Just fall through for other cases
\r
284 if (Can_SetControllerMode(canControllerId, CAN_T_SLEEP) == CAN_NOT_OK){
\r
287 CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_SLEEP;
\r
290 case CANIF_CS_STOPPED:
\r
294 case CANIF_CS_SLEEP:
\r
295 if (Can_SetControllerMode(canControllerId, CAN_T_WAKEUP) == CAN_NOT_OK){
\r
300 // Just fall through for other cases
\r
304 CanIf_SetPduMode(channel, CANIF_SET_OFFLINE);
\r
305 if (Can_SetControllerMode(canControllerId, CAN_T_STOP) == CAN_NOT_OK){
\r
308 CanIf_Global.channelData[channel].ControllerMode = CANIF_CS_STOPPED;
\r
312 case CANIF_CS_UNINIT:
\r
313 // Just fall through
\r
319 //-------------------------------------------------------------------
\r
321 Std_ReturnType CanIf_GetControllerMode(uint8 Controller,
\r
322 CanIf_ControllerModeType *ControllerModePtr)
\r
324 // We call this a CanIf channel. Hopefully makes it easier to follow.
\r
325 CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;
\r
327 VALIDATE(CanIf_Global.initRun, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_UNINIT );
\r
328 VALIDATE(channel < CANIF_CHANNEL_CNT, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_CONTROLLER );
\r
329 VALIDATE(ControllerModePtr != NULL, CANIF_GET_CONTROLLER_MODE_ID, CANIF_E_PARAM_POINTER );
\r
331 *ControllerModePtr = CanIf_Global.channelData[channel].ControllerMode;
\r
336 //-------------------------------------------------------------------
\r
338 * Matches a Tx PDU id agaist the ones that are in the database.
\r
340 * @returns Ptr a TxPdu
\r
342 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )
\r
343 CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)
\r
345 static const CanIf_TxPduConfigType * CanIf_FindTxPduEntry(PduIdType id)
\r
348 if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds) {
\r
351 return &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[id];
\r
356 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )
\r
357 CanIf_RxPduConfigType * CanIf_FindRxPduEntry(PduIdType id) {
\r
358 if (id >= CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds) {
\r
361 return &CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr[id];
\r
365 const CanIf_HrhConfigType* CanIf_Arc_GetReceiveHandler(CanIf_Arc_ChannelIdType Channel) {
366 const CanIf_InitHohConfigType *hohConfig;
367 const CanIf_HrhConfigType *hrhConfig;
369 // foreach(hoh){ foreach(hrh in hoh) {} }
370 hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
376 hrhConfig = hohConfig->CanIfHrhConfig;
381 if (hrhConfig->CanIfCanControllerHrhIdRef == Channel)
383 } while(!hrhConfig->CanIf_Arc_EOL);
385 } while(!hohConfig->CanIf_Arc_EOL);
387 DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HRH);
392 const CanIf_HthConfigType* CanIf_Arc_GetTransmitHandler(CanIf_Arc_ChannelIdType Channel) {
393 const CanIf_InitHohConfigType *hohConfig;
394 const CanIf_HthConfigType *hthConfig;
396 // foreach(hoh){ foreach(hrh in hoh) {} }
397 hohConfig = CanIf_ConfigPtr->InitConfig->CanIfHohConfigPtr;
403 hthConfig = hohConfig->CanIfHthConfig;
408 if (hthConfig->CanIfCanControllerIdRef == Channel)
410 } while(!hthConfig->CanIf_Arc_EOL);
412 } while(!hohConfig->CanIf_Arc_EOL);
414 DET_REPORTERROR(MODULE_ID_CANIF, 0, 0xFF, CANIF_E_PARAM_HTH);
420 //-------------------------------------------------------------------
\r
422 Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId,
\r
423 const PduInfoType *PduInfoPtr)
\r
425 Can_PduType canPdu;
\r
426 const CanIf_TxPduConfigType *txEntry;
\r
427 CanIf_ControllerModeType csMode;
\r
428 CanIf_ChannelGetModeType pduMode;
\r
430 VALIDATE(CanIf_Global.initRun, CANIF_TRANSMIT_ID, CANIF_E_UNINIT );
\r
431 VALIDATE((PduInfoPtr != 0), CANIF_TRANSMIT_ID, CANIF_E_PARAM_POINTER );
\r
433 // Get the controller from L-PDU handle
\r
434 txEntry = CanIf_FindTxPduEntry(CanTxPduId);
\r
438 VALIDATE(FALSE, CANIF_TRANSMIT_ID, CANIF_E_INVALID_TXPDUID);
\r
442 CanIf_Arc_ChannelIdType channel = txEntry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef;
\r
444 // Get and verify the controller mode
\r
445 if (CanIf_GetControllerMode(channel, &csMode) == E_NOT_OK){
\r
449 if (csMode != CANIF_CS_STARTED){ // CANIF_161
\r
453 // Get and verify the PDU channel mode control
\r
454 if (CanIf_GetPduMode(channel, &pduMode) == E_NOT_OK){
\r
458 if ((pduMode != CANIF_GET_TX_ONLINE) && (pduMode != CANIF_GET_ONLINE)){
\r
462 canPdu.id = txEntry->CanIfCanTxPduIdCanId;
\r
464 canPdu.length = PduInfoPtr->SduLength;
\r
465 canPdu.sdu = PduInfoPtr->SduDataPtr;
\r
466 canPdu.swPduHandle = CanTxPduId;
\r
468 Can_ReturnType rVal = Can_Write(txEntry->CanIfCanTxPduHthRef->CanIfHthIdSymRef, &canPdu);
\r
470 if (rVal == CAN_NOT_OK){
\r
474 if (rVal == CAN_BUSY) // CANIF 082, CANIF 161
\r
476 // Tx buffering not supported so just return.
\r
483 //-------------------------------------------------------------------
\r
485 #if ( CANIF_READRXPDU_DATA_API == STD_ON )
\r
486 Std_ReturnType CanIf_ReadRxPduData(PduIdType CanRxPduId,
\r
487 PduInfoType *PduInfoPtr)
\r
489 VALIDATE(FALSE, CANIF_READTXPDUDATA_ID, CANIF_E_NOK_NOSUPPORT);
\r
490 VALIDATE(CanIf_Global.initRun == STD_ON, CANIF_READTXPDUDATA_ID, CANIF_E_UNINIT );
\r
491 VALIDATE(PduInfoPtr != 0, CANIF_READTXPDUDATA_ID, CANIF_E_PARAM_POINTER );
\r
493 // This function is not supported
\r
499 //-------------------------------------------------------------------
\r
501 #if ( CANIF_READTXPDU_NOTIFY_STATUS_API == STD_ON )
\r
502 CanIf_NotifStatusType CanIf_ReadTxNotifStatus(PduIdType CanTxPduId)
\r
504 const CanIf_TxPduConfigType *txEntry;
\r
505 VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);
\r
506 VALIDATE(CanIf_Global.initRun, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_UNINIT );
\r
508 // Get the controller from L-PDU handle
\r
509 txEntry = CanIf_FindTxPduEntry(CanTxPduId);
\r
513 VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);
\r
514 return CANIF_NO_NOTIFICATION;
\r
517 if (txEntry->CanIfReadTxPduNotifyStatus == FALSE)
\r
519 VALIDATE(FALSE, CANIF_READTXNOTIFSTATUS_ID, CANIF_E_INVALID_TXPDUID);
\r
520 return CANIF_NO_NOTIFICATION;
\r
523 // This function is not supported
\r
525 return CANIF_NO_NOTIFICATION;
\r
529 //-------------------------------------------------------------------
\r
531 #if ( CANIF_READRXPDU_NOTIFY_STATUS_API == STD_ON )
\r
532 CanIf_NotifStatusType CanIf_ReadRxNotifStatus(PduIdType CanRxPduId)
\r
534 VALIDATE(FALSE, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_NOK_NOSUPPORT);
\r
535 VALIDATE(CanIf_Global.initRun, CANIF_READRXNOTIFSTATUS_ID, CANIF_E_UNINIT );
\r
537 return CANIF_NO_NOTIFICATION;
\r
541 //-------------------------------------------------------------------
\r
543 Std_ReturnType CanIf_SetPduMode(uint8 Controller,
\r
544 CanIf_ChannelSetModeType PduModeRequest)
\r
546 // We call this a CanIf channel. Hopefully makes it easier to follow.
\r
547 CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;
\r
549 VALIDATE( CanIf_Global.initRun, CANIF_SETPDUMODE_ID, CANIF_E_UNINIT );
\r
550 VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_SETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );
\r
552 CanIf_ChannelGetModeType oldMode = CanIf_Global.channelData[channel].PduMode;
\r
554 switch(PduModeRequest)
\r
556 case CANIF_SET_OFFLINE:
\r
557 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
\r
559 case CANIF_SET_RX_OFFLINE:
\r
560 if (oldMode == CANIF_GET_RX_ONLINE){
\r
561 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
\r
562 } else if (oldMode == CANIF_GET_ONLINE){
\r
563 CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;
\r
564 } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE){
\r
565 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;
\r
568 // Other oldmodes don't care
\r
570 case CANIF_SET_RX_ONLINE:
\r
571 if (oldMode == CANIF_GET_OFFLINE){
\r
572 CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;
\r
573 } else if (oldMode == CANIF_GET_TX_ONLINE) {
\r
574 CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
\r
575 } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE){
\r
576 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;
\r
579 // Other oldmodes don't care
\r
581 case CANIF_SET_TX_OFFLINE:
\r
582 if (oldMode == CANIF_GET_TX_ONLINE){
\r
583 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
\r
584 } else if (oldMode == CANIF_GET_ONLINE) {
\r
585 CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;
\r
586 } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {
\r
587 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE;
\r
588 } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {
\r
589 CanIf_Global.channelData[channel].PduMode = CANIF_GET_RX_ONLINE;
\r
592 // Other oldmodes don't care
\r
594 case CANIF_SET_TX_ONLINE:
\r
595 if (oldMode == CANIF_GET_OFFLINE){
\r
596 CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;
\r
597 } else if (oldMode == CANIF_GET_RX_ONLINE) {
\r
598 CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
\r
599 } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE) {
\r
600 CanIf_Global.channelData[channel].PduMode = CANIF_GET_TX_ONLINE;
\r
601 } else if (oldMode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) {
\r
602 CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
\r
605 // Other oldmodes don't care
\r
607 case CANIF_SET_ONLINE:
\r
608 CanIf_Global.channelData[channel].PduMode = CANIF_GET_ONLINE;
\r
611 case CANIF_SET_TX_OFFLINE_ACTIVE:
\r
612 if (oldMode == CANIF_GET_OFFLINE) {
\r
613 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;
\r
614 } else if (oldMode == CANIF_GET_RX_ONLINE) {
\r
615 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;
\r
616 } else if (oldMode == CANIF_GET_TX_ONLINE) {
\r
617 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE;
\r
618 } else if (oldMode == CANIF_GET_ONLINE) {
\r
619 CanIf_Global.channelData[channel].PduMode = CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE;
\r
622 // Other oldmodes don't care
\r
629 //-------------------------------------------------------------------
\r
631 Std_ReturnType CanIf_GetPduMode(uint8 Controller,
\r
632 CanIf_ChannelGetModeType *PduModePtr)
\r
634 // We call this a CanIf channel. Hopefully makes it easier to follow.
\r
635 CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;
\r
637 VALIDATE( CanIf_Global.initRun, CANIF_GETPDUMODE_ID, CANIF_E_UNINIT );
\r
638 VALIDATE( channel < CANIF_CHANNEL_CNT, CANIF_GETPDUMODE_ID, CANIF_E_PARAM_CONTROLLER );
\r
640 *PduModePtr = CanIf_Global.channelData[channel].PduMode;
\r
645 #if ( CANIF_ARC_RUNTIME_PDU_CONFIGURATION == STD_ON )
646 void CanIf_SetDynamicTxId(PduIdType CanTxPduId, Can_IdType CanId)
\r
648 CanIf_TxPduConfigType *txEntry;
\r
649 VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_SETDYNAMICTX_ID, CANIF_E_UNINIT );
\r
651 // Get the controller from L-PDU handle
\r
652 txEntry = CanIf_FindTxPduEntry(CanTxPduId);
\r
656 VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);
\r
660 // Check that this is a dymanic PDU
\r
661 if (txEntry->CanIfCanTxPduType != ARC_PDU_TYPE_DYNAMIC)
\r
663 VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);
\r
667 // Check that this is an extended or standard id
\r
668 if (((CanId & U0x80000000) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_29)) ||
\r
669 (((CanId & U0x80000000) == 0) && (txEntry->CanIfTxPduIdCanIdType == ARC_CAN_ID_TYPE_11)))
\r
671 // Update the CanID
\r
672 //txEntry->CanIfCanTxPduIdCanId = CanId; // TODO How do we fix this from a const pointer
\r
678 // Inavlid Canid to configuration
\r
679 VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_PARAM_CANID);
\r
684 #if ( CANIF_TRANSCEIVER_API == STD_ON )
\r
685 Std_ReturnType CanIf_SetTransceiverMode(uint8 Transceiver,
\r
686 CanIf_TransceiverModeType TransceiverMode)
\r
688 VALIDATE(FALSE, CANIF_SET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);
\r
694 Std_ReturnType CanIf_GetTransceiverMode(uint8 Transceiver,
\r
695 CanIf_TransceiverModeType *TransceiverModePtr)
\r
697 VALIDATE(FALSE, CANIF_GET_TRANSCEIVERMODE_ID, CANIF_E_NOK_NOSUPPORT);
\r
703 Std_ReturnType CanIf_GetTrcvWakeupReason(uint8 Transceiver,
\r
704 CanIf_TrcvWakeupReasonType *TrcvWuReasonPtr)
\r
706 VALIDATE(FALSE, CANIF_GET_TRCVMODEREASON_ID, CANIF_E_NOK_NOSUPPORT);
\r
712 Std_ReturnType CanIf_SetTransceiverWakeupMode(uint8 Transceiver,
\r
713 CanIf_TrcvWakeupModeType *TrcvWakeupMode)
\r
715 VALIDATE(FALSE, CANIF_SET_TRANSCEIVERWAKEMODE_ID, CANIF_E_NOK_NOSUPPORT);
\r
722 #if ( CANIF_WAKEUP_EVENT_API == STD_ON )
\r
723 Std_ReturnType CanIf_CheckWakeup(EcuM_WakeupSourceType WakeupSource)
\r
725 VALIDATE(FALSE, CANIF_CHECKWAKEUP_ID, CANIF_E_NOK_NOSUPPORT);
\r
731 Std_ReturnType CanIf_CheckValidation(EcuM_WakeupSourceType WakeupSource)
\r
733 VALIDATE(FALSE, CANIF_CHECKVALIDATION_ID, CANIF_E_NOK_NOSUPPORT);
\r
741 * Callback interface from driver
\r
743 void CanIf_TxConfirmation(PduIdType canTxPduId)
\r
745 VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_TXCONFIRMATION_ID, CANIF_E_UNINIT)
\r
746 VALIDATE_NO_RV(canTxPduId < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);
\r
748 const CanIf_TxPduConfigType* entry =
\r
749 &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[canTxPduId];
\r
751 if (entry->CanIfUserTxConfirmation != NULL)
\r
753 CanIf_ChannelGetModeType mode;
\r
754 CanIf_GetPduMode(entry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef, &mode);
\r
755 if ((mode == CANIF_GET_TX_ONLINE) || (mode == CANIF_GET_ONLINE)
\r
756 || (mode == CANIF_GET_OFFLINE_ACTIVE) || (mode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) )
\r
758 entry->CanIfUserTxConfirmation(entry->CanIfTxPduId); /* CANIF053 */
\r
764 void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc,
\r
765 const uint8 *CanSduPtr)
\r
767 VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_RXINDICATION_ID, CANIF_E_UNINIT);
\r
768 VALIDATE_NO_RV(CanSduPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);
\r
770 /* Check PDU mode before continue processing */
\r
771 CanIf_ChannelGetModeType mode;
\r
772 CanIf_Arc_ChannelIdType channel = CanIf_Arc_FindHrhChannel( (Can_Arc_HRHType) Hrh);
\r
773 if (channel == -1) // Invalid HRH
\r
778 if (CanIf_GetPduMode(channel, &mode) == E_OK)
\r
780 if ( (mode == CANIF_GET_OFFLINE) || (mode == CANIF_GET_TX_ONLINE) ||
\r
781 (mode == CANIF_GET_OFFLINE_ACTIVE) )
\r
783 // Receiver path is disabled so just drop it
\r
789 return; // No mode so just return
\r
792 const CanIf_RxPduConfigType *entry = CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr;
\r
794 /* Find the CAN id in the RxPduList */
\r
795 for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds; i++)
\r
797 if (entry->CanIfCanRxPduHrhRef->CanIfHrhIdSymRef == Hrh)
\r
799 // Software filtering
\r
800 if (entry->CanIfCanRxPduHrhRef->CanIfHrhType == CAN_ARC_HANDLE_TYPE_BASIC)
\r
802 if (entry->CanIfCanRxPduHrhRef->CanIfSoftwareFilterHrh)
\r
804 if (entry->CanIfSoftwareFilterType == CANIF_SOFTFILTER_TYPE_MASK)
\r
806 if ((CanId & entry->CanIfCanRxPduCanIdMask ) ==
\r
807 ( entry->CanIfCanRxPduCanId & entry->CanIfCanRxPduCanIdMask))
\r
809 // We found a pdu so call higher layers
\r
814 continue; // Go to next entry
819 DET_REPORTERROR(MODULE_ID_CAN, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);
\r
820 continue; // Not a supported filter type, so just drop the frame
\r
825 #if (CANIF_DLC_CHECK == STD_ON)
\r
826 if (CanDlc < entry->CanIfCanRxPduDlc)
\r
828 VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_DLC);
\r
833 switch (entry->CanIfRxUserType)
\r
835 case CANIF_USER_TYPE_CAN_SPECIAL:
\r
837 ( (CanIf_FuncTypeCanSpecial)(entry->CanIfUserRxIndication) )(
838 entry->CanIfCanRxPduHrhRef->CanIfCanControllerHrhIdRef,
839 entry->CanIfCanRxPduId,
848 case CANIF_USER_TYPE_CAN_NM:
\r
849 #if defined(USE_CANNM)
\r
850 CanNm_RxIndication(entry->CanIfCanRxPduId,CanSduPtr);
\r
855 case CANIF_USER_TYPE_CAN_PDUR:
\r
856 // Send Can frame to PDU router
\r
857 #if defined(USE_PDUR)
\r
859 PduInfoType pduInfo;
\r
860 pduInfo.SduLength = CanDlc;
\r
861 pduInfo.SduDataPtr = (uint8 *)CanSduPtr;
\r
862 PduR_CanIfRxIndication(entry->CanIfCanRxPduId,&pduInfo);
\r
868 case CANIF_USER_TYPE_CAN_TP:
\r
869 // Send Can frame to CAN TP
\r
870 #if defined(USE_CANTP)
\r
872 PduInfoType CanTpRxPdu;
\r
873 CanTpRxPdu.SduLength = CanDlc;
\r
874 CanTpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;
\r
875 CanTp_RxIndication(entry->CanIfCanRxPduId, &CanTpRxPdu);
\r
880 case CANIF_USER_TYPE_J1939TP:
\r
881 // Send Can frame to CAN TP
\r
882 #if defined(USE_J1939TP)
\r
884 PduInfoType J1939TpRxPdu;
\r
885 J1939TpRxPdu.SduLength = CanDlc;
\r
886 J1939TpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;
\r
887 J1939Tp_RxIndication(entry->CanIfCanRxPduId, &J1939TpRxPdu);
\r
898 // Did not find the PDU, something is wrong
\r
899 VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_LPDU);
\r
902 #if ( CANIF_TRANSMIT_CANCELLATION == STD_ON )
\r
903 void CanIf_CancelTxConfirmation(const Can_PduType *PduInfoPtr)
\r
905 VALIDATE(FALSE, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_NOK_NOSUPPORT);
\r
906 VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_UNINIT);
\r
907 VALIDATE_NO_RV(PduInfoPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);
\r
909 const CanIf_TxPduConfigType *entry =
\r
910 CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr;
\r
914 // Did not find the PDU, something is wrong
\r
915 VALIDATE_NO_RV(FALSE, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);
\r
919 void CanIf_ControllerBusOff(uint8 Controller)
\r
921 CanIf_Arc_ChannelIdType channel = 0xff;
\r
923 VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_UNINIT );
\r
925 for(int i = 0; i < CANIF_CHANNEL_CNT; i++)
\r
927 if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)
\r
933 VALIDATE_NO_RV( Controller < CANIF_CHANNEL_CNT, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_PARAM_CONTROLLER );
\r
935 // According to figure 35 in canif spec this should be done in
\r
936 // Can driver but it is better to do it here
\r
937 CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);
\r
939 if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)
\r
941 CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);
\r
945 void CanIf_SetWakeupEvent(uint8 Controller)
\r
947 CanIf_Arc_ChannelIdType channel = 0xff;
\r
949 VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_SETWAKEUPEVENT_ID, CANIF_E_UNINIT );
\r
951 for(int i = 0; i < CANIF_CHANNEL_CNT; i++)
\r
953 if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)
\r
959 VALIDATE_NO_RV(FALSE, CANIF_SETWAKEUPEVENT_ID, CANIF_E_NOK_NOSUPPORT);
\r
960 VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_SETWAKEUPEVENT_ID, CANIF_E_PARAM_CONTROLLER );
\r
965 void CanIf_Arc_Error(uint8 Controller, Can_Arc_ErrorType Error)
\r
967 CanIf_Arc_ChannelIdType channel = 0xff;
\r
969 VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_ARCERROR_ID, CANIF_E_UNINIT );
\r
971 for(int i = 0; i < CANIF_CHANNEL_CNT; i++)
\r
973 if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)
\r
979 VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_ARCERROR_ID, CANIF_E_PARAM_CONTROLLER );
\r
981 if (CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton != NULL)
\r
983 CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton(Controller, Error);
\r
986 // Special fix for restart of bus incase of general can error i.e. connection to CanSM
\r
987 if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)
\r
989 CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);
\r
993 uint8 CanIf_Arc_GetChannelDefaultConfIndex(CanIf_Arc_ChannelIdType Channel)
995 return CanIf_Config.Arc_ChannelDefaultConfIndex[Channel];