Driver Core: devtmpfs - kernel-maintained tmpfs-based /dev
[linux/fpc-iii.git] / drivers / staging / epl / EplApiGeneric.c
blobc4419569183f25404f1daa33edcfbb14222c816f
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 generic EPL API 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: EplApiGeneric.c,v $
54 $Author: D.Krueger $
56 $Revision: 1.21 $ $Date: 2008/11/21 09:00:38 $
58 $State: Exp $
60 Build Environment:
61 GCC V3.4
63 -------------------------------------------------------------------------
65 Revision History:
67 2006/09/05 d.k.: start of the implementation, version 1.00
69 ****************************************************************************/
71 #include "Epl.h"
72 #include "kernel/EplDllk.h"
73 #include "kernel/EplErrorHandlerk.h"
74 #include "kernel/EplEventk.h"
75 #include "kernel/EplNmtk.h"
76 #include "kernel/EplObdk.h"
77 #include "kernel/EplTimerk.h"
78 #include "kernel/EplDllkCal.h"
79 #include "kernel/EplPdokCal.h"
80 #include "user/EplDlluCal.h"
81 #include "user/EplLedu.h"
82 #include "user/EplNmtCnu.h"
83 #include "user/EplNmtMnu.h"
84 #include "user/EplSdoComu.h"
85 #include "user/EplIdentu.h"
86 #include "user/EplStatusu.h"
88 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
89 #include "kernel/EplPdok.h"
90 #endif
92 #include "SharedBuff.h"
94 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
95 #error "EPL API layer needs EPL module OBDK!"
96 #endif
98 /***************************************************************************/
99 /* */
100 /* */
101 /* G L O B A L D E F I N I T I O N S */
102 /* */
103 /* */
104 /***************************************************************************/
106 //---------------------------------------------------------------------------
107 // const defines
108 //---------------------------------------------------------------------------
110 //---------------------------------------------------------------------------
111 // local types
112 //---------------------------------------------------------------------------
114 //---------------------------------------------------------------------------
115 // modul globale vars
116 //---------------------------------------------------------------------------
118 //---------------------------------------------------------------------------
119 // local function prototypes
120 //---------------------------------------------------------------------------
122 /***************************************************************************/
123 /* */
124 /* */
125 /* C L A S S EplApi */
126 /* */
127 /* */
128 /***************************************************************************/
130 // Description:
133 /***************************************************************************/
135 //=========================================================================//
136 // //
137 // P R I V A T E D E F I N I T I O N S //
138 // //
139 //=========================================================================//
141 //---------------------------------------------------------------------------
142 // const defines
143 //---------------------------------------------------------------------------
145 //---------------------------------------------------------------------------
146 // local types
147 //---------------------------------------------------------------------------
149 typedef struct {
150 tEplApiInitParam m_InitParam;
152 } tEplApiInstance;
154 //---------------------------------------------------------------------------
155 // local vars
156 //---------------------------------------------------------------------------
158 static tEplApiInstance EplApiInstance_g;
160 //---------------------------------------------------------------------------
161 // local function prototypes
162 //---------------------------------------------------------------------------
164 // NMT state change event callback function
165 static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
167 // update DLL configuration from OD
168 static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
170 // update OD from init param
171 static tEplKernel EplApiUpdateObd(void);
173 // process events from user event queue
174 static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p);
176 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
177 // callback function of SDO module
178 static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p);
179 #endif
181 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
182 // callback functions of NmtMnu module
183 static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
184 tEplNmtNodeEvent NodeEvent_p,
185 tEplNmtState NmtState_p,
186 u16 wErrorCode_p, BOOL fMandatory_p);
188 static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
189 tEplNmtState NmtState_p,
190 u16 wErrorCode_p);
191 #endif
193 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
194 // callback function of Ledu module
195 static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p);
196 #endif
198 // OD initialization function (implemented in Objdict.c)
199 tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
201 //=========================================================================//
202 // //
203 // P U B L I C F U N C T I O N S //
204 // //
205 //=========================================================================//
207 //---------------------------------------------------------------------------
209 // Function: EplApiInitialize()
211 // Description: add and initialize new instance of EPL stack.
212 // After return from this function the application must start
213 // the NMT state machine via
214 // EplApiExecNmtCommand(kEplNmtEventSwReset)
215 // and thereby the whole EPL stack :-)
217 // Parameters: pInitParam_p = initialisation parameters
219 // Returns: tEplKernel = error code
222 // State:
224 //---------------------------------------------------------------------------
226 tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p)
228 tEplKernel Ret = kEplSuccessful;
229 tEplObdInitParam ObdInitParam;
230 tEplDllkInitParam DllkInitParam;
231 #ifndef EPL_NO_FIFO
232 tShbError ShbError;
233 #endif
235 // reset instance structure
236 EPL_MEMSET(&EplApiInstance_g, 0, sizeof(EplApiInstance_g));
238 EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p,
239 min(sizeof(tEplApiInitParam),
240 pInitParam_p->m_uiSizeOfStruct));
242 // check event callback function pointer
243 if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL) { // application must always have an event callback function
244 Ret = kEplApiInvalidParam;
245 goto Exit;
247 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
248 // init OD
249 // FIXME
250 // Ret = EplObdInitRam(&ObdInitParam);
251 // if (Ret != kEplSuccessful)
252 // {
253 // goto Exit;
254 // }
256 // initialize EplObd module
257 Ret = EplObdInit(&ObdInitParam);
258 if (Ret != kEplSuccessful) {
259 goto Exit;
261 #endif
263 #ifndef EPL_NO_FIFO
264 ShbError = ShbInit();
265 if (ShbError != kShbOk) {
266 Ret = kEplNoResource;
267 goto Exit;
269 #endif
271 // initialize EplEventk module
272 Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync);
273 if (Ret != kEplSuccessful) {
274 goto Exit;
276 // initialize EplEventu module
277 Ret = EplEventuInit(EplApiProcessEvent);
278 if (Ret != kEplSuccessful) {
279 goto Exit;
281 // init EplTimerk module
282 Ret = EplTimerkInit();
283 if (Ret != kEplSuccessful) {
284 goto Exit;
286 // initialize EplNmtk module before DLL
287 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
288 Ret = EplNmtkInit();
289 if (Ret != kEplSuccessful) {
290 goto Exit;
292 #endif
294 // initialize EplDllk module
295 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
296 EPL_MEMCPY(DllkInitParam.m_be_abSrcMac,
297 EplApiInstance_g.m_InitParam.m_abMacAddress, 6);
298 Ret = EplDllkAddInstance(&DllkInitParam);
299 if (Ret != kEplSuccessful) {
300 goto Exit;
302 // initialize EplErrorHandlerk module
303 Ret = EplErrorHandlerkInit();
304 if (Ret != kEplSuccessful) {
305 goto Exit;
307 // initialize EplDllkCal module
308 Ret = EplDllkCalAddInstance();
309 if (Ret != kEplSuccessful) {
310 goto Exit;
312 #endif
314 // initialize EplDlluCal module
315 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
316 Ret = EplDlluCalAddInstance();
317 if (Ret != kEplSuccessful) {
318 goto Exit;
320 #endif
322 // initialize EplPdok module
323 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
324 Ret = EplPdokAddInstance();
325 if (Ret != kEplSuccessful) {
326 goto Exit;
329 Ret = EplPdokCalAddInstance();
330 if (Ret != kEplSuccessful) {
331 goto Exit;
333 #endif
335 // initialize EplNmtCnu module
336 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
337 Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId);
338 if (Ret != kEplSuccessful) {
339 goto Exit;
341 #endif
343 // initialize EplNmtu module
344 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
345 Ret = EplNmtuInit();
346 if (Ret != kEplSuccessful) {
347 goto Exit;
349 // register NMT event callback function
350 Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange);
351 if (Ret != kEplSuccessful) {
352 goto Exit;
354 #endif
356 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
357 // initialize EplNmtMnu module
358 Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent);
359 if (Ret != kEplSuccessful) {
360 goto Exit;
362 // initialize EplIdentu module
363 Ret = EplIdentuInit();
364 if (Ret != kEplSuccessful) {
365 goto Exit;
367 // initialize EplStatusu module
368 Ret = EplStatusuInit();
369 if (Ret != kEplSuccessful) {
370 goto Exit;
372 #endif
374 // initialize EplLedu module
375 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
376 Ret = EplLeduInit(EplApiCbLedStateChange);
377 if (Ret != kEplSuccessful) {
378 goto Exit;
380 #endif
382 // init SDO module
383 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
384 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
385 // init sdo command layer
386 Ret = EplSdoComInit();
387 if (Ret != kEplSuccessful) {
388 goto Exit;
390 #endif
392 // the application must start NMT state machine
393 // via EplApiExecNmtCommand(kEplNmtEventSwReset)
394 // and thereby the whole EPL stack
396 Exit:
397 return Ret;
400 //---------------------------------------------------------------------------
402 // Function: EplApiShutdown()
404 // Description: deletes an instance of EPL stack
406 // Parameters: (none)
408 // Returns: tEplKernel = error code
411 // State:
413 //---------------------------------------------------------------------------
415 tEplKernel EplApiShutdown(void)
417 tEplKernel Ret = kEplSuccessful;
419 // $$$ d.k.: check if NMT state is NMT_GS_OFF
421 // $$$ d.k.: maybe delete event queues at first, but this implies that
422 // no other module must not use the event queues for communication
423 // during shutdown.
425 // delete instance for all modules
427 // deinitialize EplSdoCom module
428 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
429 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
430 Ret = EplSdoComDelInstance();
431 // PRINTF1("EplSdoComDelInstance(): 0x%X\n", Ret);
432 #endif
434 // deinitialize EplLedu module
435 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
436 Ret = EplLeduDelInstance();
437 // PRINTF1("EplLeduDelInstance(): 0x%X\n", Ret);
438 #endif
440 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
441 // deinitialize EplNmtMnu module
442 Ret = EplNmtMnuDelInstance();
443 // PRINTF1("EplNmtMnuDelInstance(): 0x%X\n", Ret);
445 // deinitialize EplIdentu module
446 Ret = EplIdentuDelInstance();
447 // PRINTF1("EplIdentuDelInstance(): 0x%X\n", Ret);
449 // deinitialize EplStatusu module
450 Ret = EplStatusuDelInstance();
451 // PRINTF1("EplStatusuDelInstance(): 0x%X\n", Ret);
452 #endif
454 // deinitialize EplNmtCnu module
455 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
456 Ret = EplNmtCnuDelInstance();
457 // PRINTF1("EplNmtCnuDelInstance(): 0x%X\n", Ret);
458 #endif
460 // deinitialize EplNmtu module
461 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
462 Ret = EplNmtuDelInstance();
463 // PRINTF1("EplNmtuDelInstance(): 0x%X\n", Ret);
464 #endif
466 // deinitialize EplDlluCal module
467 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
468 Ret = EplDlluCalDelInstance();
469 // PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret);
471 #endif
473 // deinitialize EplEventu module
474 Ret = EplEventuDelInstance();
475 // PRINTF1("EplEventuDelInstance(): 0x%X\n", Ret);
477 // deinitialize EplNmtk module
478 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
479 Ret = EplNmtkDelInstance();
480 // PRINTF1("EplNmtkDelInstance(): 0x%X\n", Ret);
481 #endif
483 // deinitialize EplDllk module
484 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
485 Ret = EplDllkDelInstance();
486 // PRINTF1("EplDllkDelInstance(): 0x%X\n", Ret);
488 // deinitialize EplDllkCal module
489 Ret = EplDllkCalDelInstance();
490 // PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret);
491 #endif
493 // deinitialize EplEventk module
494 Ret = EplEventkDelInstance();
495 // PRINTF1("EplEventkDelInstance(): 0x%X\n", Ret);
497 // deinitialize EplTimerk module
498 Ret = EplTimerkDelInstance();
499 // PRINTF1("EplTimerkDelInstance(): 0x%X\n", Ret);
501 #ifndef EPL_NO_FIFO
502 ShbExit();
503 #endif
505 return Ret;
508 //----------------------------------------------------------------------------
509 // Function: EplApiExecNmtCommand()
511 // Description: executes a NMT command, i.e. post the NMT command/event to the
512 // NMTk module. NMT commands which are not appropriate in the current
513 // NMT state are silently ignored. Please keep in mind that the
514 // NMT state may change until the NMT command is actually executed.
516 // Parameters: NmtEvent_p = NMT command/event
518 // Returns: tEplKernel = error code
520 // State:
521 //----------------------------------------------------------------------------
523 tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
525 tEplKernel Ret = kEplSuccessful;
527 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
528 Ret = EplNmtuNmtEvent(NmtEvent_p);
529 #endif
531 return Ret;
534 //----------------------------------------------------------------------------
535 // Function: EplApiLinkObject()
537 // Description: Function maps array of application variables onto specified object in OD
539 // Parameters: uiObjIndex_p = Function maps variables for this object index
540 // pVar_p = Pointer to data memory area for the specified object
541 // puiVarEntries_p = IN: pointer to number of entries to map
542 // OUT: pointer to number of actually used entries
543 // pEntrySize_p = IN: pointer to size of one entry;
544 // if size is zero, the actual size will be read from OD
545 // OUT: pointer to entire size of all entries mapped
546 // uiFirstSubindex_p = This is the first subindex to be mapped.
548 // Returns: tEplKernel = error code
550 // State:
551 //----------------------------------------------------------------------------
553 tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
554 void *pVar_p,
555 unsigned int *puiVarEntries_p,
556 tEplObdSize *pEntrySize_p,
557 unsigned int uiFirstSubindex_p)
559 u8 bVarEntries;
560 u8 bIndexEntries;
561 u8 *pbData;
562 unsigned int uiSubindex;
563 tEplVarParam VarParam;
564 tEplObdSize EntrySize;
565 tEplObdSize UsedSize;
567 tEplKernel RetCode = kEplSuccessful;
569 if ((pVar_p == NULL)
570 || (puiVarEntries_p == NULL)
571 || (*puiVarEntries_p == 0)
572 || (pEntrySize_p == NULL)) {
573 RetCode = kEplApiInvalidParam;
574 goto Exit;
577 pbData = (u8 *)pVar_p;
578 bVarEntries = (u8) * puiVarEntries_p;
579 UsedSize = 0;
581 // init VarParam structure with default values
582 VarParam.m_uiIndex = uiObjIndex_p;
583 VarParam.m_ValidFlag = kVarValidAll;
585 if (uiFirstSubindex_p != 0) { // check if object exists by reading subindex 0x00,
586 // because user wants to link a variable to a subindex unequal 0x00
587 // read number of entries
588 EntrySize = (tEplObdSize) sizeof(bIndexEntries);
589 RetCode = EplObdReadEntry(uiObjIndex_p,
590 0x00,
591 (void *)&bIndexEntries,
592 &EntrySize);
594 if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
595 // Object doesn't exist or invalid entry number
596 RetCode = kEplObdIndexNotExist;
597 goto Exit;
599 } else { // user wants to link a variable to subindex 0x00
600 // that's OK
601 bIndexEntries = 0;
604 // Correct number of entries if number read from OD is greater
605 // than the specified number.
606 // This is done, so that we do not set more entries than subindexes the
607 // object actually has.
608 if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
609 (bVarEntries != 0x00)) {
610 bIndexEntries = (u8) (bVarEntries + uiFirstSubindex_p - 1);
612 // map entries
613 for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
614 uiSubindex++) {
615 // if passed entry size is 0, then get size from OD
616 if (*pEntrySize_p == 0x00) {
617 // read entry size
618 EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex);
620 if (EntrySize == 0x00) {
621 // invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty)
622 RetCode = kEplObdSubindexNotExist;
623 break;
625 } else { // use passed entry size
626 EntrySize = *pEntrySize_p;
629 VarParam.m_uiSubindex = uiSubindex;
631 // set pointer to user var
632 VarParam.m_Size = EntrySize;
633 VarParam.m_pData = pbData;
635 UsedSize += EntrySize;
636 pbData += EntrySize;
638 RetCode = EplObdDefineVar(&VarParam);
639 if (RetCode != kEplSuccessful) {
640 break;
644 // set number of mapped entries and entry size
645 *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1);
646 *pEntrySize_p = UsedSize;
648 Exit:
650 return (RetCode);
654 // ----------------------------------------------------------------------------
656 // Function: EplApiReadObject()
658 // Description: reads the specified entry from the OD of the specified node.
659 // If this node is a remote node, it performs a SDO transfer, which
660 // means this function returns kEplApiTaskDeferred and the application
661 // is informed via the event callback function when the task is completed.
663 // Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
664 // uiNodeId_p = IN: node ID (0 = itself)
665 // uiIndex_p = IN: index of object in OD
666 // uiSubindex_p = IN: sub-index of object in OD
667 // pDstData_le_p = OUT: pointer to data in little endian
668 // puiSize_p = INOUT: pointer to size of data
669 // SdoType_p = IN: type of SDO transfer
670 // pUserArg_p = IN: user-definable argument pointer,
671 // which will be passed to the event callback function
673 // Return: tEplKernel = error code
675 // ----------------------------------------------------------------------------
677 tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
678 unsigned int uiNodeId_p,
679 unsigned int uiIndex_p,
680 unsigned int uiSubindex_p,
681 void *pDstData_le_p,
682 unsigned int *puiSize_p,
683 tEplSdoType SdoType_p, void *pUserArg_p)
685 tEplKernel Ret = kEplSuccessful;
687 if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL)
688 || (*puiSize_p == 0)) {
689 Ret = kEplApiInvalidParam;
690 goto Exit;
693 if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed
694 tEplObdSize ObdSize;
696 ObdSize = (tEplObdSize) * puiSize_p;
697 Ret =
698 EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p,
699 &ObdSize);
700 *puiSize_p = (unsigned int)ObdSize;
701 } else { // perform SDO transfer
702 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
703 tEplSdoComTransParamByIndex TransParamByIndex;
704 // tEplSdoComConHdl SdoComConHdl;
706 // check if application provides space for handle
707 if (pSdoComConHdl_p == NULL) {
708 Ret = kEplApiInvalidParam;
709 goto Exit;
710 // pSdoComConHdl_p = &SdoComConHdl;
712 // init command layer connection
713 Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p, // target node id
714 SdoType_p); // SDO type
715 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
716 goto Exit;
718 TransParamByIndex.m_pData = pDstData_le_p;
719 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead;
720 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
721 TransParamByIndex.m_uiDataSize = *puiSize_p;
722 TransParamByIndex.m_uiIndex = uiIndex_p;
723 TransParamByIndex.m_uiSubindex = uiSubindex_p;
724 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
725 TransParamByIndex.m_pUserArg = pUserArg_p;
727 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
728 if (Ret != kEplSuccessful) {
729 goto Exit;
731 Ret = kEplApiTaskDeferred;
733 #else
734 Ret = kEplApiInvalidParam;
735 #endif
738 Exit:
739 return Ret;
742 // ----------------------------------------------------------------------------
744 // Function: EplApiWriteObject()
746 // Description: writes the specified entry to the OD of the specified node.
747 // If this node is a remote node, it performs a SDO transfer, which
748 // means this function returns kEplApiTaskDeferred and the application
749 // is informed via the event callback function when the task is completed.
751 // Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
752 // uiNodeId_p = IN: node ID (0 = itself)
753 // uiIndex_p = IN: index of object in OD
754 // uiSubindex_p = IN: sub-index of object in OD
755 // pSrcData_le_p = IN: pointer to data in little endian
756 // uiSize_p = IN: size of data in bytes
757 // SdoType_p = IN: type of SDO transfer
758 // pUserArg_p = IN: user-definable argument pointer,
759 // which will be passed to the event callback function
761 // Return: tEplKernel = error code
763 // ----------------------------------------------------------------------------
765 tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
766 unsigned int uiNodeId_p,
767 unsigned int uiIndex_p,
768 unsigned int uiSubindex_p,
769 void *pSrcData_le_p,
770 unsigned int uiSize_p,
771 tEplSdoType SdoType_p, void *pUserArg_p)
773 tEplKernel Ret = kEplSuccessful;
775 if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0)) {
776 Ret = kEplApiInvalidParam;
777 goto Exit;
780 if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed
782 Ret =
783 EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p,
784 pSrcData_le_p, uiSize_p);
785 } else { // perform SDO transfer
786 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
787 tEplSdoComTransParamByIndex TransParamByIndex;
788 // tEplSdoComConHdl SdoComConHdl;
790 // check if application provides space for handle
791 if (pSdoComConHdl_p == NULL) {
792 Ret = kEplApiInvalidParam;
793 goto Exit;
794 // pSdoComConHdl_p = &SdoComConHdl;
796 // d.k.: How to recycle command layer connection?
797 // Try to redefine it, which will return kEplSdoComHandleExists
798 // and the existing command layer handle.
799 // If the returned handle is busy, EplSdoComInitTransferByIndex()
800 // will return with error.
801 // $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and
802 // Configuration Manager, are trying to communicate with the very same node.
803 // possible solution: disallow communication by application if Configuration Manager is busy
805 // init command layer connection
806 Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p, // target node id
807 SdoType_p); // SDO type
808 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
809 goto Exit;
811 TransParamByIndex.m_pData = pSrcData_le_p;
812 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite;
813 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
814 TransParamByIndex.m_uiDataSize = uiSize_p;
815 TransParamByIndex.m_uiIndex = uiIndex_p;
816 TransParamByIndex.m_uiSubindex = uiSubindex_p;
817 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
818 TransParamByIndex.m_pUserArg = pUserArg_p;
820 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
821 if (Ret != kEplSuccessful) {
822 goto Exit;
824 Ret = kEplApiTaskDeferred;
826 #else
827 Ret = kEplApiInvalidParam;
828 #endif
831 Exit:
832 return Ret;
835 // ----------------------------------------------------------------------------
837 // Function: EplApiFreeSdoChannel()
839 // Description: frees the specified SDO channel.
840 // This function must be called after each call to EplApiReadObject()/EplApiWriteObject()
841 // which returns kEplApiTaskDeferred and the application
842 // is informed via the event callback function when the task is completed.
844 // Parameters: SdoComConHdl_p = IN: SDO connection handle
846 // Return: tEplKernel = error code
848 // ----------------------------------------------------------------------------
850 tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
852 tEplKernel Ret = kEplSuccessful;
854 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
856 // init command layer connection
857 Ret = EplSdoComUndefineCon(SdoComConHdl_p);
859 #else
860 Ret = kEplApiInvalidParam;
861 #endif
863 return Ret;
866 // ----------------------------------------------------------------------------
868 // Function: EplApiReadLocalObject()
870 // Description: reads the specified entry from the local OD.
872 // Parameters: uiIndex_p = IN: index of object in OD
873 // uiSubindex_p = IN: sub-index of object in OD
874 // pDstData_p = OUT: pointer to data in platform byte order
875 // puiSize_p = INOUT: pointer to size of data
877 // Return: tEplKernel = error code
879 // ----------------------------------------------------------------------------
881 tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
882 unsigned int uiSubindex_p,
883 void *pDstData_p, unsigned int *puiSize_p)
885 tEplKernel Ret = kEplSuccessful;
886 tEplObdSize ObdSize;
888 ObdSize = (tEplObdSize) * puiSize_p;
889 Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize);
890 *puiSize_p = (unsigned int)ObdSize;
892 return Ret;
895 // ----------------------------------------------------------------------------
897 // Function: EplApiWriteLocalObject()
899 // Description: writes the specified entry to the local OD.
901 // Parameters: uiIndex_p = IN: index of object in OD
902 // uiSubindex_p = IN: sub-index of object in OD
903 // pSrcData_p = IN: pointer to data in platform byte order
904 // uiSize_p = IN: size of data in bytes
906 // Return: tEplKernel = error code
908 // ----------------------------------------------------------------------------
910 tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
911 unsigned int uiSubindex_p,
912 void *pSrcData_p,
913 unsigned int uiSize_p)
915 tEplKernel Ret = kEplSuccessful;
917 Ret =
918 EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p,
919 (tEplObdSize) uiSize_p);
921 return Ret;
924 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
925 // ----------------------------------------------------------------------------
927 // Function: EplApiMnTriggerStateChange()
929 // Description: triggers the specified node command for the specified node.
931 // Parameters: uiNodeId_p = node ID for which the node command will be executed
932 // NodeCommand_p = node command
934 // Return: tEplKernel = error code
936 // ----------------------------------------------------------------------------
938 tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
939 tEplNmtNodeCommand NodeCommand_p)
941 tEplKernel Ret = kEplSuccessful;
943 Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p);
945 return Ret;
948 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
950 //---------------------------------------------------------------------------
952 // Function: EplApiCbObdAccess
954 // Description: callback function for OD accesses
956 // Parameters: pParam_p = OBD parameter
958 // Returns: tEplKernel = error code
961 // State:
963 //---------------------------------------------------------------------------
965 tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p)
967 tEplKernel Ret = kEplSuccessful;
969 #if (EPL_API_OBD_FORWARD_EVENT != FALSE)
970 tEplApiEventArg EventArg;
972 // call user callback
973 // must be disabled for EplApiLinuxKernel.c, because of reentrancy problem
974 // for local OD access. This is not so bad as user callback function in
975 // application does not use OD callbacks at the moment.
976 EventArg.m_ObdCbParam = *pParam_p;
977 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess,
978 &EventArg,
979 EplApiInstance_g.
980 m_InitParam.
981 m_pEventUserArg);
982 #endif
984 switch (pParam_p->m_uiIndex) {
985 //case 0x1006: // NMT_CycleLen_U32 (valid on reset)
986 case 0x1C14: // DLL_LossOfFrameTolerance_U32
987 //case 0x1F98: // NMT_CycleTiming_REC (valid on reset)
989 if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
990 // update DLL configuration
991 Ret = EplApiUpdateDllConfig(FALSE);
993 break;
996 case 0x1020: // CFM_VerifyConfiguration_REC.ConfId_U32 != 0
998 if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
999 && (pParam_p->m_uiSubIndex == 3)
1000 && (*((u32 *) pParam_p->m_pArg) != 0)) {
1001 u32 dwVerifyConfInvalid = 0;
1002 // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
1003 Ret =
1004 EplObdWriteEntry(0x1020, 4,
1005 &dwVerifyConfInvalid, 4);
1006 // ignore any error because this objekt is optional
1007 Ret = kEplSuccessful;
1009 break;
1012 case 0x1F9E: // NMT_ResetCmd_U8
1014 if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
1015 u8 bNmtCommand;
1017 bNmtCommand = *((u8 *) pParam_p->m_pArg);
1018 // check value range
1019 switch ((tEplNmtCommand) bNmtCommand) {
1020 case kEplNmtCmdResetNode:
1021 case kEplNmtCmdResetCommunication:
1022 case kEplNmtCmdResetConfiguration:
1023 case kEplNmtCmdSwReset:
1024 case kEplNmtCmdInvalidService:
1025 // valid command identifier specified
1026 break;
1028 default:
1029 pParam_p->m_dwAbortCode =
1030 EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1031 Ret = kEplObdAccessViolation;
1032 break;
1034 } else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
1035 u8 bNmtCommand;
1037 bNmtCommand = *((u8 *) pParam_p->m_pArg);
1038 // check value range
1039 switch ((tEplNmtCommand) bNmtCommand) {
1040 case kEplNmtCmdResetNode:
1041 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1042 Ret =
1043 EplNmtuNmtEvent
1044 (kEplNmtEventResetNode);
1045 #endif
1046 break;
1048 case kEplNmtCmdResetCommunication:
1049 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1050 Ret =
1051 EplNmtuNmtEvent
1052 (kEplNmtEventResetCom);
1053 #endif
1054 break;
1056 case kEplNmtCmdResetConfiguration:
1057 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1058 Ret =
1059 EplNmtuNmtEvent
1060 (kEplNmtEventResetConfig);
1061 #endif
1062 break;
1064 case kEplNmtCmdSwReset:
1065 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1066 Ret =
1067 EplNmtuNmtEvent
1068 (kEplNmtEventSwReset);
1069 #endif
1070 break;
1072 case kEplNmtCmdInvalidService:
1073 break;
1075 default:
1076 pParam_p->m_dwAbortCode =
1077 EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1078 Ret = kEplObdAccessViolation;
1079 break;
1082 break;
1085 default:
1086 break;
1089 //Exit:
1090 return Ret;
1093 //=========================================================================//
1094 // //
1095 // P R I V A T E F U N C T I O N S //
1096 // //
1097 //=========================================================================//
1099 //---------------------------------------------------------------------------
1101 // Function: EplApiProcessEvent
1103 // Description: processes events from event queue and forwards these to
1104 // the application's event callback function
1106 // Parameters: pEplEvent_p = pointer to event
1108 // Returns: tEplKernel = errorcode
1110 // State:
1112 //---------------------------------------------------------------------------
1114 static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p)
1116 tEplKernel Ret;
1117 tEplEventError *pEventError;
1118 tEplApiEventType EventType;
1120 Ret = kEplSuccessful;
1122 // process event
1123 switch (pEplEvent_p->m_EventType) {
1124 // error event
1125 case kEplEventTypeError:
1127 pEventError = (tEplEventError *) pEplEvent_p->m_pArg;
1128 switch (pEventError->m_EventSource) {
1129 // treat the errors from the following sources as critical
1130 case kEplEventSourceEventk:
1131 case kEplEventSourceEventu:
1132 case kEplEventSourceDllk:
1134 EventType = kEplApiEventCriticalError;
1135 // halt the stack by entering NMT state Off
1136 Ret =
1137 EplNmtuNmtEvent
1138 (kEplNmtEventCriticalError);
1139 break;
1142 // the other errors are just warnings
1143 default:
1145 EventType = kEplApiEventWarning;
1146 break;
1150 // call user callback
1151 Ret =
1152 EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType,
1153 (tEplApiEventArg
1155 pEventError,
1156 EplApiInstance_g.
1157 m_InitParam.
1158 m_pEventUserArg);
1159 // discard error from callback function, because this could generate an endless loop
1160 Ret = kEplSuccessful;
1161 break;
1164 // at present, there are no other events for this module
1165 default:
1166 break;
1169 return Ret;
1172 //---------------------------------------------------------------------------
1174 // Function: EplApiCbNmtStateChange
1176 // Description: callback function for NMT state changes
1178 // Parameters: NmtStateChange_p = NMT state change event
1180 // Returns: tEplKernel = error code
1183 // State:
1185 //---------------------------------------------------------------------------
1187 static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
1189 tEplKernel Ret = kEplSuccessful;
1190 u8 bNmtState;
1191 tEplApiEventArg EventArg;
1193 // save NMT state in OD
1194 bNmtState = (u8) NmtStateChange_p.m_NewNmtState;
1195 Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
1196 if (Ret != kEplSuccessful) {
1197 goto Exit;
1199 // do work which must be done in that state
1200 switch (NmtStateChange_p.m_NewNmtState) {
1201 // EPL stack is not running
1202 case kEplNmtGsOff:
1203 break;
1205 // first init of the hardware
1206 case kEplNmtGsInitialising:
1207 #if 0
1208 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
1209 // configure SDO via UDP (i.e. bind it to the EPL ethernet interface)
1210 Ret =
1211 EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress,
1212 EPL_C_SDO_EPL_PORT);
1213 if (Ret != kEplSuccessful) {
1214 goto Exit;
1216 #endif
1217 #endif
1219 break;
1221 // init of the manufacturer-specific profile area and the
1222 // standardised device profile area
1223 case kEplNmtGsResetApplication:
1225 // reset application part of OD
1226 Ret = EplObdAccessOdPart(kEplObdPartApp,
1227 kEplObdDirLoad);
1228 if (Ret != kEplSuccessful) {
1229 goto Exit;
1232 break;
1235 // init of the communication profile area
1236 case kEplNmtGsResetCommunication:
1238 // reset communication part of OD
1239 Ret = EplObdAccessOdPart(kEplObdPartGen,
1240 kEplObdDirLoad);
1242 if (Ret != kEplSuccessful) {
1243 goto Exit;
1245 // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory
1246 Ret = EplApiUpdateObd();
1247 if (Ret != kEplSuccessful) {
1248 goto Exit;
1251 break;
1254 // build the configuration with infos from OD
1255 case kEplNmtGsResetConfiguration:
1258 Ret = EplApiUpdateDllConfig(TRUE);
1259 if (Ret != kEplSuccessful) {
1260 goto Exit;
1263 break;
1266 //-----------------------------------------------------------
1267 // CN part of the state machine
1269 // node liste for EPL-Frames and check timeout
1270 case kEplNmtCsNotActive:
1272 // indicate completion of reset in NMT_ResetCmd_U8
1273 bNmtState = (u8) kEplNmtCmdInvalidService;
1274 Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
1275 if (Ret != kEplSuccessful) {
1276 goto Exit;
1279 break;
1282 // node process only async frames
1283 case kEplNmtCsPreOperational1:
1285 break;
1288 // node process isochronus and asynchronus frames
1289 case kEplNmtCsPreOperational2:
1291 break;
1294 // node should be configured und application is ready
1295 case kEplNmtCsReadyToOperate:
1297 break;
1300 // normal work state
1301 case kEplNmtCsOperational:
1303 break;
1306 // node stopped by MN
1307 // -> only process asynchronus frames
1308 case kEplNmtCsStopped:
1310 break;
1313 // no EPL cycle
1314 // -> normal ethernet communication
1315 case kEplNmtCsBasicEthernet:
1317 break;
1320 //-----------------------------------------------------------
1321 // MN part of the state machine
1323 // node listens for EPL-Frames and check timeout
1324 case kEplNmtMsNotActive:
1326 break;
1329 // node processes only async frames
1330 case kEplNmtMsPreOperational1:
1332 break;
1335 // node processes isochronous and asynchronous frames
1336 case kEplNmtMsPreOperational2:
1338 break;
1341 // node should be configured und application is ready
1342 case kEplNmtMsReadyToOperate:
1344 break;
1347 // normal work state
1348 case kEplNmtMsOperational:
1350 break;
1353 // no EPL cycle
1354 // -> normal ethernet communication
1355 case kEplNmtMsBasicEthernet:
1357 break;
1360 default:
1362 TRACE0
1363 ("EplApiCbNmtStateChange(): unhandled NMT state\n");
1367 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
1368 // forward event to Led module
1369 Ret = EplLeduCbNmtStateChange(NmtStateChange_p);
1370 if (Ret != kEplSuccessful) {
1371 goto Exit;
1373 #endif
1375 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1376 // forward event to NmtMn module
1377 Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p);
1378 if (Ret != kEplSuccessful) {
1379 goto Exit;
1381 #endif
1383 // call user callback
1384 EventArg.m_NmtStateChange = NmtStateChange_p;
1385 Ret =
1386 EplApiInstance_g.m_InitParam.
1387 m_pfnCbEvent(kEplApiEventNmtStateChange, &EventArg,
1388 EplApiInstance_g.m_InitParam.m_pEventUserArg);
1390 Exit:
1391 return Ret;
1394 //---------------------------------------------------------------------------
1396 // Function: EplApiUpdateDllConfig
1398 // Description: update configuration of DLL
1400 // Parameters: fUpdateIdentity_p = TRUE, if identity must be updated
1402 // Returns: tEplKernel = error code
1405 // State:
1407 //---------------------------------------------------------------------------
1409 static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
1411 tEplKernel Ret = kEplSuccessful;
1412 tEplDllConfigParam DllConfigParam;
1413 tEplDllIdentParam DllIdentParam;
1414 tEplObdSize ObdSize;
1415 u16 wTemp;
1416 u8 bTemp;
1418 // configure Dll
1419 EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
1420 DllConfigParam.m_uiNodeId = EplObdGetNodeId();
1422 // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
1423 ObdSize = 4;
1424 Ret =
1425 EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize);
1426 if (Ret != kEplSuccessful) {
1427 goto Exit;
1429 // 0x1F82: NMT_FeatureFlags_U32
1430 ObdSize = 4;
1431 Ret =
1432 EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags,
1433 &ObdSize);
1434 if (Ret != kEplSuccessful) {
1435 goto Exit;
1437 // d.k. There is no dependance between FeatureFlags and async-only CN
1438 DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly;
1440 // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
1441 ObdSize = 4;
1442 Ret =
1443 EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance,
1444 &ObdSize);
1445 if (Ret != kEplSuccessful) {
1446 goto Exit;
1448 // 0x1F98: NMT_CycleTiming_REC
1449 // 0x1F98.1: IsochrTxMaxPayload_U16
1450 ObdSize = 2;
1451 Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize);
1452 if (Ret != kEplSuccessful) {
1453 goto Exit;
1455 DllConfigParam.m_uiIsochrTxMaxPayload = wTemp;
1457 // 0x1F98.2: IsochrRxMaxPayload_U16
1458 ObdSize = 2;
1459 Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize);
1460 if (Ret != kEplSuccessful) {
1461 goto Exit;
1463 DllConfigParam.m_uiIsochrRxMaxPayload = wTemp;
1465 // 0x1F98.3: PResMaxLatency_U32
1466 ObdSize = 4;
1467 Ret =
1468 EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency,
1469 &ObdSize);
1470 if (Ret != kEplSuccessful) {
1471 goto Exit;
1473 // 0x1F98.4: PReqActPayloadLimit_U16
1474 ObdSize = 2;
1475 Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize);
1476 if (Ret != kEplSuccessful) {
1477 goto Exit;
1479 DllConfigParam.m_uiPreqActPayloadLimit = wTemp;
1481 // 0x1F98.5: PResActPayloadLimit_U16
1482 ObdSize = 2;
1483 Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize);
1484 if (Ret != kEplSuccessful) {
1485 goto Exit;
1487 DllConfigParam.m_uiPresActPayloadLimit = wTemp;
1489 // 0x1F98.6: ASndMaxLatency_U32
1490 ObdSize = 4;
1491 Ret =
1492 EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency,
1493 &ObdSize);
1494 if (Ret != kEplSuccessful) {
1495 goto Exit;
1497 // 0x1F98.7: MultiplCycleCnt_U8
1498 ObdSize = 1;
1499 Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize);
1500 if (Ret != kEplSuccessful) {
1501 goto Exit;
1503 DllConfigParam.m_uiMultiplCycleCnt = bTemp;
1505 // 0x1F98.8: AsyncMTU_U16
1506 ObdSize = 2;
1507 Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize);
1508 if (Ret != kEplSuccessful) {
1509 goto Exit;
1511 DllConfigParam.m_uiAsyncMtu = wTemp;
1513 // $$$ Prescaler
1515 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1516 // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
1517 ObdSize = 4;
1518 Ret =
1519 EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq,
1520 &ObdSize);
1521 if (Ret != kEplSuccessful) {
1522 goto Exit;
1524 // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional)
1525 ObdSize = 4;
1526 Ret =
1527 EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout,
1528 &ObdSize);
1529 /* if(Ret != kEplSuccessful)
1531 goto Exit;
1533 #endif
1535 DllConfigParam.m_uiSizeOfStruct = sizeof(DllConfigParam);
1536 Ret = EplDllkConfig(&DllConfigParam);
1537 if (Ret != kEplSuccessful) {
1538 goto Exit;
1541 if (fUpdateIdentity_p != FALSE) {
1542 // configure Identity
1543 EPL_MEMSET(&DllIdentParam, 0, sizeof(DllIdentParam));
1544 ObdSize = 4;
1545 Ret =
1546 EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType,
1547 &ObdSize);
1548 if (Ret != kEplSuccessful) {
1549 goto Exit;
1552 ObdSize = 4;
1553 Ret =
1554 EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId,
1555 &ObdSize);
1556 if (Ret != kEplSuccessful) {
1557 goto Exit;
1559 ObdSize = 4;
1560 Ret =
1561 EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode,
1562 &ObdSize);
1563 if (Ret != kEplSuccessful) {
1564 goto Exit;
1566 ObdSize = 4;
1567 Ret =
1568 EplObdReadEntry(0x1018, 3,
1569 &DllIdentParam.m_dwRevisionNumber,
1570 &ObdSize);
1571 if (Ret != kEplSuccessful) {
1572 goto Exit;
1574 ObdSize = 4;
1575 Ret =
1576 EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber,
1577 &ObdSize);
1578 if (Ret != kEplSuccessful) {
1579 goto Exit;
1582 DllIdentParam.m_dwIpAddress =
1583 EplApiInstance_g.m_InitParam.m_dwIpAddress;
1584 DllIdentParam.m_dwSubnetMask =
1585 EplApiInstance_g.m_InitParam.m_dwSubnetMask;
1586 EPL_MEMCPY(DllIdentParam.m_sHostname,
1587 EplApiInstance_g.m_InitParam.m_sHostname,
1588 sizeof(DllIdentParam.m_sHostname));
1590 ObdSize = 4;
1591 Ret =
1592 EplObdReadEntry(0x1020, 1,
1593 &DllIdentParam.m_dwVerifyConfigurationDate,
1594 &ObdSize);
1595 // ignore any error, because this object is optional
1597 ObdSize = 4;
1598 Ret =
1599 EplObdReadEntry(0x1020, 2,
1600 &DllIdentParam.m_dwVerifyConfigurationTime,
1601 &ObdSize);
1602 // ignore any error, because this object is optional
1604 // $$$ d.k.: fill rest of ident structure
1606 DllIdentParam.m_uiSizeOfStruct = sizeof(DllIdentParam);
1607 Ret = EplDllkSetIdentity(&DllIdentParam);
1608 if (Ret != kEplSuccessful) {
1609 goto Exit;
1613 Exit:
1614 return Ret;
1617 //---------------------------------------------------------------------------
1619 // Function: EplApiUpdateObd
1621 // Description: update OD from init param
1623 // Parameters: (none)
1625 // Returns: tEplKernel = error code
1628 // State:
1630 //---------------------------------------------------------------------------
1632 static tEplKernel EplApiUpdateObd(void)
1634 tEplKernel Ret = kEplSuccessful;
1635 u16 wTemp;
1636 u8 bTemp;
1638 // set node id in OD
1639 Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId, // node id
1640 kEplObdNodeIdHardware); // set by hardware
1641 if (Ret != kEplSuccessful) {
1642 goto Exit;
1645 if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1) {
1646 Ret =
1647 EplObdWriteEntry(0x1006, 0,
1648 &EplApiInstance_g.m_InitParam.m_dwCycleLen,
1650 /* if(Ret != kEplSuccessful)
1652 goto Exit;
1656 if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1) {
1657 Ret =
1658 EplObdWriteEntry(0x1C14, 0,
1659 &EplApiInstance_g.m_InitParam.
1660 m_dwLossOfFrameTolerance, 4);
1661 /* if(Ret != kEplSuccessful)
1663 goto Exit;
1664 } */
1666 // d.k. There is no dependance between FeatureFlags and async-only CN.
1667 if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1) {
1668 Ret =
1669 EplObdWriteEntry(0x1F82, 0,
1670 &EplApiInstance_g.m_InitParam.
1671 m_dwFeatureFlags, 4);
1672 /* if(Ret != kEplSuccessful)
1674 goto Exit;
1675 } */
1678 wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
1679 Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
1680 /* if(Ret != kEplSuccessful)
1682 goto Exit;
1685 wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
1686 Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
1687 /* if(Ret != kEplSuccessful)
1689 goto Exit;
1692 Ret =
1693 EplObdWriteEntry(0x1F98, 3,
1694 &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency,
1696 /* if(Ret != kEplSuccessful)
1698 goto Exit;
1701 if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
1702 EPL_C_DLL_ISOCHR_MAX_PAYL) {
1703 wTemp =
1704 (u16) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
1705 Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
1706 /* if(Ret != kEplSuccessful)
1708 goto Exit;
1712 if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
1713 EPL_C_DLL_ISOCHR_MAX_PAYL) {
1714 wTemp =
1715 (u16) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
1716 Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
1717 /* if(Ret != kEplSuccessful)
1719 goto Exit;
1723 Ret =
1724 EplObdWriteEntry(0x1F98, 6,
1725 &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency,
1727 /* if(Ret != kEplSuccessful)
1729 goto Exit;
1732 if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
1733 bTemp = (u8) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
1734 Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
1735 /* if(Ret != kEplSuccessful)
1737 goto Exit;
1741 if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
1742 EPL_C_DLL_MAX_ASYNC_MTU) {
1743 wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
1744 Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
1745 /* if(Ret != kEplSuccessful)
1747 goto Exit;
1751 if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
1752 wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiPrescaler;
1753 Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
1754 // ignore return code
1755 Ret = kEplSuccessful;
1757 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1758 if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1) {
1759 Ret =
1760 EplObdWriteEntry(0x1F8A, 1,
1761 &EplApiInstance_g.m_InitParam.
1762 m_dwWaitSocPreq, 4);
1763 /* if(Ret != kEplSuccessful)
1765 goto Exit;
1766 } */
1769 if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0)
1770 && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1)) {
1771 Ret =
1772 EplObdWriteEntry(0x1F8A, 2,
1773 &EplApiInstance_g.m_InitParam.
1774 m_dwAsyncSlotTimeout, 4);
1775 /* if(Ret != kEplSuccessful)
1777 goto Exit;
1778 } */
1780 #endif
1782 // configure Identity
1783 if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1) {
1784 Ret =
1785 EplObdWriteEntry(0x1000, 0,
1786 &EplApiInstance_g.m_InitParam.
1787 m_dwDeviceType, 4);
1788 /* if(Ret != kEplSuccessful)
1790 goto Exit;
1794 if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1) {
1795 Ret =
1796 EplObdWriteEntry(0x1018, 1,
1797 &EplApiInstance_g.m_InitParam.m_dwVendorId,
1799 /* if(Ret != kEplSuccessful)
1801 goto Exit;
1805 if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1) {
1806 Ret =
1807 EplObdWriteEntry(0x1018, 2,
1808 &EplApiInstance_g.m_InitParam.
1809 m_dwProductCode, 4);
1810 /* if(Ret != kEplSuccessful)
1812 goto Exit;
1816 if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1) {
1817 Ret =
1818 EplObdWriteEntry(0x1018, 3,
1819 &EplApiInstance_g.m_InitParam.
1820 m_dwRevisionNumber, 4);
1821 /* if(Ret != kEplSuccessful)
1823 goto Exit;
1827 if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1) {
1828 Ret =
1829 EplObdWriteEntry(0x1018, 4,
1830 &EplApiInstance_g.m_InitParam.
1831 m_dwSerialNumber, 4);
1832 /* if(Ret != kEplSuccessful)
1834 goto Exit;
1838 if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL) {
1839 // write Device Name (0x1008)
1840 Ret =
1841 EplObdWriteEntry(0x1008, 0,
1842 (void *)EplApiInstance_g.
1843 m_InitParam.m_pszDevName,
1844 (tEplObdSize) strlen(EplApiInstance_g.
1845 m_InitParam.
1846 m_pszDevName));
1847 /* if (Ret != kEplSuccessful)
1849 goto Exit;
1853 if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL) {
1854 // write Hardware version (0x1009)
1855 Ret =
1856 EplObdWriteEntry(0x1009, 0,
1857 (void *)EplApiInstance_g.
1858 m_InitParam.m_pszHwVersion,
1859 (tEplObdSize) strlen(EplApiInstance_g.
1860 m_InitParam.
1861 m_pszHwVersion));
1862 /* if (Ret != kEplSuccessful)
1864 goto Exit;
1868 if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL) {
1869 // write Software version (0x100A)
1870 Ret =
1871 EplObdWriteEntry(0x100A, 0,
1872 (void *)EplApiInstance_g.
1873 m_InitParam.m_pszSwVersion,
1874 (tEplObdSize) strlen(EplApiInstance_g.
1875 m_InitParam.
1876 m_pszSwVersion));
1877 /* if (Ret != kEplSuccessful)
1879 goto Exit;
1883 Exit:
1884 return Ret;
1887 //---------------------------------------------------------------------------
1889 // Function: EplApiCbSdoCon
1891 // Description: callback function for SDO transfers
1893 // Parameters: pSdoComFinished_p = SDO parameter
1895 // Returns: tEplKernel = error code
1898 // State:
1900 //---------------------------------------------------------------------------
1902 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1903 static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p)
1905 tEplKernel Ret;
1906 tEplApiEventArg EventArg;
1908 Ret = kEplSuccessful;
1910 // call user callback
1911 EventArg.m_Sdo = *pSdoComFinished_p;
1912 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo,
1913 &EventArg,
1914 EplApiInstance_g.
1915 m_InitParam.
1916 m_pEventUserArg);
1918 return Ret;
1921 #endif
1923 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1925 //---------------------------------------------------------------------------
1927 // Function: EplApiCbNodeEvent
1929 // Description: callback function for node events
1931 // Parameters: uiNodeId_p = node ID of the CN
1932 // NodeEvent_p = event from the specified CN
1933 // NmtState_p = current NMT state of the CN
1934 // wErrorCode_p = EPL error code if NodeEvent_p==kEplNmtNodeEventError
1935 // fMandatory_p = flag if CN is mandatory
1937 // Returns: tEplKernel = error code
1940 // State:
1942 //---------------------------------------------------------------------------
1944 static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
1945 tEplNmtNodeEvent NodeEvent_p,
1946 tEplNmtState NmtState_p,
1947 u16 wErrorCode_p, BOOL fMandatory_p)
1949 tEplKernel Ret;
1950 tEplApiEventArg EventArg;
1952 Ret = kEplSuccessful;
1954 // call user callback
1955 EventArg.m_Node.m_uiNodeId = uiNodeId_p;
1956 EventArg.m_Node.m_NodeEvent = NodeEvent_p;
1957 EventArg.m_Node.m_NmtState = NmtState_p;
1958 EventArg.m_Node.m_wErrorCode = wErrorCode_p;
1959 EventArg.m_Node.m_fMandatory = fMandatory_p;
1961 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode,
1962 &EventArg,
1963 EplApiInstance_g.
1964 m_InitParam.
1965 m_pEventUserArg);
1967 return Ret;
1971 //---------------------------------------------------------------------------
1973 // Function: EplApiCbBootEvent
1975 // Description: callback function for boot events
1977 // Parameters: BootEvent_p = event from the boot-up process
1978 // NmtState_p = current local NMT state
1979 // wErrorCode_p = EPL error code if BootEvent_p==kEplNmtBootEventError
1981 // Returns: tEplKernel = error code
1984 // State:
1986 //---------------------------------------------------------------------------
1988 static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
1989 tEplNmtState NmtState_p,
1990 u16 wErrorCode_p)
1992 tEplKernel Ret;
1993 tEplApiEventArg EventArg;
1995 Ret = kEplSuccessful;
1997 // call user callback
1998 EventArg.m_Boot.m_BootEvent = BootEvent_p;
1999 EventArg.m_Boot.m_NmtState = NmtState_p;
2000 EventArg.m_Boot.m_wErrorCode = wErrorCode_p;
2002 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot,
2003 &EventArg,
2004 EplApiInstance_g.
2005 m_InitParam.
2006 m_pEventUserArg);
2008 return Ret;
2012 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
2014 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
2016 //---------------------------------------------------------------------------
2018 // Function: EplApiCbLedStateChange
2020 // Description: callback function for LED change events.
2022 // Parameters: LedType_p = type of LED
2023 // fOn_p = state of LED
2025 // Returns: tEplKernel = errorcode
2027 // State:
2029 //---------------------------------------------------------------------------
2031 static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p)
2033 tEplKernel Ret;
2034 tEplApiEventArg EventArg;
2036 Ret = kEplSuccessful;
2038 // call user callback
2039 EventArg.m_Led.m_LedType = LedType_p;
2040 EventArg.m_Led.m_fOn = fOn_p;
2042 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed,
2043 &EventArg,
2044 EplApiInstance_g.
2045 m_InitParam.
2046 m_pEventUserArg);
2048 return Ret;
2052 #endif
2054 // EOF