Staging: comedi: Remove comedi_cmd typedef
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / epl / demo_main.c
1 /****************************************************************************
2
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
5
6 Project: openPOWERLINK
7
8 Description: demoapplication for EPL MN (with SDO over UDP)
9 under Linux on X86 with RTL8139 Ethernet controller
10
11 License:
12
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions
15 are met:
16
17 1. Redistributions of source code must retain the above copyright
18 notice, this list of conditions and the following disclaimer.
19
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.
23
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.
28
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.
41
42 Severability Clause:
43
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.
50
51 -------------------------------------------------------------------------
52
53 $RCSfile: demo_main.c,v $
54
55 $Author: D.Krueger $
56
57 $Revision: 1.10 $ $Date: 2008/11/19 18:11:43 $
58
59 $State: Exp $
60
61 Build Environment:
62 GCC
63
64 -------------------------------------------------------------------------
65
66 Revision History:
67
68 2006/09/01 d.k.: start of implementation
69
70 ****************************************************************************/
71
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 <linux/version.h>
78 #include <asm/io.h>
79 #include <asm/uaccess.h>
80 #include <asm/atomic.h>
81 #include <linux/sched.h>
82 #include <linux/kmod.h>
83 #include <linux/slab.h>
84 #include <linux/pci.h>
85 #include <linux/proc_fs.h>
86
87 #include "Epl.h"
88 #include "proc_fs.h"
89
90 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
91 // remove ("make invisible") obsolete symbols for kernel versions 2.6
92 // and higher
93 #define MOD_INC_USE_COUNT
94 #define MOD_DEC_USE_COUNT
95 #define EXPORT_NO_SYMBOLS
96 #else
97 #error "This driver needs a 2.6.x kernel or higher"
98 #endif
99
100 /***************************************************************************/
101 /* */
102 /* */
103 /* G L O B A L D E F I N I T I O N S */
104 /* */
105 /* */
106 /***************************************************************************/
107
108 // Metainformation
109 MODULE_LICENSE("Dual BSD/GPL");
110 #ifdef MODULE_AUTHOR
111 MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
112 MODULE_DESCRIPTION("EPL MN demo");
113 #endif
114
115 //---------------------------------------------------------------------------
116 // const defines
117 //---------------------------------------------------------------------------
118
119 // TracePoint support for realtime-debugging
120 #ifdef _DBG_TRACE_POINTS_
121 void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
122 #define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
123 #else
124 #define TGT_DBG_SIGNAL_TRACE_POINT(p)
125 #endif
126
127 #define NODEID 0xF0 //=> MN
128 #define CYCLE_LEN 5000 // [us]
129 #define IP_ADDR 0xc0a86401 // 192.168.100.1
130 #define SUBNET_MASK 0xFFFFFF00 // 255.255.255.0
131 #define HOSTNAME "SYS TEC electronic EPL Stack "
132 #define IF_ETH EPL_VETH_NAME
133
134 // LIGHT EFFECT
135 #define DEFAULT_MAX_CYCLE_COUNT 20 // 6 is very fast
136 #define APP_DEFAULT_MODE 0x01
137 #define APP_LED_COUNT 5 // number of LEDs in one row
138 #define APP_LED_MASK ((1 << APP_LED_COUNT) - 1)
139 #define APP_DOUBLE_LED_MASK ((1 << (APP_LED_COUNT * 2)) - 1)
140 #define APP_MODE_COUNT 5
141 #define APP_MODE_MASK ((1 << APP_MODE_COUNT) - 1)
142
143 //---------------------------------------------------------------------------
144 // local types
145 //---------------------------------------------------------------------------
146
147 //---------------------------------------------------------------------------
148 // modul globale vars
149 //---------------------------------------------------------------------------
150
151 CONST BYTE abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
152
153 BYTE bVarIn1_l;
154 BYTE bVarOut1_l;
155 BYTE bVarOut1Old_l;
156 BYTE bModeSelect_l; // state of the pushbuttons to select the mode
157 BYTE bSpeedSelect_l; // state of the pushbuttons to increase/decrease the speed
158 BYTE bSpeedSelectOld_l; // old state of the pushbuttons
159 DWORD dwLeds_l; // current state of all LEDs
160 BYTE bLedsRow1_l; // current state of the LEDs in row 1
161 BYTE bLedsRow2_l; // current state of the LEDs in row 2
162 BYTE abSelect_l[3]; // pushbuttons from CNs
163
164 DWORD dwMode_l; // current mode
165 int iCurCycleCount_l; // current cycle count
166 int iMaxCycleCount_l; // maximum cycle count (i.e. number of cycles until next light movement step)
167 int iToggle; // indicates the light movement direction
168
169 BYTE abDomain_l[3000];
170
171 static wait_queue_head_t WaitQueueShutdown_g; // wait queue for tEplNmtEventSwitchOff
172 static atomic_t AtomicShutdown_g = ATOMIC_INIT(FALSE);
173
174 static DWORD dw_le_CycleLen_g;
175
176 static uint uiNodeId_g = EPL_C_ADR_INVALID;
177 module_param_named(nodeid, uiNodeId_g, uint, 0);
178
179 static uint uiCycleLen_g = CYCLE_LEN;
180 module_param_named(cyclelen, uiCycleLen_g, uint, 0);
181
182 //---------------------------------------------------------------------------
183 // local function prototypes
184 //---------------------------------------------------------------------------
185
186 // This function is the entry point for your object dictionary. It is defined
187 // in OBJDICT.C by define EPL_OBD_INIT_RAM_NAME. Use this function name to define
188 // this function prototype here. If you want to use more than one Epl
189 // instances then the function name of each object dictionary has to differ.
190
191 tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
192
193 tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
194 tEplApiEventArg * pEventArg_p, // IN: event argument (union)
195 void GENERIC * pUserArg_p);
196
197 tEplKernel PUBLIC AppCbSync(void);
198
199 static int __init EplLinInit(void);
200 static void __exit EplLinExit(void);
201
202 //---------------------------------------------------------------------------
203 // Kernel Module specific Data Structures
204 //---------------------------------------------------------------------------
205
206 EXPORT_NO_SYMBOLS;
207
208 //module_init(EplLinInit);
209 //module_exit(EplLinExit);
210
211 //=========================================================================//
212 // //
213 // P U B L I C F U N C T I O N S //
214 // //
215 //=========================================================================//
216
217 //---------------------------------------------------------------------------
218 //
219 // Function:
220 //
221 // Description:
222 //
223 //
224 //
225 // Parameters:
226 //
227 //
228 // Returns:
229 //
230 //
231 // State:
232 //
233 //---------------------------------------------------------------------------
234 static int __init EplLinInit(void)
235 {
236 tEplKernel EplRet;
237 int iRet;
238 static tEplApiInitParam EplApiInitParam = { 0 };
239 char *sHostname = HOSTNAME;
240 char *argv[4], *envp[3];
241 char sBuffer[16];
242 unsigned int uiVarEntries;
243 tEplObdSize ObdSize;
244
245 atomic_set(&AtomicShutdown_g, TRUE);
246
247 // get node ID from insmod command line
248 EplApiInitParam.m_uiNodeId = uiNodeId_g;
249
250 if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) { // invalid node ID set
251 // set default node ID
252 EplApiInitParam.m_uiNodeId = NODEID;
253 }
254
255 uiNodeId_g = EplApiInitParam.m_uiNodeId;
256
257 // calculate IP address
258 EplApiInitParam.m_dwIpAddress =
259 (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId;
260
261 EplApiInitParam.m_fAsyncOnly = FALSE;
262
263 EplApiInitParam.m_uiSizeOfStruct = sizeof(EplApiInitParam);
264 EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr,
265 sizeof(EplApiInitParam.m_abMacAddress));
266 // EplApiInitParam.m_abMacAddress[5] = (BYTE) EplApiInitParam.m_uiNodeId;
267 EplApiInitParam.m_dwFeatureFlags = -1;
268 EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection
269 EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const
270 EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const
271 EplApiInitParam.m_dwPresMaxLatency = 50000; // const; only required for IdentRes
272 EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes)
273 EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes)
274 EplApiInitParam.m_dwAsndMaxLatency = 150000; // const; only required for IdentRes
275 EplApiInitParam.m_uiMultiplCycleCnt = 0; // required for error detection
276 EplApiInitParam.m_uiAsyncMtu = 1500; // required to set up max frame size
277 EplApiInitParam.m_uiPrescaler = 2; // required for sync
278 EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
279 EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
280 EplApiInitParam.m_dwWaitSocPreq = 150000;
281 EplApiInitParam.m_dwDeviceType = -1; // NMT_DeviceType_U32
282 EplApiInitParam.m_dwVendorId = -1; // NMT_IdentityObject_REC.VendorId_U32
283 EplApiInitParam.m_dwProductCode = -1; // NMT_IdentityObject_REC.ProductCode_U32
284 EplApiInitParam.m_dwRevisionNumber = -1; // NMT_IdentityObject_REC.RevisionNo_U32
285 EplApiInitParam.m_dwSerialNumber = -1; // NMT_IdentityObject_REC.SerialNo_U32
286 EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
287 EplApiInitParam.m_dwDefaultGateway = 0;
288 EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname,
289 sizeof(EplApiInitParam.m_sHostname));
290
291 // currently unset parameters left at default value 0
292 //EplApiInitParam.m_qwVendorSpecificExt1;
293 //EplApiInitParam.m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
294 //EplApiInitParam.m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
295 //EplApiInitParam.m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
296 //EplApiInitParam.m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
297 //EplApiInitParam.m_abVendorSpecificExt2[48];
298
299 // set callback functions
300 EplApiInitParam.m_pfnCbEvent = AppCbEvent;
301 EplApiInitParam.m_pfnCbSync = AppCbSync;
302
303 printk
304 ("\n\n Hello, I'm a simple POWERLINK node running as %s!\n (build: %s / %s)\n\n",
305 (uiNodeId_g ==
306 EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"),
307 __DATE__, __TIME__);
308
309 // initialize the Linux a wait queue for shutdown of this module
310 init_waitqueue_head(&WaitQueueShutdown_g);
311
312 // initialize the procfs device
313 EplRet = EplLinProcInit();
314 if (EplRet != kEplSuccessful) {
315 goto Exit;
316 }
317 // initialize POWERLINK stack
318 EplRet = EplApiInitialize(&EplApiInitParam);
319 if (EplRet != kEplSuccessful) {
320 goto Exit;
321 }
322 // link process variables used by CN to object dictionary
323 ObdSize = sizeof(bVarIn1_l);
324 uiVarEntries = 1;
325 EplRet =
326 EplApiLinkObject(0x6000, &bVarIn1_l, &uiVarEntries, &ObdSize, 0x01);
327 if (EplRet != kEplSuccessful) {
328 goto Exit;
329 }
330
331 ObdSize = sizeof(bVarOut1_l);
332 uiVarEntries = 1;
333 EplRet =
334 EplApiLinkObject(0x6200, &bVarOut1_l, &uiVarEntries, &ObdSize,
335 0x01);
336 if (EplRet != kEplSuccessful) {
337 goto Exit;
338 }
339 // link process variables used by MN to object dictionary
340 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
341 ObdSize = sizeof(bLedsRow1_l);
342 uiVarEntries = 1;
343 EplRet =
344 EplApiLinkObject(0x2000, &bLedsRow1_l, &uiVarEntries, &ObdSize,
345 0x01);
346 if (EplRet != kEplSuccessful) {
347 goto Exit;
348 }
349
350 ObdSize = sizeof(bLedsRow2_l);
351 uiVarEntries = 1;
352 EplRet =
353 EplApiLinkObject(0x2000, &bLedsRow2_l, &uiVarEntries, &ObdSize,
354 0x02);
355 if (EplRet != kEplSuccessful) {
356 goto Exit;
357 }
358
359 ObdSize = sizeof(bSpeedSelect_l);
360 uiVarEntries = 1;
361 EplRet =
362 EplApiLinkObject(0x2000, &bSpeedSelect_l, &uiVarEntries, &ObdSize,
363 0x03);
364 if (EplRet != kEplSuccessful) {
365 goto Exit;
366 }
367
368 ObdSize = sizeof(bSpeedSelectOld_l);
369 uiVarEntries = 1;
370 EplRet =
371 EplApiLinkObject(0x2000, &bSpeedSelectOld_l, &uiVarEntries,
372 &ObdSize, 0x04);
373 if (EplRet != kEplSuccessful) {
374 goto Exit;
375 }
376
377 ObdSize = sizeof(abSelect_l[0]);
378 uiVarEntries = sizeof(abSelect_l);
379 EplRet =
380 EplApiLinkObject(0x2200, &abSelect_l[0], &uiVarEntries, &ObdSize,
381 0x01);
382 if (EplRet != kEplSuccessful) {
383 goto Exit;
384 }
385 #endif
386
387 // link a DOMAIN to object 0x6100, but do not exit, if it is missing
388 ObdSize = sizeof(abDomain_l);
389 uiVarEntries = 1;
390 EplRet =
391 EplApiLinkObject(0x6100, &abDomain_l, &uiVarEntries, &ObdSize,
392 0x00);
393 if (EplRet != kEplSuccessful) {
394 printk("EplApiLinkObject(0x6100): returns 0x%X\n", EplRet);
395 }
396 // reset old process variables
397 bVarOut1Old_l = 0;
398 bSpeedSelectOld_l = 0;
399 dwMode_l = APP_DEFAULT_MODE;
400 iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
401
402 // configure IP address of virtual network interface
403 // for TCP/IP communication over the POWERLINK network
404 sprintf(sBuffer, "%lu.%lu.%lu.%lu",
405 (EplApiInitParam.m_dwIpAddress >> 24),
406 ((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF),
407 ((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF),
408 (EplApiInitParam.m_dwIpAddress & 0xFF));
409 /* set up a minimal environment */
410 iRet = 0;
411 envp[iRet++] = "HOME=/";
412 envp[iRet++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
413 envp[iRet] = NULL;
414
415 /* set up the argument list */
416 iRet = 0;
417 argv[iRet++] = "/sbin/ifconfig";
418 argv[iRet++] = IF_ETH;
419 argv[iRet++] = sBuffer;
420 argv[iRet] = NULL;
421
422 /* call ifconfig to configure the virtual network interface */
423 iRet = call_usermodehelper(argv[0], argv, envp, 1);
424 printk("ifconfig %s %s returned %d\n", argv[1], argv[2], iRet);
425
426 // start the NMT state machine
427 EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
428 atomic_set(&AtomicShutdown_g, FALSE);
429
430 Exit:
431 printk("EplLinInit(): returns 0x%X\n", EplRet);
432 return EplRet;
433 }
434
435 static void __exit EplLinExit(void)
436 {
437 tEplKernel EplRet;
438
439 // halt the NMT state machine
440 // so the processing of POWERLINK frames stops
441 EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
442
443 // wait until NMT state machine is shut down
444 wait_event_interruptible(WaitQueueShutdown_g,
445 (atomic_read(&AtomicShutdown_g) == TRUE));
446 /* if ((iErr != 0) || (atomic_read(&AtomicShutdown_g) == EVENT_STATE_IOCTL))
447 { // waiting was interrupted by signal or application called wrong function
448 EplRet = kEplShutdown;
449 }*/
450 // delete instance for all modules
451 EplRet = EplApiShutdown();
452 printk("EplApiShutdown(): 0x%X\n", EplRet);
453
454 // deinitialize proc fs
455 EplRet = EplLinProcFree();
456 printk("EplLinProcFree(): 0x%X\n", EplRet);
457
458 }
459
460 //=========================================================================//
461 // //
462 // P R I V A T E F U N C T I O N S //
463 // //
464 //=========================================================================//
465
466 //---------------------------------------------------------------------------
467 //
468 // Function: AppCbEvent
469 //
470 // Description: event callback function called by EPL API layer within
471 // user part (low priority).
472 //
473 // Parameters: EventType_p = event type
474 // pEventArg_p = pointer to union, which describes
475 // the event in detail
476 // pUserArg_p = user specific argument
477 //
478 // Returns: tEplKernel = error code,
479 // kEplSuccessful = no error
480 // kEplReject = reject further processing
481 // otherwise = post error event to API layer
482 //
483 // State:
484 //
485 //---------------------------------------------------------------------------
486
487 tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
488 tEplApiEventArg * pEventArg_p, // IN: event argument (union)
489 void GENERIC * pUserArg_p)
490 {
491 tEplKernel EplRet = kEplSuccessful;
492
493 // check if NMT_GS_OFF is reached
494 switch (EventType_p) {
495 case kEplApiEventNmtStateChange:
496 {
497 switch (pEventArg_p->m_NmtStateChange.m_NewNmtState) {
498 case kEplNmtGsOff:
499 { // NMT state machine was shut down,
500 // because of user signal (CTRL-C) or critical EPL stack error
501 // -> also shut down EplApiProcess() and main()
502 EplRet = kEplShutdown;
503
504 printk
505 ("AppCbEvent(kEplNmtGsOff) originating event = 0x%X\n",
506 pEventArg_p->m_NmtStateChange.
507 m_NmtEvent);
508
509 // wake up EplLinExit()
510 atomic_set(&AtomicShutdown_g, TRUE);
511 wake_up_interruptible
512 (&WaitQueueShutdown_g);
513 break;
514 }
515
516 case kEplNmtGsResetCommunication:
517 {
518 DWORD dwBuffer;
519
520 // configure OD for MN in state ResetComm after reseting the OD
521 // TODO: setup your own network configuration here
522 dwBuffer = (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS); // 0x00000003L
523 EplRet =
524 EplApiWriteLocalObject(0x1F81, 0x01,
525 &dwBuffer,
526 4);
527 EplRet =
528 EplApiWriteLocalObject(0x1F81, 0x02,
529 &dwBuffer,
530 4);
531 EplRet =
532 EplApiWriteLocalObject(0x1F81, 0x03,
533 &dwBuffer,
534 4);
535 EplRet =
536 EplApiWriteLocalObject(0x1F81, 0x04,
537 &dwBuffer,
538 4);
539 EplRet =
540 EplApiWriteLocalObject(0x1F81, 0x05,
541 &dwBuffer,
542 4);
543 EplRet =
544 EplApiWriteLocalObject(0x1F81, 0x06,
545 &dwBuffer,
546 4);
547 EplRet =
548 EplApiWriteLocalObject(0x1F81, 0x07,
549 &dwBuffer,
550 4);
551 EplRet =
552 EplApiWriteLocalObject(0x1F81, 0x08,
553 &dwBuffer,
554 4);
555 EplRet =
556 EplApiWriteLocalObject(0x1F81, 0x20,
557 &dwBuffer,
558 4);
559 EplRet =
560 EplApiWriteLocalObject(0x1F81, 0xFE,
561 &dwBuffer,
562 4);
563 EplRet =
564 EplApiWriteLocalObject(0x1F81, 0x6E,
565 &dwBuffer,
566 4);
567
568 // dwBuffer |= EPL_NODEASSIGN_MANDATORY_CN; // 0x0000000BL
569 // EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwBuffer, 4);
570 dwBuffer = (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS); // 0x00010001L
571 EplRet =
572 EplApiWriteLocalObject(0x1F81, 0xF0,
573 &dwBuffer,
574 4);
575
576 // continue
577 }
578
579 case kEplNmtGsResetConfiguration:
580 {
581 unsigned int uiSize;
582
583 // fetch object 0x1006 NMT_CycleLen_U32 from local OD (in little endian byte order)
584 // for configuration of remote CN
585 uiSize = 4;
586 EplRet =
587 EplApiReadObject(NULL, 0, 0x1006,
588 0x00,
589 &dw_le_CycleLen_g,
590 &uiSize,
591 kEplSdoTypeAsnd,
592 NULL);
593 if (EplRet != kEplSuccessful) { // local OD access failed
594 break;
595 }
596 // continue
597 }
598
599 case kEplNmtMsPreOperational1:
600 {
601 printk
602 ("AppCbEvent(0x%X) originating event = 0x%X\n",
603 pEventArg_p->m_NmtStateChange.
604 m_NewNmtState,
605 pEventArg_p->m_NmtStateChange.
606 m_NmtEvent);
607
608 // continue
609 }
610
611 case kEplNmtGsInitialising:
612 case kEplNmtGsResetApplication:
613 case kEplNmtMsNotActive:
614 case kEplNmtCsNotActive:
615 case kEplNmtCsPreOperational1:
616 {
617 break;
618 }
619
620 case kEplNmtCsOperational:
621 case kEplNmtMsOperational:
622 {
623 break;
624 }
625
626 default:
627 {
628 break;
629 }
630 }
631
632 /*
633 switch (pEventArg_p->m_NmtStateChange.m_NmtEvent)
634 {
635 case kEplNmtEventSwReset:
636 case kEplNmtEventResetNode:
637 case kEplNmtEventResetCom:
638 case kEplNmtEventResetConfig:
639 case kEplNmtEventInternComError:
640 case kEplNmtEventNmtCycleError:
641 {
642 printk("AppCbEvent(0x%X) originating event = 0x%X\n",
643 pEventArg_p->m_NmtStateChange.m_NewNmtState,
644 pEventArg_p->m_NmtStateChange.m_NmtEvent);
645 break;
646 }
647
648 default:
649 {
650 break;
651 }
652 }
653 */
654 break;
655 }
656
657 case kEplApiEventCriticalError:
658 case kEplApiEventWarning:
659 { // error or warning occured within the stack or the application
660 // on error the API layer stops the NMT state machine
661
662 printk
663 ("AppCbEvent(Err/Warn): Source=%02X EplError=0x%03X",
664 pEventArg_p->m_InternalError.m_EventSource,
665 pEventArg_p->m_InternalError.m_EplError);
666 // check additional argument
667 switch (pEventArg_p->m_InternalError.m_EventSource) {
668 case kEplEventSourceEventk:
669 case kEplEventSourceEventu:
670 { // error occured within event processing
671 // either in kernel or in user part
672 printk(" OrgSource=%02X\n",
673 pEventArg_p->m_InternalError.
674 m_Arg.m_EventSource);
675 break;
676 }
677
678 case kEplEventSourceDllk:
679 { // error occured within the data link layer (e.g. interrupt processing)
680 // the DWORD argument contains the DLL state and the NMT event
681 printk(" val=%lX\n",
682 pEventArg_p->m_InternalError.
683 m_Arg.m_dwArg);
684 break;
685 }
686
687 default:
688 {
689 printk("\n");
690 break;
691 }
692 }
693 break;
694 }
695
696 case kEplApiEventNode:
697 {
698 // printk("AppCbEvent(Node): Source=%02X EplError=0x%03X", pEventArg_p->m_InternalError.m_EventSource, pEventArg_p->m_InternalError.m_EplError);
699 // check additional argument
700 switch (pEventArg_p->m_Node.m_NodeEvent) {
701 case kEplNmtNodeEventCheckConf:
702 {
703 tEplSdoComConHdl SdoComConHdl;
704 // update object 0x1006 on CN
705 EplRet =
706 EplApiWriteObject(&SdoComConHdl,
707 pEventArg_p->
708 m_Node.m_uiNodeId,
709 0x1006, 0x00,
710 &dw_le_CycleLen_g,
711 4,
712 kEplSdoTypeAsnd,
713 NULL);
714 if (EplRet == kEplApiTaskDeferred) { // SDO transfer started
715 EplRet = kEplReject;
716 } else if (EplRet == kEplSuccessful) { // local OD access (should not occur)
717 printk
718 ("AppCbEvent(Node) write to local OD\n");
719 } else { // error occured
720 TGT_DBG_SIGNAL_TRACE_POINT(1);
721
722 EplRet =
723 EplApiFreeSdoChannel
724 (SdoComConHdl);
725 SdoComConHdl = 0;
726
727 EplRet =
728 EplApiWriteObject
729 (&SdoComConHdl,
730 pEventArg_p->m_Node.
731 m_uiNodeId, 0x1006, 0x00,
732 &dw_le_CycleLen_g, 4,
733 kEplSdoTypeAsnd, NULL);
734 if (EplRet == kEplApiTaskDeferred) { // SDO transfer started
735 EplRet = kEplReject;
736 } else {
737 printk
738 ("AppCbEvent(Node): EplApiWriteObject() returned 0x%02X\n",
739 EplRet);
740 }
741 }
742
743 break;
744 }
745
746 default:
747 {
748 break;
749 }
750 }
751 break;
752 }
753
754 case kEplApiEventSdo:
755 { // SDO transfer finished
756 EplRet =
757 EplApiFreeSdoChannel(pEventArg_p->m_Sdo.
758 m_SdoComConHdl);
759 if (EplRet != kEplSuccessful) {
760 break;
761 }
762 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
763 if (pEventArg_p->m_Sdo.m_SdoComConState == kEplSdoComTransferFinished) { // continue boot-up of CN with NMT command Reset Configuration
764 EplRet =
765 EplApiMnTriggerStateChange(pEventArg_p->
766 m_Sdo.m_uiNodeId,
767 kEplNmtNodeCommandConfReset);
768 } else { // indicate configuration error CN
769 EplRet =
770 EplApiMnTriggerStateChange(pEventArg_p->
771 m_Sdo.m_uiNodeId,
772 kEplNmtNodeCommandConfErr);
773 }
774 #endif
775
776 break;
777 }
778
779 default:
780 break;
781 }
782
783 return EplRet;
784 }
785
786 //---------------------------------------------------------------------------
787 //
788 // Function: AppCbSync
789 //
790 // Description: sync event callback function called by event module within
791 // kernel part (high priority).
792 // This function sets the outputs, reads the inputs and runs
793 // the control loop.
794 //
795 // Parameters: void
796 //
797 // Returns: tEplKernel = error code,
798 // kEplSuccessful = no error
799 // otherwise = post error event to API layer
800 //
801 // State:
802 //
803 //---------------------------------------------------------------------------
804
805 tEplKernel PUBLIC AppCbSync(void)
806 {
807 tEplKernel EplRet = kEplSuccessful;
808
809 if (bVarOut1Old_l != bVarOut1_l) { // output variable has changed
810 bVarOut1Old_l = bVarOut1_l;
811 // set LEDs
812
813 // printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (WORD) bVarIn_l, (WORD) bVarOut_l);
814 }
815 if (uiNodeId_g != EPL_C_ADR_MN_DEF_NODE_ID) {
816 bVarIn1_l++;
817 }
818
819 if (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID) { // we are the master and must run the control loop
820
821 // collect inputs from CNs and own input
822 bSpeedSelect_l = (bVarIn1_l | abSelect_l[0]) & 0x07;
823
824 bModeSelect_l = abSelect_l[1] | abSelect_l[2];
825
826 if ((bModeSelect_l & APP_MODE_MASK) != 0) {
827 dwMode_l = bModeSelect_l & APP_MODE_MASK;
828 }
829
830 iCurCycleCount_l--;
831
832 if (iCurCycleCount_l <= 0) {
833 if ((dwMode_l & 0x01) != 0) { // fill-up
834 if (iToggle) {
835 if ((dwLeds_l & APP_DOUBLE_LED_MASK) ==
836 0x00) {
837 dwLeds_l = 0x01;
838 } else {
839 dwLeds_l <<= 1;
840 dwLeds_l++;
841 if (dwLeds_l >=
842 APP_DOUBLE_LED_MASK) {
843 iToggle = 0;
844 }
845 }
846 } else {
847 dwLeds_l <<= 1;
848 if ((dwLeds_l & APP_DOUBLE_LED_MASK) ==
849 0x00) {
850 iToggle = 1;
851 }
852 }
853 bLedsRow1_l =
854 (unsigned char)(dwLeds_l & APP_LED_MASK);
855 bLedsRow2_l =
856 (unsigned char)((dwLeds_l >> APP_LED_COUNT)
857 & APP_LED_MASK);
858 }
859
860 else if ((dwMode_l & 0x02) != 0) { // running light forward
861 dwLeds_l <<= 1;
862 if ((dwLeds_l > APP_DOUBLE_LED_MASK)
863 || (dwLeds_l == 0x00000000L)) {
864 dwLeds_l = 0x01;
865 }
866 bLedsRow1_l =
867 (unsigned char)(dwLeds_l & APP_LED_MASK);
868 bLedsRow2_l =
869 (unsigned char)((dwLeds_l >> APP_LED_COUNT)
870 & APP_LED_MASK);
871 }
872
873 else if ((dwMode_l & 0x04) != 0) { // running light backward
874 dwLeds_l >>= 1;
875 if ((dwLeds_l > APP_DOUBLE_LED_MASK)
876 || (dwLeds_l == 0x00000000L)) {
877 dwLeds_l = 1 << (APP_LED_COUNT * 2);
878 }
879 bLedsRow1_l =
880 (unsigned char)(dwLeds_l & APP_LED_MASK);
881 bLedsRow2_l =
882 (unsigned char)((dwLeds_l >> APP_LED_COUNT)
883 & APP_LED_MASK);
884 }
885
886 else if ((dwMode_l & 0x08) != 0) { // Knightrider
887 if (bLedsRow1_l == 0x00) {
888 bLedsRow1_l = 0x01;
889 iToggle = 1;
890 } else if (iToggle) {
891 bLedsRow1_l <<= 1;
892 if (bLedsRow1_l >=
893 (1 << (APP_LED_COUNT - 1))) {
894 iToggle = 0;
895 }
896 } else {
897 bLedsRow1_l >>= 1;
898 if (bLedsRow1_l <= 0x01) {
899 iToggle = 1;
900 }
901 }
902 bLedsRow2_l = bLedsRow1_l;
903 }
904
905 else if ((dwMode_l & 0x10) != 0) { // Knightrider
906 if ((bLedsRow1_l == 0x00)
907 || (bLedsRow2_l == 0x00)
908 || ((bLedsRow2_l & ~APP_LED_MASK) != 0)) {
909 bLedsRow1_l = 0x01;
910 bLedsRow2_l =
911 (1 << (APP_LED_COUNT - 1));
912 iToggle = 1;
913 } else if (iToggle) {
914 bLedsRow1_l <<= 1;
915 bLedsRow2_l >>= 1;
916 if (bLedsRow1_l >=
917 (1 << (APP_LED_COUNT - 1))) {
918 iToggle = 0;
919 }
920 } else {
921 bLedsRow1_l >>= 1;
922 bLedsRow2_l <<= 1;
923 if (bLedsRow1_l <= 0x01) {
924 iToggle = 1;
925 }
926 }
927 }
928 // set own output
929 bVarOut1_l = bLedsRow1_l;
930 // bVarOut1_l = (bLedsRow1_l & 0x03) | (bLedsRow2_l << 2);
931
932 // restart cycle counter
933 iCurCycleCount_l = iMaxCycleCount_l;
934 }
935
936 if (bSpeedSelectOld_l == 0) {
937 if ((bSpeedSelect_l & 0x01) != 0) {
938 if (iMaxCycleCount_l < 200) {
939 iMaxCycleCount_l++;
940 }
941 bSpeedSelectOld_l = bSpeedSelect_l;
942 } else if ((bSpeedSelect_l & 0x02) != 0) {
943 if (iMaxCycleCount_l > 1) {
944 iMaxCycleCount_l--;
945 }
946 bSpeedSelectOld_l = bSpeedSelect_l;
947 } else if ((bSpeedSelect_l & 0x04) != 0) {
948 iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
949 bSpeedSelectOld_l = bSpeedSelect_l;
950 }
951 } else if (bSpeedSelect_l == 0) {
952 bSpeedSelectOld_l = 0;
953 }
954 }
955
956 TGT_DBG_SIGNAL_TRACE_POINT(1);
957
958 return EplRet;
959 }
960
961 // EOF