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 PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
168 // update DLL configuration from OD
169 static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
171 // update OD from init param
172 static tEplKernel PUBLIC EplApiUpdateObd(void);
174 // process events from user event queue
175 static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p);
177 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
178 // callback function of SDO module
179 static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p);
182 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
183 // callback functions of NmtMnu module
184 static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
185 tEplNmtNodeEvent NodeEvent_p,
186 tEplNmtState NmtState_p,
190 static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
191 tEplNmtState NmtState_p,
195 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
196 // callback function of Ledu module
197 static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
201 // OD initialization function (implemented in Objdict.c)
202 tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
204 //=========================================================================//
206 // P U B L I C F U N C T I O N S //
208 //=========================================================================//
210 //---------------------------------------------------------------------------
212 // Function: EplApiInitialize()
214 // Description: add and initialize new instance of EPL stack.
215 // After return from this function the application must start
216 // the NMT state machine via
217 // EplApiExecNmtCommand(kEplNmtEventSwReset)
218 // and thereby the whole EPL stack :-)
220 // Parameters: pInitParam_p = initialisation parameters
222 // Returns: tEplKernel = error code
227 //---------------------------------------------------------------------------
229 tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
231 tEplKernel Ret = kEplSuccessful;
232 tEplObdInitParam ObdInitParam;
233 tEplDllkInitParam DllkInitParam;
238 // reset instance structure
239 EPL_MEMSET(&EplApiInstance_g, 0, sizeof(EplApiInstance_g));
241 EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p,
242 min(sizeof(tEplApiInitParam),
243 pInitParam_p->m_uiSizeOfStruct));
245 // check event callback function pointer
246 if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL) { // application must always have an event callback function
247 Ret = kEplApiInvalidParam;
250 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
253 // Ret = EplObdInitRam(&ObdInitParam);
254 // if (Ret != kEplSuccessful)
259 // initialize EplObd module
260 Ret = EplObdInit(&ObdInitParam);
261 if (Ret != kEplSuccessful) {
267 ShbError = ShbInit();
268 if (ShbError != kShbOk) {
269 Ret = kEplNoResource;
274 // initialize EplEventk module
275 Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync);
276 if (Ret != kEplSuccessful) {
279 // initialize EplEventu module
280 Ret = EplEventuInit(EplApiProcessEvent);
281 if (Ret != kEplSuccessful) {
284 // init EplTimerk module
285 Ret = EplTimerkInit();
286 if (Ret != kEplSuccessful) {
289 // initialize EplNmtk module before DLL
290 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
292 if (Ret != kEplSuccessful) {
297 // initialize EplDllk module
298 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
299 EPL_MEMCPY(DllkInitParam.m_be_abSrcMac,
300 EplApiInstance_g.m_InitParam.m_abMacAddress, 6);
301 Ret = EplDllkAddInstance(&DllkInitParam);
302 if (Ret != kEplSuccessful) {
305 // initialize EplErrorHandlerk module
306 Ret = EplErrorHandlerkInit();
307 if (Ret != kEplSuccessful) {
310 // initialize EplDllkCal module
311 Ret = EplDllkCalAddInstance();
312 if (Ret != kEplSuccessful) {
317 // initialize EplDlluCal module
318 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
319 Ret = EplDlluCalAddInstance();
320 if (Ret != kEplSuccessful) {
325 // initialize EplPdok module
326 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
327 Ret = EplPdokAddInstance();
328 if (Ret != kEplSuccessful) {
332 Ret = EplPdokCalAddInstance();
333 if (Ret != kEplSuccessful) {
338 // initialize EplNmtCnu module
339 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
340 Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId);
341 if (Ret != kEplSuccessful) {
346 // initialize EplNmtu module
347 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
349 if (Ret != kEplSuccessful) {
352 // register NMT event callback function
353 Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange);
354 if (Ret != kEplSuccessful) {
359 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
360 // initialize EplNmtMnu module
361 Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent);
362 if (Ret != kEplSuccessful) {
365 // initialize EplIdentu module
366 Ret = EplIdentuInit();
367 if (Ret != kEplSuccessful) {
370 // initialize EplStatusu module
371 Ret = EplStatusuInit();
372 if (Ret != kEplSuccessful) {
377 // initialize EplLedu module
378 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
379 Ret = EplLeduInit(EplApiCbLedStateChange);
380 if (Ret != kEplSuccessful) {
386 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
387 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
388 // init sdo command layer
389 Ret = EplSdoComInit();
390 if (Ret != kEplSuccessful) {
395 // the application must start NMT state machine
396 // via EplApiExecNmtCommand(kEplNmtEventSwReset)
397 // and thereby the whole EPL stack
403 //---------------------------------------------------------------------------
405 // Function: EplApiShutdown()
407 // Description: deletes an instance of EPL stack
409 // Parameters: (none)
411 // Returns: tEplKernel = error code
416 //---------------------------------------------------------------------------
418 tEplKernel PUBLIC EplApiShutdown(void)
420 tEplKernel Ret = kEplSuccessful;
422 // $$$ d.k.: check if NMT state is NMT_GS_OFF
424 // $$$ d.k.: maybe delete event queues at first, but this implies that
425 // no other module must not use the event queues for communication
428 // delete instance for all modules
430 // deinitialize EplSdoCom module
431 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
432 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
433 Ret = EplSdoComDelInstance();
434 // PRINTF1("EplSdoComDelInstance(): 0x%X\n", Ret);
437 // deinitialize EplLedu module
438 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
439 Ret = EplLeduDelInstance();
440 // PRINTF1("EplLeduDelInstance(): 0x%X\n", Ret);
443 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
444 // deinitialize EplNmtMnu module
445 Ret = EplNmtMnuDelInstance();
446 // PRINTF1("EplNmtMnuDelInstance(): 0x%X\n", Ret);
448 // deinitialize EplIdentu module
449 Ret = EplIdentuDelInstance();
450 // PRINTF1("EplIdentuDelInstance(): 0x%X\n", Ret);
452 // deinitialize EplStatusu module
453 Ret = EplStatusuDelInstance();
454 // PRINTF1("EplStatusuDelInstance(): 0x%X\n", Ret);
457 // deinitialize EplNmtCnu module
458 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
459 Ret = EplNmtCnuDelInstance();
460 // PRINTF1("EplNmtCnuDelInstance(): 0x%X\n", Ret);
463 // deinitialize EplNmtu module
464 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
465 Ret = EplNmtuDelInstance();
466 // PRINTF1("EplNmtuDelInstance(): 0x%X\n", Ret);
469 // deinitialize EplDlluCal module
470 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
471 Ret = EplDlluCalDelInstance();
472 // PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret);
476 // deinitialize EplEventu module
477 Ret = EplEventuDelInstance();
478 // PRINTF1("EplEventuDelInstance(): 0x%X\n", Ret);
480 // deinitialize EplNmtk module
481 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
482 Ret = EplNmtkDelInstance();
483 // PRINTF1("EplNmtkDelInstance(): 0x%X\n", Ret);
486 // deinitialize EplDllk module
487 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
488 Ret = EplDllkDelInstance();
489 // PRINTF1("EplDllkDelInstance(): 0x%X\n", Ret);
491 // deinitialize EplDllkCal module
492 Ret = EplDllkCalDelInstance();
493 // PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret);
496 // deinitialize EplEventk module
497 Ret = EplEventkDelInstance();
498 // PRINTF1("EplEventkDelInstance(): 0x%X\n", Ret);
500 // deinitialize EplTimerk module
501 Ret = EplTimerkDelInstance();
502 // PRINTF1("EplTimerkDelInstance(): 0x%X\n", Ret);
511 //----------------------------------------------------------------------------
512 // Function: EplApiExecNmtCommand()
514 // Description: executes a NMT command, i.e. post the NMT command/event to the
515 // NMTk module. NMT commands which are not appropriate in the current
516 // NMT state are silently ignored. Please keep in mind that the
517 // NMT state may change until the NMT command is actually executed.
519 // Parameters: NmtEvent_p = NMT command/event
521 // Returns: tEplKernel = error code
524 //----------------------------------------------------------------------------
526 tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
528 tEplKernel Ret = kEplSuccessful;
530 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
531 Ret = EplNmtuNmtEvent(NmtEvent_p);
537 //----------------------------------------------------------------------------
538 // Function: EplApiLinkObject()
540 // Description: Function maps array of application variables onto specified object in OD
542 // Parameters: uiObjIndex_p = Function maps variables for this object index
543 // pVar_p = Pointer to data memory area for the specified object
544 // puiVarEntries_p = IN: pointer to number of entries to map
545 // OUT: pointer to number of actually used entries
546 // pEntrySize_p = IN: pointer to size of one entry;
547 // if size is zero, the actual size will be read from OD
548 // OUT: pointer to entire size of all entries mapped
549 // uiFirstSubindex_p = This is the first subindex to be mapped.
551 // Returns: tEplKernel = error code
554 //----------------------------------------------------------------------------
556 tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
558 unsigned int *puiVarEntries_p,
559 tEplObdSize * pEntrySize_p,
560 unsigned int uiFirstSubindex_p)
565 unsigned int uiSubindex;
566 tEplVarParam VarParam;
567 tEplObdSize EntrySize;
568 tEplObdSize UsedSize;
570 tEplKernel RetCode = kEplSuccessful;
573 || (puiVarEntries_p == NULL)
574 || (*puiVarEntries_p == 0)
575 || (pEntrySize_p == NULL)) {
576 RetCode = kEplApiInvalidParam;
580 pbData = (BYTE MEM *) pVar_p;
581 bVarEntries = (BYTE) * puiVarEntries_p;
584 // init VarParam structure with default values
585 VarParam.m_uiIndex = uiObjIndex_p;
586 VarParam.m_ValidFlag = kVarValidAll;
588 if (uiFirstSubindex_p != 0) { // check if object exists by reading subindex 0x00,
589 // because user wants to link a variable to a subindex unequal 0x00
590 // read number of entries
591 EntrySize = (tEplObdSize) sizeof(bIndexEntries);
592 RetCode = EplObdReadEntry(uiObjIndex_p,
594 (void GENERIC *)&bIndexEntries,
597 if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
598 // Object doesn't exist or invalid entry number
599 RetCode = kEplObdIndexNotExist;
602 } else { // user wants to link a variable to subindex 0x00
607 // Correct number of entries if number read from OD is greater
608 // than the specified number.
609 // This is done, so that we do not set more entries than subindexes the
610 // object actually has.
611 if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
612 (bVarEntries != 0x00)) {
613 bIndexEntries = (BYTE) (bVarEntries + uiFirstSubindex_p - 1);
616 for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
618 // if passed entry size is 0, then get size from OD
619 if (*pEntrySize_p == 0x00) {
621 EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex);
623 if (EntrySize == 0x00) {
624 // invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty)
625 RetCode = kEplObdSubindexNotExist;
628 } else { // use passed entry size
629 EntrySize = *pEntrySize_p;
632 VarParam.m_uiSubindex = uiSubindex;
634 // set pointer to user var
635 VarParam.m_Size = EntrySize;
636 VarParam.m_pData = pbData;
638 UsedSize += EntrySize;
641 RetCode = EplObdDefineVar(&VarParam);
642 if (RetCode != kEplSuccessful) {
647 // set number of mapped entries and entry size
648 *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1);
649 *pEntrySize_p = UsedSize;
657 // ----------------------------------------------------------------------------
659 // Function: EplApiReadObject()
661 // Description: reads the specified entry from the OD of the specified node.
662 // If this node is a remote node, it performs a SDO transfer, which
663 // means this function returns kEplApiTaskDeferred and the application
664 // is informed via the event callback function when the task is completed.
666 // Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
667 // uiNodeId_p = IN: node ID (0 = itself)
668 // uiIndex_p = IN: index of object in OD
669 // uiSubindex_p = IN: sub-index of object in OD
670 // pDstData_le_p = OUT: pointer to data in little endian
671 // puiSize_p = INOUT: pointer to size of data
672 // SdoType_p = IN: type of SDO transfer
673 // pUserArg_p = IN: user-definable argument pointer,
674 // which will be passed to the event callback function
676 // Return: tEplKernel = error code
678 // ----------------------------------------------------------------------------
680 tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
681 unsigned int uiNodeId_p,
682 unsigned int uiIndex_p,
683 unsigned int uiSubindex_p,
685 unsigned int *puiSize_p,
686 tEplSdoType SdoType_p, void *pUserArg_p)
688 tEplKernel Ret = kEplSuccessful;
690 if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL)
691 || (*puiSize_p == 0)) {
692 Ret = kEplApiInvalidParam;
696 if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed
699 ObdSize = (tEplObdSize) * puiSize_p;
701 EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p,
703 *puiSize_p = (unsigned int)ObdSize;
704 } else { // perform SDO transfer
705 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
706 tEplSdoComTransParamByIndex TransParamByIndex;
707 // tEplSdoComConHdl SdoComConHdl;
709 // check if application provides space for handle
710 if (pSdoComConHdl_p == NULL) {
711 Ret = kEplApiInvalidParam;
713 // pSdoComConHdl_p = &SdoComConHdl;
715 // init command layer connection
716 Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p, // target node id
717 SdoType_p); // SDO type
718 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
721 TransParamByIndex.m_pData = pDstData_le_p;
722 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead;
723 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
724 TransParamByIndex.m_uiDataSize = *puiSize_p;
725 TransParamByIndex.m_uiIndex = uiIndex_p;
726 TransParamByIndex.m_uiSubindex = uiSubindex_p;
727 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
728 TransParamByIndex.m_pUserArg = pUserArg_p;
730 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
731 if (Ret != kEplSuccessful) {
734 Ret = kEplApiTaskDeferred;
737 Ret = kEplApiInvalidParam;
745 // ----------------------------------------------------------------------------
747 // Function: EplApiWriteObject()
749 // Description: writes the specified entry to the OD of the specified node.
750 // If this node is a remote node, it performs a SDO transfer, which
751 // means this function returns kEplApiTaskDeferred and the application
752 // is informed via the event callback function when the task is completed.
754 // Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
755 // uiNodeId_p = IN: node ID (0 = itself)
756 // uiIndex_p = IN: index of object in OD
757 // uiSubindex_p = IN: sub-index of object in OD
758 // pSrcData_le_p = IN: pointer to data in little endian
759 // uiSize_p = IN: size of data in bytes
760 // SdoType_p = IN: type of SDO transfer
761 // pUserArg_p = IN: user-definable argument pointer,
762 // which will be passed to the event callback function
764 // Return: tEplKernel = error code
766 // ----------------------------------------------------------------------------
768 tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
769 unsigned int uiNodeId_p,
770 unsigned int uiIndex_p,
771 unsigned int uiSubindex_p,
773 unsigned int uiSize_p,
774 tEplSdoType SdoType_p, void *pUserArg_p)
776 tEplKernel Ret = kEplSuccessful;
778 if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0)) {
779 Ret = kEplApiInvalidParam;
783 if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) { // local OD access can be performed
786 EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p,
787 pSrcData_le_p, uiSize_p);
788 } else { // perform SDO transfer
789 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
790 tEplSdoComTransParamByIndex TransParamByIndex;
791 // tEplSdoComConHdl SdoComConHdl;
793 // check if application provides space for handle
794 if (pSdoComConHdl_p == NULL) {
795 Ret = kEplApiInvalidParam;
797 // pSdoComConHdl_p = &SdoComConHdl;
799 // d.k.: How to recycle command layer connection?
800 // Try to redefine it, which will return kEplSdoComHandleExists
801 // and the existing command layer handle.
802 // If the returned handle is busy, EplSdoComInitTransferByIndex()
803 // will return with error.
804 // $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and
805 // Configuration Manager, are trying to communicate with the very same node.
806 // possible solution: disallow communication by application if Configuration Manager is busy
808 // init command layer connection
809 Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p, // target node id
810 SdoType_p); // SDO type
811 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
814 TransParamByIndex.m_pData = pSrcData_le_p;
815 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite;
816 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
817 TransParamByIndex.m_uiDataSize = uiSize_p;
818 TransParamByIndex.m_uiIndex = uiIndex_p;
819 TransParamByIndex.m_uiSubindex = uiSubindex_p;
820 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
821 TransParamByIndex.m_pUserArg = pUserArg_p;
823 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
824 if (Ret != kEplSuccessful) {
827 Ret = kEplApiTaskDeferred;
830 Ret = kEplApiInvalidParam;
838 // ----------------------------------------------------------------------------
840 // Function: EplApiFreeSdoChannel()
842 // Description: frees the specified SDO channel.
843 // This function must be called after each call to EplApiReadObject()/EplApiWriteObject()
844 // which returns kEplApiTaskDeferred and the application
845 // is informed via the event callback function when the task is completed.
847 // Parameters: SdoComConHdl_p = IN: SDO connection handle
849 // Return: tEplKernel = error code
851 // ----------------------------------------------------------------------------
853 tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
855 tEplKernel Ret = kEplSuccessful;
857 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
859 // init command layer connection
860 Ret = EplSdoComUndefineCon(SdoComConHdl_p);
863 Ret = kEplApiInvalidParam;
869 // ----------------------------------------------------------------------------
871 // Function: EplApiReadLocalObject()
873 // Description: reads the specified entry from the local OD.
875 // Parameters: uiIndex_p = IN: index of object in OD
876 // uiSubindex_p = IN: sub-index of object in OD
877 // pDstData_p = OUT: pointer to data in platform byte order
878 // puiSize_p = INOUT: pointer to size of data
880 // Return: tEplKernel = error code
882 // ----------------------------------------------------------------------------
884 tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
885 unsigned int uiSubindex_p,
887 unsigned int *puiSize_p)
889 tEplKernel Ret = kEplSuccessful;
892 ObdSize = (tEplObdSize) * puiSize_p;
893 Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize);
894 *puiSize_p = (unsigned int)ObdSize;
899 // ----------------------------------------------------------------------------
901 // Function: EplApiWriteLocalObject()
903 // Description: writes the specified entry to the local OD.
905 // Parameters: uiIndex_p = IN: index of object in OD
906 // uiSubindex_p = IN: sub-index of object in OD
907 // pSrcData_p = IN: pointer to data in platform byte order
908 // uiSize_p = IN: size of data in bytes
910 // Return: tEplKernel = error code
912 // ----------------------------------------------------------------------------
914 tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
915 unsigned int uiSubindex_p,
917 unsigned int uiSize_p)
919 tEplKernel Ret = kEplSuccessful;
922 EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p,
923 (tEplObdSize) uiSize_p);
928 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
929 // ----------------------------------------------------------------------------
931 // Function: EplApiMnTriggerStateChange()
933 // Description: triggers the specified node command for the specified node.
935 // Parameters: uiNodeId_p = node ID for which the node command will be executed
936 // NodeCommand_p = node command
938 // Return: tEplKernel = error code
940 // ----------------------------------------------------------------------------
942 tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
943 tEplNmtNodeCommand NodeCommand_p)
945 tEplKernel Ret = kEplSuccessful;
947 Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p);
952 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
954 //---------------------------------------------------------------------------
956 // Function: EplApiCbObdAccess
958 // Description: callback function for OD accesses
960 // Parameters: pParam_p = OBD parameter
962 // Returns: tEplKernel = error code
967 //---------------------------------------------------------------------------
969 tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
971 tEplKernel Ret = kEplSuccessful;
973 #if (EPL_API_OBD_FORWARD_EVENT != FALSE)
974 tEplApiEventArg EventArg;
976 // call user callback
977 // must be disabled for EplApiLinuxKernel.c, because of reentrancy problem
978 // for local OD access. This is not so bad as user callback function in
979 // application does not use OD callbacks at the moment.
980 EventArg.m_ObdCbParam = *pParam_p;
981 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess,
988 switch (pParam_p->m_uiIndex) {
989 //case 0x1006: // NMT_CycleLen_U32 (valid on reset)
990 case 0x1C14: // DLL_LossOfFrameTolerance_U32
991 //case 0x1F98: // NMT_CycleTiming_REC (valid on reset)
993 if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
994 // update DLL configuration
995 Ret = EplApiUpdateDllConfig(FALSE);
1000 case 0x1020: // CFM_VerifyConfiguration_REC.ConfId_U32 != 0
1002 if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
1003 && (pParam_p->m_uiSubIndex == 3)
1004 && (*((DWORD *) pParam_p->m_pArg) != 0)) {
1005 DWORD dwVerifyConfInvalid = 0;
1006 // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
1008 EplObdWriteEntry(0x1020, 4,
1009 &dwVerifyConfInvalid, 4);
1010 // ignore any error because this objekt is optional
1011 Ret = kEplSuccessful;
1016 case 0x1F9E: // NMT_ResetCmd_U8
1018 if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
1021 bNmtCommand = *((BYTE *) pParam_p->m_pArg);
1022 // check value range
1023 switch ((tEplNmtCommand) bNmtCommand) {
1024 case kEplNmtCmdResetNode:
1025 case kEplNmtCmdResetCommunication:
1026 case kEplNmtCmdResetConfiguration:
1027 case kEplNmtCmdSwReset:
1028 case kEplNmtCmdInvalidService:
1029 // valid command identifier specified
1033 pParam_p->m_dwAbortCode =
1034 EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1035 Ret = kEplObdAccessViolation;
1038 } else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
1041 bNmtCommand = *((BYTE *) pParam_p->m_pArg);
1042 // check value range
1043 switch ((tEplNmtCommand) bNmtCommand) {
1044 case kEplNmtCmdResetNode:
1045 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1048 (kEplNmtEventResetNode);
1052 case kEplNmtCmdResetCommunication:
1053 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1056 (kEplNmtEventResetCom);
1060 case kEplNmtCmdResetConfiguration:
1061 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1064 (kEplNmtEventResetConfig);
1068 case kEplNmtCmdSwReset:
1069 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1072 (kEplNmtEventSwReset);
1076 case kEplNmtCmdInvalidService:
1080 pParam_p->m_dwAbortCode =
1081 EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1082 Ret = kEplObdAccessViolation;
1097 //=========================================================================//
1099 // P R I V A T E F U N C T I O N S //
1101 //=========================================================================//
1103 //---------------------------------------------------------------------------
1105 // Function: EplApiProcessEvent
1107 // Description: processes events from event queue and forwards these to
1108 // the application's event callback function
1110 // Parameters: pEplEvent_p = pointer to event
1112 // Returns: tEplKernel = errorcode
1116 //---------------------------------------------------------------------------
1118 static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p)
1121 tEplEventError *pEventError;
1122 tEplApiEventType EventType;
1124 Ret = kEplSuccessful;
1127 switch (pEplEvent_p->m_EventType) {
1129 case kEplEventTypeError:
1131 pEventError = (tEplEventError *) pEplEvent_p->m_pArg;
1132 switch (pEventError->m_EventSource) {
1133 // treat the errors from the following sources as critical
1134 case kEplEventSourceEventk:
1135 case kEplEventSourceEventu:
1136 case kEplEventSourceDllk:
1138 EventType = kEplApiEventCriticalError;
1139 // halt the stack by entering NMT state Off
1142 (kEplNmtEventCriticalError);
1146 // the other errors are just warnings
1149 EventType = kEplApiEventWarning;
1154 // call user callback
1156 EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType,
1163 // discard error from callback function, because this could generate an endless loop
1164 Ret = kEplSuccessful;
1168 // at present, there are no other events for this module
1176 //---------------------------------------------------------------------------
1178 // Function: EplApiCbNmtStateChange
1180 // Description: callback function for NMT state changes
1182 // Parameters: NmtStateChange_p = NMT state change event
1184 // Returns: tEplKernel = error code
1189 //---------------------------------------------------------------------------
1191 static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
1194 tEplKernel Ret = kEplSuccessful;
1196 tEplApiEventArg EventArg;
1198 // save NMT state in OD
1199 bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState;
1200 Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
1201 if (Ret != kEplSuccessful) {
1204 // do work which must be done in that state
1205 switch (NmtStateChange_p.m_NewNmtState) {
1206 // EPL stack is not running
1210 // first init of the hardware
1211 case kEplNmtGsInitialising:
1213 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
1214 // configure SDO via UDP (i.e. bind it to the EPL ethernet interface)
1216 EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress,
1217 EPL_C_SDO_EPL_PORT);
1218 if (Ret != kEplSuccessful) {
1226 // init of the manufacturer-specific profile area and the
1227 // standardised device profile area
1228 case kEplNmtGsResetApplication:
1230 // reset application part of OD
1231 Ret = EplObdAccessOdPart(kEplObdPartApp,
1233 if (Ret != kEplSuccessful) {
1240 // init of the communication profile area
1241 case kEplNmtGsResetCommunication:
1243 // reset communication part of OD
1244 Ret = EplObdAccessOdPart(kEplObdPartGen,
1247 if (Ret != kEplSuccessful) {
1250 // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory
1251 Ret = EplApiUpdateObd();
1252 if (Ret != kEplSuccessful) {
1259 // build the configuration with infos from OD
1260 case kEplNmtGsResetConfiguration:
1263 Ret = EplApiUpdateDllConfig(TRUE);
1264 if (Ret != kEplSuccessful) {
1271 //-----------------------------------------------------------
1272 // CN part of the state machine
1274 // node liste for EPL-Frames and check timeout
1275 case kEplNmtCsNotActive:
1277 // indicate completion of reset in NMT_ResetCmd_U8
1278 bNmtState = (BYTE) kEplNmtCmdInvalidService;
1279 Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
1280 if (Ret != kEplSuccessful) {
1287 // node process only async frames
1288 case kEplNmtCsPreOperational1:
1293 // node process isochronus and asynchronus frames
1294 case kEplNmtCsPreOperational2:
1299 // node should be configured und application is ready
1300 case kEplNmtCsReadyToOperate:
1305 // normal work state
1306 case kEplNmtCsOperational:
1311 // node stopped by MN
1312 // -> only process asynchronus frames
1313 case kEplNmtCsStopped:
1319 // -> normal ethernet communication
1320 case kEplNmtCsBasicEthernet:
1325 //-----------------------------------------------------------
1326 // MN part of the state machine
1328 // node listens for EPL-Frames and check timeout
1329 case kEplNmtMsNotActive:
1334 // node processes only async frames
1335 case kEplNmtMsPreOperational1:
1340 // node processes isochronous and asynchronous frames
1341 case kEplNmtMsPreOperational2:
1346 // node should be configured und application is ready
1347 case kEplNmtMsReadyToOperate:
1352 // normal work state
1353 case kEplNmtMsOperational:
1359 // -> normal ethernet communication
1360 case kEplNmtMsBasicEthernet:
1368 ("EplApiCbNmtStateChange(): unhandled NMT state\n");
1372 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
1373 // forward event to Led module
1374 Ret = EplLeduCbNmtStateChange(NmtStateChange_p);
1375 if (Ret != kEplSuccessful) {
1380 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1381 // forward event to NmtMn module
1382 Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p);
1383 if (Ret != kEplSuccessful) {
1388 // call user callback
1389 EventArg.m_NmtStateChange = NmtStateChange_p;
1391 EplApiInstance_g.m_InitParam.
1392 m_pfnCbEvent(kEplApiEventNmtStateChange, &EventArg,
1393 EplApiInstance_g.m_InitParam.m_pEventUserArg);
1399 //---------------------------------------------------------------------------
1401 // Function: EplApiUpdateDllConfig
1403 // Description: update configuration of DLL
1405 // Parameters: fUpdateIdentity_p = TRUE, if identity must be updated
1407 // Returns: tEplKernel = error code
1412 //---------------------------------------------------------------------------
1414 static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
1416 tEplKernel Ret = kEplSuccessful;
1417 tEplDllConfigParam DllConfigParam;
1418 tEplDllIdentParam DllIdentParam;
1419 tEplObdSize ObdSize;
1424 EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
1425 DllConfigParam.m_uiNodeId = EplObdGetNodeId();
1427 // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
1430 EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize);
1431 if (Ret != kEplSuccessful) {
1434 // 0x1F82: NMT_FeatureFlags_U32
1437 EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags,
1439 if (Ret != kEplSuccessful) {
1442 // d.k. There is no dependance between FeatureFlags and async-only CN
1443 DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly;
1445 // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
1448 EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance,
1450 if (Ret != kEplSuccessful) {
1453 // 0x1F98: NMT_CycleTiming_REC
1454 // 0x1F98.1: IsochrTxMaxPayload_U16
1456 Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize);
1457 if (Ret != kEplSuccessful) {
1460 DllConfigParam.m_uiIsochrTxMaxPayload = wTemp;
1462 // 0x1F98.2: IsochrRxMaxPayload_U16
1464 Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize);
1465 if (Ret != kEplSuccessful) {
1468 DllConfigParam.m_uiIsochrRxMaxPayload = wTemp;
1470 // 0x1F98.3: PResMaxLatency_U32
1473 EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency,
1475 if (Ret != kEplSuccessful) {
1478 // 0x1F98.4: PReqActPayloadLimit_U16
1480 Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize);
1481 if (Ret != kEplSuccessful) {
1484 DllConfigParam.m_uiPreqActPayloadLimit = wTemp;
1486 // 0x1F98.5: PResActPayloadLimit_U16
1488 Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize);
1489 if (Ret != kEplSuccessful) {
1492 DllConfigParam.m_uiPresActPayloadLimit = wTemp;
1494 // 0x1F98.6: ASndMaxLatency_U32
1497 EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency,
1499 if (Ret != kEplSuccessful) {
1502 // 0x1F98.7: MultiplCycleCnt_U8
1504 Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize);
1505 if (Ret != kEplSuccessful) {
1508 DllConfigParam.m_uiMultiplCycleCnt = bTemp;
1510 // 0x1F98.8: AsyncMTU_U16
1512 Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize);
1513 if (Ret != kEplSuccessful) {
1516 DllConfigParam.m_uiAsyncMtu = wTemp;
1520 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1521 // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
1524 EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq,
1526 if (Ret != kEplSuccessful) {
1529 // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional)
1532 EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout,
1534 /* if(Ret != kEplSuccessful)
1540 DllConfigParam.m_uiSizeOfStruct = sizeof(DllConfigParam);
1541 Ret = EplDllkConfig(&DllConfigParam);
1542 if (Ret != kEplSuccessful) {
1546 if (fUpdateIdentity_p != FALSE) {
1547 // configure Identity
1548 EPL_MEMSET(&DllIdentParam, 0, sizeof(DllIdentParam));
1551 EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType,
1553 if (Ret != kEplSuccessful) {
1559 EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId,
1561 if (Ret != kEplSuccessful) {
1566 EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode,
1568 if (Ret != kEplSuccessful) {
1573 EplObdReadEntry(0x1018, 3,
1574 &DllIdentParam.m_dwRevisionNumber,
1576 if (Ret != kEplSuccessful) {
1581 EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber,
1583 if (Ret != kEplSuccessful) {
1587 DllIdentParam.m_dwIpAddress =
1588 EplApiInstance_g.m_InitParam.m_dwIpAddress;
1589 DllIdentParam.m_dwSubnetMask =
1590 EplApiInstance_g.m_InitParam.m_dwSubnetMask;
1591 EPL_MEMCPY(DllIdentParam.m_sHostname,
1592 EplApiInstance_g.m_InitParam.m_sHostname,
1593 sizeof(DllIdentParam.m_sHostname));
1597 EplObdReadEntry(0x1020, 1,
1598 &DllIdentParam.m_dwVerifyConfigurationDate,
1600 // ignore any error, because this object is optional
1604 EplObdReadEntry(0x1020, 2,
1605 &DllIdentParam.m_dwVerifyConfigurationTime,
1607 // ignore any error, because this object is optional
1609 // $$$ d.k.: fill rest of ident structure
1611 DllIdentParam.m_uiSizeOfStruct = sizeof(DllIdentParam);
1612 Ret = EplDllkSetIdentity(&DllIdentParam);
1613 if (Ret != kEplSuccessful) {
1622 //---------------------------------------------------------------------------
1624 // Function: EplApiUpdateObd
1626 // Description: update OD from init param
1628 // Parameters: (none)
1630 // Returns: tEplKernel = error code
1635 //---------------------------------------------------------------------------
1637 static tEplKernel PUBLIC EplApiUpdateObd(void)
1639 tEplKernel Ret = kEplSuccessful;
1643 // set node id in OD
1644 Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId, // node id
1645 kEplObdNodeIdHardware); // set by hardware
1646 if (Ret != kEplSuccessful) {
1650 if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1) {
1652 EplObdWriteEntry(0x1006, 0,
1653 &EplApiInstance_g.m_InitParam.m_dwCycleLen,
1655 /* if(Ret != kEplSuccessful)
1661 if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1) {
1663 EplObdWriteEntry(0x1C14, 0,
1664 &EplApiInstance_g.m_InitParam.
1665 m_dwLossOfFrameTolerance, 4);
1666 /* if(Ret != kEplSuccessful)
1671 // d.k. There is no dependance between FeatureFlags and async-only CN.
1672 if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1) {
1674 EplObdWriteEntry(0x1F82, 0,
1675 &EplApiInstance_g.m_InitParam.
1676 m_dwFeatureFlags, 4);
1677 /* if(Ret != kEplSuccessful)
1683 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
1684 Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
1685 /* if(Ret != kEplSuccessful)
1690 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
1691 Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
1692 /* if(Ret != kEplSuccessful)
1698 EplObdWriteEntry(0x1F98, 3,
1699 &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency,
1701 /* if(Ret != kEplSuccessful)
1706 if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
1707 EPL_C_DLL_ISOCHR_MAX_PAYL) {
1709 (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
1710 Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
1711 /* if(Ret != kEplSuccessful)
1717 if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
1718 EPL_C_DLL_ISOCHR_MAX_PAYL) {
1720 (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
1721 Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
1722 /* if(Ret != kEplSuccessful)
1729 EplObdWriteEntry(0x1F98, 6,
1730 &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency,
1732 /* if(Ret != kEplSuccessful)
1737 if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
1738 bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
1739 Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
1740 /* if(Ret != kEplSuccessful)
1746 if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
1747 EPL_C_DLL_MAX_ASYNC_MTU) {
1748 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
1749 Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
1750 /* if(Ret != kEplSuccessful)
1756 if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
1757 wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPrescaler;
1758 Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
1759 // ignore return code
1760 Ret = kEplSuccessful;
1762 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1763 if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1) {
1765 EplObdWriteEntry(0x1F8A, 1,
1766 &EplApiInstance_g.m_InitParam.
1767 m_dwWaitSocPreq, 4);
1768 /* if(Ret != kEplSuccessful)
1774 if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0)
1775 && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1)) {
1777 EplObdWriteEntry(0x1F8A, 2,
1778 &EplApiInstance_g.m_InitParam.
1779 m_dwAsyncSlotTimeout, 4);
1780 /* if(Ret != kEplSuccessful)
1787 // configure Identity
1788 if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1) {
1790 EplObdWriteEntry(0x1000, 0,
1791 &EplApiInstance_g.m_InitParam.
1793 /* if(Ret != kEplSuccessful)
1799 if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1) {
1801 EplObdWriteEntry(0x1018, 1,
1802 &EplApiInstance_g.m_InitParam.m_dwVendorId,
1804 /* if(Ret != kEplSuccessful)
1810 if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1) {
1812 EplObdWriteEntry(0x1018, 2,
1813 &EplApiInstance_g.m_InitParam.
1814 m_dwProductCode, 4);
1815 /* if(Ret != kEplSuccessful)
1821 if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1) {
1823 EplObdWriteEntry(0x1018, 3,
1824 &EplApiInstance_g.m_InitParam.
1825 m_dwRevisionNumber, 4);
1826 /* if(Ret != kEplSuccessful)
1832 if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1) {
1834 EplObdWriteEntry(0x1018, 4,
1835 &EplApiInstance_g.m_InitParam.
1836 m_dwSerialNumber, 4);
1837 /* if(Ret != kEplSuccessful)
1843 if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL) {
1844 // write Device Name (0x1008)
1846 EplObdWriteEntry(0x1008, 0,
1847 (void GENERIC *)EplApiInstance_g.
1848 m_InitParam.m_pszDevName,
1849 (tEplObdSize) strlen(EplApiInstance_g.
1852 /* if (Ret != kEplSuccessful)
1858 if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL) {
1859 // write Hardware version (0x1009)
1861 EplObdWriteEntry(0x1009, 0,
1862 (void GENERIC *)EplApiInstance_g.
1863 m_InitParam.m_pszHwVersion,
1864 (tEplObdSize) strlen(EplApiInstance_g.
1867 /* if (Ret != kEplSuccessful)
1873 if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL) {
1874 // write Software version (0x100A)
1876 EplObdWriteEntry(0x100A, 0,
1877 (void GENERIC *)EplApiInstance_g.
1878 m_InitParam.m_pszSwVersion,
1879 (tEplObdSize) strlen(EplApiInstance_g.
1882 /* if (Ret != kEplSuccessful)
1892 //---------------------------------------------------------------------------
1894 // Function: EplApiCbSdoCon
1896 // Description: callback function for SDO transfers
1898 // Parameters: pSdoComFinished_p = SDO parameter
1900 // Returns: tEplKernel = error code
1905 //---------------------------------------------------------------------------
1907 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1908 static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p)
1911 tEplApiEventArg EventArg;
1913 Ret = kEplSuccessful;
1915 // call user callback
1916 EventArg.m_Sdo = *pSdoComFinished_p;
1917 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo,
1928 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1930 //---------------------------------------------------------------------------
1932 // Function: EplApiCbNodeEvent
1934 // Description: callback function for node events
1936 // Parameters: uiNodeId_p = node ID of the CN
1937 // NodeEvent_p = event from the specified CN
1938 // NmtState_p = current NMT state of the CN
1939 // wErrorCode_p = EPL error code if NodeEvent_p==kEplNmtNodeEventError
1940 // fMandatory_p = flag if CN is mandatory
1942 // Returns: tEplKernel = error code
1947 //---------------------------------------------------------------------------
1949 static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
1950 tEplNmtNodeEvent NodeEvent_p,
1951 tEplNmtState NmtState_p,
1952 WORD wErrorCode_p, BOOL fMandatory_p)
1955 tEplApiEventArg EventArg;
1957 Ret = kEplSuccessful;
1959 // call user callback
1960 EventArg.m_Node.m_uiNodeId = uiNodeId_p;
1961 EventArg.m_Node.m_NodeEvent = NodeEvent_p;
1962 EventArg.m_Node.m_NmtState = NmtState_p;
1963 EventArg.m_Node.m_wErrorCode = wErrorCode_p;
1964 EventArg.m_Node.m_fMandatory = fMandatory_p;
1966 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode,
1976 //---------------------------------------------------------------------------
1978 // Function: EplApiCbBootEvent
1980 // Description: callback function for boot events
1982 // Parameters: BootEvent_p = event from the boot-up process
1983 // NmtState_p = current local NMT state
1984 // wErrorCode_p = EPL error code if BootEvent_p==kEplNmtBootEventError
1986 // Returns: tEplKernel = error code
1991 //---------------------------------------------------------------------------
1993 static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
1994 tEplNmtState NmtState_p,
1998 tEplApiEventArg EventArg;
2000 Ret = kEplSuccessful;
2002 // call user callback
2003 EventArg.m_Boot.m_BootEvent = BootEvent_p;
2004 EventArg.m_Boot.m_NmtState = NmtState_p;
2005 EventArg.m_Boot.m_wErrorCode = wErrorCode_p;
2007 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot,
2017 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
2019 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
2021 //---------------------------------------------------------------------------
2023 // Function: EplApiCbLedStateChange
2025 // Description: callback function for LED change events.
2027 // Parameters: LedType_p = type of LED
2028 // fOn_p = state of LED
2030 // Returns: tEplKernel = errorcode
2034 //---------------------------------------------------------------------------
2036 static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
2040 tEplApiEventArg EventArg;
2042 Ret = kEplSuccessful;
2044 // call user callback
2045 EventArg.m_Led.m_LedType = LedType_p;
2046 EventArg.m_Led.m_fOn = fOn_p;
2048 Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed,