833dfbe746
It's a start, still a mess... Cc: Daniel Krueger <daniel.krueger@systec-electronic.com> Cc: Ronald Sieber <Ronald.Sieber@systec-electronic.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2061 lines
57 KiB
C
2061 lines
57 KiB
C
/****************************************************************************
|
|
|
|
(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
|