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 //---------------------------------------------------------------------------
109 /***************************************************************************/
112 /* C L A S S EplDllkCal */
115 /***************************************************************************/
120 /***************************************************************************/
122 //=========================================================================//
124 // P R I V A T E D E F I N I T I O N S //
126 //=========================================================================//
128 //---------------------------------------------------------------------------
130 //---------------------------------------------------------------------------
132 #define EPL_DLLKCAL_MAX_QUEUES 5 // CnGenReq, CnNmtReq, {MnGenReq, MnNmtReq}, MnIdentReq, MnStatusReq
134 //---------------------------------------------------------------------------
136 //---------------------------------------------------------------------------
140 // tShbInstance m_ShbInstanceRx; // FIFO for Rx ASnd frames
141 tShbInstance m_ShbInstanceTxNmt; // FIFO for Tx frames with NMT request priority
142 tShbInstance m_ShbInstanceTxGen; // FIFO for Tx frames with generic priority
144 unsigned int m_uiFrameSizeNmt;
145 u8 m_abFrameNmt[1500];
146 unsigned int m_uiFrameSizeGen;
147 u8 m_abFrameGen[1500];
150 tEplDllkCalStatistics m_Statistics;
152 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
153 // IdentRequest queue with CN node IDs
154 unsigned int m_auiQueueIdentReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty
155 unsigned int m_uiWriteIdentReq;
156 unsigned int m_uiReadIdentReq;
158 // StatusRequest queue with CN node IDs
159 unsigned int m_auiQueueStatusReq[EPL_D_NMT_MaxCNNumber_U8 + 1]; // 1 entry is reserved to distinguish between full and empty
160 unsigned int m_uiWriteStatusReq;
161 unsigned int m_uiReadStatusReq;
163 unsigned int m_auiQueueCnRequests[254 * 2];
164 // first 254 entries represent the generic requests of the corresponding node
165 // second 254 entries represent the NMT requests of the corresponding node
166 unsigned int m_uiNextQueueCnRequest;
167 unsigned int m_uiNextRequestQueue;
170 } tEplDllkCalInstance;
172 //---------------------------------------------------------------------------
174 //---------------------------------------------------------------------------
176 // if no dynamic memory allocation shall be used
177 // define structures statically
178 static tEplDllkCalInstance EplDllkCalInstance_g;
180 //---------------------------------------------------------------------------
181 // local function prototypes
182 //---------------------------------------------------------------------------
184 //=========================================================================//
186 // P U B L I C F U N C T I O N S //
188 //=========================================================================//
190 //---------------------------------------------------------------------------
192 // Function: EplDllkCalAddInstance()
194 // Description: add and initialize new instance of DLL CAL module
198 // Returns: tEplKernel = error code
203 //---------------------------------------------------------------------------
205 tEplKernel EplDllkCalAddInstance(void)
207 tEplKernel Ret = kEplSuccessful;
210 unsigned int fShbNewCreated;
212 /* ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_RX, EPL_DLLCAL_BUFFER_ID_RX,
213 &EplDllkCalInstance_g.m_ShbInstanceRx, &fShbNewCreated);
214 // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
216 if (ShbError != kShbOk)
218 Ret = kEplNoResource;
222 ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_NMT,
223 EPL_DLLCAL_BUFFER_ID_TX_NMT,
224 &EplDllkCalInstance_g.m_ShbInstanceTxNmt,
226 // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
228 if (ShbError != kShbOk) {
229 Ret = kEplNoResource;
232 /* ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxNmt, EplDllkCalTxNmtSignalHandler, kShbPriorityNormal);
233 // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
235 if (ShbError != kShbOk)
237 Ret = kEplNoResource;
241 ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_GEN,
242 EPL_DLLCAL_BUFFER_ID_TX_GEN,
243 &EplDllkCalInstance_g.m_ShbInstanceTxGen,
245 // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
247 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(void)
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) {
297 Ret = kEplNoResource;
299 EplDllkCalInstance_g.m_ShbInstanceTxNmt = NULL;
301 ShbError = ShbCirReleaseBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen);
302 if (ShbError != kShbOk) {
303 Ret = kEplNoResource;
305 EplDllkCalInstance_g.m_ShbInstanceTxGen = NULL;
308 EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
309 EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
315 //---------------------------------------------------------------------------
317 // Function: EplDllkCalProcess
319 // Description: process the passed configuration
321 // Parameters: pEvent_p = event containing configuration options
323 // Returns: tEplKernel = error code
328 //---------------------------------------------------------------------------
330 tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p)
332 tEplKernel Ret = kEplSuccessful;
334 switch (pEvent_p->m_EventType) {
335 case kEplEventTypeDllkServFilter:
337 tEplDllCalAsndServiceIdFilter *pServFilter;
340 (tEplDllCalAsndServiceIdFilter *) pEvent_p->m_pArg;
342 EplDllkSetAsndServiceIdFilter(pServFilter->
349 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
350 case kEplEventTypeDllkIssueReq:
352 tEplDllCalIssueRequest *pIssueReq;
354 pIssueReq = (tEplDllCalIssueRequest *) pEvent_p->m_pArg;
356 EplDllkCalIssueRequest(pIssueReq->m_Service,
357 pIssueReq->m_uiNodeId,
358 pIssueReq->m_bSoaFlag1);
362 case kEplEventTypeDllkAddNode:
364 tEplDllNodeInfo *pNodeInfo;
366 pNodeInfo = (tEplDllNodeInfo *) pEvent_p->m_pArg;
367 Ret = EplDllkAddNode(pNodeInfo);
371 case kEplEventTypeDllkDelNode:
373 unsigned int *puiNodeId;
375 puiNodeId = (unsigned int *)pEvent_p->m_pArg;
376 Ret = EplDllkDeleteNode(*puiNodeId);
380 case kEplEventTypeDllkSoftDelNode:
382 unsigned int *puiNodeId;
384 puiNodeId = (unsigned int *)pEvent_p->m_pArg;
385 Ret = EplDllkSoftDeleteNode(*puiNodeId);
390 case kEplEventTypeDllkIdentity:
392 tEplDllIdentParam *pIdentParam;
394 pIdentParam = (tEplDllIdentParam *) pEvent_p->m_pArg;
395 if (pIdentParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) {
396 pIdentParam->m_uiSizeOfStruct =
399 Ret = EplDllkSetIdentity(pIdentParam);
403 case kEplEventTypeDllkConfig:
405 tEplDllConfigParam *pConfigParam;
407 pConfigParam = (tEplDllConfigParam *) pEvent_p->m_pArg;
408 if (pConfigParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) {
409 pConfigParam->m_uiSizeOfStruct =
412 Ret = EplDllkConfig(pConfigParam);
424 //---------------------------------------------------------------------------
426 // Function: EplDllkCalAsyncGetTxCount()
428 // Description: returns count of Tx frames of FIFO with highest priority
432 // Returns: tEplKernel = error code
437 //---------------------------------------------------------------------------
439 tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p,
440 unsigned int *puiCount_p)
442 tEplKernel Ret = kEplSuccessful;
445 unsigned long ulFrameCount;
447 // get frame count of Tx FIFO with NMT request priority
449 ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
451 // returns kShbOk, kShbInvalidArg
454 if (ShbError != kShbOk) {
455 Ret = kEplNoResource;
460 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt) {
461 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt =
465 if (ulFrameCount != 0) { // NMT requests are in queue
466 *pPriority_p = kEplDllAsyncReqPrioNmt;
467 *puiCount_p = (unsigned int)ulFrameCount;
470 // get frame count of Tx FIFO with generic priority
472 ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen,
474 // returns kShbOk, kShbInvalidArg
477 if (ShbError != kShbOk) {
478 Ret = kEplNoResource;
483 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen) {
484 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen =
488 *pPriority_p = kEplDllAsyncReqPrioGeneric;
489 *puiCount_p = (unsigned int)ulFrameCount;
493 if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) {
494 *pPriority_p = kEplDllAsyncReqPrioNmt;
496 } else if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) {
497 *pPriority_p = kEplDllAsyncReqPrioGeneric;
500 *pPriority_p = kEplDllAsyncReqPrioGeneric;
508 //---------------------------------------------------------------------------
510 // Function: EplDllkCalAsyncGetTxFrame()
512 // Description: returns Tx frames from FIFO with specified priority
514 // Parameters: pFrame_p = IN: pointer to buffer
515 // puiFrameSize_p = IN: max size of buffer
516 // OUT: actual size of frame
517 // Priority_p = IN: priority
519 // Returns: tEplKernel = error code
524 //---------------------------------------------------------------------------
526 tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
527 unsigned int *puiFrameSize_p,
528 tEplDllAsyncReqPriority Priority_p)
530 tEplKernel Ret = kEplSuccessful;
533 unsigned long ulFrameSize;
535 switch (Priority_p) {
536 case kEplDllAsyncReqPrioNmt: // NMT request priority
538 ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
539 (u8 *) pFrame_p, *puiFrameSize_p,
541 // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
544 default: // generic priority
546 ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxGen,
547 (u8 *) pFrame_p, *puiFrameSize_p,
549 // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
555 if (ShbError != kShbOk) {
556 if (ShbError == kShbNoReadableData) {
557 Ret = kEplDllAsyncTxBufferEmpty;
558 } else { // other error
559 Ret = kEplNoResource;
564 *puiFrameSize_p = (unsigned int)ulFrameSize;
568 switch (Priority_p) {
569 case kEplDllAsyncReqPrioNmt: // NMT request priority
571 min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeNmt);
572 EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameNmt,
574 EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
577 default: // generic priority
579 min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeGen);
580 EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameGen,
582 EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
591 //---------------------------------------------------------------------------
593 // Function: EplDllkCalAsyncFrameReceived()
595 // Description: passes ASnd frame to receive FIFO.
596 // It will be called only for frames with registered AsndServiceIds.
600 // Returns: tEplKernel = error code
605 //---------------------------------------------------------------------------
607 tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p)
609 tEplKernel Ret = kEplSuccessful;
612 Event.m_EventSink = kEplEventSinkDlluCal;
613 Event.m_EventType = kEplEventTypeAsndRx;
614 Event.m_pArg = pFrameInfo_p->m_pFrame;
615 Event.m_uiSize = pFrameInfo_p->m_uiFrameSize;
616 // pass NetTime of frame to userspace
617 Event.m_NetTime = pFrameInfo_p->m_NetTime;
619 Ret = EplEventkPost(&Event);
620 if (Ret != kEplSuccessful) {
621 EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount++;
623 EplDllkCalInstance_g.m_Statistics.m_ulMaxRxFrameCount++;
629 //---------------------------------------------------------------------------
631 // Function: EplDllkCalAsyncSend()
633 // Description: puts the given frame into the transmit FIFO with the specified
636 // Parameters: pFrameInfo_p = frame info structure
637 // Priority_p = priority
639 // Returns: tEplKernel = error code
644 //---------------------------------------------------------------------------
646 tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p,
647 tEplDllAsyncReqPriority Priority_p)
649 tEplKernel Ret = kEplSuccessful;
654 switch (Priority_p) {
655 case kEplDllAsyncReqPrioNmt: // NMT request priority
657 ShbCirWriteDataBlock(EplDllkCalInstance_g.
659 pFrameInfo_p->m_pFrame,
660 pFrameInfo_p->m_uiFrameSize);
661 // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
664 default: // generic priority
666 ShbCirWriteDataBlock(EplDllkCalInstance_g.
668 pFrameInfo_p->m_pFrame,
669 pFrameInfo_p->m_uiFrameSize);
670 // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
680 case kShbExceedDataSizeLimit:
681 Ret = kEplDllAsyncTxBufferFull;
685 Ret = kEplDllAsyncTxBufferFull;
690 Ret = kEplNoResource;
696 switch (Priority_p) {
697 case kEplDllAsyncReqPrioNmt: // NMT request priority
698 if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0) {
699 EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt,
700 pFrameInfo_p->m_pFrame,
701 pFrameInfo_p->m_uiFrameSize);
702 EplDllkCalInstance_g.m_uiFrameSizeNmt =
703 pFrameInfo_p->m_uiFrameSize;
705 Ret = kEplDllAsyncTxBufferFull;
710 default: // generic priority
711 if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0) {
712 EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen,
713 pFrameInfo_p->m_pFrame,
714 pFrameInfo_p->m_uiFrameSize);
715 EplDllkCalInstance_g.m_uiFrameSizeGen =
716 pFrameInfo_p->m_uiFrameSize;
718 Ret = kEplDllAsyncTxBufferFull;
727 Event.m_EventSink = kEplEventSinkDllk;
728 Event.m_EventType = kEplEventTypeDllkFillTx;
729 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
730 Event.m_pArg = &Priority_p;
731 Event.m_uiSize = sizeof(Priority_p);
732 Ret = EplEventkPost(&Event);
741 //---------------------------------------------------------------------------
743 // Function: EplDllkCalAsyncClearBuffer()
745 // Description: clears the transmit buffer
747 // Parameters: (none)
749 // Returns: tEplKernel = error code
754 //---------------------------------------------------------------------------
756 tEplKernel EplDllkCalAsyncClearBuffer(void)
758 tEplKernel Ret = kEplSuccessful;
763 ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxNmt, 1000,
766 ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen, 1000,
770 EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
771 EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
774 // EPL_MEMSET(&EplDllkCalInstance_g.m_Statistics, 0, sizeof (tEplDllkCalStatistics));
778 //---------------------------------------------------------------------------
780 // Function: EplDllkCalAsyncClearQueues()
782 // Description: clears the transmit buffer
784 // Parameters: (none)
786 // Returns: tEplKernel = error code
791 //---------------------------------------------------------------------------
793 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
794 tEplKernel EplDllkCalAsyncClearQueues(void)
796 tEplKernel Ret = kEplSuccessful;
798 // clear MN asynchronous queues
799 EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
800 EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
801 EplDllkCalInstance_g.m_uiReadIdentReq = 0;
802 EplDllkCalInstance_g.m_uiWriteIdentReq = 0;
803 EplDllkCalInstance_g.m_uiReadStatusReq = 0;
804 EplDllkCalInstance_g.m_uiWriteStatusReq = 0;
810 //---------------------------------------------------------------------------
812 // Function: EplDllkCalGetStatistics()
814 // Description: returns statistics of the asynchronous queues.
816 // Parameters: ppStatistics = statistics structure
818 // Returns: tEplKernel = error code
823 //---------------------------------------------------------------------------
825 tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
827 tEplKernel Ret = kEplSuccessful;
832 ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
833 &EplDllkCalInstance_g.m_Statistics.
834 m_ulCurTxFrameCountNmt);
836 ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen,
837 &EplDllkCalInstance_g.m_Statistics.
838 m_ulCurTxFrameCountGen);
839 // ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceRx, &EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount);
842 if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) {
843 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 1;
845 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 0;
847 if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) {
848 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 1;
850 EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 0;
854 *ppStatistics = &EplDllkCalInstance_g.m_Statistics;
858 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
860 //---------------------------------------------------------------------------
862 // Function: EplDllkCalIssueRequest()
864 // Description: issues a StatusRequest or a IdentRequest to the specified node.
866 // Parameters: Service_p = request service ID
867 // uiNodeId_p = node ID
868 // bSoaFlag1_p = flag1 for this node (transmit in SoA and PReq)
869 // If 0xFF this flag is ignored.
871 // Returns: tEplKernel = error code
876 //---------------------------------------------------------------------------
878 tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
879 unsigned int uiNodeId_p, u8 bSoaFlag1_p)
881 tEplKernel Ret = kEplSuccessful;
883 if (bSoaFlag1_p != 0xFF) {
884 Ret = EplDllkSetFlag1OfNode(uiNodeId_p, bSoaFlag1_p);
885 if (Ret != kEplSuccessful) {
889 // add node to appropriate request queue
891 case kEplDllReqServiceIdent:
893 if (((EplDllkCalInstance_g.m_uiWriteIdentReq +
895 tabentries(EplDllkCalInstance_g.
897 == EplDllkCalInstance_g.m_uiReadIdentReq) { // queue is full
898 Ret = kEplDllAsyncTxBufferFull;
901 EplDllkCalInstance_g.
902 m_auiQueueIdentReq[EplDllkCalInstance_g.
903 m_uiWriteIdentReq] = uiNodeId_p;
904 EplDllkCalInstance_g.m_uiWriteIdentReq =
905 (EplDllkCalInstance_g.m_uiWriteIdentReq +
907 tabentries(EplDllkCalInstance_g.m_auiQueueIdentReq);
911 case kEplDllReqServiceStatus:
913 if (((EplDllkCalInstance_g.m_uiWriteStatusReq +
915 tabentries(EplDllkCalInstance_g.
916 m_auiQueueStatusReq))
917 == EplDllkCalInstance_g.m_uiReadStatusReq) { // queue is full
918 Ret = kEplDllAsyncTxBufferFull;
921 EplDllkCalInstance_g.
922 m_auiQueueStatusReq[EplDllkCalInstance_g.
923 m_uiWriteStatusReq] =
925 EplDllkCalInstance_g.m_uiWriteStatusReq =
926 (EplDllkCalInstance_g.m_uiWriteStatusReq +
928 tabentries(EplDllkCalInstance_g.
929 m_auiQueueStatusReq);
935 Ret = kEplDllInvalidParam;
944 //---------------------------------------------------------------------------
946 // Function: EplDllkCalAsyncGetSoaRequest()
948 // Description: returns next request for SoA. This function is called by DLLk module.
950 // Parameters: pReqServiceId_p = pointer to request service ID
951 // IN: available request for MN NMT or generic request queue (Flag2.PR)
952 // or kEplDllReqServiceNo if queues are empty
954 // puiNodeId_p = OUT: pointer to node ID of next request
955 // = EPL_C_ADR_INVALID, if request is self addressed
957 // Returns: tEplKernel = error code
962 //---------------------------------------------------------------------------
964 tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p,
965 unsigned int *puiNodeId_p)
967 tEplKernel Ret = kEplSuccessful;
968 unsigned int uiCount;
970 // *pReqServiceId_p = kEplDllReqServiceNo;
972 for (uiCount = EPL_DLLKCAL_MAX_QUEUES; uiCount > 0; uiCount--) {
973 switch (EplDllkCalInstance_g.m_uiNextRequestQueue) {
977 EplDllkCalInstance_g.
978 m_uiNextQueueCnRequest <
980 (EplDllkCalInstance_g.
981 m_auiQueueCnRequests) / 2);
982 EplDllkCalInstance_g.
983 m_uiNextQueueCnRequest++) {
984 if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) { // non empty queue found
985 // remove one request from queue
986 EplDllkCalInstance_g.
988 [EplDllkCalInstance_g.
989 m_uiNextQueueCnRequest]--;
991 EplDllkCalInstance_g.
992 m_uiNextQueueCnRequest + 1;
994 kEplDllReqServiceUnspecified;
995 EplDllkCalInstance_g.
996 m_uiNextQueueCnRequest++;
997 if (EplDllkCalInstance_g.m_uiNextQueueCnRequest >= (tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) { // last node reached
998 // continue with CnNmtReq queue at next SoA
999 EplDllkCalInstance_g.
1000 m_uiNextRequestQueue
1006 // all CnGenReq queues are empty -> continue with CnNmtReq queue
1007 EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
1014 EplDllkCalInstance_g.
1015 m_uiNextQueueCnRequest <
1016 tabentries(EplDllkCalInstance_g.
1017 m_auiQueueCnRequests);
1018 EplDllkCalInstance_g.
1019 m_uiNextQueueCnRequest++) {
1020 if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) { // non empty queue found
1021 // remove one request from queue
1022 EplDllkCalInstance_g.
1023 m_auiQueueCnRequests
1024 [EplDllkCalInstance_g.
1025 m_uiNextQueueCnRequest]--;
1027 EplDllkCalInstance_g.
1028 m_uiNextQueueCnRequest + 1 -
1030 (EplDllkCalInstance_g.
1031 m_auiQueueCnRequests) /
1034 kEplDllReqServiceNmtRequest;
1035 EplDllkCalInstance_g.
1036 m_uiNextQueueCnRequest++;
1037 if (EplDllkCalInstance_g.m_uiNextQueueCnRequest > tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests)) { // last node reached
1038 // restart CnGenReq queue
1039 EplDllkCalInstance_g.
1040 m_uiNextQueueCnRequest
1042 // continue with MnGenReq queue at next SoA
1043 EplDllkCalInstance_g.
1044 m_uiNextRequestQueue
1050 // restart CnGenReq queue
1051 EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
1052 // all CnNmtReq queues are empty -> continue with MnGenReq queue
1053 EplDllkCalInstance_g.m_uiNextRequestQueue = 2;
1058 { // MnNmtReq and MnGenReq
1059 // next queue will be MnIdentReq queue
1060 EplDllkCalInstance_g.m_uiNextRequestQueue = 3;
1061 if (*pReqServiceId_p != kEplDllReqServiceNo) {
1062 *puiNodeId_p = EPL_C_ADR_INVALID; // DLLk must exchange this with the actual node ID
1070 // next queue will be MnStatusReq queue
1071 EplDllkCalInstance_g.m_uiNextRequestQueue = 4;
1072 if (EplDllkCalInstance_g.m_uiReadIdentReq != EplDllkCalInstance_g.m_uiWriteIdentReq) { // queue is not empty
1074 EplDllkCalInstance_g.
1076 [EplDllkCalInstance_g.
1078 EplDllkCalInstance_g.m_uiReadIdentReq =
1079 (EplDllkCalInstance_g.
1082 tabentries(EplDllkCalInstance_g.
1083 m_auiQueueIdentReq);
1085 kEplDllReqServiceIdent;
1093 // next queue will be CnGenReq queue
1094 EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
1095 if (EplDllkCalInstance_g.m_uiReadStatusReq != EplDllkCalInstance_g.m_uiWriteStatusReq) { // queue is not empty
1097 EplDllkCalInstance_g.
1099 [EplDllkCalInstance_g.
1101 EplDllkCalInstance_g.m_uiReadStatusReq =
1102 (EplDllkCalInstance_g.
1105 tabentries(EplDllkCalInstance_g.
1106 m_auiQueueStatusReq);
1108 kEplDllReqServiceStatus;
1121 //---------------------------------------------------------------------------
1123 // Function: EplDllkCalAsyncSetPendingRequests()
1125 // Description: sets the pending asynchronous frame requests of the specified node.
1126 // This will add the node to the asynchronous request scheduler.
1128 // Parameters: uiNodeId_p = node ID
1129 // AsyncReqPrio_p = asynchronous request priority
1130 // uiCount_p = count of asynchronous frames
1132 // Returns: tEplKernel = error code
1137 //---------------------------------------------------------------------------
1139 tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p,
1140 tEplDllAsyncReqPriority
1142 unsigned int uiCount_p)
1144 tEplKernel Ret = kEplSuccessful;
1146 // add node to appropriate request queue
1147 switch (AsyncReqPrio_p) {
1148 case kEplDllAsyncReqPrioNmt:
1153 (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) {
1154 Ret = kEplDllInvalidParam;
1158 tabentries(EplDllkCalInstance_g.
1159 m_auiQueueCnRequests) / 2;
1160 EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] =
1170 (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) {
1171 Ret = kEplDllInvalidParam;
1174 EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] =
1183 #endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1185 //=========================================================================//
1187 // P R I V A T E F U N C T I O N S //
1189 //=========================================================================//
1191 //---------------------------------------------------------------------------
1192 // Callback handler for new data signaling
1193 //---------------------------------------------------------------------------
1196 /*static void EplDllkCalTxNmtSignalHandler (
1197 tShbInstance pShbRxInstance_p,
1198 unsigned long ulDataSize_p)
1200 tEplKernel Ret = kEplSuccessful;
1202 tEplDllAsyncReqPriority Priority;
1205 unsigned long ulBlockCount;
1207 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulBlockCount);
1208 if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
1210 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulBlockCount;
1215 // post event to DLL
1216 Priority = kEplDllAsyncReqPrioNmt;
1217 Event.m_EventSink = kEplEventSinkDllk;
1218 Event.m_EventType = kEplEventTypeDllkFillTx;
1219 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
1220 Event.m_pArg = &Priority;
1221 Event.m_uiSize = sizeof(Priority);
1222 Ret = EplEventkPost(&Event);
1226 static void EplDllkCalTxGenSignalHandler (
1227 tShbInstance pShbRxInstance_p,
1228 unsigned long ulDataSize_p)
1230 tEplKernel Ret = kEplSuccessful;
1232 tEplDllAsyncReqPriority Priority;
1235 unsigned long ulBlockCount;
1237 ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulBlockCount);
1238 if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
1240 EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulBlockCount;
1245 // post event to DLL
1246 Priority = kEplDllAsyncReqPrioGeneric;
1247 Event.m_EventSink = kEplEventSinkDllk;
1248 Event.m_EventType = kEplEventTypeDllkFillTx;
1249 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
1250 Event.m_pArg = &Priority;
1251 Event.m_uiSize = sizeof(Priority);
1252 Ret = EplEventkPost(&Event);
1258 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)