diff options
Diffstat (limited to 'drivers/staging/epl/EplDllkCal.c')
-rw-r--r-- | drivers/staging/epl/EplDllkCal.c | 1260 |
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 |