]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/staging/epl/EplDllkCal.c
de67e5bbee98a814dd72ff9b28bca9e91d9caeb4
[linux-2.6-omap-h63xx.git] / drivers / staging / epl / EplDllkCal.c
1 /****************************************************************************
2
3   (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4       www.systec-electronic.com
5
6   Project:      openPOWERLINK
7
8   Description:  source file for kernel DLL Communication Abstraction Layer module
9
10   License:
11
12     Redistribution and use in source and binary forms, with or without
13     modification, are permitted provided that the following conditions
14     are met:
15
16     1. Redistributions of source code must retain the above copyright
17        notice, this list of conditions and the following disclaimer.
18
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.
22
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.
27
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.
40
41     Severability Clause:
42
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.
49
50   -------------------------------------------------------------------------
51
52                 $RCSfile: EplDllkCal.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.7 $  $Date: 2008/11/13 17:13:09 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                     GCC V3.4
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/06/15 d.k.:   start of the implementation, version 1.00
68
69 ****************************************************************************/
70
71 #include "kernel/EplDllkCal.h"
72 #include "kernel/EplDllk.h"
73 #include "kernel/EplEventk.h"
74
75 #include "EplDllCal.h"
76 #ifndef EPL_NO_FIFO
77 #include "SharedBuff.h"
78 #endif
79
80 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
81 /***************************************************************************/
82 /*                                                                         */
83 /*                                                                         */
84 /*          G L O B A L   D E F I N I T I O N S                            */
85 /*                                                                         */
86 /*                                                                         */
87 /***************************************************************************/
88
89 //---------------------------------------------------------------------------
90 // const defines
91 //---------------------------------------------------------------------------
92
93 #ifndef min
94 #define min(a,b)            (((a) < (b)) ? (a) : (b))
95 #endif
96
97 //---------------------------------------------------------------------------
98 // local types
99 //---------------------------------------------------------------------------
100
101 //---------------------------------------------------------------------------
102 // modul globale vars
103 //---------------------------------------------------------------------------
104
105 //---------------------------------------------------------------------------
106 // local function prototypes
107 //---------------------------------------------------------------------------
108
109
110 /***************************************************************************/
111 /*                                                                         */
112 /*                                                                         */
113 /*          C L A S S  EplDllkCal                                          */
114 /*                                                                         */
115 /*                                                                         */
116 /***************************************************************************/
117 //
118 // Description:
119 //
120 //
121 /***************************************************************************/
122
123
124 //=========================================================================//
125 //                                                                         //
126 //          P R I V A T E   D E F I N I T I O N S                          //
127 //                                                                         //
128 //=========================================================================//
129
130 //---------------------------------------------------------------------------
131 // const defines
132 //---------------------------------------------------------------------------
133
134 #define EPL_DLLKCAL_MAX_QUEUES  5   // CnGenReq, CnNmtReq, {MnGenReq, MnNmtReq}, MnIdentReq, MnStatusReq
135
136 //---------------------------------------------------------------------------
137 // local types
138 //---------------------------------------------------------------------------
139
140 typedef struct
141 {
142 #ifndef EPL_NO_FIFO
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
146 #else
147     unsigned int    m_uiFrameSizeNmt;
148     BYTE            m_abFrameNmt[1500];
149     unsigned int    m_uiFrameSizeGen;
150     BYTE            m_abFrameGen[1500];
151 #endif
152
153     tEplDllkCalStatistics   m_Statistics;
154
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;
160
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;
165
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;
171 #endif
172
173 } tEplDllkCalInstance;
174
175 //---------------------------------------------------------------------------
176 // local vars
177 //---------------------------------------------------------------------------
178
179 // if no dynamic memory allocation shall be used
180 // define structures statically
181 static tEplDllkCalInstance     EplDllkCalInstance_g;
182
183 //---------------------------------------------------------------------------
184 // local function prototypes
185 //---------------------------------------------------------------------------
186
187
188 //=========================================================================//
189 //                                                                         //
190 //          P U B L I C   F U N C T I O N S                                //
191 //                                                                         //
192 //=========================================================================//
193
194 //---------------------------------------------------------------------------
195 //
196 // Function:    EplDllkCalAddInstance()
197 //
198 // Description: add and initialize new instance of DLL CAL module
199 //
200 // Parameters:  none
201 //
202 // Returns:     tEplKernel              = error code
203 //
204 //
205 // State:
206 //
207 //---------------------------------------------------------------------------
208
209 tEplKernel EplDllkCalAddInstance()
210 {
211 tEplKernel      Ret = kEplSuccessful;
212 #ifndef EPL_NO_FIFO
213 tShbError       ShbError;
214 unsigned int    fShbNewCreated;
215
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
219
220     if (ShbError != kShbOk)
221     {
222         Ret = kEplNoResource;
223     }
224 */
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
228
229     if (ShbError != kShbOk)
230     {
231         Ret = kEplNoResource;
232     }
233
234 /*    ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxNmt, EplDllkCalTxNmtSignalHandler, kShbPriorityNormal);
235     // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
236
237     if (ShbError != kShbOk)
238     {
239         Ret = kEplNoResource;
240     }
241 */
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
245
246     if (ShbError != kShbOk)
247     {
248         Ret = kEplNoResource;
249     }
250
251 /*    ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxGen, EplDllkCalTxGenSignalHandler, kShbPriorityNormal);
252     // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
253
254     if (ShbError != kShbOk)
255     {
256         Ret = kEplNoResource;
257     }
258 */
259 #else
260     EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
261     EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
262 #endif
263
264     return Ret;
265 }
266
267 //---------------------------------------------------------------------------
268 //
269 // Function:    EplDllkCalDelInstance()
270 //
271 // Description: deletes instance of DLL CAL module
272 //
273 // Parameters:  none
274 //
275 // Returns:     tEplKernel              = error code
276 //
277 //
278 // State:
279 //
280 //---------------------------------------------------------------------------
281
282 tEplKernel EplDllkCalDelInstance()
283 {
284 tEplKernel      Ret = kEplSuccessful;
285 #ifndef EPL_NO_FIFO
286 tShbError       ShbError;
287
288 /*    ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceRx);
289     if (ShbError != kShbOk)
290     {
291         Ret = kEplNoResource;
292     }
293     EplDllkCalInstance_g.m_ShbInstanceRx = NULL;
294 */
295     ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceTxNmt);
296     if (ShbError != kShbOk)
297     {
298         Ret = kEplNoResource;
299     }
300     EplDllkCalInstance_g.m_ShbInstanceTxNmt = NULL;
301
302     ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceTxGen);
303     if (ShbError != kShbOk)
304     {
305         Ret = kEplNoResource;
306     }
307     EplDllkCalInstance_g.m_ShbInstanceTxGen = NULL;
308
309 #else
310     EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
311     EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
312 #endif
313
314     return Ret;
315 }
316
317 //---------------------------------------------------------------------------
318 //
319 // Function:    EplDllkCalProcess
320 //
321 // Description: process the passed configuration
322 //
323 // Parameters:  pEvent_p                = event containing configuration options
324 //
325 // Returns:     tEplKernel              = error code
326 //
327 //
328 // State:
329 //
330 //---------------------------------------------------------------------------
331
332 tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p)
333 {
334 tEplKernel      Ret = kEplSuccessful;
335
336     switch (pEvent_p->m_EventType)
337     {
338         case kEplEventTypeDllkServFilter:
339         {
340         tEplDllCalAsndServiceIdFilter*  pServFilter;
341
342             pServFilter = (tEplDllCalAsndServiceIdFilter*) pEvent_p->m_pArg;
343             Ret = EplDllkSetAsndServiceIdFilter(pServFilter->m_ServiceId, pServFilter->m_Filter);
344             break;
345         }
346
347 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
348         case kEplEventTypeDllkIssueReq:
349         {
350         tEplDllCalIssueRequest*  pIssueReq;
351
352             pIssueReq = (tEplDllCalIssueRequest*) pEvent_p->m_pArg;
353             Ret = EplDllkCalIssueRequest(pIssueReq->m_Service, pIssueReq->m_uiNodeId, pIssueReq->m_bSoaFlag1);
354             break;
355         }
356
357         case kEplEventTypeDllkAddNode:
358         {
359         tEplDllNodeInfo*    pNodeInfo;
360
361             pNodeInfo = (tEplDllNodeInfo*) pEvent_p->m_pArg;
362             Ret = EplDllkAddNode(pNodeInfo);
363             break;
364         }
365
366         case kEplEventTypeDllkDelNode:
367         {
368         unsigned int*   puiNodeId;
369
370             puiNodeId = (unsigned int*) pEvent_p->m_pArg;
371             Ret = EplDllkDeleteNode(*puiNodeId);
372             break;
373         }
374
375         case kEplEventTypeDllkSoftDelNode:
376         {
377         unsigned int*   puiNodeId;
378
379             puiNodeId = (unsigned int*) pEvent_p->m_pArg;
380             Ret = EplDllkSoftDeleteNode(*puiNodeId);
381             break;
382         }
383 #endif
384
385         case kEplEventTypeDllkIdentity:
386         {
387         tEplDllIdentParam*  pIdentParam;
388
389             pIdentParam = (tEplDllIdentParam*) pEvent_p->m_pArg;
390             if (pIdentParam->m_uiSizeOfStruct > pEvent_p->m_uiSize)
391             {
392                 pIdentParam->m_uiSizeOfStruct = pEvent_p->m_uiSize;
393             }
394             Ret = EplDllkSetIdentity(pIdentParam);
395             break;
396         }
397
398         case kEplEventTypeDllkConfig:
399         {
400         tEplDllConfigParam* pConfigParam;
401
402             pConfigParam = (tEplDllConfigParam*) pEvent_p->m_pArg;
403             if (pConfigParam->m_uiSizeOfStruct > pEvent_p->m_uiSize)
404             {
405                 pConfigParam->m_uiSizeOfStruct = pEvent_p->m_uiSize;
406             }
407             Ret = EplDllkConfig(pConfigParam);
408             break;
409         }
410
411         default:
412             break;
413     }
414
415 //Exit:
416     return Ret;
417 }
418
419
420 //---------------------------------------------------------------------------
421 //
422 // Function:    EplDllkCalAsyncGetTxCount()
423 //
424 // Description: returns count of Tx frames of FIFO with highest priority
425 //
426 // Parameters:  none
427 //
428 // Returns:     tEplKernel              = error code
429 //
430 //
431 // State:
432 //
433 //---------------------------------------------------------------------------
434
435 tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p, unsigned int * puiCount_p)
436 {
437 tEplKernel  Ret = kEplSuccessful;
438 #ifndef EPL_NO_FIFO
439 tShbError       ShbError;
440 unsigned long   ulFrameCount;
441
442     // get frame count of Tx FIFO with NMT request priority
443     ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulFrameCount);
444     // returns kShbOk, kShbInvalidArg
445
446     // error handling
447     if (ShbError != kShbOk)
448     {
449         Ret = kEplNoResource;
450         goto Exit;
451     }
452
453     if (ulFrameCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
454     {
455         EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulFrameCount;
456     }
457
458     if (ulFrameCount != 0)
459     {   // NMT requests are in queue
460         *pPriority_p = kEplDllAsyncReqPrioNmt;
461         *puiCount_p = (unsigned int) ulFrameCount;
462         goto Exit;
463     }
464
465     // get frame count of Tx FIFO with generic priority
466     ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulFrameCount);
467     // returns kShbOk, kShbInvalidArg
468
469     // error handling
470     if (ShbError != kShbOk)
471     {
472         Ret = kEplNoResource;
473         goto Exit;
474     }
475
476     if (ulFrameCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
477     {
478         EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulFrameCount;
479     }
480
481     *pPriority_p = kEplDllAsyncReqPrioGeneric;
482     *puiCount_p = (unsigned int) ulFrameCount;
483
484 Exit:
485 #else
486     if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0)
487     {
488         *pPriority_p = kEplDllAsyncReqPrioNmt;
489         *puiCount_p = 1;
490     }
491     else if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0)
492     {
493         *pPriority_p = kEplDllAsyncReqPrioGeneric;
494         *puiCount_p = 1;
495     }
496     else
497     {
498         *pPriority_p = kEplDllAsyncReqPrioGeneric;
499         *puiCount_p = 0;
500     }
501 #endif
502
503     return Ret;
504 }
505
506 //---------------------------------------------------------------------------
507 //
508 // Function:    EplDllkCalAsyncGetTxFrame()
509 //
510 // Description: returns Tx frames from FIFO with specified priority
511 //
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
516 //
517 // Returns:     tEplKernel              = error code
518 //
519 //
520 // State:
521 //
522 //---------------------------------------------------------------------------
523
524 tEplKernel EplDllkCalAsyncGetTxFrame(void * pFrame_p, unsigned int * puiFrameSize_p, tEplDllAsyncReqPriority Priority_p)
525 {
526 tEplKernel      Ret = kEplSuccessful;
527 #ifndef EPL_NO_FIFO
528 tShbError       ShbError;
529 unsigned long   ulFrameSize;
530
531     switch (Priority_p)
532     {
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
536             break;
537
538         default:    // generic priority
539             ShbError = ShbCirReadDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxGen, (BYTE *) pFrame_p, *puiFrameSize_p, &ulFrameSize);
540             // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
541             break;
542
543     }
544
545     // error handling
546     if (ShbError != kShbOk)
547     {
548         if (ShbError == kShbNoReadableData)
549         {
550             Ret = kEplDllAsyncTxBufferEmpty;
551         }
552         else
553         {   // other error
554             Ret = kEplNoResource;
555         }
556         goto Exit;
557     }
558
559     *puiFrameSize_p = (unsigned int) ulFrameSize;
560
561 Exit:
562 #else
563     switch (Priority_p)
564     {
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;
569             break;
570
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;
575             break;
576     }
577
578 #endif
579
580     return Ret;
581 }
582
583 //---------------------------------------------------------------------------
584 //
585 // Function:    EplDllkCalAsyncFrameReceived()
586 //
587 // Description: passes ASnd frame to receive FIFO.
588 //              It will be called only for frames with registered AsndServiceIds.
589 //
590 // Parameters:  none
591 //
592 // Returns:     tEplKernel              = error code
593 //
594 //
595 // State:
596 //
597 //---------------------------------------------------------------------------
598
599 tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p)
600 {
601 tEplKernel  Ret = kEplSuccessful;
602 tEplEvent   Event;
603
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;
610
611     Ret = EplEventkPost(&Event);
612     if (Ret != kEplSuccessful)
613     {
614         EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount++;
615     }
616     else
617     {
618         EplDllkCalInstance_g.m_Statistics.m_ulMaxRxFrameCount++;
619     }
620
621     return Ret;
622 }
623
624
625 //---------------------------------------------------------------------------
626 //
627 // Function:    EplDllkCalAsyncSend()
628 //
629 // Description: puts the given frame into the transmit FIFO with the specified
630 //              priority.
631 //
632 // Parameters:  pFrameInfo_p            = frame info structure
633 //              Priority_p              = priority
634 //
635 // Returns:     tEplKernel              = error code
636 //
637 //
638 // State:
639 //
640 //---------------------------------------------------------------------------
641
642 tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p, tEplDllAsyncReqPriority Priority_p)
643 {
644 tEplKernel  Ret = kEplSuccessful;
645 tEplEvent       Event;
646 #ifndef EPL_NO_FIFO
647 tShbError   ShbError;
648
649     switch (Priority_p)
650     {
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
654             break;
655
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
659             break;
660
661     }
662
663     // error handling
664     switch (ShbError)
665     {
666         case kShbOk:
667             break;
668
669         case kShbExceedDataSizeLimit:
670             Ret = kEplDllAsyncTxBufferFull;
671             break;
672
673         case kShbBufferFull:
674             Ret = kEplDllAsyncTxBufferFull;
675             break;
676
677         case kShbInvalidArg:
678         default:
679             Ret = kEplNoResource;
680             break;
681     }
682
683 #else
684
685     switch (Priority_p)
686     {
687         case kEplDllAsyncReqPrioNmt:    // NMT request priority
688             if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0)
689             {
690                 EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
691                 EplDllkCalInstance_g.m_uiFrameSizeNmt = pFrameInfo_p->m_uiFrameSize;
692             }
693             else
694             {
695                 Ret = kEplDllAsyncTxBufferFull;
696                 goto Exit;
697             }
698             break;
699
700         default:    // generic priority
701             if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0)
702             {
703                 EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
704                 EplDllkCalInstance_g.m_uiFrameSizeGen = pFrameInfo_p->m_uiFrameSize;
705             }
706             else
707             {
708                 Ret = kEplDllAsyncTxBufferFull;
709                 goto Exit;
710             }
711             break;
712     }
713
714 #endif
715
716     // post event to DLL
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);
723
724 #ifdef EPL_NO_FIFO
725 Exit:
726 #endif
727
728     return Ret;
729 }
730
731
732 //---------------------------------------------------------------------------
733 //
734 // Function:    EplDllkCalAsyncClearBuffer()
735 //
736 // Description: clears the transmit buffer
737 //
738 // Parameters:  (none)
739 //
740 // Returns:     tEplKernel              = error code
741 //
742 //
743 // State:
744 //
745 //---------------------------------------------------------------------------
746
747 tEplKernel EplDllkCalAsyncClearBuffer(void)
748 {
749 tEplKernel  Ret = kEplSuccessful;
750 #ifndef EPL_NO_FIFO
751 tShbError   ShbError;
752
753     ShbError = ShbCirResetBuffer (EplDllkCalInstance_g.m_ShbInstanceTxNmt, 1000, NULL);
754     ShbError = ShbCirResetBuffer (EplDllkCalInstance_g.m_ShbInstanceTxGen, 1000, NULL);
755
756 #else
757     EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
758     EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
759 #endif
760
761 //    EPL_MEMSET(&EplDllkCalInstance_g.m_Statistics, 0, sizeof (tEplDllkCalStatistics));
762     return Ret;
763 }
764
765
766 //---------------------------------------------------------------------------
767 //
768 // Function:    EplDllkCalAsyncClearQueues()
769 //
770 // Description: clears the transmit buffer
771 //
772 // Parameters:  (none)
773 //
774 // Returns:     tEplKernel              = error code
775 //
776 //
777 // State:
778 //
779 //---------------------------------------------------------------------------
780
781 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
782 tEplKernel EplDllkCalAsyncClearQueues(void)
783 {
784 tEplKernel  Ret = kEplSuccessful;
785
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;
793
794     return Ret;
795 }
796 #endif
797
798
799 //---------------------------------------------------------------------------
800 //
801 // Function:    EplDllkCalGetStatistics()
802 //
803 // Description: returns statistics of the asynchronous queues.
804 //
805 // Parameters:  ppStatistics            = statistics structure
806 //
807 // Returns:     tEplKernel              = error code
808 //
809 //
810 // State:
811 //
812 //---------------------------------------------------------------------------
813
814 tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
815 {
816 tEplKernel  Ret = kEplSuccessful;
817 #ifndef EPL_NO_FIFO
818 tShbError   ShbError;
819
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);
823
824 #else
825     if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0)
826     {
827         EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 1;
828     }
829     else
830     {
831         EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 0;
832     }
833     if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0)
834     {
835         EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 1;
836     }
837     else
838     {
839         EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 0;
840     }
841 #endif
842
843     *ppStatistics = &EplDllkCalInstance_g.m_Statistics;
844     return Ret;
845 }
846
847
848 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
849
850 //---------------------------------------------------------------------------
851 //
852 // Function:    EplDllkCalIssueRequest()
853 //
854 // Description: issues a StatusRequest or a IdentRequest to the specified node.
855 //
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.
860 //
861 // Returns:     tEplKernel              = error code
862 //
863 //
864 // State:
865 //
866 //---------------------------------------------------------------------------
867
868 tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p, unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
869 {
870 tEplKernel  Ret = kEplSuccessful;
871
872     if (bSoaFlag1_p != 0xFF)
873     {
874         Ret = EplDllkSetFlag1OfNode(uiNodeId_p, bSoaFlag1_p);
875         if (Ret != kEplSuccessful)
876         {
877             goto Exit;
878         }
879     }
880
881     // add node to appropriate request queue
882     switch (Service_p)
883     {
884         case kEplDllReqServiceIdent:
885         {
886             if (((EplDllkCalInstance_g.m_uiWriteIdentReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueIdentReq))
887                 == EplDllkCalInstance_g.m_uiReadIdentReq)
888             {   // queue is full
889                 Ret = kEplDllAsyncTxBufferFull;
890                 goto Exit;
891             }
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);
895             break;
896         }
897
898         case kEplDllReqServiceStatus:
899         {
900             if (((EplDllkCalInstance_g.m_uiWriteStatusReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueStatusReq))
901                 == EplDllkCalInstance_g.m_uiReadStatusReq)
902             {   // queue is full
903                 Ret = kEplDllAsyncTxBufferFull;
904                 goto Exit;
905             }
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);
909             break;
910         }
911
912         default:
913         {
914             Ret = kEplDllInvalidParam;
915             goto Exit;
916         }
917     }
918
919 Exit:
920     return Ret;
921 }
922
923
924 //---------------------------------------------------------------------------
925 //
926 // Function:    EplDllkCalAsyncGetSoaRequest()
927 //
928 // Description: returns next request for SoA. This function is called by DLLk module.
929 //
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
933 //                                        OUT: next request
934 //              puiNodeId_p             = OUT: pointer to node ID of next request
935 //                                             = EPL_C_ADR_INVALID, if request is self addressed
936 //
937 // Returns:     tEplKernel              = error code
938 //
939 //
940 // State:
941 //
942 //---------------------------------------------------------------------------
943
944 tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId* pReqServiceId_p, unsigned int* puiNodeId_p)
945 {
946 tEplKernel      Ret = kEplSuccessful;
947 unsigned int    uiCount;
948
949 //    *pReqServiceId_p = kEplDllReqServiceNo;
950
951     for (uiCount = EPL_DLLKCAL_MAX_QUEUES; uiCount > 0; uiCount--)
952     {
953         switch (EplDllkCalInstance_g.m_uiNextRequestQueue)
954         {
955             case 0:
956             {   // CnGenReq
957                 for (;EplDllkCalInstance_g.m_uiNextQueueCnRequest < (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2);
958                     EplDllkCalInstance_g.m_uiNextQueueCnRequest++)
959                 {
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;
971                         }
972                         goto Exit;
973                     }
974                 }
975                 // all CnGenReq queues are empty -> continue with CnNmtReq queue
976                 EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
977                 break;
978             }
979
980             case 1:
981             {   // CnNmtReq
982                 for (;EplDllkCalInstance_g.m_uiNextQueueCnRequest < tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests);
983                     EplDllkCalInstance_g.m_uiNextQueueCnRequest++)
984                 {
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;
998                         }
999                         goto Exit;
1000                     }
1001                 }
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;
1006                 break;
1007             }
1008
1009             case 2:
1010             {   // MnNmtReq and MnGenReq
1011                 // next queue will be MnIdentReq queue
1012                 EplDllkCalInstance_g.m_uiNextRequestQueue = 3;
1013                 if (*pReqServiceId_p != kEplDllReqServiceNo)
1014                 {
1015                     *puiNodeId_p = EPL_C_ADR_INVALID;   // DLLk must exchange this with the actual node ID
1016                     goto Exit;
1017                 }
1018                 break;
1019             }
1020
1021             case 3:
1022             {   // MnIdentReq
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;
1031                     goto Exit;
1032                 }
1033                 break;
1034             }
1035
1036             case 4:
1037             {   // MnStatusReq
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;
1046                     goto Exit;
1047                 }
1048                 break;
1049             }
1050
1051         }
1052     }
1053
1054 Exit:
1055     return Ret;
1056 }
1057
1058 //---------------------------------------------------------------------------
1059 //
1060 // Function:    EplDllkCalAsyncSetPendingRequests()
1061 //
1062 // Description: sets the pending asynchronous frame requests of the specified node.
1063 //              This will add the node to the asynchronous request scheduler.
1064 //
1065 // Parameters:  uiNodeId_p              = node ID
1066 //              AsyncReqPrio_p          = asynchronous request priority
1067 //              uiCount_p               = count of asynchronous frames
1068 //
1069 // Returns:     tEplKernel              = error code
1070 //
1071 //
1072 // State:
1073 //
1074 //---------------------------------------------------------------------------
1075
1076 tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p, tEplDllAsyncReqPriority AsyncReqPrio_p, unsigned int uiCount_p)
1077 {
1078 tEplKernel  Ret = kEplSuccessful;
1079
1080     // add node to appropriate request queue
1081     switch (AsyncReqPrio_p)
1082     {
1083         case kEplDllAsyncReqPrioNmt:
1084         {
1085             uiNodeId_p--;
1086             if (uiNodeId_p >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
1087             {
1088                 Ret = kEplDllInvalidParam;
1089                 goto Exit;
1090             }
1091             uiNodeId_p += tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2;
1092             EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = uiCount_p;
1093             break;
1094         }
1095
1096         default:
1097         {
1098             uiNodeId_p--;
1099             if (uiNodeId_p >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
1100             {
1101                 Ret = kEplDllInvalidParam;
1102                 goto Exit;
1103             }
1104             EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = uiCount_p;
1105             break;
1106         }
1107     }
1108
1109 Exit:
1110     return Ret;
1111 }
1112 #endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1113
1114 //=========================================================================//
1115 //                                                                         //
1116 //          P R I V A T E   F U N C T I O N S                              //
1117 //                                                                         //
1118 //=========================================================================//
1119
1120 //---------------------------------------------------------------------------
1121 //  Callback handler for new data signaling
1122 //---------------------------------------------------------------------------
1123
1124 #ifndef EPL_NO_FIFO
1125 /*static void  EplDllkCalTxNmtSignalHandler (
1126     tShbInstance pShbRxInstance_p,
1127     unsigned long ulDataSize_p)
1128 {
1129 tEplKernel      Ret = kEplSuccessful;
1130 tEplEvent       Event;
1131 tEplDllAsyncReqPriority Priority;
1132 #ifndef EPL_NO_FIFO
1133 tShbError   ShbError;
1134 unsigned long   ulBlockCount;
1135
1136
1137     ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulBlockCount);
1138     if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
1139     {
1140         EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulBlockCount;
1141     }
1142
1143 #endif
1144
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);
1153
1154 }
1155
1156 static void  EplDllkCalTxGenSignalHandler (
1157     tShbInstance pShbRxInstance_p,
1158     unsigned long ulDataSize_p)
1159 {
1160 tEplKernel      Ret = kEplSuccessful;
1161 tEplEvent       Event;
1162 tEplDllAsyncReqPriority Priority;
1163 #ifndef EPL_NO_FIFO
1164 tShbError   ShbError;
1165 unsigned long   ulBlockCount;
1166
1167
1168     ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulBlockCount);
1169     if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
1170     {
1171         EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulBlockCount;
1172     }
1173
1174 #endif
1175
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);
1184
1185 }
1186 */
1187 #endif
1188
1189
1190 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
1191
1192 // EOF
1193