EtherCAT slave that reads 3 Xsens IMU's connected to a Xbus Master
Dependencies: MODSERIAL mbed KL25Z_ClockControl
Fork of EtherCAT by
esc.cpp
00001 /* 00002 * SOES Simple Open EtherCAT Slave 00003 * 00004 * File : esc.c 00005 * Version : 1.0.0 00006 * Date : 11-07-2010 00007 * Copyright (C) 2007-2010 Arthur Ketels 00008 * 00009 * SOES is free software; you can redistribute it and/or modify it under 00010 * the terms of the GNU General Public License version 2 as published by the Free 00011 * Software Foundation. 00012 * 00013 * SOES is distributed in the hope that it will be useful, but WITHOUT ANY 00014 * WARRANTY; without even the implied warranty of MERCHANTABILITY or 00015 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00016 * for more details. 00017 * 00018 * As a special exception, if other files instantiate templates or use macros 00019 * or inline functions from this file, or you compile this file and link it 00020 * with other works to produce a work based on this file, this file does not 00021 * by itself cause the resulting work to be covered by the GNU General Public 00022 * License. However the source code for this file must still be made available 00023 * in accordance with section (3) of the GNU General Public License. 00024 * 00025 * This exception does not invalidate any other reasons why a work based on 00026 * this file might be covered by the GNU General Public License. 00027 * 00028 * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 00029 * property of, and protected by Beckhoff Automation GmbH. 00030 */ 00031 //#include <stdio.h> 00032 00033 #ifdef TARGET_ATMEL 00034 #include <avr/io.h> 00035 #include <avr/pgmspace.h> 00036 #else 00037 #define PROGMEM 00038 #define pgm_read_dword(x) *(x) 00039 #define pgm_read_word(x) *(x) 00040 #define pgm_read_byte(x) *(x) 00041 00042 #endif 00043 00044 #include <string.h> 00045 #include "utypes.h" 00046 #include "esc.h" 00047 #include "objectlist.h" 00048 00049 #define BITS2BYTES(b) ((b + 7) >> 3) 00050 00051 uint16 SDO_findobject(uint16 index) 00052 { 00053 int16 n = 0; 00054 while (pgm_read_word(&SDOobjects[n].index) < index) 00055 { 00056 n++; 00057 } 00058 if (pgm_read_word(&SDOobjects[n].index) != index) 00059 { 00060 return -1; 00061 } 00062 return n; 00063 } 00064 00065 uint16 sizeTXPDO(void) 00066 { 00067 uint8 c , l, si, sic; 00068 uint16 size = 0; 00069 int16 nidx; 00070 _objd FLASHSTORE *objd; 00071 00072 if (pgm_read_word(&SDO1C13[0].data)) 00073 si = *((uint8 *)pgm_read_word(&SDO1C13[0].data)); 00074 else 00075 si = pgm_read_byte(&SDO1C13[0].value); 00076 if (si) 00077 { 00078 for (sic = 1 ; sic <= si ; sic++) 00079 { 00080 nidx = SDO_findobject(pgm_read_word(&SDO1C13[sic].value)); 00081 if (nidx > 0) 00082 { 00083 objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); 00084 l = pgm_read_byte(&objd->value); 00085 for (c = 1 ; c <= l ; c++) 00086 size += (pgm_read_dword(&(objd + c)->value) & 0xff); 00087 } 00088 } 00089 } 00090 return BITS2BYTES(size); 00091 } 00092 00093 uint16 sizeRXPDO(void) 00094 { 00095 uint8 c , l, si, sic; 00096 uint16 size = 0; 00097 int16 nidx; 00098 _objd FLASHSTORE *objd; 00099 00100 if (pgm_read_word(&SDO1C12[0].data)) 00101 si = *((uint8 *)pgm_read_word(&SDO1C12[0].data)); 00102 else 00103 si = pgm_read_byte(&SDO1C12[0].value); 00104 if (si) 00105 { 00106 for (sic = 1 ; sic <= si ; sic++) 00107 { 00108 nidx = SDO_findobject(pgm_read_word(&SDO1C12[sic].value)); 00109 if (nidx > 0) 00110 { 00111 objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); 00112 l = pgm_read_byte(&objd->value); 00113 for (c = 1 ; c <= l ; c++) 00114 size += (pgm_read_dword(&(objd + c)->value) & 0xff); 00115 } 00116 } 00117 } 00118 return BITS2BYTES(size); 00119 } 00120 00121 void ESC_ALerror(uint16 errornumber) 00122 { 00123 uint16 dummy; 00124 ESCvar.ALerror = errornumber; 00125 dummy = htoes(errornumber); 00126 ESC_write(ESCREG_ALERROR, &dummy, sizeof(dummy), &ESCvar.ALevent); 00127 } 00128 00129 void ESC_ALstatus(uint8 status) 00130 { 00131 uint16 dummy; 00132 ESCvar.ALstatus = status; 00133 dummy = htoes((uint16)status); 00134 ESC_write(ESCREG_ALSTATUS, &dummy, sizeof(dummy), &ESCvar.ALevent); 00135 } 00136 00137 void ESC_SMack(uint8 n) 00138 { 00139 uint16 dummy; 00140 ESC_read(ESCREG_SM0STATUS + (n << 3), &dummy, 2, &ESCvar.ALevent); 00141 } 00142 00143 void ESC_SMstatus(uint8 n) 00144 { 00145 _ESCsm2 *sm; 00146 uint16 temp; 00147 sm = (_ESCsm2 *)&ESCvar.SM[n]; 00148 ESC_read(ESCREG_SM0STATUS + (n << 3), &temp, 2, &ESCvar.ALevent); 00149 temp = etohs(temp); 00150 sm->ActESC = temp >> 8; 00151 sm->Status = temp; 00152 } 00153 00154 void ESC_SMwritepdi(uint8 n) 00155 { 00156 _ESCsm2 *sm; 00157 sm = (_ESCsm2 *)&ESCvar.SM[n]; 00158 ESC_write(ESCREG_SM0PDI + (n << 3), &(sm->ActPDI), 1, &ESCvar.ALevent); 00159 } 00160 00161 void ESC_SMenable(uint8 n) 00162 { 00163 _ESCsm2 *sm; 00164 sm = (_ESCsm2 *)&ESCvar.SM[n]; 00165 sm->ActPDI &= ~ESCREG_SMENABLE_BIT; 00166 ESC_SMwritepdi(n); 00167 } 00168 00169 void ESC_SMdisable(uint8 n) 00170 { 00171 _ESCsm2 *sm; 00172 sm = (_ESCsm2 *)&ESCvar.SM[n]; 00173 sm->ActPDI |= ESCREG_SMENABLE_BIT; 00174 ESC_SMwritepdi(n); 00175 } 00176 00177 void ESC_address(void) 00178 { 00179 ESC_read(ESCREG_ADDRESS, &ESCvar.address, sizeof(ESCvar.address), &ESCvar.ALevent); 00180 ESCvar.address = etohs(ESCvar.address); 00181 } 00182 00183 uint8 ESC_WDstatus(void) 00184 { 00185 uint16 wdstatus; 00186 ESC_read(ESCREG_WDSTATUS, &wdstatus, 2, &ESCvar.ALevent); 00187 wdstatus = etohs(wdstatus); 00188 return (uint8)wdstatus; 00189 } 00190 00191 uint8 ESC_checkmbx(uint8 state) 00192 { 00193 _ESCsm2 *SM; 00194 ESC_read(ESCREG_SM0, &ESCvar.SM[0], sizeof(ESCvar.SM[0]), &ESCvar.ALevent); 00195 ESC_read(ESCREG_SM1, &ESCvar.SM[1], sizeof(ESCvar.SM[1]), &ESCvar.ALevent); 00196 SM = (_ESCsm2 *)&ESCvar.SM[0]; 00197 if ((etohs(SM->PSA) != MBX0_sma) || (etohs(SM->Length) != MBX0_sml) || (SM->Command != MBX0_smc) || (ESCvar.SM[0].ECsm == 0)) 00198 { 00199 ESCvar.SMtestresult = SMRESULT_ERRSM0; 00200 ESC_SMdisable(0); 00201 ESC_SMdisable(1); 00202 return (uint8)(ESCinit | ESCerror); //fail state change 00203 } 00204 SM = (_ESCsm2 *)&ESCvar.SM[1]; 00205 if ((etohs(SM->PSA) != MBX1_sma) || (etohs(SM->Length) != MBX1_sml) || (SM->Command != MBX1_smc) || (ESCvar.SM[1].ECsm == 0)) 00206 { 00207 ESCvar.SMtestresult = SMRESULT_ERRSM1; 00208 ESC_SMdisable(0); 00209 ESC_SMdisable(1); 00210 return ESCinit | ESCerror; //fail state change 00211 } 00212 return state; 00213 } 00214 00215 uint8 ESC_startmbx(uint8 state) 00216 { 00217 ESC_SMenable(0); 00218 ESC_SMenable(1); 00219 ESC_SMstatus(0); 00220 ESC_SMstatus(1); 00221 if ((state = ESC_checkmbx(state)) & ESCerror) 00222 { 00223 ESC_ALerror(ALERR_INVALIDMBXCONFIG); 00224 MBXrun = 0; 00225 } 00226 else 00227 { 00228 ESCvar.toggle = ESCvar.SM[1].ECrep; //sync repeat request toggle state 00229 MBXrun = 1; 00230 } 00231 return state; 00232 } 00233 00234 void ESC_stopmbx(void) 00235 { 00236 uint8 n; 00237 MBXrun = 0; 00238 ESC_SMdisable(0); 00239 ESC_SMdisable(1); 00240 for (n = 0 ; n < MBXBUFFERS ; n++) MBXcontrol[n].state = MBXstate_idle; 00241 ESCvar.mbxoutpost = 0; 00242 ESCvar.mbxbackup = 0; 00243 ESCvar.xoe = 0; 00244 ESCvar.mbxfree = 1; 00245 ESCvar.toggle = 0; 00246 ESCvar.mbxincnt = 0; 00247 ESCvar.segmented = 0; 00248 ESCvar.frags = 0; 00249 ESCvar.fragsleft = 0; 00250 ESCvar.txcue = 0; 00251 } 00252 00253 void ESC_readmbx(void) 00254 { 00255 _MBX *MB = &MBX[0]; 00256 uint16 length; 00257 ESC_read(MBX0_sma, MB,MBXHSIZE, &ESCvar.ALevent); 00258 length = etohs(MB->header.length); 00259 if (length > (MBX0_sml - MBXHSIZE)) length = MBX0_sml - MBXHSIZE; 00260 ESC_read(MBX0_sma + MBXHSIZE, &(MB->b[0]), length, &ESCvar.ALevent); 00261 if (length + MBXHSIZE < MBX0_sml) 00262 { 00263 ESC_read(MBX0_sme, &length, 1, &ESCvar.ALevent); 00264 } 00265 MBXcontrol[0].state = MBXstate_inclaim; 00266 } 00267 00268 void ESC_writembx(uint8 n) 00269 { 00270 _MBX *MB = &MBX[n]; 00271 uint8 dummy = 0; 00272 uint16 length; 00273 length = etohs(MB->header.length); 00274 if (length > (MBX1_sml - MBXHSIZE)) length = MBX1_sml - MBXHSIZE; 00275 ESC_write(MBX1_sma, MB, MBXHSIZE + length, &ESCvar.ALevent); 00276 if (length + MBXHSIZE < MBX1_sml) 00277 { 00278 ESC_write(MBX1_sme, &dummy, 1, &ESCvar.ALevent); 00279 } 00280 ESCvar.mbxfree = 0; 00281 } 00282 00283 void ESC_ackmbxread(void) 00284 { 00285 uint8 dummy = 0; 00286 ESC_write(MBX1_sma, &dummy, 1, &ESCvar.ALevent); 00287 ESCvar.mbxfree = 1; 00288 } 00289 00290 uint8 ESC_claimbuffer(void) 00291 { 00292 _MBX *MB; 00293 uint8 n = MBXBUFFERS - 1; 00294 while ((n > 0) && (MBXcontrol[n].state)) n--; 00295 if (n) 00296 { 00297 MBXcontrol[n].state = MBXstate_outclaim; 00298 MB = &MBX[n]; 00299 ESCvar.mbxcnt = (++ESCvar.mbxcnt) & 0x07; 00300 if (ESCvar.mbxcnt == 0) ESCvar.mbxcnt = 1; 00301 MB->header.address = htoes(0x0000); // destination is master 00302 MB->header.channel = 0; 00303 MB->header.priority = 0; 00304 MB->header.mbxcnt = ESCvar.mbxcnt; 00305 ESCvar.txcue++; 00306 } 00307 return n; 00308 } 00309 00310 uint8 ESC_outreqbuffer(void) 00311 { 00312 uint8 n = MBXBUFFERS-1; 00313 while ((n > 0) && (MBXcontrol[n].state != MBXstate_outreq)) n--; 00314 return n; 00315 } 00316 00317 void MBX_error(uint16 error) 00318 { 00319 uint8 MBXout; 00320 _MBXerr *mbxerr; 00321 MBXout = ESC_claimbuffer(); 00322 if (MBXout) 00323 { 00324 mbxerr = (_MBXerr *)&MBX[MBXout]; 00325 mbxerr->mbxheader.length = htoes((uint16)0x04); 00326 mbxerr->mbxheader.mbxtype = MBXERR; 00327 mbxerr->type = htoes((uint16)0x01); 00328 mbxerr->detail = htoes(error); 00329 MBXcontrol[MBXout].state = MBXstate_outreq; 00330 } 00331 } 00332 00333 uint8 ESC_mbxprocess(void) 00334 { 00335 uint8 mbxhandle = 0; 00336 _MBX *MB = &MBX[0]; 00337 00338 if (!MBXrun) 00339 { 00340 return 0; //nothing to do 00341 } 00342 00343 if (ESCvar.ALevent & ESCREG_ALEVENT_SM_MASK) // SM0/1 access or SMn change event 00344 { 00345 ESC_SMstatus(0); 00346 ESC_SMstatus(1); 00347 } 00348 00349 if (ESCvar.mbxoutpost && ESCvar.SM[1].IntR) //outmbx read by master 00350 { 00351 ESC_ackmbxread(); 00352 if (ESCvar.mbxbackup) // dispose old backup 00353 { 00354 MBXcontrol[ESCvar.mbxbackup].state = MBXstate_idle; 00355 } 00356 if (MBXcontrol[ESCvar.mbxoutpost].state == MBXstate_again) // if still to do 00357 { 00358 ESC_writembx(ESCvar.mbxoutpost); 00359 } 00360 MBXcontrol[ESCvar.mbxoutpost].state = MBXstate_backup; //create new backup 00361 ESCvar.mbxbackup = ESCvar.mbxoutpost; 00362 ESCvar.mbxoutpost = 0; 00363 return 0; 00364 } 00365 00366 if (ESCvar.SM[1].ECrep != ESCvar.toggle) // repeat request 00367 { 00368 if (ESCvar.mbxoutpost || ESCvar.mbxbackup) 00369 { 00370 if (!ESCvar.mbxoutpost) // if outmbx empty 00371 { 00372 ESC_writembx(ESCvar.mbxbackup); // use backup mbx 00373 } 00374 else 00375 { 00376 ESC_SMdisable(1); // reset mailbox 00377 MBXcontrol[ESCvar.mbxoutpost].state = MBXstate_again; // have to resend later 00378 ESC_SMenable(1); // activate mailbox 00379 ESC_writembx(ESCvar.mbxbackup); // use backup mbx 00380 } 00381 ESCvar.toggle = ESCvar.SM[1].ECrep; 00382 ESCvar.SM[1].PDIrep = ESCvar.toggle; 00383 ESC_SMwritepdi(1); 00384 } 00385 return 0; 00386 } 00387 00388 // if the outmailbox is free check if we have something to send 00389 if (ESCvar.txcue && (ESCvar.mbxfree || !ESCvar.SM[1].MBXstat)) 00390 { 00391 mbxhandle = ESC_outreqbuffer(); // check out request mbx 00392 if (mbxhandle) // outmbx empty and outreq mbx available 00393 { 00394 ESC_writembx(mbxhandle); 00395 MBXcontrol[mbxhandle].state = MBXstate_outpost; // change state 00396 ESCvar.mbxoutpost = mbxhandle; 00397 if (ESCvar.txcue) ESCvar.txcue--; 00398 } 00399 } 00400 00401 // read mailbox if full and no xoe in progress 00402 if (ESCvar.SM[0].MBXstat && !MBXcontrol[0].state && !ESCvar.mbxoutpost && !ESCvar.xoe) 00403 { 00404 ESC_readmbx(); 00405 ESCvar.SM[0].MBXstat = 0; 00406 if (etohs(MB->header.length) < 8) 00407 { 00408 if (etohs(MB->header.length) == 0) 00409 MBX_error(MBXERR_INVALIDHEADER); 00410 else 00411 MBX_error(MBXERR_SIZETOOSHORT); 00412 MBXcontrol[0].state = MBXstate_idle; // drop mailbox 00413 } 00414 if ((MB->header.mbxcnt !=0) && (MB->header.mbxcnt == ESCvar.mbxincnt)) 00415 { 00416 MBXcontrol[0].state = MBXstate_idle; // drop mailbox 00417 } 00418 ESCvar.mbxincnt = MB->header.mbxcnt; 00419 return 1; 00420 } 00421 00422 if (ESCvar.ALevent & ESCREG_ALEVENT_SMCHANGE) // ack changes in non used SM 00423 { 00424 ESC_SMack(4); 00425 ESC_SMack(5); 00426 ESC_SMack(6); 00427 ESC_SMack(7); 00428 } 00429 00430 return 0; 00431 } 00432 00433 int16 SDO_findsubindex(int16 nidx, uint8 subindex) 00434 { 00435 _objd FLASHSTORE *objd; 00436 int16 n = 0; 00437 uint8 maxsub; 00438 objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); 00439 maxsub = pgm_read_byte(&SDOobjects[nidx].maxsub); 00440 while (( pgm_read_byte(&(objd + n)->subindex) < subindex) && (n < maxsub)) 00441 { 00442 n++; 00443 } 00444 if (pgm_read_byte(&(objd + n)->subindex) != subindex) 00445 { 00446 return -1; 00447 } 00448 return n; 00449 } 00450 00451 void copy2mbx(void *source, void *dest, uint16 size) 00452 { 00453 memcpy(dest, source, size); 00454 } 00455 00456 void SDO_abort(uint16 index, uint8 subindex, uint32 abortcode) 00457 { 00458 uint8 MBXout; 00459 _COEsdo *coeres; 00460 MBXout = ESC_claimbuffer(); 00461 if (MBXout) 00462 { 00463 coeres = (_COEsdo *)&MBX[MBXout]; 00464 coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); 00465 coeres->mbxheader.mbxtype = MBXCOE; 00466 coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOREQUEST << 12)); 00467 coeres->index = htoes(index); 00468 coeres->subindex = subindex; 00469 coeres->command = COE_COMMAND_SDOABORT; 00470 coeres->size = htoel(abortcode); 00471 MBXcontrol[MBXout].state = MBXstate_outreq; 00472 } 00473 } 00474 00475 void SDO_upload(void) 00476 { 00477 _COEsdo *coesdo,*coeres; 00478 uint16 index; 00479 uint8 subindex; 00480 int16 nidx, nsub; 00481 uint8 MBXout; 00482 uint16 size; 00483 uint8 dss; 00484 _objd FLASHSTORE *objd; 00485 coesdo = (_COEsdo *)&MBX[0]; 00486 index = etohs(coesdo->index); 00487 subindex = coesdo->subindex; 00488 nidx = SDO_findobject(index); 00489 if (nidx >= 0) 00490 { 00491 nsub = SDO_findsubindex(nidx, subindex); 00492 if (nsub >= 0) 00493 { 00494 objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); 00495 MBXout = ESC_claimbuffer(); 00496 if (MBXout) 00497 { 00498 coeres = (_COEsdo *)&MBX[MBXout]; 00499 coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); 00500 coeres->mbxheader.mbxtype = MBXCOE; 00501 coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDORESPONSE << 12)); 00502 size = pgm_read_word(&(objd + nsub)->bitlength); 00503 // expedited bits used calculation 00504 dss = 0x0c; 00505 if (size>8) dss = 0x08; 00506 if (size>16) dss = 0x04; 00507 if (size>24) dss = 0x00; 00508 coeres->index = htoes(index); 00509 coeres->subindex = subindex; 00510 if (size <= 32) 00511 { // expedited response i.e. length<=4 bytes 00512 coeres->command = COE_COMMAND_UPLOADRESPONSE + 00513 COE_SIZE_INDICATOR + 00514 COE_EXPEDITED_INDICATOR + dss; 00515 if (pgm_read_word(&(objd+nsub)->data) == nil) 00516 { 00517 coeres->size = htoel(pgm_read_dword(&(objd + nsub)->value)); //use constant value 00518 } 00519 else 00520 { 00521 size = (size + 7) >> 3; //convert bits to bytes 00522 copy2mbx((void *)pgm_read_word(&(objd + nsub)->data), &(coeres->size), size); //use dynamic data 00523 } 00524 } 00525 else 00526 { // normal response i.e. length>4 bytes 00527 coeres->command = COE_COMMAND_UPLOADRESPONSE + 00528 COE_SIZE_INDICATOR; 00529 size=(size + 7) >> 3; //convert bits to bytes 00530 coeres->size = htoel(size); 00531 if ((size + COE_HEADERSIZE) > MBXDSIZE) 00532 { // segemented transfer needed 00533 ESCvar.frags = size; // set total size in bytes 00534 size = MBXDSIZE - COE_HEADERSIZE; //limit to mailbox size 00535 ESCvar.fragsleft = size; // number of bytes done 00536 ESCvar.segmented = MBXSEU; // signal segmented transfer 00537 ESCvar.data = (void *)pgm_read_word(&(objd + nsub)->data); 00538 } 00539 else 00540 { 00541 ESCvar.segmented = 0; 00542 } 00543 coeres->mbxheader.length = htoes(COE_HEADERSIZE + size); 00544 copy2mbx((void *)pgm_read_word(&(objd + nsub)->data), (&(coeres->size)) + 1, size); //use dynamic data 00545 } 00546 MBXcontrol[MBXout].state = MBXstate_outreq; 00547 } 00548 } 00549 else 00550 { 00551 SDO_abort(index, subindex, ABORT_NOSUBINDEX); 00552 } 00553 } 00554 else 00555 { 00556 SDO_abort(index, subindex, ABORT_NOOBJECT); 00557 } 00558 MBXcontrol[0].state = MBXstate_idle; 00559 ESCvar.xoe = 0; 00560 } 00561 00562 00563 void SDO_uploadsegment(void) 00564 { 00565 _COEsdo *coesdo, *coeres; 00566 uint8 MBXout; 00567 uint16 size, offset; 00568 coesdo = (_COEsdo *)&MBX[0]; 00569 MBXout = ESC_claimbuffer(); 00570 if (MBXout) 00571 { 00572 coeres = (_COEsdo *)&MBX[MBXout]; 00573 offset = ESCvar.fragsleft; 00574 size = ESCvar.frags - ESCvar.fragsleft; 00575 coeres->mbxheader.mbxtype = MBXCOE; 00576 coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDORESPONSE << 12)); 00577 coeres->command = COE_COMMAND_UPLOADSEGMENT + 00578 (coesdo->command & COE_TOGGLEBIT); // copy toggle bit 00579 if ((size + COE_SEGMENTHEADERSIZE) > MBXDSIZE) 00580 { // more segemented transfer needed 00581 size = MBXDSIZE - COE_SEGMENTHEADERSIZE; //limit to mailbox size 00582 ESCvar.fragsleft += size; // number of bytes done 00583 coeres->mbxheader.length = htoes(COE_SEGMENTHEADERSIZE + size); 00584 } 00585 else 00586 {// last segment 00587 ESCvar.segmented = 0; 00588 ESCvar.frags = 0; 00589 ESCvar.fragsleft = 0; 00590 coeres->command += COE_COMMAND_LASTSEGMENTBIT; 00591 if (size >= 7) 00592 { 00593 coeres->mbxheader.length = htoes(COE_SEGMENTHEADERSIZE + size); 00594 } 00595 else 00596 { 00597 coeres->command += (7 - size) << 1; 00598 coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); 00599 } 00600 } 00601 copy2mbx((uint8*)ESCvar.data + offset, (&(coeres->command)) + 1, size); //copy to mailbox 00602 00603 MBXcontrol[MBXout].state = MBXstate_outreq; 00604 } 00605 MBXcontrol[0].state = MBXstate_idle; 00606 ESCvar.xoe = 0; 00607 } 00608 00609 void SDO_download(void) 00610 { 00611 _COEsdo *coesdo, *coeres; 00612 uint16 index; 00613 uint8 subindex; 00614 int16 nidx, nsub; 00615 uint8 MBXout; 00616 uint16 size, actsize; 00617 _objd FLASHSTORE *objd; 00618 uint32 *mbxdata; 00619 coesdo = (_COEsdo *)&MBX[0]; 00620 index = etohs(coesdo->index); 00621 subindex = coesdo->subindex; 00622 nidx = SDO_findobject(index); 00623 if (nidx >= 0) 00624 { 00625 nsub = SDO_findsubindex(nidx, subindex); 00626 if (nsub >= 0) 00627 { 00628 objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); 00629 if ((pgm_read_word(&(objd + nsub)->access) == ATYPE_RW) || 00630 ((pgm_read_word(&(objd + nsub)->access) == ATYPE_RWpre) && ((ESCvar.ALstatus & 0x0f) == ESCpreop))) 00631 { 00632 if (coesdo->command & COE_EXPEDITED_INDICATOR) //expedited? 00633 { 00634 size = 4 - ((coesdo->command & 0x0c) >> 2); 00635 mbxdata = &(coesdo->size); 00636 } 00637 else // normal upload 00638 { 00639 size = (etohs(coesdo->size) & 0xffff); 00640 mbxdata = (&(coesdo->size)) + 1; 00641 } 00642 actsize = (pgm_read_word(&(objd + nsub)->bitlength) + 7) >> 3; 00643 if ( actsize == size ) 00644 { 00645 copy2mbx(mbxdata, (void *)pgm_read_word(&(objd + nsub)->data), size); 00646 MBXout = ESC_claimbuffer(); 00647 if (MBXout) 00648 { 00649 coeres = (_COEsdo *)&MBX[MBXout]; 00650 coeres->mbxheader.length = htoes(COE_DEFAULTLENGTH); 00651 coeres->mbxheader.mbxtype = MBXCOE; 00652 coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDORESPONSE << 12)); 00653 coeres->index = htoes(index); 00654 coeres->subindex = subindex; 00655 coeres->command = COE_COMMAND_DOWNLOADRESPONSE; 00656 coeres->size = htoel(0); 00657 MBXcontrol[MBXout].state = MBXstate_outreq; 00658 } 00659 // external object write handler 00660 ESC_objecthandler(index, subindex); 00661 } 00662 else 00663 { 00664 SDO_abort(index, subindex, ABORT_TYPEMISMATCH); 00665 } 00666 } 00667 else 00668 { 00669 if(pgm_read_word(&(objd + nsub)->access) == ATYPE_RWpre) 00670 SDO_abort(index, subindex, ABORT_NOTINTHISSTATE); 00671 else 00672 SDO_abort(index, subindex, ABORT_READONLY); 00673 } 00674 } 00675 else 00676 { 00677 SDO_abort(index, subindex, ABORT_NOSUBINDEX); 00678 } 00679 } 00680 else 00681 { 00682 SDO_abort(index, subindex, ABORT_NOOBJECT); 00683 } 00684 MBXcontrol[0].state = MBXstate_idle; 00685 ESCvar.xoe = 0; 00686 } 00687 00688 void SDO_infoerror(uint32 abortcode) 00689 { 00690 uint8 MBXout; 00691 _COEobjdesc *coeres; 00692 MBXout = ESC_claimbuffer(); 00693 if (MBXout) 00694 { 00695 coeres = (_COEobjdesc *)&MBX[MBXout]; 00696 coeres->mbxheader.length = htoes((uint16)0x0a); 00697 coeres->mbxheader.mbxtype = MBXCOE; 00698 coeres->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); 00699 coeres->infoheader.opcode = COE_INFOERROR; //SDO info error request 00700 coeres->infoheader.incomplete = 0; 00701 coeres->infoheader.reserved = 0x00; 00702 coeres->infoheader.fragmentsleft = 0; 00703 coeres->index = htoel(abortcode); 00704 MBXcontrol[MBXout].state = MBXstate_outreq; 00705 } 00706 } 00707 00708 #define ODLISTSIZE ((MBX1_sml - MBXHSIZE - sizeof(_COEh) - sizeof(_INFOh) - 2) & 0xfffe) 00709 00710 void SDO_getodlist(void) 00711 { 00712 uint16 frags; 00713 uint8 MBXout = 0; 00714 uint16 entries = 0; 00715 uint16 i, n; 00716 uint16 *p; 00717 _COEobjdesc *coel, *coer; 00718 00719 while (pgm_read_word(&SDOobjects[entries].index) != 0xffff) entries++; 00720 ESCvar.entries = entries; 00721 frags = ((entries << 1) + ODLISTSIZE - 1); 00722 frags /= ODLISTSIZE; 00723 coer = (_COEobjdesc *)&MBX[0]; 00724 if (etohs(coer->index) > 0x01) // check for unsupported opcodes 00725 { 00726 SDO_infoerror(ABORT_UNSUPPORTED); 00727 } 00728 else 00729 { 00730 MBXout = ESC_claimbuffer(); 00731 } 00732 if (MBXout) 00733 { 00734 coel = (_COEobjdesc *)&MBX[MBXout]; 00735 coel->mbxheader.mbxtype = MBXCOE; 00736 coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); 00737 coel->infoheader.opcode = COE_GETODLISTRESPONSE; 00738 if (etohs(coer->index) == 0x00) //number of objects request 00739 { 00740 coel->index = htoes((uint16)0x00); 00741 coel->infoheader.incomplete = 0; 00742 coel->infoheader.reserved = 0x00; 00743 coel->infoheader.fragmentsleft = htoes((uint16)0); 00744 MBXcontrol[0].state = MBXstate_idle; 00745 ESCvar.xoe = 0; 00746 ESCvar.frags = frags; 00747 ESCvar.fragsleft = frags - 1; 00748 p = &(coel->datatype); 00749 *p = htoes(entries); 00750 p++; 00751 *p = 0; 00752 p++; 00753 *p = 0; 00754 p++; 00755 *p = 0; 00756 p++; 00757 *p = 0; 00758 coel->mbxheader.length = htoes(0x08 + (5 << 1)); 00759 } 00760 if (etohs(coer->index) == 0x01) //only return all objects 00761 { 00762 if (frags > 1) 00763 { 00764 coel->infoheader.incomplete = 1; 00765 ESCvar.xoe = MBXCOE + MBXODL; 00766 n = ODLISTSIZE >> 1; 00767 } 00768 else 00769 { 00770 coel->infoheader.incomplete = 0; 00771 MBXcontrol[0].state = MBXstate_idle; 00772 ESCvar.xoe = 0; 00773 n = entries; 00774 } 00775 coel->infoheader.reserved = 0x00; 00776 ESCvar.frags = frags; 00777 ESCvar.fragsleft = frags - 1; 00778 coel->infoheader.fragmentsleft = htoes(ESCvar.fragsleft); 00779 coel->index = htoes((uint16)0x01); 00780 00781 p = &(coel->datatype); 00782 for (i = 0 ; i < n ; i++) 00783 { 00784 *p = htoes(pgm_read_word(&SDOobjects[i].index)); 00785 p++; 00786 } 00787 00788 coel->mbxheader.length = htoes(0x08 + ( n << 1)); 00789 } 00790 MBXcontrol[MBXout].state = MBXstate_outreq; 00791 } 00792 } 00793 00794 void SDO_getodlistcont(void) 00795 { 00796 uint8 MBXout; 00797 uint16 i , n, s; 00798 uint16 *p; 00799 _COEobjdesc *coel; 00800 00801 MBXout = ESC_claimbuffer(); 00802 if (MBXout) 00803 { 00804 coel = (_COEobjdesc *)&MBX[MBXout]; 00805 coel->mbxheader.mbxtype = MBXCOE; 00806 coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); 00807 coel->infoheader.opcode = COE_GETODLISTRESPONSE; 00808 s = (ESCvar.frags - ESCvar.fragsleft) * (ODLISTSIZE >> 1); 00809 if (ESCvar.fragsleft > 1) 00810 { 00811 coel->infoheader.incomplete = 1; 00812 n = s + (ODLISTSIZE >> 1); 00813 } 00814 else 00815 { 00816 coel->infoheader.incomplete = 0; 00817 MBXcontrol[0].state = MBXstate_idle; 00818 ESCvar.xoe = 0; 00819 n = ESCvar.entries; 00820 } 00821 coel->infoheader.reserved = 0x00; 00822 ESCvar.fragsleft--; 00823 coel->infoheader.fragmentsleft = htoes(ESCvar.fragsleft); 00824 p = &(coel->index); //pointer 2 bytes back to exclude index 00825 for ( i = s ; i < n ; i++) 00826 { 00827 *p = htoes(pgm_read_word(&SDOobjects[i].index)); 00828 p++; 00829 } 00830 coel->mbxheader.length = htoes(0x06 + ((n - s) << 1)); 00831 MBXcontrol[MBXout].state = MBXstate_outreq; 00832 } 00833 } 00834 00835 void SDO_getod(void) 00836 { 00837 uint8 MBXout; 00838 uint16 index; 00839 int16 nidx; 00840 uint8 *d; 00841 uint8 FLASHSTORE *s; 00842 uint8 n = 0; 00843 _COEobjdesc *coer, *coel; 00844 coer = (_COEobjdesc *)&MBX[0]; 00845 index = etohs(coer->index); 00846 nidx = SDO_findobject(index); 00847 if (nidx >= 0) 00848 { 00849 MBXout = ESC_claimbuffer(); 00850 if (MBXout) 00851 { 00852 coel = (_COEobjdesc *)&MBX[MBXout]; 00853 coel->mbxheader.mbxtype = MBXCOE; 00854 coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); 00855 coel->infoheader.opcode = COE_GETODRESPONSE; 00856 coel->infoheader.incomplete = 0; 00857 coel->infoheader.reserved = 0x00; 00858 coel->infoheader.fragmentsleft = htoes(0); 00859 coel->index = htoes(index); 00860 coel->datatype = htoes(0); 00861 coel->maxsub = pgm_read_byte(&SDOobjects[nidx].maxsub); 00862 coel->objectcode = pgm_read_word(&SDOobjects[nidx].objtype); 00863 s = (uint8 *)pgm_read_word(&SDOobjects[nidx].name); 00864 d = (uint8 *)&(coel->name); 00865 while (pgm_read_byte(s) && (n < (MBXDSIZE - 0x0c))) 00866 { 00867 *d = pgm_read_byte(s); 00868 n++; 00869 s++; 00870 d++; 00871 } 00872 *d = pgm_read_byte(s); 00873 coel->mbxheader.length = htoes((uint16)0x0c + n); 00874 MBXcontrol[MBXout].state = MBXstate_outreq; 00875 MBXcontrol[0].state = MBXstate_idle; 00876 ESCvar.xoe=0; 00877 } 00878 } 00879 else 00880 { 00881 SDO_infoerror(ABORT_NOOBJECT); 00882 } 00883 } 00884 00885 void SDO_geted(void) 00886 { 00887 uint8 MBXout; 00888 uint16 index; 00889 int16 nidx, nsub; 00890 uint8 subindex; 00891 uint8 *d; 00892 uint8 FLASHSTORE *s; 00893 _objd FLASHSTORE *objd; 00894 uint8 n = 0; 00895 _COEentdesc *coer, *coel; 00896 coer = (_COEentdesc *)&MBX[0]; 00897 index = etohs(coer->index); 00898 subindex = coer->subindex; 00899 nidx = SDO_findobject(index); 00900 if (nidx >= 0) 00901 { 00902 nsub = SDO_findsubindex(nidx, subindex); 00903 if (nsub >= 0) 00904 { 00905 objd = (_objd FLASHSTORE *)pgm_read_word(&SDOobjects[nidx].objdesc); 00906 MBXout = ESC_claimbuffer(); 00907 if (MBXout) 00908 { 00909 coel = (_COEentdesc *)&MBX[MBXout]; 00910 coel->mbxheader.mbxtype = MBXCOE; 00911 coel->coeheader.numberservice = htoes((0 & 0x01f) | (COE_SDOINFORMATION << 12)); 00912 coel->infoheader.opcode = COE_ENTRYDESCRIPTIONRESPONSE; 00913 coel->infoheader.incomplete = 0; 00914 coel->infoheader.reserved = 0x00; 00915 coel->infoheader.fragmentsleft = htoes((uint16)0); 00916 coel->index = htoes(index); 00917 coel->subindex = subindex; 00918 coel->valueinfo = COE_VALUEINFO_ACCESS + 00919 COE_VALUEINFO_OBJECT + 00920 COE_VALUEINFO_MAPPABLE; 00921 coel->datatype = htoes(pgm_read_word(&(objd + nsub)->datatype)); 00922 coel->bitlength = htoes(pgm_read_word(&(objd + nsub)->bitlength)); 00923 coel->access = htoes(pgm_read_word(&(objd + nsub)->access)); 00924 s = (uint8 *)pgm_read_word(&(objd+nsub)->name); 00925 d = (uint8 *)&(coel->name); 00926 while (pgm_read_byte(s) && (n < (MBXDSIZE - 0x10))) 00927 { 00928 *d = pgm_read_byte(s); 00929 n++; 00930 s++; 00931 d++; 00932 } 00933 *d = pgm_read_byte(s); 00934 coel->mbxheader.length = htoes((uint16)0x10 + n); 00935 MBXcontrol[MBXout].state = MBXstate_outreq; 00936 MBXcontrol[0].state = MBXstate_idle; 00937 ESCvar.xoe = 0; 00938 } 00939 } 00940 else 00941 { 00942 SDO_infoerror(ABORT_NOSUBINDEX); 00943 } 00944 } 00945 else 00946 { 00947 SDO_infoerror(ABORT_NOOBJECT); 00948 } 00949 } 00950 00951 void ESC_coeprocess(void) 00952 { 00953 _MBXh *mbh; 00954 _COEsdo *coesdo; 00955 _COEobjdesc *coeobjdesc; 00956 uint8 service; 00957 if (!MBXrun) 00958 { 00959 return; 00960 } 00961 if (!ESCvar.xoe && (MBXcontrol[0].state == MBXstate_inclaim)) 00962 { 00963 mbh = (_MBXh *)&MBX[0]; 00964 if (mbh->mbxtype == MBXCOE) 00965 { 00966 ESCvar.xoe = MBXCOE; 00967 } 00968 } 00969 if ((ESCvar.xoe == (MBXCOE + MBXODL)) && (!ESCvar.mbxoutpost)) 00970 { 00971 SDO_getodlistcont(); // continue get OD list 00972 } 00973 if (ESCvar.xoe == MBXCOE) 00974 { 00975 coesdo = (_COEsdo *)&MBX[0]; 00976 coeobjdesc = (_COEobjdesc *)&MBX[0]; 00977 service = etohs(coesdo->coeheader.numberservice) >> 12; 00978 //initiate SDO upload request 00979 if ((service == COE_SDOREQUEST) 00980 && (coesdo->command == COE_COMMAND_UPLOADREQUEST) 00981 && (etohs(coesdo->mbxheader.length) == 0x0a)) 00982 { 00983 SDO_upload(); 00984 } 00985 //SDO upload segment request 00986 if ((service == COE_SDOREQUEST) 00987 && ((coesdo->command & 0xef) == COE_COMMAND_UPLOADSEGREQ) 00988 && (etohs(coesdo->mbxheader.length) == 0x0a) 00989 && (ESCvar.segmented == MBXSEU)) 00990 { 00991 SDO_uploadsegment(); 00992 } 00993 //initiate SDO download request 00994 else 00995 if ((service == COE_SDOREQUEST) 00996 && ((coesdo->command & 0xf1) == 0x21)) 00997 { 00998 SDO_download(); 00999 } 01000 //initiate SDO get OD list 01001 else 01002 if ((service == COE_SDOINFORMATION) 01003 &&(coeobjdesc->infoheader.opcode == 0x01)) 01004 { 01005 SDO_getodlist(); 01006 } 01007 //initiate SDO get OD 01008 else 01009 if ((service == COE_SDOINFORMATION) 01010 && (coeobjdesc->infoheader.opcode == 0x03)) 01011 { 01012 SDO_getod(); 01013 } 01014 //initiate SDO get ED 01015 else 01016 if ((service == COE_SDOINFORMATION) 01017 && (coeobjdesc->infoheader.opcode == 0x05)) 01018 { 01019 SDO_geted(); 01020 } 01021 else 01022 if (ESCvar.xoe == MBXCOE) //COE not recognised above 01023 { 01024 if (service == 0) 01025 { 01026 MBX_error(MBXERR_INVALIDHEADER); 01027 } 01028 else 01029 { 01030 SDO_abort(etohs(coesdo->index), coesdo->subindex, ABORT_UNKNOWN); 01031 } 01032 MBXcontrol[0].state = MBXstate_idle; 01033 ESCvar.xoe = 0; 01034 } 01035 } 01036 } 01037 01038 void ESC_xoeprocess(void) 01039 { 01040 _MBXh *mbh; 01041 if (!MBXrun) 01042 { 01043 return; 01044 } 01045 if (!ESCvar.xoe && (MBXcontrol[0].state == MBXstate_inclaim)) 01046 { 01047 mbh = (_MBXh *)&MBX[0]; 01048 if ((mbh->mbxtype == 0) || (etohs(mbh->length) == 0)) 01049 { 01050 MBX_error(MBXERR_INVALIDHEADER); 01051 } 01052 else 01053 { 01054 MBX_error(MBXERR_UNSUPPORTEDPROTOCOL); 01055 } 01056 MBXcontrol[0].state = MBXstate_idle; // mailbox type not supported, drop mailbox 01057 } 01058 } 01059 01060 uint8 ESC_checkSM23(uint8 state) 01061 { 01062 _ESCsm2 *SM; 01063 ESC_read(ESCREG_SM2, &ESCvar.SM[2], sizeof(ESCvar.SM[2]), &ESCvar.ALevent); 01064 ESC_read(ESCREG_SM3, &ESCvar.SM[3], sizeof(ESCvar.SM[3]), &ESCvar.ALevent); 01065 SM = (_ESCsm2 *)&ESCvar.SM[2]; 01066 if ((etohs(SM->PSA) != SM2_sma) || (etohs(SM->Length) != SM2_sml) || (SM->Command != SM2_smc) || !(SM->ActESC & SM2_act)) 01067 { 01068 ESCvar.SMtestresult = SMRESULT_ERRSM2; 01069 return ESCpreop | ESCerror; //fail state change 01070 } 01071 SM = (_ESCsm2 *)&ESCvar.SM[3]; 01072 if ((etohs(SM->PSA) != SM3_sma) || (etohs(SM->Length) != SM3_sml) || (SM->Command != SM3_smc) || !(SM->ActESC & SM3_act)) 01073 { 01074 ESCvar.SMtestresult = SMRESULT_ERRSM3; 01075 return ESCpreop | ESCerror; //fail state change 01076 } 01077 return state; 01078 } 01079 01080 uint8 ESC_startinput(uint8 state) 01081 { 01082 state = ESC_checkSM23(state); 01083 if (state != (ESCpreop | ESCerror)) 01084 { 01085 ESC_SMenable(3); 01086 APPstate = APPSTATE_INPUT; 01087 } 01088 else 01089 { 01090 ESC_SMdisable(2); 01091 ESC_SMdisable(3); 01092 if( ESCvar.SMtestresult & SMRESULT_ERRSM3 ) 01093 ESC_ALerror(ALERR_INVALIDINPUTSM); 01094 else 01095 ESC_ALerror(ALERR_INVALIDOUTPUTSM); 01096 } 01097 return state; 01098 } 01099 01100 void ESC_stopinput(void) 01101 { 01102 APPstate = APPSTATE_IDLE; 01103 ESC_SMdisable(3); 01104 ESC_SMdisable(2); 01105 } 01106 01107 uint8 ESC_startoutput(uint8 state) 01108 { 01109 ESC_SMenable(2); 01110 APPstate |= APPSTATE_OUTPUT; 01111 return state; 01112 } 01113 01114 void ESC_stopoutput(void) 01115 { 01116 APPstate &= APPSTATE_INPUT; 01117 ESC_SMdisable(2); 01118 APP_safeoutput(); 01119 } 01120 01121 void ESC_ALevent(void) 01122 { 01123 if (!(ESCvar.ALevent & (ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE)) && 01124 (ESCvar.wdcnt++ < 1000)) 01125 { //nothing to do 01126 ESCvar.ALcontrol = 0; 01127 return; 01128 } 01129 ESCvar.wdcnt = 0; 01130 ESC_read(ESCREG_ALCONTROL, &ESCvar.ALcontrol, sizeof(ESCvar.ALcontrol), &ESCvar.ALevent); 01131 ESCvar.ALcontrol = etohs(ESCvar.ALcontrol); 01132 } 01133 01134 void ESC_state(void) 01135 { 01136 uint8 ac, an, as, ax; 01137 if (!ESCvar.ALcontrol) return; //nothing to do 01138 ac = ESCvar.ALcontrol & 0x001f; 01139 as = ESCvar.ALstatus & 0x001f; 01140 an = as; 01141 if (((ac & ESCerror) || (ac == ESCinit))) 01142 { 01143 ac &= 0x0f; // if error bit confirmed reset 01144 an &= 0x0f; 01145 } 01146 if ((ESCvar.ALevent & ESCREG_ALEVENT_SMCHANGE) && 01147 (as & 0x0e) && 01148 !(ESCvar.ALevent & ESCREG_ALEVENT_CONTROL) && 01149 MBXrun) 01150 { 01151 ESCvar.ALevent = 0; 01152 ax = ESC_checkmbx(as); 01153 if ((as & ESCerror) && ((ac != (ESCinit | ESCerror)) || (ac != ESCinit))) 01154 return; // if in error then stay there 01155 if (ax == (ESCinit | ESCerror)) 01156 { 01157 if (APPstate) 01158 { 01159 ESC_stopoutput(); 01160 ESC_stopinput(); 01161 } 01162 ESC_stopmbx(); 01163 ESC_ALerror(ALERR_INVALIDMBXCONFIG); 01164 MBXrun = 0; 01165 ESC_ALstatus(ax); 01166 return; 01167 } 01168 ax = ESC_checkSM23(as); 01169 if ((APPstate) && (ax == (ESCpreop | ESCerror))) 01170 { 01171 ESC_stopoutput(); 01172 ESC_stopinput(); 01173 if( ESCvar.SMtestresult & SMRESULT_ERRSM3 ) 01174 ESC_ALerror(ALERR_INVALIDINPUTSM); 01175 else 01176 ESC_ALerror(ALERR_INVALIDOUTPUTSM); 01177 ESC_ALstatus(ax); 01178 return; 01179 } 01180 } 01181 ESCvar.ALevent = 0; 01182 if ((an & ESCerror) && !(ac & ESCerror)) return; //error state not acked, leave original 01183 as = (ac << 4) | (as & 0x0f); // high bits ALcommand, low bits ALstatus 01184 switch (as) 01185 { 01186 case INIT_TO_INIT: 01187 case PREOP_TO_PREOP: 01188 case OP_TO_OP: 01189 break; 01190 case INIT_TO_PREOP: 01191 ESC_address(); // get station address 01192 an = ESC_startmbx(ac); 01193 break; 01194 case INIT_TO_BOOT: 01195 an = ESCinit | ESCerror; 01196 ESC_ALerror(ALERR_BOOTNOTSUPPORTED); 01197 break; 01198 case INIT_TO_SAFEOP: 01199 case INIT_TO_OP: 01200 an = ESCinit | ESCerror; 01201 ESC_ALerror(ALERR_INVALIDSTATECHANGE); 01202 break; 01203 case OP_TO_INIT: 01204 ESC_stopoutput(); 01205 case SAFEOP_TO_INIT: 01206 ESC_stopinput(); 01207 case PREOP_TO_INIT: 01208 ESC_stopmbx(); 01209 an = ESCinit; 01210 break; 01211 case PREOP_TO_BOOT: 01212 an = ESCpreop | ESCerror; 01213 ESC_ALerror(ALERR_INVALIDSTATECHANGE); 01214 break; 01215 case PREOP_TO_SAFEOP: 01216 case SAFEOP_TO_SAFEOP: 01217 SM2_sml = sizeRXPDO(); 01218 SM3_sml = sizeTXPDO(); 01219 an = ESC_startinput(ac); 01220 if (an == ac) ESC_SMenable(2); 01221 break; 01222 case PREOP_TO_OP: 01223 an = ESCpreop | ESCerror; 01224 ESC_ALerror(ALERR_INVALIDSTATECHANGE); 01225 break; 01226 case OP_TO_PREOP: 01227 ESC_stopoutput(); 01228 case SAFEOP_TO_PREOP: 01229 ESC_stopinput(); 01230 an = ESCpreop; 01231 break; 01232 case SAFEOP_TO_BOOT: 01233 an = ESCsafeop | ESCerror; 01234 ESC_ALerror(ALERR_INVALIDSTATECHANGE); 01235 break; 01236 case SAFEOP_TO_OP: 01237 an = ESC_startoutput(ac); 01238 break; 01239 case OP_TO_BOOT: 01240 an = ESCsafeop | ESCerror; 01241 ESC_ALerror(ALERR_INVALIDSTATECHANGE); 01242 ESC_stopoutput(); 01243 break; 01244 case OP_TO_SAFEOP: 01245 an = ESCsafeop; 01246 ESC_stopoutput(); 01247 break; 01248 default : 01249 if (an == ESCop) 01250 { 01251 ESC_stopoutput(); 01252 an = ESCsafeop; 01253 } 01254 if (as == ESCsafeop) 01255 ESC_stopinput(); 01256 an |= ESCerror; 01257 ESC_ALerror(ALERR_UNKNOWNSTATE); 01258 } 01259 if (!(an & ESCerror) && (ESCvar.ALerror)) 01260 { 01261 ESC_ALerror(ALERR_NONE); // clear error 01262 } 01263 ESC_ALstatus(an); 01264 } 01265
Generated on Wed Jul 13 2022 17:16:52 by 1.7.2