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"
95 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
96 #error "EPL API layer needs EPL module OBDK!"
100 /***************************************************************************/
103 /* G L O B A L D E F I N I T I O N S */
106 /***************************************************************************/
108 //---------------------------------------------------------------------------
110 //---------------------------------------------------------------------------
112 //---------------------------------------------------------------------------
114 //---------------------------------------------------------------------------
116 //---------------------------------------------------------------------------
117 // modul globale vars
118 //---------------------------------------------------------------------------
120 //---------------------------------------------------------------------------
121 // local function prototypes
122 //---------------------------------------------------------------------------
125 /***************************************************************************/
128 /* C L A S S EplApi */
131 /***************************************************************************/
136 /***************************************************************************/
139 //=========================================================================//
141 // P R I V A T E D E F I N I T I O N S //
143 //=========================================================================//
145 //---------------------------------------------------------------------------
147 //---------------------------------------------------------------------------
149 //---------------------------------------------------------------------------
151 //---------------------------------------------------------------------------
155 tEplApiInitParam m_InitParam;
159 //---------------------------------------------------------------------------
161 //---------------------------------------------------------------------------
163 static tEplApiInstance EplApiInstance_g;
166 //---------------------------------------------------------------------------
167 // local function prototypes
168 //---------------------------------------------------------------------------
170 // NMT state change event callback function
171 static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
173 // update DLL configuration from OD
174 static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
176 // update OD from init param
177 static tEplKernel PUBLIC EplApiUpdateObd(void);
179 // process events from user event queue
180 static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent* pEplEvent_p);
182 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
183 // callback function of SDO module
184 static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished* pSdoComFinished_p);
187 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
188 // callback functions of NmtMnu module
189 static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
190 tEplNmtNodeEvent NodeEvent_p,
191 tEplNmtState NmtState_p,
195 static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
196 tEplNmtState NmtState_p,
200 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
201 // callback function of Ledu module
202 static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
206 // OD initialization function (implemented in Objdict.c)
207 tEplKernel PUBLIC EplObdInitRam (tEplObdInitParam MEM* pInitParam_p);
210 //=========================================================================//
212 // P U B L I C F U N C T I O N S //
214 //=========================================================================//
216 //---------------------------------------------------------------------------
218 // Function: EplApiInitialize()
220 // Description: add and initialize new instance of EPL stack.
221 // After return from this function the application must start
222 // the NMT state machine via
223 // EplApiExecNmtCommand(kEplNmtEventSwReset)
224 // and thereby the whole EPL stack :-)
226 // Parameters: pInitParam_p = initialisation parameters
228 // Returns: tEplKernel = error code
233 //---------------------------------------------------------------------------
235 tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
237 tEplKernel Ret = kEplSuccessful;
238 tEplObdInitParam ObdInitParam;
239 tEplDllkInitParam DllkInitParam;
244 // reset instance structure
245 EPL_MEMSET(&EplApiInstance_g, 0, sizeof (EplApiInstance_g));
247 EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p, min(sizeof (tEplApiInitParam), pInitParam_p->m_uiSizeOfStruct));
249 // check event callback function pointer
250 if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL)
251 { // application must always have an event callback function
252 Ret = kEplApiInvalidParam;
256 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
259 // Ret = EplObdInitRam(&ObdInitParam);
260 // if (Ret != kEplSuccessful)
265 // initialize EplObd module
266 Ret = EplObdInit(&ObdInitParam);
267 if (Ret != kEplSuccessful)
274 ShbError = ShbInit();
275 if (ShbError != kShbOk)
277 Ret = kEplNoResource;
282 // initialize EplEventk module
283 Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync);
284 if (Ret != kEplSuccessful)
289 // initialize EplEventu module
290 Ret = EplEventuInit(EplApiProcessEvent);
291 if (Ret != kEplSuccessful)
296 // init EplTimerk module
297 Ret = EplTimerkInit();
298 if (Ret != kEplSuccessful)
303 // initialize EplNmtk module before DLL
304 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
306 if (Ret != kEplSuccessful)
312 // initialize EplDllk module
313 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
314 EPL_MEMCPY(DllkInitParam.m_be_abSrcMac, EplApiInstance_g.m_InitParam.m_abMacAddress, 6);
315 Ret = EplDllkAddInstance(&DllkInitParam);
316 if (Ret != kEplSuccessful)
321 // initialize EplErrorHandlerk module
322 Ret = EplErrorHandlerkInit();
323 if (Ret != kEplSuccessful)
328 // initialize EplDllkCal module
329 Ret = EplDllkCalAddInstance();
330 if (Ret != kEplSuccessful)
336 // initialize EplDlluCal module
337 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
338 Ret = EplDlluCalAddInstance();
339 if (Ret != kEplSuccessful)
346 // initialize EplPdok module
347 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
348 Ret = EplPdokAddInstance();
349 if (Ret != kEplSuccessful)
354 Ret = EplPdokCalAddInstance();
355 if (Ret != kEplSuccessful)
362 // initialize EplNmtCnu module
363 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
364 Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId);
365 if (Ret != kEplSuccessful)
371 // initialize EplNmtu module
372 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
374 if (Ret != kEplSuccessful)
379 // register NMT event callback function
380 Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange);
381 if (Ret != kEplSuccessful)
387 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
388 // initialize EplNmtMnu module
389 Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent);
390 if (Ret != kEplSuccessful)
395 // initialize EplIdentu module
396 Ret = EplIdentuInit();
397 if (Ret != kEplSuccessful)
402 // initialize EplStatusu module
403 Ret = EplStatusuInit();
404 if (Ret != kEplSuccessful)
410 // initialize EplLedu module
411 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
412 Ret = EplLeduInit(EplApiCbLedStateChange);
413 if (Ret != kEplSuccessful)
420 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
421 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
422 // init sdo command layer
423 Ret = EplSdoComInit();
424 if (Ret != kEplSuccessful)
430 // the application must start NMT state machine
431 // via EplApiExecNmtCommand(kEplNmtEventSwReset)
432 // and thereby the whole EPL stack
438 //---------------------------------------------------------------------------
440 // Function: EplApiShutdown()
442 // Description: deletes an instance of EPL stack
444 // Parameters: (none)
446 // Returns: tEplKernel = error code
451 //---------------------------------------------------------------------------
453 tEplKernel PUBLIC EplApiShutdown(void)
455 tEplKernel Ret = kEplSuccessful;
457 // $$$ d.k.: check if NMT state is NMT_GS_OFF
459 // $$$ d.k.: maybe delete event queues at first, but this implies that
460 // no other module must not use the event queues for communication
463 // delete instance for all modules
465 // deinitialize EplSdoCom module
466 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
467 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
468 Ret = EplSdoComDelInstance();
469 // PRINTF1("EplSdoComDelInstance(): 0x%X\n", Ret);
472 // deinitialize EplLedu module
473 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
474 Ret = EplLeduDelInstance();
475 // PRINTF1("EplLeduDelInstance(): 0x%X\n", Ret);
478 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
479 // deinitialize EplNmtMnu module
480 Ret = EplNmtMnuDelInstance();
481 // PRINTF1("EplNmtMnuDelInstance(): 0x%X\n", Ret);
483 // deinitialize EplIdentu module
484 Ret = EplIdentuDelInstance();
485 // PRINTF1("EplIdentuDelInstance(): 0x%X\n", Ret);
487 // deinitialize EplStatusu module
488 Ret = EplStatusuDelInstance();
489 // PRINTF1("EplStatusuDelInstance(): 0x%X\n", Ret);
492 // deinitialize EplNmtCnu module
493 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
494 Ret = EplNmtCnuDelInstance();
495 // PRINTF1("EplNmtCnuDelInstance(): 0x%X\n", Ret);
498 // deinitialize EplNmtu module
499 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
500 Ret = EplNmtuDelInstance();
501 // PRINTF1("EplNmtuDelInstance(): 0x%X\n", Ret);
504 // deinitialize EplDlluCal module
505 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
506 Ret = EplDlluCalDelInstance();
507 // PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret);
511 // deinitialize EplEventu module
512 Ret = EplEventuDelInstance();
513 // PRINTF1("EplEventuDelInstance(): 0x%X\n", Ret);
515 // deinitialize EplNmtk module
516 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
517 Ret = EplNmtkDelInstance();
518 // PRINTF1("EplNmtkDelInstance(): 0x%X\n", Ret);
521 // deinitialize EplDllk module
522 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
523 Ret = EplDllkDelInstance();
524 // PRINTF1("EplDllkDelInstance(): 0x%X\n", Ret);
526 // deinitialize EplDllkCal module
527 Ret = EplDllkCalDelInstance();
528 // PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret);
531 // deinitialize EplEventk module
532 Ret = EplEventkDelInstance();
533 // PRINTF1("EplEventkDelInstance(): 0x%X\n", Ret);
535 // deinitialize EplTimerk module
536 Ret = EplTimerkDelInstance();
537 // PRINTF1("EplTimerkDelInstance(): 0x%X\n", Ret);
547 //----------------------------------------------------------------------------
548 // Function: EplApiExecNmtCommand()
550 // Description: executes a NMT command, i.e. post the NMT command/event to the
551 // NMTk module. NMT commands which are not appropriate in the current
552 // NMT state are silently ignored. Please keep in mind that the
553 // NMT state may change until the NMT command is actually executed.
555 // Parameters: NmtEvent_p = NMT command/event
557 // Returns: tEplKernel = error code
560 //----------------------------------------------------------------------------
562 tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
564 tEplKernel Ret = kEplSuccessful;
566 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
567 Ret = EplNmtuNmtEvent(NmtEvent_p);
574 //----------------------------------------------------------------------------
575 // Function: EplApiLinkObject()
577 // Description: Function maps array of application variables onto specified object in OD
579 // Parameters: uiObjIndex_p = Function maps variables for this object index
580 // pVar_p = Pointer to data memory area for the specified object
581 // puiVarEntries_p = IN: pointer to number of entries to map
582 // OUT: pointer to number of actually used entries
583 // pEntrySize_p = IN: pointer to size of one entry;
584 // if size is zero, the actual size will be read from OD
585 // OUT: pointer to entire size of all entries mapped
586 // uiFirstSubindex_p = This is the first subindex to be mapped.
588 // Returns: tEplKernel = error code
591 //----------------------------------------------------------------------------
593 tEplKernel PUBLIC EplApiLinkObject( unsigned int uiObjIndex_p,
595 unsigned int* puiVarEntries_p,
596 tEplObdSize* pEntrySize_p,
597 unsigned int uiFirstSubindex_p)
602 unsigned int uiSubindex;
603 tEplVarParam VarParam;
604 tEplObdSize EntrySize;
605 tEplObdSize UsedSize;
607 tEplKernel RetCode = kEplSuccessful;
610 || (puiVarEntries_p == NULL)
611 || (*puiVarEntries_p == 0)
612 || (pEntrySize_p == NULL))
614 RetCode = kEplApiInvalidParam;
618 pbData = (BYTE MEM*) pVar_p;
619 bVarEntries = (BYTE) *puiVarEntries_p;
622 // init VarParam structure with default values
623 VarParam.m_uiIndex = uiObjIndex_p;
624 VarParam.m_ValidFlag = kVarValidAll;
626 if (uiFirstSubindex_p != 0)
627 { // check if object exists by reading subindex 0x00,
628 // because user wants to link a variable to a subindex unequal 0x00
629 // read number of entries
630 EntrySize = (tEplObdSize) sizeof(bIndexEntries);
631 RetCode = EplObdReadEntry (
634 (void GENERIC*) &bIndexEntries,
637 if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00) )
639 // Object doesn't exist or invalid entry number
640 RetCode = kEplObdIndexNotExist;
645 { // user wants to link a variable to subindex 0x00
650 // Correct number of entries if number read from OD is greater
651 // than the specified number.
652 // This is done, so that we do not set more entries than subindexes the
653 // object actually has.
654 if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
655 (bVarEntries != 0x00) )
657 bIndexEntries = (BYTE) (bVarEntries + uiFirstSubindex_p - 1);
661 for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries; uiSubindex++)
663 // if passed entry size is 0, then get size from OD
664 if (*pEntrySize_p == 0x00)
667 EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex);
669 if (EntrySize == 0x00)
671 // invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty)
672 RetCode = kEplObdSubindexNotExist;
677 { // use passed entry size
678 EntrySize = *pEntrySize_p;
681 VarParam.m_uiSubindex = uiSubindex;
683 // set pointer to user var
684 VarParam.m_Size = EntrySize;
685 VarParam.m_pData = pbData;
687 UsedSize += EntrySize;
690 RetCode = EplObdDefineVar(&VarParam);
691 if (RetCode != kEplSuccessful)
697 // set number of mapped entries and entry size
698 *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1);
699 *pEntrySize_p = UsedSize;
709 // ----------------------------------------------------------------------------
711 // Function: EplApiReadObject()
713 // Description: reads the specified entry from the OD of the specified node.
714 // If this node is a remote node, it performs a SDO transfer, which
715 // means this function returns kEplApiTaskDeferred and the application
716 // is informed via the event callback function when the task is completed.
718 // Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
719 // uiNodeId_p = IN: node ID (0 = itself)
720 // uiIndex_p = IN: index of object in OD
721 // uiSubindex_p = IN: sub-index of object in OD
722 // pDstData_le_p = OUT: pointer to data in little endian
723 // puiSize_p = INOUT: pointer to size of data
724 // SdoType_p = IN: type of SDO transfer
725 // pUserArg_p = IN: user-definable argument pointer,
726 // which will be passed to the event callback function
728 // Return: tEplKernel = error code
730 // ----------------------------------------------------------------------------
732 tEplKernel PUBLIC EplApiReadObject(
733 tEplSdoComConHdl* pSdoComConHdl_p,
734 unsigned int uiNodeId_p,
735 unsigned int uiIndex_p,
736 unsigned int uiSubindex_p,
738 unsigned int* puiSize_p,
739 tEplSdoType SdoType_p,
742 tEplKernel Ret = kEplSuccessful;
744 if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL) || (*puiSize_p == 0))
746 Ret = kEplApiInvalidParam;
751 || uiNodeId_p == EplObdGetNodeId())
752 { // local OD access can be performed
755 ObdSize = (tEplObdSize) *puiSize_p;
756 Ret = EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p, &ObdSize);
757 *puiSize_p = (unsigned int) ObdSize;
760 { // perform SDO transfer
761 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
762 tEplSdoComTransParamByIndex TransParamByIndex;
763 // tEplSdoComConHdl SdoComConHdl;
765 // check if application provides space for handle
766 if (pSdoComConHdl_p == NULL)
768 Ret = kEplApiInvalidParam;
770 // pSdoComConHdl_p = &SdoComConHdl;
773 // init command layer connection
774 Ret = EplSdoComDefineCon(pSdoComConHdl_p,
775 uiNodeId_p, // target node id
776 SdoType_p); // SDO type
777 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists))
781 TransParamByIndex.m_pData = pDstData_le_p;
782 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead;
783 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
784 TransParamByIndex.m_uiDataSize = *puiSize_p;
785 TransParamByIndex.m_uiIndex = uiIndex_p;
786 TransParamByIndex.m_uiSubindex = uiSubindex_p;
787 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
788 TransParamByIndex.m_pUserArg = pUserArg_p;
790 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
791 if (Ret != kEplSuccessful)
795 Ret = kEplApiTaskDeferred;
798 Ret = kEplApiInvalidParam;
807 // ----------------------------------------------------------------------------
809 // Function: EplApiWriteObject()
811 // Description: writes the specified entry to the OD of the specified node.
812 // If this node is a remote node, it performs a SDO transfer, which
813 // means this function returns kEplApiTaskDeferred and the application
814 // is informed via the event callback function when the task is completed.
816 // Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
817 // uiNodeId_p = IN: node ID (0 = itself)
818 // uiIndex_p = IN: index of object in OD
819 // uiSubindex_p = IN: sub-index of object in OD
820 // pSrcData_le_p = IN: pointer to data in little endian
821 // uiSize_p = IN: size of data in bytes
822 // SdoType_p = IN: type of SDO transfer
823 // pUserArg_p = IN: user-definable argument pointer,
824 // which will be passed to the event callback function
826 // Return: tEplKernel = error code
828 // ----------------------------------------------------------------------------
830 tEplKernel PUBLIC EplApiWriteObject(
831 tEplSdoComConHdl* pSdoComConHdl_p,
832 unsigned int uiNodeId_p,
833 unsigned int uiIndex_p,
834 unsigned int uiSubindex_p,
836 unsigned int uiSize_p,
837 tEplSdoType SdoType_p,
840 tEplKernel Ret = kEplSuccessful;
842 if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0))
844 Ret = kEplApiInvalidParam;
849 || uiNodeId_p == EplObdGetNodeId())
850 { // local OD access can be performed
852 Ret = EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p, pSrcData_le_p, uiSize_p);
855 { // perform SDO transfer
856 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
857 tEplSdoComTransParamByIndex TransParamByIndex;
858 // tEplSdoComConHdl SdoComConHdl;
860 // check if application provides space for handle
861 if (pSdoComConHdl_p == NULL)
863 Ret = kEplApiInvalidParam;
865 // pSdoComConHdl_p = &SdoComConHdl;
868 // d.k.: How to recycle command layer connection?
869 // Try to redefine it, which will return kEplSdoComHandleExists
870 // and the existing command layer handle.
871 // If the returned handle is busy, EplSdoComInitTransferByIndex()
872 // will return with error.
873 // $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and
874 // Configuration Manager, are trying to communicate with the very same node.
875 // possible solution: disallow communication by application if Configuration Manager is busy
877 // init command layer connection
878 Ret = EplSdoComDefineCon(pSdoComConHdl_p,
879 uiNodeId_p, // target node id
880 SdoType_p); // SDO type
881 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists))
885 TransParamByIndex.m_pData = pSrcData_le_p;
886 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite;
887 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
888 TransParamByIndex.m_uiDataSize = uiSize_p;
889 TransParamByIndex.m_uiIndex = uiIndex_p;
890 TransParamByIndex.m_uiSubindex = uiSubindex_p;
891 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
892 TransParamByIndex.m_pUserArg = pUserArg_p;
894 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
895 if (Ret != kEplSuccessful)
899 Ret = kEplApiTaskDeferred;
902 Ret = kEplApiInvalidParam;
911 // ----------------------------------------------------------------------------
913 // Function: EplApiFreeSdoChannel()
915 // Description: frees the specified SDO channel.
916 // This function must be called after each call to EplApiReadObject()/EplApiWriteObject()
917 // which returns kEplApiTaskDeferred and the application
918 // is informed via the event callback function when the task is completed.
920 // Parameters: SdoComConHdl_p = IN: SDO connection handle
922 // Return: tEplKernel = error code
924 // ----------------------------------------------------------------------------
926 tEplKernel PUBLIC EplApiFreeSdoChannel(
927 tEplSdoComConHdl SdoComConHdl_p)
929 tEplKernel Ret = kEplSuccessful;
931 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
933 // init command layer connection
934 Ret = EplSdoComUndefineCon(SdoComConHdl_p);
937 Ret = kEplApiInvalidParam;
944 // ----------------------------------------------------------------------------
946 // Function: EplApiReadLocalObject()
948 // Description: reads the specified entry from the local OD.
950 // Parameters: uiIndex_p = IN: index of object in OD
951 // uiSubindex_p = IN: sub-index of object in OD
952 // pDstData_p = OUT: pointer to data in platform byte order
953 // puiSize_p = INOUT: pointer to size of data
955 // Return: tEplKernel = error code
957 // ----------------------------------------------------------------------------
959 tEplKernel PUBLIC EplApiReadLocalObject(
960 unsigned int uiIndex_p,
961 unsigned int uiSubindex_p,
963 unsigned int* puiSize_p)
965 tEplKernel Ret = kEplSuccessful;
968 ObdSize = (tEplObdSize) *puiSize_p;
969 Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize);
970 *puiSize_p = (unsigned int) ObdSize;
976 // ----------------------------------------------------------------------------
978 // Function: EplApiWriteLocalObject()
980 // Description: writes the specified entry to the local OD.
982 // Parameters: uiIndex_p = IN: index of object in OD
983 // uiSubindex_p = IN: sub-index of object in OD
984 // pSrcData_p = IN: pointer to data in platform byte order
985 // uiSize_p = IN: size of data in bytes
987 // Return: tEplKernel = error code
989 // ----------------------------------------------------------------------------
991 tEplKernel PUBLIC EplApiWriteLocalObject(
992 unsigned int uiIndex_p,
993 unsigned int uiSubindex_p,
995 unsigned int uiSize_p)
997 tEplKernel Ret = kEplSuccessful;
999 Ret = EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p, (tEplObdSize) uiSize_p);
1005 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1006 // ----------------------------------------------------------------------------
1008 // Function: EplApiMnTriggerStateChange()
1010 // Description: triggers the specified node command for the specified node.
1012 // Parameters: uiNodeId_p = node ID for which the node command will be executed
1013 // NodeCommand_p = node command
1015 // Return: tEplKernel = error code
1017 // ----------------------------------------------------------------------------
1019 tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
1020 tEplNmtNodeCommand NodeCommand_p)
1022 tEplKernel Ret = kEplSuccessful;
1024 Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p);
1029 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1031 //---------------------------------------------------------------------------
1033 // Function: EplApiCbObdAccess
1035 // Description: callback function for OD accesses
1037 // Parameters: pParam_p = OBD parameter
1039 // Returns: tEplKernel = error code
1044 //---------------------------------------------------------------------------
1046 tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM* pParam_p)
1048 tEplKernel Ret = kEplSuccessful;
1050 #if (EPL_API_OBD_FORWARD_EVENT != FALSE)
1051 tEplApiEventArg EventArg;
1053 // call user callback
1054 // must be disabled for EplApiLinuxKernel.c, because of reentrancy problem
1055 // for local OD access. This is not so bad as user callback function in
1056 // application does not use OD callbacks at the moment.
1057 EventArg.m_ObdCbParam = *pParam_p;
1058 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess,
1060 EplApiInstance_g.m_InitParam.m_pEventUserArg);
1063 switch (pParam_p->m_uiIndex)
1065 //case 0x1006: // NMT_CycleLen_U32 (valid on reset)
1066 case 0x1C14: // DLL_LossOfFrameTolerance_U32
1067 //case 0x1F98: // NMT_CycleTiming_REC (valid on reset)
1069 if (pParam_p->m_ObdEvent == kEplObdEvPostWrite)
1071 // update DLL configuration
1072 Ret = EplApiUpdateDllConfig(FALSE);
1077 case 0x1020: // CFM_VerifyConfiguration_REC.ConfId_U32 != 0
1079 if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
1080 && (pParam_p->m_uiSubIndex == 3)
1081 && (*((DWORD*)pParam_p->m_pArg) != 0))
1083 DWORD dwVerifyConfInvalid = 0;
1084 // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
1085 Ret = EplObdWriteEntry(0x1020, 4, &dwVerifyConfInvalid, 4);
1086 // ignore any error because this objekt is optional
1087 Ret = kEplSuccessful;
1092 case 0x1F9E: // NMT_ResetCmd_U8
1094 if (pParam_p->m_ObdEvent == kEplObdEvPreWrite)
1098 bNmtCommand = *((BYTE *) pParam_p->m_pArg);
1099 // check value range
1100 switch ((tEplNmtCommand)bNmtCommand)
1102 case kEplNmtCmdResetNode:
1103 case kEplNmtCmdResetCommunication:
1104 case kEplNmtCmdResetConfiguration:
1105 case kEplNmtCmdSwReset:
1106 case kEplNmtCmdInvalidService:
1107 // valid command identifier specified
1111 pParam_p->m_dwAbortCode = EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1112 Ret = kEplObdAccessViolation;
1116 else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite)
1120 bNmtCommand = *((BYTE *) pParam_p->m_pArg);
1121 // check value range
1122 switch ((tEplNmtCommand)bNmtCommand)
1124 case kEplNmtCmdResetNode:
1125 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1126 Ret = EplNmtuNmtEvent(kEplNmtEventResetNode);
1130 case kEplNmtCmdResetCommunication:
1131 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1132 Ret = EplNmtuNmtEvent(kEplNmtEventResetCom);
1136 case kEplNmtCmdResetConfiguration:
1137 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1138 Ret = EplNmtuNmtEvent(kEplNmtEventResetConfig);
1142 case kEplNmtCmdSwReset:
1143 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1144 Ret = EplNmtuNmtEvent(kEplNmtEventSwReset);
1148 case kEplNmtCmdInvalidService:
1152 pParam_p->m_dwAbortCode = EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1153 Ret = kEplObdAccessViolation;
1170 //=========================================================================//
1172 // P R I V A T E F U N C T I O N S //
1174 //=========================================================================//
1177 //---------------------------------------------------------------------------
1179 // Function: EplApiProcessEvent
1181 // Description: processes events from event queue and forwards these to
1182 // the application's event callback function
1184 // Parameters: pEplEvent_p = pointer to event
1186 // Returns: tEplKernel = errorcode
1190 //---------------------------------------------------------------------------
1192 static tEplKernel PUBLIC EplApiProcessEvent(
1193 tEplEvent* pEplEvent_p)
1196 tEplEventError* pEventError;
1197 tEplApiEventType EventType;
1199 Ret = kEplSuccessful;
1202 switch(pEplEvent_p->m_EventType)
1205 case kEplEventTypeError:
1207 pEventError = (tEplEventError*) pEplEvent_p->m_pArg;
1208 switch (pEventError->m_EventSource)
1210 // treat the errors from the following sources as critical
1211 case kEplEventSourceEventk:
1212 case kEplEventSourceEventu:
1213 case kEplEventSourceDllk:
1215 EventType = kEplApiEventCriticalError;
1216 // halt the stack by entering NMT state Off
1217 Ret = EplNmtuNmtEvent(kEplNmtEventCriticalError);
1221 // the other errors are just warnings
1224 EventType = kEplApiEventWarning;
1229 // call user callback
1230 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType, (tEplApiEventArg*) pEventError, EplApiInstance_g.m_InitParam.m_pEventUserArg);
1231 // discard error from callback function, because this could generate an endless loop
1232 Ret = kEplSuccessful;
1236 // at present, there are no other events for this module
1245 //---------------------------------------------------------------------------
1247 // Function: EplApiCbNmtStateChange
1249 // Description: callback function for NMT state changes
1251 // Parameters: NmtStateChange_p = NMT state change event
1253 // Returns: tEplKernel = error code
1258 //---------------------------------------------------------------------------
1260 static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
1262 tEplKernel Ret = kEplSuccessful;
1264 tEplApiEventArg EventArg;
1266 // save NMT state in OD
1267 bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState;
1268 Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
1269 if(Ret != kEplSuccessful)
1274 // do work which must be done in that state
1275 switch (NmtStateChange_p.m_NewNmtState)
1277 // EPL stack is not running
1281 // first init of the hardware
1282 case kEplNmtGsInitialising:
1284 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
1285 // configure SDO via UDP (i.e. bind it to the EPL ethernet interface)
1286 Ret = EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress, EPL_C_SDO_EPL_PORT);
1287 if (Ret != kEplSuccessful)
1296 // init of the manufacturer-specific profile area and the
1297 // standardised device profile area
1298 case kEplNmtGsResetApplication:
1300 // reset application part of OD
1301 Ret = EplObdAccessOdPart(
1304 if (Ret != kEplSuccessful)
1312 // init of the communication profile area
1313 case kEplNmtGsResetCommunication:
1315 // reset communication part of OD
1316 Ret = EplObdAccessOdPart(
1320 if (Ret != kEplSuccessful)
1325 // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory
1326 Ret = EplApiUpdateObd();
1327 if (Ret != kEplSuccessful)
1335 // build the configuration with infos from OD
1336 case kEplNmtGsResetConfiguration:
1339 Ret = EplApiUpdateDllConfig(TRUE);
1340 if (Ret != kEplSuccessful)
1348 //-----------------------------------------------------------
1349 // CN part of the state machine
1351 // node liste for EPL-Frames and check timeout
1352 case kEplNmtCsNotActive:
1354 // indicate completion of reset in NMT_ResetCmd_U8
1355 bNmtState = (BYTE) kEplNmtCmdInvalidService;
1356 Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
1357 if (Ret != kEplSuccessful)
1365 // node process only async frames
1366 case kEplNmtCsPreOperational1:
1371 // node process isochronus and asynchronus frames
1372 case kEplNmtCsPreOperational2:
1377 // node should be configured und application is ready
1378 case kEplNmtCsReadyToOperate:
1383 // normal work state
1384 case kEplNmtCsOperational:
1389 // node stopped by MN
1390 // -> only process asynchronus frames
1391 case kEplNmtCsStopped:
1397 // -> normal ethernet communication
1398 case kEplNmtCsBasicEthernet:
1403 //-----------------------------------------------------------
1404 // MN part of the state machine
1406 // node listens for EPL-Frames and check timeout
1407 case kEplNmtMsNotActive:
1412 // node processes only async frames
1413 case kEplNmtMsPreOperational1:
1418 // node processes isochronous and asynchronous frames
1419 case kEplNmtMsPreOperational2:
1424 // node should be configured und application is ready
1425 case kEplNmtMsReadyToOperate:
1430 // normal work state
1431 case kEplNmtMsOperational:
1437 // -> normal ethernet communication
1438 case kEplNmtMsBasicEthernet:
1445 TRACE0("EplApiCbNmtStateChange(): unhandled NMT state\n");
1449 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
1450 // forward event to Led module
1451 Ret = EplLeduCbNmtStateChange(NmtStateChange_p);
1452 if (Ret != kEplSuccessful)
1458 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1459 // forward event to NmtMn module
1460 Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p);
1461 if (Ret != kEplSuccessful)
1467 // call user callback
1468 EventArg.m_NmtStateChange = NmtStateChange_p;
1469 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNmtStateChange,
1471 EplApiInstance_g.m_InitParam.m_pEventUserArg);
1477 //---------------------------------------------------------------------------
1479 // Function: EplApiUpdateDllConfig
1481 // Description: update configuration of DLL
1483 // Parameters: fUpdateIdentity_p = TRUE, if identity must be updated
1485 // Returns: tEplKernel = error code
1490 //---------------------------------------------------------------------------
1492 static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
1494 tEplKernel Ret = kEplSuccessful;
1495 tEplDllConfigParam DllConfigParam;
1496 tEplDllIdentParam DllIdentParam;
1497 tEplObdSize ObdSize;
1502 EPL_MEMSET(&DllConfigParam, 0, sizeof (DllConfigParam));
1503 DllConfigParam.m_uiNodeId = EplObdGetNodeId();
1505 // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
1507 Ret = EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize);
1508 if(Ret != kEplSuccessful)
1513 // 0x1F82: NMT_FeatureFlags_U32
1515 Ret = EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags, &ObdSize);
1516 if(Ret != kEplSuccessful)
1521 // d.k. There is no dependance between FeatureFlags and async-only CN
1522 DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly;
1524 // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
1526 Ret = EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance, &ObdSize);
1527 if(Ret != kEplSuccessful)
1532 // 0x1F98: NMT_CycleTiming_REC
1533 // 0x1F98.1: IsochrTxMaxPayload_U16
1535 Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize);
1536 if(Ret != kEplSuccessful)
1540 DllConfigParam.m_uiIsochrTxMaxPayload = wTemp;
1542 // 0x1F98.2: IsochrRxMaxPayload_U16
1544 Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize);
1545 if(Ret != kEplSuccessful)
1549 DllConfigParam.m_uiIsochrRxMaxPayload = wTemp;
1551 // 0x1F98.3: PResMaxLatency_U32
1553 Ret = EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency, &ObdSize);
1554 if(Ret != kEplSuccessful)
1559 // 0x1F98.4: PReqActPayloadLimit_U16
1561 Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize);
1562 if(Ret != kEplSuccessful)
1566 DllConfigParam.m_uiPreqActPayloadLimit = wTemp;
1568 // 0x1F98.5: PResActPayloadLimit_U16
1570 Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize);
1571 if(Ret != kEplSuccessful)
1575 DllConfigParam.m_uiPresActPayloadLimit = wTemp;
1577 // 0x1F98.6: ASndMaxLatency_U32
1579 Ret = EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency, &ObdSize);
1580 if(Ret != kEplSuccessful)
1585 // 0x1F98.7: MultiplCycleCnt_U8
1587 Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize);
1588 if(Ret != kEplSuccessful)
1592 DllConfigParam.m_uiMultiplCycleCnt = bTemp;
1594 // 0x1F98.8: AsyncMTU_U16
1596 Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize);
1597 if(Ret != kEplSuccessful)
1601 DllConfigParam.m_uiAsyncMtu = wTemp;
1605 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1606 // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
1608 Ret = EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq, &ObdSize);
1609 if(Ret != kEplSuccessful)
1614 // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional)
1616 Ret = EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout, &ObdSize);
1617 /* if(Ret != kEplSuccessful)
1623 DllConfigParam.m_uiSizeOfStruct = sizeof (DllConfigParam);
1624 Ret = EplDllkConfig(&DllConfigParam);
1625 if(Ret != kEplSuccessful)
1630 if (fUpdateIdentity_p != FALSE)
1632 // configure Identity
1633 EPL_MEMSET(&DllIdentParam, 0, sizeof (DllIdentParam));
1635 Ret = EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType, &ObdSize);
1636 if(Ret != kEplSuccessful)
1642 Ret = EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId, &ObdSize);
1643 if(Ret != kEplSuccessful)
1648 Ret = EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode, &ObdSize);
1649 if(Ret != kEplSuccessful)
1654 Ret = EplObdReadEntry(0x1018, 3, &DllIdentParam.m_dwRevisionNumber, &ObdSize);
1655 if(Ret != kEplSuccessful)
1660 Ret = EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber, &ObdSize);
1661 if(Ret != kEplSuccessful)
1666 DllIdentParam.m_dwIpAddress = EplApiInstance_g.m_InitParam.m_dwIpAddress;
1667 DllIdentParam.m_dwSubnetMask = EplApiInstance_g.m_InitParam.m_dwSubnetMask;
1668 EPL_MEMCPY(DllIdentParam.m_sHostname, EplApiInstance_g.m_InitParam.m_sHostname, sizeof (DllIdentParam.m_sHostname));
1671 Ret = EplObdReadEntry(0x1020, 1, &DllIdentParam.m_dwVerifyConfigurationDate, &ObdSize);
1672 // ignore any error, because this object is optional
1675 Ret = EplObdReadEntry(0x1020, 2, &DllIdentParam.m_dwVerifyConfigurationTime, &ObdSize);
1676 // ignore any error, because this object is optional
1678 // $$$ d.k.: fill rest of ident structure
1680 DllIdentParam.m_uiSizeOfStruct = sizeof (DllIdentParam);
1681 Ret = EplDllkSetIdentity(&DllIdentParam);
1682 if(Ret != kEplSuccessful)
1692 //---------------------------------------------------------------------------
1694 // Function: EplApiUpdateObd
1696 // Description: update OD from init param
1698 // Parameters: (none)
1700 // Returns: tEplKernel = error code
1705 //---------------------------------------------------------------------------
1707 static tEplKernel PUBLIC EplApiUpdateObd(void)
1709 tEplKernel Ret = kEplSuccessful;
1713 // set node id in OD
1714 Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId, // node id
1715 kEplObdNodeIdHardware); // set by hardware
1716 if(Ret != kEplSuccessful)
1721 if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1)
1723 Ret = EplObdWriteEntry(0x1006, 0, &EplApiInstance_g.m_InitParam.m_dwCycleLen, 4);
1724 /* if(Ret != kEplSuccessful)
1730 if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1)
1732 Ret = EplObdWriteEntry(0x1C14, 0, &EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance, 4);
1733 /* if(Ret != kEplSuccessful)
1739 // d.k. There is no dependance between FeatureFlags and async-only CN.
1740 if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1)
1742 Ret = EplObdWriteEntry(0x1F82, 0, &EplApiInstance_g.m_InitParam.m_dwFeatureFlags, 4);
1743 /* if(Ret != kEplSuccessful)
1749 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
1750 Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
1751 /* if(Ret != kEplSuccessful)
1756 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
1757 Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
1758 /* if(Ret != kEplSuccessful)
1763 Ret = EplObdWriteEntry(0x1F98, 3, &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency, 4);
1764 /* if(Ret != kEplSuccessful)
1769 if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <= EPL_C_DLL_ISOCHR_MAX_PAYL)
1771 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
1772 Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
1773 /* if(Ret != kEplSuccessful)
1779 if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <= EPL_C_DLL_ISOCHR_MAX_PAYL)
1781 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
1782 Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
1783 /* if(Ret != kEplSuccessful)
1789 Ret = EplObdWriteEntry(0x1F98, 6, &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency, 4);
1790 /* if(Ret != kEplSuccessful)
1795 if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF)
1797 bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
1798 Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
1799 /* if(Ret != kEplSuccessful)
1805 if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <= EPL_C_DLL_MAX_ASYNC_MTU)
1807 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
1808 Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
1809 /* if(Ret != kEplSuccessful)
1815 if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000)
1817 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPrescaler;
1818 Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
1819 // ignore return code
1820 Ret = kEplSuccessful;
1823 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1824 if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1)
1826 Ret = EplObdWriteEntry(0x1F8A, 1, &EplApiInstance_g.m_InitParam.m_dwWaitSocPreq, 4);
1827 /* if(Ret != kEplSuccessful)
1833 if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0) && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1))
1835 Ret = EplObdWriteEntry(0x1F8A, 2, &EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout, 4);
1836 /* if(Ret != kEplSuccessful)
1843 // configure Identity
1844 if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1)
1846 Ret = EplObdWriteEntry(0x1000, 0, &EplApiInstance_g.m_InitParam.m_dwDeviceType, 4);
1847 /* if(Ret != kEplSuccessful)
1853 if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1)
1855 Ret = EplObdWriteEntry(0x1018, 1, &EplApiInstance_g.m_InitParam.m_dwVendorId, 4);
1856 /* if(Ret != kEplSuccessful)
1862 if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1)
1864 Ret = EplObdWriteEntry(0x1018, 2, &EplApiInstance_g.m_InitParam.m_dwProductCode, 4);
1865 /* if(Ret != kEplSuccessful)
1871 if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1)
1873 Ret = EplObdWriteEntry(0x1018, 3, &EplApiInstance_g.m_InitParam.m_dwRevisionNumber, 4);
1874 /* if(Ret != kEplSuccessful)
1880 if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1)
1882 Ret = EplObdWriteEntry(0x1018, 4, &EplApiInstance_g.m_InitParam.m_dwSerialNumber, 4);
1883 /* if(Ret != kEplSuccessful)
1889 if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL)
1891 // write Device Name (0x1008)
1892 Ret = EplObdWriteEntry (
1893 0x1008, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszDevName, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszDevName));
1894 /* if (Ret != kEplSuccessful)
1900 if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL)
1902 // write Hardware version (0x1009)
1903 Ret = EplObdWriteEntry (
1904 0x1009, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszHwVersion, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszHwVersion));
1905 /* if (Ret != kEplSuccessful)
1911 if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL)
1913 // write Software version (0x100A)
1914 Ret = EplObdWriteEntry (
1915 0x100A, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszSwVersion, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszSwVersion));
1916 /* if (Ret != kEplSuccessful)
1927 //---------------------------------------------------------------------------
1929 // Function: EplApiCbSdoCon
1931 // Description: callback function for SDO transfers
1933 // Parameters: pSdoComFinished_p = SDO parameter
1935 // Returns: tEplKernel = error code
1940 //---------------------------------------------------------------------------
1942 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1943 static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished* pSdoComFinished_p)
1946 tEplApiEventArg EventArg;
1948 Ret = kEplSuccessful;
1950 // call user callback
1951 EventArg.m_Sdo = *pSdoComFinished_p;
1952 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo,
1954 EplApiInstance_g.m_InitParam.m_pEventUserArg);
1962 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1964 //---------------------------------------------------------------------------
1966 // Function: EplApiCbNodeEvent
1968 // Description: callback function for node events
1970 // Parameters: uiNodeId_p = node ID of the CN
1971 // NodeEvent_p = event from the specified CN
1972 // NmtState_p = current NMT state of the CN
1973 // wErrorCode_p = EPL error code if NodeEvent_p==kEplNmtNodeEventError
1974 // fMandatory_p = flag if CN is mandatory
1976 // Returns: tEplKernel = error code
1981 //---------------------------------------------------------------------------
1983 static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
1984 tEplNmtNodeEvent NodeEvent_p,
1985 tEplNmtState NmtState_p,
1990 tEplApiEventArg EventArg;
1992 Ret = kEplSuccessful;
1994 // call user callback
1995 EventArg.m_Node.m_uiNodeId = uiNodeId_p;
1996 EventArg.m_Node.m_NodeEvent = NodeEvent_p;
1997 EventArg.m_Node.m_NmtState = NmtState_p;
1998 EventArg.m_Node.m_wErrorCode = wErrorCode_p;
1999 EventArg.m_Node.m_fMandatory = fMandatory_p;
2001 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode,
2003 EplApiInstance_g.m_InitParam.m_pEventUserArg);
2010 //---------------------------------------------------------------------------
2012 // Function: EplApiCbBootEvent
2014 // Description: callback function for boot events
2016 // Parameters: BootEvent_p = event from the boot-up process
2017 // NmtState_p = current local NMT state
2018 // wErrorCode_p = EPL error code if BootEvent_p==kEplNmtBootEventError
2020 // Returns: tEplKernel = error code
2025 //---------------------------------------------------------------------------
2027 static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
2028 tEplNmtState NmtState_p,
2032 tEplApiEventArg EventArg;
2034 Ret = kEplSuccessful;
2036 // call user callback
2037 EventArg.m_Boot.m_BootEvent = BootEvent_p;
2038 EventArg.m_Boot.m_NmtState = NmtState_p;
2039 EventArg.m_Boot.m_wErrorCode = wErrorCode_p;
2041 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot,
2043 EplApiInstance_g.m_InitParam.m_pEventUserArg);
2049 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
2052 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
2054 //---------------------------------------------------------------------------
2056 // Function: EplApiCbLedStateChange
2058 // Description: callback function for LED change events.
2060 // Parameters: LedType_p = type of LED
2061 // fOn_p = state of LED
2063 // Returns: tEplKernel = errorcode
2067 //---------------------------------------------------------------------------
2069 static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
2073 tEplApiEventArg EventArg;
2075 Ret = kEplSuccessful;
2077 // call user callback
2078 EventArg.m_Led.m_LedType = LedType_p;
2079 EventArg.m_Led.m_fOn = fOn_p;
2081 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed,
2083 EplApiInstance_g.m_InitParam.m_pEventUserArg);