Driver Core: devtmpfs - kernel-maintained tmpfs-based /dev
[linux/fpc-iii.git] / drivers / staging / epl / EplNmtu.c
blob9ac2e8e4845cfbc870007a3b4d50ffc59316f2b6
1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
6 Project: openPOWERLINK
8 Description: source file for NMT-Userspace-Module
10 License:
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
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.
41 Severability Clause:
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 $
54 $Author: D.Krueger $
56 $Revision: 1.8 $ $Date: 2008/11/10 17:17:42 $
58 $State: Exp $
60 Build Environment:
61 GCC V3.4
63 -------------------------------------------------------------------------
65 Revision History:
67 2006/06/09 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "EplInc.h"
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"
77 #endif
79 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
80 /***************************************************************************/
81 /* */
82 /* */
83 /* G L O B A L D E F I N I T I O N S */
84 /* */
85 /* */
86 /***************************************************************************/
88 //---------------------------------------------------------------------------
89 // const defines
90 //---------------------------------------------------------------------------
92 //---------------------------------------------------------------------------
93 // local types
94 //---------------------------------------------------------------------------
96 typedef struct {
97 tEplNmtuStateChangeCallback m_pfnNmtChangeCb;
98 tEplTimerHdl m_TimerHdl;
100 } tEplNmtuInstance;
102 //---------------------------------------------------------------------------
103 // modul globale vars
104 //---------------------------------------------------------------------------
106 static tEplNmtuInstance EplNmtuInstance_g;
108 //---------------------------------------------------------------------------
109 // local function prototypes
110 //---------------------------------------------------------------------------
112 //=========================================================================//
113 // //
114 // P U B L I C F U N C T I O N S //
115 // //
116 //=========================================================================//
118 //---------------------------------------------------------------------------
120 // Function: EplNmtuInit
122 // Description: init first instance of the module
126 // Parameters:
129 // Returns: tEplKernel = errorcode
132 // State:
134 //---------------------------------------------------------------------------
135 tEplKernel EplNmtuInit(void)
137 tEplKernel Ret;
139 Ret = EplNmtuAddInstance();
141 return Ret;
144 //---------------------------------------------------------------------------
146 // Function: EplNmtuAddInstance
148 // Description: init other instances of the module
152 // Parameters:
155 // Returns: tEplKernel = errorcode
158 // State:
160 //---------------------------------------------------------------------------
161 tEplKernel EplNmtuAddInstance(void)
163 tEplKernel Ret;
165 Ret = kEplSuccessful;
167 EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
169 return Ret;
173 //---------------------------------------------------------------------------
175 // Function: EplNmtuDelInstance
177 // Description: delete instance
181 // Parameters:
184 // Returns: tEplKernel = errorcode
187 // State:
189 //---------------------------------------------------------------------------
190 tEplKernel EplNmtuDelInstance(void)
192 tEplKernel Ret;
194 Ret = kEplSuccessful;
196 EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
198 // delete timer
199 Ret = EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
201 return Ret;
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
219 // State:
221 //---------------------------------------------------------------------------
222 tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
224 tEplKernel Ret;
225 tEplEvent Event;
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);
236 return Ret;
239 //---------------------------------------------------------------------------
241 // Function: EplNmtuGetNmtState
243 // Description: returns the actuell NMT-State
247 // Parameters:
250 // Returns: tEplNmtState = NMT-State
253 // 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();
263 #else
264 NmtState = 0;
265 #endif
267 return NmtState;
270 //---------------------------------------------------------------------------
272 // Function: EplNmtuProcessEvent
274 // Description: processes events from event queue
278 // Parameters: pEplEvent_p = pointer to event
281 // Returns: tEplKernel = errorcode
284 // State:
286 //---------------------------------------------------------------------------
287 tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p)
289 tEplKernel Ret;
291 Ret = kEplSuccessful;
293 // process event
294 switch (pEplEvent_p->m_EventType) {
295 // state change of NMT-Module
296 case kEplEventTypeNmtStateChange:
298 tEplEventNmtStateChange *pNmtStateChange;
300 // delete timer
301 Ret =
302 EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
304 pNmtStateChange =
305 (tEplEventNmtStateChange *) pEplEvent_p->m_pArg;
307 // call cb-functions to inform higher layer
308 if (EplNmtuInstance_g.m_pfnNmtChangeCb != NULL) {
309 Ret =
310 EplNmtuInstance_g.
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
317 case kEplNmtGsOff:
318 break;
320 // first init of the hardware
321 case kEplNmtGsInitialising:
323 Ret =
324 EplNmtuNmtEvent
325 (kEplNmtEventEnterResetApp);
326 break;
329 // init of the manufacturer-specific profile area and the
330 // standardised device profile area
331 case kEplNmtGsResetApplication:
333 Ret =
334 EplNmtuNmtEvent
335 (kEplNmtEventEnterResetCom);
336 break;
339 // init of the communication profile area
340 case kEplNmtGsResetCommunication:
342 Ret =
343 EplNmtuNmtEvent
344 (kEplNmtEventEnterResetConfig);
345 break;
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)
355 uiNodeId =
356 EplObduGetNodeId
357 (EPL_MCO_PTR_INSTANCE_PTR);
358 #else
359 uiNodeId = 0;
360 #endif
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)
364 Ret =
365 EplNmtuNmtEvent
366 (kEplNmtEventEnterMsNotActive);
367 #else
368 TRACE0
369 ("EplNmtuProcess(): no MN functionality implemented\n");
370 #endif
371 } else { // node shall be CN
372 Ret =
373 EplNmtuNmtEvent
374 (kEplNmtEventEnterCsNotActive);
376 break;
379 //-----------------------------------------------------------
380 // CN part of the state machine
382 // node listens for EPL-Frames and check timeout
383 case kEplNmtCsNotActive:
385 u32 dwBuffer;
386 tEplObdSize ObdSize;
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)
394 Ret =
395 EplObduReadEntry
396 (EPL_MCO_PTR_INSTANCE_PTR_
397 0x1F99, 0x00, &dwBuffer,
398 &ObdSize);
399 #else
400 Ret = kEplObdIndexNotExist;
401 #endif
402 if (Ret != kEplSuccessful) {
403 break;
405 if (dwBuffer != 0) { // BasicEthernet is enabled
406 // convert us into ms
407 dwBuffer =
408 dwBuffer / 1000;
409 if (dwBuffer == 0) { // timer was below one ms
410 // set one ms
411 dwBuffer = 1;
413 TimerArg.m_EventSink =
414 kEplEventSinkNmtk;
415 TimerArg.m_ulArg =
416 (unsigned long)
417 kEplNmtEventTimerBasicEthernet;
418 Ret =
419 EplTimeruModifyTimerMs
420 (&EplNmtuInstance_g.
421 m_TimerHdl,
422 (unsigned long)
423 dwBuffer,
424 TimerArg);
425 // potential error is forwarded to event queue which generates error event
427 break;
430 // node processes only async frames
431 case kEplNmtCsPreOperational1:
433 break;
436 // node processes isochronous and asynchronous frames
437 case kEplNmtCsPreOperational2:
439 Ret =
440 EplNmtuNmtEvent
441 (kEplNmtEventEnterReadyToOperate);
442 break;
445 // node should be configured und application is ready
446 case kEplNmtCsReadyToOperate:
448 break;
451 // normal work state
452 case kEplNmtCsOperational:
454 break;
457 // node stopped by MN
458 // -> only process asynchronous frames
459 case kEplNmtCsStopped:
461 break;
464 // no EPL cycle
465 // -> normal ethernet communication
466 case kEplNmtCsBasicEthernet:
468 break;
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:
478 u32 dwBuffer;
479 tEplObdSize ObdSize;
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)
488 Ret =
489 EplObduReadEntry
490 (EPL_MCO_PTR_INSTANCE_PTR_
491 0x1F80, 0x00, &dwBuffer,
492 &ObdSize);
493 #else
494 Ret = kEplObdIndexNotExist;
495 #endif
496 if (Ret != kEplSuccessful) {
497 break;
500 if ((dwBuffer & EPL_NMTST_BASICETHERNET) == 0) { // NMT_StartUp_U32.Bit13 == 0
501 // new state PreOperational1
502 TimerArg.m_ulArg =
503 (unsigned long)
504 kEplNmtEventTimerMsPreOp1;
505 } else { // NMT_StartUp_U32.Bit13 == 1
506 // new state BasicEthernet
507 TimerArg.m_ulArg =
508 (unsigned long)
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)
515 Ret =
516 EplObduReadEntry
517 (EPL_MCO_PTR_INSTANCE_PTR_
518 0x1F89, 0x01, &dwBuffer,
519 &ObdSize);
520 #else
521 Ret = kEplObdIndexNotExist;
522 #endif
523 if (Ret != kEplSuccessful) {
524 break;
526 // convert us into ms
527 dwBuffer = dwBuffer / 1000;
528 if (dwBuffer == 0) { // timer was below one ms
529 // set one ms
530 dwBuffer = 1;
532 TimerArg.m_EventSink =
533 kEplEventSinkNmtk;
534 Ret =
535 EplTimeruModifyTimerMs
536 (&EplNmtuInstance_g.
537 m_TimerHdl,
538 (unsigned long)dwBuffer,
539 TimerArg);
540 // potential error is forwarded to event queue which generates error event
541 break;
544 // node processes only async frames
545 case kEplNmtMsPreOperational1:
547 u32 dwBuffer = 0;
548 tEplObdSize ObdSize;
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)
556 Ret =
557 EplObduReadEntry
558 (EPL_MCO_PTR_INSTANCE_PTR_
559 0x1F89, 0x03, &dwBuffer,
560 &ObdSize);
561 if (Ret != kEplSuccessful) {
562 // ignore error, because this timeout is optional
563 dwBuffer = 0;
565 #endif
566 if (dwBuffer == 0) { // delay is deactivated
567 // immediately post timer event
568 Ret =
569 EplNmtuNmtEvent
570 (kEplNmtEventTimerMsPreOp2);
571 break;
573 // convert us into ms
574 dwBuffer = dwBuffer / 1000;
575 if (dwBuffer == 0) { // timer was below one ms
576 // set one ms
577 dwBuffer = 1;
579 TimerArg.m_EventSink =
580 kEplEventSinkNmtk;
581 TimerArg.m_ulArg =
582 (unsigned long)
583 kEplNmtEventTimerMsPreOp2;
584 Ret =
585 EplTimeruModifyTimerMs
586 (&EplNmtuInstance_g.
587 m_TimerHdl,
588 (unsigned long)dwBuffer,
589 TimerArg);
590 // potential error is forwarded to event queue which generates error event
591 break;
594 // node processes isochronous and asynchronous frames
595 case kEplNmtMsPreOperational2:
597 break;
600 // node should be configured und application is ready
601 case kEplNmtMsReadyToOperate:
603 break;
606 // normal work state
607 case kEplNmtMsOperational:
609 break;
612 // no EPL cycle
613 // -> normal ethernet communication
614 case kEplNmtMsBasicEthernet:
616 break;
618 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
620 default:
622 TRACE1
623 ("EplNmtuProcess(): unhandled NMT state 0x%X\n",
624 pNmtStateChange->
625 m_NewNmtState);
628 } else if (Ret == kEplReject) { // application wants to change NMT state itself
629 // it's OK
630 Ret = kEplSuccessful;
633 EPL_DBGLVL_NMTU_TRACE0
634 ("EplNmtuProcessEvent(): NMT-State-Maschine announce change of NMT State\n");
635 break;
638 default:
640 Ret = kEplNmtInvalidEvent;
645 //Exit:
646 return Ret;
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
664 // State:
666 //---------------------------------------------------------------------------
667 tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
669 tEplKernel Ret;
671 Ret = kEplSuccessful;
673 // save callback-function in modul global var
674 EplNmtuInstance_g.m_pfnNmtChangeCb = pfnEplNmtStateChangeCb_p;
676 return Ret;
680 //=========================================================================//
681 // //
682 // P R I V A T E F U N C T I O N S //
683 // //
684 //=========================================================================//
686 //---------------------------------------------------------------------------
688 // Function:
690 // Description:
694 // Parameters:
697 // Returns:
700 // State:
702 //---------------------------------------------------------------------------
704 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
706 // EOF