aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/epl/EplDllkCal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/epl/EplDllkCal.c')
-rw-r--r--drivers/staging/epl/EplDllkCal.c1260
1 files changed, 1260 insertions, 0 deletions
diff --git a/drivers/staging/epl/EplDllkCal.c b/drivers/staging/epl/EplDllkCal.c
new file mode 100644
index 000000000000..359083ebe12d
--- /dev/null
+++ b/drivers/staging/epl/EplDllkCal.c
@@ -0,0 +1,1260 @@
+/****************************************************************************
+
+ (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+ www.systec-electronic.com
+
+ Project: openPOWERLINK
+
+ Description: source file for kernel DLL Communication Abstraction Layer 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: EplDllkCal.c,v $
+
+ $Author: D.Krueger $
+
+ $Revision: 1.7 $ $Date: 2008/11/13 17:13:09 $
+
+ $State: Exp $
+
+ Build Environment:
+ GCC V3.4
+
+ -------------------------------------------------------------------------
+
+ Revision History:
+
+ 2006/06/15 d.k.: start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "kernel/EplDllkCal.h"
+#include "kernel/EplDllk.h"
+#include "kernel/EplEventk.h"
+
+#include "EplDllCal.h"
+#ifndef EPL_NO_FIFO
+#include "SharedBuff.h"
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+/***************************************************************************/
+/* */
+/* */
+/* G L O B A L D E F I N I T I O N S */
+/* */
+/* */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+/***************************************************************************/
+/* */
+/* */
+/* C L A S S EplDllkCal */
+/* */
+/* */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+// //
+// P R I V A T E D E F I N I T I O N S //
+// //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define EPL_DLLKCAL_MAX_QUEUES 5 // CnGenReq, CnNmtReq, {MnGenReq, MnNmtReq}, MnIdentReq, MnStatusReq
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct {
+#ifndef EPL_NO_FIFO
+// tShbInstance m_ShbInstanceRx; // FIFO for Rx ASnd frames
+ tShbInstance m_ShbInstanceTxNmt; // FIFO for Tx frames with NMT request priority
+ tShbInstance m_ShbInstanceTxGen; // FIFO for Tx frames with generic priority
+#else
+ unsigned int m_uiFrameSizeNmt;
+ BYTE m_abFrameNmt[1500];
+ unsigned int m_uiFrameSizeGen;
+ BYTE m_abFrameGen[1500];
+#endif
+
+ tEplDllkCalStatistics m_Statistics;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+ // IdentRequest queue with CN node IDs
+ unsigned int m_auiQueueIdentReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty
+ unsigned int m_uiWriteIdentReq;
+ unsigned int m_uiReadIdentReq;
+
+ // StatusRequest queue with CN node IDs
+ unsigned int m_auiQueueStatusReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty
+ unsigned int m_uiWriteStatusReq;
+ unsigned int m_uiReadStatusReq;
+
+ unsigned int m_auiQueueCnRequests[254 * 2];
+ // first 254 entries represent the generic requests of the corresponding node
+ // second 254 entries represent the NMT requests of the corresponding node
+ unsigned int m_uiNextQueueCnRequest;
+ unsigned int m_uiNextRequestQueue;
+#endif
+
+} tEplDllkCalInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+// if no dynamic memory allocation shall be used
+// define structures statically
+static tEplDllkCalInstance EplDllkCalInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+//=========================================================================//
+// //
+// P U B L I C F U N C T I O N S //
+// //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAddInstance()
+//
+// Description: add and initialize new instance of DLL CAL module
+//
+// Parameters: none
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAddInstance()
+{
+ tEplKernel Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+ tShbError ShbError;
+ unsigned int fShbNewCreated;
+
+/* ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_RX, EPL_DLLCAL_BUFFER_ID_RX,
+ &EplDllkCalInstance_g.m_ShbInstanceRx, &fShbNewCreated);
+ // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
+
+ if (ShbError != kShbOk)
+ {
+ Ret = kEplNoResource;
+ }
+*/
+ ShbError =
+ ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_NMT,
+ EPL_DLLCAL_BUFFER_ID_TX_NMT,
+ &EplDllkCalInstance_g.m_ShbInstanceTxNmt,
+ &fShbNewCreated);
+ // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
+
+ if (ShbError != kShbOk) {
+ Ret = kEplNoResource;
+ }
+
+/* ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxNmt, EplDllkCalTxNmtSignalHandler, kShbPriorityNormal);
+ // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
+
+ if (ShbError != kShbOk)
+ {
+ Ret = kEplNoResource;
+ }
+*/
+ ShbError =
+ ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_GEN,
+ EPL_DLLCAL_BUFFER_ID_TX_GEN,
+ &EplDllkCalInstance_g.m_ShbInstanceTxGen,
+ &fShbNewCreated);
+ // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
+
+ if (ShbError != kShbOk) {
+ Ret = kEplNoResource;
+ }
+
+/* ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxGen, EplDllkCalTxGenSignalHandler, kShbPriorityNormal);
+ // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
+
+ if (ShbError != kShbOk)
+ {
+ Ret = kEplNoResource;
+ }
+*/
+#else
+ EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+ EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+#endif
+
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalDelInstance()
+//
+// Description: deletes instance of DLL CAL module
+//
+// Parameters: none
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalDelInstance()
+{
+ tEplKernel Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+ tShbError ShbError;
+
+/* ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceRx);
+ if (ShbError != kShbOk)
+ {
+ Ret = kEplNoResource;
+ }
+ EplDllkCalInstance_g.m_ShbInstanceRx = NULL;
+*/
+ ShbError = ShbCirReleaseBuffer(EplDllkCalInstance_g.m_ShbInstanceTxNmt);
+ if (ShbError != kShbOk) {
+ Ret = kEplNoResource;
+ }
+ EplDllkCalInstance_g.m_ShbInstanceTxNmt = NULL;
+
+ ShbError = ShbCirReleaseBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen);
+ if (ShbError != kShbOk) {
+ Ret = kEplNoResource;
+ }
+ EplDllkCalInstance_g.m_ShbInstanceTxGen = NULL;
+
+#else
+ EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+ EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+#endif
+
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalProcess
+//
+// Description: process the passed configuration
+//
+// Parameters: pEvent_p = event containing configuration options
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+
+ switch (pEvent_p->m_EventType) {
+ case kEplEventTypeDllkServFilter:
+ {
+ tEplDllCalAsndServiceIdFilter *pServFilter;
+
+ pServFilter =
+ (tEplDllCalAsndServiceIdFilter *) pEvent_p->m_pArg;
+ Ret =
+ EplDllkSetAsndServiceIdFilter(pServFilter->
+ m_ServiceId,
+ pServFilter->
+ m_Filter);
+ break;
+ }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+ case kEplEventTypeDllkIssueReq:
+ {
+ tEplDllCalIssueRequest *pIssueReq;
+
+ pIssueReq = (tEplDllCalIssueRequest *) pEvent_p->m_pArg;
+ Ret =
+ EplDllkCalIssueRequest(pIssueReq->m_Service,
+ pIssueReq->m_uiNodeId,
+ pIssueReq->m_bSoaFlag1);
+ break;
+ }
+
+ case kEplEventTypeDllkAddNode:
+ {
+ tEplDllNodeInfo *pNodeInfo;
+
+ pNodeInfo = (tEplDllNodeInfo *) pEvent_p->m_pArg;
+ Ret = EplDllkAddNode(pNodeInfo);
+ break;
+ }
+
+ case kEplEventTypeDllkDelNode:
+ {
+ unsigned int *puiNodeId;
+
+ puiNodeId = (unsigned int *)pEvent_p->m_pArg;
+ Ret = EplDllkDeleteNode(*puiNodeId);
+ break;
+ }
+
+ case kEplEventTypeDllkSoftDelNode:
+ {
+ unsigned int *puiNodeId;
+
+ puiNodeId = (unsigned int *)pEvent_p->m_pArg;
+ Ret = EplDllkSoftDeleteNode(*puiNodeId);
+ break;
+ }
+#endif
+
+ case kEplEventTypeDllkIdentity:
+ {
+ tEplDllIdentParam *pIdentParam;
+
+ pIdentParam = (tEplDllIdentParam *) pEvent_p->m_pArg;
+ if (pIdentParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) {
+ pIdentParam->m_uiSizeOfStruct =
+ pEvent_p->m_uiSize;
+ }
+ Ret = EplDllkSetIdentity(pIdentParam);
+ break;
+ }
+
+ case kEplEventTypeDllkConfig:
+ {
+ tEplDllConfigParam *pConfigParam;
+
+ pConfigParam = (tEplDllConfigParam *) pEvent_p->m_pArg;
+ if (pConfigParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) {
+ pConfigParam->m_uiSizeOfStruct =
+ pEvent_p->m_uiSize;
+ }
+ Ret = EplDllkConfig(pConfigParam);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+//Exit:
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncGetTxCount()
+//
+// Description: returns count of Tx frames of FIFO with highest priority
+//
+// Parameters: none
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p,
+ unsigned int *puiCount_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+ tShbError ShbError;
+ unsigned long ulFrameCount;
+
+ // get frame count of Tx FIFO with NMT request priority
+ ShbError =
+ ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
+ &ulFrameCount);
+ // returns kShbOk, kShbInvalidArg
+
+ // error handling
+ if (ShbError != kShbOk) {
+ Ret = kEplNoResource;
+ goto Exit;
+ }
+
+ if (ulFrameCount >
+ EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt) {
+ EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt =
+ ulFrameCount;
+ }
+
+ if (ulFrameCount != 0) { // NMT requests are in queue
+ *pPriority_p = kEplDllAsyncReqPrioNmt;
+ *puiCount_p = (unsigned int)ulFrameCount;
+ goto Exit;
+ }
+ // get frame count of Tx FIFO with generic priority
+ ShbError =
+ ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen,
+ &ulFrameCount);
+ // returns kShbOk, kShbInvalidArg
+
+ // error handling
+ if (ShbError != kShbOk) {
+ Ret = kEplNoResource;
+ goto Exit;
+ }
+
+ if (ulFrameCount >
+ EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen) {
+ EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen =
+ ulFrameCount;
+ }
+
+ *pPriority_p = kEplDllAsyncReqPrioGeneric;
+ *puiCount_p = (unsigned int)ulFrameCount;
+
+ Exit:
+#else
+ if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) {
+ *pPriority_p = kEplDllAsyncReqPrioNmt;
+ *puiCount_p = 1;
+ } else if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) {
+ *pPriority_p = kEplDllAsyncReqPrioGeneric;
+ *puiCount_p = 1;
+ } else {
+ *pPriority_p = kEplDllAsyncReqPrioGeneric;
+ *puiCount_p = 0;
+ }
+#endif
+
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncGetTxFrame()
+//
+// Description: returns Tx frames from FIFO with specified priority
+//
+// Parameters: pFrame_p = IN: pointer to buffer
+// puiFrameSize_p = IN: max size of buffer
+// OUT: actual size of frame
+// Priority_p = IN: priority
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
+ unsigned int *puiFrameSize_p,
+ tEplDllAsyncReqPriority Priority_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+ tShbError ShbError;
+ unsigned long ulFrameSize;
+
+ switch (Priority_p) {
+ case kEplDllAsyncReqPrioNmt: // NMT request priority
+ ShbError =
+ ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
+ (BYTE *) pFrame_p, *puiFrameSize_p,
+ &ulFrameSize);
+ // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
+ break;
+
+ default: // generic priority
+ ShbError =
+ ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxGen,
+ (BYTE *) pFrame_p, *puiFrameSize_p,
+ &ulFrameSize);
+ // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
+ break;
+
+ }
+
+ // error handling
+ if (ShbError != kShbOk) {
+ if (ShbError == kShbNoReadableData) {
+ Ret = kEplDllAsyncTxBufferEmpty;
+ } else { // other error
+ Ret = kEplNoResource;
+ }
+ goto Exit;
+ }
+
+ *puiFrameSize_p = (unsigned int)ulFrameSize;
+
+ Exit:
+#else
+ switch (Priority_p) {
+ case kEplDllAsyncReqPrioNmt: // NMT request priority
+ *puiFrameSize_p =
+ min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeNmt);
+ EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameNmt,
+ *puiFrameSize_p);
+ EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+ break;
+
+ default: // generic priority
+ *puiFrameSize_p =
+ min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeGen);
+ EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameGen,
+ *puiFrameSize_p);
+ EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+ break;
+ }
+
+#endif
+
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncFrameReceived()
+//
+// Description: passes ASnd frame to receive FIFO.
+// It will be called only for frames with registered AsndServiceIds.
+//
+// Parameters: none
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+ tEplEvent Event;
+
+ Event.m_EventSink = kEplEventSinkDlluCal;
+ Event.m_EventType = kEplEventTypeAsndRx;
+ Event.m_pArg = pFrameInfo_p->m_pFrame;
+ Event.m_uiSize = pFrameInfo_p->m_uiFrameSize;
+ // pass NetTime of frame to userspace
+ Event.m_NetTime = pFrameInfo_p->m_NetTime;
+
+ Ret = EplEventkPost(&Event);
+ if (Ret != kEplSuccessful) {
+ EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount++;
+ } else {
+ EplDllkCalInstance_g.m_Statistics.m_ulMaxRxFrameCount++;
+ }
+
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncSend()
+//
+// Description: puts the given frame into the transmit FIFO with the specified
+// priority.
+//
+// Parameters: pFrameInfo_p = frame info structure
+// Priority_p = priority
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p,
+ tEplDllAsyncReqPriority Priority_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+ tEplEvent Event;
+#ifndef EPL_NO_FIFO
+ tShbError ShbError;
+
+ switch (Priority_p) {
+ case kEplDllAsyncReqPrioNmt: // NMT request priority
+ ShbError =
+ ShbCirWriteDataBlock(EplDllkCalInstance_g.
+ m_ShbInstanceTxNmt,
+ pFrameInfo_p->m_pFrame,
+ pFrameInfo_p->m_uiFrameSize);
+ // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
+ break;
+
+ default: // generic priority
+ ShbError =
+ ShbCirWriteDataBlock(EplDllkCalInstance_g.
+ m_ShbInstanceTxGen,
+ pFrameInfo_p->m_pFrame,
+ pFrameInfo_p->m_uiFrameSize);
+ // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
+ break;
+
+ }
+
+ // error handling
+ switch (ShbError) {
+ case kShbOk:
+ break;
+
+ case kShbExceedDataSizeLimit:
+ Ret = kEplDllAsyncTxBufferFull;
+ break;
+
+ case kShbBufferFull:
+ Ret = kEplDllAsyncTxBufferFull;
+ break;
+
+ case kShbInvalidArg:
+ default:
+ Ret = kEplNoResource;
+ break;
+ }
+
+#else
+
+ switch (Priority_p) {
+ case kEplDllAsyncReqPrioNmt: // NMT request priority
+ if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0) {
+ EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt,
+ pFrameInfo_p->m_pFrame,
+ pFrameInfo_p->m_uiFrameSize);
+ EplDllkCalInstance_g.m_uiFrameSizeNmt =
+ pFrameInfo_p->m_uiFrameSize;
+ } else {
+ Ret = kEplDllAsyncTxBufferFull;
+ goto Exit;
+ }
+ break;
+
+ default: // generic priority
+ if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0) {
+ EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen,
+ pFrameInfo_p->m_pFrame,
+ pFrameInfo_p->m_uiFrameSize);
+ EplDllkCalInstance_g.m_uiFrameSizeGen =
+ pFrameInfo_p->m_uiFrameSize;
+ } else {
+ Ret = kEplDllAsyncTxBufferFull;
+ goto Exit;
+ }
+ break;
+ }
+
+#endif
+
+ // post event to DLL
+ Event.m_EventSink = kEplEventSinkDllk;
+ Event.m_EventType = kEplEventTypeDllkFillTx;
+ EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+ Event.m_pArg = &Priority_p;
+ Event.m_uiSize = sizeof(Priority_p);
+ Ret = EplEventkPost(&Event);
+
+#ifdef EPL_NO_FIFO
+ Exit:
+#endif
+
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncClearBuffer()
+//
+// Description: clears the transmit buffer
+//
+// Parameters: (none)
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncClearBuffer(void)
+{
+ tEplKernel Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+ tShbError ShbError;
+
+ ShbError =
+ ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxNmt, 1000,
+ NULL);
+ ShbError =
+ ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen, 1000,
+ NULL);
+
+#else
+ EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+ EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+#endif
+
+// EPL_MEMSET(&EplDllkCalInstance_g.m_Statistics, 0, sizeof (tEplDllkCalStatistics));
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncClearQueues()
+//
+// Description: clears the transmit buffer
+//
+// Parameters: (none)
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+tEplKernel EplDllkCalAsyncClearQueues(void)
+{
+ tEplKernel Ret = kEplSuccessful;
+
+ // clear MN asynchronous queues
+ EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
+ EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
+ EplDllkCalInstance_g.m_uiReadIdentReq = 0;
+ EplDllkCalInstance_g.m_uiWriteIdentReq = 0;
+ EplDllkCalInstance_g.m_uiReadStatusReq = 0;
+ EplDllkCalInstance_g.m_uiWriteStatusReq = 0;
+
+ return Ret;
+}
+#endif
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalGetStatistics()
+//
+// Description: returns statistics of the asynchronous queues.
+//
+// Parameters: ppStatistics = statistics structure
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
+{
+ tEplKernel Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+ tShbError ShbError;
+
+ ShbError =
+ ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
+ &EplDllkCalInstance_g.m_Statistics.
+ m_ulCurTxFrameCountNmt);
+ ShbError =
+ ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen,
+ &EplDllkCalInstance_g.m_Statistics.
+ m_ulCurTxFrameCountGen);
+// ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceRx, &EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount);
+
+#else
+ if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) {
+ EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 1;
+ } else {
+ EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 0;
+ }
+ if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) {
+ EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 1;
+ } else {
+ EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 0;
+ }
+#endif
+
+ *ppStatistics = &EplDllkCalInstance_g.m_Statistics;
+ return Ret;
+}
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalIssueRequest()
+//
+// Description: issues a StatusRequest or a IdentRequest to the specified node.
+//
+// Parameters: Service_p = request service ID
+// uiNodeId_p = node ID
+// bSoaFlag1_p = flag1 for this node (transmit in SoA and PReq)
+// If 0xFF this flag is ignored.
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
+ unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+
+ if (bSoaFlag1_p != 0xFF) {
+ Ret = EplDllkSetFlag1OfNode(uiNodeId_p, bSoaFlag1_p);
+ if (Ret != kEplSuccessful) {
+ goto Exit;
+ }
+ }
+ // add node to appropriate request queue
+ switch (Service_p) {
+ case kEplDllReqServiceIdent:
+ {
+ if (((EplDllkCalInstance_g.m_uiWriteIdentReq +
+ 1) %
+ tabentries(EplDllkCalInstance_g.
+ m_auiQueueIdentReq))
+ == EplDllkCalInstance_g.m_uiReadIdentReq) { // queue is full
+ Ret = kEplDllAsyncTxBufferFull;
+ goto Exit;
+ }
+ EplDllkCalInstance_g.
+ m_auiQueueIdentReq[EplDllkCalInstance_g.
+ m_uiWriteIdentReq] = uiNodeId_p;
+ EplDllkCalInstance_g.m_uiWriteIdentReq =
+ (EplDllkCalInstance_g.m_uiWriteIdentReq +
+ 1) %
+ tabentries(EplDllkCalInstance_g.m_auiQueueIdentReq);
+ break;
+ }
+
+ case kEplDllReqServiceStatus:
+ {
+ if (((EplDllkCalInstance_g.m_uiWriteStatusReq +
+ 1) %
+ tabentries(EplDllkCalInstance_g.
+ m_auiQueueStatusReq))
+ == EplDllkCalInstance_g.m_uiReadStatusReq) { // queue is full
+ Ret = kEplDllAsyncTxBufferFull;
+ goto Exit;
+ }
+ EplDllkCalInstance_g.
+ m_auiQueueStatusReq[EplDllkCalInstance_g.
+ m_uiWriteStatusReq] =
+ uiNodeId_p;
+ EplDllkCalInstance_g.m_uiWriteStatusReq =
+ (EplDllkCalInstance_g.m_uiWriteStatusReq +
+ 1) %
+ tabentries(EplDllkCalInstance_g.
+ m_auiQueueStatusReq);
+ break;
+ }
+
+ default:
+ {
+ Ret = kEplDllInvalidParam;
+ goto Exit;
+ }
+ }
+
+ Exit:
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncGetSoaRequest()
+//
+// Description: returns next request for SoA. This function is called by DLLk module.
+//
+// Parameters: pReqServiceId_p = pointer to request service ID
+// IN: available request for MN NMT or generic request queue (Flag2.PR)
+// or kEplDllReqServiceNo if queues are empty
+// OUT: next request
+// puiNodeId_p = OUT: pointer to node ID of next request
+// = EPL_C_ADR_INVALID, if request is self addressed
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p,
+ unsigned int *puiNodeId_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+ unsigned int uiCount;
+
+// *pReqServiceId_p = kEplDllReqServiceNo;
+
+ for (uiCount = EPL_DLLKCAL_MAX_QUEUES; uiCount > 0; uiCount--) {
+ switch (EplDllkCalInstance_g.m_uiNextRequestQueue) {
+ case 0:
+ { // CnGenReq
+ for (;
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest <
+ (tabentries
+ (EplDllkCalInstance_g.
+ m_auiQueueCnRequests) / 2);
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest++) {
+ if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) { // non empty queue found
+ // remove one request from queue
+ EplDllkCalInstance_g.
+ m_auiQueueCnRequests
+ [EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest]--;
+ *puiNodeId_p =
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest + 1;
+ *pReqServiceId_p =
+ kEplDllReqServiceUnspecified;
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest++;
+ if (EplDllkCalInstance_g.m_uiNextQueueCnRequest >= (tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) { // last node reached
+ // continue with CnNmtReq queue at next SoA
+ EplDllkCalInstance_g.
+ m_uiNextRequestQueue
+ = 1;
+ }
+ goto Exit;
+ }
+ }
+ // all CnGenReq queues are empty -> continue with CnNmtReq queue
+ EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
+ break;
+ }
+
+ case 1:
+ { // CnNmtReq
+ for (;
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest <
+ tabentries(EplDllkCalInstance_g.
+ m_auiQueueCnRequests);
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest++) {
+ if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) { // non empty queue found
+ // remove one request from queue
+ EplDllkCalInstance_g.
+ m_auiQueueCnRequests
+ [EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest]--;
+ *puiNodeId_p =
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest + 1 -
+ (tabentries
+ (EplDllkCalInstance_g.
+ m_auiQueueCnRequests) /
+ 2);
+ *pReqServiceId_p =
+ kEplDllReqServiceNmtRequest;
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest++;
+ if (EplDllkCalInstance_g.m_uiNextQueueCnRequest > tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests)) { // last node reached
+ // restart CnGenReq queue
+ EplDllkCalInstance_g.
+ m_uiNextQueueCnRequest
+ = 0;
+ // continue with MnGenReq queue at next SoA
+ EplDllkCalInstance_g.
+ m_uiNextRequestQueue
+ = 2;
+ }
+ goto Exit;
+ }
+ }
+ // restart CnGenReq queue
+ EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
+ // all CnNmtReq queues are empty -> continue with MnGenReq queue
+ EplDllkCalInstance_g.m_uiNextRequestQueue = 2;
+ break;
+ }
+
+ case 2:
+ { // MnNmtReq and MnGenReq
+ // next queue will be MnIdentReq queue
+ EplDllkCalInstance_g.m_uiNextRequestQueue = 3;
+ if (*pReqServiceId_p != kEplDllReqServiceNo) {
+ *puiNodeId_p = EPL_C_ADR_INVALID; // DLLk must exchange this with the actual node ID
+ goto Exit;
+ }
+ break;
+ }
+
+ case 3:
+ { // MnIdentReq
+ // next queue will be MnStatusReq queue
+ EplDllkCalInstance_g.m_uiNextRequestQueue = 4;
+ if (EplDllkCalInstance_g.m_uiReadIdentReq != EplDllkCalInstance_g.m_uiWriteIdentReq) { // queue is not empty
+ *puiNodeId_p =
+ EplDllkCalInstance_g.
+ m_auiQueueIdentReq
+ [EplDllkCalInstance_g.
+ m_uiReadIdentReq];
+ EplDllkCalInstance_g.m_uiReadIdentReq =
+ (EplDllkCalInstance_g.
+ m_uiReadIdentReq +
+ 1) %
+ tabentries(EplDllkCalInstance_g.
+ m_auiQueueIdentReq);
+ *pReqServiceId_p =
+ kEplDllReqServiceIdent;
+ goto Exit;
+ }
+ break;
+ }
+
+ case 4:
+ { // MnStatusReq
+ // next queue will be CnGenReq queue
+ EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
+ if (EplDllkCalInstance_g.m_uiReadStatusReq != EplDllkCalInstance_g.m_uiWriteStatusReq) { // queue is not empty
+ *puiNodeId_p =
+ EplDllkCalInstance_g.
+ m_auiQueueStatusReq
+ [EplDllkCalInstance_g.
+ m_uiReadStatusReq];
+ EplDllkCalInstance_g.m_uiReadStatusReq =
+ (EplDllkCalInstance_g.
+ m_uiReadStatusReq +
+ 1) %
+ tabentries(EplDllkCalInstance_g.
+ m_auiQueueStatusReq);
+ *pReqServiceId_p =
+ kEplDllReqServiceStatus;
+ goto Exit;
+ }
+ break;
+ }
+
+ }
+ }
+
+ Exit:
+ return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function: EplDllkCalAsyncSetPendingRequests()
+//
+// Description: sets the pending asynchronous frame requests of the specified node.
+// This will add the node to the asynchronous request scheduler.
+//
+// Parameters: uiNodeId_p = node ID
+// AsyncReqPrio_p = asynchronous request priority
+// uiCount_p = count of asynchronous frames
+//
+// Returns: tEplKernel = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p,
+ tEplDllAsyncReqPriority
+ AsyncReqPrio_p,
+ unsigned int uiCount_p)
+{
+ tEplKernel Ret = kEplSuccessful;
+
+ // add node to appropriate request queue
+ switch (AsyncReqPrio_p) {
+ case kEplDllAsyncReqPrioNmt:
+ {
+ uiNodeId_p--;
+ if (uiNodeId_p >=
+ (tabentries
+ (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) {
+ Ret = kEplDllInvalidParam;
+ goto Exit;
+ }
+ uiNodeId_p +=
+ tabentries(EplDllkCalInstance_g.
+ m_auiQueueCnRequests) / 2;
+ EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] =
+ uiCount_p;
+ break;
+ }
+
+ default:
+ {
+ uiNodeId_p--;
+ if (uiNodeId_p >=
+ (tabentries
+ (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) {
+ Ret = kEplDllInvalidParam;
+ goto Exit;
+ }
+ EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] =
+ uiCount_p;
+ break;
+ }
+ }
+
+ Exit:
+ return Ret;
+}
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//=========================================================================//
+// //
+// P R I V A T E F U N C T I O N S //
+// //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// Callback handler for new data signaling
+//---------------------------------------------------------------------------
+
+#ifndef EPL_NO_FIFO
+/*static void EplDllkCalTxNmtSignalHandler (
+ tShbInstance pShbRxInstance_p,
+ unsigned long ulDataSize_p)
+{
+tEplKernel Ret = kEplSuccessful;
+tEplEvent Event;
+tEplDllAsyncReqPriority Priority;
+#ifndef EPL_NO_FIFO
+tShbError ShbError;
+unsigned long ulBlockCount;
+
+ ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulBlockCount);
+ if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
+ {
+ EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulBlockCount;
+ }
+
+#endif
+
+ // post event to DLL
+ Priority = kEplDllAsyncReqPrioNmt;
+ Event.m_EventSink = kEplEventSinkDllk;
+ Event.m_EventType = kEplEventTypeDllkFillTx;
+ EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+ Event.m_pArg = &Priority;
+ Event.m_uiSize = sizeof(Priority);
+ Ret = EplEventkPost(&Event);
+
+}
+
+static void EplDllkCalTxGenSignalHandler (
+ tShbInstance pShbRxInstance_p,
+ unsigned long ulDataSize_p)
+{
+tEplKernel Ret = kEplSuccessful;
+tEplEvent Event;
+tEplDllAsyncReqPriority Priority;
+#ifndef EPL_NO_FIFO
+tShbError ShbError;
+unsigned long ulBlockCount;
+
+ ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulBlockCount);
+ if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
+ {
+ EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulBlockCount;
+ }
+
+#endif
+
+ // post event to DLL
+ Priority = kEplDllAsyncReqPrioGeneric;
+ Event.m_EventSink = kEplEventSinkDllk;
+ Event.m_EventType = kEplEventTypeDllkFillTx;
+ EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+ Event.m_pArg = &Priority;
+ Event.m_uiSize = sizeof(Priority);
+ Ret = EplEventkPost(&Event);
+
+}
+*/
+#endif
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+// EOF