1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for SDO Command 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: EplSdoComu.c,v $
56 $Revision: 1.14 $ $Date: 2008/10/17 15:32:32 $
63 -------------------------------------------------------------------------
67 2006/06/26 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "user/EplSdoComu.h"
73 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) == 0) &&\
74 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) == 0) )
76 #error 'ERROR: At least SDO Server or SDO Client should be activate!'
80 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
81 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
83 #error 'ERROR: SDO Server needs OBDu module!'
89 /***************************************************************************/
92 /* G L O B A L D E F I N I T I O N S */
95 /***************************************************************************/
97 //---------------------------------------------------------------------------
99 //---------------------------------------------------------------------------
101 #ifndef EPL_MAX_SDO_COM_CON
102 #define EPL_MAX_SDO_COM_CON 5
105 //---------------------------------------------------------------------------
107 //---------------------------------------------------------------------------
111 kEplSdoComConEventSendFirst = 0x00, // first frame to send
112 kEplSdoComConEventRec = 0x01, // frame received
113 kEplSdoComConEventConEstablished = 0x02, // connection established
114 kEplSdoComConEventConClosed = 0x03, // connection closed
115 kEplSdoComConEventAckReceived = 0x04, // acknowledge received by lower layer
116 // -> continue sending
117 kEplSdoComConEventFrameSended = 0x05, // lower has send a frame
118 kEplSdoComConEventInitError = 0x06, // error duringinitialisiation
120 kEplSdoComConEventTimeout = 0x07 // timeout in lower layer
121 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
124 kEplSdoComConEventInitCon = 0x08, // init connection (only client)
125 kEplSdoComConEventAbort = 0x09 // abort sdo transfer (only client)
127 } tEplSdoComConEvent;
130 kEplSdoComSendTypeReq = 0x00, // send a request
131 kEplSdoComSendTypeAckRes = 0x01, // send a resonse without data
132 kEplSdoComSendTypeRes = 0x02, // send response with data
133 kEplSdoComSendTypeAbort = 0x03 // send abort
134 } tEplSdoComSendType;
136 // state of the state maschine
139 kEplSdoComStateIdle = 0x00, // idle state
141 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
143 kEplSdoComStateServerSegmTrans = 0x01, // send following frames
146 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
148 kEplSdoComStateClientWaitInit = 0x10, // wait for init connection
150 kEplSdoComStateClientConnected = 0x11, // connection established
151 kEplSdoComStateClientSegmTrans = 0x12 // send following frames
155 // control structure for transaction
157 tEplSdoSeqConHdl m_SdoSeqConHdl; // if != 0 -> entry used
158 tEplSdoComState m_SdoComState;
159 BYTE m_bTransactionId;
160 unsigned int m_uiNodeId; // NodeId of the target
161 // -> needed to reinit connection
163 tEplSdoTransType m_SdoTransType; // Auto, Expedited, Segmented
164 tEplSdoServiceType m_SdoServiceType; // WriteByIndex, ReadByIndex
165 tEplSdoType m_SdoProtType; // protocol layer: Auto, Udp, Asnd, Pdo
166 BYTE *m_pData; // pointer to data
167 unsigned int m_uiTransSize; // number of bytes
169 unsigned int m_uiTransferredByte; // number of bytes
170 // already transferred
171 tEplSdoFinishedCb m_pfnTransferFinished; // callback function of the
173 // -> called in the end of
175 void *m_pUserArg; // user definable argument pointer
177 DWORD m_dwLastAbortCode; // save the last abort code
178 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
180 unsigned int m_uiTargetIndex; // index to access
181 unsigned int m_uiTargetSubIndex; // subiondex to access
184 unsigned int m_uiTimeout; // timeout for this connection
192 tEplSdoComCon m_SdoComCon[EPL_MAX_SDO_COM_CON];
194 #if defined(WIN32) || defined(_WIN32)
195 LPCRITICAL_SECTION m_pCriticalSection;
196 CRITICAL_SECTION m_CriticalSection;
199 } tEplSdoComInstance;
201 //---------------------------------------------------------------------------
202 // modul globale vars
203 //---------------------------------------------------------------------------
204 static tEplSdoComInstance SdoComInstance_g;
205 //---------------------------------------------------------------------------
206 // local function prototypes
207 //---------------------------------------------------------------------------
208 tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
209 tEplAsySdoCom * pAsySdoCom_p,
210 unsigned int uiDataSize_p);
212 tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
213 tEplAsySdoConState AsySdoConState_p);
215 static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
216 tEplSdoComConEvent SdoComConEvent_p,
217 tEplAsySdoCom * pAsySdoCom_p);
219 static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
220 tEplSdoComConEvent SdoComConEvent_p,
221 tEplAsySdoCom * pAsySdoCom_p);
223 static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
224 tEplSdoComCon * pSdoComCon_p,
228 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
229 static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
230 tEplAsySdoCom * pAsySdoCom_p);
232 static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
233 unsigned int uiIndex_p,
234 unsigned int uiSubIndex_p,
235 tEplSdoComSendType SendType_p);
237 static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
238 tEplAsySdoCom * pAsySdoCom_p);
241 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
243 static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p);
245 static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
246 tEplAsySdoCom * pAsySdoCom_p);
248 static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
249 DWORD dwAbortCode_p);
252 /***************************************************************************/
255 /* C L A S S <SDO Command Layer> */
258 /***************************************************************************/
260 // Description: SDO Command layer Modul
263 /***************************************************************************/
265 //=========================================================================//
267 // P U B L I C F U N C T I O N S //
269 //=========================================================================//
271 //---------------------------------------------------------------------------
273 // Function: EplSdoComInit
275 // Description: Init first instance of the module
282 // Returns: tEplKernel = errorcode
287 //---------------------------------------------------------------------------
288 tEplKernel PUBLIC EplSdoComInit(void)
292 Ret = EplSdoComAddInstance();
298 //---------------------------------------------------------------------------
300 // Function: EplSdoComAddInstance
302 // Description: Init additional instance of the module
309 // Returns: tEplKernel = errorcode
314 //---------------------------------------------------------------------------
315 tEplKernel PUBLIC EplSdoComAddInstance(void)
319 Ret = kEplSuccessful;
321 // init controll structure
322 EPL_MEMSET(&SdoComInstance_g, 0x00, sizeof(SdoComInstance_g));
324 // init instance of lower layer
325 Ret = EplSdoAsySeqAddInstance(EplSdoComReceiveCb, EplSdoComConCb);
326 if (Ret != kEplSuccessful) {
329 #if defined(WIN32) || defined(_WIN32)
330 // create critical section for process function
331 SdoComInstance_g.m_pCriticalSection =
332 &SdoComInstance_g.m_CriticalSection;
333 InitializeCriticalSection(SdoComInstance_g.m_pCriticalSection);
340 //---------------------------------------------------------------------------
342 // Function: EplSdoComDelInstance
344 // Description: delete instance of the module
351 // Returns: tEplKernel = errorcode
356 //---------------------------------------------------------------------------
357 tEplKernel PUBLIC EplSdoComDelInstance(void)
361 Ret = kEplSuccessful;
363 #if defined(WIN32) || defined(_WIN32)
364 // delete critical section for process function
365 DeleteCriticalSection(SdoComInstance_g.m_pCriticalSection);
368 Ret = EplSdoAsySeqDelInstance();
369 if (Ret != kEplSuccessful) {
377 //---------------------------------------------------------------------------
379 // Function: EplSdoComDefineCon
381 // Description: function defines a SDO connection to another node
382 // -> init lower layer and returns a handle for the connection.
383 // Two client connections to the same node via the same protocol
384 // are not allowed. If this function detects such a situation
385 // it will return kEplSdoComHandleExists and the handle of
386 // the existing connection in pSdoComConHdl_p.
387 // Using of existing server connections is possible.
389 // Parameters: pSdoComConHdl_p = pointer to the buffer of the handle
390 // uiTargetNodeId_p = NodeId of the targetnode
391 // ProtType_p = type of protocol to use for connection
394 // Returns: tEplKernel = errorcode
399 //---------------------------------------------------------------------------
400 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
401 tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
402 unsigned int uiTargetNodeId_p,
403 tEplSdoType ProtType_p)
406 unsigned int uiCount;
407 unsigned int uiFreeHdl;
408 tEplSdoComCon *pSdoComCon;
411 ASSERT(pSdoComConHdl_p != NULL);
414 if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
415 || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) {
416 Ret = kEplInvalidNodeId;
419 // search free control structure
420 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
422 uiFreeHdl = EPL_MAX_SDO_COM_CON;
423 while (uiCount < EPL_MAX_SDO_COM_CON) {
424 if (pSdoComCon->m_SdoSeqConHdl == 0) { // free entry
426 } else if ((pSdoComCon->m_uiNodeId == uiTargetNodeId_p)
427 && (pSdoComCon->m_SdoProtType == ProtType_p)) { // existing client connection with same node ID and same protocol type
428 *pSdoComConHdl_p = uiCount;
429 Ret = kEplSdoComHandleExists;
436 if (uiFreeHdl == EPL_MAX_SDO_COM_CON) {
437 Ret = kEplSdoComNoFreeHandle;
441 pSdoComCon = &SdoComInstance_g.m_SdoComCon[uiFreeHdl];
442 // save handle for application
443 *pSdoComConHdl_p = uiFreeHdl;
445 pSdoComCon->m_SdoProtType = ProtType_p;
446 pSdoComCon->m_uiNodeId = uiTargetNodeId_p;
448 // set Transaction Id
449 pSdoComCon->m_bTransactionId = 0;
452 switch (ProtType_p) {
456 // call connection int function of lower layer
457 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
458 pSdoComCon->m_uiNodeId,
460 if (Ret != kEplSuccessful) {
467 case kEplSdoTypeAsnd:
469 // call connection int function of lower layer
470 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
471 pSdoComCon->m_uiNodeId,
473 if (Ret != kEplSuccessful) {
479 // Pdo -> not supported
483 Ret = kEplSdoComUnsupportedProt;
486 } // end of switch(m_ProtType_p)
488 // call process function
489 Ret = EplSdoComProcessIntern(uiFreeHdl,
490 kEplSdoComConEventInitCon, NULL);
496 //---------------------------------------------------------------------------
498 // Function: EplSdoComInitTransferByIndex
500 // Description: function init SDO Transfer for a defined connection
504 // Parameters: SdoComTransParam_p = Structure with parameters for connection
507 // Returns: tEplKernel = errorcode
512 //---------------------------------------------------------------------------
513 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
514 tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
518 tEplSdoComCon *pSdoComCon;
521 if ((pSdoComTransParam_p->m_uiSubindex >= 0xFF)
522 || (pSdoComTransParam_p->m_uiIndex == 0)
523 || (pSdoComTransParam_p->m_uiIndex > 0xFFFF)
524 || (pSdoComTransParam_p->m_pData == NULL)
525 || (pSdoComTransParam_p->m_uiDataSize == 0)) {
526 Ret = kEplSdoComInvalidParam;
530 if (pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON) {
531 Ret = kEplSdoComInvalidHandle;
534 // get pointer to control structure of connection
536 &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl];
538 // check if handle ok
539 if (pSdoComCon->m_SdoSeqConHdl == 0) {
540 Ret = kEplSdoComInvalidHandle;
543 // check if command layer is idle
544 if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0) { // handle is not idle
545 Ret = kEplSdoComHandleBusy;
549 // callback function for end of transfer
550 pSdoComCon->m_pfnTransferFinished =
551 pSdoComTransParam_p->m_pfnSdoFinishedCb;
552 pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg;
554 // set type of SDO command
555 if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead) {
556 pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex;
558 pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex;
561 // save pointer to data
562 pSdoComCon->m_pData = pSdoComTransParam_p->m_pData;
563 // maximal bytes to transfer
564 pSdoComCon->m_uiTransSize = pSdoComTransParam_p->m_uiDataSize;
565 // bytes already transfered
566 pSdoComCon->m_uiTransferredByte = 0;
568 // reset parts of control structure
569 pSdoComCon->m_dwLastAbortCode = 0;
570 pSdoComCon->m_SdoTransType = kEplSdoTransAuto;
572 //pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout;
574 // save index and subindex
575 pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex;
576 pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex;
578 // call process function
579 Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl, kEplSdoComConEventSendFirst, // event to start transfer
588 //---------------------------------------------------------------------------
590 // Function: EplSdoComUndefineCon
592 // Description: function undefine a SDO connection
596 // Parameters: SdoComConHdl_p = handle for the connection
599 // Returns: tEplKernel = errorcode
604 //---------------------------------------------------------------------------
605 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
606 tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
609 tEplSdoComCon *pSdoComCon;
611 Ret = kEplSuccessful;
613 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
614 Ret = kEplSdoComInvalidHandle;
617 // get pointer to control structure
618 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
620 // $$$ d.k. abort a running transfer before closing the sequence layer
622 if (((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) !=
623 EPL_SDO_SEQ_INVALID_HDL)
624 && (pSdoComCon->m_SdoSeqConHdl != 0)) {
625 // close connection in lower layer
626 switch (pSdoComCon->m_SdoProtType) {
627 case kEplSdoTypeAsnd:
631 EplSdoAsySeqDelCon(pSdoComCon->
637 case kEplSdoTypeAuto:
640 Ret = kEplSdoComUnsupportedProt;
644 } // end of switch(pSdoComCon->m_SdoProtType)
647 // clean controll structure
648 EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
653 //---------------------------------------------------------------------------
655 // Function: EplSdoComGetState
657 // Description: function returns the state fo the connection
661 // Parameters: SdoComConHdl_p = handle for the connection
662 // pSdoComFinished_p = pointer to structur for sdo state
665 // Returns: tEplKernel = errorcode
670 //---------------------------------------------------------------------------
671 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
672 tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
673 tEplSdoComFinished * pSdoComFinished_p)
676 tEplSdoComCon *pSdoComCon;
678 Ret = kEplSuccessful;
680 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
681 Ret = kEplSdoComInvalidHandle;
684 // get pointer to control structure
685 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
687 // check if handle ok
688 if (pSdoComCon->m_SdoSeqConHdl == 0) {
689 Ret = kEplSdoComInvalidHandle;
693 pSdoComFinished_p->m_pUserArg = pSdoComCon->m_pUserArg;
694 pSdoComFinished_p->m_uiNodeId = pSdoComCon->m_uiNodeId;
695 pSdoComFinished_p->m_uiTargetIndex = pSdoComCon->m_uiTargetIndex;
696 pSdoComFinished_p->m_uiTargetSubIndex = pSdoComCon->m_uiTargetSubIndex;
697 pSdoComFinished_p->m_uiTransferredByte =
698 pSdoComCon->m_uiTransferredByte;
699 pSdoComFinished_p->m_dwAbortCode = pSdoComCon->m_dwLastAbortCode;
700 pSdoComFinished_p->m_SdoComConHdl = SdoComConHdl_p;
701 if (pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex) {
702 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeWrite;
704 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead;
707 if (pSdoComCon->m_dwLastAbortCode != 0) { // sdo abort
708 pSdoComFinished_p->m_SdoComConState =
709 kEplSdoComTransferRxAborted;
712 pSdoComCon->m_dwLastAbortCode = 0;
714 } else if ((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL) { // check state
715 pSdoComFinished_p->m_SdoComConState =
716 kEplSdoComTransferLowerLayerAbort;
717 } else if (pSdoComCon->m_SdoComState == kEplSdoComStateClientWaitInit) {
719 pSdoComFinished_p->m_SdoComConState =
720 kEplSdoComTransferNotActive;
721 } else if (pSdoComCon->m_uiTransSize == 0) { // finished
722 pSdoComFinished_p->m_SdoComConState =
723 kEplSdoComTransferFinished;
731 //---------------------------------------------------------------------------
733 // Function: EplSdoComSdoAbort
735 // Description: function abort a sdo transfer
739 // Parameters: SdoComConHdl_p = handle for the connection
740 // dwAbortCode_p = abort code
743 // Returns: tEplKernel = errorcode
748 //---------------------------------------------------------------------------
749 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
750 tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
754 tEplSdoComCon *pSdoComCon;
756 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
757 Ret = kEplSdoComInvalidHandle;
760 // get pointer to control structure of connection
761 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
763 // check if handle ok
764 if (pSdoComCon->m_SdoSeqConHdl == 0) {
765 Ret = kEplSdoComInvalidHandle;
768 // save pointer to abort code
769 pSdoComCon->m_pData = (BYTE *) & dwAbortCode_p;
771 Ret = EplSdoComProcessIntern(SdoComConHdl_p,
772 kEplSdoComConEventAbort,
773 (tEplAsySdoCom *) NULL);
780 //=========================================================================//
782 // P R I V A T E F U N C T I O N S //
784 //=========================================================================//
786 //---------------------------------------------------------------------------
788 // Function: EplSdoComReceiveCb
790 // Description: callback function for SDO Sequence Layer
791 // -> indicates new data
795 // Parameters: SdoSeqConHdl_p = Handle for connection
796 // pAsySdoCom_p = pointer to data
797 // uiDataSize_p = size of data ($$$ not used yet, but it should)
805 //---------------------------------------------------------------------------
806 tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
807 tEplAsySdoCom * pAsySdoCom_p,
808 unsigned int uiDataSize_p)
812 // search connection internally
813 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
814 kEplSdoComConEventRec, pAsySdoCom_p);
816 EPL_DBGLVL_SDO_TRACE3
817 ("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n",
818 SdoSeqConHdl_p, (WORD) pAsySdoCom_p->m_le_abCommandData[0],
824 //---------------------------------------------------------------------------
826 // Function: EplSdoComConCb
828 // Description: callback function called by SDO Sequence Layer to inform
829 // command layer about state change of connection
833 // Parameters: SdoSeqConHdl_p = Handle of the connection
834 // AsySdoConState_p = Event of the connection
837 // Returns: tEplKernel = Errorcode
842 //---------------------------------------------------------------------------
843 tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
844 tEplAsySdoConState AsySdoConState_p)
847 tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
849 Ret = kEplSuccessful;
852 switch (AsySdoConState_p) {
853 case kAsySdoConStateConnected:
855 EPL_DBGLVL_SDO_TRACE0("Connection established\n");
856 SdoComConEvent = kEplSdoComConEventConEstablished;
857 // start transmission if needed
861 case kAsySdoConStateInitError:
863 EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n");
864 SdoComConEvent = kEplSdoComConEventInitError;
865 // inform app about error and close sequence layer handle
869 case kAsySdoConStateConClosed:
871 EPL_DBGLVL_SDO_TRACE0("Connection closed\n");
872 SdoComConEvent = kEplSdoComConEventConClosed;
873 // close sequence layer handle
877 case kAsySdoConStateAckReceived:
879 EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n");
880 SdoComConEvent = kEplSdoComConEventAckReceived;
881 // continue transmission
885 case kAsySdoConStateFrameSended:
887 EPL_DBGLVL_SDO_TRACE0("One Frame sent\n");
888 SdoComConEvent = kEplSdoComConEventFrameSended;
889 // to continue transmission
894 case kAsySdoConStateTimeout:
896 EPL_DBGLVL_SDO_TRACE0("Timeout\n");
897 SdoComConEvent = kEplSdoComConEventTimeout;
898 // close sequence layer handle
902 } // end of switch(AsySdoConState_p)
904 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
905 SdoComConEvent, (tEplAsySdoCom *) NULL);
910 //---------------------------------------------------------------------------
912 // Function: EplSdoComSearchConIntern
914 // Description: search a Sdo Sequence Layer connection handle in the
915 // control structure of the Command Layer
917 // Parameters: SdoSeqConHdl_p = Handle to search
918 // SdoComConEvent_p = event to process
919 // pAsySdoCom_p = pointer to received frame
921 // Returns: tEplKernel
926 //---------------------------------------------------------------------------
927 static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
928 tEplSdoComConEvent SdoComConEvent_p,
929 tEplAsySdoCom * pAsySdoCom_p)
932 tEplSdoComCon *pSdoComCon;
933 tEplSdoComConHdl HdlCount;
934 tEplSdoComConHdl HdlFree;
936 Ret = kEplSdoComNotResponsible;
938 // get pointer to first element of the array
939 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
942 while (HdlCount < EPL_MAX_SDO_COM_CON) {
943 if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p) { // matching command layer handle found
944 Ret = EplSdoComProcessIntern(HdlCount,
947 } else if ((pSdoComCon->m_SdoSeqConHdl == 0)
948 && (HdlFree == 0xFFFF)) {
956 if (Ret == kEplSdoComNotResponsible) { // no responsible command layer handle found
957 if (HdlFree == 0xFFFF) { // no free handle
958 // delete connection immediately
959 // 2008/04/14 m.u./d.k. This connection actually does not exist.
960 // pSdoComCon is invalid.
961 // Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
962 Ret = kEplSdoComNoFreeHandle;
963 } else { // create new handle
965 pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount];
966 pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p;
967 Ret = EplSdoComProcessIntern(HdlCount,
977 //---------------------------------------------------------------------------
979 // Function: EplSdoComProcessIntern
981 // Description: search a Sdo Sequence Layer connection handle in the
982 // control structer of the Command Layer
986 // Parameters: SdoComCon_p = index of control structure of connection
987 // SdoComConEvent_p = event to process
988 // pAsySdoCom_p = pointer to received frame
990 // Returns: tEplKernel = errorcode
995 //---------------------------------------------------------------------------
996 static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
997 tEplSdoComConEvent SdoComConEvent_p,
998 tEplAsySdoCom * pAsySdoCom_p)
1001 tEplSdoComCon *pSdoComCon;
1004 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1006 unsigned int uiSize;
1009 #if defined(WIN32) || defined(_WIN32)
1010 // enter critical section for process function
1011 EnterCriticalSection(SdoComInstance_g.m_pCriticalSection);
1012 EPL_DBGLVL_SDO_TRACE0
1013 ("\n\tEnterCiticalSection EplSdoComProcessIntern\n\n");
1016 Ret = kEplSuccessful;
1018 // get pointer to control structure
1019 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
1021 // process state maschine
1022 switch (pSdoComCon->m_SdoComState) {
1024 case kEplSdoComStateIdle:
1027 switch (SdoComConEvent_p) {
1028 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1029 // init con for client
1030 case kEplSdoComConEventInitCon:
1033 // call of the init function already
1034 // processed in EplSdoComDefineCon()
1035 // only change state to kEplSdoComStateClientWaitInit
1036 pSdoComCon->m_SdoComState =
1037 kEplSdoComStateClientWaitInit;
1042 // int con for server
1043 case kEplSdoComConEventRec:
1045 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1046 // check if init of an transfer and no SDO abort
1047 if ((pAsySdoCom_p->m_le_bFlags & 0x80) == 0) { // SDO request
1048 if ((pAsySdoCom_p->m_le_bFlags & 0x40) == 0) { // no SDO abort
1049 // save tansaction id
1054 m_le_bTransactionId);
1056 switch (pAsySdoCom_p->
1059 case kEplSdoServiceNIL:
1060 { // simply acknowlegde NIL command on sequence layer
1063 EplSdoAsySeqSendData
1074 case kEplSdoServiceReadByIndex:
1077 // search entry an start transfer
1078 EplSdoComServerInitReadByIndex
1082 if (pSdoComCon->m_uiTransSize == 0) { // ready -> stay idle
1086 kEplSdoComStateIdle;
1092 } else { // segmented transfer
1096 kEplSdoComStateServerSegmTrans;
1102 case kEplSdoServiceWriteByIndex:
1105 // search entry an start write
1106 EplSdoComServerInitWriteByIndex
1110 if (pSdoComCon->m_uiTransSize == 0) { // already -> stay idle
1114 kEplSdoComStateIdle;
1120 } else { // segmented transfer
1124 kEplSdoComStateServerSegmTrans;
1132 // unsupported command
1136 EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER;
1146 EplSdoComServerSendFrameIntern
1150 kEplSdoComSendTypeAbort);
1154 } // end of switch(pAsySdoCom_p->m_le_bCommandId)
1156 } else { // this command layer handle is not responsible
1157 // (wrong direction or wrong transaction ID)
1158 Ret = kEplSdoComNotResponsible;
1161 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1166 // connection closed
1167 case kEplSdoComConEventInitError:
1168 case kEplSdoComConEventTimeout:
1169 case kEplSdoComConEventConClosed:
1172 EplSdoAsySeqDelCon(pSdoComCon->
1174 // clean control structure
1175 EPL_MEMSET(pSdoComCon, 0x00,
1176 sizeof(tEplSdoComCon));
1183 } // end of switch(SdoComConEvent_p)
1187 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1188 //-------------------------------------------------------------------------
1190 // segmented transfer
1191 case kEplSdoComStateServerSegmTrans:
1194 switch (SdoComConEvent_p) {
1196 case kEplSdoComConEventAckReceived:
1197 case kEplSdoComConEventFrameSended:
1199 // check if it is a read
1200 if (pSdoComCon->m_SdoServiceType ==
1201 kEplSdoServiceReadByIndex) {
1203 EplSdoComServerSendFrameIntern
1205 kEplSdoComSendTypeRes);
1206 // if all send -> back to idle
1207 if (pSdoComCon->m_uiTransSize == 0) { // back to idle
1210 kEplSdoComStateIdle;
1221 // process next frame
1222 case kEplSdoComConEventRec:
1224 // check if the frame is a SDO response and has the right transaction ID
1226 AmiGetByteFromLe(&pAsySdoCom_p->
1228 if (((bFlag & 0x80) != 0)
1232 m_le_bTransactionId) ==
1233 pSdoComCon->m_bTransactionId)) {
1234 // check if it is a abort
1235 if ((bFlag & 0x40) != 0) { // SDO abort
1236 // clear control structure
1245 kEplSdoComStateIdle;
1250 // d.k.: do not execute anything further on this command
1253 // check if it is a write
1256 kEplSdoServiceWriteByIndex)
1264 m_dwLastAbortCode ==
1284 m_dwLastAbortCode ==
1291 // check end of transfer
1292 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30) { // transfer ready
1302 EplSdoComServerSendFrameIntern
1306 kEplSdoComSendTypeRes);
1307 // if all send -> back to idle
1308 if (pSdoComCon->m_uiTransSize == 0) { // back to idle
1312 kEplSdoComStateIdle;
1319 } else { // send dabort code
1330 EplSdoComServerSendFrameIntern
1334 kEplSdoComSendTypeAbort);
1343 // send acknowledge without any Command layer data
1345 EplSdoAsySeqSendData
1353 } else { // this command layer handle is not responsible
1354 // (wrong direction or wrong transaction ID)
1355 Ret = kEplSdoComNotResponsible;
1361 // connection closed
1362 case kEplSdoComConEventInitError:
1363 case kEplSdoComConEventTimeout:
1364 case kEplSdoComConEventConClosed:
1367 EplSdoAsySeqDelCon(pSdoComCon->
1369 // clean control structure
1370 EPL_MEMSET(pSdoComCon, 0x00,
1371 sizeof(tEplSdoComCon));
1378 } // end of switch(SdoComConEvent_p)
1382 #endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1384 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1385 //-------------------------------------------------------------------------
1387 // wait for finish of establishing connection
1388 case kEplSdoComStateClientWaitInit:
1391 // if connection handle is invalid reinit connection
1392 // d.k.: this will be done only on new events (i.e. InitTransfer)
1394 m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) ==
1395 EPL_SDO_SEQ_INVALID_HDL) {
1396 // check kind of connection to reinit
1398 switch (pSdoComCon->m_SdoProtType) {
1400 case kEplSdoTypeUdp:
1402 // call connection int function of lower layer
1407 pSdoComCon->m_uiNodeId,
1409 if (Ret != kEplSuccessful) {
1415 // Asend -> not supported
1416 case kEplSdoTypeAsnd:
1418 // call connection int function of lower layer
1423 pSdoComCon->m_uiNodeId,
1425 if (Ret != kEplSuccessful) {
1431 // Pdo -> not supported
1432 case kEplSdoTypePdo:
1435 Ret = kEplSdoComUnsupportedProt;
1438 } // end of switch(m_ProtType_p)
1439 // d.k.: reset transaction ID, because new sequence layer connection was initialized
1440 // $$$ d.k. is this really necessary?
1441 //pSdoComCon->m_bTransactionId = 0;
1444 switch (SdoComConEvent_p) {
1445 // connection established
1446 case kEplSdoComConEventConEstablished:
1448 //send first frame if needed
1449 if ((pSdoComCon->m_uiTransSize > 0)
1450 && (pSdoComCon->m_uiTargetIndex != 0)) { // start SDO transfer
1454 if (Ret != kEplSuccessful) {
1457 // check if segemted transfer
1460 kEplSdoTransSegmented) {
1463 kEplSdoComStateClientSegmTrans;
1467 // goto state kEplSdoComStateClientConnected
1468 pSdoComCon->m_SdoComState =
1469 kEplSdoComStateClientConnected;
1473 case kEplSdoComConEventSendFirst:
1475 // infos for transfer already saved by function EplSdoComInitTransferByIndex
1479 case kEplSdoComConEventConClosed:
1480 case kEplSdoComConEventInitError:
1481 case kEplSdoComConEventTimeout:
1483 // close sequence layer handle
1485 EplSdoAsySeqDelCon(pSdoComCon->
1487 pSdoComCon->m_SdoSeqConHdl |=
1488 EPL_SDO_SEQ_INVALID_HDL;
1489 // call callback function
1490 if (SdoComConEvent_p ==
1491 kEplSdoComConEventTimeout) {
1492 pSdoComCon->m_dwLastAbortCode =
1495 pSdoComCon->m_dwLastAbortCode =
1499 EplSdoComTransferFinished
1500 (SdoComCon_p, pSdoComCon,
1501 kEplSdoComTransferLowerLayerAbort);
1502 // d.k.: do not clean control structure
1510 } // end of switch(SdoComConEvent_p)
1515 case kEplSdoComStateClientConnected:
1518 switch (SdoComConEvent_p) {
1520 case kEplSdoComConEventSendFirst:
1521 case kEplSdoComConEventAckReceived:
1522 case kEplSdoComConEventFrameSended:
1524 Ret = EplSdoComClientSend(pSdoComCon);
1525 if (Ret != kEplSuccessful) {
1528 // check if read transfer finished
1529 if ((pSdoComCon->m_uiTransSize == 0)
1531 m_uiTransferredByte != 0)
1532 && (pSdoComCon->m_SdoServiceType ==
1533 kEplSdoServiceReadByIndex)) {
1534 // inc transaction id
1535 pSdoComCon->m_bTransactionId++;
1536 // call callback of application
1537 pSdoComCon->m_dwLastAbortCode =
1540 EplSdoComTransferFinished
1541 (SdoComCon_p, pSdoComCon,
1542 kEplSdoComTransferFinished);
1546 // check if segemted transfer
1547 if (pSdoComCon->m_SdoTransType ==
1548 kEplSdoTransSegmented) {
1549 pSdoComCon->m_SdoComState =
1550 kEplSdoComStateClientSegmTrans;
1557 case kEplSdoComConEventRec:
1559 // check if the frame is a SDO response and has the right transaction ID
1561 AmiGetByteFromLe(&pAsySdoCom_p->
1563 if (((bFlag & 0x80) != 0)
1567 m_le_bTransactionId) ==
1568 pSdoComCon->m_bTransactionId)) {
1569 // check if abort or not
1570 if ((bFlag & 0x40) != 0) {
1571 // send acknowledge without any Command layer data
1573 EplSdoAsySeqSendData
1578 // inc transaction id
1588 // call callback of application
1590 EplSdoComTransferFinished
1593 kEplSdoComTransferRxAborted);
1596 } else { // normal frame received
1599 EplSdoComClientProcessFrame
1603 // check if transfer ready
1607 // send acknowledge without any Command layer data
1609 EplSdoAsySeqSendData
1615 // inc transaction id
1618 // call callback of application
1623 EplSdoComTransferFinished
1626 kEplSdoComTransferFinished);
1632 } else { // this command layer handle is not responsible
1633 // (wrong direction or wrong transaction ID)
1634 Ret = kEplSdoComNotResponsible;
1640 // connection closed event go back to kEplSdoComStateClientWaitInit
1641 case kEplSdoComConEventConClosed:
1642 { // connection closed by communication partner
1643 // close sequence layer handle
1645 EplSdoAsySeqDelCon(pSdoComCon->
1647 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1648 pSdoComCon->m_SdoSeqConHdl |=
1649 EPL_SDO_SEQ_INVALID_HDL;
1651 pSdoComCon->m_SdoComState =
1652 kEplSdoComStateClientWaitInit;
1654 // call callback of application
1655 pSdoComCon->m_dwLastAbortCode = 0;
1657 EplSdoComTransferFinished
1658 (SdoComCon_p, pSdoComCon,
1659 kEplSdoComTransferLowerLayerAbort);
1666 // abort to send from higher layer
1667 case kEplSdoComConEventAbort:
1669 EplSdoComClientSendAbort(pSdoComCon,
1674 // inc transaction id
1675 pSdoComCon->m_bTransactionId++;
1676 // call callback of application
1677 pSdoComCon->m_dwLastAbortCode =
1678 *((DWORD *) pSdoComCon->m_pData);
1680 EplSdoComTransferFinished
1681 (SdoComCon_p, pSdoComCon,
1682 kEplSdoComTransferTxAborted);
1687 case kEplSdoComConEventInitError:
1688 case kEplSdoComConEventTimeout:
1690 // close sequence layer handle
1692 EplSdoAsySeqDelCon(pSdoComCon->
1694 pSdoComCon->m_SdoSeqConHdl |=
1695 EPL_SDO_SEQ_INVALID_HDL;
1697 pSdoComCon->m_SdoComState =
1698 kEplSdoComStateClientWaitInit;
1699 // call callback of application
1700 pSdoComCon->m_dwLastAbortCode =
1703 EplSdoComTransferFinished
1704 (SdoComCon_p, pSdoComCon,
1705 kEplSdoComTransferLowerLayerAbort);
1713 } // end of switch(SdoComConEvent_p)
1718 // process segmented transfer
1719 case kEplSdoComStateClientSegmTrans:
1722 switch (SdoComConEvent_p) {
1724 case kEplSdoComConEventSendFirst:
1725 case kEplSdoComConEventAckReceived:
1726 case kEplSdoComConEventFrameSended:
1728 Ret = EplSdoComClientSend(pSdoComCon);
1729 if (Ret != kEplSuccessful) {
1732 // check if read transfer finished
1733 if ((pSdoComCon->m_uiTransSize == 0)
1734 && (pSdoComCon->m_SdoServiceType ==
1735 kEplSdoServiceReadByIndex)) {
1736 // inc transaction id
1737 pSdoComCon->m_bTransactionId++;
1739 pSdoComCon->m_SdoComState =
1740 kEplSdoComStateClientConnected;
1741 // call callback of application
1742 pSdoComCon->m_dwLastAbortCode =
1745 EplSdoComTransferFinished
1746 (SdoComCon_p, pSdoComCon,
1747 kEplSdoComTransferFinished);
1756 case kEplSdoComConEventRec:
1758 // check if the frame is a response
1760 AmiGetByteFromLe(&pAsySdoCom_p->
1762 if (((bFlag & 0x80) != 0)
1766 m_le_bTransactionId) ==
1767 pSdoComCon->m_bTransactionId)) {
1768 // check if abort or not
1769 if ((bFlag & 0x40) != 0) {
1770 // send acknowledge without any Command layer data
1772 EplSdoAsySeqSendData
1777 // inc transaction id
1783 kEplSdoComStateClientConnected;
1791 // call callback of application
1793 EplSdoComTransferFinished
1796 kEplSdoComTransferRxAborted);
1799 } else { // normal frame received
1802 EplSdoComClientProcessFrame
1806 // check if transfer ready
1810 // send acknowledge without any Command layer data
1812 EplSdoAsySeqSendData
1818 // inc transaction id
1825 kEplSdoComStateClientConnected;
1826 // call callback of application
1831 EplSdoComTransferFinished
1834 kEplSdoComTransferFinished);
1843 // connection closed event go back to kEplSdoComStateClientWaitInit
1844 case kEplSdoComConEventConClosed:
1845 { // connection closed by communication partner
1846 // close sequence layer handle
1848 EplSdoAsySeqDelCon(pSdoComCon->
1850 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1851 pSdoComCon->m_SdoSeqConHdl |=
1852 EPL_SDO_SEQ_INVALID_HDL;
1854 pSdoComCon->m_SdoComState =
1855 kEplSdoComStateClientWaitInit;
1856 // inc transaction id
1857 pSdoComCon->m_bTransactionId++;
1858 // call callback of application
1859 pSdoComCon->m_dwLastAbortCode = 0;
1861 EplSdoComTransferFinished
1862 (SdoComCon_p, pSdoComCon,
1863 kEplSdoComTransferFinished);
1868 // abort to send from higher layer
1869 case kEplSdoComConEventAbort:
1871 EplSdoComClientSendAbort(pSdoComCon,
1876 // inc transaction id
1877 pSdoComCon->m_bTransactionId++;
1879 pSdoComCon->m_SdoComState =
1880 kEplSdoComStateClientConnected;
1881 // call callback of application
1882 pSdoComCon->m_dwLastAbortCode =
1883 *((DWORD *) pSdoComCon->m_pData);
1885 EplSdoComTransferFinished
1886 (SdoComCon_p, pSdoComCon,
1887 kEplSdoComTransferTxAborted);
1892 case kEplSdoComConEventInitError:
1893 case kEplSdoComConEventTimeout:
1895 // close sequence layer handle
1897 EplSdoAsySeqDelCon(pSdoComCon->
1899 pSdoComCon->m_SdoSeqConHdl |=
1900 EPL_SDO_SEQ_INVALID_HDL;
1902 pSdoComCon->m_SdoComState =
1903 kEplSdoComStateClientWaitInit;
1904 // call callback of application
1905 pSdoComCon->m_dwLastAbortCode =
1908 EplSdoComTransferFinished
1909 (SdoComCon_p, pSdoComCon,
1910 kEplSdoComTransferLowerLayerAbort);
1918 } // end of switch(SdoComConEvent_p)
1922 #endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1924 } // end of switch(pSdoComCon->m_SdoComState)
1926 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1930 #if defined(WIN32) || defined(_WIN32)
1931 // leave critical section for process function
1932 EPL_DBGLVL_SDO_TRACE0
1933 ("\n\tLeaveCriticalSection EplSdoComProcessIntern\n\n");
1934 LeaveCriticalSection(SdoComInstance_g.m_pCriticalSection);
1942 //---------------------------------------------------------------------------
1944 // Function: EplSdoComServerInitReadByIndex
1946 // Description: function start the processing of an read by index command
1950 // Parameters: pSdoComCon_p = pointer to control structure of connection
1951 // pAsySdoCom_p = pointer to received frame
1953 // Returns: tEplKernel = errorcode
1958 //---------------------------------------------------------------------------
1959 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1960 static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
1961 tEplAsySdoCom * pAsySdoCom_p)
1964 unsigned int uiIndex;
1965 unsigned int uiSubindex;
1966 tEplObdSize EntrySize;
1967 tEplObdAccess AccessType;
1972 // a init of a read could not be a segmented transfer
1973 // -> no variable part of header
1975 // get index and subindex
1976 uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
1977 uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
1979 // check accesstype of entry
1980 // existens of entry
1981 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
1982 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
1984 Ret = kEplObdSubindexNotExist;
1987 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
1988 dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
1990 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
1991 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1994 kEplSdoComSendTypeAbort);
1996 } else if (Ret != kEplSuccessful) { // entry doesn't exist
1997 dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
1999 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
2000 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2003 kEplSdoComSendTypeAbort);
2006 // compare accesstype must be read or const
2007 if (((AccessType & kEplObdAccRead) == 0)
2008 && ((AccessType & kEplObdAccConst) == 0)) {
2010 if ((AccessType & kEplObdAccWrite) != 0) {
2011 // entry read a write only object
2012 dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ;
2014 dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
2017 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
2018 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2021 kEplSdoComSendTypeAbort);
2025 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex;
2027 // get size of object to see iof segmented or expedited transfer
2028 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2029 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
2033 if (EntrySize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer
2034 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2035 // get pointer to object-entry data
2036 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2037 pSdoComCon_p->m_pData =
2038 EplObduGetObjectDataPtr(uiIndex, uiSubindex);
2040 } else { // expedited transfer
2041 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2044 pSdoComCon_p->m_uiTransSize = EntrySize;
2045 pSdoComCon_p->m_uiTransferredByte = 0;
2047 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2049 uiSubindex, kEplSdoComSendTypeRes);
2050 if (Ret != kEplSuccessful) {
2052 dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
2054 pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
2055 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2058 kEplSdoComSendTypeAbort);
2067 //---------------------------------------------------------------------------
2069 // Function: EplSdoComServerSendFrameIntern();
2071 // Description: function creats and send a frame for server
2075 // Parameters: pSdoComCon_p = pointer to control structure of connection
2076 // uiIndex_p = index to send if expedited transfer else 0
2077 // uiSubIndex_p = subindex to send if expedited transfer else 0
2078 // SendType_p = to of frame to send
2080 // Returns: tEplKernel = errorcode
2085 //---------------------------------------------------------------------------
2086 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
2087 static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
2088 unsigned int uiIndex_p,
2089 unsigned int uiSubIndex_p,
2090 tEplSdoComSendType SendType_p)
2093 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
2095 tEplAsySdoCom *pCommandFrame;
2096 unsigned int uiSizeOfFrame;
2099 Ret = kEplSuccessful;
2101 pFrame = (tEplFrame *) & abFrame[0];
2103 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2105 // build generic part of frame
2106 // get pointer to command layerpart of frame
2108 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2109 m_le_abSdoSeqPayload;
2110 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
2111 pSdoComCon_p->m_SdoServiceType);
2112 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
2113 pSdoComCon_p->m_bTransactionId);
2115 // set size to header size
2119 switch (SendType_p) {
2120 // requestframe to send
2121 case kEplSdoComSendTypeReq:
2123 // nothing to do for server
2125 Ret = kEplSdoComInvalidSendType;
2129 // response without data to send
2130 case kEplSdoComSendTypeAckRes:
2132 // set response flag
2133 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, 0x80);
2136 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2137 uiSizeOfFrame, pFrame);
2142 // responsframe to send
2143 case kEplSdoComSendTypeRes:
2145 // set response flag
2146 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
2148 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2150 // check type of resonse
2151 if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // Expedited transfer
2152 // copy data in frame
2153 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2154 Ret = EplObduReadEntryToLe(uiIndex_p,
2162 if (Ret != kEplSuccessful) {
2167 // set size of frame
2168 AmiSetWordToLe(&pCommandFrame->
2170 (WORD) pSdoComCon_p->
2173 // correct byte-counter
2174 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2175 pSdoComCon_p->m_uiTransferredByte +=
2176 pSdoComCon_p->m_uiTransSize;
2177 pSdoComCon_p->m_uiTransSize = 0;
2180 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2182 EplSdoAsySeqSendData(pSdoComCon_p->
2184 uiSizeOfFrame, pFrame);
2185 } else if (pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented) { // segmented transfer
2186 // distinguish between init, segment and complete
2187 if (pSdoComCon_p->m_uiTransferredByte == 0) { // init
2190 AmiGetByteFromLe(&pCommandFrame->
2193 AmiSetByteToLe(&pCommandFrame->
2194 m_le_bFlags, bFlag);
2195 // init variable header
2196 AmiSetDwordToLe(&pCommandFrame->
2197 m_le_abCommandData[0],
2200 // copy data in frame
2201 EPL_MEMCPY(&pCommandFrame->
2202 m_le_abCommandData[4],
2203 pSdoComCon_p->m_pData,
2204 (EPL_SDO_MAX_PAYLOAD - 4));
2206 // correct byte-counter
2207 pSdoComCon_p->m_uiTransSize -=
2208 (EPL_SDO_MAX_PAYLOAD - 4);
2209 pSdoComCon_p->m_uiTransferredByte +=
2210 (EPL_SDO_MAX_PAYLOAD - 4);
2211 // move data pointer
2212 pSdoComCon_p->m_pData +=
2213 (EPL_SDO_MAX_PAYLOAD - 4);
2216 AmiSetWordToLe(&pCommandFrame->
2218 (EPL_SDO_MAX_PAYLOAD -
2222 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2224 EplSdoAsySeqSendData(pSdoComCon_p->
2230 if ((pSdoComCon_p->m_uiTransferredByte > 0)
2231 && (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)) { // segment
2234 AmiGetByteFromLe(&pCommandFrame->
2237 AmiSetByteToLe(&pCommandFrame->
2238 m_le_bFlags, bFlag);
2240 // copy data in frame
2241 EPL_MEMCPY(&pCommandFrame->
2242 m_le_abCommandData[0],
2243 pSdoComCon_p->m_pData,
2244 EPL_SDO_MAX_PAYLOAD);
2246 // correct byte-counter
2247 pSdoComCon_p->m_uiTransSize -=
2248 EPL_SDO_MAX_PAYLOAD;
2249 pSdoComCon_p->m_uiTransferredByte +=
2250 EPL_SDO_MAX_PAYLOAD;
2251 // move data pointer
2252 pSdoComCon_p->m_pData +=
2253 EPL_SDO_MAX_PAYLOAD;
2256 AmiSetWordToLe(&pCommandFrame->
2258 EPL_SDO_MAX_PAYLOAD);
2261 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2263 EplSdoAsySeqSendData(pSdoComCon_p->
2268 if ((pSdoComCon_p->m_uiTransSize == 0)
2271 kEplSdoServiceWriteByIndex)) {
2275 // set segment complete flag
2277 AmiGetByteFromLe(&pCommandFrame->
2280 AmiSetByteToLe(&pCommandFrame->
2281 m_le_bFlags, bFlag);
2283 // copy data in frame
2284 EPL_MEMCPY(&pCommandFrame->
2285 m_le_abCommandData[0],
2286 pSdoComCon_p->m_pData,
2287 pSdoComCon_p->m_uiTransSize);
2289 // correct byte-counter
2290 pSdoComCon_p->m_uiTransferredByte +=
2291 pSdoComCon_p->m_uiTransSize;
2293 // move data pointer
2294 pSdoComCon_p->m_pData +=
2295 pSdoComCon_p->m_uiTransSize;
2298 AmiSetWordToLe(&pCommandFrame->
2300 (WORD) pSdoComCon_p->
2305 pSdoComCon_p->m_uiTransSize;
2306 pSdoComCon_p->m_uiTransSize = 0;
2308 EplSdoAsySeqSendData(pSdoComCon_p->
2318 case kEplSdoComSendTypeAbort:
2320 // set response and abort flag
2321 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
2323 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2325 // copy abortcode to frame
2326 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],
2327 *((DWORD *) pSdoComCon_p->m_pData));
2329 // set size of segment
2330 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,
2334 pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
2335 pSdoComCon_p->m_uiTransSize = 0;
2338 uiSizeOfFrame += sizeof(DWORD);
2339 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2340 uiSizeOfFrame, pFrame);
2343 } // end of switch(SendType_p)
2349 //---------------------------------------------------------------------------
2351 // Function: EplSdoComServerInitWriteByIndex
2353 // Description: function start the processing of an write by index command
2357 // Parameters: pSdoComCon_p = pointer to control structure of connection
2358 // pAsySdoCom_p = pointer to received frame
2360 // Returns: tEplKernel = errorcode
2365 //---------------------------------------------------------------------------
2366 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
2367 static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
2368 tEplAsySdoCom * pAsySdoCom_p)
2370 tEplKernel Ret = kEplSuccessful;
2371 unsigned int uiIndex;
2372 unsigned int uiSubindex;
2373 unsigned int uiBytesToTransfer;
2374 tEplObdSize EntrySize;
2375 tEplObdAccess AccessType;
2381 // a init of a write
2382 // -> variable part of header possible
2384 // check if expedited or segmented transfer
2385 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x10) { // initiate segmented transfer
2386 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2387 // get index and subindex
2389 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]);
2391 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]);
2392 // get source-pointer for copy
2393 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8];
2395 pSdoComCon_p->m_uiTransSize =
2396 AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2398 } else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00) { // expedited transfer
2399 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2400 // get index and subindex
2402 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2404 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
2405 // get source-pointer for copy
2406 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4];
2408 pSdoComCon_p->m_uiTransSize =
2409 AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2411 pSdoComCon_p->m_uiTransSize -= 4;
2414 // just ignore any other transfer type
2418 // check accesstype of entry
2419 // existens of entry
2420 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2421 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
2423 Ret = kEplObdSubindexNotExist;
2426 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
2427 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
2429 // d.k. This is wrong: k.t. not needed send abort on end of write
2430 /*pSdoComCon_p->m_pData = (BYTE*)pSdoComCon_p->m_dwLastAbortCode;
2431 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2434 kEplSdoComSendTypeAbort); */
2436 } else if (Ret != kEplSuccessful) { // entry doesn't exist
2437 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
2439 // d.k. This is wrong: k.t. not needed send abort on end of write
2441 pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2442 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2445 kEplSdoComSendTypeAbort); */
2448 // compare accesstype must be read
2449 if ((AccessType & kEplObdAccWrite) == 0) {
2451 if ((AccessType & kEplObdAccRead) != 0) {
2452 // entry write a read only object
2453 pSdoComCon_p->m_dwLastAbortCode =
2454 EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ;
2456 pSdoComCon_p->m_dwLastAbortCode =
2457 EPL_SDOAC_UNSUPPORTED_ACCESS;
2460 // d.k. This is wrong: k.t. not needed send abort on end of write
2461 /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2462 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2465 kEplSdoComSendTypeAbort); */
2469 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex;
2471 pSdoComCon_p->m_uiTransferredByte = 0;
2474 if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // expedited transfer
2475 // size checking is done by EplObduWriteEntryFromLe()
2477 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2478 Ret = EplObduWriteEntryFromLe(uiIndex,
2481 pSdoComCon_p->m_uiTransSize);
2483 case kEplSuccessful:
2488 case kEplObdAccessViolation:
2490 pSdoComCon_p->m_dwLastAbortCode =
2491 EPL_SDOAC_UNSUPPORTED_ACCESS;
2496 case kEplObdValueLengthError:
2498 pSdoComCon_p->m_dwLastAbortCode =
2499 EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH;
2504 case kEplObdValueTooHigh:
2506 pSdoComCon_p->m_dwLastAbortCode =
2507 EPL_SDOAC_VALUE_RANGE_TOO_HIGH;
2512 case kEplObdValueTooLow:
2514 pSdoComCon_p->m_dwLastAbortCode =
2515 EPL_SDOAC_VALUE_RANGE_TOO_LOW;
2522 pSdoComCon_p->m_dwLastAbortCode =
2523 EPL_SDOAC_GENERAL_ERROR;
2529 // send command acknowledge
2530 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2533 kEplSdoComSendTypeAckRes);
2535 pSdoComCon_p->m_uiTransSize = 0;
2538 // get size of the object to check if it fits
2539 // because we directly write to the destination memory
2540 // d.k. no one calls the user OD callback function
2542 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2543 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
2547 if (EntrySize < pSdoComCon_p->m_uiTransSize) { // parameter too big
2548 pSdoComCon_p->m_dwLastAbortCode =
2549 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
2551 // d.k. This is wrong: k.t. not needed send abort on end of write
2552 /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
2553 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2556 kEplSdoComSendTypeAbort); */
2561 AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2562 // eleminate header (Command header (8) + variable part (4) + Command header (4))
2563 uiBytesToTransfer -= 16;
2564 // get pointer to object entry
2565 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2566 pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex,
2569 if (pSdoComCon_p->m_pData == NULL) {
2570 pSdoComCon_p->m_dwLastAbortCode =
2571 EPL_SDOAC_GENERAL_ERROR;
2573 // d.k. This is wrong: k.t. not needed send abort on end of write
2574 /* pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
2575 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2578 kEplSdoComSendTypeAbort);*/
2582 EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer);
2584 // update internal counter
2585 pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer;
2586 pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
2588 // update target pointer
2589 ( /*(BYTE*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
2591 // send acknowledge without any Command layer data
2592 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2593 0, (tEplFrame *) NULL);
2598 if (pSdoComCon_p->m_dwLastAbortCode != 0) {
2600 pSdoComCon_p->m_pData =
2601 (BYTE *) & pSdoComCon_p->m_dwLastAbortCode;
2603 EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex,
2605 kEplSdoComSendTypeAbort);
2608 pSdoComCon_p->m_dwLastAbortCode = 0;
2609 pSdoComCon_p->m_uiTransSize = 0;
2618 //---------------------------------------------------------------------------
2620 // Function: EplSdoComClientSend
2622 // Description: function starts an sdo transfer an send all further frames
2626 // Parameters: pSdoComCon_p = pointer to control structure of connection
2628 // Returns: tEplKernel = errorcode
2633 //---------------------------------------------------------------------------
2634 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
2635 static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
2638 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
2640 tEplAsySdoCom *pCommandFrame;
2641 unsigned int uiSizeOfFrame;
2645 Ret = kEplSuccessful;
2647 pFrame = (tEplFrame *) & abFrame[0];
2649 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2651 // build generic part of frame
2652 // get pointer to command layerpart of frame
2654 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2655 m_le_abSdoSeqPayload;
2656 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
2657 pSdoComCon_p->m_SdoServiceType);
2658 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
2659 pSdoComCon_p->m_bTransactionId);
2661 // set size constant part of header
2664 // check if first frame to send -> command header needed
2665 if (pSdoComCon_p->m_uiTransSize > 0) {
2666 if (pSdoComCon_p->m_uiTransferredByte == 0) { // start SDO transfer
2667 // check if segmented or expedited transfer
2668 // only for write commands
2669 switch (pSdoComCon_p->m_SdoServiceType) {
2670 case kEplSdoServiceReadByIndex:
2671 { // first frame of read access always expedited
2672 pSdoComCon_p->m_SdoTransType =
2673 kEplSdoTransExpedited;
2676 m_le_abCommandData[0];
2677 // fill rest of header
2678 AmiSetWordToLe(&pCommandFrame->
2679 m_le_wSegmentSize, 4);
2681 // create command header
2682 AmiSetWordToLe(pbPayload,
2683 (WORD) pSdoComCon_p->
2686 AmiSetByteToLe(pbPayload,
2687 (BYTE) pSdoComCon_p->
2688 m_uiTargetSubIndex);
2692 // set pSdoComCon_p->m_uiTransferredByte to one
2693 pSdoComCon_p->m_uiTransferredByte = 1;
2697 case kEplSdoServiceWriteByIndex:
2699 if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer
2700 // -> variable part of header needed
2701 // save that transfer is segmented
2702 pSdoComCon_p->m_SdoTransType =
2703 kEplSdoTransSegmented;
2704 // fill variable part of header
2705 AmiSetDwordToLe(&pCommandFrame->
2710 // set pointer to real payload
2713 m_le_abCommandData[4];
2714 // fill rest of header
2715 AmiSetWordToLe(&pCommandFrame->
2717 EPL_SDO_MAX_PAYLOAD);
2719 AmiSetByteToLe(&pCommandFrame->
2722 // create command header
2723 AmiSetWordToLe(pbPayload,
2728 AmiSetByteToLe(pbPayload,
2731 m_uiTargetSubIndex);
2732 // on byte for reserved
2736 EPL_SDO_MAX_PAYLOAD;
2739 EPL_MEMCPY(pbPayload,
2742 (EPL_SDO_MAX_PAYLOAD
2744 pSdoComCon_p->m_pData +=
2745 (EPL_SDO_MAX_PAYLOAD - 8);
2746 // correct intern counter
2747 pSdoComCon_p->m_uiTransSize -=
2748 (EPL_SDO_MAX_PAYLOAD - 8);
2750 m_uiTransferredByte =
2751 (EPL_SDO_MAX_PAYLOAD - 8);
2753 } else { // expedited trandsfer
2754 // save that transfer is expedited
2755 pSdoComCon_p->m_SdoTransType =
2756 kEplSdoTransExpedited;
2759 m_le_abCommandData[0];
2761 // create command header
2762 AmiSetWordToLe(pbPayload,
2767 AmiSetByteToLe(pbPayload,
2770 m_uiTargetSubIndex);
2771 // + 2 -> one byte for subindex and one byte reserved
2774 EPL_MEMCPY(pbPayload,
2784 // fill rest of header
2785 AmiSetWordToLe(&pCommandFrame->
2792 m_uiTransferredByte =
2793 pSdoComCon_p->m_uiTransSize;
2794 pSdoComCon_p->m_uiTransSize = 0;
2799 case kEplSdoServiceNIL:
2801 // invalid service requested
2802 Ret = kEplSdoComInvalidServiceType;
2804 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2805 } else // (pSdoComCon_p->m_uiTransferredByte > 0)
2806 { // continue SDO transfer
2807 switch (pSdoComCon_p->m_SdoServiceType) {
2808 // for expedited read is nothing to do
2809 // -> server sends data
2811 case kEplSdoServiceWriteByIndex:
2812 { // send next frame
2813 if (pSdoComCon_p->m_SdoTransType ==
2814 kEplSdoTransSegmented) {
2815 if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // next segment
2820 // fill rest of header
2824 EPL_SDO_MAX_PAYLOAD);
2831 EPL_MEMCPY(pbPayload,
2834 EPL_SDO_MAX_PAYLOAD);
2835 pSdoComCon_p->m_pData +=
2836 EPL_SDO_MAX_PAYLOAD;
2837 // correct intern counter
2840 EPL_SDO_MAX_PAYLOAD;
2844 EPL_SDO_MAX_PAYLOAD;
2847 EPL_SDO_MAX_PAYLOAD;
2849 } else { // end of transfer
2854 // fill rest of header
2867 EPL_MEMCPY(pbPayload,
2872 pSdoComCon_p->m_pData +=
2879 // correct intern counter
2898 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2904 // call send function of lower layer
2905 switch (pSdoComCon_p->m_SdoProtType) {
2906 case kEplSdoTypeAsnd:
2907 case kEplSdoTypeUdp:
2909 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2910 uiSizeOfFrame, pFrame);
2916 Ret = kEplSdoComUnsupportedProt;
2918 } // end of switch(pSdoComCon_p->m_SdoProtType)
2925 //---------------------------------------------------------------------------
2927 // Function: EplSdoComClientProcessFrame
2929 // Description: function process a received frame
2933 // Parameters: SdoComCon_p = connection handle
2934 // pAsySdoCom_p = pointer to frame to process
2936 // Returns: tEplKernel = errorcode
2941 //---------------------------------------------------------------------------
2942 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
2943 static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
2944 tEplAsySdoCom * pAsySdoCom_p)
2948 unsigned int uiBuffer;
2949 unsigned int uiDataSize;
2950 unsigned long ulBuffer;
2951 tEplSdoComCon *pSdoComCon;
2953 Ret = kEplSuccessful;
2955 // get pointer to control structure
2956 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
2958 // check if transaction Id fit
2959 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
2960 if (pSdoComCon->m_bTransactionId != bBuffer) {
2961 // incorrect transaction id
2963 // if running transfer
2964 if ((pSdoComCon->m_uiTransferredByte != 0)
2965 && (pSdoComCon->m_uiTransSize != 0)) {
2966 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
2968 EplSdoComClientSendAbort(pSdoComCon,
2969 pSdoComCon->m_dwLastAbortCode);
2970 // call callback of application
2972 EplSdoComTransferFinished(SdoComCon_p, pSdoComCon,
2973 kEplSdoComTransferTxAborted);
2976 } else { // check if correct command
2977 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bCommandId);
2978 if (pSdoComCon->m_SdoServiceType != bBuffer) {
2979 // incorrect command
2980 // if running transfer
2981 if ((pSdoComCon->m_uiTransferredByte != 0)
2982 && (pSdoComCon->m_uiTransSize != 0)) {
2983 pSdoComCon->m_dwLastAbortCode =
2984 EPL_SDOAC_GENERAL_ERROR;
2986 EplSdoComClientSendAbort(pSdoComCon,
2989 // call callback of application
2991 EplSdoComTransferFinished(SdoComCon_p,
2993 kEplSdoComTransferTxAborted);
2996 } else { // switch on command
2997 switch (pSdoComCon->m_SdoServiceType) {
2998 case kEplSdoServiceWriteByIndex:
2999 { // check if confirmation from server
3000 // nothing more to do
3004 case kEplSdoServiceReadByIndex:
3005 { // check if it is an segmented or an expedited transfer
3007 AmiGetByteFromLe(&pAsySdoCom_p->
3009 // mask uninteressting bits
3012 // expedited transfer
3015 // check size of buffer
3020 if (uiBuffer > pSdoComCon->m_uiTransSize) { // buffer provided by the application is to small
3025 } else { // buffer fits
3031 EPL_MEMCPY(pSdoComCon->
3047 // start of a segmented transfer
3049 { // get total size of transfer
3055 if (ulBuffer <= pSdoComCon->m_uiTransSize) { // buffer fit
3062 } else { // buffer to small
3067 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
3069 EplSdoComClientSendAbort
3073 // call callback of application
3075 EplSdoComTransferFinished
3078 kEplSdoComTransferRxAborted);
3083 // check size of buffer
3088 // subtract size of vaiable header from datasize
3091 EPL_MEMCPY(pSdoComCon->
3098 // correct counter an pointer
3099 pSdoComCon->m_pData +=
3115 // check size of buffer
3120 // check if data to copy fit to buffer
3121 if (uiBuffer >= pSdoComCon->m_uiTransSize) { // to much data
3128 EPL_MEMCPY(pSdoComCon->
3135 // correct counter an pointer
3136 pSdoComCon->m_pData +=
3151 // check size of buffer
3156 // check if data to copy fit to buffer
3157 if (uiBuffer > pSdoComCon->m_uiTransSize) { // to much data
3164 EPL_MEMCPY(pSdoComCon->
3171 // correct counter an pointer
3172 pSdoComCon->m_pData +=
3182 } // end of switch(bBuffer & 0x30)
3187 case kEplSdoServiceNIL:
3189 // invalid service requested
3190 // $$$ d.k. What should we do?
3192 } // end of switch(pSdoComCon->m_SdoServiceType)
3201 //---------------------------------------------------------------------------
3203 // Function: EplSdoComClientSendAbort
3205 // Description: function send a abort message
3209 // Parameters: pSdoComCon_p = pointer to control structure of connection
3210 // dwAbortCode_p = Sdo abort code
3212 // Returns: tEplKernel = errorcode
3217 //---------------------------------------------------------------------------
3218 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
3219 static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
3220 DWORD dwAbortCode_p)
3223 BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
3225 tEplAsySdoCom *pCommandFrame;
3226 unsigned int uiSizeOfFrame;
3228 Ret = kEplSuccessful;
3230 pFrame = (tEplFrame *) & abFrame[0];
3232 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
3234 // build generic part of frame
3235 // get pointer to command layerpart of frame
3237 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
3238 m_le_abSdoSeqPayload;
3239 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
3240 pSdoComCon_p->m_SdoServiceType);
3241 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
3242 pSdoComCon_p->m_bTransactionId);
3246 // set response and abort flag
3247 pCommandFrame->m_le_bFlags |= 0x40;
3249 // copy abortcode to frame
3250 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
3252 // set size of segment
3253 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
3256 pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
3257 pSdoComCon_p->m_uiTransSize = 0;
3260 uiSizeOfFrame += sizeof(DWORD);
3263 pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
3265 // call send function of lower layer
3266 switch (pSdoComCon_p->m_SdoProtType) {
3267 case kEplSdoTypeAsnd:
3268 case kEplSdoTypeUdp:
3270 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
3271 uiSizeOfFrame, pFrame);
3277 Ret = kEplSdoComUnsupportedProt;
3279 } // end of switch(pSdoComCon_p->m_SdoProtType)
3285 //---------------------------------------------------------------------------
3287 // Function: EplSdoComTransferFinished
3289 // Description: calls callback function of application if available
3290 // and clears entry in control structure
3292 // Parameters: pSdoComCon_p = pointer to control structure of connection
3293 // SdoComConState_p = state of SDO transfer
3295 // Returns: tEplKernel = errorcode
3300 //---------------------------------------------------------------------------
3301 static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
3302 tEplSdoComCon * pSdoComCon_p,
3303 tEplSdoComConState SdoComConState_p)
3307 Ret = kEplSuccessful;
3309 if (pSdoComCon_p->m_pfnTransferFinished != NULL) {
3310 tEplSdoFinishedCb pfnTransferFinished;
3311 tEplSdoComFinished SdoComFinished;
3313 SdoComFinished.m_pUserArg = pSdoComCon_p->m_pUserArg;
3314 SdoComFinished.m_uiNodeId = pSdoComCon_p->m_uiNodeId;
3315 SdoComFinished.m_uiTargetIndex = pSdoComCon_p->m_uiTargetIndex;
3316 SdoComFinished.m_uiTargetSubIndex =
3317 pSdoComCon_p->m_uiTargetSubIndex;
3318 SdoComFinished.m_uiTransferredByte =
3319 pSdoComCon_p->m_uiTransferredByte;
3320 SdoComFinished.m_dwAbortCode = pSdoComCon_p->m_dwLastAbortCode;
3321 SdoComFinished.m_SdoComConHdl = SdoComCon_p;
3322 SdoComFinished.m_SdoComConState = SdoComConState_p;
3323 if (pSdoComCon_p->m_SdoServiceType ==
3324 kEplSdoServiceWriteByIndex) {
3325 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeWrite;
3327 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead;
3330 // reset transfer state so this handle is not busy anymore
3331 pSdoComCon_p->m_uiTransferredByte = 0;
3332 pSdoComCon_p->m_uiTransSize = 0;
3334 pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished;
3335 // delete function pointer to inform application only once for each transfer
3336 pSdoComCon_p->m_pfnTransferFinished = NULL;
3338 // call application's callback function
3339 pfnTransferFinished(&SdoComFinished);