1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for kernel DLL Communication Abstraction Layer module
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplDllkCal.c,v $
56 $Revision: 1.7 $ $Date: 2008/11/13 17:13:09 $
63 -------------------------------------------------------------------------
67 2006/06/15 d.k.: start of the implementation, version 1.00
69 ****************************************************************************/
71 #include "kernel/EplDllkCal.h"
72 #include "kernel/EplDllk.h"
73 #include "kernel/EplEventk.h"
75 #include "EplDllCal.h"
77 #include "SharedBuff.h"
80 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
81 /***************************************************************************/
84 /* G L O B A L D E F I N I T I O N S */
87 /***************************************************************************/
89 //---------------------------------------------------------------------------
91 //---------------------------------------------------------------------------
94 #define min(a,b) (((a) < (b)) ? (a) : (b))
97 //---------------------------------------------------------------------------
99 //---------------------------------------------------------------------------
101 //---------------------------------------------------------------------------
102 // modul globale vars
103 //---------------------------------------------------------------------------
105 //---------------------------------------------------------------------------
106 // local function prototypes
107 //---------------------------------------------------------------------------
110 /***************************************************************************/
113 /* C L A S S EplDllkCal */
116 /***************************************************************************/
121 /***************************************************************************/
124 //=========================================================================//
126 // P R I V A T E D E F I N I T I O N S //
128 //=========================================================================//
130 //---------------------------------------------------------------------------
132 //---------------------------------------------------------------------------
134 #define EPL_DLLKCAL_MAX_QUEUES 5 // CnGenReq, CnNmtReq, {MnGenReq, MnNmtReq}, MnIdentReq, MnStatusReq
136 //---------------------------------------------------------------------------
138 //---------------------------------------------------------------------------
143 // tShbInstance m_ShbInstanceRx; // FIFO for Rx ASnd frames
144 tShbInstance m_ShbInstanceTxNmt; // FIFO for Tx frames with NMT request priority
145 tShbInstance m_ShbInstanceTxGen; // FIFO for Tx frames with generic priority
147 unsigned int m_uiFrameSizeNmt;
148 BYTE m_abFrameNmt[1500];
149 unsigned int m_uiFrameSizeGen;
150 BYTE m_abFrameGen[1500];
153 tEplDllkCalStatistics m_Statistics;
155 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
156 // IdentRequest queue with CN node IDs
157 unsigned int m_auiQueueIdentReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty
158 unsigned int m_uiWriteIdentReq;
159 unsigned int m_uiReadIdentReq;
161 // StatusRequest queue with CN node IDs
162 unsigned int m_auiQueueStatusReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty
163 unsigned int m_uiWriteStatusReq;
164 unsigned int m_uiReadStatusReq;
166 unsigned int m_auiQueueCnRequests[254 * 2];
167 // first 254 entries represent the generic requests of the corresponding node
168 // second 254 entries represent the NMT requests of the corresponding node
169 unsigned int m_uiNextQueueCnRequest;
170 unsigned int m_uiNextRequestQueue;
173 } tEplDllkCalInstance;
175 //---------------------------------------------------------------------------
177 //---------------------------------------------------------------------------
179 // if no dynamic memory allocation shall be used
180 // define structures statically
181 static tEplDllkCalInstance EplDllkCalInstance_g;
183 //---------------------------------------------------------------------------
184 // local function prototypes
185 //---------------------------------------------------------------------------
188 //=========================================================================//
190 // P U B L I C F U N C T I O N S //
192 //=========================================================================//
194 //---------------------------------------------------------------------------
196 // Function: EplDllkCalAddInstance()
198 // Description: add and initialize new instance of DLL CAL module
202 // Returns: tEplKernel = error code
207 //---------------------------------------------------------------------------
209 tEplKernel EplDllkCalAddInstance()
211 tEplKernel Ret = kEplSuccessful;
214 unsigned int fShbNewCreated;
216 /* ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_RX, EPL_DLLCAL_BUFFER_ID_RX,
217 &EplDllkCalInstance_g.m_ShbInstanceRx, &fShbNewCreated);
218 // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
220 if (ShbError != kShbOk)
222 Ret = kEplNoResource;
225 ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_TX_NMT, EPL_DLLCAL_BUFFER_ID_TX_NMT,
226 &EplDllkCalInstance_g.m_ShbInstanceTxNmt, &fShbNewCreated);
227 // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
229 if (ShbError != kShbOk)
231 Ret = kEplNoResource;
234 /* ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxNmt, EplDllkCalTxNmtSignalHandler, kShbPriorityNormal);
235 // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
237 if (ShbError != kShbOk)
239 Ret = kEplNoResource;
242 ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_TX_GEN, EPL_DLLCAL_BUFFER_ID_TX_GEN,
243 &EplDllkCalInstance_g.m_ShbInstanceTxGen, &fShbNewCreated);
244 // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
246 if (ShbError != kShbOk)
248 Ret = kEplNoResource;
251 /* ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxGen, EplDllkCalTxGenSignalHandler, kShbPriorityNormal);
252 // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
254 if (ShbError != kShbOk)
256 Ret = kEplNoResource;
260 EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
261 EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
267 //---------------------------------------------------------------------------
269 // Function: EplDllkCalDelInstance()
271 // Description: deletes instance of DLL CAL module
275 // Returns: tEplKernel = error code
280 //---------------------------------------------------------------------------
282 tEplKernel EplDllkCalDelInstance()
284 tEplKernel Ret = kEplSuccessful;
288 /* ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceRx);
289 if (ShbError != kShbOk)
291 Ret = kEplNoResource;
293 EplDllkCalInstance_g.m_ShbInstanceRx = NULL;
295 ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceTxNmt);
296 if (ShbError != kShbOk)
298 Ret = kEplNoResource;
300 EplDllkCalInstance_g.m_ShbInstanceTxNmt = NULL;
302 ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceTxGen);
303 if (ShbError != kShbOk)
305 Ret = kEplNoResource;
307 EplDllkCalInstance_g.m_ShbInstanceTxGen = NULL;
310 EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
311 EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
317 //---------------------------------------------------------------------------
319 // Function: EplDllkCalProcess
321 // Description: process the passed configuration
323 // Parameters: pEvent_p = event containing configuration options
325 // Returns: tEplKernel = error code
330 //---------------------------------------------------------------------------
332 tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p)
334 tEplKernel Ret = kEplSuccessful;
336 switch (pEvent_p->m_EventType)
338 case kEplEventTypeDllkServFilter:
340 tEplDllCalAsndServiceIdFilter* pServFilter;
342 pServFilter = (tEplDllCalAsndServiceIdFilter*) pEvent_p->m_pArg;
343 Ret = EplDllkSetAsndServiceIdFilter(pServFilter->m_ServiceId, pServFilter->m_Filter);
347 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
348 case kEplEventTypeDllkIssueReq:
350 tEplDllCalIssueRequest* pIssueReq;
352 pIssueReq = (tEplDllCalIssueRequest*) pEvent_p->m_pArg;
353 Ret = EplDllkCalIssueRequest(pIssueReq->m_Service, pIssueReq->m_uiNodeId, pIssueReq->m_bSoaFlag1);
357 case kEplEventTypeDllkAddNode:
359 tEplDllNodeInfo* pNodeInfo;
361 pNodeInfo = (tEplDllNodeInfo*) pEvent_p->m_pArg;
362 Ret = EplDllkAddNode(pNodeInfo);
366 case kEplEventTypeDllkDelNode:
368 unsigned int* puiNodeId;
370 puiNodeId = (unsigned int*) pEvent_p->m_pArg;
371 Ret = EplDllkDeleteNode(*puiNodeId);
375 case kEplEventTypeDllkSoftDelNode:
377 unsigned int* puiNodeId;
379 puiNodeId = (unsigned int*) pEvent_p->m_pArg;
380 Ret = EplDllkSoftDeleteNode(*puiNodeId);
385 case kEplEventTypeDllkIdentity:
387 tEplDllIdentParam* pIdentParam;
389 pIdentParam = (tEplDllIdentParam*) pEvent_p->m_pArg;
390 if (pIdentParam->m_uiSizeOfStruct > pEvent_p->m_uiSize)
392 pIdentParam->m_uiSizeOfStruct = pEvent_p->m_uiSize;
394 Ret = EplDllkSetIdentity(pIdentParam);
398 case kEplEventTypeDllkConfig:
400 tEplDllConfigParam* pConfigParam;
402 pConfigParam = (tEplDllConfigParam*) pEvent_p->m_pArg;
403 if (pConfigParam->m_uiSizeOfStruct > pEvent_p->m_uiSize)
405 pConfigParam->m_uiSizeOfStruct = pEvent_p->m_uiSize;
407 Ret = EplDllkConfig(pConfigParam);
420 //---------------------------------------------------------------------------
422 // Function: EplDllkCalAsyncGetTxCount()
424 // Description: returns count of Tx frames of FIFO with highest priority
428 // Returns: tEplKernel = error code
433 //---------------------------------------------------------------------------
435 tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p, unsigned int * puiCount_p)
437 tEplKernel Ret = kEplSuccessful;
440 unsigned long ulFrameCount;
442 // get frame count of Tx FIFO with NMT request priority
443 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulFrameCount);
444 // returns kShbOk, kShbInvalidArg
447 if (ShbError != kShbOk)
449 Ret = kEplNoResource;
453 if (ulFrameCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
455 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulFrameCount;
458 if (ulFrameCount != 0)
459 { // NMT requests are in queue
460 *pPriority_p = kEplDllAsyncReqPrioNmt;
461 *puiCount_p = (unsigned int) ulFrameCount;
465 // get frame count of Tx FIFO with generic priority
466 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulFrameCount);
467 // returns kShbOk, kShbInvalidArg
470 if (ShbError != kShbOk)
472 Ret = kEplNoResource;
476 if (ulFrameCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
478 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulFrameCount;
481 *pPriority_p = kEplDllAsyncReqPrioGeneric;
482 *puiCount_p = (unsigned int) ulFrameCount;
486 if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0)
488 *pPriority_p = kEplDllAsyncReqPrioNmt;
491 else if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0)
493 *pPriority_p = kEplDllAsyncReqPrioGeneric;
498 *pPriority_p = kEplDllAsyncReqPrioGeneric;
506 //---------------------------------------------------------------------------
508 // Function: EplDllkCalAsyncGetTxFrame()
510 // Description: returns Tx frames from FIFO with specified priority
512 // Parameters: pFrame_p = IN: pointer to buffer
513 // puiFrameSize_p = IN: max size of buffer
514 // OUT: actual size of frame
515 // Priority_p = IN: priority
517 // Returns: tEplKernel = error code
522 //---------------------------------------------------------------------------
524 tEplKernel EplDllkCalAsyncGetTxFrame(void * pFrame_p, unsigned int * puiFrameSize_p, tEplDllAsyncReqPriority Priority_p)
526 tEplKernel Ret = kEplSuccessful;
529 unsigned long ulFrameSize;
533 case kEplDllAsyncReqPrioNmt: // NMT request priority
534 ShbError = ShbCirReadDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxNmt, (BYTE *) pFrame_p, *puiFrameSize_p, &ulFrameSize);
535 // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
538 default: // generic priority
539 ShbError = ShbCirReadDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxGen, (BYTE *) pFrame_p, *puiFrameSize_p, &ulFrameSize);
540 // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
546 if (ShbError != kShbOk)
548 if (ShbError == kShbNoReadableData)
550 Ret = kEplDllAsyncTxBufferEmpty;
554 Ret = kEplNoResource;
559 *puiFrameSize_p = (unsigned int) ulFrameSize;
565 case kEplDllAsyncReqPrioNmt: // NMT request priority
566 *puiFrameSize_p = min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeNmt);
567 EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameNmt, *puiFrameSize_p);
568 EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
571 default: // generic priority
572 *puiFrameSize_p = min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeGen);
573 EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameGen, *puiFrameSize_p);
574 EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
583 //---------------------------------------------------------------------------
585 // Function: EplDllkCalAsyncFrameReceived()
587 // Description: passes ASnd frame to receive FIFO.
588 // It will be called only for frames with registered AsndServiceIds.
592 // Returns: tEplKernel = error code
597 //---------------------------------------------------------------------------
599 tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p)
601 tEplKernel Ret = kEplSuccessful;
604 Event.m_EventSink = kEplEventSinkDlluCal;
605 Event.m_EventType = kEplEventTypeAsndRx;
606 Event.m_pArg = pFrameInfo_p->m_pFrame;
607 Event.m_uiSize = pFrameInfo_p->m_uiFrameSize;
608 // pass NetTime of frame to userspace
609 Event.m_NetTime = pFrameInfo_p->m_NetTime;
611 Ret = EplEventkPost(&Event);
612 if (Ret != kEplSuccessful)
614 EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount++;
618 EplDllkCalInstance_g.m_Statistics.m_ulMaxRxFrameCount++;
625 //---------------------------------------------------------------------------
627 // Function: EplDllkCalAsyncSend()
629 // Description: puts the given frame into the transmit FIFO with the specified
632 // Parameters: pFrameInfo_p = frame info structure
633 // Priority_p = priority
635 // Returns: tEplKernel = error code
640 //---------------------------------------------------------------------------
642 tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p, tEplDllAsyncReqPriority Priority_p)
644 tEplKernel Ret = kEplSuccessful;
651 case kEplDllAsyncReqPrioNmt: // NMT request priority
652 ShbError = ShbCirWriteDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxNmt, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
653 // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
656 default: // generic priority
657 ShbError = ShbCirWriteDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxGen, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
658 // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
669 case kShbExceedDataSizeLimit:
670 Ret = kEplDllAsyncTxBufferFull;
674 Ret = kEplDllAsyncTxBufferFull;
679 Ret = kEplNoResource;
687 case kEplDllAsyncReqPrioNmt: // NMT request priority
688 if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0)
690 EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
691 EplDllkCalInstance_g.m_uiFrameSizeNmt = pFrameInfo_p->m_uiFrameSize;
695 Ret = kEplDllAsyncTxBufferFull;
700 default: // generic priority
701 if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0)
703 EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
704 EplDllkCalInstance_g.m_uiFrameSizeGen = pFrameInfo_p->m_uiFrameSize;
708 Ret = kEplDllAsyncTxBufferFull;
717 Event.m_EventSink = kEplEventSinkDllk;
718 Event.m_EventType = kEplEventTypeDllkFillTx;
719 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
720 Event.m_pArg = &Priority_p;
721 Event.m_uiSize = sizeof(Priority_p);
722 Ret = EplEventkPost(&Event);
732 //---------------------------------------------------------------------------
734 // Function: EplDllkCalAsyncClearBuffer()
736 // Description: clears the transmit buffer
738 // Parameters: (none)
740 // Returns: tEplKernel = error code
745 //---------------------------------------------------------------------------
747 tEplKernel EplDllkCalAsyncClearBuffer(void)
749 tEplKernel Ret = kEplSuccessful;
753 ShbError = ShbCirResetBuffer (EplDllkCalInstance_g.m_ShbInstanceTxNmt, 1000, NULL);
754 ShbError = ShbCirResetBuffer (EplDllkCalInstance_g.m_ShbInstanceTxGen, 1000, NULL);
757 EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
758 EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
761 // EPL_MEMSET(&EplDllkCalInstance_g.m_Statistics, 0, sizeof (tEplDllkCalStatistics));
766 //---------------------------------------------------------------------------
768 // Function: EplDllkCalAsyncClearQueues()
770 // Description: clears the transmit buffer
772 // Parameters: (none)
774 // Returns: tEplKernel = error code
779 //---------------------------------------------------------------------------
781 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
782 tEplKernel EplDllkCalAsyncClearQueues(void)
784 tEplKernel Ret = kEplSuccessful;
786 // clear MN asynchronous queues
787 EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
788 EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
789 EplDllkCalInstance_g.m_uiReadIdentReq = 0;
790 EplDllkCalInstance_g.m_uiWriteIdentReq = 0;
791 EplDllkCalInstance_g.m_uiReadStatusReq = 0;
792 EplDllkCalInstance_g.m_uiWriteStatusReq = 0;
799 //---------------------------------------------------------------------------
801 // Function: EplDllkCalGetStatistics()
803 // Description: returns statistics of the asynchronous queues.
805 // Parameters: ppStatistics = statistics structure
807 // Returns: tEplKernel = error code
812 //---------------------------------------------------------------------------
814 tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
816 tEplKernel Ret = kEplSuccessful;
820 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt);
821 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen);
822 // ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceRx, &EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount);
825 if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0)
827 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 1;
831 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 0;
833 if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0)
835 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 1;
839 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 0;
843 *ppStatistics = &EplDllkCalInstance_g.m_Statistics;
848 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
850 //---------------------------------------------------------------------------
852 // Function: EplDllkCalIssueRequest()
854 // Description: issues a StatusRequest or a IdentRequest to the specified node.
856 // Parameters: Service_p = request service ID
857 // uiNodeId_p = node ID
858 // bSoaFlag1_p = flag1 for this node (transmit in SoA and PReq)
859 // If 0xFF this flag is ignored.
861 // Returns: tEplKernel = error code
866 //---------------------------------------------------------------------------
868 tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p, unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
870 tEplKernel Ret = kEplSuccessful;
872 if (bSoaFlag1_p != 0xFF)
874 Ret = EplDllkSetFlag1OfNode(uiNodeId_p, bSoaFlag1_p);
875 if (Ret != kEplSuccessful)
881 // add node to appropriate request queue
884 case kEplDllReqServiceIdent:
886 if (((EplDllkCalInstance_g.m_uiWriteIdentReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueIdentReq))
887 == EplDllkCalInstance_g.m_uiReadIdentReq)
889 Ret = kEplDllAsyncTxBufferFull;
892 EplDllkCalInstance_g.m_auiQueueIdentReq[EplDllkCalInstance_g.m_uiWriteIdentReq] = uiNodeId_p;
893 EplDllkCalInstance_g.m_uiWriteIdentReq =
894 (EplDllkCalInstance_g.m_uiWriteIdentReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueIdentReq);
898 case kEplDllReqServiceStatus:
900 if (((EplDllkCalInstance_g.m_uiWriteStatusReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueStatusReq))
901 == EplDllkCalInstance_g.m_uiReadStatusReq)
903 Ret = kEplDllAsyncTxBufferFull;
906 EplDllkCalInstance_g.m_auiQueueStatusReq[EplDllkCalInstance_g.m_uiWriteStatusReq] = uiNodeId_p;
907 EplDllkCalInstance_g.m_uiWriteStatusReq =
908 (EplDllkCalInstance_g.m_uiWriteStatusReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueStatusReq);
914 Ret = kEplDllInvalidParam;
924 //---------------------------------------------------------------------------
926 // Function: EplDllkCalAsyncGetSoaRequest()
928 // Description: returns next request for SoA. This function is called by DLLk module.
930 // Parameters: pReqServiceId_p = pointer to request service ID
931 // IN: available request for MN NMT or generic request queue (Flag2.PR)
932 // or kEplDllReqServiceNo if queues are empty
934 // puiNodeId_p = OUT: pointer to node ID of next request
935 // = EPL_C_ADR_INVALID, if request is self addressed
937 // Returns: tEplKernel = error code
942 //---------------------------------------------------------------------------
944 tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId* pReqServiceId_p, unsigned int* puiNodeId_p)
946 tEplKernel Ret = kEplSuccessful;
947 unsigned int uiCount;
949 // *pReqServiceId_p = kEplDllReqServiceNo;
951 for (uiCount = EPL_DLLKCAL_MAX_QUEUES; uiCount > 0; uiCount--)
953 switch (EplDllkCalInstance_g.m_uiNextRequestQueue)
957 for (;EplDllkCalInstance_g.m_uiNextQueueCnRequest < (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2);
958 EplDllkCalInstance_g.m_uiNextQueueCnRequest++)
960 if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0)
961 { // non empty queue found
962 // remove one request from queue
963 EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest]--;
964 *puiNodeId_p = EplDllkCalInstance_g.m_uiNextQueueCnRequest + 1;
965 *pReqServiceId_p = kEplDllReqServiceUnspecified;
966 EplDllkCalInstance_g.m_uiNextQueueCnRequest++;
967 if (EplDllkCalInstance_g.m_uiNextQueueCnRequest >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
968 { // last node reached
969 // continue with CnNmtReq queue at next SoA
970 EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
975 // all CnGenReq queues are empty -> continue with CnNmtReq queue
976 EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
982 for (;EplDllkCalInstance_g.m_uiNextQueueCnRequest < tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests);
983 EplDllkCalInstance_g.m_uiNextQueueCnRequest++)
985 if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0)
986 { // non empty queue found
987 // remove one request from queue
988 EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest]--;
989 *puiNodeId_p = EplDllkCalInstance_g.m_uiNextQueueCnRequest + 1 - (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2);
990 *pReqServiceId_p = kEplDllReqServiceNmtRequest;
991 EplDllkCalInstance_g.m_uiNextQueueCnRequest++;
992 if (EplDllkCalInstance_g.m_uiNextQueueCnRequest > tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests))
993 { // last node reached
994 // restart CnGenReq queue
995 EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
996 // continue with MnGenReq queue at next SoA
997 EplDllkCalInstance_g.m_uiNextRequestQueue = 2;
1002 // restart CnGenReq queue
1003 EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
1004 // all CnNmtReq queues are empty -> continue with MnGenReq queue
1005 EplDllkCalInstance_g.m_uiNextRequestQueue = 2;
1010 { // MnNmtReq and MnGenReq
1011 // next queue will be MnIdentReq queue
1012 EplDllkCalInstance_g.m_uiNextRequestQueue = 3;
1013 if (*pReqServiceId_p != kEplDllReqServiceNo)
1015 *puiNodeId_p = EPL_C_ADR_INVALID; // DLLk must exchange this with the actual node ID
1023 // next queue will be MnStatusReq queue
1024 EplDllkCalInstance_g.m_uiNextRequestQueue = 4;
1025 if (EplDllkCalInstance_g.m_uiReadIdentReq != EplDllkCalInstance_g.m_uiWriteIdentReq)
1026 { // queue is not empty
1027 *puiNodeId_p = EplDllkCalInstance_g.m_auiQueueIdentReq[EplDllkCalInstance_g.m_uiReadIdentReq];
1028 EplDllkCalInstance_g.m_uiReadIdentReq =
1029 (EplDllkCalInstance_g.m_uiReadIdentReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueIdentReq);
1030 *pReqServiceId_p = kEplDllReqServiceIdent;
1038 // next queue will be CnGenReq queue
1039 EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
1040 if (EplDllkCalInstance_g.m_uiReadStatusReq != EplDllkCalInstance_g.m_uiWriteStatusReq)
1041 { // queue is not empty
1042 *puiNodeId_p = EplDllkCalInstance_g.m_auiQueueStatusReq[EplDllkCalInstance_g.m_uiReadStatusReq];
1043 EplDllkCalInstance_g.m_uiReadStatusReq =
1044 (EplDllkCalInstance_g.m_uiReadStatusReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueStatusReq);
1045 *pReqServiceId_p = kEplDllReqServiceStatus;
1058 //---------------------------------------------------------------------------
1060 // Function: EplDllkCalAsyncSetPendingRequests()
1062 // Description: sets the pending asynchronous frame requests of the specified node.
1063 // This will add the node to the asynchronous request scheduler.
1065 // Parameters: uiNodeId_p = node ID
1066 // AsyncReqPrio_p = asynchronous request priority
1067 // uiCount_p = count of asynchronous frames
1069 // Returns: tEplKernel = error code
1074 //---------------------------------------------------------------------------
1076 tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p, tEplDllAsyncReqPriority AsyncReqPrio_p, unsigned int uiCount_p)
1078 tEplKernel Ret = kEplSuccessful;
1080 // add node to appropriate request queue
1081 switch (AsyncReqPrio_p)
1083 case kEplDllAsyncReqPrioNmt:
1086 if (uiNodeId_p >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
1088 Ret = kEplDllInvalidParam;
1091 uiNodeId_p += tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2;
1092 EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = uiCount_p;
1099 if (uiNodeId_p >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
1101 Ret = kEplDllInvalidParam;
1104 EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = uiCount_p;
1112 #endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1114 //=========================================================================//
1116 // P R I V A T E F U N C T I O N S //
1118 //=========================================================================//
1120 //---------------------------------------------------------------------------
1121 // Callback handler for new data signaling
1122 //---------------------------------------------------------------------------
1125 /*static void EplDllkCalTxNmtSignalHandler (
1126 tShbInstance pShbRxInstance_p,
1127 unsigned long ulDataSize_p)
1129 tEplKernel Ret = kEplSuccessful;
1131 tEplDllAsyncReqPriority Priority;
1134 unsigned long ulBlockCount;
1137 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulBlockCount);
1138 if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
1140 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulBlockCount;
1145 // post event to DLL
1146 Priority = kEplDllAsyncReqPrioNmt;
1147 Event.m_EventSink = kEplEventSinkDllk;
1148 Event.m_EventType = kEplEventTypeDllkFillTx;
1149 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
1150 Event.m_pArg = &Priority;
1151 Event.m_uiSize = sizeof(Priority);
1152 Ret = EplEventkPost(&Event);
1156 static void EplDllkCalTxGenSignalHandler (
1157 tShbInstance pShbRxInstance_p,
1158 unsigned long ulDataSize_p)
1160 tEplKernel Ret = kEplSuccessful;
1162 tEplDllAsyncReqPriority Priority;
1165 unsigned long ulBlockCount;
1168 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulBlockCount);
1169 if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
1171 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulBlockCount;
1176 // post event to DLL
1177 Priority = kEplDllAsyncReqPrioGeneric;
1178 Event.m_EventSink = kEplEventSinkDllk;
1179 Event.m_EventType = kEplEventTypeDllkFillTx;
1180 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
1181 Event.m_pArg = &Priority;
1182 Event.m_uiSize = sizeof(Priority);
1183 Ret = EplEventkPost(&Event);
1190 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)