diff options
Diffstat (limited to 'drivers/staging/epl/EplApiGeneric.c')
-rw-r--r-- | drivers/staging/epl/EplApiGeneric.c | 2093 |
1 files changed, 2093 insertions, 0 deletions
diff --git a/drivers/staging/epl/EplApiGeneric.c b/drivers/staging/epl/EplApiGeneric.c new file mode 100644 index 0000000..61ed18e --- /dev/null +++ b/drivers/staging/epl/EplApiGeneric.c @@ -0,0 +1,2093 @@ +/**************************************************************************** + + (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 + www.systec-electronic.com + + Project: openPOWERLINK + + Description: source file for generic EPL API module + + License: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of SYSTEC electronic GmbH nor the names of its + contributors may be used to endorse or promote products derived + from this software without prior written permission. For written + permission, please contact info@systec-electronic.com. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Severability Clause: + + If a provision of this License is or becomes illegal, invalid or + unenforceable in any jurisdiction, that shall not affect: + 1. the validity or enforceability in that jurisdiction of any other + provision of this License; or + 2. the validity or enforceability in other jurisdictions of that or + any other provision of this License. + + ------------------------------------------------------------------------- + + $RCSfile: EplApiGeneric.c,v $ + + $Author: D.Krueger $ + + $Revision: 1.21 $ $Date: 2008/11/21 09:00:38 $ + + $State: Exp $ + + Build Environment: + GCC V3.4 + + ------------------------------------------------------------------------- + + Revision History: + + 2006/09/05 d.k.: start of the implementation, version 1.00 + +****************************************************************************/ + +#include "Epl.h" +#include "kernel/EplDllk.h" +#include "kernel/EplErrorHandlerk.h" +#include "kernel/EplEventk.h" +#include "kernel/EplNmtk.h" +#include "kernel/EplObdk.h" +#include "kernel/EplTimerk.h" +#include "kernel/EplDllkCal.h" +#include "kernel/EplPdokCal.h" +#include "user/EplDlluCal.h" +#include "user/EplLedu.h" +#include "user/EplNmtCnu.h" +#include "user/EplNmtMnu.h" +#include "user/EplSdoComu.h" +#include "user/EplIdentu.h" +#include "user/EplStatusu.h" + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) +#include "kernel/EplPdok.h" +#endif + +#include "SharedBuff.h" + + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0) +#error "EPL API layer needs EPL module OBDK!" +#endif + + +/***************************************************************************/ +/* */ +/* */ +/* G L O B A L D E F I N I T I O N S */ +/* */ +/* */ +/***************************************************************************/ + +//--------------------------------------------------------------------------- +// const defines +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// local types +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// modul globale vars +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// local function prototypes +//--------------------------------------------------------------------------- + + +/***************************************************************************/ +/* */ +/* */ +/* C L A S S EplApi */ +/* */ +/* */ +/***************************************************************************/ +// +// Description: +// +// +/***************************************************************************/ + + +//=========================================================================// +// // +// P R I V A T E D E F I N I T I O N S // +// // +//=========================================================================// + +//--------------------------------------------------------------------------- +// const defines +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +// local types +//--------------------------------------------------------------------------- + +typedef struct +{ + tEplApiInitParam m_InitParam; + +} tEplApiInstance; + +//--------------------------------------------------------------------------- +// local vars +//--------------------------------------------------------------------------- + +static tEplApiInstance EplApiInstance_g; + + +//--------------------------------------------------------------------------- +// local function prototypes +//--------------------------------------------------------------------------- + +// NMT state change event callback function +static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p); + +// update DLL configuration from OD +static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p); + +// update OD from init param +static tEplKernel PUBLIC EplApiUpdateObd(void); + +// process events from user event queue +static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent* pEplEvent_p); + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) +// callback function of SDO module +static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished* pSdoComFinished_p); +#endif + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) +// callback functions of NmtMnu module +static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p, + tEplNmtNodeEvent NodeEvent_p, + tEplNmtState NmtState_p, + WORD wErrorCode_p, + BOOL fMandatory_p); + +static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p, + tEplNmtState NmtState_p, + WORD wErrorCode_p); +#endif + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) +// callback function of Ledu module +static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p, + BOOL fOn_p); +#endif + +// OD initialization function (implemented in Objdict.c) +tEplKernel PUBLIC EplObdInitRam (tEplObdInitParam MEM* pInitParam_p); + + +//=========================================================================// +// // +// P U B L I C F U N C T I O N S // +// // +//=========================================================================// + +//--------------------------------------------------------------------------- +// +// Function: EplApiInitialize() +// +// Description: add and initialize new instance of EPL stack. +// After return from this function the application must start +// the NMT state machine via +// EplApiExecNmtCommand(kEplNmtEventSwReset) +// and thereby the whole EPL stack :-) +// +// Parameters: pInitParam_p = initialisation parameters +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p) +{ +tEplKernel Ret = kEplSuccessful; +tEplObdInitParam ObdInitParam; +tEplDllkInitParam DllkInitParam; +#ifndef EPL_NO_FIFO + tShbError ShbError; +#endif + + // reset instance structure + EPL_MEMSET(&EplApiInstance_g, 0, sizeof (EplApiInstance_g)); + + EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p, min(sizeof (tEplApiInitParam), pInitParam_p->m_uiSizeOfStruct)); + + // check event callback function pointer + if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL) + { // application must always have an event callback function + Ret = kEplApiInvalidParam; + goto Exit; + } + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) + // init OD +// FIXME +// Ret = EplObdInitRam(&ObdInitParam); +// if (Ret != kEplSuccessful) +// { +// goto Exit; +// } + + // initialize EplObd module + Ret = EplObdInit(&ObdInitParam); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + +#ifndef EPL_NO_FIFO + ShbError = ShbInit(); + if (ShbError != kShbOk) + { + Ret = kEplNoResource; + goto Exit; + } +#endif + + // initialize EplEventk module + Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // initialize EplEventu module + Ret = EplEventuInit(EplApiProcessEvent); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // init EplTimerk module + Ret = EplTimerkInit(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // initialize EplNmtk module before DLL +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) + Ret = EplNmtkInit(); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + + // initialize EplDllk module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) + EPL_MEMCPY(DllkInitParam.m_be_abSrcMac, EplApiInstance_g.m_InitParam.m_abMacAddress, 6); + Ret = EplDllkAddInstance(&DllkInitParam); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // initialize EplErrorHandlerk module + Ret = EplErrorHandlerkInit(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // initialize EplDllkCal module + Ret = EplDllkCalAddInstance(); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + + // initialize EplDlluCal module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) + Ret = EplDlluCalAddInstance(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + +#endif + + // initialize EplPdok module +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) + Ret = EplPdokAddInstance(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + Ret = EplPdokCalAddInstance(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + +#endif + + // initialize EplNmtCnu module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) + Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + + // initialize EplNmtu module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) + Ret = EplNmtuInit(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // register NMT event callback function + Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + // initialize EplNmtMnu module + Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // initialize EplIdentu module + Ret = EplIdentuInit(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // initialize EplStatusu module + Ret = EplStatusuInit(); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + + // initialize EplLedu module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) + Ret = EplLeduInit(EplApiCbLedStateChange); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + + // init SDO module +#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \ + (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)) + // init sdo command layer + Ret = EplSdoComInit(); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + + // the application must start NMT state machine + // via EplApiExecNmtCommand(kEplNmtEventSwReset) + // and thereby the whole EPL stack + +Exit: + return Ret; +} + +//--------------------------------------------------------------------------- +// +// Function: EplApiShutdown() +// +// Description: deletes an instance of EPL stack +// +// Parameters: (none) +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiShutdown(void) +{ +tEplKernel Ret = kEplSuccessful; + + // $$$ d.k.: check if NMT state is NMT_GS_OFF + + // $$$ d.k.: maybe delete event queues at first, but this implies that + // no other module must not use the event queues for communication + // during shutdown. + + // delete instance for all modules + + // deinitialize EplSdoCom module +#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \ + (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)) + Ret = EplSdoComDelInstance(); +// PRINTF1("EplSdoComDelInstance(): 0x%X\n", Ret); +#endif + + // deinitialize EplLedu module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) + Ret = EplLeduDelInstance(); +// PRINTF1("EplLeduDelInstance(): 0x%X\n", Ret); +#endif + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + // deinitialize EplNmtMnu module + Ret = EplNmtMnuDelInstance(); +// PRINTF1("EplNmtMnuDelInstance(): 0x%X\n", Ret); + + // deinitialize EplIdentu module + Ret = EplIdentuDelInstance(); +// PRINTF1("EplIdentuDelInstance(): 0x%X\n", Ret); + + // deinitialize EplStatusu module + Ret = EplStatusuDelInstance(); +// PRINTF1("EplStatusuDelInstance(): 0x%X\n", Ret); +#endif + + // deinitialize EplNmtCnu module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0) + Ret = EplNmtCnuDelInstance(); +// PRINTF1("EplNmtCnuDelInstance(): 0x%X\n", Ret); +#endif + + // deinitialize EplNmtu module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) + Ret = EplNmtuDelInstance(); +// PRINTF1("EplNmtuDelInstance(): 0x%X\n", Ret); +#endif + + // deinitialize EplDlluCal module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0) + Ret = EplDlluCalDelInstance(); +// PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret); + +#endif + + // deinitialize EplEventu module + Ret = EplEventuDelInstance(); +// PRINTF1("EplEventuDelInstance(): 0x%X\n", Ret); + + // deinitialize EplNmtk module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0) + Ret = EplNmtkDelInstance(); +// PRINTF1("EplNmtkDelInstance(): 0x%X\n", Ret); +#endif + + // deinitialize EplDllk module +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0) + Ret = EplDllkDelInstance(); +// PRINTF1("EplDllkDelInstance(): 0x%X\n", Ret); + + // deinitialize EplDllkCal module + Ret = EplDllkCalDelInstance(); +// PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret); +#endif + + // deinitialize EplEventk module + Ret = EplEventkDelInstance(); +// PRINTF1("EplEventkDelInstance(): 0x%X\n", Ret); + + // deinitialize EplTimerk module + Ret = EplTimerkDelInstance(); +// PRINTF1("EplTimerkDelInstance(): 0x%X\n", Ret); + +#ifndef EPL_NO_FIFO + ShbExit(); +#endif + + return Ret; +} + + +//---------------------------------------------------------------------------- +// Function: EplApiExecNmtCommand() +// +// Description: executes a NMT command, i.e. post the NMT command/event to the +// NMTk module. NMT commands which are not appropriate in the current +// NMT state are silently ignored. Please keep in mind that the +// NMT state may change until the NMT command is actually executed. +// +// Parameters: NmtEvent_p = NMT command/event +// +// Returns: tEplKernel = error code +// +// State: +//---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p) +{ +tEplKernel Ret = kEplSuccessful; + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) + Ret = EplNmtuNmtEvent(NmtEvent_p); +#endif + + return Ret; +} + + +//---------------------------------------------------------------------------- +// Function: EplApiLinkObject() +// +// Description: Function maps array of application variables onto specified object in OD +// +// Parameters: uiObjIndex_p = Function maps variables for this object index +// pVar_p = Pointer to data memory area for the specified object +// puiVarEntries_p = IN: pointer to number of entries to map +// OUT: pointer to number of actually used entries +// pEntrySize_p = IN: pointer to size of one entry; +// if size is zero, the actual size will be read from OD +// OUT: pointer to entire size of all entries mapped +// uiFirstSubindex_p = This is the first subindex to be mapped. +// +// Returns: tEplKernel = error code +// +// State: +//---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiLinkObject( unsigned int uiObjIndex_p, + void* pVar_p, + unsigned int* puiVarEntries_p, + tEplObdSize* pEntrySize_p, + unsigned int uiFirstSubindex_p) +{ +BYTE bVarEntries; +BYTE bIndexEntries; +BYTE MEM* pbData; +unsigned int uiSubindex; +tEplVarParam VarParam; +tEplObdSize EntrySize; +tEplObdSize UsedSize; + +tEplKernel RetCode = kEplSuccessful; + + if ((pVar_p == NULL) + || (puiVarEntries_p == NULL) + || (*puiVarEntries_p == 0) + || (pEntrySize_p == NULL)) + { + RetCode = kEplApiInvalidParam; + goto Exit; + } + + pbData = (BYTE MEM*) pVar_p; + bVarEntries = (BYTE) *puiVarEntries_p; + UsedSize = 0; + + // init VarParam structure with default values + VarParam.m_uiIndex = uiObjIndex_p; + VarParam.m_ValidFlag = kVarValidAll; + + if (uiFirstSubindex_p != 0) + { // check if object exists by reading subindex 0x00, + // because user wants to link a variable to a subindex unequal 0x00 + // read number of entries + EntrySize = (tEplObdSize) sizeof(bIndexEntries); + RetCode = EplObdReadEntry ( + uiObjIndex_p, + 0x00, + (void GENERIC*) &bIndexEntries, + &EntrySize ); + + if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00) ) + { + // Object doesn't exist or invalid entry number + RetCode = kEplObdIndexNotExist; + goto Exit; + } + } + else + { // user wants to link a variable to subindex 0x00 + // that's OK + bIndexEntries = 0; + } + + // Correct number of entries if number read from OD is greater + // than the specified number. + // This is done, so that we do not set more entries than subindexes the + // object actually has. + if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) && + (bVarEntries != 0x00) ) + { + bIndexEntries = (BYTE) (bVarEntries + uiFirstSubindex_p - 1); + } + + // map entries + for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries; uiSubindex++) + { + // if passed entry size is 0, then get size from OD + if (*pEntrySize_p == 0x00) + { + // read entry size + EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex); + + if (EntrySize == 0x00) + { + // invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty) + RetCode = kEplObdSubindexNotExist; + break; + } + } + else + { // use passed entry size + EntrySize = *pEntrySize_p; + } + + VarParam.m_uiSubindex = uiSubindex; + + // set pointer to user var + VarParam.m_Size = EntrySize; + VarParam.m_pData = pbData; + + UsedSize += EntrySize; + pbData += EntrySize; + + RetCode = EplObdDefineVar(&VarParam); + if (RetCode != kEplSuccessful) + { + break; + } + } + + // set number of mapped entries and entry size + *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1); + *pEntrySize_p = UsedSize; + + +Exit: + + return (RetCode); + +} + + +// ---------------------------------------------------------------------------- +// +// Function: EplApiReadObject() +// +// Description: reads the specified entry from the OD of the specified node. +// If this node is a remote node, it performs a SDO transfer, which +// means this function returns kEplApiTaskDeferred and the application +// is informed via the event callback function when the task is completed. +// +// Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access) +// uiNodeId_p = IN: node ID (0 = itself) +// uiIndex_p = IN: index of object in OD +// uiSubindex_p = IN: sub-index of object in OD +// pDstData_le_p = OUT: pointer to data in little endian +// puiSize_p = INOUT: pointer to size of data +// SdoType_p = IN: type of SDO transfer +// pUserArg_p = IN: user-definable argument pointer, +// which will be passed to the event callback function +// +// Return: tEplKernel = error code +// +// ---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiReadObject( + tEplSdoComConHdl* pSdoComConHdl_p, + unsigned int uiNodeId_p, + unsigned int uiIndex_p, + unsigned int uiSubindex_p, + void* pDstData_le_p, + unsigned int* puiSize_p, + tEplSdoType SdoType_p, + void* pUserArg_p) +{ +tEplKernel Ret = kEplSuccessful; + + if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL) || (*puiSize_p == 0)) + { + Ret = kEplApiInvalidParam; + goto Exit; + } + + if (uiNodeId_p == 0 + || uiNodeId_p == EplObdGetNodeId()) + { // local OD access can be performed + tEplObdSize ObdSize; + + ObdSize = (tEplObdSize) *puiSize_p; + Ret = EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p, &ObdSize); + *puiSize_p = (unsigned int) ObdSize; + } + else + { // perform SDO transfer +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) + tEplSdoComTransParamByIndex TransParamByIndex; +// tEplSdoComConHdl SdoComConHdl; + + // check if application provides space for handle + if (pSdoComConHdl_p == NULL) + { + Ret = kEplApiInvalidParam; + goto Exit; +// pSdoComConHdl_p = &SdoComConHdl; + } + + // init command layer connection + Ret = EplSdoComDefineCon(pSdoComConHdl_p, + uiNodeId_p, // target node id + SdoType_p); // SDO type + if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) + { + goto Exit; + } + TransParamByIndex.m_pData = pDstData_le_p; + TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead; + TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p; + TransParamByIndex.m_uiDataSize = *puiSize_p; + TransParamByIndex.m_uiIndex = uiIndex_p; + TransParamByIndex.m_uiSubindex = uiSubindex_p; + TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon; + TransParamByIndex.m_pUserArg = pUserArg_p; + + Ret = EplSdoComInitTransferByIndex(&TransParamByIndex); + if (Ret != kEplSuccessful) + { + goto Exit; + } + Ret = kEplApiTaskDeferred; + +#else + Ret = kEplApiInvalidParam; +#endif + } + +Exit: + return Ret; +} + + +// ---------------------------------------------------------------------------- +// +// Function: EplApiWriteObject() +// +// Description: writes the specified entry to the OD of the specified node. +// If this node is a remote node, it performs a SDO transfer, which +// means this function returns kEplApiTaskDeferred and the application +// is informed via the event callback function when the task is completed. +// +// Parameters: pSdoComConHdl_p = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access) +// uiNodeId_p = IN: node ID (0 = itself) +// uiIndex_p = IN: index of object in OD +// uiSubindex_p = IN: sub-index of object in OD +// pSrcData_le_p = IN: pointer to data in little endian +// uiSize_p = IN: size of data in bytes +// SdoType_p = IN: type of SDO transfer +// pUserArg_p = IN: user-definable argument pointer, +// which will be passed to the event callback function +// +// Return: tEplKernel = error code +// +// ---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiWriteObject( + tEplSdoComConHdl* pSdoComConHdl_p, + unsigned int uiNodeId_p, + unsigned int uiIndex_p, + unsigned int uiSubindex_p, + void* pSrcData_le_p, + unsigned int uiSize_p, + tEplSdoType SdoType_p, + void* pUserArg_p) +{ +tEplKernel Ret = kEplSuccessful; + + if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0)) + { + Ret = kEplApiInvalidParam; + goto Exit; + } + + if (uiNodeId_p == 0 + || uiNodeId_p == EplObdGetNodeId()) + { // local OD access can be performed + + Ret = EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p, pSrcData_le_p, uiSize_p); + } + else + { // perform SDO transfer +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) + tEplSdoComTransParamByIndex TransParamByIndex; +// tEplSdoComConHdl SdoComConHdl; + + // check if application provides space for handle + if (pSdoComConHdl_p == NULL) + { + Ret = kEplApiInvalidParam; + goto Exit; +// pSdoComConHdl_p = &SdoComConHdl; + } + + // d.k.: How to recycle command layer connection? + // Try to redefine it, which will return kEplSdoComHandleExists + // and the existing command layer handle. + // If the returned handle is busy, EplSdoComInitTransferByIndex() + // will return with error. + // $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and + // Configuration Manager, are trying to communicate with the very same node. + // possible solution: disallow communication by application if Configuration Manager is busy + + // init command layer connection + Ret = EplSdoComDefineCon(pSdoComConHdl_p, + uiNodeId_p, // target node id + SdoType_p); // SDO type + if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) + { + goto Exit; + } + TransParamByIndex.m_pData = pSrcData_le_p; + TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite; + TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p; + TransParamByIndex.m_uiDataSize = uiSize_p; + TransParamByIndex.m_uiIndex = uiIndex_p; + TransParamByIndex.m_uiSubindex = uiSubindex_p; + TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon; + TransParamByIndex.m_pUserArg = pUserArg_p; + + Ret = EplSdoComInitTransferByIndex(&TransParamByIndex); + if (Ret != kEplSuccessful) + { + goto Exit; + } + Ret = kEplApiTaskDeferred; + +#else + Ret = kEplApiInvalidParam; +#endif + } + +Exit: + return Ret; +} + + +// ---------------------------------------------------------------------------- +// +// Function: EplApiFreeSdoChannel() +// +// Description: frees the specified SDO channel. +// This function must be called after each call to EplApiReadObject()/EplApiWriteObject() +// which returns kEplApiTaskDeferred and the application +// is informed via the event callback function when the task is completed. +// +// Parameters: SdoComConHdl_p = IN: SDO connection handle +// +// Return: tEplKernel = error code +// +// ---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiFreeSdoChannel( + tEplSdoComConHdl SdoComConHdl_p) +{ +tEplKernel Ret = kEplSuccessful; + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) + + // init command layer connection + Ret = EplSdoComUndefineCon(SdoComConHdl_p); + +#else + Ret = kEplApiInvalidParam; +#endif + + return Ret; +} + + +// ---------------------------------------------------------------------------- +// +// Function: EplApiReadLocalObject() +// +// Description: reads the specified entry from the local OD. +// +// Parameters: uiIndex_p = IN: index of object in OD +// uiSubindex_p = IN: sub-index of object in OD +// pDstData_p = OUT: pointer to data in platform byte order +// puiSize_p = INOUT: pointer to size of data +// +// Return: tEplKernel = error code +// +// ---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiReadLocalObject( + unsigned int uiIndex_p, + unsigned int uiSubindex_p, + void* pDstData_p, + unsigned int* puiSize_p) +{ +tEplKernel Ret = kEplSuccessful; +tEplObdSize ObdSize; + + ObdSize = (tEplObdSize) *puiSize_p; + Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize); + *puiSize_p = (unsigned int) ObdSize; + + return Ret; +} + + +// ---------------------------------------------------------------------------- +// +// Function: EplApiWriteLocalObject() +// +// Description: writes the specified entry to the local OD. +// +// Parameters: uiIndex_p = IN: index of object in OD +// uiSubindex_p = IN: sub-index of object in OD +// pSrcData_p = IN: pointer to data in platform byte order +// uiSize_p = IN: size of data in bytes +// +// Return: tEplKernel = error code +// +// ---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiWriteLocalObject( + unsigned int uiIndex_p, + unsigned int uiSubindex_p, + void* pSrcData_p, + unsigned int uiSize_p) +{ +tEplKernel Ret = kEplSuccessful; + + Ret = EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p, (tEplObdSize) uiSize_p); + + return Ret; +} + + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) +// ---------------------------------------------------------------------------- +// +// Function: EplApiMnTriggerStateChange() +// +// Description: triggers the specified node command for the specified node. +// +// Parameters: uiNodeId_p = node ID for which the node command will be executed +// NodeCommand_p = node command +// +// Return: tEplKernel = error code +// +// ---------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p, + tEplNmtNodeCommand NodeCommand_p) +{ +tEplKernel Ret = kEplSuccessful; + + Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p); + + return Ret; +} + +#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + +//--------------------------------------------------------------------------- +// +// Function: EplApiCbObdAccess +// +// Description: callback function for OD accesses +// +// Parameters: pParam_p = OBD parameter +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM* pParam_p) +{ +tEplKernel Ret = kEplSuccessful; + +#if (EPL_API_OBD_FORWARD_EVENT != FALSE) +tEplApiEventArg EventArg; + + // call user callback + // must be disabled for EplApiLinuxKernel.c, because of reentrancy problem + // for local OD access. This is not so bad as user callback function in + // application does not use OD callbacks at the moment. + EventArg.m_ObdCbParam = *pParam_p; + Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess, + &EventArg, + EplApiInstance_g.m_InitParam.m_pEventUserArg); +#endif + + switch (pParam_p->m_uiIndex) + { + //case 0x1006: // NMT_CycleLen_U32 (valid on reset) + case 0x1C14: // DLL_LossOfFrameTolerance_U32 + //case 0x1F98: // NMT_CycleTiming_REC (valid on reset) + { + if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) + { + // update DLL configuration + Ret = EplApiUpdateDllConfig(FALSE); + } + break; + } + + case 0x1020: // CFM_VerifyConfiguration_REC.ConfId_U32 != 0 + { + if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite) + && (pParam_p->m_uiSubIndex == 3) + && (*((DWORD*)pParam_p->m_pArg) != 0)) + { + DWORD dwVerifyConfInvalid = 0; + // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0 + Ret = EplObdWriteEntry(0x1020, 4, &dwVerifyConfInvalid, 4); + // ignore any error because this objekt is optional + Ret = kEplSuccessful; + } + break; + } + + case 0x1F9E: // NMT_ResetCmd_U8 + { + if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) + { + BYTE bNmtCommand; + + bNmtCommand = *((BYTE *) pParam_p->m_pArg); + // check value range + switch ((tEplNmtCommand)bNmtCommand) + { + case kEplNmtCmdResetNode: + case kEplNmtCmdResetCommunication: + case kEplNmtCmdResetConfiguration: + case kEplNmtCmdSwReset: + case kEplNmtCmdInvalidService: + // valid command identifier specified + break; + + default: + pParam_p->m_dwAbortCode = EPL_SDOAC_VALUE_RANGE_EXCEEDED; + Ret = kEplObdAccessViolation; + break; + } + } + else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) + { + BYTE bNmtCommand; + + bNmtCommand = *((BYTE *) pParam_p->m_pArg); + // check value range + switch ((tEplNmtCommand)bNmtCommand) + { + case kEplNmtCmdResetNode: +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) + Ret = EplNmtuNmtEvent(kEplNmtEventResetNode); +#endif + break; + + case kEplNmtCmdResetCommunication: +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) + Ret = EplNmtuNmtEvent(kEplNmtEventResetCom); +#endif + break; + + case kEplNmtCmdResetConfiguration: +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) + Ret = EplNmtuNmtEvent(kEplNmtEventResetConfig); +#endif + break; + + case kEplNmtCmdSwReset: +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0) + Ret = EplNmtuNmtEvent(kEplNmtEventSwReset); +#endif + break; + + case kEplNmtCmdInvalidService: + break; + + default: + pParam_p->m_dwAbortCode = EPL_SDOAC_VALUE_RANGE_EXCEEDED; + Ret = kEplObdAccessViolation; + break; + } + } + break; + } + + default: + break; + } + +//Exit: + return Ret; +} + + + +//=========================================================================// +// // +// P R I V A T E F U N C T I O N S // +// // +//=========================================================================// + + +//--------------------------------------------------------------------------- +// +// Function: EplApiProcessEvent +// +// Description: processes events from event queue and forwards these to +// the application's event callback function +// +// Parameters: pEplEvent_p = pointer to event +// +// Returns: tEplKernel = errorcode +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplApiProcessEvent( + tEplEvent* pEplEvent_p) +{ +tEplKernel Ret; +tEplEventError* pEventError; +tEplApiEventType EventType; + + Ret = kEplSuccessful; + + // process event + switch(pEplEvent_p->m_EventType) + { + // error event + case kEplEventTypeError: + { + pEventError = (tEplEventError*) pEplEvent_p->m_pArg; + switch (pEventError->m_EventSource) + { + // treat the errors from the following sources as critical + case kEplEventSourceEventk: + case kEplEventSourceEventu: + case kEplEventSourceDllk: + { + EventType = kEplApiEventCriticalError; + // halt the stack by entering NMT state Off + Ret = EplNmtuNmtEvent(kEplNmtEventCriticalError); + break; + } + + // the other errors are just warnings + default: + { + EventType = kEplApiEventWarning; + break; + } + } + + // call user callback + Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType, (tEplApiEventArg*) pEventError, EplApiInstance_g.m_InitParam.m_pEventUserArg); + // discard error from callback function, because this could generate an endless loop + Ret = kEplSuccessful; + break; + } + + // at present, there are no other events for this module + default: + break; + } + + return Ret; +} + + +//--------------------------------------------------------------------------- +// +// Function: EplApiCbNmtStateChange +// +// Description: callback function for NMT state changes +// +// Parameters: NmtStateChange_p = NMT state change event +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p) +{ +tEplKernel Ret = kEplSuccessful; +BYTE bNmtState; +tEplApiEventArg EventArg; + + // save NMT state in OD + bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState; + Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // do work which must be done in that state + switch (NmtStateChange_p.m_NewNmtState) + { + // EPL stack is not running + case kEplNmtGsOff: + break; + + // first init of the hardware + case kEplNmtGsInitialising: +#if 0 +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0) + // configure SDO via UDP (i.e. bind it to the EPL ethernet interface) + Ret = EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress, EPL_C_SDO_EPL_PORT); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif +#endif + + break; + + // init of the manufacturer-specific profile area and the + // standardised device profile area + case kEplNmtGsResetApplication: + { + // reset application part of OD + Ret = EplObdAccessOdPart( + kEplObdPartApp, + kEplObdDirLoad); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + break; + } + + // init of the communication profile area + case kEplNmtGsResetCommunication: + { + // reset communication part of OD + Ret = EplObdAccessOdPart( + kEplObdPartGen, + kEplObdDirLoad); + + if (Ret != kEplSuccessful) + { + goto Exit; + } + + // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory + Ret = EplApiUpdateObd(); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + break; + } + + // build the configuration with infos from OD + case kEplNmtGsResetConfiguration: + { + + Ret = EplApiUpdateDllConfig(TRUE); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + break; + } + + //----------------------------------------------------------- + // CN part of the state machine + + // node liste for EPL-Frames and check timeout + case kEplNmtCsNotActive: + { + // indicate completion of reset in NMT_ResetCmd_U8 + bNmtState = (BYTE) kEplNmtCmdInvalidService; + Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1); + if (Ret != kEplSuccessful) + { + goto Exit; + } + + break; + } + + // node process only async frames + case kEplNmtCsPreOperational1: + { + break; + } + + // node process isochronus and asynchronus frames + case kEplNmtCsPreOperational2: + { + break; + } + + // node should be configured und application is ready + case kEplNmtCsReadyToOperate: + { + break; + } + + // normal work state + case kEplNmtCsOperational: + { + break; + } + + // node stopped by MN + // -> only process asynchronus frames + case kEplNmtCsStopped: + { + break; + } + + // no EPL cycle + // -> normal ethernet communication + case kEplNmtCsBasicEthernet: + { + break; + } + + //----------------------------------------------------------- + // MN part of the state machine + + // node listens for EPL-Frames and check timeout + case kEplNmtMsNotActive: + { + break; + } + + // node processes only async frames + case kEplNmtMsPreOperational1: + { + break; + } + + // node processes isochronous and asynchronous frames + case kEplNmtMsPreOperational2: + { + break; + } + + // node should be configured und application is ready + case kEplNmtMsReadyToOperate: + { + break; + } + + // normal work state + case kEplNmtMsOperational: + { + break; + } + + // no EPL cycle + // -> normal ethernet communication + case kEplNmtMsBasicEthernet: + { + break; + } + + default: + { + TRACE0("EplApiCbNmtStateChange(): unhandled NMT state\n"); + } + } + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) + // forward event to Led module + Ret = EplLeduCbNmtStateChange(NmtStateChange_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + // forward event to NmtMn module + Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p); + if (Ret != kEplSuccessful) + { + goto Exit; + } +#endif + + // call user callback + EventArg.m_NmtStateChange = NmtStateChange_p; + Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNmtStateChange, + &EventArg, + EplApiInstance_g.m_InitParam.m_pEventUserArg); + +Exit: + return Ret; +} + +//--------------------------------------------------------------------------- +// +// Function: EplApiUpdateDllConfig +// +// Description: update configuration of DLL +// +// Parameters: fUpdateIdentity_p = TRUE, if identity must be updated +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p) +{ +tEplKernel Ret = kEplSuccessful; +tEplDllConfigParam DllConfigParam; +tEplDllIdentParam DllIdentParam; +tEplObdSize ObdSize; +WORD wTemp; +BYTE bTemp; + + // configure Dll + EPL_MEMSET(&DllConfigParam, 0, sizeof (DllConfigParam)); + DllConfigParam.m_uiNodeId = EplObdGetNodeId(); + + // Cycle Length (0x1006: NMT_CycleLen_U32) in [us] + ObdSize = 4; + Ret = EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // 0x1F82: NMT_FeatureFlags_U32 + ObdSize = 4; + Ret = EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // d.k. There is no dependance between FeatureFlags and async-only CN + DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly; + + // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns] + ObdSize = 4; + Ret = EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // 0x1F98: NMT_CycleTiming_REC + // 0x1F98.1: IsochrTxMaxPayload_U16 + ObdSize = 2; + Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + DllConfigParam.m_uiIsochrTxMaxPayload = wTemp; + + // 0x1F98.2: IsochrRxMaxPayload_U16 + ObdSize = 2; + Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + DllConfigParam.m_uiIsochrRxMaxPayload = wTemp; + + // 0x1F98.3: PResMaxLatency_U32 + ObdSize = 4; + Ret = EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // 0x1F98.4: PReqActPayloadLimit_U16 + ObdSize = 2; + Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + DllConfigParam.m_uiPreqActPayloadLimit = wTemp; + + // 0x1F98.5: PResActPayloadLimit_U16 + ObdSize = 2; + Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + DllConfigParam.m_uiPresActPayloadLimit = wTemp; + + // 0x1F98.6: ASndMaxLatency_U32 + ObdSize = 4; + Ret = EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // 0x1F98.7: MultiplCycleCnt_U8 + ObdSize = 1; + Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + DllConfigParam.m_uiMultiplCycleCnt = bTemp; + + // 0x1F98.8: AsyncMTU_U16 + ObdSize = 2; + Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + DllConfigParam.m_uiAsyncMtu = wTemp; + + // $$$ Prescaler + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + // 0x1F8A.1: WaitSoCPReq_U32 in [ns] + ObdSize = 4; + Ret = EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional) + ObdSize = 4; + Ret = EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout, &ObdSize); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ +#endif + + DllConfigParam.m_uiSizeOfStruct = sizeof (DllConfigParam); + Ret = EplDllkConfig(&DllConfigParam); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + if (fUpdateIdentity_p != FALSE) + { + // configure Identity + EPL_MEMSET(&DllIdentParam, 0, sizeof (DllIdentParam)); + ObdSize = 4; + Ret = EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + ObdSize = 4; + Ret = EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + ObdSize = 4; + Ret = EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + ObdSize = 4; + Ret = EplObdReadEntry(0x1018, 3, &DllIdentParam.m_dwRevisionNumber, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + ObdSize = 4; + Ret = EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber, &ObdSize); + if(Ret != kEplSuccessful) + { + goto Exit; + } + + DllIdentParam.m_dwIpAddress = EplApiInstance_g.m_InitParam.m_dwIpAddress; + DllIdentParam.m_dwSubnetMask = EplApiInstance_g.m_InitParam.m_dwSubnetMask; + EPL_MEMCPY(DllIdentParam.m_sHostname, EplApiInstance_g.m_InitParam.m_sHostname, sizeof (DllIdentParam.m_sHostname)); + + ObdSize = 4; + Ret = EplObdReadEntry(0x1020, 1, &DllIdentParam.m_dwVerifyConfigurationDate, &ObdSize); + // ignore any error, because this object is optional + + ObdSize = 4; + Ret = EplObdReadEntry(0x1020, 2, &DllIdentParam.m_dwVerifyConfigurationTime, &ObdSize); + // ignore any error, because this object is optional + + // $$$ d.k.: fill rest of ident structure + + DllIdentParam.m_uiSizeOfStruct = sizeof (DllIdentParam); + Ret = EplDllkSetIdentity(&DllIdentParam); + if(Ret != kEplSuccessful) + { + goto Exit; + } + } + +Exit: + return Ret; +} + +//--------------------------------------------------------------------------- +// +// Function: EplApiUpdateObd +// +// Description: update OD from init param +// +// Parameters: (none) +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplApiUpdateObd(void) +{ +tEplKernel Ret = kEplSuccessful; +WORD wTemp; +BYTE bTemp; + + // set node id in OD + Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId, // node id + kEplObdNodeIdHardware); // set by hardware + if(Ret != kEplSuccessful) + { + goto Exit; + } + + if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1) + { + Ret = EplObdWriteEntry(0x1006, 0, &EplApiInstance_g.m_InitParam.m_dwCycleLen, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1) + { + Ret = EplObdWriteEntry(0x1C14, 0, &EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance, 4); + /* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + // d.k. There is no dependance between FeatureFlags and async-only CN. + if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1) + { + Ret = EplObdWriteEntry(0x1F82, 0, &EplApiInstance_g.m_InitParam.m_dwFeatureFlags, 4); + /* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload; + Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + + wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload; + Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + + Ret = EplObdWriteEntry(0x1F98, 3, &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + + if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <= EPL_C_DLL_ISOCHR_MAX_PAYL) + { + wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit; + Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <= EPL_C_DLL_ISOCHR_MAX_PAYL) + { + wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit; + Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + Ret = EplObdWriteEntry(0x1F98, 6, &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + + if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) + { + bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt; + Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <= EPL_C_DLL_MAX_ASYNC_MTU) + { + wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu; + Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) + { + wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPrescaler; + Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2); + // ignore return code + Ret = kEplSuccessful; + } + +#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1) + { + Ret = EplObdWriteEntry(0x1F8A, 1, &EplApiInstance_g.m_InitParam.m_dwWaitSocPreq, 4); + /* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0) && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1)) + { + Ret = EplObdWriteEntry(0x1F8A, 2, &EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout, 4); + /* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } +#endif + + // configure Identity + if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1) + { + Ret = EplObdWriteEntry(0x1000, 0, &EplApiInstance_g.m_InitParam.m_dwDeviceType, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1) + { + Ret = EplObdWriteEntry(0x1018, 1, &EplApiInstance_g.m_InitParam.m_dwVendorId, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1) + { + Ret = EplObdWriteEntry(0x1018, 2, &EplApiInstance_g.m_InitParam.m_dwProductCode, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1) + { + Ret = EplObdWriteEntry(0x1018, 3, &EplApiInstance_g.m_InitParam.m_dwRevisionNumber, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1) + { + Ret = EplObdWriteEntry(0x1018, 4, &EplApiInstance_g.m_InitParam.m_dwSerialNumber, 4); +/* if(Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL) + { + // write Device Name (0x1008) + Ret = EplObdWriteEntry ( + 0x1008, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszDevName, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszDevName)); +/* if (Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL) + { + // write Hardware version (0x1009) + Ret = EplObdWriteEntry ( + 0x1009, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszHwVersion, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszHwVersion)); +/* if (Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + + if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL) + { + // write Software version (0x100A) + Ret = EplObdWriteEntry ( + 0x100A, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszSwVersion, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszSwVersion)); +/* if (Ret != kEplSuccessful) + { + goto Exit; + }*/ + } + +Exit: + return Ret; +} + + +//--------------------------------------------------------------------------- +// +// Function: EplApiCbSdoCon +// +// Description: callback function for SDO transfers +// +// Parameters: pSdoComFinished_p = SDO parameter +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) +static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished* pSdoComFinished_p) +{ +tEplKernel Ret; +tEplApiEventArg EventArg; + + Ret = kEplSuccessful; + + // call user callback + EventArg.m_Sdo = *pSdoComFinished_p; + Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo, + &EventArg, + EplApiInstance_g.m_InitParam.m_pEventUserArg); + + return Ret; + +} +#endif + + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + +//--------------------------------------------------------------------------- +// +// Function: EplApiCbNodeEvent +// +// Description: callback function for node events +// +// Parameters: uiNodeId_p = node ID of the CN +// NodeEvent_p = event from the specified CN +// NmtState_p = current NMT state of the CN +// wErrorCode_p = EPL error code if NodeEvent_p==kEplNmtNodeEventError +// fMandatory_p = flag if CN is mandatory +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p, + tEplNmtNodeEvent NodeEvent_p, + tEplNmtState NmtState_p, + WORD wErrorCode_p, + BOOL fMandatory_p) +{ +tEplKernel Ret; +tEplApiEventArg EventArg; + + Ret = kEplSuccessful; + + // call user callback + EventArg.m_Node.m_uiNodeId = uiNodeId_p; + EventArg.m_Node.m_NodeEvent = NodeEvent_p; + EventArg.m_Node.m_NmtState = NmtState_p; + EventArg.m_Node.m_wErrorCode = wErrorCode_p; + EventArg.m_Node.m_fMandatory = fMandatory_p; + + Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode, + &EventArg, + EplApiInstance_g.m_InitParam.m_pEventUserArg); + + return Ret; + +} + + +//--------------------------------------------------------------------------- +// +// Function: EplApiCbBootEvent +// +// Description: callback function for boot events +// +// Parameters: BootEvent_p = event from the boot-up process +// NmtState_p = current local NMT state +// wErrorCode_p = EPL error code if BootEvent_p==kEplNmtBootEventError +// +// Returns: tEplKernel = error code +// +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p, + tEplNmtState NmtState_p, + WORD wErrorCode_p) +{ +tEplKernel Ret; +tEplApiEventArg EventArg; + + Ret = kEplSuccessful; + + // call user callback + EventArg.m_Boot.m_BootEvent = BootEvent_p; + EventArg.m_Boot.m_NmtState = NmtState_p; + EventArg.m_Boot.m_wErrorCode = wErrorCode_p; + + Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot, + &EventArg, + EplApiInstance_g.m_InitParam.m_pEventUserArg); + + return Ret; + +} + +#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0) + + +#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0) + +//--------------------------------------------------------------------------- +// +// Function: EplApiCbLedStateChange +// +// Description: callback function for LED change events. +// +// Parameters: LedType_p = type of LED +// fOn_p = state of LED +// +// Returns: tEplKernel = errorcode +// +// State: +// +//--------------------------------------------------------------------------- + +static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p, + BOOL fOn_p) +{ +tEplKernel Ret; +tEplApiEventArg EventArg; + + Ret = kEplSuccessful; + + // call user callback + EventArg.m_Led.m_LedType = LedType_p; + EventArg.m_Led.m_fOn = fOn_p; + + Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed, + &EventArg, + EplApiInstance_g.m_InitParam.m_pEventUserArg); + + return Ret; + +} + +#endif + + +// EOF + |