1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for generic EPL API module
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplApiGeneric.c,v $
56 $Revision: 1.21 $ $Date: 2008/11/21 09:00:38 $
63 -------------------------------------------------------------------------
67 2006/09/05 d.k.: start of the implementation, version 1.00
69 ****************************************************************************/
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"
92 #include "SharedBuff.h"
94 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
95 #error "EPL API layer needs EPL module OBDK!"
98 /***************************************************************************/
101 /* G L O B A L D E F I N I T I O N S */
104 /***************************************************************************/
106 //---------------------------------------------------------------------------
108 //---------------------------------------------------------------------------
110 //---------------------------------------------------------------------------
112 //---------------------------------------------------------------------------
114 //---------------------------------------------------------------------------
115 // modul globale vars
116 //---------------------------------------------------------------------------
118 //---------------------------------------------------------------------------
119 // local function prototypes
120 //---------------------------------------------------------------------------
122 /***************************************************************************/
125 /* C L A S S EplApi */
128 /***************************************************************************/
133 /***************************************************************************/
135 //=========================================================================//
137 // P R I V A T E D E F I N I T I O N S //
139 //=========================================================================//
141 //---------------------------------------------------------------------------
143 //---------------------------------------------------------------------------
145 //---------------------------------------------------------------------------
147 //---------------------------------------------------------------------------
150 tEplApiInitParam m_InitParam;
154 //---------------------------------------------------------------------------
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);
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 WORD wErrorCode_p, BOOL fMandatory_p);
188 static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
189 tEplNmtState NmtState_p,
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);
198 // OD initialization function (implemented in Objdict.c)
199 tEplKernel EplObdInitRam(tEplObdInitParam MEM *pInitParam_p);
201 //=========================================================================//
203 // P U B L I C F U N C T I O N S //
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
224 //---------------------------------------------------------------------------
226 tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p)
228 tEplKernel Ret = kEplSuccessful;
229 tEplObdInitParam ObdInitParam;
230 tEplDllkInitParam DllkInitParam;
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;
247 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
250 // Ret = EplObdInitRam(&ObdInitParam);
251 // if (Ret != kEplSuccessful)
256 // initialize EplObd module
257 Ret = EplObdInit(&ObdInitParam);
258 if (Ret != kEplSuccessful) {
264 ShbError = ShbInit();
265 if (ShbError != kShbOk) {
266 Ret = kEplNoResource;
271 // initialize EplEventk module
272 Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync);
273 if (Ret != kEplSuccessful) {
276 // initialize EplEventu module
277 Ret = EplEventuInit(EplApiProcessEvent);
278 if (Ret != kEplSuccessful) {
281 // init EplTimerk module
282 Ret = EplTimerkInit();
283 if (Ret != kEplSuccessful) {
286 // initialize EplNmtk module before DLL
287 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
289 if (Ret != kEplSuccessful) {
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) {
302 // initialize EplErrorHandlerk module
303 Ret = EplErrorHandlerkInit();
304 if (Ret != kEplSuccessful) {
307 // initialize EplDllkCal module
308 Ret = EplDllkCalAddInstance();
309 if (Ret != kEplSuccessful) {
314 // initialize EplDlluCal module
315 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
316 Ret = EplDlluCalAddInstance();
317 if (Ret != kEplSuccessful) {
322 // initialize EplPdok module
323 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
324 Ret = EplPdokAddInstance();
325 if (Ret != kEplSuccessful) {
329 Ret = EplPdokCalAddInstance();
330 if (Ret != kEplSuccessful) {
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) {
343 // initialize EplNmtu module
344 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
346 if (Ret != kEplSuccessful) {
349 // register NMT event callback function
350 Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange);
351 if (Ret != kEplSuccessful) {
356 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
357 // initialize EplNmtMnu module
358 Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent);
359 if (Ret != kEplSuccessful) {
362 // initialize EplIdentu module
363 Ret = EplIdentuInit();
364 if (Ret != kEplSuccessful) {
367 // initialize EplStatusu module
368 Ret = EplStatusuInit();
369 if (Ret != kEplSuccessful) {
374 // initialize EplLedu module
375 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
376 Ret = EplLeduInit(EplApiCbLedStateChange);
377 if (Ret != kEplSuccessful) {
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) {
392 // the application must start NMT state machine
393 // via EplApiExecNmtCommand(kEplNmtEventSwReset)
394 // and thereby the whole EPL stack
400 //---------------------------------------------------------------------------
402 // Function: EplApiShutdown()
404 // Description: deletes an instance of EPL stack
406 // Parameters: (none)
408 // Returns: tEplKernel = error code
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
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);
434 // deinitialize EplLedu module
435 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
436 Ret = EplLeduDelInstance();
437 // PRINTF1("EplLeduDelInstance(): 0x%X\n", Ret);
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);
454 // deinitialize EplNmtCnu module
455 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
456 Ret = EplNmtCnuDelInstance();
457 // PRINTF1("EplNmtCnuDelInstance(): 0x%X\n", Ret);
460 // deinitialize EplNmtu module
461 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
462 Ret = EplNmtuDelInstance();
463 // PRINTF1("EplNmtuDelInstance(): 0x%X\n", Ret);
466 // deinitialize EplDlluCal module
467 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
468 Ret = EplDlluCalDelInstance();
469 // PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret);
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);
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);
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);
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
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);
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
551 //----------------------------------------------------------------------------
553 tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
555 unsigned int *puiVarEntries_p,
556 tEplObdSize *pEntrySize_p,
557 unsigned int uiFirstSubindex_p)
562 unsigned int uiSubindex;
563 tEplVarParam VarParam;
564 tEplObdSize EntrySize;
565 tEplObdSize UsedSize;
567 tEplKernel RetCode = kEplSuccessful;
570 || (puiVarEntries_p == NULL)
571 || (*puiVarEntries_p == 0)
572 || (pEntrySize_p == NULL)) {
573 RetCode = kEplApiInvalidParam;
577 pbData = (BYTE MEM *) pVar_p;
578 bVarEntries = (BYTE) * puiVarEntries_p;
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,
591 (void GENERIC *)&bIndexEntries,
594 if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
595 // Object doesn't exist or invalid entry number
596 RetCode = kEplObdIndexNotExist;
599 } else { // user wants to link a variable to subindex 0x00
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 = (BYTE) (bVarEntries + uiFirstSubindex_p - 1);
613 for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
615 // if passed entry size is 0, then get size from OD
616 if (*pEntrySize_p == 0x00) {
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;
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;
638 RetCode = EplObdDefineVar(&VarParam);
639 if (RetCode != kEplSuccessful) {
644 // set number of mapped entries and entry size
645 *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1);
646 *pEntrySize_p = UsedSize;
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,
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;
693 if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed
696 ObdSize = (tEplObdSize) * puiSize_p;
698 EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p,
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;
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)) {
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) {
731 Ret = kEplApiTaskDeferred;
734 Ret = kEplApiInvalidParam;
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,
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;
780 if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed
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;
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)) {
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) {
824 Ret = kEplApiTaskDeferred;
827 Ret = kEplApiInvalidParam;
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);
860 Ret = kEplApiInvalidParam;
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;
888 ObdSize = (tEplObdSize) * puiSize_p;
889 Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize);
890 *puiSize_p = (unsigned int)ObdSize;
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,
913 unsigned int uiSize_p)
915 tEplKernel Ret = kEplSuccessful;
918 EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p,
919 (tEplObdSize) uiSize_p);
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);
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
963 //---------------------------------------------------------------------------
965 tEplKernel EplApiCbObdAccess(tEplObdCbParam MEM *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,
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);
996 case 0x1020: // CFM_VerifyConfiguration_REC.ConfId_U32 != 0
998 if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
999 && (pParam_p->m_uiSubIndex == 3)
1000 && (*((DWORD *) pParam_p->m_pArg) != 0)) {
1001 DWORD dwVerifyConfInvalid = 0;
1002 // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
1004 EplObdWriteEntry(0x1020, 4,
1005 &dwVerifyConfInvalid, 4);
1006 // ignore any error because this objekt is optional
1007 Ret = kEplSuccessful;
1012 case 0x1F9E: // NMT_ResetCmd_U8
1014 if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
1017 bNmtCommand = *((BYTE *) 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
1029 pParam_p->m_dwAbortCode =
1030 EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1031 Ret = kEplObdAccessViolation;
1034 } else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
1037 bNmtCommand = *((BYTE *) pParam_p->m_pArg);
1038 // check value range
1039 switch ((tEplNmtCommand) bNmtCommand) {
1040 case kEplNmtCmdResetNode:
1041 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1044 (kEplNmtEventResetNode);
1048 case kEplNmtCmdResetCommunication:
1049 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1052 (kEplNmtEventResetCom);
1056 case kEplNmtCmdResetConfiguration:
1057 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1060 (kEplNmtEventResetConfig);
1064 case kEplNmtCmdSwReset:
1065 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1068 (kEplNmtEventSwReset);
1072 case kEplNmtCmdInvalidService:
1076 pParam_p->m_dwAbortCode =
1077 EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1078 Ret = kEplObdAccessViolation;
1093 //=========================================================================//
1095 // P R I V A T E F U N C T I O N S //
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
1112 //---------------------------------------------------------------------------
1114 static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p)
1117 tEplEventError *pEventError;
1118 tEplApiEventType EventType;
1120 Ret = kEplSuccessful;
1123 switch (pEplEvent_p->m_EventType) {
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
1138 (kEplNmtEventCriticalError);
1142 // the other errors are just warnings
1145 EventType = kEplApiEventWarning;
1150 // call user callback
1152 EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType,
1159 // discard error from callback function, because this could generate an endless loop
1160 Ret = kEplSuccessful;
1164 // at present, there are no other events for this module
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
1185 //---------------------------------------------------------------------------
1187 static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
1189 tEplKernel Ret = kEplSuccessful;
1191 tEplApiEventArg EventArg;
1193 // save NMT state in OD
1194 bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState;
1195 Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
1196 if (Ret != kEplSuccessful) {
1199 // do work which must be done in that state
1200 switch (NmtStateChange_p.m_NewNmtState) {
1201 // EPL stack is not running
1205 // first init of the hardware
1206 case kEplNmtGsInitialising:
1208 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
1209 // configure SDO via UDP (i.e. bind it to the EPL ethernet interface)
1211 EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress,
1212 EPL_C_SDO_EPL_PORT);
1213 if (Ret != kEplSuccessful) {
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,
1228 if (Ret != kEplSuccessful) {
1235 // init of the communication profile area
1236 case kEplNmtGsResetCommunication:
1238 // reset communication part of OD
1239 Ret = EplObdAccessOdPart(kEplObdPartGen,
1242 if (Ret != kEplSuccessful) {
1245 // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory
1246 Ret = EplApiUpdateObd();
1247 if (Ret != kEplSuccessful) {
1254 // build the configuration with infos from OD
1255 case kEplNmtGsResetConfiguration:
1258 Ret = EplApiUpdateDllConfig(TRUE);
1259 if (Ret != kEplSuccessful) {
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 = (BYTE) kEplNmtCmdInvalidService;
1274 Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
1275 if (Ret != kEplSuccessful) {
1282 // node process only async frames
1283 case kEplNmtCsPreOperational1:
1288 // node process isochronus and asynchronus frames
1289 case kEplNmtCsPreOperational2:
1294 // node should be configured und application is ready
1295 case kEplNmtCsReadyToOperate:
1300 // normal work state
1301 case kEplNmtCsOperational:
1306 // node stopped by MN
1307 // -> only process asynchronus frames
1308 case kEplNmtCsStopped:
1314 // -> normal ethernet communication
1315 case kEplNmtCsBasicEthernet:
1320 //-----------------------------------------------------------
1321 // MN part of the state machine
1323 // node listens for EPL-Frames and check timeout
1324 case kEplNmtMsNotActive:
1329 // node processes only async frames
1330 case kEplNmtMsPreOperational1:
1335 // node processes isochronous and asynchronous frames
1336 case kEplNmtMsPreOperational2:
1341 // node should be configured und application is ready
1342 case kEplNmtMsReadyToOperate:
1347 // normal work state
1348 case kEplNmtMsOperational:
1354 // -> normal ethernet communication
1355 case kEplNmtMsBasicEthernet:
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) {
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) {
1383 // call user callback
1384 EventArg.m_NmtStateChange = NmtStateChange_p;
1386 EplApiInstance_g.m_InitParam.
1387 m_pfnCbEvent(kEplApiEventNmtStateChange, &EventArg,
1388 EplApiInstance_g.m_InitParam.m_pEventUserArg);
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
1407 //---------------------------------------------------------------------------
1409 static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
1411 tEplKernel Ret = kEplSuccessful;
1412 tEplDllConfigParam DllConfigParam;
1413 tEplDllIdentParam DllIdentParam;
1414 tEplObdSize ObdSize;
1419 EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
1420 DllConfigParam.m_uiNodeId = EplObdGetNodeId();
1422 // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
1425 EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize);
1426 if (Ret != kEplSuccessful) {
1429 // 0x1F82: NMT_FeatureFlags_U32
1432 EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags,
1434 if (Ret != kEplSuccessful) {
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]
1443 EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance,
1445 if (Ret != kEplSuccessful) {
1448 // 0x1F98: NMT_CycleTiming_REC
1449 // 0x1F98.1: IsochrTxMaxPayload_U16
1451 Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize);
1452 if (Ret != kEplSuccessful) {
1455 DllConfigParam.m_uiIsochrTxMaxPayload = wTemp;
1457 // 0x1F98.2: IsochrRxMaxPayload_U16
1459 Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize);
1460 if (Ret != kEplSuccessful) {
1463 DllConfigParam.m_uiIsochrRxMaxPayload = wTemp;
1465 // 0x1F98.3: PResMaxLatency_U32
1468 EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency,
1470 if (Ret != kEplSuccessful) {
1473 // 0x1F98.4: PReqActPayloadLimit_U16
1475 Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize);
1476 if (Ret != kEplSuccessful) {
1479 DllConfigParam.m_uiPreqActPayloadLimit = wTemp;
1481 // 0x1F98.5: PResActPayloadLimit_U16
1483 Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize);
1484 if (Ret != kEplSuccessful) {
1487 DllConfigParam.m_uiPresActPayloadLimit = wTemp;
1489 // 0x1F98.6: ASndMaxLatency_U32
1492 EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency,
1494 if (Ret != kEplSuccessful) {
1497 // 0x1F98.7: MultiplCycleCnt_U8
1499 Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize);
1500 if (Ret != kEplSuccessful) {
1503 DllConfigParam.m_uiMultiplCycleCnt = bTemp;
1505 // 0x1F98.8: AsyncMTU_U16
1507 Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize);
1508 if (Ret != kEplSuccessful) {
1511 DllConfigParam.m_uiAsyncMtu = wTemp;
1515 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1516 // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
1519 EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq,
1521 if (Ret != kEplSuccessful) {
1524 // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional)
1527 EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout,
1529 /* if(Ret != kEplSuccessful)
1535 DllConfigParam.m_uiSizeOfStruct = sizeof(DllConfigParam);
1536 Ret = EplDllkConfig(&DllConfigParam);
1537 if (Ret != kEplSuccessful) {
1541 if (fUpdateIdentity_p != FALSE) {
1542 // configure Identity
1543 EPL_MEMSET(&DllIdentParam, 0, sizeof(DllIdentParam));
1546 EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType,
1548 if (Ret != kEplSuccessful) {
1554 EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId,
1556 if (Ret != kEplSuccessful) {
1561 EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode,
1563 if (Ret != kEplSuccessful) {
1568 EplObdReadEntry(0x1018, 3,
1569 &DllIdentParam.m_dwRevisionNumber,
1571 if (Ret != kEplSuccessful) {
1576 EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber,
1578 if (Ret != kEplSuccessful) {
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));
1592 EplObdReadEntry(0x1020, 1,
1593 &DllIdentParam.m_dwVerifyConfigurationDate,
1595 // ignore any error, because this object is optional
1599 EplObdReadEntry(0x1020, 2,
1600 &DllIdentParam.m_dwVerifyConfigurationTime,
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) {
1617 //---------------------------------------------------------------------------
1619 // Function: EplApiUpdateObd
1621 // Description: update OD from init param
1623 // Parameters: (none)
1625 // Returns: tEplKernel = error code
1630 //---------------------------------------------------------------------------
1632 static tEplKernel EplApiUpdateObd(void)
1634 tEplKernel Ret = kEplSuccessful;
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) {
1645 if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1) {
1647 EplObdWriteEntry(0x1006, 0,
1648 &EplApiInstance_g.m_InitParam.m_dwCycleLen,
1650 /* if(Ret != kEplSuccessful)
1656 if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1) {
1658 EplObdWriteEntry(0x1C14, 0,
1659 &EplApiInstance_g.m_InitParam.
1660 m_dwLossOfFrameTolerance, 4);
1661 /* if(Ret != kEplSuccessful)
1666 // d.k. There is no dependance between FeatureFlags and async-only CN.
1667 if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1) {
1669 EplObdWriteEntry(0x1F82, 0,
1670 &EplApiInstance_g.m_InitParam.
1671 m_dwFeatureFlags, 4);
1672 /* if(Ret != kEplSuccessful)
1678 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
1679 Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
1680 /* if(Ret != kEplSuccessful)
1685 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
1686 Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
1687 /* if(Ret != kEplSuccessful)
1693 EplObdWriteEntry(0x1F98, 3,
1694 &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency,
1696 /* if(Ret != kEplSuccessful)
1701 if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
1702 EPL_C_DLL_ISOCHR_MAX_PAYL) {
1704 (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
1705 Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
1706 /* if(Ret != kEplSuccessful)
1712 if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
1713 EPL_C_DLL_ISOCHR_MAX_PAYL) {
1715 (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
1716 Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
1717 /* if(Ret != kEplSuccessful)
1724 EplObdWriteEntry(0x1F98, 6,
1725 &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency,
1727 /* if(Ret != kEplSuccessful)
1732 if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
1733 bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
1734 Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
1735 /* if(Ret != kEplSuccessful)
1741 if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
1742 EPL_C_DLL_MAX_ASYNC_MTU) {
1743 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
1744 Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
1745 /* if(Ret != kEplSuccessful)
1751 if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
1752 wTemp = (WORD) 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) {
1760 EplObdWriteEntry(0x1F8A, 1,
1761 &EplApiInstance_g.m_InitParam.
1762 m_dwWaitSocPreq, 4);
1763 /* if(Ret != kEplSuccessful)
1769 if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0)
1770 && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1)) {
1772 EplObdWriteEntry(0x1F8A, 2,
1773 &EplApiInstance_g.m_InitParam.
1774 m_dwAsyncSlotTimeout, 4);
1775 /* if(Ret != kEplSuccessful)
1782 // configure Identity
1783 if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1) {
1785 EplObdWriteEntry(0x1000, 0,
1786 &EplApiInstance_g.m_InitParam.
1788 /* if(Ret != kEplSuccessful)
1794 if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1) {
1796 EplObdWriteEntry(0x1018, 1,
1797 &EplApiInstance_g.m_InitParam.m_dwVendorId,
1799 /* if(Ret != kEplSuccessful)
1805 if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1) {
1807 EplObdWriteEntry(0x1018, 2,
1808 &EplApiInstance_g.m_InitParam.
1809 m_dwProductCode, 4);
1810 /* if(Ret != kEplSuccessful)
1816 if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1) {
1818 EplObdWriteEntry(0x1018, 3,
1819 &EplApiInstance_g.m_InitParam.
1820 m_dwRevisionNumber, 4);
1821 /* if(Ret != kEplSuccessful)
1827 if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1) {
1829 EplObdWriteEntry(0x1018, 4,
1830 &EplApiInstance_g.m_InitParam.
1831 m_dwSerialNumber, 4);
1832 /* if(Ret != kEplSuccessful)
1838 if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL) {
1839 // write Device Name (0x1008)
1841 EplObdWriteEntry(0x1008, 0,
1842 (void GENERIC *)EplApiInstance_g.
1843 m_InitParam.m_pszDevName,
1844 (tEplObdSize) strlen(EplApiInstance_g.
1847 /* if (Ret != kEplSuccessful)
1853 if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL) {
1854 // write Hardware version (0x1009)
1856 EplObdWriteEntry(0x1009, 0,
1857 (void GENERIC *)EplApiInstance_g.
1858 m_InitParam.m_pszHwVersion,
1859 (tEplObdSize) strlen(EplApiInstance_g.
1862 /* if (Ret != kEplSuccessful)
1868 if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL) {
1869 // write Software version (0x100A)
1871 EplObdWriteEntry(0x100A, 0,
1872 (void GENERIC *)EplApiInstance_g.
1873 m_InitParam.m_pszSwVersion,
1874 (tEplObdSize) strlen(EplApiInstance_g.
1877 /* if (Ret != kEplSuccessful)
1887 //---------------------------------------------------------------------------
1889 // Function: EplApiCbSdoCon
1891 // Description: callback function for SDO transfers
1893 // Parameters: pSdoComFinished_p = SDO parameter
1895 // Returns: tEplKernel = error code
1900 //---------------------------------------------------------------------------
1902 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1903 static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p)
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,
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
1942 //---------------------------------------------------------------------------
1944 static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
1945 tEplNmtNodeEvent NodeEvent_p,
1946 tEplNmtState NmtState_p,
1947 WORD wErrorCode_p, BOOL fMandatory_p)
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,
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
1986 //---------------------------------------------------------------------------
1988 static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
1989 tEplNmtState NmtState_p,
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,
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
2029 //---------------------------------------------------------------------------
2031 static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p)
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,