]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/staging/epl/EplSdoAsndu.c
54b1a175cfd46140164e3d859a4c51827aa5ef21
[linux-2.6-omap-h63xx.git] / drivers / staging / epl / EplSdoAsndu.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 SDO/Asnd-Protocolabstractionlayer 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: EplSdoAsndu.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.7 $  $Date: 2008/10/17 15:32:32 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                     GCC V3.4
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/07/07 k.t.:   start of the implementation
68
69 ****************************************************************************/
70
71 #include "user/EplSdoAsndu.h"
72 #include "user/EplDlluCal.h"
73
74 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
75
76 /***************************************************************************/
77 /*                                                                         */
78 /*                                                                         */
79 /*          G L O B A L   D E F I N I T I O N S                            */
80 /*                                                                         */
81 /*                                                                         */
82 /***************************************************************************/
83
84 //---------------------------------------------------------------------------
85 // const defines
86 //---------------------------------------------------------------------------
87
88 #ifndef EPL_SDO_MAX_CONNECTION_ASND
89 #define EPL_SDO_MAX_CONNECTION_ASND 5
90 #endif
91
92 //---------------------------------------------------------------------------
93 // local types
94 //---------------------------------------------------------------------------
95
96 // instance table
97 typedef struct
98 {
99     unsigned int            m_auiSdoAsndConnection[EPL_SDO_MAX_CONNECTION_ASND];
100     tEplSequLayerReceiveCb  m_fpSdoAsySeqCb;
101
102
103 } tEplSdoAsndInstance;
104
105 //---------------------------------------------------------------------------
106 // modul globale vars
107 //---------------------------------------------------------------------------
108
109 static tEplSdoAsndInstance  SdoAsndInstance_g;
110
111 //---------------------------------------------------------------------------
112 // local function prototypes
113 //---------------------------------------------------------------------------
114
115 tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
116
117 /***************************************************************************/
118 /*                                                                         */
119 /*                                                                         */
120 /*          C L A S S  <EPL SDO-Asnd Protocolabstraction layer>            */
121 /*                                                                         */
122 /*                                                                         */
123 /***************************************************************************/
124 //
125 // Description: EPL SDO-Asnd Protocolabstraction layer
126 //
127 //
128 /***************************************************************************/
129
130
131
132 //=========================================================================//
133 //                                                                         //
134 //          P U B L I C   F U N C T I O N S                                //
135 //                                                                         //
136 //=========================================================================//
137
138 //---------------------------------------------------------------------------
139 //
140 // Function:    EplSdoAsnduInit
141 //
142 // Description: init first instance of the module
143 //
144 //
145 //
146 // Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
147 //                                  callback-function
148 //
149 //
150 // Returns:     tEplKernel  = Errorcode
151 //
152 //
153 // State:
154 //
155 //---------------------------------------------------------------------------
156 tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
157 {
158 tEplKernel  Ret;
159
160
161     Ret = EplSdoAsnduAddInstance(fpReceiveCb_p);
162
163 return Ret;
164 }
165
166
167 //---------------------------------------------------------------------------
168 //
169 // Function:    EplSdoAsnduAddInstance
170 //
171 // Description: init additional instance of the module
172 //
173 //
174 //
175 // Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
176 //                                  callback-function
177 //
178 //
179 // Returns:     tEplKernel  = Errorcode
180 //
181 //
182 // State:
183 //
184 //---------------------------------------------------------------------------
185 tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
186 {
187 tEplKernel  Ret;
188
189     Ret = kEplSuccessful;
190
191     // init control structure
192     EPL_MEMSET(&SdoAsndInstance_g, 0x00, sizeof(SdoAsndInstance_g));
193
194     // save pointer to callback-function
195     if (fpReceiveCb_p != NULL)
196     {
197         SdoAsndInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
198     }
199     else
200     {
201         Ret = kEplSdoUdpMissCb;
202     }
203
204 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
205     Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
206                                    EplSdoAsnduCb,
207                                    kEplDllAsndFilterLocal);
208 #endif
209
210     return Ret;
211 }
212
213 //---------------------------------------------------------------------------
214 //
215 // Function:    EplSdoAsnduDelInstance
216 //
217 // Description: del instance of the module
218 //              del socket and del Listen-Thread
219 //
220 //
221 //
222 // Parameters:
223 //
224 //
225 // Returns:     tEplKernel  = Errorcode
226 //
227 //
228 // State:
229 //
230 //---------------------------------------------------------------------------
231 tEplKernel PUBLIC EplSdoAsnduDelInstance()
232 {
233 tEplKernel  Ret;
234
235     Ret = kEplSuccessful;
236
237 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
238     // deregister callback function from DLL
239     Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
240                                    NULL,
241                                    kEplDllAsndFilterNone);
242 #endif
243
244 return Ret;
245 }
246
247
248 //---------------------------------------------------------------------------
249 //
250 // Function:    EplSdoAsnduInitCon
251 //
252 // Description: init a new connect
253 //
254 //
255 //
256 // Parameters:  pSdoConHandle_p = pointer for the new connection handle
257 //              uiTargetNodeId_p = NodeId of the target node
258 //
259 //
260 // Returns:     tEplKernel  = Errorcode
261 //
262 //
263 // State:
264 //
265 //---------------------------------------------------------------------------
266 tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl*  pSdoConHandle_p,
267                                unsigned int    uiTargetNodeId_p)
268 {
269 tEplKernel      Ret;
270 unsigned int    uiCount;
271 unsigned int    uiFreeCon;
272 unsigned int*   puiConnection;
273
274     Ret = kEplSuccessful;
275
276     if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
277         || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST))
278     {
279         Ret = kEplSdoAsndInvalidNodeId;
280         goto Exit;
281     }
282
283     // get free entry in control structure
284     uiCount = 0;
285     uiFreeCon = EPL_SDO_MAX_CONNECTION_ASND;
286     puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
287     while(uiCount < EPL_SDO_MAX_CONNECTION_ASND)
288     {
289         if (*puiConnection == uiTargetNodeId_p)
290         {   // existing connection to target node found
291             // save handle for higher layer
292             *pSdoConHandle_p = (uiCount | EPL_SDO_ASND_HANDLE );
293
294             goto Exit;
295         }
296         else if (*puiConnection == 0)
297         {   // free entry-> save target nodeId
298             uiFreeCon = uiCount;
299         }
300         uiCount++;
301         puiConnection++;
302     }
303
304     if (uiFreeCon == EPL_SDO_MAX_CONNECTION_ASND)
305     {
306         // no free connection
307         Ret = kEplSdoAsndNoFreeHandle;
308     }
309     else
310     {
311         puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeCon];
312         *puiConnection = uiTargetNodeId_p;
313         // save handle for higher layer
314         *pSdoConHandle_p = (uiFreeCon | EPL_SDO_ASND_HANDLE );
315
316         goto Exit;
317     }
318
319 Exit:
320     return Ret;
321 }
322
323 //---------------------------------------------------------------------------
324 //
325 // Function:    EplSdoAsnduSendData
326 //
327 // Description: send data using exisiting connection
328 //
329 //
330 //
331 // Parameters:  SdoConHandle_p  = connection handle
332 //              pSrcData_p      = pointer to data
333 //              dwDataSize_p    = number of databyte
334 //                                  -> without asnd-header!!!
335 //
336 // Returns:     tEplKernel  = Errorcode
337 //
338 //
339 // State:
340 //
341 //---------------------------------------------------------------------------
342 tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl       SdoConHandle_p,
343                                     tEplFrame *          pSrcData_p,
344                                     DWORD                dwDataSize_p)
345 {
346 tEplKernel      Ret;
347 unsigned int    uiArray;
348 tEplFrameInfo   FrameInfo;
349
350     Ret = kEplSuccessful;
351
352     uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
353
354     if(uiArray > EPL_SDO_MAX_CONNECTION_ASND)
355     {
356         Ret = kEplSdoAsndInvalidHandle;
357         goto Exit;
358     }
359
360     // fillout Asnd header
361     // own node id not needed -> filled by DLL
362
363     // set message type
364     AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (BYTE)kEplMsgTypeAsnd); // ASnd == 0x06
365     // target node id
366     AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, (BYTE) SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray]);
367     // set source-nodeid (filled by DLL 0)
368     AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
369
370     // calc size
371     dwDataSize_p += EPL_ASND_HEADER_SIZE;
372
373     // send function of DLL
374     FrameInfo.m_uiFrameSize = dwDataSize_p;
375     FrameInfo.m_pFrame = pSrcData_p;
376     EPL_MEMSET(&FrameInfo.m_NetTime , 0x00, sizeof(tEplNetTime));
377 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
378     Ret = EplDlluCalAsyncSend(&FrameInfo,kEplDllAsyncReqPrioGeneric);
379 #endif
380
381 Exit:
382     return Ret;
383
384 }
385
386 //---------------------------------------------------------------------------
387 //
388 // Function:    EplSdoAsnduDelCon
389 //
390 // Description: delete connection from intern structure
391 //
392 //
393 //
394 // Parameters:  SdoConHandle_p  = connection handle
395 //
396 // Returns:     tEplKernel  = Errorcode
397 //
398 //
399 // State:
400 //
401 //---------------------------------------------------------------------------
402 tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
403 {
404 tEplKernel  Ret;
405 unsigned int    uiArray;
406
407     Ret = kEplSuccessful;
408
409
410     uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
411     // check parameter
412     if(uiArray > EPL_SDO_MAX_CONNECTION_ASND)
413     {
414         Ret = kEplSdoAsndInvalidHandle;
415         goto Exit;
416     }
417
418     // set target nodeId to 0
419     SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray] = 0;
420
421 Exit:
422     return Ret;
423 }
424
425 //=========================================================================//
426 //                                                                         //
427 //          P R I V A T E   F U N C T I O N S                              //
428 //                                                                         //
429 //=========================================================================//
430
431 //---------------------------------------------------------------------------
432 //
433 // Function:    EplSdoAsnduCb
434 //
435 // Description: callback function for SDO ASnd frames
436 //
437 //
438 //
439 // Parameters:      pFrameInfo_p = Frame with SDO payload
440 //
441 //
442 // Returns:         tEplKernel = errorcode
443 //
444 //
445 // State:
446 //
447 //---------------------------------------------------------------------------
448 tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)
449 {
450 tEplKernel      Ret = kEplSuccessful;
451 unsigned int    uiCount;
452 unsigned int*   puiConnection;
453 unsigned int    uiNodeId;
454 unsigned int    uiFreeEntry = 0xFFFF;
455 tEplSdoConHdl   SdoConHdl;
456 tEplFrame*      pFrame;
457
458     pFrame = pFrameInfo_p->m_pFrame;
459
460     uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
461
462     // search corresponding entry in control structure
463     uiCount = 0;
464     puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
465     while (uiCount < EPL_SDO_MAX_CONNECTION_ASND)
466     {
467         if (uiNodeId == *puiConnection)
468         {
469             break;
470         }
471         else if ((*puiConnection == 0)
472             && (uiFreeEntry == 0xFFFF))
473         {   // free entry
474             uiFreeEntry = uiCount;
475         }
476         uiCount++;
477         puiConnection++;
478     }
479
480     if (uiCount == EPL_SDO_MAX_CONNECTION_ASND)
481     {
482         if (uiFreeEntry != 0xFFFF)
483         {
484             puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeEntry];
485             *puiConnection = uiNodeId;
486             uiCount = uiFreeEntry;
487         }
488         else
489         {
490             EPL_DBGLVL_SDO_TRACE0("EplSdoAsnduCb(): no free handle\n");
491             goto Exit;
492         }
493     }
494 //    if (uiNodeId == *puiConnection)
495     {   // entry found or created
496         SdoConHdl = (uiCount | EPL_SDO_ASND_HANDLE );
497
498         SdoAsndInstance_g.m_fpSdoAsySeqCb(SdoConHdl, &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame, (pFrameInfo_p->m_uiFrameSize - 18));
499     }
500
501 Exit:
502     return Ret;
503
504 }
505
506
507 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
508 // EOF
509