Staging: epl: clean up demo_main.c
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / epl / demo_main.c
blob7ad10fc2b1d01c75b651d93b9a79a3580463faca
1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
6 Project: openPOWERLINK
8 Description: demoapplication for EPL MN (with SDO over UDP)
9 under Linux on X86 with RTL8139 Ethernet controller
11 License:
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions
15 are met:
17 1. Redistributions of source code must retain the above copyright
18 notice, this list of conditions and the following disclaimer.
20 2. Redistributions in binary form must reproduce the above copyright
21 notice, this list of conditions and the following disclaimer in the
22 documentation and/or other materials provided with the distribution.
24 3. Neither the name of SYSTEC electronic GmbH nor the names of its
25 contributors may be used to endorse or promote products derived
26 from this software without prior written permission. For written
27 permission, please contact info@systec-electronic.com.
29 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
32 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
37 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
39 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40 POSSIBILITY OF SUCH DAMAGE.
42 Severability Clause:
44 If a provision of this License is or becomes illegal, invalid or
45 unenforceable in any jurisdiction, that shall not affect:
46 1. the validity or enforceability in that jurisdiction of any other
47 provision of this License; or
48 2. the validity or enforceability in other jurisdictions of that or
49 any other provision of this License.
51 -------------------------------------------------------------------------
53 $RCSfile: demo_main.c,v $
55 $Author: D.Krueger $
57 $Revision: 1.10 $ $Date: 2008/11/19 18:11:43 $
59 $State: Exp $
61 Build Environment:
62 GCC
64 -------------------------------------------------------------------------
66 Revision History:
68 2006/09/01 d.k.: start of implementation
70 ****************************************************************************/
72 #include <linux/module.h>
73 #include <linux/kernel.h>
74 #include <linux/init.h>
75 #include <linux/errno.h>
76 #include <linux/major.h>
77 #include <asm/io.h>
78 #include <asm/uaccess.h>
79 #include <asm/atomic.h>
80 #include <linux/sched.h>
81 #include <linux/kmod.h>
82 #include <linux/slab.h>
83 #include <linux/pci.h>
84 #include <linux/proc_fs.h>
86 #include "Epl.h"
87 #include "proc_fs.h"
89 /***************************************************************************/
90 /* */
91 /* */
92 /* G L O B A L D E F I N I T I O N S */
93 /* */
94 /* */
95 /***************************************************************************/
97 // Metainformation
98 MODULE_LICENSE("Dual BSD/GPL");
99 #ifdef MODULE_AUTHOR
100 MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
101 MODULE_DESCRIPTION("EPL MN demo");
102 #endif
104 //---------------------------------------------------------------------------
105 // const defines
106 //---------------------------------------------------------------------------
108 // TracePoint support for realtime-debugging
109 #ifdef _DBG_TRACE_POINTS_
110 void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
111 #define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
112 #else
113 #define TGT_DBG_SIGNAL_TRACE_POINT(p)
114 #endif
116 #define NODEID 0xF0 //=> MN
117 #define CYCLE_LEN 5000 // [us]
118 #define IP_ADDR 0xc0a86401 // 192.168.100.1
119 #define SUBNET_MASK 0xFFFFFF00 // 255.255.255.0
120 #define HOSTNAME "SYS TEC electronic EPL Stack "
121 #define IF_ETH EPL_VETH_NAME
123 // LIGHT EFFECT
124 #define DEFAULT_MAX_CYCLE_COUNT 20 // 6 is very fast
125 #define APP_DEFAULT_MODE 0x01
126 #define APP_LED_COUNT 5 // number of LEDs in one row
127 #define APP_LED_MASK ((1 << APP_LED_COUNT) - 1)
128 #define APP_DOUBLE_LED_MASK ((1 << (APP_LED_COUNT * 2)) - 1)
129 #define APP_MODE_COUNT 5
130 #define APP_MODE_MASK ((1 << APP_MODE_COUNT) - 1)
132 //---------------------------------------------------------------------------
133 // local types
134 //---------------------------------------------------------------------------
136 //---------------------------------------------------------------------------
137 // modul globale vars
138 //---------------------------------------------------------------------------
140 static const u8 abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
142 static u8 bVarIn1_l;
143 static u8 bVarOut1_l;
144 static u8 bVarOut1Old_l;
145 static u8 bModeSelect_l; // state of the pushbuttons to select the mode
146 static u8 bSpeedSelect_l; // state of the pushbuttons to increase/decrease the speed
147 static u8 bSpeedSelectOld_l; // old state of the pushbuttons
148 static u32 dwLeds_l; // current state of all LEDs
149 static u8 bLedsRow1_l; // current state of the LEDs in row 1
150 static u8 bLedsRow2_l; // current state of the LEDs in row 2
151 static u8 abSelect_l[3]; // pushbuttons from CNs
153 static u32 dwMode_l; // current mode
154 static int iCurCycleCount_l; // current cycle count
155 static int iMaxCycleCount_l; // maximum cycle count (i.e. number of cycles until next light movement step)
156 static int iToggle; // indicates the light movement direction
158 //static u8 abDomain_l[3000];
160 static wait_queue_head_t WaitQueueShutdown_g; // wait queue for tEplNmtEventSwitchOff
161 static atomic_t AtomicShutdown_g = ATOMIC_INIT(FALSE);
163 static u32 dw_le_CycleLen_g;
165 static uint uiNodeId_g = EPL_C_ADR_INVALID;
166 module_param_named(nodeid, uiNodeId_g, uint, 0);
168 static uint uiCycleLen_g = CYCLE_LEN;
169 module_param_named(cyclelen, uiCycleLen_g, uint, 0);
171 //---------------------------------------------------------------------------
172 // local function prototypes
173 //---------------------------------------------------------------------------
175 // This function is the entry point for your object dictionary. It is defined
176 // in OBJDICT.C by define EPL_OBD_INIT_RAM_NAME. Use this function name to define
177 // this function prototype here. If you want to use more than one Epl
178 // instances then the function name of each object dictionary has to differ.
180 tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
182 tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
183 tEplApiEventArg *pEventArg_p, // IN: event argument (union)
184 void *pUserArg_p);
186 tEplKernel AppCbSync(void);
189 //---------------------------------------------------------------------------
190 // Kernel Module specific Data Structures
191 //---------------------------------------------------------------------------
193 //module_init(EplLinInit);
194 //module_exit(EplLinExit);
196 //=========================================================================//
197 // //
198 // P U B L I C F U N C T I O N S //
199 // //
200 //=========================================================================//
202 //---------------------------------------------------------------------------
204 // Function:
206 // Description:
210 // Parameters:
213 // Returns:
216 // State:
218 //---------------------------------------------------------------------------
219 #if 0
220 static int __init EplLinInit(void)
222 tEplKernel EplRet;
223 int iRet;
224 static tEplApiInitParam EplApiInitParam = { 0 };
225 char *sHostname = HOSTNAME;
226 char *argv[4], *envp[3];
227 char sBuffer[16];
228 unsigned int uiVarEntries;
229 tEplObdSize ObdSize;
231 atomic_set(&AtomicShutdown_g, TRUE);
233 // get node ID from insmod command line
234 EplApiInitParam.m_uiNodeId = uiNodeId_g;
236 if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) { // invalid node ID set
237 // set default node ID
238 EplApiInitParam.m_uiNodeId = NODEID;
241 uiNodeId_g = EplApiInitParam.m_uiNodeId;
243 // calculate IP address
244 EplApiInitParam.m_dwIpAddress =
245 (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId;
247 EplApiInitParam.m_fAsyncOnly = FALSE;
249 EplApiInitParam.m_uiSizeOfStruct = sizeof(EplApiInitParam);
250 EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr,
251 sizeof(EplApiInitParam.m_abMacAddress));
252 // EplApiInitParam.m_abMacAddress[5] = (u8) EplApiInitParam.m_uiNodeId;
253 EplApiInitParam.m_dwFeatureFlags = -1;
254 EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection
255 EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const
256 EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const
257 EplApiInitParam.m_dwPresMaxLatency = 50000; // const; only required for IdentRes
258 EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes)
259 EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes)
260 EplApiInitParam.m_dwAsndMaxLatency = 150000; // const; only required for IdentRes
261 EplApiInitParam.m_uiMultiplCycleCnt = 0; // required for error detection
262 EplApiInitParam.m_uiAsyncMtu = 1500; // required to set up max frame size
263 EplApiInitParam.m_uiPrescaler = 2; // required for sync
264 EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
265 EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
266 EplApiInitParam.m_dwWaitSocPreq = 150000;
267 EplApiInitParam.m_dwDeviceType = -1; // NMT_DeviceType_U32
268 EplApiInitParam.m_dwVendorId = -1; // NMT_IdentityObject_REC.VendorId_U32
269 EplApiInitParam.m_dwProductCode = -1; // NMT_IdentityObject_REC.ProductCode_U32
270 EplApiInitParam.m_dwRevisionNumber = -1; // NMT_IdentityObject_REC.RevisionNo_U32
271 EplApiInitParam.m_dwSerialNumber = -1; // NMT_IdentityObject_REC.SerialNo_U32
272 EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
273 EplApiInitParam.m_dwDefaultGateway = 0;
274 EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname,
275 sizeof(EplApiInitParam.m_sHostname));
277 // currently unset parameters left at default value 0
278 //EplApiInitParam.m_qwVendorSpecificExt1;
279 //EplApiInitParam.m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
280 //EplApiInitParam.m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
281 //EplApiInitParam.m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
282 //EplApiInitParam.m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
283 //EplApiInitParam.m_abVendorSpecificExt2[48];
285 // set callback functions
286 EplApiInitParam.m_pfnCbEvent = AppCbEvent;
287 EplApiInitParam.m_pfnCbSync = AppCbSync;
289 printk
290 ("\n\n Hello, I'm a simple POWERLINK node running as %s!\n (build: %s / %s)\n\n",
291 (uiNodeId_g ==
292 EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"),
293 __DATE__, __TIME__);
295 // initialize the Linux a wait queue for shutdown of this module
296 init_waitqueue_head(&WaitQueueShutdown_g);
298 // initialize the procfs device
299 EplRet = EplLinProcInit();
300 if (EplRet != kEplSuccessful) {
301 goto Exit;
303 // initialize POWERLINK stack
304 EplRet = EplApiInitialize(&EplApiInitParam);
305 if (EplRet != kEplSuccessful) {
306 goto Exit;
308 // link process variables used by CN to object dictionary
309 ObdSize = sizeof(bVarIn1_l);
310 uiVarEntries = 1;
311 EplRet =
312 EplApiLinkObject(0x6000, &bVarIn1_l, &uiVarEntries, &ObdSize, 0x01);
313 if (EplRet != kEplSuccessful) {
314 goto Exit;
317 ObdSize = sizeof(bVarOut1_l);
318 uiVarEntries = 1;
319 EplRet =
320 EplApiLinkObject(0x6200, &bVarOut1_l, &uiVarEntries, &ObdSize,
321 0x01);
322 if (EplRet != kEplSuccessful) {
323 goto Exit;
325 // link process variables used by MN to object dictionary
326 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
327 ObdSize = sizeof(bLedsRow1_l);
328 uiVarEntries = 1;
329 EplRet =
330 EplApiLinkObject(0x2000, &bLedsRow1_l, &uiVarEntries, &ObdSize,
331 0x01);
332 if (EplRet != kEplSuccessful) {
333 goto Exit;
336 ObdSize = sizeof(bLedsRow2_l);
337 uiVarEntries = 1;
338 EplRet =
339 EplApiLinkObject(0x2000, &bLedsRow2_l, &uiVarEntries, &ObdSize,
340 0x02);
341 if (EplRet != kEplSuccessful) {
342 goto Exit;
345 ObdSize = sizeof(bSpeedSelect_l);
346 uiVarEntries = 1;
347 EplRet =
348 EplApiLinkObject(0x2000, &bSpeedSelect_l, &uiVarEntries, &ObdSize,
349 0x03);
350 if (EplRet != kEplSuccessful) {
351 goto Exit;
354 ObdSize = sizeof(bSpeedSelectOld_l);
355 uiVarEntries = 1;
356 EplRet =
357 EplApiLinkObject(0x2000, &bSpeedSelectOld_l, &uiVarEntries,
358 &ObdSize, 0x04);
359 if (EplRet != kEplSuccessful) {
360 goto Exit;
363 ObdSize = sizeof(abSelect_l[0]);
364 uiVarEntries = sizeof(abSelect_l);
365 EplRet =
366 EplApiLinkObject(0x2200, &abSelect_l[0], &uiVarEntries, &ObdSize,
367 0x01);
368 if (EplRet != kEplSuccessful) {
369 goto Exit;
371 #endif
373 // link a DOMAIN to object 0x6100, but do not exit, if it is missing
374 ObdSize = sizeof(abDomain_l);
375 uiVarEntries = 1;
376 EplRet =
377 EplApiLinkObject(0x6100, &abDomain_l, &uiVarEntries, &ObdSize,
378 0x00);
379 if (EplRet != kEplSuccessful) {
380 printk("EplApiLinkObject(0x6100): returns 0x%X\n", EplRet);
382 // reset old process variables
383 bVarOut1Old_l = 0;
384 bSpeedSelectOld_l = 0;
385 dwMode_l = APP_DEFAULT_MODE;
386 iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
388 // configure IP address of virtual network interface
389 // for TCP/IP communication over the POWERLINK network
390 sprintf(sBuffer, "%u.%u.%u.%u",
391 (EplApiInitParam.m_dwIpAddress >> 24),
392 ((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF),
393 ((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF),
394 (EplApiInitParam.m_dwIpAddress & 0xFF));
395 /* set up a minimal environment */
396 iRet = 0;
397 envp[iRet++] = "HOME=/";
398 envp[iRet++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
399 envp[iRet] = NULL;
401 /* set up the argument list */
402 iRet = 0;
403 argv[iRet++] = "/sbin/ifconfig";
404 argv[iRet++] = IF_ETH;
405 argv[iRet++] = sBuffer;
406 argv[iRet] = NULL;
408 /* call ifconfig to configure the virtual network interface */
409 iRet = call_usermodehelper(argv[0], argv, envp, 1);
410 printk("ifconfig %s %s returned %d\n", argv[1], argv[2], iRet);
412 // start the NMT state machine
413 EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
414 atomic_set(&AtomicShutdown_g, FALSE);
416 Exit:
417 printk("EplLinInit(): returns 0x%X\n", EplRet);
418 return EplRet;
421 static void __exit EplLinExit(void)
423 tEplKernel EplRet;
425 // halt the NMT state machine
426 // so the processing of POWERLINK frames stops
427 EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
429 // wait until NMT state machine is shut down
430 wait_event_interruptible(WaitQueueShutdown_g,
431 (atomic_read(&AtomicShutdown_g) == TRUE));
432 /* if ((iErr != 0) || (atomic_read(&AtomicShutdown_g) == EVENT_STATE_IOCTL))
433 { // waiting was interrupted by signal or application called wrong function
434 EplRet = kEplShutdown;
436 // delete instance for all modules
437 EplRet = EplApiShutdown();
438 printk("EplApiShutdown(): 0x%X\n", EplRet);
440 // deinitialize proc fs
441 EplRet = EplLinProcFree();
442 printk("EplLinProcFree(): 0x%X\n", EplRet);
445 #endif
446 //=========================================================================//
447 // //
448 // P R I V A T E F U N C T I O N S //
449 // //
450 //=========================================================================//
452 //---------------------------------------------------------------------------
454 // Function: AppCbEvent
456 // Description: event callback function called by EPL API layer within
457 // user part (low priority).
459 // Parameters: EventType_p = event type
460 // pEventArg_p = pointer to union, which describes
461 // the event in detail
462 // pUserArg_p = user specific argument
464 // Returns: tEplKernel = error code,
465 // kEplSuccessful = no error
466 // kEplReject = reject further processing
467 // otherwise = post error event to API layer
469 // State:
471 //---------------------------------------------------------------------------
473 tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
474 tEplApiEventArg *pEventArg_p, // IN: event argument (union)
475 void *pUserArg_p)
477 tEplKernel EplRet = kEplSuccessful;
479 // check if NMT_GS_OFF is reached
480 switch (EventType_p) {
481 case kEplApiEventNmtStateChange:
483 switch (pEventArg_p->m_NmtStateChange.m_NewNmtState) {
484 case kEplNmtGsOff:
485 { // NMT state machine was shut down,
486 // because of user signal (CTRL-C) or critical EPL stack error
487 // -> also shut down EplApiProcess() and main()
488 EplRet = kEplShutdown;
490 printk
491 ("AppCbEvent(kEplNmtGsOff) originating event = 0x%X\n",
492 pEventArg_p->m_NmtStateChange.
493 m_NmtEvent);
495 // wake up EplLinExit()
496 atomic_set(&AtomicShutdown_g, TRUE);
497 wake_up_interruptible
498 (&WaitQueueShutdown_g);
499 break;
502 case kEplNmtGsResetCommunication:
504 u32 dwBuffer;
506 // configure OD for MN in state ResetComm after reseting the OD
507 // TODO: setup your own network configuration here
508 dwBuffer = (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS); // 0x00000003L
509 EplRet =
510 EplApiWriteLocalObject(0x1F81, 0x01,
511 &dwBuffer,
513 EplRet =
514 EplApiWriteLocalObject(0x1F81, 0x02,
515 &dwBuffer,
517 EplRet =
518 EplApiWriteLocalObject(0x1F81, 0x03,
519 &dwBuffer,
521 EplRet =
522 EplApiWriteLocalObject(0x1F81, 0x04,
523 &dwBuffer,
525 EplRet =
526 EplApiWriteLocalObject(0x1F81, 0x05,
527 &dwBuffer,
529 EplRet =
530 EplApiWriteLocalObject(0x1F81, 0x06,
531 &dwBuffer,
533 EplRet =
534 EplApiWriteLocalObject(0x1F81, 0x07,
535 &dwBuffer,
537 EplRet =
538 EplApiWriteLocalObject(0x1F81, 0x08,
539 &dwBuffer,
541 EplRet =
542 EplApiWriteLocalObject(0x1F81, 0x20,
543 &dwBuffer,
545 EplRet =
546 EplApiWriteLocalObject(0x1F81, 0xFE,
547 &dwBuffer,
549 EplRet =
550 EplApiWriteLocalObject(0x1F81, 0x6E,
551 &dwBuffer,
554 // dwBuffer |= EPL_NODEASSIGN_MANDATORY_CN; // 0x0000000BL
555 // EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwBuffer, 4);
556 dwBuffer = (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS); // 0x00010001L
557 EplRet =
558 EplApiWriteLocalObject(0x1F81, 0xF0,
559 &dwBuffer,
562 // continue
565 case kEplNmtGsResetConfiguration:
567 unsigned int uiSize;
569 // fetch object 0x1006 NMT_CycleLen_U32 from local OD (in little endian byte order)
570 // for configuration of remote CN
571 uiSize = 4;
572 EplRet =
573 EplApiReadObject(NULL, 0, 0x1006,
574 0x00,
575 &dw_le_CycleLen_g,
576 &uiSize,
577 kEplSdoTypeAsnd,
578 NULL);
579 if (EplRet != kEplSuccessful) { // local OD access failed
580 break;
582 // continue
585 case kEplNmtMsPreOperational1:
587 printk
588 ("AppCbEvent(0x%X) originating event = 0x%X\n",
589 pEventArg_p->m_NmtStateChange.
590 m_NewNmtState,
591 pEventArg_p->m_NmtStateChange.
592 m_NmtEvent);
594 // continue
597 case kEplNmtGsInitialising:
598 case kEplNmtGsResetApplication:
599 case kEplNmtMsNotActive:
600 case kEplNmtCsNotActive:
601 case kEplNmtCsPreOperational1:
603 break;
606 case kEplNmtCsOperational:
607 case kEplNmtMsOperational:
609 break;
612 default:
614 break;
619 switch (pEventArg_p->m_NmtStateChange.m_NmtEvent)
621 case kEplNmtEventSwReset:
622 case kEplNmtEventResetNode:
623 case kEplNmtEventResetCom:
624 case kEplNmtEventResetConfig:
625 case kEplNmtEventInternComError:
626 case kEplNmtEventNmtCycleError:
628 printk("AppCbEvent(0x%X) originating event = 0x%X\n",
629 pEventArg_p->m_NmtStateChange.m_NewNmtState,
630 pEventArg_p->m_NmtStateChange.m_NmtEvent);
631 break;
634 default:
636 break;
640 break;
643 case kEplApiEventCriticalError:
644 case kEplApiEventWarning:
645 { // error or warning occured within the stack or the application
646 // on error the API layer stops the NMT state machine
648 printk
649 ("AppCbEvent(Err/Warn): Source=%02X EplError=0x%03X",
650 pEventArg_p->m_InternalError.m_EventSource,
651 pEventArg_p->m_InternalError.m_EplError);
652 // check additional argument
653 switch (pEventArg_p->m_InternalError.m_EventSource) {
654 case kEplEventSourceEventk:
655 case kEplEventSourceEventu:
656 { // error occured within event processing
657 // either in kernel or in user part
658 printk(" OrgSource=%02X\n",
659 pEventArg_p->m_InternalError.
660 m_Arg.m_EventSource);
661 break;
664 case kEplEventSourceDllk:
665 { // error occured within the data link layer (e.g. interrupt processing)
666 // the u32 argument contains the DLL state and the NMT event
667 printk(" val=%X\n",
668 pEventArg_p->m_InternalError.
669 m_Arg.m_dwArg);
670 break;
673 default:
675 printk("\n");
676 break;
679 break;
682 case kEplApiEventNode:
684 // printk("AppCbEvent(Node): Source=%02X EplError=0x%03X", pEventArg_p->m_InternalError.m_EventSource, pEventArg_p->m_InternalError.m_EplError);
685 // check additional argument
686 switch (pEventArg_p->m_Node.m_NodeEvent) {
687 case kEplNmtNodeEventCheckConf:
689 tEplSdoComConHdl SdoComConHdl;
690 // update object 0x1006 on CN
691 EplRet =
692 EplApiWriteObject(&SdoComConHdl,
693 pEventArg_p->
694 m_Node.m_uiNodeId,
695 0x1006, 0x00,
696 &dw_le_CycleLen_g,
698 kEplSdoTypeAsnd,
699 NULL);
700 if (EplRet == kEplApiTaskDeferred) { // SDO transfer started
701 EplRet = kEplReject;
702 } else if (EplRet == kEplSuccessful) { // local OD access (should not occur)
703 printk
704 ("AppCbEvent(Node) write to local OD\n");
705 } else { // error occured
706 TGT_DBG_SIGNAL_TRACE_POINT(1);
708 EplRet =
709 EplApiFreeSdoChannel
710 (SdoComConHdl);
711 SdoComConHdl = 0;
713 EplRet =
714 EplApiWriteObject
715 (&SdoComConHdl,
716 pEventArg_p->m_Node.
717 m_uiNodeId, 0x1006, 0x00,
718 &dw_le_CycleLen_g, 4,
719 kEplSdoTypeAsnd, NULL);
720 if (EplRet == kEplApiTaskDeferred) { // SDO transfer started
721 EplRet = kEplReject;
722 } else {
723 printk
724 ("AppCbEvent(Node): EplApiWriteObject() returned 0x%02X\n",
725 EplRet);
729 break;
732 default:
734 break;
737 break;
740 case kEplApiEventSdo:
741 { // SDO transfer finished
742 EplRet =
743 EplApiFreeSdoChannel(pEventArg_p->m_Sdo.
744 m_SdoComConHdl);
745 if (EplRet != kEplSuccessful) {
746 break;
748 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
749 if (pEventArg_p->m_Sdo.m_SdoComConState == kEplSdoComTransferFinished) { // continue boot-up of CN with NMT command Reset Configuration
750 EplRet =
751 EplApiMnTriggerStateChange(pEventArg_p->
752 m_Sdo.m_uiNodeId,
753 kEplNmtNodeCommandConfReset);
754 } else { // indicate configuration error CN
755 EplRet =
756 EplApiMnTriggerStateChange(pEventArg_p->
757 m_Sdo.m_uiNodeId,
758 kEplNmtNodeCommandConfErr);
760 #endif
762 break;
765 default:
766 break;
769 return EplRet;
772 //---------------------------------------------------------------------------
774 // Function: AppCbSync
776 // Description: sync event callback function called by event module within
777 // kernel part (high priority).
778 // This function sets the outputs, reads the inputs and runs
779 // the control loop.
781 // Parameters: void
783 // Returns: tEplKernel = error code,
784 // kEplSuccessful = no error
785 // otherwise = post error event to API layer
787 // State:
789 //---------------------------------------------------------------------------
791 tEplKernel AppCbSync(void)
793 tEplKernel EplRet = kEplSuccessful;
795 if (bVarOut1Old_l != bVarOut1_l) { // output variable has changed
796 bVarOut1Old_l = bVarOut1_l;
797 // set LEDs
799 // printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (u16) bVarIn_l, (u16) bVarOut_l);
801 if (uiNodeId_g != EPL_C_ADR_MN_DEF_NODE_ID) {
802 bVarIn1_l++;
805 if (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID) { // we are the master and must run the control loop
807 // collect inputs from CNs and own input
808 bSpeedSelect_l = (bVarIn1_l | abSelect_l[0]) & 0x07;
810 bModeSelect_l = abSelect_l[1] | abSelect_l[2];
812 if ((bModeSelect_l & APP_MODE_MASK) != 0) {
813 dwMode_l = bModeSelect_l & APP_MODE_MASK;
816 iCurCycleCount_l--;
818 if (iCurCycleCount_l <= 0) {
819 if ((dwMode_l & 0x01) != 0) { // fill-up
820 if (iToggle) {
821 if ((dwLeds_l & APP_DOUBLE_LED_MASK) ==
822 0x00) {
823 dwLeds_l = 0x01;
824 } else {
825 dwLeds_l <<= 1;
826 dwLeds_l++;
827 if (dwLeds_l >=
828 APP_DOUBLE_LED_MASK) {
829 iToggle = 0;
832 } else {
833 dwLeds_l <<= 1;
834 if ((dwLeds_l & APP_DOUBLE_LED_MASK) ==
835 0x00) {
836 iToggle = 1;
839 bLedsRow1_l =
840 (unsigned char)(dwLeds_l & APP_LED_MASK);
841 bLedsRow2_l =
842 (unsigned char)((dwLeds_l >> APP_LED_COUNT)
843 & APP_LED_MASK);
846 else if ((dwMode_l & 0x02) != 0) { // running light forward
847 dwLeds_l <<= 1;
848 if ((dwLeds_l > APP_DOUBLE_LED_MASK)
849 || (dwLeds_l == 0x00000000L)) {
850 dwLeds_l = 0x01;
852 bLedsRow1_l =
853 (unsigned char)(dwLeds_l & APP_LED_MASK);
854 bLedsRow2_l =
855 (unsigned char)((dwLeds_l >> APP_LED_COUNT)
856 & APP_LED_MASK);
859 else if ((dwMode_l & 0x04) != 0) { // running light backward
860 dwLeds_l >>= 1;
861 if ((dwLeds_l > APP_DOUBLE_LED_MASK)
862 || (dwLeds_l == 0x00000000L)) {
863 dwLeds_l = 1 << (APP_LED_COUNT * 2);
865 bLedsRow1_l =
866 (unsigned char)(dwLeds_l & APP_LED_MASK);
867 bLedsRow2_l =
868 (unsigned char)((dwLeds_l >> APP_LED_COUNT)
869 & APP_LED_MASK);
872 else if ((dwMode_l & 0x08) != 0) { // Knightrider
873 if (bLedsRow1_l == 0x00) {
874 bLedsRow1_l = 0x01;
875 iToggle = 1;
876 } else if (iToggle) {
877 bLedsRow1_l <<= 1;
878 if (bLedsRow1_l >=
879 (1 << (APP_LED_COUNT - 1))) {
880 iToggle = 0;
882 } else {
883 bLedsRow1_l >>= 1;
884 if (bLedsRow1_l <= 0x01) {
885 iToggle = 1;
888 bLedsRow2_l = bLedsRow1_l;
891 else if ((dwMode_l & 0x10) != 0) { // Knightrider
892 if ((bLedsRow1_l == 0x00)
893 || (bLedsRow2_l == 0x00)
894 || ((bLedsRow2_l & ~APP_LED_MASK) != 0)) {
895 bLedsRow1_l = 0x01;
896 bLedsRow2_l =
897 (1 << (APP_LED_COUNT - 1));
898 iToggle = 1;
899 } else if (iToggle) {
900 bLedsRow1_l <<= 1;
901 bLedsRow2_l >>= 1;
902 if (bLedsRow1_l >=
903 (1 << (APP_LED_COUNT - 1))) {
904 iToggle = 0;
906 } else {
907 bLedsRow1_l >>= 1;
908 bLedsRow2_l <<= 1;
909 if (bLedsRow1_l <= 0x01) {
910 iToggle = 1;
914 // set own output
915 bVarOut1_l = bLedsRow1_l;
916 // bVarOut1_l = (bLedsRow1_l & 0x03) | (bLedsRow2_l << 2);
918 // restart cycle counter
919 iCurCycleCount_l = iMaxCycleCount_l;
922 if (bSpeedSelectOld_l == 0) {
923 if ((bSpeedSelect_l & 0x01) != 0) {
924 if (iMaxCycleCount_l < 200) {
925 iMaxCycleCount_l++;
927 bSpeedSelectOld_l = bSpeedSelect_l;
928 } else if ((bSpeedSelect_l & 0x02) != 0) {
929 if (iMaxCycleCount_l > 1) {
930 iMaxCycleCount_l--;
932 bSpeedSelectOld_l = bSpeedSelect_l;
933 } else if ((bSpeedSelect_l & 0x04) != 0) {
934 iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
935 bSpeedSelectOld_l = bSpeedSelect_l;
937 } else if (bSpeedSelect_l == 0) {
938 bSpeedSelectOld_l = 0;
942 TGT_DBG_SIGNAL_TRACE_POINT(1);
944 return EplRet;
947 // EOF