1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for NMT-Userspace-Module
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplNmtu.c,v $
56 $Revision: 1.8 $ $Date: 2008/11/10 17:17:42 $
63 -------------------------------------------------------------------------
67 2006/06/09 k.t.: start of the implementation
69 ****************************************************************************/
72 #include "user/EplNmtu.h"
73 #include "user/EplObdu.h"
74 #include "user/EplTimeru.h"
75 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
76 #include "kernel/EplNmtk.h"
79 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
80 /***************************************************************************/
83 /* G L O B A L D E F I N I T I O N S */
86 /***************************************************************************/
88 //---------------------------------------------------------------------------
90 //---------------------------------------------------------------------------
92 //---------------------------------------------------------------------------
94 //---------------------------------------------------------------------------
97 tEplNmtuStateChangeCallback m_pfnNmtChangeCb;
98 tEplTimerHdl m_TimerHdl;
102 //---------------------------------------------------------------------------
103 // modul globale vars
104 //---------------------------------------------------------------------------
106 static tEplNmtuInstance EplNmtuInstance_g;
108 //---------------------------------------------------------------------------
109 // local function prototypes
110 //---------------------------------------------------------------------------
112 //=========================================================================//
114 // P U B L I C F U N C T I O N S //
116 //=========================================================================//
118 //---------------------------------------------------------------------------
120 // Function: EplNmtuInit
122 // Description: init first instance of the module
129 // Returns: tEplKernel = errorcode
134 //---------------------------------------------------------------------------
135 tEplKernel EplNmtuInit(void)
139 Ret = EplNmtuAddInstance();
144 //---------------------------------------------------------------------------
146 // Function: EplNmtuAddInstance
148 // Description: init other instances of the module
155 // Returns: tEplKernel = errorcode
160 //---------------------------------------------------------------------------
161 tEplKernel EplNmtuAddInstance(void)
165 Ret = kEplSuccessful;
167 EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
173 //---------------------------------------------------------------------------
175 // Function: EplNmtuDelInstance
177 // Description: delete instance
184 // Returns: tEplKernel = errorcode
189 //---------------------------------------------------------------------------
190 tEplKernel EplNmtuDelInstance(void)
194 Ret = kEplSuccessful;
196 EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
199 Ret = EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
205 //---------------------------------------------------------------------------
207 // Function: EplNmtuNmtEvent
209 // Description: sends the NMT-Event to the NMT-State-Maschine
213 // Parameters: NmtEvent_p = NMT-Event to send
216 // Returns: tEplKernel = errorcode
221 //---------------------------------------------------------------------------
222 tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
227 Event.m_EventSink = kEplEventSinkNmtk;
228 Event.m_NetTime.m_dwNanoSec = 0;
229 Event.m_NetTime.m_dwSec = 0;
230 Event.m_EventType = kEplEventTypeNmtEvent;
231 Event.m_pArg = &NmtEvent_p;
232 Event.m_uiSize = sizeof(NmtEvent_p);
234 Ret = EplEventuPost(&Event);
239 //---------------------------------------------------------------------------
241 // Function: EplNmtuGetNmtState
243 // Description: returns the actuell NMT-State
250 // Returns: tEplNmtState = NMT-State
255 //---------------------------------------------------------------------------
256 tEplNmtState EplNmtuGetNmtState(void)
258 tEplNmtState NmtState;
260 // $$$ call function of communication abstraction layer
261 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
262 NmtState = EplNmtkGetNmtState();
270 //---------------------------------------------------------------------------
272 // Function: EplNmtuProcessEvent
274 // Description: processes events from event queue
278 // Parameters: pEplEvent_p = pointer to event
281 // Returns: tEplKernel = errorcode
286 //---------------------------------------------------------------------------
287 tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p)
291 Ret = kEplSuccessful;
294 switch (pEplEvent_p->m_EventType) {
295 // state change of NMT-Module
296 case kEplEventTypeNmtStateChange:
298 tEplEventNmtStateChange *pNmtStateChange;
302 EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
305 (tEplEventNmtStateChange *) pEplEvent_p->m_pArg;
307 // call cb-functions to inform higher layer
308 if (EplNmtuInstance_g.m_pfnNmtChangeCb != NULL) {
311 m_pfnNmtChangeCb(*pNmtStateChange);
314 if (Ret == kEplSuccessful) { // everything is OK, so switch to next state if necessary
315 switch (pNmtStateChange->m_NewNmtState) {
316 // EPL stack is not running
320 // first init of the hardware
321 case kEplNmtGsInitialising:
325 (kEplNmtEventEnterResetApp);
329 // init of the manufacturer-specific profile area and the
330 // standardised device profile area
331 case kEplNmtGsResetApplication:
335 (kEplNmtEventEnterResetCom);
339 // init of the communication profile area
340 case kEplNmtGsResetCommunication:
344 (kEplNmtEventEnterResetConfig);
348 // build the configuration with infos from OD
349 case kEplNmtGsResetConfiguration:
351 unsigned int uiNodeId;
353 // get node ID from OD
354 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
357 (EPL_MCO_PTR_INSTANCE_PTR);
361 //check node ID if not should be master or slave
362 if (uiNodeId == EPL_C_ADR_MN_DEF_NODE_ID) { // node shall be MN
363 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
366 (kEplNmtEventEnterMsNotActive);
369 ("EplNmtuProcess(): no MN functionality implemented\n");
371 } else { // node shall be CN
374 (kEplNmtEventEnterCsNotActive);
379 //-----------------------------------------------------------
380 // CN part of the state machine
382 // node listens for EPL-Frames and check timeout
383 case kEplNmtCsNotActive:
387 tEplTimerArg TimerArg;
389 // create timer to switch automatically to BasicEthernet if no MN available in network
391 // read NMT_CNBasicEthernetTimerout_U32 from OD
392 ObdSize = sizeof(dwBuffer);
393 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
396 (EPL_MCO_PTR_INSTANCE_PTR_
397 0x1F99, 0x00, &dwBuffer,
400 Ret = kEplObdIndexNotExist;
402 if (Ret != kEplSuccessful) {
405 if (dwBuffer != 0) { // BasicEthernet is enabled
406 // convert us into ms
409 if (dwBuffer == 0) { // timer was below one ms
413 TimerArg.m_EventSink =
417 kEplNmtEventTimerBasicEthernet;
419 EplTimeruModifyTimerMs
425 // potential error is forwarded to event queue which generates error event
430 // node processes only async frames
431 case kEplNmtCsPreOperational1:
436 // node processes isochronous and asynchronous frames
437 case kEplNmtCsPreOperational2:
441 (kEplNmtEventEnterReadyToOperate);
445 // node should be configured und application is ready
446 case kEplNmtCsReadyToOperate:
452 case kEplNmtCsOperational:
457 // node stopped by MN
458 // -> only process asynchronous frames
459 case kEplNmtCsStopped:
465 // -> normal ethernet communication
466 case kEplNmtCsBasicEthernet:
471 //-----------------------------------------------------------
472 // MN part of the state machine
474 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
475 // node listens for EPL-Frames and check timeout
476 case kEplNmtMsNotActive:
480 tEplTimerArg TimerArg;
482 // create timer to switch automatically to BasicEthernet/PreOp1 if no other MN active in network
484 // check NMT_StartUp_U32.Bit13
485 // read NMT_StartUp_U32 from OD
486 ObdSize = sizeof(dwBuffer);
487 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
490 (EPL_MCO_PTR_INSTANCE_PTR_
491 0x1F80, 0x00, &dwBuffer,
494 Ret = kEplObdIndexNotExist;
496 if (Ret != kEplSuccessful) {
500 if ((dwBuffer & EPL_NMTST_BASICETHERNET) == 0) { // NMT_StartUp_U32.Bit13 == 0
501 // new state PreOperational1
504 kEplNmtEventTimerMsPreOp1;
505 } else { // NMT_StartUp_U32.Bit13 == 1
506 // new state BasicEthernet
509 kEplNmtEventTimerBasicEthernet;
512 // read NMT_BootTime_REC.MNWaitNotAct_U32 from OD
513 ObdSize = sizeof(dwBuffer);
514 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
517 (EPL_MCO_PTR_INSTANCE_PTR_
518 0x1F89, 0x01, &dwBuffer,
521 Ret = kEplObdIndexNotExist;
523 if (Ret != kEplSuccessful) {
526 // convert us into ms
527 dwBuffer = dwBuffer / 1000;
528 if (dwBuffer == 0) { // timer was below one ms
532 TimerArg.m_EventSink =
535 EplTimeruModifyTimerMs
538 (unsigned long)dwBuffer,
540 // potential error is forwarded to event queue which generates error event
544 // node processes only async frames
545 case kEplNmtMsPreOperational1:
549 tEplTimerArg TimerArg;
551 // create timer to switch automatically to PreOp2 if MN identified all mandatory CNs
553 // read NMT_BootTime_REC.MNWaitPreOp1_U32 from OD
554 ObdSize = sizeof(dwBuffer);
555 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
558 (EPL_MCO_PTR_INSTANCE_PTR_
559 0x1F89, 0x03, &dwBuffer,
561 if (Ret != kEplSuccessful) {
562 // ignore error, because this timeout is optional
566 if (dwBuffer == 0) { // delay is deactivated
567 // immediately post timer event
570 (kEplNmtEventTimerMsPreOp2);
573 // convert us into ms
574 dwBuffer = dwBuffer / 1000;
575 if (dwBuffer == 0) { // timer was below one ms
579 TimerArg.m_EventSink =
583 kEplNmtEventTimerMsPreOp2;
585 EplTimeruModifyTimerMs
588 (unsigned long)dwBuffer,
590 // potential error is forwarded to event queue which generates error event
594 // node processes isochronous and asynchronous frames
595 case kEplNmtMsPreOperational2:
600 // node should be configured und application is ready
601 case kEplNmtMsReadyToOperate:
607 case kEplNmtMsOperational:
613 // -> normal ethernet communication
614 case kEplNmtMsBasicEthernet:
618 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
623 ("EplNmtuProcess(): unhandled NMT state 0x%X\n",
628 } else if (Ret == kEplReject) { // application wants to change NMT state itself
630 Ret = kEplSuccessful;
633 EPL_DBGLVL_NMTU_TRACE0
634 ("EplNmtuProcessEvent(): NMT-State-Maschine announce change of NMT State\n");
640 Ret = kEplNmtInvalidEvent;
649 //---------------------------------------------------------------------------
651 // Function: EplNmtuRegisterStateChangeCb
653 // Description: register Callback-function go get informed about a
654 // NMT-Change-State-Event
658 // Parameters: pfnEplNmtStateChangeCb_p = functionpointer
661 // Returns: tEplKernel = errorcode
666 //---------------------------------------------------------------------------
667 tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
671 Ret = kEplSuccessful;
673 // save callback-function in modul global var
674 EplNmtuInstance_g.m_pfnNmtChangeCb = pfnEplNmtStateChangeCb_p;
680 //=========================================================================//
682 // P R I V A T E F U N C T I O N S //
684 //=========================================================================//
686 //---------------------------------------------------------------------------
702 //---------------------------------------------------------------------------
704 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)