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
16 //lint -emacro(904,CANNM_VALIDATE_INIT,CANNM_VALIDATE_CHANNEL,CANNM_VALIDATE_NOTNULL) //904 PC-Lint exception to MISRA 14.7 (validate macros).
\r
19 /* Globally fulfilled requirements */
\r
20 /** @req CANNM081 */
\r
21 /** @req CANNM044 */
\r
22 /** @req CANNM050 */
\r
23 /** @req CANNM088 */
\r
24 /** @req CANNM089 */
\r
25 /** @req CANNM090 */
\r
26 /** @req CANNM093 */
\r
27 /** @req CANNM206 */
\r
28 /** @req CANNM125 */
\r
29 /** @req CANNM140 */
\r
30 /** @req CANNM142 */
\r
31 /** @req CANNM145 */
\r
32 /** @req CANNM146 */
\r
33 /** @req CANNM039 */
\r
34 /** @req CANNM001.mandatory */
\r
35 /** @req CANNM158 */
\r
36 /** @req CANNM161 */
\r
37 /** @req CANNM162 */
\r
38 /** @req CANNM086 */
\r
39 /** @req CANNM019 */
\r
40 /** @req CANNM189 */
\r
41 /** @req CANNM190 */
\r
42 /** @req CANNM191 */
\r
43 /** @req CANNM016 */
\r
44 /** @req CANNM195 */
\r
45 /** @req CANNM197.toolchain */
\r
46 /** @req CANNM198.toolchain */
\r
47 /** @req CANNM026 */
\r
48 /** @req CANNM201 */
\r
50 #include "ComStack_Types.h" /** @req CANNM082 */
\r
51 #include "CanNm.h" /** @req CANNM082 */
\r
52 #include "CanNm_Internal.h"
\r
53 #include "Nm_Cbk.h" /** @req CANNM082 */
\r
54 #include "NmStack_Types.h" /** @req CANNM082 */
\r
55 //#include SchM_CanNm.h //Not implemented. (CANNM082)
\r
56 #include "MemMap.h" /** @req CANNM082 */
\r
58 /** @req CANNM083 */
\r
64 #if (CANNM_DEV_ERROR_DETECT == STD_ON)
\r
65 #if defined(USE_DET)
\r
66 #include "Det.h" /** @req CANNM082 */
\r
69 #if defined(USE_DEM)
\r
70 #include "Dem.h" /** @req CANNM082 */
\r
74 static const CanNm_ConfigType* CanNm_ConfigPtr;
\r
76 //lint -save -e785 //PC-Lint exception: Too few initializers for aggregate...
\r
77 CanNm_InternalType CanNm_Internal = {
\r
78 .InitStatus = CANNM_UNINIT,
\r
82 /** Initialize the complete CanNm module, i.e. all channels which are activated */
\r
83 /** @req CANNM041 */
\r
84 void CanNm_Init( const CanNm_ConfigType * const cannmConfigPtr ){
\r
85 CANNM_VALIDATE_NOTNULL(cannmConfigPtr, CANNM_SERVICEID_INIT);
\r
87 CanNm_ConfigPtr = cannmConfigPtr; /**< @req CANNM060 */
\r
90 for (channel = 0; channel < CANNM_CHANNEL_COUNT; channel++) {
\r
91 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[channel];
\r
92 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[channel];
\r
93 if (ChannelConf->Active) { /**< @req CANNM204 */
\r
94 ChannelInternal->Mode = NM_MODE_BUS_SLEEP; /**< @req CANNM144 */
\r
95 ChannelInternal->State = NM_STATE_BUS_SLEEP; /**< @req CANNM141 */
\r
96 ChannelInternal->Requested = FALSE; /**< @req CANNM143 */
\r
98 /** @req CANNM085 */
\r
99 memset(ChannelInternal->TxMessageSdu, 0x00, 8);
\r
100 memset(ChannelInternal->RxMessageSdu, 0x00, 8);
\r
102 /** @req CANNM025 */
\r
103 uint8* destUserData = CanNm_Internal_GetUserDataPtr(ChannelConf, ChannelInternal->TxMessageSdu);
\r
104 uint8 userDataLength = CanNm_Internal_GetUserDataLength(ChannelConf);
\r
105 memset(destUserData, 0xFF, userDataLength);
\r
107 #if (CANNM_NODE_ID_ENABLED == STD_ON)
\r
108 /** @req CANNM013 */
\r
109 if (ChannelConf->NidPosition != CANNM_PDU_OFF) {
\r
110 ChannelInternal->TxMessageSdu[ChannelConf->NidPosition] = ChannelConf->NodeId;
\r
114 ChannelInternal->State = NM_STATE_UNINIT;
\r
118 CanNm_Internal.InitStatus = CANNM_INIT;
\r
120 /** @req CANNM061 */
\r
121 /** @req CANNM033 */
\r
124 /** Passive startup of the AUTOSAR CAN NM. It triggers the transition from Bus-
\r
125 * Sleep Mode to the Network Mode in Repeat Message State.
\r
126 * This service has no effect if the current state is not equal to Bus-Sleep Mode. In
\r
127 * that case NM_E_NOT_EXECUTED is returned. */
\r
128 Nm_ReturnType CanNm_PassiveStartUp( const NetworkHandleType nmChannelHandle ){
\r
129 CANNM_VALIDATE_INIT(CANNM_SERVICEID_PASSIVESTARTUP);
\r
130 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_PASSIVESTARTUP);
\r
132 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
133 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
134 Nm_ReturnType status = NM_E_OK;
\r
136 if (ChannelInternal->Mode == NM_MODE_BUS_SLEEP) {
\r
137 CanNm_Internal_BusSleep_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM128 @req CANNM095.3 */
\r
140 status = NM_E_NOT_EXECUTED; /**< @req CANNM147 */
\r
145 /** Request the network, since ECU needs to communicate on the bus. Network
\r
146 * state shall be changed to
\91requested
\92 */
\r
147 Nm_ReturnType CanNm_NetworkRequest( const NetworkHandleType nmChannelHandle ){
\r
148 CANNM_VALIDATE_INIT(CANNM_SERVICEID_NETWORKREQUEST);
\r
149 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_NETWORKREQUEST);
\r
151 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
152 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
154 ChannelInternal->Requested = TRUE; /**< @req CANNM104 */
\r
156 if (ChannelInternal->Mode == NM_MODE_BUS_SLEEP) {
\r
157 CanNm_Internal_BusSleep_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM129 @req CANNM095.1 */
\r
158 } else if (ChannelInternal->Mode == NM_MODE_PREPARE_BUS_SLEEP) {
\r
159 CanNm_Internal_PrepareBusSleep_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM123 @req CANNM095.2 */
\r
160 } else if (ChannelInternal->Mode == NM_MODE_NETWORK) {
\r
161 if (ChannelInternal->State == NM_STATE_READY_SLEEP) {
\r
162 CanNm_Internal_ReadySleep_to_NormalOperation(ChannelConf, ChannelInternal); /**< @req CANNM110 */
\r
165 //Nothing to be done
\r
170 /** Release the network, since ECU doesn
\92t have to communicate on the bus. Network
\r
171 * state shall be changed to
\91released
\92. */
\r
172 Nm_ReturnType CanNm_NetworkRelease( const NetworkHandleType nmChannelHandle ){
\r
173 CANNM_VALIDATE_INIT(CANNM_SERVICEID_NETWORKRELEASE);
\r
174 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_NETWORKRELEASE);
\r
175 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
176 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
178 ChannelInternal->Requested = FALSE; /**< @req CANNM105 */
\r
180 if (ChannelInternal->Mode == NM_MODE_NETWORK) {
\r
181 if (ChannelInternal->State == NM_STATE_NORMAL_OPERATION) {
\r
182 CanNm_Internal_NormalOperation_to_ReadySleep(ChannelConf, ChannelInternal); /**< @req CANNM118 */
\r
188 /** Disable the NM PDU transmission ability due to a ISO14229 Communication
\r
189 * Control (28hex) service */
\r
190 Nm_ReturnType CanNm_DisableCommunication( const NetworkHandleType nmChannelHandle ){
\r
191 CANNM_VALIDATE_INIT(CANNM_SERVICEID_DISABLECOMMUNICATION);
\r
192 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_DISABLECOMMUNICATION);
\r
193 return NM_E_NOT_OK;
\r
196 /** Enable the NM PDU transmission ability due to a ISO14229 Communication
\r
197 * Control (28hex) service */
\r
198 Nm_ReturnType CanNm_EnableCommunication( const NetworkHandleType nmChannelHandle ){
\r
199 CANNM_VALIDATE_INIT(CANNM_SERVICEID_ENABLECOMMUNICATION);
\r
200 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_ENABLECOMMUNICATION);
\r
201 return NM_E_NOT_OK;
\r
204 #if (CANNM_USER_DATA_ENABLED == STD_ON) /**< @req CANNM053.1 */
\r
205 /** Set user data for NM messages transmitted next on the bus. */
\r
206 /** @req CANNM159 @req CANNM015 */
\r
207 Nm_ReturnType CanNm_SetUserData( const NetworkHandleType nmChannelHandle, const uint8* const nmUserDataPtr ){
\r
208 CANNM_VALIDATE_INIT(CANNM_SERVICEID_SETUSERDATA);
\r
209 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_SETUSERDATA);
\r
211 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
212 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
213 uint8* destUserData = CanNm_Internal_GetUserDataPtr(ChannelConf, ChannelInternal->TxMessageSdu);
\r
214 uint8 userDataLength = CanNm_Internal_GetUserDataLength(ChannelConf);
\r
216 memcpy(destUserData, nmUserDataPtr, userDataLength);
\r
222 #if (CANNM_USER_DATA_ENABLED == STD_ON) /**< @req CANNM053.2 */
\r
223 /** Get user data out of the most recently received NM message. */
\r
224 /** @req CANNM160 @req CANNM031 */
\r
225 Nm_ReturnType CanNm_GetUserData( const NetworkHandleType nmChannelHandle, uint8* const nmUserDataPtr ){
\r
226 CANNM_VALIDATE_INIT(CANNM_SERVICEID_GETUSERDATA);
\r
227 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_GETUSERDATA);
\r
229 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
230 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
231 uint8* sourceUserData = CanNm_Internal_GetUserDataPtr(ChannelConf, ChannelInternal->RxMessageSdu);
\r
232 uint8 userDataLength = CanNm_Internal_GetUserDataLength(ChannelConf);
\r
234 memcpy(nmUserDataPtr, sourceUserData, userDataLength);
\r
240 #if (CANNM_NODE_ID_ENABLED == STD_ON)
\r
241 /** Get node identifier out of the most recently received NM PDU. */
\r
242 /** @req CANNM132 */
\r
243 Nm_ReturnType CanNm_GetNodeIdentifier( const NetworkHandleType nmChannelHandle, uint8 * const nmNodeIdPtr ){
\r
244 CANNM_VALIDATE_INIT(CANNM_SERVICEID_GETNODEIDENTIFIER);
\r
245 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_GETNODEIDENTIFIER);
\r
247 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
248 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
249 Nm_ReturnType status = NM_E_OK;
\r
251 if (ChannelConf->NidPosition == CANNM_PDU_OFF) {
\r
252 status = NM_E_NOT_EXECUTED;
\r
254 *nmNodeIdPtr = ChannelInternal->RxMessageSdu[ChannelConf->NidPosition];
\r
260 /** Get node identifier configured for the local node. */
\r
261 /** @req CANNM133 */
\r
262 Nm_ReturnType CanNm_GetLocalNodeIdentifier( const NetworkHandleType nmChannelHandle, uint8 * const nmNodeIdPtr ){
\r
263 CANNM_VALIDATE_INIT(CANNM_SERVICEID_GETLOCALNODEIDENTIFIER);
\r
264 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_GETLOCALNODEIDENTIFIER);
\r
266 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
267 *nmNodeIdPtr = ChannelConf->NodeId;
\r
273 #if (CANNM_NODE_DETECTION_ENABLED == STD_ON)
\r
274 /** Set Repeat Message Request Bit for NM messages transmitted next on the bus. */
\r
275 /** @req CANNM135 @req CANNM136 */
\r
276 Nm_ReturnType CanNm_RepeatMessageRequest( const NetworkHandleType nmChannelHandle ){
\r
277 CANNM_VALIDATE_INIT(CANNM_SERVICEID_REPEATMESSAGEREQUEST);
\r
278 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_REPEATMESSAGEREQUEST);
\r
280 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
281 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
282 Nm_ReturnType status = NM_E_NOT_EXECUTED; /**< @req CANNM137 */
\r
284 if (ChannelConf->CbvPosition != CANNM_PDU_OFF) {
\r
285 if (ChannelInternal->State == NM_STATE_READY_SLEEP) {
\r
286 ChannelInternal->TxMessageSdu[ChannelConf->CbvPosition] = CANNM_CBV_REPEAT_MESSAGE_REQUEST; /**< @req CANNM113 */
\r
287 CanNm_Internal_ReadySleep_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM112 */
\r
289 } else if (ChannelInternal->State == NM_STATE_NORMAL_OPERATION) {
\r
290 ChannelInternal->TxMessageSdu[ChannelConf->CbvPosition] = CANNM_CBV_REPEAT_MESSAGE_REQUEST; /**< @req CANNM121 */
\r
291 CanNm_Internal_NormalOperation_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM120 */
\r
294 //Nothing to be done
\r
301 #if ((CANNM_NODE_ID_ENABLED == STD_ON) || (CANNM_NODE_DETECTION_ENABLED == STD_ON) || (CANNM_USER_DATA_ENABLED == STD_ON))
\r
302 /** Get the whole PDU data out of the most recently received NM message. */
\r
303 /** @req CANNM138 @req CANNM139 */
\r
304 Nm_ReturnType CanNm_GetPduData( const NetworkHandleType nmChannelHandle, uint8 * const nmPduDataPtr ){
\r
305 CANNM_VALIDATE_INIT(CANNM_SERVICEID_GETPDUDATA);
\r
306 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_GETPDUDATA);
\r
308 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
309 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
311 memcpy(nmPduDataPtr, ChannelInternal->RxMessageSdu, ChannelConf->PduLength);
\r
317 /** Returns the state and the mode of the network management. */
\r
318 /** @req CANNM091 */
\r
319 Nm_ReturnType CanNm_GetState( const NetworkHandleType nmChannelHandle, Nm_StateType * const nmStatePtr, Nm_ModeType * const nmModePtr ){
\r
320 CANNM_VALIDATE_INIT(CANNM_SERVICEID_GETSTATE);
\r
321 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_GETSTATE);
\r
323 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
324 *nmStatePtr = ChannelInternal->State;
\r
325 *nmModePtr = ChannelInternal->Mode;
\r
330 /** Request bus synchronization. */
\r
331 Nm_ReturnType CanNm_RequestBusSynchronization( const NetworkHandleType nmChannelHandle ){
\r
332 CANNM_VALIDATE_INIT(CANNM_SERVICEID_REQUESTBUSSYNCHRONIZATION);
\r
333 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_REQUESTBUSSYNCHRONIZATION);
\r
335 return NM_E_NOT_OK;
\r
338 /** Check if remote sleep indication takes place or not. */
\r
339 Nm_ReturnType CanNm_CheckRemoteSleepIndication( const NetworkHandleType nmChannelHandle, boolean * const nmRemoteSleepIndPtr ){
\r
340 CANNM_VALIDATE_INIT(CANNM_SERVICEID_CHECKREMOTESLEEPINDICATION);
\r
341 CANNM_VALIDATE_CHANNEL(nmChannelHandle, CANNM_SERVICEID_CHECKREMOTESLEEPINDICATION);
\r
342 (void)nmRemoteSleepIndPtr;
\r
344 return NM_E_NOT_OK;
\r
348 // Functions called by CAN Interface
\r
349 // ---------------------------------
\r
351 /** This service confirms a previous successfully processed CAN transmit request.
\r
352 * This callback service is called by the CanIf and implemented by the CanNm. */
\r
353 /** @req CANNM034.deferred */
\r
354 void CanNm_TxConfirmation( PduIdType canNmTxPduId ){
\r
355 CANNM_VALIDATE_INIT_NORV(CANNM_SERVICEID_TXCONFIRMATION);
\r
356 CANNM_VALIDATE_CHANNEL_NORV(canNmTxPduId, CANNM_SERVICEID_TXCONFIRMATION);
\r
358 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[canNmTxPduId];
\r
359 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[canNmTxPduId];
\r
361 if (ChannelInternal->Mode == NM_MODE_NETWORK) {
\r
362 CanNm_Internal_NetworkMode_to_NetworkMode(ChannelConf, ChannelInternal); /**< @req CANNM099.1 */
\r
366 /** This service indicates a successful reception of a received NM message to the
\r
367 * CanNm after passing all filters and validation checks.
\r
368 * This callback service is called by the CAN Interface and implemented by the CanNm. */
\r
369 void CanNm_RxIndication( PduIdType canNmRxPduId, const uint8 *canSduPtr ){
\r
370 CANNM_VALIDATE_INIT_NORV(CANNM_SERVICEID_RXINDICATION);
\r
371 CANNM_VALIDATE_CHANNEL_NORV(canNmRxPduId, CANNM_SERVICEID_RXINDICATION);
\r
373 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[canNmRxPduId];
\r
374 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[canNmRxPduId];
\r
376 memcpy(ChannelInternal->RxMessageSdu, canSduPtr, ChannelConf->PduLength); /**< @req CANNM035 */
\r
378 boolean repeatMessageBitIndication = FALSE;
\r
379 if (ChannelConf->CbvPosition != CANNM_PDU_OFF) {
\r
380 uint8 cbv = ChannelInternal->RxMessageSdu[ChannelConf->CbvPosition];
\r
381 repeatMessageBitIndication = cbv & CANNM_CBV_REPEAT_MESSAGE_REQUEST;
\r
384 if (ChannelInternal->Mode == NM_MODE_BUS_SLEEP) {
\r
385 CanNm_Internal_BusSleep_to_BusSleep(ChannelConf, ChannelInternal); /**< @req CANNM127.2 */
\r
386 } else if (ChannelInternal->Mode == NM_MODE_PREPARE_BUS_SLEEP) {
\r
387 CanNm_Internal_PrepareBusSleep_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM124 @req CANNM095.4 */
\r
388 } else if (ChannelInternal->Mode == NM_MODE_NETWORK) {
\r
389 CanNm_Internal_NetworkMode_to_NetworkMode(ChannelConf, ChannelInternal); /**< @req CANNM098.1 */
\r
390 if (repeatMessageBitIndication) {
\r
391 if (ChannelInternal->State == NM_STATE_READY_SLEEP) {
\r
392 CanNm_Internal_ReadySleep_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM111 */
\r
393 } else if (ChannelInternal->State == NM_STATE_NORMAL_OPERATION) {
\r
394 CanNm_Internal_NormalOperation_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM119 */
\r
396 //Nothing to be done
\r
400 //Nothing to be done
\r
402 #if (CANNM_PDU_RX_INDICATION_ENABLED == STD_ON)
\r
403 // TODO: call NM rx indication
\r
410 // ----------------------------------------------------------------------------
\r
411 // Internal functions
\r
412 // ----------------------------------------------------------------------------
\r
413 // Accessed through CanNm_MainFunction_<channel>
\r
414 void CanNm_MainFunction(NetworkHandleType nmChannelHandle);
\r
416 void CanNm_MainFunction( NetworkHandleType nmChannelHandle ) {
\r
417 CANNM_VALIDATE_INIT_NORV(CANNM_SERVICEID_ARC_MAINFUNCTION);
\r
419 /** @req CANNM108 */
\r
421 const CanNm_ChannelType* ChannelConf = &CanNm_ConfigPtr->Channels[nmChannelHandle];
\r
422 CanNm_Internal_ChannelType* ChannelInternal = &CanNm_Internal.Channels[nmChannelHandle];
\r
423 if (ChannelInternal->Mode == NM_MODE_NETWORK) {
\r
424 CanNm_Internal_TickTimeoutTime(ChannelConf, ChannelInternal);
\r
425 #if (CANNM_PASSIVE_MODE_ENABLED != STD_ON) /**< @req CANNM072 */
\r
426 if ((ChannelInternal->State == NM_STATE_REPEAT_MESSAGE) ||
\r
427 (ChannelInternal->State == NM_STATE_NORMAL_OPERATION)) {
\r
428 /** @req CANNM051 @req CANNM032 @req CANNM087.1 @req CANNM100.6 */
\r
429 CanNm_Internal_TickMessageCycleTime(ChannelConf, ChannelInternal);
\r
432 if (ChannelInternal->State == NM_STATE_REPEAT_MESSAGE) {
\r
433 CanNm_Internal_TickRepeatMessageTime(ChannelConf, ChannelInternal); /**< @req CANNM102.2 */
\r
435 } else if (ChannelInternal->Mode == NM_MODE_PREPARE_BUS_SLEEP) {
\r
436 CanNm_Internal_TickWaitBusSleepTime(ChannelConf, ChannelInternal); /**< @req CANNM115.2 */
\r
438 //Nothing to be done
\r
445 static inline void CanNm_Internal_TickTimeoutTime( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
446 if (ChannelConf->MainFunctionPeriod >= ChannelInternal->TimeoutTimeLeft) {
\r
447 ChannelInternal->TimeoutTimeLeft = 0;
\r
448 if (ChannelInternal->State == NM_STATE_REPEAT_MESSAGE) {
\r
449 #if defined(USE_DEM)
\r
450 Dem_ReportErrorStatus(CANNM_E_NETWORK_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
452 CanNm_Internal_RepeatMessage_to_RepeatMessage(ChannelConf, ChannelInternal); /**< @req CANNM101.1 */
\r
453 } else if (ChannelInternal->State == NM_STATE_NORMAL_OPERATION) {
\r
454 #if defined(USE_DEM)
\r
455 Dem_ReportErrorStatus(CANNM_E_NETWORK_TIMEOUT, DEM_EVENT_STATUS_FAILED);
\r
457 CanNm_Internal_NormalOperation_to_NormalOperation(ChannelConf, ChannelInternal); /**< @req CANNM117.1 */
\r
458 } else if (ChannelInternal->State == NM_STATE_READY_SLEEP) {
\r
459 CanNm_Internal_ReadySleep_to_PrepareBusSleep(ChannelConf, ChannelInternal); /**< @req CANNM109 */
\r
461 //Nothing to be done
\r
464 ChannelInternal->TimeoutTimeLeft -= ChannelConf->MainFunctionPeriod;
\r
468 /** @req CANNM102.1 */
\r
469 static inline void CanNm_Internal_TickRepeatMessageTime( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
470 if (ChannelConf->MainFunctionPeriod >= ChannelInternal->RepeatMessageTimeLeft) {
\r
471 ChannelInternal->RepeatMessageTimeLeft = 0;
\r
472 if (ChannelInternal->State == NM_STATE_REPEAT_MESSAGE) {
\r
473 if (ChannelInternal->Requested) {
\r
474 CanNm_Internal_RepeatMessage_to_NormalOperation(ChannelConf, ChannelInternal); /**< @req CANNM103 */
\r
476 CanNm_Internal_RepeatMessage_to_ReadySleep(ChannelConf, ChannelInternal); /**< @req CANNM104 */
\r
480 ChannelInternal->RepeatMessageTimeLeft -= ChannelConf->MainFunctionPeriod;
\r
484 /** @req CANNM115.1 */
\r
485 static inline void CanNm_Internal_TickWaitBusSleepTime( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
486 if (ChannelConf->MainFunctionPeriod >= ChannelInternal->WaitBusSleepTimeLeft) {
\r
487 ChannelInternal->WaitBusSleepTimeLeft = 0;
\r
488 if (ChannelInternal->Mode == NM_MODE_PREPARE_BUS_SLEEP) {
\r
489 CanNm_Internal_PrepareBusSleep_to_BusSleep(ChannelConf, ChannelInternal);
\r
492 ChannelInternal->WaitBusSleepTimeLeft -= ChannelConf->MainFunctionPeriod;
\r
496 static inline void CanNm_Internal_TickMessageCycleTime( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
497 if (ChannelConf->MainFunctionPeriod >= ChannelInternal->MessageCycleTimeLeft) {
\r
498 ChannelInternal->MessageCycleTimeLeft = 0;
\r
499 if ((ChannelInternal->State == NM_STATE_REPEAT_MESSAGE) ||
\r
500 (ChannelInternal->State == NM_STATE_NORMAL_OPERATION)) {
\r
501 ChannelInternal->MessageCycleTimeLeft = ChannelConf->MessageCycleTime; /**< @req CANNM040 */
\r
502 /** @req CANNM087.2 @req CANNM100.5 */
\r
503 CanNm_Internal_TransmitMessage(ChannelConf, ChannelInternal);
\r
506 ChannelInternal->MessageCycleTimeLeft -= ChannelConf->MainFunctionPeriod;
\r
513 static inline void CanNm_Internal_TransmitMessage( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
514 PduInfoType pdu = {
\r
515 .SduDataPtr = ChannelInternal->TxMessageSdu,
\r
516 .SduLength = ChannelConf->PduLength,
\r
518 Std_ReturnType status = CanIf_Transmit(ChannelConf->CanIfPduId, &pdu);
\r
520 // TODO: what to do if Transmit fails?
\r
523 static inline uint8 CanNm_Internal_GetUserDataOffset( const CanNm_ChannelType* ChannelConf ) {
\r
524 uint8 userDataPos = 0;
\r
525 userDataPos += (ChannelConf->NidPosition == CANNM_PDU_OFF) ? 0 : 1;
\r
526 userDataPos += (ChannelConf->CbvPosition == CANNM_PDU_OFF) ? 0 : 1;
\r
527 return userDataPos;
\r
530 static inline uint8* CanNm_Internal_GetUserDataPtr( const CanNm_ChannelType* ChannelConf, uint8* MessageSduPtr ) {
\r
531 uint8 userDataOffset = CanNm_Internal_GetUserDataOffset(ChannelConf);
\r
532 return &MessageSduPtr[userDataOffset];
\r
535 static inline uint8 CanNm_Internal_GetUserDataLength( const CanNm_ChannelType* ChannelConf ) {
\r
536 uint8 userDataOffset = CanNm_Internal_GetUserDataOffset(ChannelConf);
\r
537 return ChannelConf->PduLength - userDataOffset;
\r
540 static inline void CanNm_Internal_ClearCbv( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
541 if (ChannelConf->CbvPosition != CANNM_PDU_OFF) {
\r
542 ChannelInternal->TxMessageSdu[ChannelConf->CbvPosition] = 0x00;
\r
546 // Transition helpers
\r
547 // ------------------
\r
549 static inline void CanNm_Internal_PrepareBusSleep_to_RepeatMessage( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
550 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
551 ChannelInternal->State = NM_STATE_REPEAT_MESSAGE;
\r
552 ChannelInternal->TimeoutTimeLeft = ChannelConf->TimeoutTime; /**< @req CANNM096.1 */
\r
553 ChannelInternal->RepeatMessageTimeLeft = ChannelConf->RepeatMessageTime;
\r
554 ChannelInternal->MessageCycleTimeLeft = ChannelConf->MessageCycleOffsetTime; /**< @req CANNM100.2 */
\r
555 // Notify 'Network Mode'
\r
556 Nm_NetworkMode(ChannelConf->NmNetworkHandle); /**< @req CANNM097.1 */
\r
559 static inline void CanNm_Internal_PrepareBusSleep_to_BusSleep( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
560 ChannelInternal->Mode = NM_MODE_BUS_SLEEP;
\r
561 ChannelInternal->State = NM_STATE_BUS_SLEEP;
\r
562 // Notify 'Bus-Sleep Mode'
\r
563 Nm_BusSleepMode(ChannelConf->NmNetworkHandle); /**< @req CANNM126 */
\r
566 static inline void CanNm_Internal_BusSleep_to_RepeatMessage( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
567 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
568 ChannelInternal->State = NM_STATE_REPEAT_MESSAGE;
\r
569 ChannelInternal->TimeoutTimeLeft = ChannelConf->TimeoutTime; /**< @req CANNM096.2 */
\r
570 ChannelInternal->RepeatMessageTimeLeft = ChannelConf->RepeatMessageTime;
\r
571 ChannelInternal->MessageCycleTimeLeft = ChannelConf->MessageCycleOffsetTime; /**< @req CANNM100.1 */
\r
572 // Notify 'Network Mode'
\r
573 Nm_NetworkMode(ChannelConf->NmNetworkHandle); /**< @req CANNM097.2 */
\r
575 static inline void CanNm_Internal_BusSleep_to_BusSleep( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
576 // Notify 'Network Start'
\r
577 Nm_NetworkStartIndication(ChannelConf->NmNetworkHandle); /**< @req CANNM127.1 */
\r
578 (void) ChannelInternal; //Just to avoid 715 PC-Lint warning about not used.
\r
581 static inline void CanNm_Internal_RepeatMessage_to_RepeatMessage( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
582 ChannelInternal->TimeoutTimeLeft = ChannelConf->TimeoutTime; /**< @req CANNM101.2 */
\r
583 // TODO: Notify 'Network Timeout'?
\r
585 static inline void CanNm_Internal_RepeatMessage_to_ReadySleep( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
586 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
587 ChannelInternal->State = NM_STATE_READY_SLEEP;
\r
588 #if (CANNM_NODE_DETECTION_ENABLED == STD_ON)
\r
589 /** @req CANNM107.1 */
\r
590 CanNm_Internal_ClearCbv(ChannelConf, ChannelInternal);
\r
593 static inline void CanNm_Internal_RepeatMessage_to_NormalOperation( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
594 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
595 ChannelInternal->State = NM_STATE_NORMAL_OPERATION;
\r
596 #if (CANNM_NODE_DETECTION_ENABLED == STD_ON)
\r
597 /** @req CANNM107.2 */
\r
598 CanNm_Internal_ClearCbv(ChannelConf, ChannelInternal);
\r
602 static inline void CanNm_Internal_NormalOperation_to_RepeatMessage( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
603 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
604 ChannelInternal->State = NM_STATE_REPEAT_MESSAGE;
\r
605 ChannelInternal->RepeatMessageTimeLeft = ChannelConf->RepeatMessageTime;
\r
606 ChannelInternal->MessageCycleTimeLeft = ChannelConf->MessageCycleOffsetTime; /**< @req CANNM100.3 */
\r
608 static inline void CanNm_Internal_NormalOperation_to_ReadySleep( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
609 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
610 ChannelInternal->State = NM_STATE_READY_SLEEP;
\r
611 (void) ChannelConf; //Just to avoid 715 PC-Lint warning about not used.
\r
613 static inline void CanNm_Internal_NormalOperation_to_NormalOperation( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
614 ChannelInternal->TimeoutTimeLeft = ChannelConf->TimeoutTime; /**< @req CANNM117.2 */
\r
617 static inline void CanNm_Internal_ReadySleep_to_NormalOperation( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
618 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
619 ChannelInternal->State = NM_STATE_NORMAL_OPERATION;
\r
620 ChannelInternal->MessageCycleTimeLeft = ChannelConf->MessageCycleOffsetTime; /**< @req CANNM116 */
\r
622 static inline void CanNm_Internal_ReadySleep_to_PrepareBusSleep( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
623 ChannelInternal->Mode = NM_MODE_PREPARE_BUS_SLEEP;
\r
624 ChannelInternal->State = NM_STATE_PREPARE_BUS_SLEEP;
\r
625 ChannelInternal->WaitBusSleepTimeLeft = ChannelConf->WaitBusSleepTime;
\r
626 // Notify 'Prepare Bus-Sleep Mode'
\r
627 Nm_PrepareBusSleepMode(ChannelConf->NmNetworkHandle); /**< @req CANNM114 */
\r
629 static inline void CanNm_Internal_ReadySleep_to_RepeatMessage( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
630 ChannelInternal->Mode = NM_MODE_NETWORK;
\r
631 ChannelInternal->State = NM_STATE_REPEAT_MESSAGE;
\r
632 ChannelInternal->RepeatMessageTimeLeft = ChannelConf->RepeatMessageTime;
\r
633 ChannelInternal->MessageCycleTimeLeft = ChannelConf->MessageCycleOffsetTime; /**< @req CANNM100.4 */
\r
636 static inline void CanNm_Internal_NetworkMode_to_NetworkMode( const CanNm_ChannelType* ChannelConf, CanNm_Internal_ChannelType* ChannelInternal ) {
\r
637 ChannelInternal->TimeoutTimeLeft = ChannelConf->TimeoutTime; /**< @req CANNM098.2 @req CANNM099.2 */
\r