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;
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 u8 *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 u32 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 EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
209 tEplAsySdoCom *pAsySdoCom_p,
210 unsigned int uiDataSize_p);
212 tEplKernel 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,
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 EplSdoComInit(void)
292 Ret = EplSdoComAddInstance();
298 //---------------------------------------------------------------------------
300 // Function: EplSdoComAddInstance
302 // Description: Init additional instance of the module
309 // Returns: tEplKernel = errorcode
314 //---------------------------------------------------------------------------
315 tEplKernel 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 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 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 EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p)
517 tEplSdoComCon *pSdoComCon;
520 if ((pSdoComTransParam_p->m_uiSubindex >= 0xFF)
521 || (pSdoComTransParam_p->m_uiIndex == 0)
522 || (pSdoComTransParam_p->m_uiIndex > 0xFFFF)
523 || (pSdoComTransParam_p->m_pData == NULL)
524 || (pSdoComTransParam_p->m_uiDataSize == 0)) {
525 Ret = kEplSdoComInvalidParam;
529 if (pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON) {
530 Ret = kEplSdoComInvalidHandle;
533 // get pointer to control structure of connection
535 &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl];
537 // check if handle ok
538 if (pSdoComCon->m_SdoSeqConHdl == 0) {
539 Ret = kEplSdoComInvalidHandle;
542 // check if command layer is idle
543 if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0) { // handle is not idle
544 Ret = kEplSdoComHandleBusy;
548 // callback function for end of transfer
549 pSdoComCon->m_pfnTransferFinished =
550 pSdoComTransParam_p->m_pfnSdoFinishedCb;
551 pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg;
553 // set type of SDO command
554 if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead) {
555 pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex;
557 pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex;
560 // save pointer to data
561 pSdoComCon->m_pData = pSdoComTransParam_p->m_pData;
562 // maximal bytes to transfer
563 pSdoComCon->m_uiTransSize = pSdoComTransParam_p->m_uiDataSize;
564 // bytes already transfered
565 pSdoComCon->m_uiTransferredByte = 0;
567 // reset parts of control structure
568 pSdoComCon->m_dwLastAbortCode = 0;
569 pSdoComCon->m_SdoTransType = kEplSdoTransAuto;
571 //pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout;
573 // save index and subindex
574 pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex;
575 pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex;
577 // call process function
578 Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl, kEplSdoComConEventSendFirst, // event to start transfer
587 //---------------------------------------------------------------------------
589 // Function: EplSdoComUndefineCon
591 // Description: function undefine a SDO connection
595 // Parameters: SdoComConHdl_p = handle for the connection
598 // Returns: tEplKernel = errorcode
603 //---------------------------------------------------------------------------
604 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
605 tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
608 tEplSdoComCon *pSdoComCon;
610 Ret = kEplSuccessful;
612 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
613 Ret = kEplSdoComInvalidHandle;
616 // get pointer to control structure
617 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
619 // $$$ d.k. abort a running transfer before closing the sequence layer
621 if (((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) !=
622 EPL_SDO_SEQ_INVALID_HDL)
623 && (pSdoComCon->m_SdoSeqConHdl != 0)) {
624 // close connection in lower layer
625 switch (pSdoComCon->m_SdoProtType) {
626 case kEplSdoTypeAsnd:
630 EplSdoAsySeqDelCon(pSdoComCon->
636 case kEplSdoTypeAuto:
639 Ret = kEplSdoComUnsupportedProt;
643 } // end of switch(pSdoComCon->m_SdoProtType)
646 // clean controll structure
647 EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
652 //---------------------------------------------------------------------------
654 // Function: EplSdoComGetState
656 // Description: function returns the state fo the connection
660 // Parameters: SdoComConHdl_p = handle for the connection
661 // pSdoComFinished_p = pointer to structur for sdo state
664 // Returns: tEplKernel = errorcode
669 //---------------------------------------------------------------------------
670 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
671 tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
672 tEplSdoComFinished *pSdoComFinished_p)
675 tEplSdoComCon *pSdoComCon;
677 Ret = kEplSuccessful;
679 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
680 Ret = kEplSdoComInvalidHandle;
683 // get pointer to control structure
684 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
686 // check if handle ok
687 if (pSdoComCon->m_SdoSeqConHdl == 0) {
688 Ret = kEplSdoComInvalidHandle;
692 pSdoComFinished_p->m_pUserArg = pSdoComCon->m_pUserArg;
693 pSdoComFinished_p->m_uiNodeId = pSdoComCon->m_uiNodeId;
694 pSdoComFinished_p->m_uiTargetIndex = pSdoComCon->m_uiTargetIndex;
695 pSdoComFinished_p->m_uiTargetSubIndex = pSdoComCon->m_uiTargetSubIndex;
696 pSdoComFinished_p->m_uiTransferredByte =
697 pSdoComCon->m_uiTransferredByte;
698 pSdoComFinished_p->m_dwAbortCode = pSdoComCon->m_dwLastAbortCode;
699 pSdoComFinished_p->m_SdoComConHdl = SdoComConHdl_p;
700 if (pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex) {
701 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeWrite;
703 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead;
706 if (pSdoComCon->m_dwLastAbortCode != 0) { // sdo abort
707 pSdoComFinished_p->m_SdoComConState =
708 kEplSdoComTransferRxAborted;
711 pSdoComCon->m_dwLastAbortCode = 0;
713 } else if ((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL) { // check state
714 pSdoComFinished_p->m_SdoComConState =
715 kEplSdoComTransferLowerLayerAbort;
716 } else if (pSdoComCon->m_SdoComState == kEplSdoComStateClientWaitInit) {
718 pSdoComFinished_p->m_SdoComConState =
719 kEplSdoComTransferNotActive;
720 } else if (pSdoComCon->m_uiTransSize == 0) { // finished
721 pSdoComFinished_p->m_SdoComConState =
722 kEplSdoComTransferFinished;
730 //---------------------------------------------------------------------------
732 // Function: EplSdoComSdoAbort
734 // Description: function abort a sdo transfer
738 // Parameters: SdoComConHdl_p = handle for the connection
739 // dwAbortCode_p = abort code
742 // Returns: tEplKernel = errorcode
747 //---------------------------------------------------------------------------
748 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
749 tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
753 tEplSdoComCon *pSdoComCon;
755 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
756 Ret = kEplSdoComInvalidHandle;
759 // get pointer to control structure of connection
760 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
762 // check if handle ok
763 if (pSdoComCon->m_SdoSeqConHdl == 0) {
764 Ret = kEplSdoComInvalidHandle;
767 // save pointer to abort code
768 pSdoComCon->m_pData = (u8 *) & dwAbortCode_p;
770 Ret = EplSdoComProcessIntern(SdoComConHdl_p,
771 kEplSdoComConEventAbort,
772 (tEplAsySdoCom *) NULL);
779 //=========================================================================//
781 // P R I V A T E F U N C T I O N S //
783 //=========================================================================//
785 //---------------------------------------------------------------------------
787 // Function: EplSdoComReceiveCb
789 // Description: callback function for SDO Sequence Layer
790 // -> indicates new data
794 // Parameters: SdoSeqConHdl_p = Handle for connection
795 // pAsySdoCom_p = pointer to data
796 // uiDataSize_p = size of data ($$$ not used yet, but it should)
804 //---------------------------------------------------------------------------
805 tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
806 tEplAsySdoCom *pAsySdoCom_p,
807 unsigned int uiDataSize_p)
811 // search connection internally
812 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
813 kEplSdoComConEventRec, pAsySdoCom_p);
815 EPL_DBGLVL_SDO_TRACE3
816 ("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n",
817 SdoSeqConHdl_p, (u16) pAsySdoCom_p->m_le_abCommandData[0],
823 //---------------------------------------------------------------------------
825 // Function: EplSdoComConCb
827 // Description: callback function called by SDO Sequence Layer to inform
828 // command layer about state change of connection
832 // Parameters: SdoSeqConHdl_p = Handle of the connection
833 // AsySdoConState_p = Event of the connection
836 // Returns: tEplKernel = Errorcode
841 //---------------------------------------------------------------------------
842 tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
843 tEplAsySdoConState AsySdoConState_p)
846 tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
848 Ret = kEplSuccessful;
851 switch (AsySdoConState_p) {
852 case kAsySdoConStateConnected:
854 EPL_DBGLVL_SDO_TRACE0("Connection established\n");
855 SdoComConEvent = kEplSdoComConEventConEstablished;
856 // start transmission if needed
860 case kAsySdoConStateInitError:
862 EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n");
863 SdoComConEvent = kEplSdoComConEventInitError;
864 // inform app about error and close sequence layer handle
868 case kAsySdoConStateConClosed:
870 EPL_DBGLVL_SDO_TRACE0("Connection closed\n");
871 SdoComConEvent = kEplSdoComConEventConClosed;
872 // close sequence layer handle
876 case kAsySdoConStateAckReceived:
878 EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n");
879 SdoComConEvent = kEplSdoComConEventAckReceived;
880 // continue transmission
884 case kAsySdoConStateFrameSended:
886 EPL_DBGLVL_SDO_TRACE0("One Frame sent\n");
887 SdoComConEvent = kEplSdoComConEventFrameSended;
888 // to continue transmission
893 case kAsySdoConStateTimeout:
895 EPL_DBGLVL_SDO_TRACE0("Timeout\n");
896 SdoComConEvent = kEplSdoComConEventTimeout;
897 // close sequence layer handle
901 } // end of switch(AsySdoConState_p)
903 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
904 SdoComConEvent, (tEplAsySdoCom *) NULL);
909 //---------------------------------------------------------------------------
911 // Function: EplSdoComSearchConIntern
913 // Description: search a Sdo Sequence Layer connection handle in the
914 // control structure of the Command Layer
916 // Parameters: SdoSeqConHdl_p = Handle to search
917 // SdoComConEvent_p = event to process
918 // pAsySdoCom_p = pointer to received frame
920 // Returns: tEplKernel
925 //---------------------------------------------------------------------------
926 static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
927 tEplSdoComConEvent SdoComConEvent_p,
928 tEplAsySdoCom * pAsySdoCom_p)
931 tEplSdoComCon *pSdoComCon;
932 tEplSdoComConHdl HdlCount;
933 tEplSdoComConHdl HdlFree;
935 Ret = kEplSdoComNotResponsible;
937 // get pointer to first element of the array
938 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
941 while (HdlCount < EPL_MAX_SDO_COM_CON) {
942 if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p) { // matching command layer handle found
943 Ret = EplSdoComProcessIntern(HdlCount,
946 } else if ((pSdoComCon->m_SdoSeqConHdl == 0)
947 && (HdlFree == 0xFFFF)) {
955 if (Ret == kEplSdoComNotResponsible) { // no responsible command layer handle found
956 if (HdlFree == 0xFFFF) { // no free handle
957 // delete connection immediately
958 // 2008/04/14 m.u./d.k. This connection actually does not exist.
959 // pSdoComCon is invalid.
960 // Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
961 Ret = kEplSdoComNoFreeHandle;
962 } else { // create new handle
964 pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount];
965 pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p;
966 Ret = EplSdoComProcessIntern(HdlCount,
976 //---------------------------------------------------------------------------
978 // Function: EplSdoComProcessIntern
980 // Description: search a Sdo Sequence Layer connection handle in the
981 // control structer of the Command Layer
985 // Parameters: SdoComCon_p = index of control structure of connection
986 // SdoComConEvent_p = event to process
987 // pAsySdoCom_p = pointer to received frame
989 // Returns: tEplKernel = errorcode
994 //---------------------------------------------------------------------------
995 static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
996 tEplSdoComConEvent SdoComConEvent_p,
997 tEplAsySdoCom * pAsySdoCom_p)
1000 tEplSdoComCon *pSdoComCon;
1003 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1005 unsigned int uiSize;
1008 #if defined(WIN32) || defined(_WIN32)
1009 // enter critical section for process function
1010 EnterCriticalSection(SdoComInstance_g.m_pCriticalSection);
1011 EPL_DBGLVL_SDO_TRACE0
1012 ("\n\tEnterCiticalSection EplSdoComProcessIntern\n\n");
1015 Ret = kEplSuccessful;
1017 // get pointer to control structure
1018 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
1020 // process state maschine
1021 switch (pSdoComCon->m_SdoComState) {
1023 case kEplSdoComStateIdle:
1026 switch (SdoComConEvent_p) {
1027 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1028 // init con for client
1029 case kEplSdoComConEventInitCon:
1032 // call of the init function already
1033 // processed in EplSdoComDefineCon()
1034 // only change state to kEplSdoComStateClientWaitInit
1035 pSdoComCon->m_SdoComState =
1036 kEplSdoComStateClientWaitInit;
1041 // int con for server
1042 case kEplSdoComConEventRec:
1044 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1045 // check if init of an transfer and no SDO abort
1046 if ((pAsySdoCom_p->m_le_bFlags & 0x80) == 0) { // SDO request
1047 if ((pAsySdoCom_p->m_le_bFlags & 0x40) == 0) { // no SDO abort
1048 // save tansaction id
1053 m_le_bTransactionId);
1055 switch (pAsySdoCom_p->
1058 case kEplSdoServiceNIL:
1059 { // simply acknowlegde NIL command on sequence layer
1062 EplSdoAsySeqSendData
1073 case kEplSdoServiceReadByIndex:
1076 // search entry an start transfer
1077 EplSdoComServerInitReadByIndex
1081 if (pSdoComCon->m_uiTransSize == 0) { // ready -> stay idle
1085 kEplSdoComStateIdle;
1091 } else { // segmented transfer
1095 kEplSdoComStateServerSegmTrans;
1101 case kEplSdoServiceWriteByIndex:
1104 // search entry an start write
1105 EplSdoComServerInitWriteByIndex
1109 if (pSdoComCon->m_uiTransSize == 0) { // already -> stay idle
1113 kEplSdoComStateIdle;
1119 } else { // segmented transfer
1123 kEplSdoComStateServerSegmTrans;
1131 // unsupported command
1135 EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER;
1145 EplSdoComServerSendFrameIntern
1149 kEplSdoComSendTypeAbort);
1153 } // end of switch(pAsySdoCom_p->m_le_bCommandId)
1155 } else { // this command layer handle is not responsible
1156 // (wrong direction or wrong transaction ID)
1157 Ret = kEplSdoComNotResponsible;
1160 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1165 // connection closed
1166 case kEplSdoComConEventInitError:
1167 case kEplSdoComConEventTimeout:
1168 case kEplSdoComConEventConClosed:
1171 EplSdoAsySeqDelCon(pSdoComCon->
1173 // clean control structure
1174 EPL_MEMSET(pSdoComCon, 0x00,
1175 sizeof(tEplSdoComCon));
1182 } // end of switch(SdoComConEvent_p)
1186 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1187 //-------------------------------------------------------------------------
1189 // segmented transfer
1190 case kEplSdoComStateServerSegmTrans:
1193 switch (SdoComConEvent_p) {
1195 case kEplSdoComConEventAckReceived:
1196 case kEplSdoComConEventFrameSended:
1198 // check if it is a read
1199 if (pSdoComCon->m_SdoServiceType ==
1200 kEplSdoServiceReadByIndex) {
1202 EplSdoComServerSendFrameIntern
1204 kEplSdoComSendTypeRes);
1205 // if all send -> back to idle
1206 if (pSdoComCon->m_uiTransSize == 0) { // back to idle
1209 kEplSdoComStateIdle;
1220 // process next frame
1221 case kEplSdoComConEventRec:
1223 // check if the frame is a SDO response and has the right transaction ID
1225 AmiGetByteFromLe(&pAsySdoCom_p->
1227 if (((bFlag & 0x80) != 0)
1231 m_le_bTransactionId) ==
1232 pSdoComCon->m_bTransactionId)) {
1233 // check if it is a abort
1234 if ((bFlag & 0x40) != 0) { // SDO abort
1235 // clear control structure
1244 kEplSdoComStateIdle;
1249 // d.k.: do not execute anything further on this command
1252 // check if it is a write
1255 kEplSdoServiceWriteByIndex)
1263 m_dwLastAbortCode ==
1283 m_dwLastAbortCode ==
1290 // check end of transfer
1291 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30) { // transfer ready
1301 EplSdoComServerSendFrameIntern
1305 kEplSdoComSendTypeRes);
1306 // if all send -> back to idle
1307 if (pSdoComCon->m_uiTransSize == 0) { // back to idle
1311 kEplSdoComStateIdle;
1318 } else { // send dabort code
1329 EplSdoComServerSendFrameIntern
1333 kEplSdoComSendTypeAbort);
1342 // send acknowledge without any Command layer data
1344 EplSdoAsySeqSendData
1352 } else { // this command layer handle is not responsible
1353 // (wrong direction or wrong transaction ID)
1354 Ret = kEplSdoComNotResponsible;
1360 // connection closed
1361 case kEplSdoComConEventInitError:
1362 case kEplSdoComConEventTimeout:
1363 case kEplSdoComConEventConClosed:
1366 EplSdoAsySeqDelCon(pSdoComCon->
1368 // clean control structure
1369 EPL_MEMSET(pSdoComCon, 0x00,
1370 sizeof(tEplSdoComCon));
1377 } // end of switch(SdoComConEvent_p)
1381 #endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1383 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1384 //-------------------------------------------------------------------------
1386 // wait for finish of establishing connection
1387 case kEplSdoComStateClientWaitInit:
1390 // if connection handle is invalid reinit connection
1391 // d.k.: this will be done only on new events (i.e. InitTransfer)
1393 m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) ==
1394 EPL_SDO_SEQ_INVALID_HDL) {
1395 // check kind of connection to reinit
1397 switch (pSdoComCon->m_SdoProtType) {
1399 case kEplSdoTypeUdp:
1401 // call connection int function of lower layer
1406 pSdoComCon->m_uiNodeId,
1408 if (Ret != kEplSuccessful) {
1414 // Asend -> not supported
1415 case kEplSdoTypeAsnd:
1417 // call connection int function of lower layer
1422 pSdoComCon->m_uiNodeId,
1424 if (Ret != kEplSuccessful) {
1430 // Pdo -> not supported
1431 case kEplSdoTypePdo:
1434 Ret = kEplSdoComUnsupportedProt;
1437 } // end of switch(m_ProtType_p)
1438 // d.k.: reset transaction ID, because new sequence layer connection was initialized
1439 // $$$ d.k. is this really necessary?
1440 //pSdoComCon->m_bTransactionId = 0;
1443 switch (SdoComConEvent_p) {
1444 // connection established
1445 case kEplSdoComConEventConEstablished:
1447 //send first frame if needed
1448 if ((pSdoComCon->m_uiTransSize > 0)
1449 && (pSdoComCon->m_uiTargetIndex != 0)) { // start SDO transfer
1453 if (Ret != kEplSuccessful) {
1456 // check if segemted transfer
1459 kEplSdoTransSegmented) {
1462 kEplSdoComStateClientSegmTrans;
1466 // goto state kEplSdoComStateClientConnected
1467 pSdoComCon->m_SdoComState =
1468 kEplSdoComStateClientConnected;
1472 case kEplSdoComConEventSendFirst:
1474 // infos for transfer already saved by function EplSdoComInitTransferByIndex
1478 case kEplSdoComConEventConClosed:
1479 case kEplSdoComConEventInitError:
1480 case kEplSdoComConEventTimeout:
1482 // close sequence layer handle
1484 EplSdoAsySeqDelCon(pSdoComCon->
1486 pSdoComCon->m_SdoSeqConHdl |=
1487 EPL_SDO_SEQ_INVALID_HDL;
1488 // call callback function
1489 if (SdoComConEvent_p ==
1490 kEplSdoComConEventTimeout) {
1491 pSdoComCon->m_dwLastAbortCode =
1494 pSdoComCon->m_dwLastAbortCode =
1498 EplSdoComTransferFinished
1499 (SdoComCon_p, pSdoComCon,
1500 kEplSdoComTransferLowerLayerAbort);
1501 // d.k.: do not clean control structure
1509 } // end of switch(SdoComConEvent_p)
1514 case kEplSdoComStateClientConnected:
1517 switch (SdoComConEvent_p) {
1519 case kEplSdoComConEventSendFirst:
1520 case kEplSdoComConEventAckReceived:
1521 case kEplSdoComConEventFrameSended:
1523 Ret = EplSdoComClientSend(pSdoComCon);
1524 if (Ret != kEplSuccessful) {
1527 // check if read transfer finished
1528 if ((pSdoComCon->m_uiTransSize == 0)
1530 m_uiTransferredByte != 0)
1531 && (pSdoComCon->m_SdoServiceType ==
1532 kEplSdoServiceReadByIndex)) {
1533 // inc transaction id
1534 pSdoComCon->m_bTransactionId++;
1535 // call callback of application
1536 pSdoComCon->m_dwLastAbortCode =
1539 EplSdoComTransferFinished
1540 (SdoComCon_p, pSdoComCon,
1541 kEplSdoComTransferFinished);
1545 // check if segemted transfer
1546 if (pSdoComCon->m_SdoTransType ==
1547 kEplSdoTransSegmented) {
1548 pSdoComCon->m_SdoComState =
1549 kEplSdoComStateClientSegmTrans;
1556 case kEplSdoComConEventRec:
1558 // check if the frame is a SDO response and has the right transaction ID
1560 AmiGetByteFromLe(&pAsySdoCom_p->
1562 if (((bFlag & 0x80) != 0)
1566 m_le_bTransactionId) ==
1567 pSdoComCon->m_bTransactionId)) {
1568 // check if abort or not
1569 if ((bFlag & 0x40) != 0) {
1570 // send acknowledge without any Command layer data
1572 EplSdoAsySeqSendData
1577 // inc transaction id
1587 // call callback of application
1589 EplSdoComTransferFinished
1592 kEplSdoComTransferRxAborted);
1595 } else { // normal frame received
1598 EplSdoComClientProcessFrame
1602 // check if transfer ready
1606 // send acknowledge without any Command layer data
1608 EplSdoAsySeqSendData
1614 // inc transaction id
1617 // call callback of application
1622 EplSdoComTransferFinished
1625 kEplSdoComTransferFinished);
1631 } else { // this command layer handle is not responsible
1632 // (wrong direction or wrong transaction ID)
1633 Ret = kEplSdoComNotResponsible;
1639 // connection closed event go back to kEplSdoComStateClientWaitInit
1640 case kEplSdoComConEventConClosed:
1641 { // connection closed by communication partner
1642 // close sequence layer handle
1644 EplSdoAsySeqDelCon(pSdoComCon->
1646 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1647 pSdoComCon->m_SdoSeqConHdl |=
1648 EPL_SDO_SEQ_INVALID_HDL;
1650 pSdoComCon->m_SdoComState =
1651 kEplSdoComStateClientWaitInit;
1653 // call callback of application
1654 pSdoComCon->m_dwLastAbortCode = 0;
1656 EplSdoComTransferFinished
1657 (SdoComCon_p, pSdoComCon,
1658 kEplSdoComTransferLowerLayerAbort);
1665 // abort to send from higher layer
1666 case kEplSdoComConEventAbort:
1668 EplSdoComClientSendAbort(pSdoComCon,
1673 // inc transaction id
1674 pSdoComCon->m_bTransactionId++;
1675 // call callback of application
1676 pSdoComCon->m_dwLastAbortCode =
1677 *((u32 *) pSdoComCon->m_pData);
1679 EplSdoComTransferFinished
1680 (SdoComCon_p, pSdoComCon,
1681 kEplSdoComTransferTxAborted);
1686 case kEplSdoComConEventInitError:
1687 case kEplSdoComConEventTimeout:
1689 // close sequence layer handle
1691 EplSdoAsySeqDelCon(pSdoComCon->
1693 pSdoComCon->m_SdoSeqConHdl |=
1694 EPL_SDO_SEQ_INVALID_HDL;
1696 pSdoComCon->m_SdoComState =
1697 kEplSdoComStateClientWaitInit;
1698 // call callback of application
1699 pSdoComCon->m_dwLastAbortCode =
1702 EplSdoComTransferFinished
1703 (SdoComCon_p, pSdoComCon,
1704 kEplSdoComTransferLowerLayerAbort);
1712 } // end of switch(SdoComConEvent_p)
1717 // process segmented transfer
1718 case kEplSdoComStateClientSegmTrans:
1721 switch (SdoComConEvent_p) {
1723 case kEplSdoComConEventSendFirst:
1724 case kEplSdoComConEventAckReceived:
1725 case kEplSdoComConEventFrameSended:
1727 Ret = EplSdoComClientSend(pSdoComCon);
1728 if (Ret != kEplSuccessful) {
1731 // check if read transfer finished
1732 if ((pSdoComCon->m_uiTransSize == 0)
1733 && (pSdoComCon->m_SdoServiceType ==
1734 kEplSdoServiceReadByIndex)) {
1735 // inc transaction id
1736 pSdoComCon->m_bTransactionId++;
1738 pSdoComCon->m_SdoComState =
1739 kEplSdoComStateClientConnected;
1740 // call callback of application
1741 pSdoComCon->m_dwLastAbortCode =
1744 EplSdoComTransferFinished
1745 (SdoComCon_p, pSdoComCon,
1746 kEplSdoComTransferFinished);
1755 case kEplSdoComConEventRec:
1757 // check if the frame is a response
1759 AmiGetByteFromLe(&pAsySdoCom_p->
1761 if (((bFlag & 0x80) != 0)
1765 m_le_bTransactionId) ==
1766 pSdoComCon->m_bTransactionId)) {
1767 // check if abort or not
1768 if ((bFlag & 0x40) != 0) {
1769 // send acknowledge without any Command layer data
1771 EplSdoAsySeqSendData
1776 // inc transaction id
1782 kEplSdoComStateClientConnected;
1790 // call callback of application
1792 EplSdoComTransferFinished
1795 kEplSdoComTransferRxAborted);
1798 } else { // normal frame received
1801 EplSdoComClientProcessFrame
1805 // check if transfer ready
1809 // send acknowledge without any Command layer data
1811 EplSdoAsySeqSendData
1817 // inc transaction id
1824 kEplSdoComStateClientConnected;
1825 // call callback of application
1830 EplSdoComTransferFinished
1833 kEplSdoComTransferFinished);
1842 // connection closed event go back to kEplSdoComStateClientWaitInit
1843 case kEplSdoComConEventConClosed:
1844 { // connection closed by communication partner
1845 // close sequence layer handle
1847 EplSdoAsySeqDelCon(pSdoComCon->
1849 // set handle to invalid and enter kEplSdoComStateClientWaitInit
1850 pSdoComCon->m_SdoSeqConHdl |=
1851 EPL_SDO_SEQ_INVALID_HDL;
1853 pSdoComCon->m_SdoComState =
1854 kEplSdoComStateClientWaitInit;
1855 // inc transaction id
1856 pSdoComCon->m_bTransactionId++;
1857 // call callback of application
1858 pSdoComCon->m_dwLastAbortCode = 0;
1860 EplSdoComTransferFinished
1861 (SdoComCon_p, pSdoComCon,
1862 kEplSdoComTransferFinished);
1867 // abort to send from higher layer
1868 case kEplSdoComConEventAbort:
1870 EplSdoComClientSendAbort(pSdoComCon,
1875 // inc transaction id
1876 pSdoComCon->m_bTransactionId++;
1878 pSdoComCon->m_SdoComState =
1879 kEplSdoComStateClientConnected;
1880 // call callback of application
1881 pSdoComCon->m_dwLastAbortCode =
1882 *((u32 *) pSdoComCon->m_pData);
1884 EplSdoComTransferFinished
1885 (SdoComCon_p, pSdoComCon,
1886 kEplSdoComTransferTxAborted);
1891 case kEplSdoComConEventInitError:
1892 case kEplSdoComConEventTimeout:
1894 // close sequence layer handle
1896 EplSdoAsySeqDelCon(pSdoComCon->
1898 pSdoComCon->m_SdoSeqConHdl |=
1899 EPL_SDO_SEQ_INVALID_HDL;
1901 pSdoComCon->m_SdoComState =
1902 kEplSdoComStateClientWaitInit;
1903 // call callback of application
1904 pSdoComCon->m_dwLastAbortCode =
1907 EplSdoComTransferFinished
1908 (SdoComCon_p, pSdoComCon,
1909 kEplSdoComTransferLowerLayerAbort);
1917 } // end of switch(SdoComConEvent_p)
1921 #endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1923 } // end of switch(pSdoComCon->m_SdoComState)
1925 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1929 #if defined(WIN32) || defined(_WIN32)
1930 // leave critical section for process function
1931 EPL_DBGLVL_SDO_TRACE0
1932 ("\n\tLeaveCriticalSection EplSdoComProcessIntern\n\n");
1933 LeaveCriticalSection(SdoComInstance_g.m_pCriticalSection);
1941 //---------------------------------------------------------------------------
1943 // Function: EplSdoComServerInitReadByIndex
1945 // Description: function start the processing of an read by index command
1949 // Parameters: pSdoComCon_p = pointer to control structure of connection
1950 // pAsySdoCom_p = pointer to received frame
1952 // Returns: tEplKernel = errorcode
1957 //---------------------------------------------------------------------------
1958 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
1959 static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
1960 tEplAsySdoCom * pAsySdoCom_p)
1963 unsigned int uiIndex;
1964 unsigned int uiSubindex;
1965 tEplObdSize EntrySize;
1966 tEplObdAccess AccessType;
1971 // a init of a read could not be a segmented transfer
1972 // -> no variable part of header
1974 // get index and subindex
1975 uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
1976 uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
1978 // check accesstype of entry
1979 // existens of entry
1980 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
1981 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
1983 Ret = kEplObdSubindexNotExist;
1986 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
1987 dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
1989 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
1990 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
1993 kEplSdoComSendTypeAbort);
1995 } else if (Ret != kEplSuccessful) { // entry doesn't exist
1996 dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
1998 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
1999 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2002 kEplSdoComSendTypeAbort);
2005 // compare accesstype must be read or const
2006 if (((AccessType & kEplObdAccRead) == 0)
2007 && ((AccessType & kEplObdAccConst) == 0)) {
2009 if ((AccessType & kEplObdAccWrite) != 0) {
2010 // entry read a write only object
2011 dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ;
2013 dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
2016 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
2017 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2020 kEplSdoComSendTypeAbort);
2024 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex;
2026 // get size of object to see iof segmented or expedited transfer
2027 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2028 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
2032 if (EntrySize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer
2033 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2034 // get pointer to object-entry data
2035 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2036 pSdoComCon_p->m_pData =
2037 EplObduGetObjectDataPtr(uiIndex, uiSubindex);
2039 } else { // expedited transfer
2040 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2043 pSdoComCon_p->m_uiTransSize = EntrySize;
2044 pSdoComCon_p->m_uiTransferredByte = 0;
2046 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2048 uiSubindex, kEplSdoComSendTypeRes);
2049 if (Ret != kEplSuccessful) {
2051 dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
2053 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
2054 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2057 kEplSdoComSendTypeAbort);
2066 //---------------------------------------------------------------------------
2068 // Function: EplSdoComServerSendFrameIntern();
2070 // Description: function creats and send a frame for server
2074 // Parameters: pSdoComCon_p = pointer to control structure of connection
2075 // uiIndex_p = index to send if expedited transfer else 0
2076 // uiSubIndex_p = subindex to send if expedited transfer else 0
2077 // SendType_p = to of frame to send
2079 // Returns: tEplKernel = errorcode
2084 //---------------------------------------------------------------------------
2085 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
2086 static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
2087 unsigned int uiIndex_p,
2088 unsigned int uiSubIndex_p,
2089 tEplSdoComSendType SendType_p)
2092 u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
2094 tEplAsySdoCom *pCommandFrame;
2095 unsigned int uiSizeOfFrame;
2098 Ret = kEplSuccessful;
2100 pFrame = (tEplFrame *) & abFrame[0];
2102 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2104 // build generic part of frame
2105 // get pointer to command layerpart of frame
2107 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2108 m_le_abSdoSeqPayload;
2109 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
2110 pSdoComCon_p->m_SdoServiceType);
2111 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
2112 pSdoComCon_p->m_bTransactionId);
2114 // set size to header size
2118 switch (SendType_p) {
2119 // requestframe to send
2120 case kEplSdoComSendTypeReq:
2122 // nothing to do for server
2124 Ret = kEplSdoComInvalidSendType;
2128 // response without data to send
2129 case kEplSdoComSendTypeAckRes:
2131 // set response flag
2132 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, 0x80);
2135 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2136 uiSizeOfFrame, pFrame);
2141 // responsframe to send
2142 case kEplSdoComSendTypeRes:
2144 // set response flag
2145 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
2147 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2149 // check type of resonse
2150 if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // Expedited transfer
2151 // copy data in frame
2152 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2153 Ret = EplObduReadEntryToLe(uiIndex_p,
2161 if (Ret != kEplSuccessful) {
2166 // set size of frame
2167 AmiSetWordToLe(&pCommandFrame->
2169 (u16) pSdoComCon_p->
2172 // correct byte-counter
2173 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2174 pSdoComCon_p->m_uiTransferredByte +=
2175 pSdoComCon_p->m_uiTransSize;
2176 pSdoComCon_p->m_uiTransSize = 0;
2179 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
2181 EplSdoAsySeqSendData(pSdoComCon_p->
2183 uiSizeOfFrame, pFrame);
2184 } else if (pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented) { // segmented transfer
2185 // distinguish between init, segment and complete
2186 if (pSdoComCon_p->m_uiTransferredByte == 0) { // init
2189 AmiGetByteFromLe(&pCommandFrame->
2192 AmiSetByteToLe(&pCommandFrame->
2193 m_le_bFlags, bFlag);
2194 // init variable header
2195 AmiSetDwordToLe(&pCommandFrame->
2196 m_le_abCommandData[0],
2199 // copy data in frame
2200 EPL_MEMCPY(&pCommandFrame->
2201 m_le_abCommandData[4],
2202 pSdoComCon_p->m_pData,
2203 (EPL_SDO_MAX_PAYLOAD - 4));
2205 // correct byte-counter
2206 pSdoComCon_p->m_uiTransSize -=
2207 (EPL_SDO_MAX_PAYLOAD - 4);
2208 pSdoComCon_p->m_uiTransferredByte +=
2209 (EPL_SDO_MAX_PAYLOAD - 4);
2210 // move data pointer
2211 pSdoComCon_p->m_pData +=
2212 (EPL_SDO_MAX_PAYLOAD - 4);
2215 AmiSetWordToLe(&pCommandFrame->
2217 (EPL_SDO_MAX_PAYLOAD -
2221 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2223 EplSdoAsySeqSendData(pSdoComCon_p->
2229 if ((pSdoComCon_p->m_uiTransferredByte > 0)
2230 && (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)) { // segment
2233 AmiGetByteFromLe(&pCommandFrame->
2236 AmiSetByteToLe(&pCommandFrame->
2237 m_le_bFlags, bFlag);
2239 // copy data in frame
2240 EPL_MEMCPY(&pCommandFrame->
2241 m_le_abCommandData[0],
2242 pSdoComCon_p->m_pData,
2243 EPL_SDO_MAX_PAYLOAD);
2245 // correct byte-counter
2246 pSdoComCon_p->m_uiTransSize -=
2247 EPL_SDO_MAX_PAYLOAD;
2248 pSdoComCon_p->m_uiTransferredByte +=
2249 EPL_SDO_MAX_PAYLOAD;
2250 // move data pointer
2251 pSdoComCon_p->m_pData +=
2252 EPL_SDO_MAX_PAYLOAD;
2255 AmiSetWordToLe(&pCommandFrame->
2257 EPL_SDO_MAX_PAYLOAD);
2260 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
2262 EplSdoAsySeqSendData(pSdoComCon_p->
2267 if ((pSdoComCon_p->m_uiTransSize == 0)
2270 kEplSdoServiceWriteByIndex)) {
2274 // set segment complete flag
2276 AmiGetByteFromLe(&pCommandFrame->
2279 AmiSetByteToLe(&pCommandFrame->
2280 m_le_bFlags, bFlag);
2282 // copy data in frame
2283 EPL_MEMCPY(&pCommandFrame->
2284 m_le_abCommandData[0],
2285 pSdoComCon_p->m_pData,
2286 pSdoComCon_p->m_uiTransSize);
2288 // correct byte-counter
2289 pSdoComCon_p->m_uiTransferredByte +=
2290 pSdoComCon_p->m_uiTransSize;
2292 // move data pointer
2293 pSdoComCon_p->m_pData +=
2294 pSdoComCon_p->m_uiTransSize;
2297 AmiSetWordToLe(&pCommandFrame->
2299 (u16) pSdoComCon_p->
2304 pSdoComCon_p->m_uiTransSize;
2305 pSdoComCon_p->m_uiTransSize = 0;
2307 EplSdoAsySeqSendData(pSdoComCon_p->
2317 case kEplSdoComSendTypeAbort:
2319 // set response and abort flag
2320 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
2322 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
2324 // copy abortcode to frame
2325 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],
2326 *((u32 *) pSdoComCon_p->m_pData));
2328 // set size of segment
2329 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,
2333 pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
2334 pSdoComCon_p->m_uiTransSize = 0;
2337 uiSizeOfFrame += sizeof(u32);
2338 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2339 uiSizeOfFrame, pFrame);
2342 } // end of switch(SendType_p)
2348 //---------------------------------------------------------------------------
2350 // Function: EplSdoComServerInitWriteByIndex
2352 // Description: function start the processing of an write by index command
2356 // Parameters: pSdoComCon_p = pointer to control structure of connection
2357 // pAsySdoCom_p = pointer to received frame
2359 // Returns: tEplKernel = errorcode
2364 //---------------------------------------------------------------------------
2365 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
2366 static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
2367 tEplAsySdoCom * pAsySdoCom_p)
2369 tEplKernel Ret = kEplSuccessful;
2370 unsigned int uiIndex;
2371 unsigned int uiSubindex;
2372 unsigned int uiBytesToTransfer;
2373 tEplObdSize EntrySize;
2374 tEplObdAccess AccessType;
2380 // a init of a write
2381 // -> variable part of header possible
2383 // check if expedited or segmented transfer
2384 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x10) { // initiate segmented transfer
2385 pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
2386 // get index and subindex
2388 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]);
2390 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]);
2391 // get source-pointer for copy
2392 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8];
2394 pSdoComCon_p->m_uiTransSize =
2395 AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2397 } else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00) { // expedited transfer
2398 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
2399 // get index and subindex
2401 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
2403 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
2404 // get source-pointer for copy
2405 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4];
2407 pSdoComCon_p->m_uiTransSize =
2408 AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2410 pSdoComCon_p->m_uiTransSize -= 4;
2413 // just ignore any other transfer type
2417 // check accesstype of entry
2418 // existens of entry
2419 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2420 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
2422 Ret = kEplObdSubindexNotExist;
2425 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
2426 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
2428 // d.k. This is wrong: k.t. not needed send abort on end of write
2429 /*pSdoComCon_p->m_pData = (u8*)pSdoComCon_p->m_dwLastAbortCode;
2430 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2433 kEplSdoComSendTypeAbort); */
2435 } else if (Ret != kEplSuccessful) { // entry doesn't exist
2436 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
2438 // d.k. This is wrong: k.t. not needed send abort on end of write
2440 pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
2441 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2444 kEplSdoComSendTypeAbort); */
2447 // compare accesstype must be read
2448 if ((AccessType & kEplObdAccWrite) == 0) {
2450 if ((AccessType & kEplObdAccRead) != 0) {
2451 // entry write a read only object
2452 pSdoComCon_p->m_dwLastAbortCode =
2453 EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ;
2455 pSdoComCon_p->m_dwLastAbortCode =
2456 EPL_SDOAC_UNSUPPORTED_ACCESS;
2459 // d.k. This is wrong: k.t. not needed send abort on end of write
2460 /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
2461 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2464 kEplSdoComSendTypeAbort); */
2468 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex;
2470 pSdoComCon_p->m_uiTransferredByte = 0;
2473 if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // expedited transfer
2474 // size checking is done by EplObduWriteEntryFromLe()
2476 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2477 Ret = EplObduWriteEntryFromLe(uiIndex,
2480 pSdoComCon_p->m_uiTransSize);
2482 case kEplSuccessful:
2487 case kEplObdAccessViolation:
2489 pSdoComCon_p->m_dwLastAbortCode =
2490 EPL_SDOAC_UNSUPPORTED_ACCESS;
2495 case kEplObdValueLengthError:
2497 pSdoComCon_p->m_dwLastAbortCode =
2498 EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH;
2503 case kEplObdValueTooHigh:
2505 pSdoComCon_p->m_dwLastAbortCode =
2506 EPL_SDOAC_VALUE_RANGE_TOO_HIGH;
2511 case kEplObdValueTooLow:
2513 pSdoComCon_p->m_dwLastAbortCode =
2514 EPL_SDOAC_VALUE_RANGE_TOO_LOW;
2521 pSdoComCon_p->m_dwLastAbortCode =
2522 EPL_SDOAC_GENERAL_ERROR;
2528 // send command acknowledge
2529 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2532 kEplSdoComSendTypeAckRes);
2534 pSdoComCon_p->m_uiTransSize = 0;
2537 // get size of the object to check if it fits
2538 // because we directly write to the destination memory
2539 // d.k. no one calls the user OD callback function
2541 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2542 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
2546 if (EntrySize < pSdoComCon_p->m_uiTransSize) { // parameter too big
2547 pSdoComCon_p->m_dwLastAbortCode =
2548 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
2550 // d.k. This is wrong: k.t. not needed send abort on end of write
2551 /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
2552 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2555 kEplSdoComSendTypeAbort); */
2560 AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
2561 // eleminate header (Command header (8) + variable part (4) + Command header (4))
2562 uiBytesToTransfer -= 16;
2563 // get pointer to object entry
2564 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
2565 pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex,
2568 if (pSdoComCon_p->m_pData == NULL) {
2569 pSdoComCon_p->m_dwLastAbortCode =
2570 EPL_SDOAC_GENERAL_ERROR;
2572 // d.k. This is wrong: k.t. not needed send abort on end of write
2573 /* pSdoComCon_p->m_pData = (u8*)&pSdoComCon_p->m_dwLastAbortCode;
2574 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
2577 kEplSdoComSendTypeAbort);*/
2581 EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer);
2583 // update internal counter
2584 pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer;
2585 pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
2587 // update target pointer
2588 ( /*(u8*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
2590 // send acknowledge without any Command layer data
2591 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2592 0, (tEplFrame *) NULL);
2597 if (pSdoComCon_p->m_dwLastAbortCode != 0) {
2599 pSdoComCon_p->m_pData =
2600 (u8 *) & pSdoComCon_p->m_dwLastAbortCode;
2602 EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex,
2604 kEplSdoComSendTypeAbort);
2607 pSdoComCon_p->m_dwLastAbortCode = 0;
2608 pSdoComCon_p->m_uiTransSize = 0;
2617 //---------------------------------------------------------------------------
2619 // Function: EplSdoComClientSend
2621 // Description: function starts an sdo transfer an send all further frames
2625 // Parameters: pSdoComCon_p = pointer to control structure of connection
2627 // Returns: tEplKernel = errorcode
2632 //---------------------------------------------------------------------------
2633 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
2634 static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
2637 u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
2639 tEplAsySdoCom *pCommandFrame;
2640 unsigned int uiSizeOfFrame;
2644 Ret = kEplSuccessful;
2646 pFrame = (tEplFrame *) & abFrame[0];
2648 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
2650 // build generic part of frame
2651 // get pointer to command layerpart of frame
2653 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
2654 m_le_abSdoSeqPayload;
2655 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
2656 pSdoComCon_p->m_SdoServiceType);
2657 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
2658 pSdoComCon_p->m_bTransactionId);
2660 // set size constant part of header
2663 // check if first frame to send -> command header needed
2664 if (pSdoComCon_p->m_uiTransSize > 0) {
2665 if (pSdoComCon_p->m_uiTransferredByte == 0) { // start SDO transfer
2666 // check if segmented or expedited transfer
2667 // only for write commands
2668 switch (pSdoComCon_p->m_SdoServiceType) {
2669 case kEplSdoServiceReadByIndex:
2670 { // first frame of read access always expedited
2671 pSdoComCon_p->m_SdoTransType =
2672 kEplSdoTransExpedited;
2675 m_le_abCommandData[0];
2676 // fill rest of header
2677 AmiSetWordToLe(&pCommandFrame->
2678 m_le_wSegmentSize, 4);
2680 // create command header
2681 AmiSetWordToLe(pbPayload,
2682 (u16) pSdoComCon_p->
2685 AmiSetByteToLe(pbPayload,
2687 m_uiTargetSubIndex);
2691 // set pSdoComCon_p->m_uiTransferredByte to one
2692 pSdoComCon_p->m_uiTransferredByte = 1;
2696 case kEplSdoServiceWriteByIndex:
2698 if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // segmented transfer
2699 // -> variable part of header needed
2700 // save that transfer is segmented
2701 pSdoComCon_p->m_SdoTransType =
2702 kEplSdoTransSegmented;
2703 // fill variable part of header
2704 AmiSetDwordToLe(&pCommandFrame->
2709 // set pointer to real payload
2712 m_le_abCommandData[4];
2713 // fill rest of header
2714 AmiSetWordToLe(&pCommandFrame->
2716 EPL_SDO_MAX_PAYLOAD);
2718 AmiSetByteToLe(&pCommandFrame->
2721 // create command header
2722 AmiSetWordToLe(pbPayload,
2727 AmiSetByteToLe(pbPayload,
2730 m_uiTargetSubIndex);
2731 // on byte for reserved
2735 EPL_SDO_MAX_PAYLOAD;
2738 EPL_MEMCPY(pbPayload,
2741 (EPL_SDO_MAX_PAYLOAD
2743 pSdoComCon_p->m_pData +=
2744 (EPL_SDO_MAX_PAYLOAD - 8);
2745 // correct intern counter
2746 pSdoComCon_p->m_uiTransSize -=
2747 (EPL_SDO_MAX_PAYLOAD - 8);
2749 m_uiTransferredByte =
2750 (EPL_SDO_MAX_PAYLOAD - 8);
2752 } else { // expedited trandsfer
2753 // save that transfer is expedited
2754 pSdoComCon_p->m_SdoTransType =
2755 kEplSdoTransExpedited;
2758 m_le_abCommandData[0];
2760 // create command header
2761 AmiSetWordToLe(pbPayload,
2766 AmiSetByteToLe(pbPayload,
2769 m_uiTargetSubIndex);
2770 // + 2 -> one byte for subindex and one byte reserved
2773 EPL_MEMCPY(pbPayload,
2783 // fill rest of header
2784 AmiSetWordToLe(&pCommandFrame->
2791 m_uiTransferredByte =
2792 pSdoComCon_p->m_uiTransSize;
2793 pSdoComCon_p->m_uiTransSize = 0;
2798 case kEplSdoServiceNIL:
2800 // invalid service requested
2801 Ret = kEplSdoComInvalidServiceType;
2803 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2804 } else // (pSdoComCon_p->m_uiTransferredByte > 0)
2805 { // continue SDO transfer
2806 switch (pSdoComCon_p->m_SdoServiceType) {
2807 // for expedited read is nothing to do
2808 // -> server sends data
2810 case kEplSdoServiceWriteByIndex:
2811 { // send next frame
2812 if (pSdoComCon_p->m_SdoTransType ==
2813 kEplSdoTransSegmented) {
2814 if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) { // next segment
2819 // fill rest of header
2823 EPL_SDO_MAX_PAYLOAD);
2830 EPL_MEMCPY(pbPayload,
2833 EPL_SDO_MAX_PAYLOAD);
2834 pSdoComCon_p->m_pData +=
2835 EPL_SDO_MAX_PAYLOAD;
2836 // correct intern counter
2839 EPL_SDO_MAX_PAYLOAD;
2843 EPL_SDO_MAX_PAYLOAD;
2846 EPL_SDO_MAX_PAYLOAD;
2848 } else { // end of transfer
2853 // fill rest of header
2866 EPL_MEMCPY(pbPayload,
2871 pSdoComCon_p->m_pData +=
2878 // correct intern counter
2897 } // end of switch(pSdoComCon_p->m_SdoServiceType)
2903 // call send function of lower layer
2904 switch (pSdoComCon_p->m_SdoProtType) {
2905 case kEplSdoTypeAsnd:
2906 case kEplSdoTypeUdp:
2908 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
2909 uiSizeOfFrame, pFrame);
2915 Ret = kEplSdoComUnsupportedProt;
2917 } // end of switch(pSdoComCon_p->m_SdoProtType)
2924 //---------------------------------------------------------------------------
2926 // Function: EplSdoComClientProcessFrame
2928 // Description: function process a received frame
2932 // Parameters: SdoComCon_p = connection handle
2933 // pAsySdoCom_p = pointer to frame to process
2935 // Returns: tEplKernel = errorcode
2940 //---------------------------------------------------------------------------
2941 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
2942 static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
2943 tEplAsySdoCom * pAsySdoCom_p)
2947 unsigned int uiBuffer;
2948 unsigned int uiDataSize;
2949 unsigned long ulBuffer;
2950 tEplSdoComCon *pSdoComCon;
2952 Ret = kEplSuccessful;
2954 // get pointer to control structure
2955 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
2957 // check if transaction Id fit
2958 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
2959 if (pSdoComCon->m_bTransactionId != bBuffer) {
2960 // incorrect transaction id
2962 // if running transfer
2963 if ((pSdoComCon->m_uiTransferredByte != 0)
2964 && (pSdoComCon->m_uiTransSize != 0)) {
2965 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
2967 EplSdoComClientSendAbort(pSdoComCon,
2968 pSdoComCon->m_dwLastAbortCode);
2969 // call callback of application
2971 EplSdoComTransferFinished(SdoComCon_p, pSdoComCon,
2972 kEplSdoComTransferTxAborted);
2975 } else { // check if correct command
2976 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bCommandId);
2977 if (pSdoComCon->m_SdoServiceType != bBuffer) {
2978 // incorrect command
2979 // if running transfer
2980 if ((pSdoComCon->m_uiTransferredByte != 0)
2981 && (pSdoComCon->m_uiTransSize != 0)) {
2982 pSdoComCon->m_dwLastAbortCode =
2983 EPL_SDOAC_GENERAL_ERROR;
2985 EplSdoComClientSendAbort(pSdoComCon,
2988 // call callback of application
2990 EplSdoComTransferFinished(SdoComCon_p,
2992 kEplSdoComTransferTxAborted);
2995 } else { // switch on command
2996 switch (pSdoComCon->m_SdoServiceType) {
2997 case kEplSdoServiceWriteByIndex:
2998 { // check if confirmation from server
2999 // nothing more to do
3003 case kEplSdoServiceReadByIndex:
3004 { // check if it is an segmented or an expedited transfer
3006 AmiGetByteFromLe(&pAsySdoCom_p->
3008 // mask uninteressting bits
3011 // expedited transfer
3014 // check size of buffer
3019 if (uiBuffer > pSdoComCon->m_uiTransSize) { // buffer provided by the application is to small
3024 } else { // buffer fits
3030 EPL_MEMCPY(pSdoComCon->
3046 // start of a segmented transfer
3048 { // get total size of transfer
3054 if (ulBuffer <= pSdoComCon->m_uiTransSize) { // buffer fit
3061 } else { // buffer to small
3066 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
3068 EplSdoComClientSendAbort
3072 // call callback of application
3074 EplSdoComTransferFinished
3077 kEplSdoComTransferRxAborted);
3082 // check size of buffer
3087 // subtract size of vaiable header from datasize
3090 EPL_MEMCPY(pSdoComCon->
3097 // correct counter an pointer
3098 pSdoComCon->m_pData +=
3114 // check size of buffer
3119 // check if data to copy fit to buffer
3120 if (uiBuffer >= pSdoComCon->m_uiTransSize) { // to much data
3127 EPL_MEMCPY(pSdoComCon->
3134 // correct counter an pointer
3135 pSdoComCon->m_pData +=
3150 // check size of buffer
3155 // check if data to copy fit to buffer
3156 if (uiBuffer > pSdoComCon->m_uiTransSize) { // to much data
3163 EPL_MEMCPY(pSdoComCon->
3170 // correct counter an pointer
3171 pSdoComCon->m_pData +=
3181 } // end of switch(bBuffer & 0x30)
3186 case kEplSdoServiceNIL:
3188 // invalid service requested
3189 // $$$ d.k. What should we do?
3191 } // end of switch(pSdoComCon->m_SdoServiceType)
3200 //---------------------------------------------------------------------------
3202 // Function: EplSdoComClientSendAbort
3204 // Description: function send a abort message
3208 // Parameters: pSdoComCon_p = pointer to control structure of connection
3209 // dwAbortCode_p = Sdo abort code
3211 // Returns: tEplKernel = errorcode
3216 //---------------------------------------------------------------------------
3217 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
3218 static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
3222 u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
3224 tEplAsySdoCom *pCommandFrame;
3225 unsigned int uiSizeOfFrame;
3227 Ret = kEplSuccessful;
3229 pFrame = (tEplFrame *) & abFrame[0];
3231 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
3233 // build generic part of frame
3234 // get pointer to command layerpart of frame
3236 &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
3237 m_le_abSdoSeqPayload;
3238 AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
3239 pSdoComCon_p->m_SdoServiceType);
3240 AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
3241 pSdoComCon_p->m_bTransactionId);
3245 // set response and abort flag
3246 pCommandFrame->m_le_bFlags |= 0x40;
3248 // copy abortcode to frame
3249 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
3251 // set size of segment
3252 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(u32));
3255 pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
3256 pSdoComCon_p->m_uiTransSize = 0;
3259 uiSizeOfFrame += sizeof(u32);
3262 pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
3264 // call send function of lower layer
3265 switch (pSdoComCon_p->m_SdoProtType) {
3266 case kEplSdoTypeAsnd:
3267 case kEplSdoTypeUdp:
3269 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
3270 uiSizeOfFrame, pFrame);
3276 Ret = kEplSdoComUnsupportedProt;
3278 } // end of switch(pSdoComCon_p->m_SdoProtType)
3284 //---------------------------------------------------------------------------
3286 // Function: EplSdoComTransferFinished
3288 // Description: calls callback function of application if available
3289 // and clears entry in control structure
3291 // Parameters: pSdoComCon_p = pointer to control structure of connection
3292 // SdoComConState_p = state of SDO transfer
3294 // Returns: tEplKernel = errorcode
3299 //---------------------------------------------------------------------------
3300 static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
3301 tEplSdoComCon * pSdoComCon_p,
3302 tEplSdoComConState SdoComConState_p)
3306 Ret = kEplSuccessful;
3308 if (pSdoComCon_p->m_pfnTransferFinished != NULL) {
3309 tEplSdoFinishedCb pfnTransferFinished;
3310 tEplSdoComFinished SdoComFinished;
3312 SdoComFinished.m_pUserArg = pSdoComCon_p->m_pUserArg;
3313 SdoComFinished.m_uiNodeId = pSdoComCon_p->m_uiNodeId;
3314 SdoComFinished.m_uiTargetIndex = pSdoComCon_p->m_uiTargetIndex;
3315 SdoComFinished.m_uiTargetSubIndex =
3316 pSdoComCon_p->m_uiTargetSubIndex;
3317 SdoComFinished.m_uiTransferredByte =
3318 pSdoComCon_p->m_uiTransferredByte;
3319 SdoComFinished.m_dwAbortCode = pSdoComCon_p->m_dwLastAbortCode;
3320 SdoComFinished.m_SdoComConHdl = SdoComCon_p;
3321 SdoComFinished.m_SdoComConState = SdoComConState_p;
3322 if (pSdoComCon_p->m_SdoServiceType ==
3323 kEplSdoServiceWriteByIndex) {
3324 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeWrite;
3326 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead;
3329 // reset transfer state so this handle is not busy anymore
3330 pSdoComCon_p->m_uiTransferredByte = 0;
3331 pSdoComCon_p->m_uiTransSize = 0;
3333 pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished;
3334 // delete function pointer to inform application only once for each transfer
3335 pSdoComCon_p->m_pfnTransferFinished = NULL;
3337 // call application's callback function
3338 pfnTransferFinished(&SdoComFinished);