Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.30-rc4 3345 lines 92 kB view raw
1/**************************************************************************** 2 3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 4 www.systec-electronic.com 5 6 Project: openPOWERLINK 7 8 Description: source file for SDO Command Layer module 9 10 License: 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions 14 are met: 15 16 1. Redistributions of source code must retain the above copyright 17 notice, this list of conditions and the following disclaimer. 18 19 2. Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in the 21 documentation and/or other materials provided with the distribution. 22 23 3. Neither the name of SYSTEC electronic GmbH nor the names of its 24 contributors may be used to endorse or promote products derived 25 from this software without prior written permission. For written 26 permission, please contact info@systec-electronic.com. 27 28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 POSSIBILITY OF SUCH DAMAGE. 40 41 Severability Clause: 42 43 If a provision of this License is or becomes illegal, invalid or 44 unenforceable in any jurisdiction, that shall not affect: 45 1. the validity or enforceability in that jurisdiction of any other 46 provision of this License; or 47 2. the validity or enforceability in other jurisdictions of that or 48 any other provision of this License. 49 50 ------------------------------------------------------------------------- 51 52 $RCSfile: EplSdoComu.c,v $ 53 54 $Author: D.Krueger $ 55 56 $Revision: 1.14 $ $Date: 2008/10/17 15:32:32 $ 57 58 $State: Exp $ 59 60 Build Environment: 61 GCC V3.4 62 63 ------------------------------------------------------------------------- 64 65 Revision History: 66 67 2006/06/26 k.t.: start of the implementation 68 69****************************************************************************/ 70 71#include "user/EplSdoComu.h" 72 73#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) == 0) &&\ 74 (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) == 0) ) 75 76#error 'ERROR: At least SDO Server or SDO Client should be activate!' 77 78#endif 79 80#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 81#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE) 82 83#error 'ERROR: SDO Server needs OBDu module!' 84 85#endif 86 87#endif 88 89/***************************************************************************/ 90/* */ 91/* */ 92/* G L O B A L D E F I N I T I O N S */ 93/* */ 94/* */ 95/***************************************************************************/ 96 97//--------------------------------------------------------------------------- 98// const defines 99//--------------------------------------------------------------------------- 100 101#ifndef EPL_MAX_SDO_COM_CON 102#define EPL_MAX_SDO_COM_CON 5 103#endif 104 105//--------------------------------------------------------------------------- 106// local types 107//--------------------------------------------------------------------------- 108 109// intern events 110typedef enum { 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 119 // of the connection 120 kEplSdoComConEventTimeout = 0x07 // timeout in lower layer 121#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 122 , 123 124 kEplSdoComConEventInitCon = 0x08, // init connection (only client) 125 kEplSdoComConEventAbort = 0x09 // abort sdo transfer (only client) 126#endif 127} tEplSdoComConEvent; 128 129typedef enum { 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; 135 136// state of the state maschine 137typedef enum { 138 // General State 139 kEplSdoComStateIdle = 0x00, // idle state 140 141#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 142 // Server States 143 kEplSdoComStateServerSegmTrans = 0x01, // send following frames 144#endif 145 146#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 147 // Client States 148 kEplSdoComStateClientWaitInit = 0x10, // wait for init connection 149 // on lower layer 150 kEplSdoComStateClientConnected = 0x11, // connection established 151 kEplSdoComStateClientSegmTrans = 0x12 // send following frames 152#endif 153} tEplSdoComState; 154 155// control structure for transaction 156typedef struct { 157 tEplSdoSeqConHdl m_SdoSeqConHdl; // if != 0 -> entry used 158 tEplSdoComState m_SdoComState; 159 u8 m_bTransactionId; 160 unsigned int m_uiNodeId; // NodeId of the target 161 // -> needed to reinit connection 162 // after timeout 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 168 // to transfer 169 unsigned int m_uiTransferredByte; // number of bytes 170 // already transferred 171 tEplSdoFinishedCb m_pfnTransferFinished; // callback function of the 172 // application 173 // -> called in the end of 174 // the SDO transfer 175 void *m_pUserArg; // user definable argument pointer 176 177 u32 m_dwLastAbortCode; // save the last abort code 178#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 179 // only for client 180 unsigned int m_uiTargetIndex; // index to access 181 unsigned int m_uiTargetSubIndex; // subiondex to access 182 183 // for future use 184 unsigned int m_uiTimeout; // timeout for this connection 185 186#endif 187 188} tEplSdoComCon; 189 190// instance table 191typedef struct { 192 tEplSdoComCon m_SdoComCon[EPL_MAX_SDO_COM_CON]; 193 194#if defined(WIN32) || defined(_WIN32) 195 LPCRITICAL_SECTION m_pCriticalSection; 196 CRITICAL_SECTION m_CriticalSection; 197#endif 198 199} tEplSdoComInstance; 200 201//--------------------------------------------------------------------------- 202// modul globale vars 203//--------------------------------------------------------------------------- 204static tEplSdoComInstance SdoComInstance_g; 205//--------------------------------------------------------------------------- 206// local function prototypes 207//--------------------------------------------------------------------------- 208tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p, 209 tEplAsySdoCom *pAsySdoCom_p, 210 unsigned int uiDataSize_p); 211 212tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p, 213 tEplAsySdoConState AsySdoConState_p); 214 215static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p, 216 tEplSdoComConEvent SdoComConEvent_p, 217 tEplAsySdoCom * pAsySdoCom_p); 218 219static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p, 220 tEplSdoComConEvent SdoComConEvent_p, 221 tEplAsySdoCom * pAsySdoCom_p); 222 223static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p, 224 tEplSdoComCon * pSdoComCon_p, 225 tEplSdoComConState 226 SdoComConState_p); 227 228#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 229static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p, 230 tEplAsySdoCom * pAsySdoCom_p); 231 232static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p, 233 unsigned int uiIndex_p, 234 unsigned int uiSubIndex_p, 235 tEplSdoComSendType SendType_p); 236 237static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p, 238 tEplAsySdoCom * pAsySdoCom_p); 239#endif 240 241#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 242 243static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p); 244 245static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p, 246 tEplAsySdoCom * pAsySdoCom_p); 247 248static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p, 249 u32 dwAbortCode_p); 250#endif 251 252/***************************************************************************/ 253/* */ 254/* */ 255/* C L A S S <SDO Command Layer> */ 256/* */ 257/* */ 258/***************************************************************************/ 259// 260// Description: SDO Command layer Modul 261// 262// 263/***************************************************************************/ 264 265//=========================================================================// 266// // 267// P U B L I C F U N C T I O N S // 268// // 269//=========================================================================// 270 271//--------------------------------------------------------------------------- 272// 273// Function: EplSdoComInit 274// 275// Description: Init first instance of the module 276// 277// 278// 279// Parameters: 280// 281// 282// Returns: tEplKernel = errorcode 283// 284// 285// State: 286// 287//--------------------------------------------------------------------------- 288tEplKernel EplSdoComInit(void) 289{ 290 tEplKernel Ret; 291 292 Ret = EplSdoComAddInstance(); 293 294 return Ret; 295 296} 297 298//--------------------------------------------------------------------------- 299// 300// Function: EplSdoComAddInstance 301// 302// Description: Init additional instance of the module 303// 304// 305// 306// Parameters: 307// 308// 309// Returns: tEplKernel = errorcode 310// 311// 312// State: 313// 314//--------------------------------------------------------------------------- 315tEplKernel EplSdoComAddInstance(void) 316{ 317 tEplKernel Ret; 318 319 Ret = kEplSuccessful; 320 321 // init controll structure 322 EPL_MEMSET(&SdoComInstance_g, 0x00, sizeof(SdoComInstance_g)); 323 324 // init instance of lower layer 325 Ret = EplSdoAsySeqAddInstance(EplSdoComReceiveCb, EplSdoComConCb); 326 if (Ret != kEplSuccessful) { 327 goto Exit; 328 } 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); 334#endif 335 336 Exit: 337 return Ret; 338} 339 340//--------------------------------------------------------------------------- 341// 342// Function: EplSdoComDelInstance 343// 344// Description: delete instance of the module 345// 346// 347// 348// Parameters: 349// 350// 351// Returns: tEplKernel = errorcode 352// 353// 354// State: 355// 356//--------------------------------------------------------------------------- 357tEplKernel EplSdoComDelInstance(void) 358{ 359 tEplKernel Ret; 360 361 Ret = kEplSuccessful; 362 363#if defined(WIN32) || defined(_WIN32) 364 // delete critical section for process function 365 DeleteCriticalSection(SdoComInstance_g.m_pCriticalSection); 366#endif 367 368 Ret = EplSdoAsySeqDelInstance(); 369 if (Ret != kEplSuccessful) { 370 goto Exit; 371 } 372 373 Exit: 374 return Ret; 375} 376 377//--------------------------------------------------------------------------- 378// 379// Function: EplSdoComDefineCon 380// 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. 388// 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 392// 393// 394// Returns: tEplKernel = errorcode 395// 396// 397// State: 398// 399//--------------------------------------------------------------------------- 400#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 401tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p, 402 unsigned int uiTargetNodeId_p, 403 tEplSdoType ProtType_p) 404{ 405 tEplKernel Ret; 406 unsigned int uiCount; 407 unsigned int uiFreeHdl; 408 tEplSdoComCon *pSdoComCon; 409 410 // check Parameter 411 ASSERT(pSdoComConHdl_p != NULL); 412 413 // check NodeId 414 if ((uiTargetNodeId_p == EPL_C_ADR_INVALID) 415 || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) { 416 Ret = kEplInvalidNodeId; 417 418 } 419 // search free control structure 420 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0]; 421 uiCount = 0; 422 uiFreeHdl = EPL_MAX_SDO_COM_CON; 423 while (uiCount < EPL_MAX_SDO_COM_CON) { 424 if (pSdoComCon->m_SdoSeqConHdl == 0) { // free entry 425 uiFreeHdl = uiCount; 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; 430 goto Exit; 431 } 432 uiCount++; 433 pSdoComCon++; 434 } 435 436 if (uiFreeHdl == EPL_MAX_SDO_COM_CON) { 437 Ret = kEplSdoComNoFreeHandle; 438 goto Exit; 439 } 440 441 pSdoComCon = &SdoComInstance_g.m_SdoComCon[uiFreeHdl]; 442 // save handle for application 443 *pSdoComConHdl_p = uiFreeHdl; 444 // save parameters 445 pSdoComCon->m_SdoProtType = ProtType_p; 446 pSdoComCon->m_uiNodeId = uiTargetNodeId_p; 447 448 // set Transaction Id 449 pSdoComCon->m_bTransactionId = 0; 450 451 // check protocol 452 switch (ProtType_p) { 453 // udp 454 case kEplSdoTypeUdp: 455 { 456 // call connection int function of lower layer 457 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl, 458 pSdoComCon->m_uiNodeId, 459 kEplSdoTypeUdp); 460 if (Ret != kEplSuccessful) { 461 goto Exit; 462 } 463 break; 464 } 465 466 // Asend 467 case kEplSdoTypeAsnd: 468 { 469 // call connection int function of lower layer 470 Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl, 471 pSdoComCon->m_uiNodeId, 472 kEplSdoTypeAsnd); 473 if (Ret != kEplSuccessful) { 474 goto Exit; 475 } 476 break; 477 } 478 479 // Pdo -> not supported 480 case kEplSdoTypePdo: 481 default: 482 { 483 Ret = kEplSdoComUnsupportedProt; 484 goto Exit; 485 } 486 } // end of switch(m_ProtType_p) 487 488 // call process function 489 Ret = EplSdoComProcessIntern(uiFreeHdl, 490 kEplSdoComConEventInitCon, NULL); 491 492 Exit: 493 return Ret; 494} 495#endif 496//--------------------------------------------------------------------------- 497// 498// Function: EplSdoComInitTransferByIndex 499// 500// Description: function init SDO Transfer for a defined connection 501// 502// 503// 504// Parameters: SdoComTransParam_p = Structure with parameters for connection 505// 506// 507// Returns: tEplKernel = errorcode 508// 509// 510// State: 511// 512//--------------------------------------------------------------------------- 513#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 514tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p) 515{ 516 tEplKernel Ret; 517 tEplSdoComCon *pSdoComCon; 518 519 // check parameter 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; 526 goto Exit; 527 } 528 529 if (pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON) { 530 Ret = kEplSdoComInvalidHandle; 531 goto Exit; 532 } 533 // get pointer to control structure of connection 534 pSdoComCon = 535 &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl]; 536 537 // check if handle ok 538 if (pSdoComCon->m_SdoSeqConHdl == 0) { 539 Ret = kEplSdoComInvalidHandle; 540 goto Exit; 541 } 542 // check if command layer is idle 543 if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0) { // handle is not idle 544 Ret = kEplSdoComHandleBusy; 545 goto Exit; 546 } 547 // save parameter 548 // callback function for end of transfer 549 pSdoComCon->m_pfnTransferFinished = 550 pSdoComTransParam_p->m_pfnSdoFinishedCb; 551 pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg; 552 553 // set type of SDO command 554 if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead) { 555 pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex; 556 } else { 557 pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex; 558 559 } 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; 566 567 // reset parts of control structure 568 pSdoComCon->m_dwLastAbortCode = 0; 569 pSdoComCon->m_SdoTransType = kEplSdoTransAuto; 570 // save timeout 571 //pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout; 572 573 // save index and subindex 574 pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex; 575 pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex; 576 577 // call process function 578 Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl, kEplSdoComConEventSendFirst, // event to start transfer 579 NULL); 580 581 Exit: 582 return Ret; 583 584} 585#endif 586 587//--------------------------------------------------------------------------- 588// 589// Function: EplSdoComUndefineCon 590// 591// Description: function undefine a SDO connection 592// 593// 594// 595// Parameters: SdoComConHdl_p = handle for the connection 596// 597// 598// Returns: tEplKernel = errorcode 599// 600// 601// State: 602// 603//--------------------------------------------------------------------------- 604#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 605tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p) 606{ 607 tEplKernel Ret; 608 tEplSdoComCon *pSdoComCon; 609 610 Ret = kEplSuccessful; 611 612 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) { 613 Ret = kEplSdoComInvalidHandle; 614 goto Exit; 615 } 616 // get pointer to control structure 617 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p]; 618 619 // $$$ d.k. abort a running transfer before closing the sequence layer 620 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: 627 case kEplSdoTypeUdp: 628 { 629 Ret = 630 EplSdoAsySeqDelCon(pSdoComCon-> 631 m_SdoSeqConHdl); 632 break; 633 } 634 635 case kEplSdoTypePdo: 636 case kEplSdoTypeAuto: 637 default: 638 { 639 Ret = kEplSdoComUnsupportedProt; 640 goto Exit; 641 } 642 643 } // end of switch(pSdoComCon->m_SdoProtType) 644 } 645 646 // clean controll structure 647 EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon)); 648 Exit: 649 return Ret; 650} 651#endif 652//--------------------------------------------------------------------------- 653// 654// Function: EplSdoComGetState 655// 656// Description: function returns the state fo the connection 657// 658// 659// 660// Parameters: SdoComConHdl_p = handle for the connection 661// pSdoComFinished_p = pointer to structur for sdo state 662// 663// 664// Returns: tEplKernel = errorcode 665// 666// 667// State: 668// 669//--------------------------------------------------------------------------- 670#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 671tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p, 672 tEplSdoComFinished *pSdoComFinished_p) 673{ 674 tEplKernel Ret; 675 tEplSdoComCon *pSdoComCon; 676 677 Ret = kEplSuccessful; 678 679 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) { 680 Ret = kEplSdoComInvalidHandle; 681 goto Exit; 682 } 683 // get pointer to control structure 684 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p]; 685 686 // check if handle ok 687 if (pSdoComCon->m_SdoSeqConHdl == 0) { 688 Ret = kEplSdoComInvalidHandle; 689 goto Exit; 690 } 691 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; 702 } else { 703 pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead; 704 } 705 706 if (pSdoComCon->m_dwLastAbortCode != 0) { // sdo abort 707 pSdoComFinished_p->m_SdoComConState = 708 kEplSdoComTransferRxAborted; 709 710 // delete abort code 711 pSdoComCon->m_dwLastAbortCode = 0; 712 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) { 717 // finished 718 pSdoComFinished_p->m_SdoComConState = 719 kEplSdoComTransferNotActive; 720 } else if (pSdoComCon->m_uiTransSize == 0) { // finished 721 pSdoComFinished_p->m_SdoComConState = 722 kEplSdoComTransferFinished; 723 } 724 725 Exit: 726 return Ret; 727 728} 729#endif 730//--------------------------------------------------------------------------- 731// 732// Function: EplSdoComSdoAbort 733// 734// Description: function abort a sdo transfer 735// 736// 737// 738// Parameters: SdoComConHdl_p = handle for the connection 739// dwAbortCode_p = abort code 740// 741// 742// Returns: tEplKernel = errorcode 743// 744// 745// State: 746// 747//--------------------------------------------------------------------------- 748#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 749tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p, 750 u32 dwAbortCode_p) 751{ 752 tEplKernel Ret; 753 tEplSdoComCon *pSdoComCon; 754 755 if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) { 756 Ret = kEplSdoComInvalidHandle; 757 goto Exit; 758 } 759 // get pointer to control structure of connection 760 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p]; 761 762 // check if handle ok 763 if (pSdoComCon->m_SdoSeqConHdl == 0) { 764 Ret = kEplSdoComInvalidHandle; 765 goto Exit; 766 } 767 // save pointer to abort code 768 pSdoComCon->m_pData = (u8 *) & dwAbortCode_p; 769 770 Ret = EplSdoComProcessIntern(SdoComConHdl_p, 771 kEplSdoComConEventAbort, 772 (tEplAsySdoCom *) NULL); 773 774 Exit: 775 return Ret; 776} 777#endif 778 779//=========================================================================// 780// // 781// P R I V A T E F U N C T I O N S // 782// // 783//=========================================================================// 784 785//--------------------------------------------------------------------------- 786// 787// Function: EplSdoComReceiveCb 788// 789// Description: callback function for SDO Sequence Layer 790// -> indicates new data 791// 792// 793// 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) 797// 798// 799// Returns: 800// 801// 802// State: 803// 804//--------------------------------------------------------------------------- 805tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p, 806 tEplAsySdoCom *pAsySdoCom_p, 807 unsigned int uiDataSize_p) 808{ 809 tEplKernel Ret; 810 811 // search connection internally 812 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p, 813 kEplSdoComConEventRec, pAsySdoCom_p); 814 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], 818 uiDataSize_p); 819 820 return Ret; 821} 822 823//--------------------------------------------------------------------------- 824// 825// Function: EplSdoComConCb 826// 827// Description: callback function called by SDO Sequence Layer to inform 828// command layer about state change of connection 829// 830// 831// 832// Parameters: SdoSeqConHdl_p = Handle of the connection 833// AsySdoConState_p = Event of the connection 834// 835// 836// Returns: tEplKernel = Errorcode 837// 838// 839// State: 840// 841//--------------------------------------------------------------------------- 842tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p, 843 tEplAsySdoConState AsySdoConState_p) 844{ 845 tEplKernel Ret; 846 tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst; 847 848 Ret = kEplSuccessful; 849 850 // check state 851 switch (AsySdoConState_p) { 852 case kAsySdoConStateConnected: 853 { 854 EPL_DBGLVL_SDO_TRACE0("Connection established\n"); 855 SdoComConEvent = kEplSdoComConEventConEstablished; 856 // start transmission if needed 857 break; 858 } 859 860 case kAsySdoConStateInitError: 861 { 862 EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n"); 863 SdoComConEvent = kEplSdoComConEventInitError; 864 // inform app about error and close sequence layer handle 865 break; 866 } 867 868 case kAsySdoConStateConClosed: 869 { 870 EPL_DBGLVL_SDO_TRACE0("Connection closed\n"); 871 SdoComConEvent = kEplSdoComConEventConClosed; 872 // close sequence layer handle 873 break; 874 } 875 876 case kAsySdoConStateAckReceived: 877 { 878 EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n"); 879 SdoComConEvent = kEplSdoComConEventAckReceived; 880 // continue transmission 881 break; 882 } 883 884 case kAsySdoConStateFrameSended: 885 { 886 EPL_DBGLVL_SDO_TRACE0("One Frame sent\n"); 887 SdoComConEvent = kEplSdoComConEventFrameSended; 888 // to continue transmission 889 break; 890 891 } 892 893 case kAsySdoConStateTimeout: 894 { 895 EPL_DBGLVL_SDO_TRACE0("Timeout\n"); 896 SdoComConEvent = kEplSdoComConEventTimeout; 897 // close sequence layer handle 898 break; 899 900 } 901 } // end of switch(AsySdoConState_p) 902 903 Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p, 904 SdoComConEvent, (tEplAsySdoCom *) NULL); 905 906 return Ret; 907} 908 909//--------------------------------------------------------------------------- 910// 911// Function: EplSdoComSearchConIntern 912// 913// Description: search a Sdo Sequence Layer connection handle in the 914// control structure of the Command Layer 915// 916// Parameters: SdoSeqConHdl_p = Handle to search 917// SdoComConEvent_p = event to process 918// pAsySdoCom_p = pointer to received frame 919// 920// Returns: tEplKernel 921// 922// 923// State: 924// 925//--------------------------------------------------------------------------- 926static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p, 927 tEplSdoComConEvent SdoComConEvent_p, 928 tEplAsySdoCom * pAsySdoCom_p) 929{ 930 tEplKernel Ret; 931 tEplSdoComCon *pSdoComCon; 932 tEplSdoComConHdl HdlCount; 933 tEplSdoComConHdl HdlFree; 934 935 Ret = kEplSdoComNotResponsible; 936 937 // get pointer to first element of the array 938 pSdoComCon = &SdoComInstance_g.m_SdoComCon[0]; 939 HdlCount = 0; 940 HdlFree = 0xFFFF; 941 while (HdlCount < EPL_MAX_SDO_COM_CON) { 942 if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p) { // matching command layer handle found 943 Ret = EplSdoComProcessIntern(HdlCount, 944 SdoComConEvent_p, 945 pAsySdoCom_p); 946 } else if ((pSdoComCon->m_SdoSeqConHdl == 0) 947 && (HdlFree == 0xFFFF)) { 948 HdlFree = HdlCount; 949 } 950 951 pSdoComCon++; 952 HdlCount++; 953 } 954 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 963 HdlCount = HdlFree; 964 pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount]; 965 pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p; 966 Ret = EplSdoComProcessIntern(HdlCount, 967 SdoComConEvent_p, 968 pAsySdoCom_p); 969 } 970 } 971 972 return Ret; 973 974} 975 976//--------------------------------------------------------------------------- 977// 978// Function: EplSdoComProcessIntern 979// 980// Description: search a Sdo Sequence Layer connection handle in the 981// control structer of the Command Layer 982// 983// 984// 985// Parameters: SdoComCon_p = index of control structure of connection 986// SdoComConEvent_p = event to process 987// pAsySdoCom_p = pointer to received frame 988// 989// Returns: tEplKernel = errorcode 990// 991// 992// State: 993// 994//--------------------------------------------------------------------------- 995static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p, 996 tEplSdoComConEvent SdoComConEvent_p, 997 tEplAsySdoCom * pAsySdoCom_p) 998{ 999 tEplKernel Ret; 1000 tEplSdoComCon *pSdoComCon; 1001 u8 bFlag; 1002 1003#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 1004 u32 dwAbortCode; 1005 unsigned int uiSize; 1006#endif 1007 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"); 1013#endif 1014 1015 Ret = kEplSuccessful; 1016 1017 // get pointer to control structure 1018 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p]; 1019 1020 // process state maschine 1021 switch (pSdoComCon->m_SdoComState) { 1022 // idle state 1023 case kEplSdoComStateIdle: 1024 { 1025 // check events 1026 switch (SdoComConEvent_p) { 1027#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 1028 // init con for client 1029 case kEplSdoComConEventInitCon: 1030 { 1031 1032 // call of the init function already 1033 // processed in EplSdoComDefineCon() 1034 // only change state to kEplSdoComStateClientWaitInit 1035 pSdoComCon->m_SdoComState = 1036 kEplSdoComStateClientWaitInit; 1037 break; 1038 } 1039#endif 1040 1041 // int con for server 1042 case kEplSdoComConEventRec: 1043 { 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 1049 pSdoComCon-> 1050 m_bTransactionId = 1051 AmiGetByteFromLe 1052 (&pAsySdoCom_p-> 1053 m_le_bTransactionId); 1054 // check command 1055 switch (pAsySdoCom_p-> 1056 m_le_bCommandId) 1057 { 1058 case kEplSdoServiceNIL: 1059 { // simply acknowlegde NIL command on sequence layer 1060 1061 Ret = 1062 EplSdoAsySeqSendData 1063 (pSdoComCon-> 1064 m_SdoSeqConHdl, 1065 0, 1066 (tEplFrame 1067 *) 1068 NULL); 1069 1070 break; 1071 } 1072 1073 case kEplSdoServiceReadByIndex: 1074 { // read by index 1075 1076 // search entry an start transfer 1077 EplSdoComServerInitReadByIndex 1078 (pSdoComCon, 1079 pAsySdoCom_p); 1080 // check next state 1081 if (pSdoComCon->m_uiTransSize == 0) { // ready -> stay idle 1082 pSdoComCon-> 1083 m_SdoComState 1084 = 1085 kEplSdoComStateIdle; 1086 // reset abort code 1087 pSdoComCon-> 1088 m_dwLastAbortCode 1089 = 1090 0; 1091 } else { // segmented transfer 1092 pSdoComCon-> 1093 m_SdoComState 1094 = 1095 kEplSdoComStateServerSegmTrans; 1096 } 1097 1098 break; 1099 } 1100 1101 case kEplSdoServiceWriteByIndex: 1102 { 1103 1104 // search entry an start write 1105 EplSdoComServerInitWriteByIndex 1106 (pSdoComCon, 1107 pAsySdoCom_p); 1108 // check next state 1109 if (pSdoComCon->m_uiTransSize == 0) { // already -> stay idle 1110 pSdoComCon-> 1111 m_SdoComState 1112 = 1113 kEplSdoComStateIdle; 1114 // reset abort code 1115 pSdoComCon-> 1116 m_dwLastAbortCode 1117 = 1118 0; 1119 } else { // segmented transfer 1120 pSdoComCon-> 1121 m_SdoComState 1122 = 1123 kEplSdoComStateServerSegmTrans; 1124 } 1125 1126 break; 1127 } 1128 1129 default: 1130 { 1131 // unsupported command 1132 // -> abort senden 1133 dwAbortCode 1134 = 1135 EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER; 1136 // send abort 1137 pSdoComCon-> 1138 m_pData 1139 = 1140 (u8 1141 *) 1142 & 1143 dwAbortCode; 1144 Ret = 1145 EplSdoComServerSendFrameIntern 1146 (pSdoComCon, 1147 0, 1148 0, 1149 kEplSdoComSendTypeAbort); 1150 1151 } 1152 1153 } // end of switch(pAsySdoCom_p->m_le_bCommandId) 1154 } 1155 } else { // this command layer handle is not responsible 1156 // (wrong direction or wrong transaction ID) 1157 Ret = kEplSdoComNotResponsible; 1158 goto Exit; 1159 } 1160#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 1161 1162 break; 1163 } 1164 1165 // connection closed 1166 case kEplSdoComConEventInitError: 1167 case kEplSdoComConEventTimeout: 1168 case kEplSdoComConEventConClosed: 1169 { 1170 Ret = 1171 EplSdoAsySeqDelCon(pSdoComCon-> 1172 m_SdoSeqConHdl); 1173 // clean control structure 1174 EPL_MEMSET(pSdoComCon, 0x00, 1175 sizeof(tEplSdoComCon)); 1176 break; 1177 } 1178 1179 default: 1180 // d.k. do nothing 1181 break; 1182 } // end of switch(SdoComConEvent_p) 1183 break; 1184 } 1185 1186#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 1187 //------------------------------------------------------------------------- 1188 // SDO Server part 1189 // segmented transfer 1190 case kEplSdoComStateServerSegmTrans: 1191 { 1192 // check events 1193 switch (SdoComConEvent_p) { 1194 // send next frame 1195 case kEplSdoComConEventAckReceived: 1196 case kEplSdoComConEventFrameSended: 1197 { 1198 // check if it is a read 1199 if (pSdoComCon->m_SdoServiceType == 1200 kEplSdoServiceReadByIndex) { 1201 // send next frame 1202 EplSdoComServerSendFrameIntern 1203 (pSdoComCon, 0, 0, 1204 kEplSdoComSendTypeRes); 1205 // if all send -> back to idle 1206 if (pSdoComCon->m_uiTransSize == 0) { // back to idle 1207 pSdoComCon-> 1208 m_SdoComState = 1209 kEplSdoComStateIdle; 1210 // reset abort code 1211 pSdoComCon-> 1212 m_dwLastAbortCode = 1213 0; 1214 } 1215 1216 } 1217 break; 1218 } 1219 1220 // process next frame 1221 case kEplSdoComConEventRec: 1222 { 1223 // check if the frame is a SDO response and has the right transaction ID 1224 bFlag = 1225 AmiGetByteFromLe(&pAsySdoCom_p-> 1226 m_le_bFlags); 1227 if (((bFlag & 0x80) != 0) 1228 && 1229 (AmiGetByteFromLe 1230 (&pAsySdoCom_p-> 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 1236 pSdoComCon-> 1237 m_uiTransSize = 0; 1238 pSdoComCon-> 1239 m_uiTransferredByte 1240 = 0; 1241 // change state 1242 pSdoComCon-> 1243 m_SdoComState = 1244 kEplSdoComStateIdle; 1245 // reset abort code 1246 pSdoComCon-> 1247 m_dwLastAbortCode = 1248 0; 1249 // d.k.: do not execute anything further on this command 1250 break; 1251 } 1252 // check if it is a write 1253 if (pSdoComCon-> 1254 m_SdoServiceType == 1255 kEplSdoServiceWriteByIndex) 1256 { 1257 // write data to OD 1258 uiSize = 1259 AmiGetWordFromLe 1260 (&pAsySdoCom_p-> 1261 m_le_wSegmentSize); 1262 if (pSdoComCon-> 1263 m_dwLastAbortCode == 1264 0) { 1265 EPL_MEMCPY 1266 (pSdoComCon-> 1267 m_pData, 1268 &pAsySdoCom_p-> 1269 m_le_abCommandData 1270 [0], 1271 uiSize); 1272 } 1273 // update counter 1274 pSdoComCon-> 1275 m_uiTransferredByte 1276 += uiSize; 1277 pSdoComCon-> 1278 m_uiTransSize -= 1279 uiSize; 1280 1281 // update pointer 1282 if (pSdoComCon-> 1283 m_dwLastAbortCode == 1284 0) { 1285 ( /*(u8*) */ 1286 pSdoComCon-> 1287 m_pData) += 1288 uiSize; 1289 } 1290 // check end of transfer 1291 if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30) { // transfer ready 1292 pSdoComCon-> 1293 m_uiTransSize 1294 = 0; 1295 1296 if (pSdoComCon-> 1297 m_dwLastAbortCode 1298 == 0) { 1299 // send response 1300 // send next frame 1301 EplSdoComServerSendFrameIntern 1302 (pSdoComCon, 1303 0, 1304 0, 1305 kEplSdoComSendTypeRes); 1306 // if all send -> back to idle 1307 if (pSdoComCon->m_uiTransSize == 0) { // back to idle 1308 pSdoComCon-> 1309 m_SdoComState 1310 = 1311 kEplSdoComStateIdle; 1312 // reset abort code 1313 pSdoComCon-> 1314 m_dwLastAbortCode 1315 = 1316 0; 1317 } 1318 } else { // send dabort code 1319 // send abort 1320 pSdoComCon-> 1321 m_pData 1322 = 1323 (u8 1324 *) 1325 & 1326 pSdoComCon-> 1327 m_dwLastAbortCode; 1328 Ret = 1329 EplSdoComServerSendFrameIntern 1330 (pSdoComCon, 1331 0, 1332 0, 1333 kEplSdoComSendTypeAbort); 1334 1335 // reset abort code 1336 pSdoComCon-> 1337 m_dwLastAbortCode 1338 = 0; 1339 1340 } 1341 } else { 1342 // send acknowledge without any Command layer data 1343 Ret = 1344 EplSdoAsySeqSendData 1345 (pSdoComCon-> 1346 m_SdoSeqConHdl, 1347 0, 1348 (tEplFrame 1349 *) NULL); 1350 } 1351 } 1352 } else { // this command layer handle is not responsible 1353 // (wrong direction or wrong transaction ID) 1354 Ret = kEplSdoComNotResponsible; 1355 goto Exit; 1356 } 1357 break; 1358 } 1359 1360 // connection closed 1361 case kEplSdoComConEventInitError: 1362 case kEplSdoComConEventTimeout: 1363 case kEplSdoComConEventConClosed: 1364 { 1365 Ret = 1366 EplSdoAsySeqDelCon(pSdoComCon-> 1367 m_SdoSeqConHdl); 1368 // clean control structure 1369 EPL_MEMSET(pSdoComCon, 0x00, 1370 sizeof(tEplSdoComCon)); 1371 break; 1372 } 1373 1374 default: 1375 // d.k. do nothing 1376 break; 1377 } // end of switch(SdoComConEvent_p) 1378 1379 break; 1380 } 1381#endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 1382 1383#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 1384 //------------------------------------------------------------------------- 1385 // SDO Client part 1386 // wait for finish of establishing connection 1387 case kEplSdoComStateClientWaitInit: 1388 { 1389 1390 // if connection handle is invalid reinit connection 1391 // d.k.: this will be done only on new events (i.e. InitTransfer) 1392 if ((pSdoComCon-> 1393 m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == 1394 EPL_SDO_SEQ_INVALID_HDL) { 1395 // check kind of connection to reinit 1396 // check protocol 1397 switch (pSdoComCon->m_SdoProtType) { 1398 // udp 1399 case kEplSdoTypeUdp: 1400 { 1401 // call connection int function of lower layer 1402 Ret = 1403 EplSdoAsySeqInitCon 1404 (&pSdoComCon-> 1405 m_SdoSeqConHdl, 1406 pSdoComCon->m_uiNodeId, 1407 kEplSdoTypeUdp); 1408 if (Ret != kEplSuccessful) { 1409 goto Exit; 1410 } 1411 break; 1412 } 1413 1414 // Asend -> not supported 1415 case kEplSdoTypeAsnd: 1416 { 1417 // call connection int function of lower layer 1418 Ret = 1419 EplSdoAsySeqInitCon 1420 (&pSdoComCon-> 1421 m_SdoSeqConHdl, 1422 pSdoComCon->m_uiNodeId, 1423 kEplSdoTypeAsnd); 1424 if (Ret != kEplSuccessful) { 1425 goto Exit; 1426 } 1427 break; 1428 } 1429 1430 // Pdo -> not supported 1431 case kEplSdoTypePdo: 1432 default: 1433 { 1434 Ret = kEplSdoComUnsupportedProt; 1435 goto Exit; 1436 } 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; 1441 } 1442 // check events 1443 switch (SdoComConEvent_p) { 1444 // connection established 1445 case kEplSdoComConEventConEstablished: 1446 { 1447 //send first frame if needed 1448 if ((pSdoComCon->m_uiTransSize > 0) 1449 && (pSdoComCon->m_uiTargetIndex != 0)) { // start SDO transfer 1450 Ret = 1451 EplSdoComClientSend 1452 (pSdoComCon); 1453 if (Ret != kEplSuccessful) { 1454 goto Exit; 1455 } 1456 // check if segemted transfer 1457 if (pSdoComCon-> 1458 m_SdoTransType == 1459 kEplSdoTransSegmented) { 1460 pSdoComCon-> 1461 m_SdoComState = 1462 kEplSdoComStateClientSegmTrans; 1463 goto Exit; 1464 } 1465 } 1466 // goto state kEplSdoComStateClientConnected 1467 pSdoComCon->m_SdoComState = 1468 kEplSdoComStateClientConnected; 1469 goto Exit; 1470 } 1471 1472 case kEplSdoComConEventSendFirst: 1473 { 1474 // infos for transfer already saved by function EplSdoComInitTransferByIndex 1475 break; 1476 } 1477 1478 case kEplSdoComConEventConClosed: 1479 case kEplSdoComConEventInitError: 1480 case kEplSdoComConEventTimeout: 1481 { 1482 // close sequence layer handle 1483 Ret = 1484 EplSdoAsySeqDelCon(pSdoComCon-> 1485 m_SdoSeqConHdl); 1486 pSdoComCon->m_SdoSeqConHdl |= 1487 EPL_SDO_SEQ_INVALID_HDL; 1488 // call callback function 1489 if (SdoComConEvent_p == 1490 kEplSdoComConEventTimeout) { 1491 pSdoComCon->m_dwLastAbortCode = 1492 EPL_SDOAC_TIME_OUT; 1493 } else { 1494 pSdoComCon->m_dwLastAbortCode = 1495 0; 1496 } 1497 Ret = 1498 EplSdoComTransferFinished 1499 (SdoComCon_p, pSdoComCon, 1500 kEplSdoComTransferLowerLayerAbort); 1501 // d.k.: do not clean control structure 1502 break; 1503 } 1504 1505 default: 1506 // d.k. do nothing 1507 break; 1508 1509 } // end of switch(SdoComConEvent_p) 1510 break; 1511 } 1512 1513 // connected 1514 case kEplSdoComStateClientConnected: 1515 { 1516 // check events 1517 switch (SdoComConEvent_p) { 1518 // send a frame 1519 case kEplSdoComConEventSendFirst: 1520 case kEplSdoComConEventAckReceived: 1521 case kEplSdoComConEventFrameSended: 1522 { 1523 Ret = EplSdoComClientSend(pSdoComCon); 1524 if (Ret != kEplSuccessful) { 1525 goto Exit; 1526 } 1527 // check if read transfer finished 1528 if ((pSdoComCon->m_uiTransSize == 0) 1529 && (pSdoComCon-> 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 = 1537 0; 1538 Ret = 1539 EplSdoComTransferFinished 1540 (SdoComCon_p, pSdoComCon, 1541 kEplSdoComTransferFinished); 1542 1543 goto Exit; 1544 } 1545 // check if segemted transfer 1546 if (pSdoComCon->m_SdoTransType == 1547 kEplSdoTransSegmented) { 1548 pSdoComCon->m_SdoComState = 1549 kEplSdoComStateClientSegmTrans; 1550 goto Exit; 1551 } 1552 break; 1553 } 1554 1555 // frame received 1556 case kEplSdoComConEventRec: 1557 { 1558 // check if the frame is a SDO response and has the right transaction ID 1559 bFlag = 1560 AmiGetByteFromLe(&pAsySdoCom_p-> 1561 m_le_bFlags); 1562 if (((bFlag & 0x80) != 0) 1563 && 1564 (AmiGetByteFromLe 1565 (&pAsySdoCom_p-> 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 1571 Ret = 1572 EplSdoAsySeqSendData 1573 (pSdoComCon-> 1574 m_SdoSeqConHdl, 0, 1575 (tEplFrame *) 1576 NULL); 1577 // inc transaction id 1578 pSdoComCon-> 1579 m_bTransactionId++; 1580 // save abort code 1581 pSdoComCon-> 1582 m_dwLastAbortCode = 1583 AmiGetDwordFromLe 1584 (&pAsySdoCom_p-> 1585 m_le_abCommandData 1586 [0]); 1587 // call callback of application 1588 Ret = 1589 EplSdoComTransferFinished 1590 (SdoComCon_p, 1591 pSdoComCon, 1592 kEplSdoComTransferRxAborted); 1593 1594 goto Exit; 1595 } else { // normal frame received 1596 // check frame 1597 Ret = 1598 EplSdoComClientProcessFrame 1599 (SdoComCon_p, 1600 pAsySdoCom_p); 1601 1602 // check if transfer ready 1603 if (pSdoComCon-> 1604 m_uiTransSize == 1605 0) { 1606 // send acknowledge without any Command layer data 1607 Ret = 1608 EplSdoAsySeqSendData 1609 (pSdoComCon-> 1610 m_SdoSeqConHdl, 1611 0, 1612 (tEplFrame 1613 *) NULL); 1614 // inc transaction id 1615 pSdoComCon-> 1616 m_bTransactionId++; 1617 // call callback of application 1618 pSdoComCon-> 1619 m_dwLastAbortCode 1620 = 0; 1621 Ret = 1622 EplSdoComTransferFinished 1623 (SdoComCon_p, 1624 pSdoComCon, 1625 kEplSdoComTransferFinished); 1626 1627 goto Exit; 1628 } 1629 1630 } 1631 } else { // this command layer handle is not responsible 1632 // (wrong direction or wrong transaction ID) 1633 Ret = kEplSdoComNotResponsible; 1634 goto Exit; 1635 } 1636 break; 1637 } 1638 1639 // connection closed event go back to kEplSdoComStateClientWaitInit 1640 case kEplSdoComConEventConClosed: 1641 { // connection closed by communication partner 1642 // close sequence layer handle 1643 Ret = 1644 EplSdoAsySeqDelCon(pSdoComCon-> 1645 m_SdoSeqConHdl); 1646 // set handle to invalid and enter kEplSdoComStateClientWaitInit 1647 pSdoComCon->m_SdoSeqConHdl |= 1648 EPL_SDO_SEQ_INVALID_HDL; 1649 // change state 1650 pSdoComCon->m_SdoComState = 1651 kEplSdoComStateClientWaitInit; 1652 1653 // call callback of application 1654 pSdoComCon->m_dwLastAbortCode = 0; 1655 Ret = 1656 EplSdoComTransferFinished 1657 (SdoComCon_p, pSdoComCon, 1658 kEplSdoComTransferLowerLayerAbort); 1659 1660 goto Exit; 1661 1662 break; 1663 } 1664 1665 // abort to send from higher layer 1666 case kEplSdoComConEventAbort: 1667 { 1668 EplSdoComClientSendAbort(pSdoComCon, 1669 *((u32 *) 1670 pSdoComCon-> 1671 m_pData)); 1672 1673 // inc transaction id 1674 pSdoComCon->m_bTransactionId++; 1675 // call callback of application 1676 pSdoComCon->m_dwLastAbortCode = 1677 *((u32 *) pSdoComCon->m_pData); 1678 Ret = 1679 EplSdoComTransferFinished 1680 (SdoComCon_p, pSdoComCon, 1681 kEplSdoComTransferTxAborted); 1682 1683 break; 1684 } 1685 1686 case kEplSdoComConEventInitError: 1687 case kEplSdoComConEventTimeout: 1688 { 1689 // close sequence layer handle 1690 Ret = 1691 EplSdoAsySeqDelCon(pSdoComCon-> 1692 m_SdoSeqConHdl); 1693 pSdoComCon->m_SdoSeqConHdl |= 1694 EPL_SDO_SEQ_INVALID_HDL; 1695 // change state 1696 pSdoComCon->m_SdoComState = 1697 kEplSdoComStateClientWaitInit; 1698 // call callback of application 1699 pSdoComCon->m_dwLastAbortCode = 1700 EPL_SDOAC_TIME_OUT; 1701 Ret = 1702 EplSdoComTransferFinished 1703 (SdoComCon_p, pSdoComCon, 1704 kEplSdoComTransferLowerLayerAbort); 1705 1706 } 1707 1708 default: 1709 // d.k. do nothing 1710 break; 1711 1712 } // end of switch(SdoComConEvent_p) 1713 1714 break; 1715 } 1716 1717 // process segmented transfer 1718 case kEplSdoComStateClientSegmTrans: 1719 { 1720 // check events 1721 switch (SdoComConEvent_p) { 1722 // sned a frame 1723 case kEplSdoComConEventSendFirst: 1724 case kEplSdoComConEventAckReceived: 1725 case kEplSdoComConEventFrameSended: 1726 { 1727 Ret = EplSdoComClientSend(pSdoComCon); 1728 if (Ret != kEplSuccessful) { 1729 goto Exit; 1730 } 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++; 1737 // change state 1738 pSdoComCon->m_SdoComState = 1739 kEplSdoComStateClientConnected; 1740 // call callback of application 1741 pSdoComCon->m_dwLastAbortCode = 1742 0; 1743 Ret = 1744 EplSdoComTransferFinished 1745 (SdoComCon_p, pSdoComCon, 1746 kEplSdoComTransferFinished); 1747 1748 goto Exit; 1749 } 1750 1751 break; 1752 } 1753 1754 // frame received 1755 case kEplSdoComConEventRec: 1756 { 1757 // check if the frame is a response 1758 bFlag = 1759 AmiGetByteFromLe(&pAsySdoCom_p-> 1760 m_le_bFlags); 1761 if (((bFlag & 0x80) != 0) 1762 && 1763 (AmiGetByteFromLe 1764 (&pAsySdoCom_p-> 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 1770 Ret = 1771 EplSdoAsySeqSendData 1772 (pSdoComCon-> 1773 m_SdoSeqConHdl, 0, 1774 (tEplFrame *) 1775 NULL); 1776 // inc transaction id 1777 pSdoComCon-> 1778 m_bTransactionId++; 1779 // change state 1780 pSdoComCon-> 1781 m_SdoComState = 1782 kEplSdoComStateClientConnected; 1783 // save abort code 1784 pSdoComCon-> 1785 m_dwLastAbortCode = 1786 AmiGetDwordFromLe 1787 (&pAsySdoCom_p-> 1788 m_le_abCommandData 1789 [0]); 1790 // call callback of application 1791 Ret = 1792 EplSdoComTransferFinished 1793 (SdoComCon_p, 1794 pSdoComCon, 1795 kEplSdoComTransferRxAborted); 1796 1797 goto Exit; 1798 } else { // normal frame received 1799 // check frame 1800 Ret = 1801 EplSdoComClientProcessFrame 1802 (SdoComCon_p, 1803 pAsySdoCom_p); 1804 1805 // check if transfer ready 1806 if (pSdoComCon-> 1807 m_uiTransSize == 1808 0) { 1809 // send acknowledge without any Command layer data 1810 Ret = 1811 EplSdoAsySeqSendData 1812 (pSdoComCon-> 1813 m_SdoSeqConHdl, 1814 0, 1815 (tEplFrame 1816 *) NULL); 1817 // inc transaction id 1818 pSdoComCon-> 1819 m_bTransactionId++; 1820 // change state 1821 pSdoComCon-> 1822 m_SdoComState 1823 = 1824 kEplSdoComStateClientConnected; 1825 // call callback of application 1826 pSdoComCon-> 1827 m_dwLastAbortCode 1828 = 0; 1829 Ret = 1830 EplSdoComTransferFinished 1831 (SdoComCon_p, 1832 pSdoComCon, 1833 kEplSdoComTransferFinished); 1834 1835 } 1836 1837 } 1838 } 1839 break; 1840 } 1841 1842 // connection closed event go back to kEplSdoComStateClientWaitInit 1843 case kEplSdoComConEventConClosed: 1844 { // connection closed by communication partner 1845 // close sequence layer handle 1846 Ret = 1847 EplSdoAsySeqDelCon(pSdoComCon-> 1848 m_SdoSeqConHdl); 1849 // set handle to invalid and enter kEplSdoComStateClientWaitInit 1850 pSdoComCon->m_SdoSeqConHdl |= 1851 EPL_SDO_SEQ_INVALID_HDL; 1852 // change state 1853 pSdoComCon->m_SdoComState = 1854 kEplSdoComStateClientWaitInit; 1855 // inc transaction id 1856 pSdoComCon->m_bTransactionId++; 1857 // call callback of application 1858 pSdoComCon->m_dwLastAbortCode = 0; 1859 Ret = 1860 EplSdoComTransferFinished 1861 (SdoComCon_p, pSdoComCon, 1862 kEplSdoComTransferFinished); 1863 1864 break; 1865 } 1866 1867 // abort to send from higher layer 1868 case kEplSdoComConEventAbort: 1869 { 1870 EplSdoComClientSendAbort(pSdoComCon, 1871 *((u32 *) 1872 pSdoComCon-> 1873 m_pData)); 1874 1875 // inc transaction id 1876 pSdoComCon->m_bTransactionId++; 1877 // change state 1878 pSdoComCon->m_SdoComState = 1879 kEplSdoComStateClientConnected; 1880 // call callback of application 1881 pSdoComCon->m_dwLastAbortCode = 1882 *((u32 *) pSdoComCon->m_pData); 1883 Ret = 1884 EplSdoComTransferFinished 1885 (SdoComCon_p, pSdoComCon, 1886 kEplSdoComTransferTxAborted); 1887 1888 break; 1889 } 1890 1891 case kEplSdoComConEventInitError: 1892 case kEplSdoComConEventTimeout: 1893 { 1894 // close sequence layer handle 1895 Ret = 1896 EplSdoAsySeqDelCon(pSdoComCon-> 1897 m_SdoSeqConHdl); 1898 pSdoComCon->m_SdoSeqConHdl |= 1899 EPL_SDO_SEQ_INVALID_HDL; 1900 // change state 1901 pSdoComCon->m_SdoComState = 1902 kEplSdoComStateClientWaitInit; 1903 // call callback of application 1904 pSdoComCon->m_dwLastAbortCode = 1905 EPL_SDOAC_TIME_OUT; 1906 Ret = 1907 EplSdoComTransferFinished 1908 (SdoComCon_p, pSdoComCon, 1909 kEplSdoComTransferLowerLayerAbort); 1910 1911 } 1912 1913 default: 1914 // d.k. do nothing 1915 break; 1916 1917 } // end of switch(SdoComConEvent_p) 1918 1919 break; 1920 } 1921#endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 1922 1923 } // end of switch(pSdoComCon->m_SdoComState) 1924 1925#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 1926 Exit: 1927#endif 1928 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); 1934 1935#endif 1936 1937 return Ret; 1938 1939} 1940 1941//--------------------------------------------------------------------------- 1942// 1943// Function: EplSdoComServerInitReadByIndex 1944// 1945// Description: function start the processing of an read by index command 1946// 1947// 1948// 1949// Parameters: pSdoComCon_p = pointer to control structure of connection 1950// pAsySdoCom_p = pointer to received frame 1951// 1952// Returns: tEplKernel = errorcode 1953// 1954// 1955// State: 1956// 1957//--------------------------------------------------------------------------- 1958#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 1959static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p, 1960 tEplAsySdoCom * pAsySdoCom_p) 1961{ 1962 tEplKernel Ret; 1963 unsigned int uiIndex; 1964 unsigned int uiSubindex; 1965 tEplObdSize EntrySize; 1966 tEplObdAccess AccessType; 1967 u32 dwAbortCode; 1968 1969 dwAbortCode = 0; 1970 1971 // a init of a read could not be a segmented transfer 1972 // -> no variable part of header 1973 1974 // get index and subindex 1975 uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]); 1976 uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]); 1977 1978 // check accesstype of entry 1979 // existens of entry 1980//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) 1981 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType); 1982/*#else 1983 Ret = kEplObdSubindexNotExist; 1984 AccessType = 0; 1985#endif*/ 1986 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist 1987 dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST; 1988 // send abort 1989 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; 1990 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, 1991 uiIndex, 1992 uiSubindex, 1993 kEplSdoComSendTypeAbort); 1994 goto Exit; 1995 } else if (Ret != kEplSuccessful) { // entry doesn't exist 1996 dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST; 1997 // send abort 1998 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; 1999 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, 2000 uiIndex, 2001 uiSubindex, 2002 kEplSdoComSendTypeAbort); 2003 goto Exit; 2004 } 2005 // compare accesstype must be read or const 2006 if (((AccessType & kEplObdAccRead) == 0) 2007 && ((AccessType & kEplObdAccConst) == 0)) { 2008 2009 if ((AccessType & kEplObdAccWrite) != 0) { 2010 // entry read a write only object 2011 dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ; 2012 } else { 2013 dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS; 2014 } 2015 // send abort 2016 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; 2017 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, 2018 uiIndex, 2019 uiSubindex, 2020 kEplSdoComSendTypeAbort); 2021 goto Exit; 2022 } 2023 // save service 2024 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex; 2025 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); 2029/*#else 2030 EntrySize = 0; 2031#endif*/ 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); 2038//#endif 2039 } else { // expedited transfer 2040 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited; 2041 } 2042 2043 pSdoComCon_p->m_uiTransSize = EntrySize; 2044 pSdoComCon_p->m_uiTransferredByte = 0; 2045 2046 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, 2047 uiIndex, 2048 uiSubindex, kEplSdoComSendTypeRes); 2049 if (Ret != kEplSuccessful) { 2050 // error -> abort 2051 dwAbortCode = EPL_SDOAC_GENERAL_ERROR; 2052 // send abort 2053 pSdoComCon_p->m_pData = (u8 *) & dwAbortCode; 2054 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, 2055 uiIndex, 2056 uiSubindex, 2057 kEplSdoComSendTypeAbort); 2058 goto Exit; 2059 } 2060 2061 Exit: 2062 return Ret; 2063} 2064#endif 2065 2066//--------------------------------------------------------------------------- 2067// 2068// Function: EplSdoComServerSendFrameIntern(); 2069// 2070// Description: function creats and send a frame for server 2071// 2072// 2073// 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 2078// 2079// Returns: tEplKernel = errorcode 2080// 2081// 2082// State: 2083// 2084//--------------------------------------------------------------------------- 2085#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 2086static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p, 2087 unsigned int uiIndex_p, 2088 unsigned int uiSubIndex_p, 2089 tEplSdoComSendType SendType_p) 2090{ 2091 tEplKernel Ret; 2092 u8 abFrame[EPL_MAX_SDO_FRAME_SIZE]; 2093 tEplFrame *pFrame; 2094 tEplAsySdoCom *pCommandFrame; 2095 unsigned int uiSizeOfFrame; 2096 u8 bFlag; 2097 2098 Ret = kEplSuccessful; 2099 2100 pFrame = (tEplFrame *) & abFrame[0]; 2101 2102 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); 2103 2104 // build generic part of frame 2105 // get pointer to command layerpart of frame 2106 pCommandFrame = 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); 2113 2114 // set size to header size 2115 uiSizeOfFrame = 8; 2116 2117 // check SendType 2118 switch (SendType_p) { 2119 // requestframe to send 2120 case kEplSdoComSendTypeReq: 2121 { 2122 // nothing to do for server 2123 //-> error 2124 Ret = kEplSdoComInvalidSendType; 2125 break; 2126 } 2127 2128 // response without data to send 2129 case kEplSdoComSendTypeAckRes: 2130 { 2131 // set response flag 2132 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, 0x80); 2133 2134 // send frame 2135 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, 2136 uiSizeOfFrame, pFrame); 2137 2138 break; 2139 } 2140 2141 // responsframe to send 2142 case kEplSdoComSendTypeRes: 2143 { 2144 // set response flag 2145 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags); 2146 bFlag |= 0x80; 2147 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag); 2148 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, 2154 uiSubIndex_p, 2155 &pCommandFrame-> 2156 m_le_abCommandData 2157 [0], 2158 (tEplObdSize *) & 2159 pSdoComCon_p-> 2160 m_uiTransSize); 2161 if (Ret != kEplSuccessful) { 2162 goto Exit; 2163 } 2164//#endif 2165 2166 // set size of frame 2167 AmiSetWordToLe(&pCommandFrame-> 2168 m_le_wSegmentSize, 2169 (u16) pSdoComCon_p-> 2170 m_uiTransSize); 2171 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; 2177 2178 // send frame 2179 uiSizeOfFrame += pSdoComCon_p->m_uiTransSize; 2180 Ret = 2181 EplSdoAsySeqSendData(pSdoComCon_p-> 2182 m_SdoSeqConHdl, 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 2187 // set init flag 2188 bFlag = 2189 AmiGetByteFromLe(&pCommandFrame-> 2190 m_le_bFlags); 2191 bFlag |= 0x10; 2192 AmiSetByteToLe(&pCommandFrame-> 2193 m_le_bFlags, bFlag); 2194 // init variable header 2195 AmiSetDwordToLe(&pCommandFrame-> 2196 m_le_abCommandData[0], 2197 pSdoComCon_p-> 2198 m_uiTransSize); 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)); 2204 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); 2213 2214 // set segment size 2215 AmiSetWordToLe(&pCommandFrame-> 2216 m_le_wSegmentSize, 2217 (EPL_SDO_MAX_PAYLOAD - 2218 4)); 2219 2220 // send frame 2221 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD; 2222 Ret = 2223 EplSdoAsySeqSendData(pSdoComCon_p-> 2224 m_SdoSeqConHdl, 2225 uiSizeOfFrame, 2226 pFrame); 2227 2228 } else 2229 if ((pSdoComCon_p->m_uiTransferredByte > 0) 2230 && (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)) { // segment 2231 // set segment flag 2232 bFlag = 2233 AmiGetByteFromLe(&pCommandFrame-> 2234 m_le_bFlags); 2235 bFlag |= 0x20; 2236 AmiSetByteToLe(&pCommandFrame-> 2237 m_le_bFlags, bFlag); 2238 2239 // copy data in frame 2240 EPL_MEMCPY(&pCommandFrame-> 2241 m_le_abCommandData[0], 2242 pSdoComCon_p->m_pData, 2243 EPL_SDO_MAX_PAYLOAD); 2244 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; 2253 2254 // set segment size 2255 AmiSetWordToLe(&pCommandFrame-> 2256 m_le_wSegmentSize, 2257 EPL_SDO_MAX_PAYLOAD); 2258 2259 // send frame 2260 uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD; 2261 Ret = 2262 EplSdoAsySeqSendData(pSdoComCon_p-> 2263 m_SdoSeqConHdl, 2264 uiSizeOfFrame, 2265 pFrame); 2266 } else { 2267 if ((pSdoComCon_p->m_uiTransSize == 0) 2268 && (pSdoComCon_p-> 2269 m_SdoServiceType != 2270 kEplSdoServiceWriteByIndex)) { 2271 goto Exit; 2272 } 2273 // complete 2274 // set segment complete flag 2275 bFlag = 2276 AmiGetByteFromLe(&pCommandFrame-> 2277 m_le_bFlags); 2278 bFlag |= 0x30; 2279 AmiSetByteToLe(&pCommandFrame-> 2280 m_le_bFlags, bFlag); 2281 2282 // copy data in frame 2283 EPL_MEMCPY(&pCommandFrame-> 2284 m_le_abCommandData[0], 2285 pSdoComCon_p->m_pData, 2286 pSdoComCon_p->m_uiTransSize); 2287 2288 // correct byte-counter 2289 pSdoComCon_p->m_uiTransferredByte += 2290 pSdoComCon_p->m_uiTransSize; 2291 2292 // move data pointer 2293 pSdoComCon_p->m_pData += 2294 pSdoComCon_p->m_uiTransSize; 2295 2296 // set segment size 2297 AmiSetWordToLe(&pCommandFrame-> 2298 m_le_wSegmentSize, 2299 (u16) pSdoComCon_p-> 2300 m_uiTransSize); 2301 2302 // send frame 2303 uiSizeOfFrame += 2304 pSdoComCon_p->m_uiTransSize; 2305 pSdoComCon_p->m_uiTransSize = 0; 2306 Ret = 2307 EplSdoAsySeqSendData(pSdoComCon_p-> 2308 m_SdoSeqConHdl, 2309 uiSizeOfFrame, 2310 pFrame); 2311 } 2312 2313 } 2314 break; 2315 } 2316 // abort to send 2317 case kEplSdoComSendTypeAbort: 2318 { 2319 // set response and abort flag 2320 bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags); 2321 bFlag |= 0xC0; 2322 AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag); 2323 2324 // copy abortcode to frame 2325 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], 2326 *((u32 *) pSdoComCon_p->m_pData)); 2327 2328 // set size of segment 2329 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, 2330 sizeof(u32)); 2331 2332 // update counter 2333 pSdoComCon_p->m_uiTransferredByte = sizeof(u32); 2334 pSdoComCon_p->m_uiTransSize = 0; 2335 2336 // calc framesize 2337 uiSizeOfFrame += sizeof(u32); 2338 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, 2339 uiSizeOfFrame, pFrame); 2340 break; 2341 } 2342 } // end of switch(SendType_p) 2343 2344 Exit: 2345 return Ret; 2346} 2347#endif 2348//--------------------------------------------------------------------------- 2349// 2350// Function: EplSdoComServerInitWriteByIndex 2351// 2352// Description: function start the processing of an write by index command 2353// 2354// 2355// 2356// Parameters: pSdoComCon_p = pointer to control structure of connection 2357// pAsySdoCom_p = pointer to received frame 2358// 2359// Returns: tEplKernel = errorcode 2360// 2361// 2362// State: 2363// 2364//--------------------------------------------------------------------------- 2365#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) 2366static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p, 2367 tEplAsySdoCom * pAsySdoCom_p) 2368{ 2369 tEplKernel Ret = kEplSuccessful; 2370 unsigned int uiIndex; 2371 unsigned int uiSubindex; 2372 unsigned int uiBytesToTransfer; 2373 tEplObdSize EntrySize; 2374 tEplObdAccess AccessType; 2375 u32 dwAbortCode; 2376 u8 *pbSrcData; 2377 2378 dwAbortCode = 0; 2379 2380 // a init of a write 2381 // -> variable part of header possible 2382 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 2387 uiIndex = 2388 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]); 2389 uiSubindex = 2390 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]); 2391 // get source-pointer for copy 2392 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8]; 2393 // save size 2394 pSdoComCon_p->m_uiTransSize = 2395 AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]); 2396 2397 } else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00) { // expedited transfer 2398 pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited; 2399 // get index and subindex 2400 uiIndex = 2401 AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]); 2402 uiSubindex = 2403 AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]); 2404 // get source-pointer for copy 2405 pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4]; 2406 // save size 2407 pSdoComCon_p->m_uiTransSize = 2408 AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize); 2409 // subtract header 2410 pSdoComCon_p->m_uiTransSize -= 4; 2411 2412 } else { 2413 // just ignore any other transfer type 2414 goto Exit; 2415 } 2416 2417 // check accesstype of entry 2418 // existens of entry 2419//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) 2420 Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType); 2421/*#else 2422 Ret = kEplObdSubindexNotExist; 2423 AccessType = 0; 2424#endif*/ 2425 if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist 2426 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST; 2427 // send abort 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, 2431 uiIndex, 2432 uiSubindex, 2433 kEplSdoComSendTypeAbort); */ 2434 goto Abort; 2435 } else if (Ret != kEplSuccessful) { // entry doesn't exist 2436 pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST; 2437 // send abort 2438 // d.k. This is wrong: k.t. not needed send abort on end of write 2439 /* 2440 pSdoComCon_p->m_pData = (u8*)&dwAbortCode; 2441 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, 2442 uiIndex, 2443 uiSubindex, 2444 kEplSdoComSendTypeAbort); */ 2445 goto Abort; 2446 } 2447 // compare accesstype must be read 2448 if ((AccessType & kEplObdAccWrite) == 0) { 2449 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; 2454 } else { 2455 pSdoComCon_p->m_dwLastAbortCode = 2456 EPL_SDOAC_UNSUPPORTED_ACCESS; 2457 } 2458 // send abort 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, 2462 uiIndex, 2463 uiSubindex, 2464 kEplSdoComSendTypeAbort); */ 2465 goto Abort; 2466 } 2467 // save service 2468 pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex; 2469 2470 pSdoComCon_p->m_uiTransferredByte = 0; 2471 2472 // write data to OD 2473 if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) { // expedited transfer 2474 // size checking is done by EplObduWriteEntryFromLe() 2475 2476//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) 2477 Ret = EplObduWriteEntryFromLe(uiIndex, 2478 uiSubindex, 2479 pbSrcData, 2480 pSdoComCon_p->m_uiTransSize); 2481 switch (Ret) { 2482 case kEplSuccessful: 2483 { 2484 break; 2485 } 2486 2487 case kEplObdAccessViolation: 2488 { 2489 pSdoComCon_p->m_dwLastAbortCode = 2490 EPL_SDOAC_UNSUPPORTED_ACCESS; 2491 // send abort 2492 goto Abort; 2493 } 2494 2495 case kEplObdValueLengthError: 2496 { 2497 pSdoComCon_p->m_dwLastAbortCode = 2498 EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH; 2499 // send abort 2500 goto Abort; 2501 } 2502 2503 case kEplObdValueTooHigh: 2504 { 2505 pSdoComCon_p->m_dwLastAbortCode = 2506 EPL_SDOAC_VALUE_RANGE_TOO_HIGH; 2507 // send abort 2508 goto Abort; 2509 } 2510 2511 case kEplObdValueTooLow: 2512 { 2513 pSdoComCon_p->m_dwLastAbortCode = 2514 EPL_SDOAC_VALUE_RANGE_TOO_LOW; 2515 // send abort 2516 goto Abort; 2517 } 2518 2519 default: 2520 { 2521 pSdoComCon_p->m_dwLastAbortCode = 2522 EPL_SDOAC_GENERAL_ERROR; 2523 // send abort 2524 goto Abort; 2525 } 2526 } 2527//#endif 2528 // send command acknowledge 2529 Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p, 2530 0, 2531 0, 2532 kEplSdoComSendTypeAckRes); 2533 2534 pSdoComCon_p->m_uiTransSize = 0; 2535 goto Exit; 2536 } else { 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 2540 2541 //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) 2542 EntrySize = EplObduGetDataSize(uiIndex, uiSubindex); 2543 /*#else 2544 EntrySize = 0; 2545 #endif */ 2546 if (EntrySize < pSdoComCon_p->m_uiTransSize) { // parameter too big 2547 pSdoComCon_p->m_dwLastAbortCode = 2548 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH; 2549 // send abort 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, 2553 uiIndex, 2554 uiSubindex, 2555 kEplSdoComSendTypeAbort); */ 2556 goto Abort; 2557 } 2558 2559 uiBytesToTransfer = 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, 2566 uiSubindex); 2567//#endif 2568 if (pSdoComCon_p->m_pData == NULL) { 2569 pSdoComCon_p->m_dwLastAbortCode = 2570 EPL_SDOAC_GENERAL_ERROR; 2571 // send abort 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, 2575 uiIndex, 2576 uiSubindex, 2577 kEplSdoComSendTypeAbort);*/ 2578 goto Abort; 2579 } 2580 // copy data 2581 EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer); 2582 2583 // update internal counter 2584 pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer; 2585 pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer; 2586 2587 // update target pointer 2588 ( /*(u8*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer; 2589 2590 // send acknowledge without any Command layer data 2591 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, 2592 0, (tEplFrame *) NULL); 2593 goto Exit; 2594 } 2595 2596 Abort: 2597 if (pSdoComCon_p->m_dwLastAbortCode != 0) { 2598 // send abort 2599 pSdoComCon_p->m_pData = 2600 (u8 *) & pSdoComCon_p->m_dwLastAbortCode; 2601 Ret = 2602 EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex, 2603 uiSubindex, 2604 kEplSdoComSendTypeAbort); 2605 2606 // reset abort code 2607 pSdoComCon_p->m_dwLastAbortCode = 0; 2608 pSdoComCon_p->m_uiTransSize = 0; 2609 goto Exit; 2610 } 2611 2612 Exit: 2613 return Ret; 2614} 2615#endif 2616 2617//--------------------------------------------------------------------------- 2618// 2619// Function: EplSdoComClientSend 2620// 2621// Description: function starts an sdo transfer an send all further frames 2622// 2623// 2624// 2625// Parameters: pSdoComCon_p = pointer to control structure of connection 2626// 2627// Returns: tEplKernel = errorcode 2628// 2629// 2630// State: 2631// 2632//--------------------------------------------------------------------------- 2633#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 2634static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p) 2635{ 2636 tEplKernel Ret; 2637 u8 abFrame[EPL_MAX_SDO_FRAME_SIZE]; 2638 tEplFrame *pFrame; 2639 tEplAsySdoCom *pCommandFrame; 2640 unsigned int uiSizeOfFrame; 2641 u8 bFlags; 2642 u8 *pbPayload; 2643 2644 Ret = kEplSuccessful; 2645 2646 pFrame = (tEplFrame *) & abFrame[0]; 2647 2648 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); 2649 2650 // build generic part of frame 2651 // get pointer to command layerpart of frame 2652 pCommandFrame = 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); 2659 2660 // set size constant part of header 2661 uiSizeOfFrame = 8; 2662 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; 2673 pbPayload = 2674 &pCommandFrame-> 2675 m_le_abCommandData[0]; 2676 // fill rest of header 2677 AmiSetWordToLe(&pCommandFrame-> 2678 m_le_wSegmentSize, 4); 2679 2680 // create command header 2681 AmiSetWordToLe(pbPayload, 2682 (u16) pSdoComCon_p-> 2683 m_uiTargetIndex); 2684 pbPayload += 2; 2685 AmiSetByteToLe(pbPayload, 2686 (u8) pSdoComCon_p-> 2687 m_uiTargetSubIndex); 2688 // calc size 2689 uiSizeOfFrame += 4; 2690 2691 // set pSdoComCon_p->m_uiTransferredByte to one 2692 pSdoComCon_p->m_uiTransferredByte = 1; 2693 break; 2694 } 2695 2696 case kEplSdoServiceWriteByIndex: 2697 { 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-> 2705 m_le_abCommandData 2706 [0], 2707 pSdoComCon_p-> 2708 m_uiTransSize); 2709 // set pointer to real payload 2710 pbPayload = 2711 &pCommandFrame-> 2712 m_le_abCommandData[4]; 2713 // fill rest of header 2714 AmiSetWordToLe(&pCommandFrame-> 2715 m_le_wSegmentSize, 2716 EPL_SDO_MAX_PAYLOAD); 2717 bFlags = 0x10; 2718 AmiSetByteToLe(&pCommandFrame-> 2719 m_le_bFlags, 2720 bFlags); 2721 // create command header 2722 AmiSetWordToLe(pbPayload, 2723 (u16) 2724 pSdoComCon_p-> 2725 m_uiTargetIndex); 2726 pbPayload += 2; 2727 AmiSetByteToLe(pbPayload, 2728 (u8) 2729 pSdoComCon_p-> 2730 m_uiTargetSubIndex); 2731 // on byte for reserved 2732 pbPayload += 2; 2733 // calc size 2734 uiSizeOfFrame += 2735 EPL_SDO_MAX_PAYLOAD; 2736 2737 // copy payload 2738 EPL_MEMCPY(pbPayload, 2739 pSdoComCon_p-> 2740 m_pData, 2741 (EPL_SDO_MAX_PAYLOAD 2742 - 8)); 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); 2748 pSdoComCon_p-> 2749 m_uiTransferredByte = 2750 (EPL_SDO_MAX_PAYLOAD - 8); 2751 2752 } else { // expedited trandsfer 2753 // save that transfer is expedited 2754 pSdoComCon_p->m_SdoTransType = 2755 kEplSdoTransExpedited; 2756 pbPayload = 2757 &pCommandFrame-> 2758 m_le_abCommandData[0]; 2759 2760 // create command header 2761 AmiSetWordToLe(pbPayload, 2762 (u16) 2763 pSdoComCon_p-> 2764 m_uiTargetIndex); 2765 pbPayload += 2; 2766 AmiSetByteToLe(pbPayload, 2767 (u8) 2768 pSdoComCon_p-> 2769 m_uiTargetSubIndex); 2770 // + 2 -> one byte for subindex and one byte reserved 2771 pbPayload += 2; 2772 // copy data 2773 EPL_MEMCPY(pbPayload, 2774 pSdoComCon_p-> 2775 m_pData, 2776 pSdoComCon_p-> 2777 m_uiTransSize); 2778 // calc size 2779 uiSizeOfFrame += 2780 (4 + 2781 pSdoComCon_p-> 2782 m_uiTransSize); 2783 // fill rest of header 2784 AmiSetWordToLe(&pCommandFrame-> 2785 m_le_wSegmentSize, 2786 (u16) (4 + 2787 pSdoComCon_p-> 2788 m_uiTransSize)); 2789 2790 pSdoComCon_p-> 2791 m_uiTransferredByte = 2792 pSdoComCon_p->m_uiTransSize; 2793 pSdoComCon_p->m_uiTransSize = 0; 2794 } 2795 break; 2796 } 2797 2798 case kEplSdoServiceNIL: 2799 default: 2800 // invalid service requested 2801 Ret = kEplSdoComInvalidServiceType; 2802 goto Exit; 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 2809 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 2815 pbPayload = 2816 &pCommandFrame-> 2817 m_le_abCommandData 2818 [0]; 2819 // fill rest of header 2820 AmiSetWordToLe 2821 (&pCommandFrame-> 2822 m_le_wSegmentSize, 2823 EPL_SDO_MAX_PAYLOAD); 2824 bFlags = 0x20; 2825 AmiSetByteToLe 2826 (&pCommandFrame-> 2827 m_le_bFlags, 2828 bFlags); 2829 // copy data 2830 EPL_MEMCPY(pbPayload, 2831 pSdoComCon_p-> 2832 m_pData, 2833 EPL_SDO_MAX_PAYLOAD); 2834 pSdoComCon_p->m_pData += 2835 EPL_SDO_MAX_PAYLOAD; 2836 // correct intern counter 2837 pSdoComCon_p-> 2838 m_uiTransSize -= 2839 EPL_SDO_MAX_PAYLOAD; 2840 pSdoComCon_p-> 2841 m_uiTransferredByte 2842 = 2843 EPL_SDO_MAX_PAYLOAD; 2844 // calc size 2845 uiSizeOfFrame += 2846 EPL_SDO_MAX_PAYLOAD; 2847 2848 } else { // end of transfer 2849 pbPayload = 2850 &pCommandFrame-> 2851 m_le_abCommandData 2852 [0]; 2853 // fill rest of header 2854 AmiSetWordToLe 2855 (&pCommandFrame-> 2856 m_le_wSegmentSize, 2857 (u16) 2858 pSdoComCon_p-> 2859 m_uiTransSize); 2860 bFlags = 0x30; 2861 AmiSetByteToLe 2862 (&pCommandFrame-> 2863 m_le_bFlags, 2864 bFlags); 2865 // copy data 2866 EPL_MEMCPY(pbPayload, 2867 pSdoComCon_p-> 2868 m_pData, 2869 pSdoComCon_p-> 2870 m_uiTransSize); 2871 pSdoComCon_p->m_pData += 2872 pSdoComCon_p-> 2873 m_uiTransSize; 2874 // calc size 2875 uiSizeOfFrame += 2876 pSdoComCon_p-> 2877 m_uiTransSize; 2878 // correct intern counter 2879 pSdoComCon_p-> 2880 m_uiTransSize = 0; 2881 pSdoComCon_p-> 2882 m_uiTransferredByte 2883 = 2884 pSdoComCon_p-> 2885 m_uiTransSize; 2886 2887 } 2888 } else { 2889 goto Exit; 2890 } 2891 break; 2892 } 2893 default: 2894 { 2895 goto Exit; 2896 } 2897 } // end of switch(pSdoComCon_p->m_SdoServiceType) 2898 } 2899 } else { 2900 goto Exit; 2901 } 2902 2903 // call send function of lower layer 2904 switch (pSdoComCon_p->m_SdoProtType) { 2905 case kEplSdoTypeAsnd: 2906 case kEplSdoTypeUdp: 2907 { 2908 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, 2909 uiSizeOfFrame, pFrame); 2910 break; 2911 } 2912 2913 default: 2914 { 2915 Ret = kEplSdoComUnsupportedProt; 2916 } 2917 } // end of switch(pSdoComCon_p->m_SdoProtType) 2918 2919 Exit: 2920 return Ret; 2921 2922} 2923#endif 2924//--------------------------------------------------------------------------- 2925// 2926// Function: EplSdoComClientProcessFrame 2927// 2928// Description: function process a received frame 2929// 2930// 2931// 2932// Parameters: SdoComCon_p = connection handle 2933// pAsySdoCom_p = pointer to frame to process 2934// 2935// Returns: tEplKernel = errorcode 2936// 2937// 2938// State: 2939// 2940//--------------------------------------------------------------------------- 2941#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 2942static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p, 2943 tEplAsySdoCom * pAsySdoCom_p) 2944{ 2945 tEplKernel Ret; 2946 u8 bBuffer; 2947 unsigned int uiBuffer; 2948 unsigned int uiDataSize; 2949 unsigned long ulBuffer; 2950 tEplSdoComCon *pSdoComCon; 2951 2952 Ret = kEplSuccessful; 2953 2954 // get pointer to control structure 2955 pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p]; 2956 2957 // check if transaction Id fit 2958 bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId); 2959 if (pSdoComCon->m_bTransactionId != bBuffer) { 2960 // incorrect transaction id 2961 2962 // if running transfer 2963 if ((pSdoComCon->m_uiTransferredByte != 0) 2964 && (pSdoComCon->m_uiTransSize != 0)) { 2965 pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR; 2966 // -> send abort 2967 EplSdoComClientSendAbort(pSdoComCon, 2968 pSdoComCon->m_dwLastAbortCode); 2969 // call callback of application 2970 Ret = 2971 EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, 2972 kEplSdoComTransferTxAborted); 2973 } 2974 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; 2984 // -> send abort 2985 EplSdoComClientSendAbort(pSdoComCon, 2986 pSdoComCon-> 2987 m_dwLastAbortCode); 2988 // call callback of application 2989 Ret = 2990 EplSdoComTransferFinished(SdoComCon_p, 2991 pSdoComCon, 2992 kEplSdoComTransferTxAborted); 2993 } 2994 2995 } else { // switch on command 2996 switch (pSdoComCon->m_SdoServiceType) { 2997 case kEplSdoServiceWriteByIndex: 2998 { // check if confirmation from server 2999 // nothing more to do 3000 break; 3001 } 3002 3003 case kEplSdoServiceReadByIndex: 3004 { // check if it is an segmented or an expedited transfer 3005 bBuffer = 3006 AmiGetByteFromLe(&pAsySdoCom_p-> 3007 m_le_bFlags); 3008 // mask uninteressting bits 3009 bBuffer &= 0x30; 3010 switch (bBuffer) { 3011 // expedited transfer 3012 case 0x00: 3013 { 3014 // check size of buffer 3015 uiBuffer = 3016 AmiGetWordFromLe 3017 (&pAsySdoCom_p-> 3018 m_le_wSegmentSize); 3019 if (uiBuffer > pSdoComCon->m_uiTransSize) { // buffer provided by the application is to small 3020 // copy only a part 3021 uiDataSize = 3022 pSdoComCon-> 3023 m_uiTransSize; 3024 } else { // buffer fits 3025 uiDataSize = 3026 uiBuffer; 3027 } 3028 3029 // copy data 3030 EPL_MEMCPY(pSdoComCon-> 3031 m_pData, 3032 &pAsySdoCom_p-> 3033 m_le_abCommandData 3034 [0], 3035 uiDataSize); 3036 3037 // correct counter 3038 pSdoComCon-> 3039 m_uiTransSize = 0; 3040 pSdoComCon-> 3041 m_uiTransferredByte 3042 = uiDataSize; 3043 break; 3044 } 3045 3046 // start of a segmented transfer 3047 case 0x10: 3048 { // get total size of transfer 3049 ulBuffer = 3050 AmiGetDwordFromLe 3051 (&pAsySdoCom_p-> 3052 m_le_abCommandData 3053 [0]); 3054 if (ulBuffer <= pSdoComCon->m_uiTransSize) { // buffer fit 3055 pSdoComCon-> 3056 m_uiTransSize 3057 = 3058 (unsigned 3059 int) 3060 ulBuffer; 3061 } else { // buffer to small 3062 // send abort 3063 pSdoComCon-> 3064 m_dwLastAbortCode 3065 = 3066 EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH; 3067 // -> send abort 3068 EplSdoComClientSendAbort 3069 (pSdoComCon, 3070 pSdoComCon-> 3071 m_dwLastAbortCode); 3072 // call callback of application 3073 Ret = 3074 EplSdoComTransferFinished 3075 (SdoComCon_p, 3076 pSdoComCon, 3077 kEplSdoComTransferRxAborted); 3078 goto Exit; 3079 } 3080 3081 // get segment size 3082 // check size of buffer 3083 uiBuffer = 3084 AmiGetWordFromLe 3085 (&pAsySdoCom_p-> 3086 m_le_wSegmentSize); 3087 // subtract size of vaiable header from datasize 3088 uiBuffer -= 4; 3089 // copy data 3090 EPL_MEMCPY(pSdoComCon-> 3091 m_pData, 3092 &pAsySdoCom_p-> 3093 m_le_abCommandData 3094 [4], 3095 uiBuffer); 3096 3097 // correct counter an pointer 3098 pSdoComCon->m_pData += 3099 uiBuffer; 3100 pSdoComCon-> 3101 m_uiTransferredByte 3102 += uiBuffer; 3103 pSdoComCon-> 3104 m_uiTransSize -= 3105 uiBuffer; 3106 3107 break; 3108 } 3109 3110 // segment 3111 case 0x20: 3112 { 3113 // get segment size 3114 // check size of buffer 3115 uiBuffer = 3116 AmiGetWordFromLe 3117 (&pAsySdoCom_p-> 3118 m_le_wSegmentSize); 3119 // check if data to copy fit to buffer 3120 if (uiBuffer >= pSdoComCon->m_uiTransSize) { // to much data 3121 uiBuffer = 3122 (pSdoComCon-> 3123 m_uiTransSize 3124 - 1); 3125 } 3126 // copy data 3127 EPL_MEMCPY(pSdoComCon-> 3128 m_pData, 3129 &pAsySdoCom_p-> 3130 m_le_abCommandData 3131 [0], 3132 uiBuffer); 3133 3134 // correct counter an pointer 3135 pSdoComCon->m_pData += 3136 uiBuffer; 3137 pSdoComCon-> 3138 m_uiTransferredByte 3139 += uiBuffer; 3140 pSdoComCon-> 3141 m_uiTransSize -= 3142 uiBuffer; 3143 break; 3144 } 3145 3146 // last segment 3147 case 0x30: 3148 { 3149 // get segment size 3150 // check size of buffer 3151 uiBuffer = 3152 AmiGetWordFromLe 3153 (&pAsySdoCom_p-> 3154 m_le_wSegmentSize); 3155 // check if data to copy fit to buffer 3156 if (uiBuffer > pSdoComCon->m_uiTransSize) { // to much data 3157 uiBuffer = 3158 (pSdoComCon-> 3159 m_uiTransSize 3160 - 1); 3161 } 3162 // copy data 3163 EPL_MEMCPY(pSdoComCon-> 3164 m_pData, 3165 &pAsySdoCom_p-> 3166 m_le_abCommandData 3167 [0], 3168 uiBuffer); 3169 3170 // correct counter an pointer 3171 pSdoComCon->m_pData += 3172 uiBuffer; 3173 pSdoComCon-> 3174 m_uiTransferredByte 3175 += uiBuffer; 3176 pSdoComCon-> 3177 m_uiTransSize = 0; 3178 3179 break; 3180 } 3181 } // end of switch(bBuffer & 0x30) 3182 3183 break; 3184 } 3185 3186 case kEplSdoServiceNIL: 3187 default: 3188 // invalid service requested 3189 // $$$ d.k. What should we do? 3190 break; 3191 } // end of switch(pSdoComCon->m_SdoServiceType) 3192 } 3193 } 3194 3195 Exit: 3196 return Ret; 3197} 3198#endif 3199 3200//--------------------------------------------------------------------------- 3201// 3202// Function: EplSdoComClientSendAbort 3203// 3204// Description: function send a abort message 3205// 3206// 3207// 3208// Parameters: pSdoComCon_p = pointer to control structure of connection 3209// dwAbortCode_p = Sdo abort code 3210// 3211// Returns: tEplKernel = errorcode 3212// 3213// 3214// State: 3215// 3216//--------------------------------------------------------------------------- 3217#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) 3218static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p, 3219 u32 dwAbortCode_p) 3220{ 3221 tEplKernel Ret; 3222 u8 abFrame[EPL_MAX_SDO_FRAME_SIZE]; 3223 tEplFrame *pFrame; 3224 tEplAsySdoCom *pCommandFrame; 3225 unsigned int uiSizeOfFrame; 3226 3227 Ret = kEplSuccessful; 3228 3229 pFrame = (tEplFrame *) & abFrame[0]; 3230 3231 EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame)); 3232 3233 // build generic part of frame 3234 // get pointer to command layerpart of frame 3235 pCommandFrame = 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); 3242 3243 uiSizeOfFrame = 8; 3244 3245 // set response and abort flag 3246 pCommandFrame->m_le_bFlags |= 0x40; 3247 3248 // copy abortcode to frame 3249 AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p); 3250 3251 // set size of segment 3252 AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(u32)); 3253 3254 // update counter 3255 pSdoComCon_p->m_uiTransferredByte = sizeof(u32); 3256 pSdoComCon_p->m_uiTransSize = 0; 3257 3258 // calc framesize 3259 uiSizeOfFrame += sizeof(u32); 3260 3261 // save abort code 3262 pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p; 3263 3264 // call send function of lower layer 3265 switch (pSdoComCon_p->m_SdoProtType) { 3266 case kEplSdoTypeAsnd: 3267 case kEplSdoTypeUdp: 3268 { 3269 Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl, 3270 uiSizeOfFrame, pFrame); 3271 break; 3272 } 3273 3274 default: 3275 { 3276 Ret = kEplSdoComUnsupportedProt; 3277 } 3278 } // end of switch(pSdoComCon_p->m_SdoProtType) 3279 3280 return Ret; 3281} 3282#endif 3283 3284//--------------------------------------------------------------------------- 3285// 3286// Function: EplSdoComTransferFinished 3287// 3288// Description: calls callback function of application if available 3289// and clears entry in control structure 3290// 3291// Parameters: pSdoComCon_p = pointer to control structure of connection 3292// SdoComConState_p = state of SDO transfer 3293// 3294// Returns: tEplKernel = errorcode 3295// 3296// 3297// State: 3298// 3299//--------------------------------------------------------------------------- 3300static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p, 3301 tEplSdoComCon * pSdoComCon_p, 3302 tEplSdoComConState SdoComConState_p) 3303{ 3304 tEplKernel Ret; 3305 3306 Ret = kEplSuccessful; 3307 3308 if (pSdoComCon_p->m_pfnTransferFinished != NULL) { 3309 tEplSdoFinishedCb pfnTransferFinished; 3310 tEplSdoComFinished SdoComFinished; 3311 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; 3325 } else { 3326 SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead; 3327 } 3328 3329 // reset transfer state so this handle is not busy anymore 3330 pSdoComCon_p->m_uiTransferredByte = 0; 3331 pSdoComCon_p->m_uiTransSize = 0; 3332 3333 pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished; 3334 // delete function pointer to inform application only once for each transfer 3335 pSdoComCon_p->m_pfnTransferFinished = NULL; 3336 3337 // call application's callback function 3338 pfnTransferFinished(&SdoComFinished); 3339 3340 } 3341 3342 return Ret; 3343} 3344 3345// EOF