epos.cpp
Go to the documentation of this file.
00001 
00007 // $Id: epos.c 388 2008-06-23 11:21:30Z mhauser $
00008 
00038 #include "libepos/epos.h"
00039 
00040 
00041 
00042 /* ********************************************* */
00043 /*    definitions used only internal in epos.c   */
00044 /* ********************************************* */
00045 
00046 
00050 #define E_STARTPOS_HOMING -200000 
00051 
00052 
00053 
00054 
00055 /* EPOS codes */
00056 
00057 #define E_OK      0x4f  ///< EPOS answer code for <em>all fine</em>
00058 #define E_FAIL    0x46  ///< EPOS answer code to indicate a <em>failure</em>
00059 #define E_ANS     0x00  ///< EPOS code to indicate an answer <em>frame</em>
00060 
00061 
00062 
00063 
00064 
00065 /* EPOS error codes (Communication Guide, 6.4)  */
00066 
00067 /* CANopen defined error codes */
00068 #define E_NOERR         0x00000000   ///< Error code: no error
00069 #define E_ONOTEX        0x06020000   ///< Error code: object does not exist
00070 #define E_SUBINEX       0x06090011   ///< Error code: subindex does not exist
00071 #define E_OUTMEM        0x05040005   ///< Error code: out of memory
00072 #define E_NOACCES       0x06010000   ///< Error code: Unsupported access to an object
00073 #define E_WRITEONLY     0x06010001   ///< Error code: Attempt to read a write-only object
00074 #define E_READONLY      0x06010002   ///< Error code: Attempt to write a read-only object
00075 #define E_PARAMINCOMP   0x06040043   ///< Error code: general parameter incompatibility 
00076 #define E_INTINCOMP     0x06040047   ///< Error code: general internal incompatibility in the device 
00077 #define E_HWERR         0x06060000   ///< Error code: access failed due to an hardware error
00078 #define E_PRAGNEX       0x06090030   ///< Error code: value range of parameter exeeded
00079 #define E_PARHIGH       0x06090031   ///< Error code: value of parameter written is too high
00080 #define E_PARLOW        0x06090032   ///< Error code: value of parameter written is too low
00081 #define E_PARREL        0x06090036   ///< Error code: maximum value is less than minimum value
00082 
00083 
00084 /* maxon specific error codes */
00085 #define E_NMTSTATE      0x0f00ffc0   ///< Error code: wrong NMT state
00086 #define E_RS232         0x0f00ffbf   ///< Error code: rs232 command illegeal
00087 #define E_PASSWD        0x0f00ffbe   ///< Error code: password incorrect
00088 #define E_NSERV         0x0f00ffbc   ///< Error code: device not in service mode
00089 #define E_NODEID        0x0f00fb9    ///< Error code: error in Node-ID
00090 
00091 
00092 
00093 /* EPOS Statusword -- singe bits, see firmware spec 14.1.58 */
00094 #define E_BIT15        0x8000      ///< bit code: position referenced to home position
00095 #define E_BIT14        0x4000      ///< bit code: refresh cycle of power stage
00096 #define E_BIT13        0x2000      ///< bit code: OpMode specific, some error
00097 #define E_BIT12        0x1000      ///< bit code: OpMode specific
00098 #define E_BIT11        0x0800      ///< bit code: NOT USED
00099 #define E_BIT10        0x0400      ///< bit code: Target reached
00100 #define E_BIT09        0x0200      ///< bit code: Remote (?)
00101 #define E_BIT08        0x0100      ///< bit code: offset current measured (?)
00102 #define E_BIT07        0x0080      ///< bit code: WARNING
00103 #define E_BIT06        0x0040      ///< bit code: switch on disable
00104 #define E_BIT05        0x0020      ///< bit code: quick stop
00105 #define E_BIT04        0x0010      ///< bit code: voltage enabled
00106 #define E_BIT03        0x0008      ///< bit code: FAULT
00107 #define E_BIT02        0x0004      ///< bit code: operation enable
00108 #define E_BIT01        0x0002      ///< bit code: switched on
00109 #define E_BIT00        0x0001      ///< bit code: ready to switch on             
00110 
00111 
00112 
00113 
00114 /* EPOS modes of operation, firmware spec 14.1.59 (p.133, tbl. 72) */
00115 #define E_HOMING      6 ///< EPOS operation mode: homing
00116 #define E_PROFVEL     3 ///< EPOS operation mode: profile velocity mode
00117 #define E_PROFPOS     1 ///< EPOS operation mode: profile position mode
00118 // the modes below should not be used by user, defined here only for
00119 // completeness
00120 #define E_POSMOD     -1 ///< EPOS operation mode: position mode
00121 #define E_VELMOD     -2 ///< EPOS operation mode: velocity mode
00122 #define E_CURRMOD    -3 ///< EPOS operation mode: current mode
00123 #define E_DIAGMOD    -4 ///< EPOS operation mode: diagnostics mode
00124 #define E_MASTERENCMOD -5 ///< EPOS operation mode:internal
00125 #define E_STEPDIRECMOD -6 ///< EPOS operation mode:internal
00126 
00127 
00128 
00129 
00130 int sp; 
00131 DWORD E_error; 
00132 
00133 
00134 
00135 /* Implement read functions defined in EPOS Communication Guide, 6.3.1 */
00136 /* [ one simplification: Node-ID is always 0] */
00137 
00139 int ReadObject(WORD index, BYTE subindex, WORD **answer );
00140 
00141 
00143 int InitiateSegmentedRead(WORD index, BYTE subindex );
00144 
00148 int SegmentRead(WORD **ptr);
00149 
00150 
00151 /* 6.3.2:  write functions */
00152 
00158 int WriteObject(WORD index, BYTE subindex, WORD data[2]);
00159 
00160 
00161 
00162 
00163 
00164 /* helper functions below */
00165 
00166 
00168 int writeBYTE(BYTE *c);
00169 
00171 int writeWORD(WORD *w);
00172 
00174 int readBYTE(BYTE *c);
00175   
00177 int readWORD(WORD *w);
00178 
00181 int sendCom(WORD *frame);
00182 
00184 int readAnswer(WORD **ptr);
00185 
00186 
00187 
00191 WORD CalcFieldCRC(WORD *pDataArray, WORD numberOfWords);
00192 
00193 
00195 void checkPtr(void* ptr);
00196 
00197 
00199 int bitcmp(WORD a, WORD b);
00200 
00201 
00202 /* globals */
00203 
00204 static int ep=-1; 
00205 char gMarker = 0; 
00206 
00207 
00208 
00209 
00210 /************************************************************/
00211 /*           implementation of functions are following      */
00212 /************************************************************/
00213 
00214 
00215 
00216 
00217 
00218 /************************************************************/
00219 /*            open/close device                             */
00220 /************************************************************/
00221 
00222 
00223 
00224 // von hans (atomsps.c, opensps() )
00234 int openEPOS(char *dev) {
00235  struct termios options;
00236  int i;
00237 
00238  /* EPOS transfer format is:
00239     1 start bit
00240     8 data bits
00241     no parity
00242     1 stop bit
00243  */
00244 
00245 
00246  if(ep >=0) return(-1);
00247 
00248   for(i=0;i<5;i++) {
00249     if((ep=open(dev,O_RDWR|O_NOCTTY|O_NDELAY))>=0) break;
00250     sleep(1);
00251   }
00252 
00253   if(ep==-1) {
00254     perror("open serial Port");
00255     return(-1);
00256   }
00257 
00258   if(tcgetattr(ep,&options)<0) {
00259     perror("tcgetattr");
00260     return(-1);
00261   }
00262 
00263   memset(&options,0,sizeof(options));
00264 
00265     options.c_cflag |= B115200;
00266   //options.c_cflag |= B38400;
00267   options.c_cflag |= CS8;           //8 bits per byte
00268 
00269 
00270   options.c_cflag |= CLOCAL|CREAD;
00271 
00272   tcflush(ep,TCIFLUSH);
00273 
00274   if(tcsetattr(ep,TCSANOW,&options)<0) {
00275     perror("tcsetattr");
00276     return(-1);
00277   }
00278 
00279   if ( fcntl(ep,F_SETFL,FNDELAY) < 0){ //FNDELAY enyspricht grob O_NONBLOCK
00280     perror("fcntl");
00281     return(-1);
00282   }
00283     
00284 
00285   return(0);
00286 }
00287 
00288 
00289 
00303 int openTCPEPOS(char *ip, short unsigned port){
00304 
00305   struct sockaddr_in address;
00306   const int y = 1;
00307 
00308   if ((ep = socket (AF_INET, SOCK_STREAM, 0)) > 0) { 
00309     setsockopt( ep, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));
00310     printf ("socket open.\n");
00311   }
00312   else {
00313     perror("socket");
00314     return(-1);
00315   }
00316   
00317   
00318   address.sin_family = AF_INET;
00319   address.sin_port = htons (port); 
00320   inet_aton (ip, &address.sin_addr); // 
00321    
00322   if (connect ( ep,
00323                 (struct sockaddr *) &address,
00324                 sizeof (address)) == 0)
00325     printf ("connection to %s  established.\n",
00326             inet_ntoa (address.sin_addr));
00327   else {
00328     fprintf(stderr,"connect() to >%s<, port >%d< failed in %s()\
00329  (file %s, line %d)\n\n", 
00330             inet_ntoa (address.sin_addr), port, 
00331             __func__, __FILE__, __LINE__);
00332     return(-1);
00333   }
00334   
00335 
00336   // set socket to non-blocking mode
00337   if ( fcntl(ep, F_SETFD, O_NONBLOCK) < 0) {
00338     perror("fcntl");
00339     return(-1);
00340   }
00341 
00342 
00343 
00344   return(0);
00345 }
00346 
00347 
00348 
00349 
00354 int closeEPOS(){
00355   return( close(ep) );
00356 }
00357 
00358 
00359 
00360 
00365 int checkEPOS(){
00366   if (ep<0) {
00367     fprintf(stderr, "ERROR: EPOS device not open!");
00368     return(-1);
00369   }
00370   return(0);
00371 }
00372 
00373 
00374 
00375 
00376 
00377 
00378 /************************************************************/
00379 /*          high-level read functions */
00380 /************************************************************/
00381 
00382 
00383 
00392 int readStatusword(WORD *status){
00393 
00394   WORD *answer = NULL;
00395   int n = 0;
00396   
00397   if ((n = checkEPOS())<0) return n;
00398   checkPtr(&answer);
00399   
00400   if ( (n =  ReadObject(0x6041, 0x00, &answer)) <0){
00401     
00402     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
00403             __func__, n);
00404     free(answer); // memory is allocated by readAnswer()
00405     return(-1);
00406   }
00407   
00408   // check error code
00409   if ((n = checkEPOS())<0) return n;
00410   
00411 #ifdef DEBUG
00412   printf("==> EPOS status word: %#06x\n", answer[3]);
00413 #endif
00414   *status = answer[3];
00415   free(answer); // memory is allocated by readAnswer()
00416   return(0);
00417 }
00418 
00419 
00420 
00421 
00422 
00428 int printEPOSstatusword(WORD s){
00429 
00430   printf("\nmeaning of EPOS statusword %#06x is:\n", s);
00431 
00432 
00433   printf("15: position referenced to home position: ");
00434   if ( (s & E_BIT15) == E_BIT15 ) printf("true\n");
00435   else printf("false\n");
00436 
00437   printf("14: refresh cycle of power stage:         ");   
00438   if ( (s & E_BIT14) == E_BIT14 ) printf("true\n");
00439   else printf("false\n");
00440 
00441   printf("13: OpMode specific, some error:          ");
00442   if ( (s & E_BIT13) == E_BIT13 ) printf("true\n");
00443   else printf("false\n");
00444 
00445   printf("12: OpMode specific:                      ");
00446   if ( (s & E_BIT12) == E_BIT12 ) printf("true\n");
00447   else printf("false\n");
00448 
00449   printf("11: NOT USED                              ");
00450   if ( (s & E_BIT11) == E_BIT11 ) printf("true\n");
00451   else printf("false\n");
00452 
00453   printf("10: Target reached:                       ");
00454   if ( (s & E_BIT10) == E_BIT10 ) printf("true\n");
00455   else printf("false\n");
00456 
00457   printf("09: Remote (?)                            ");
00458   if ( (s & E_BIT09) == E_BIT09 ) printf("true\n");
00459   else printf("false\n");
00460 
00461   printf("08: offset current measured (?)           ");
00462   if ( (s & E_BIT08) == E_BIT08 ) printf("true\n");
00463   else printf("false\n");
00464 
00465   printf("07: WARNING                               ");
00466   if ( (s & E_BIT07) == E_BIT07 ) printf("true\n");
00467   else printf("false\n");
00468 
00469   printf("06: switch on disable                     ");
00470   if ( (s & E_BIT06) == E_BIT06 ) printf("true\n");
00471   else printf("false\n");
00472 
00473   printf("05: quick stop                            ");
00474   if ( (s & E_BIT05) == E_BIT05 ) printf("true\n");
00475   else printf("false\n");
00476 
00477   printf("04: voltage enabled                       ");
00478   if ( (s & E_BIT04) == E_BIT04 ) printf("true\n");
00479   else printf("false\n");
00480 
00481   printf("03: FAULT                                 ");
00482   if ( (s & E_BIT03) == E_BIT03 ) printf("true\n");
00483   else printf("false\n");
00484 
00485   printf("02: operation enable                      ");
00486   if ( (s & E_BIT02) == E_BIT02 ) printf("true\n");
00487   else printf("false\n");
00488 
00489   printf("01: switched on                           ");
00490   if ( (s & E_BIT01) == E_BIT01 ) printf("true\n");
00491   else printf("false\n");
00492 
00493   printf("00: ready to switch on                    ");
00494   if ( (s & E_BIT00) == E_BIT00 ) printf("true\n");
00495   else printf("false\n");
00496   
00497   return(0);
00498 }
00499 
00500 
00501 
00502 
00508 int checkEPOSstate(){
00509 
00510   WORD w = 0x0;
00511   int n;
00512 
00513   if ( (n=readStatusword(&w)) < 0) {
00514     fprintf(stderr, " *** %s: readStatusword() returned %d **\n",
00515             __func__, n);
00516     return(-1);
00517   }
00518   
00519   /* state 'start' (0)
00520        fedc ba98  7654 3210
00521   w == x0xx xxx0  x000 0000 */
00522   if (   !bitcmp(w, E_BIT00 ) && !bitcmp(w, E_BIT01 ) 
00523       && !bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00524       && !bitcmp(w, E_BIT04) && !bitcmp(w, E_BIT05) 
00525       && !bitcmp(w, E_BIT06) && !bitcmp(w, E_BIT08) 
00526       && !bitcmp(w, E_BIT14) ) return(0);
00527       
00528   /* state 'not ready to switch on' (1)
00529           fedc ba98  7654 3210
00530      w == x0xx xxx1  x000 0000 */
00531   if (   !bitcmp(w, E_BIT00 ) && !bitcmp(w, E_BIT01 ) 
00532       && !bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00533       && !bitcmp(w, E_BIT04) && !bitcmp(w, E_BIT05) 
00534       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00535       && !bitcmp(w, E_BIT14) ) return(1);
00536 
00537 
00538   /* state 'switch on disabled' (2)
00539           fedc ba98  7654 3210
00540      w == x0xx xxx1  x100 0000 */
00541   if (   !bitcmp(w, E_BIT00 ) && !bitcmp(w, E_BIT01 ) 
00542       && !bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00543       && !bitcmp(w, E_BIT04) && !bitcmp(w, E_BIT05) 
00544       && bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00545       && !bitcmp(w, E_BIT14) ) return(2);
00546 
00547   /* state 'ready to switch on' (3)
00548           fedc ba98  7654 3210
00549      w == x0xx xxx1  x010 0001 */
00550   if (   bitcmp(w, E_BIT00 ) && !bitcmp(w, E_BIT01 ) 
00551       && !bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00552       && !bitcmp(w, E_BIT04) && bitcmp(w, E_BIT05) 
00553       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00554       && !bitcmp(w, E_BIT14) ) return(3);
00555       
00556   /* state 'switched on' (4)
00557           fedc ba98  7654 3210
00558      w == x0xx xxx1  x010 0011 */
00559   if (   bitcmp(w, E_BIT00 ) && bitcmp(w, E_BIT01 ) 
00560       && !bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00561       && !bitcmp(w, E_BIT04) && bitcmp(w, E_BIT05) 
00562       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00563       && !bitcmp(w, E_BIT14) ) return(4);
00564 
00565   /* state 'refresh' (5)
00566           fedc ba98  7654 3210
00567      w == x1xx xxx1  x010 0011 */
00568   if (   bitcmp(w, E_BIT00 ) && bitcmp(w, E_BIT01 ) 
00569       && !bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00570       && !bitcmp(w, E_BIT04) && bitcmp(w, E_BIT05) 
00571       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00572       && bitcmp(w, E_BIT14) ) return(5);
00573 
00574   /* state 'measure init' (6)
00575           fedc ba98  7654 3210
00576      w == x1xx xxx1  x011 0011 */
00577   if (   bitcmp(w, E_BIT00 ) && bitcmp(w, E_BIT01 ) 
00578       && !bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00579       && bitcmp(w, E_BIT04) && bitcmp(w, E_BIT05) 
00580       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00581       && bitcmp(w, E_BIT14) ) return(6);
00582 
00583   /* state 'operation enable' (7)
00584           fedc ba98  7654 3210
00585      w == x0xx xxx1  x011 0111 */
00586   if (   bitcmp(w, E_BIT00 ) && bitcmp(w, E_BIT01 ) 
00587       && bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00588       && bitcmp(w, E_BIT04) && bitcmp(w, E_BIT05) 
00589       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00590       && !bitcmp(w, E_BIT14) ) return(7);
00591 
00592   /* state 'quick stop active' (8)
00593           fedc ba98  7654 3210
00594      w == x0xx xxx1  x001 0111 */
00595   if (   bitcmp(w, E_BIT00 ) && bitcmp(w, E_BIT01 ) 
00596       && bitcmp(w, E_BIT02) && !bitcmp(w, E_BIT03) 
00597       && bitcmp(w, E_BIT04) && !bitcmp(w, E_BIT05) 
00598       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00599       && !bitcmp(w, E_BIT14) ) return(8);
00600 
00601   /* state 'fault reaction active (disabled)' (9)
00602           fedc ba98  7654 3210
00603      w == x0xx xxx1  x000 1111 */
00604   if (   bitcmp(w, E_BIT00 ) && bitcmp(w, E_BIT01 ) 
00605       && bitcmp(w, E_BIT02) && bitcmp(w, E_BIT03) 
00606       && !bitcmp(w, E_BIT04) && !bitcmp(w, E_BIT05) 
00607       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00608       && !bitcmp(w, E_BIT14) ) return(9);
00609 
00610   /* state 'fault reaction active (enabled)' (10)
00611           fedc ba98  7654 3210
00612      w == x0xx xxx1  x001 1111 */
00613   if (   bitcmp(w, E_BIT00 ) && bitcmp(w, E_BIT01 ) 
00614       && bitcmp(w, E_BIT02) && bitcmp(w, E_BIT03) 
00615       && bitcmp(w, E_BIT04) && !bitcmp(w, E_BIT05) 
00616       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00617       && !bitcmp(w, E_BIT14) ) return(10);
00618 
00619   /* state 'fault' (11)
00620           fedc ba98  7654 3210
00621      w == x0xx xxx1  x000 1000 */
00622   if (   !bitcmp(w, E_BIT00 ) && !bitcmp(w, E_BIT01 ) 
00623       && !bitcmp(w, E_BIT02) && bitcmp(w, E_BIT03) 
00624       && !bitcmp(w, E_BIT04) && !bitcmp(w, E_BIT05) 
00625       && !bitcmp(w, E_BIT06) && bitcmp(w, E_BIT08) 
00626       && !bitcmp(w, E_BIT14) ) return(11);
00627 
00628 
00629   // if we get down here, statusword has a unknown value!  
00630   fprintf(stderr, "WARNING: EPOS status word %#06x is an unkown state!\n", w );
00631   fprintf(stderr, "(function %s() in file %s, line %d)\n",
00632           __func__, __FILE__, __LINE__);
00633   
00634   return(-2);
00635 }
00636 
00637 
00638 /* pretty-print EPOS state */
00639 int printEPOSstate(){
00640   
00641   printf("\nEPOS is in state ");
00642 
00643   switch( checkEPOSstate() ) 
00644     {
00645     case 0: printf("start\n"); break;
00646     case 1: printf("Not ready to switch on.\n"); break;
00647     case 2: printf("Switch on disabled.\n"); break;
00648     case 3: printf("Ready to switch on.\n"); break;
00649     case 4: printf("Switched on.\n"); break;
00650     case 5: printf("Refresh.\n"); break;
00651     case 6: printf("Measure init.\n"); break;
00652     case 7: printf("Operation enable.\n"); break;
00653     case 8: printf("Quick stop active\n"); break;
00654     case 9: printf("Fault reaction active (disabled)\n"); break;
00655     case 10: printf("Fault reaction active (enabled)\n"); break;
00656     case 11: printf("FAULT\n"); break;
00657       
00658     default: 
00659       printf("UNKNOWN!\n");
00660       return(-1);
00661     }
00662   return(0);
00663 }
00664 
00665 
00666 /* change EPOS state according to firmware spec 8.1.3 */
00667 int changeEPOSstate(int state){
00668   WORD dw[2];
00669   int n;
00670   
00671   dw[1] = 0x0000; // high WORD of DWORD is not used here
00672   
00673   /* ! DO NOT READ OLD CONTROLWORD BACK, JUST SET THE BITS. It works
00674      this way, but does NOT work otherways! -- mh, 07.07.06
00675   */
00676 
00677   dw[0] = 0x0000;
00678 
00679   switch (state) 
00680     {
00681     case 0: //shutdown, controlword: 0xxx x110
00682       dw[0] &= ~E_BIT15;  // bit 15 ->0
00683       dw[0] |= E_BIT02;   // bit 02 ->1
00684       dw[0] |= E_BIT01;
00685       dw[0] &= ~E_BIT00;
00686       
00687       n = WriteObject(0x6040, 0x00, dw );
00688       if (n<0) {
00689         fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00690                 __func__, n, __FILE__, __LINE__);
00691         return(-1);
00692       }
00693       break;
00694 
00695     case 1: // switch on, controllword: 0xxx x111
00696       dw[0] &= ~E_BIT15;
00697       dw[0] |= E_BIT02;
00698       dw[0] |= E_BIT01;
00699       dw[0] |= E_BIT00;
00700 
00701       n = WriteObject(0x6040, 0x00, dw );
00702       if (n<0) {
00703         fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00704                 __func__, n, __FILE__, __LINE__);
00705         return(-1);
00706       }
00707       break;
00708 
00709     case 2: // disable voltage, controllword: 0xxx xx0x
00710       dw[0] &= ~E_BIT15;
00711       dw[0] &= ~E_BIT02;
00712 
00713       n = WriteObject(0x6040, 0x00, dw );
00714       if (n<0) {
00715         fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00716                 __func__, n, __FILE__, __LINE__);
00717         return(-1);
00718       }
00719       break;
00720 
00721     case 3: // quick stop, controllword: 0xxx x01x
00722       dw[0] &= ~E_BIT15;
00723       dw[0] &= ~E_BIT02;
00724       dw[0] |= E_BIT02;
00725 
00726       n = WriteObject(0x6040, 0x00, dw );
00727       if (n<0) {
00728         fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00729                 __func__, n, __FILE__, __LINE__);
00730         return(-1);
00731       }
00732       break;
00733 
00734     case 4: // disable operation, controllword: 0xxx 0111
00735       dw[0] &= ~E_BIT15;
00736       dw[0] &= ~E_BIT03;
00737       dw[0] |= E_BIT02;
00738       dw[0] |= E_BIT01;
00739       dw[0] |= E_BIT00;
00740 
00741       n = WriteObject(0x6040, 0x00, dw );
00742       if (n<0) {
00743         fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00744                 __func__, n, __FILE__, __LINE__);
00745         return(-1);
00746       }
00747       break;
00748 
00749 
00750     case 5: // enable operation, controllword: 0xxx 1111
00751       dw[0] &= ~E_BIT15;
00752       dw[0] |= E_BIT03;
00753       dw[0] |= E_BIT02;
00754       dw[0] |= E_BIT01;
00755       dw[0] |= E_BIT00;
00756 
00757       n = WriteObject(0x6040, 0x00, dw );
00758       if (n<0) {
00759         fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00760                 __func__, n, __FILE__, __LINE__);
00761         return(-1);
00762       }
00763       break;
00764 
00765 
00766 
00767     case 6: // fault reset, controllword: 1xxx xxxx
00768 
00769       //dw[0] |= E_BIT15; this is according to firmware spec 8.1.3,
00770       //but does not work!
00771       dw[0] |= E_BIT07; // this is according to firmware spec 14.1.57
00772                         // and IS working!
00773       
00774       
00775 /*       WORD estatus = 0x0; */
00776 /*       if ( ( n = readStatusword(&estatus) ) < 0) checkEPOSerror(); */
00777 /*       printEPOSstatusword(estatus); */
00778 
00779 
00780       n = WriteObject(0x6040, 0x00, dw );
00781       if (n<0) {
00782         fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00783                 __func__, n, __FILE__, __LINE__);
00784         return(-1);
00785       }
00786 
00787 /*       if ( ( n = readStatusword(&estatus) ) < 0) checkEPOSerror(); */
00788 /*       printEPOSstatusword(estatus); */
00789 
00790       break;
00791       
00792 
00793     default:
00794       fprintf(stderr, "ERROR: demanded state %d is UNKNOWN!\n", state);
00795       return(-1);
00796     }
00797   return(0);
00798 }
00799 
00800 
00801 
00802 
00803 
00804 /* returns software version as HEX  --  14.1.33*/
00805 int readSWversion(){
00806   WORD *answer = NULL;
00807   int n = 0;
00808   
00809   if ((n = checkEPOS())<0) return n;
00810   checkPtr(&answer);
00811   
00812   if ( (n =  ReadObject(0x2003, 0x01, &answer)) <0){
00813     
00814     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
00815             __func__, n);
00816     return(-1);
00817   }
00818   
00819 
00820   // check error code
00821   checkEPOSerror();
00822 
00823 #ifdef DEBUG
00824   printf("=x=> SW-Version: %x\n", answer[3]);
00825 #endif
00826   
00827   n =  (int) answer[3];
00828 
00829   free(answer); // memory is allocated by readAnswer()
00830   return(n);
00831 }
00832 
00833 
00834 
00835 
00836 
00837 
00838 /* read digital input functionality polarity -- firmware spec 14.1.47 */
00839 int readDInputPolarity(WORD* w){
00840   
00841   WORD *answer = NULL;
00842   int n = 0;
00843   
00844   checkEPOS();
00845   checkPtr(&answer);
00846   
00847   if ( (n =  ReadObject(0x2071, 0x03, &answer)) <0){
00848     
00849     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
00850             __func__, n);
00851     return(-1);
00852   }
00853   
00854   
00855   // check error code
00856   checkEPOSerror();
00857 
00858 #ifdef DEBUG
00859   printf("==> polarity mask: %x\n", answer[3]);
00860 #endif
00861 
00862   *w = answer[3];
00863 
00864 
00865   free(answer); // memory is allocated by readAnswer()
00866   return(0);
00867 }
00868 
00869 
00870 
00871 
00872 
00873 /* set home switch polarity -- firmware spec 14.1.47 */
00874 int setHomePolarity(int pol){
00875   WORD* answer = NULL;
00876   WORD mask = 0x00;
00877   WORD dw[2] = {0x0, 0x0};
00878   int n = 0;
00879   
00880   
00881   if (pol!=0 && pol!=1) {
00882     fprintf(stderr, "ERROR: polarity must be 0 (hight active) or 1 (low active)\n");
00883     return(-1);
00884   }
00885 
00886   if ((n = checkEPOS())<0) return n;
00887   checkPtr(&answer);
00888   
00889   // read present functionalities polarity mask
00890   if ( readDInputPolarity(&mask) ) {
00891     fprintf(stderr, "\aERROR while reading digital input polarity!\n");
00892     return(-2);
00893   }
00894 
00895   
00896   // set bit 2 (==home switch) to 0 or 1:
00897   if (pol == 0)      mask &= ~E_BIT02;
00898   else if (pol == 1) mask |= E_BIT02;
00899 
00900 
00901 
00902   dw[1] = 0x0000; // high WORD of DWORD is not used here
00903   dw[0] = mask;
00904   
00905   n = WriteObject(0x2071, 0x03, dw);
00906   if (n<0) {
00907     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
00908             __func__, n, __FILE__, __LINE__);
00909     return(-1);
00910   }
00911   
00912   return(0);
00913 }
00914 
00915 
00916 
00917 
00918 
00919 
00920 /* read EPOS control word (firmware spec 14.1.57) */
00921 int readControlword(WORD *w){
00922 
00923   WORD *answer = NULL;
00924   int n = 0;
00925   
00926   if ((n = checkEPOS())<0) return n;
00927   checkPtr(&answer);
00928   
00929   if ( (n =  ReadObject(0x6040, 0x00, &answer)) <0){
00930     
00931     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
00932             __func__, n);
00933     free(answer); // memory is allocated by readAnswer()
00934     return(-1);
00935   }
00936   
00937   // check error code
00938   checkEPOSerror();
00939   
00940 #ifdef DEBUG
00941   printf("==> EPOS control word: %#06x\n", answer[3]);
00942 #endif
00943   *w = answer[3];
00944   free(answer); // memory is allocated by readAnswer()
00945   return(0);
00946 }
00947 
00948 
00949 
00950 /* pretty-print Controlword */
00951 int printEPOScontrolword(WORD s){
00952   printf("\nmeaning of EPOS controlword %#06x is:\n", s);
00953   // bit 15..11 not in use
00954   // bit 10, 9 reserved
00955   printf("  HALT:                                 ");
00956   if ( (s & E_BIT08) == E_BIT08 ) printf("true\n");
00957   else printf("false\n");
00958 
00959   printf("  fault reset                           ");
00960   if ( (s & E_BIT07) == E_BIT07 ) printf("true\n");
00961   else printf("false\n");
00962 
00963   printf("  Op mode specific                      ");
00964   if ( (s & E_BIT06) == E_BIT06 ) printf("true\n");
00965   else printf("false\n");
00966 
00967   printf("  Op mode specific                      ");
00968   if ( (s & E_BIT05) == E_BIT05 ) printf("true\n");
00969   else printf("false\n");
00970 
00971   printf("  Op mode specific                      ");
00972   if ( (s & E_BIT04) == E_BIT04 ) printf("true\n");
00973   else printf("false\n");
00974 
00975   printf("  enable operation                      ");
00976   if ( (s & E_BIT03) == E_BIT03 ) printf("true\n");
00977   else printf("false\n");
00978 
00979   printf("  quick stop                            ");
00980   if ( (s & E_BIT02) == E_BIT02 ) printf("true\n");
00981   else printf("false\n");
00982 
00983   printf("  enable voltage                        ");
00984   if ( (s & E_BIT01) == E_BIT01 ) printf("true\n");
00985   else printf("false\n");
00986 
00987   printf("  switch on                             ");
00988   if ( (s & E_BIT00) == E_BIT00 ) printf("true\n");
00989   else printf("false\n");
00990   
00991   return(0);
00992 }
00993 
00994 
00995 
00996 
00997 
00998 
00999 /* set mode of operation --- 14.1.59 */
01000 int setOpMode(int m){
01001  
01002   WORD dw[2] = {0x0, 0x0};
01003   int n = 0;
01004 
01005   dw[1] = 0x0000; // high WORD of DWORD is not used here
01006   dw[0] = m;
01007 
01008   n = WriteObject(0x6060, 0x00, dw );
01009   if (n<0) {
01010     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01011             __func__, n, __FILE__, __LINE__);
01012     return(-1);
01013   }
01014   
01015   
01016   return(0);
01017 }
01018 
01019 
01020 
01021 
01027 int readOpMode(){
01028   WORD *answer = NULL;
01029   //short int *i;
01030   int8_t aa;
01031   int n = 0;
01032   
01033   if ( (n =  ReadObject(0x6061, 0x00, &answer)) <0){
01034     
01035     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01036             __func__, n);
01037     free(answer); // memory is allocated by readAnswer()
01038     return(0);
01039   }
01040  
01041  
01042   //w = answer[3];
01043   aa = answer[3];
01044   free(answer);
01045   // check error code
01046   checkEPOSerror();
01047   
01048   /*
01049   // return value is a 8bit signed integer. To convert it to a 16bit
01050   // signed int, move bit 7 (old signum) to bit 15 (new signum). Set
01051   // bit 7 to 0
01052   if ((w & (~E_BIT07)) == 0xFFFF){     //bit 07 is set
01053     w &= ~E_BIT07;    // set bit  7 to '0'
01054     w |= E_BIT15;     // set bit 15 to '1'
01055     
01056   }
01057   // the compiler must give a warning about signedness here, but it is
01058   // ok! Don't know how to suppress it...
01059   i = &w;
01060 
01061   */
01062   // give warning, if internal mode is used
01063   if (aa<0) fprintf(stderr,"WARNING: EPOS is set to internal mode of operation (%hd).\n Make sure that this was really intended!\n", aa);
01064 
01065   //return(*i);
01066   return(aa);
01067 }
01068 
01069 
01070 
01071 
01072 /* read demand position; 14.1.61 */
01073 int readDemandPosition(long *pos){
01074   WORD *answer = NULL;
01075   int n = 0;
01076   
01077   if ((n = checkEPOS())<0) return n;
01078   checkPtr(&answer);
01079   
01080 
01081   if ( (n =  ReadObject(0x6062, 0x00, &answer)) <0){
01082     
01083     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01084             __func__, n);
01085     free(answer); // memory is allocated by readAnswer()
01086     return(-1);
01087   }
01088   // check error code
01089   checkEPOSerror();
01090 
01091   // return value is a 32bit integer (==long int)
01092   *pos = answer[3]  | (answer[4] << 16);
01093   free(answer);
01094 #ifdef DEBUG
01095   printf("==> EPOS actual position: %ld\n", *pos);
01096 #endif
01097   return(0);
01098 }
01099 
01100 
01101 
01102 
01108 int readActualPosition(long *pos){
01109   WORD *answer = NULL;
01110   int n = 0;
01111   
01112   if ((n = checkEPOS())<0) return n;
01113   checkPtr(&answer);
01114   
01115 
01116   if ( (n =  ReadObject(0x6064, 0x00, &answer)) <0){
01117     
01118     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01119             __func__, n);
01120     free(answer); // memory is allocated by readAnswer()
01121     return(-1);
01122   }
01123   // check error code
01124   checkEPOSerror();
01125 
01126   // return value is a 32bit integer (==long int)
01127   *pos = answer[3]  | (answer[4] << 16);
01128   free(answer);
01129 #ifdef DEBUG
01130   printf("==> %s(): EPOS actual position: %ld\n", __func__, *pos);
01131 #endif
01132 
01133   return(0);
01134 }
01135   
01136 
01137 
01138 /* read position window; 14.1.64 */
01139 int readPositionWindow(unsigned long int *pos){
01140   WORD *answer = NULL;
01141   int n = 0;
01142   
01143   if ((n = checkEPOS())<0) return n;
01144   checkPtr(&answer);
01145   
01146   if ( (n =  ReadObject(0x6067, 0x00, &answer)) <0){
01147     
01148     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01149             __func__, n);
01150     free(answer); // memory is allocated by readAnswer()
01151     return(-1);
01152   }
01153   // check error code
01154   checkEPOSerror();
01155   
01156   // return value is a 32bit integer (==long int)
01157   *pos = answer[3]  | (answer[4] << 16);
01158   free(answer);
01159   
01160 #ifdef DEBUG
01161   printf("==> %s(): EPOS position window is %ld\n", __func__, *pos);
01162 #endif
01163 
01164   return(0);
01165 }
01166 
01167 
01168 /* write  position window; 14.1.64 */
01169 int writePositionWindow(unsigned long int val){
01170 
01171   WORD dw[2];
01172   int n = 0;
01173 
01174   
01175   // write intended position window
01176   dw[0] = (WORD) (val & 0x0000FFFF);
01177   dw[1] = (WORD) (val >> 16) ;
01178 
01179   n = WriteObject(0x6067, 0x00, dw );
01180   if (n<0) {
01181     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01182             __func__, n, __FILE__, __LINE__);
01183     return(-1);
01184   }
01185   checkEPOSerror();
01186 
01187   return(0);
01188 }
01189 
01190 
01191 
01192 
01193 
01194 
01195 
01196 
01197 /* read demand position; 14.1.67 */
01198 int readDemandVelocity(long *val){
01199   WORD *answer = NULL;
01200   int n = 0;
01201   
01202   if ((n = checkEPOS())<0) return n;
01203   checkPtr(&answer);
01204   
01205 
01206   if ( (n =  ReadObject(0x606b, 0x00, &answer)) <0){
01207     
01208     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01209             __func__, n);
01210     free(answer); // memory is allocated by readAnswer()
01211     return(-1);
01212   }
01213   // check error code
01214   checkEPOSerror();
01215 
01216   // return value is a 32bit integer (==long int)
01217   *val = answer[3]  | (answer[4] << 16);
01218    
01219 #ifdef DEBUG
01220   printf("==> EPOS demand velocity: %ld\n", *val);
01221 #endif
01222 
01223   return(0);
01224 }
01225 
01226 
01227 
01228 /* read actual position; 14.1.68 */
01229 int readActualVelocity(long *val){
01230   WORD *answer = NULL;
01231   int n = 0;
01232   
01233   if ((n = checkEPOS())<0) return n;
01234   checkPtr(&answer);
01235   
01236 
01237   if ( (n =  ReadObject(0x606c, 0x00, &answer)) <0){
01238     
01239     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01240             __func__, n);
01241     free(answer); // memory is allocated by readAnswer()
01242     return(-1);
01243   }
01244   // check error code
01245   checkEPOSerror();
01246 
01247   // return value is a 32bit integer (==long int)
01248   *val = answer[3]  | (answer[4] << 16);
01249     
01250 #ifdef DEBUG
01251   printf("==> EPOS actual velocity: %ld\n", *val);
01252 #endif
01253 
01254   return(0);
01255 }
01256   
01257 
01258 
01259 
01260 
01261 
01271 int readActualCurrent(short int *val){
01272   WORD *answer = NULL;
01273   int n = 0;
01274   
01275   if ((n = checkEPOS())<0) return n;
01276   checkPtr(&answer);
01277   
01278 
01279   if ( (n =  ReadObject(0x6078, 0x00, &answer)) <0){
01280     
01281     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01282             __func__, n);
01283     free(answer); // memory is allocated by readAnswer()
01284     return(-1);
01285   }
01286   // check error code
01287   checkEPOSerror();
01288 
01289   *val = answer[3];
01290   free(answer);
01291 #ifdef DEBUG
01292   printf("==> EPOS actual current: %dmA\n", *val);
01293 #endif
01294 
01295   return(0);
01296 }
01297   
01298 
01299 
01307 int readTargetPosition(long *val){
01308   WORD *answer = NULL;
01309   int n = 0;
01310   
01311   if ((n = checkEPOS())<0) return n;
01312   checkPtr(&answer);
01313   
01314 
01315   if ( (n =  ReadObject(0x607a, 0x00, &answer)) <0){
01316     
01317     fprintf(stderr, " *** %s: ReadObject() returned %d **\n",
01318             __func__, n);
01319     free(answer); // memory is allocated by readAnswer()
01320     return(-1);
01321   }
01322   // check error code
01323   checkEPOSerror();
01324 
01325   // return value is a 32bit integer (==long int)
01326   *val = (DWORD) answer[3]  | (answer[4] << 16);
01327   free(answer);
01328 #ifdef DEBUG
01329   printf("==> EPOS target position: %ld\n", *val);
01330 #endif
01331 
01332   return(0);
01333 }
01334 
01335 
01336 
01337 
01338 
01339 
01340 
01349 int readDeviceName(char *str){
01350   WORD *answer = NULL;
01351   int n = 0;
01352 
01353   if ((n = checkEPOS())<0) return n;
01354   memset(&answer, 0, sizeof(answer) );
01355   
01356   
01357   if ( ( n = ReadObject(0x1008, 0x00, &answer) ) < 0) {
01358     printf(" *** readObject returned %d at %s, line %d ***\n", 
01359            n, __func__, __LINE__);
01360   }
01361   
01362 
01363  
01364   str[0] = (answer[3] & 0x00FF);
01365   str[1] = (answer[3] & 0xFF00) >> 8;
01366   str[2] = (answer[4] & 0x00FF);
01367   str[3] = (answer[4] & 0xFF00) >> 8;
01368   str[4] = '\0';  // end of string
01369   
01370 #ifdef DEBUG
01371   printf("%s: %s \n", __func__, str); 
01372 #endif
01373 
01374 
01375   free( answer ); // memory is allocated by readAnswer()
01376   return(0);
01377 }
01378 
01379 
01380 
01381 
01382 
01383 
01384 /* firmware spec 14.1.35 */
01385 int readRS232timeout(){
01386 
01387   WORD *answer = NULL;
01388   int n = 0;
01389   
01390   if ((n = checkEPOS())<0) return n;
01391   
01392   if ( ( n = ReadObject(0x2005, 0x00, &answer) ) < 0) {
01393     printf(" *** readObject returned %d at %s, line %d ***\n", 
01394            n, __func__, __LINE__);
01395   }
01396   
01397 #ifdef DEBUG
01398   printf("%s: RS232 timeout is %d msec\n", __func__, answer[3] );
01399 #endif
01400 
01401   n =  (int) answer[3];
01402   free(answer);  // memory is allocated by ReadAnswer()
01403   return( n );
01404 }
01405 
01406 
01407 // Added by mmn, 2010-10-04
01408 // todo: Split this into two functions: speed and acc.
01409 int set_speed_profile( unsigned int max_velocity, // rpm
01410                        unsigned int acceleration, // rpm/s
01411                        unsigned int deceleration, // rpm/s
01412                        bool trapezoidal )         
01413 {
01414   WORD dw[2] = {0x0, 0x0};
01415   int n;
01416   
01417   // Write 0 (default) fpr trapezoidal profile, 1 for sinusoidal profile.
01418   if (trapezoidal)
01419     dw[1] = 0;
01420   else
01421     dw[1] = 1;
01422   n = WriteObject( 0x6086, 0x00, dw );
01423   if (n<0) {
01424     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01425             __func__, n, __FILE__, __LINE__);
01426     return(-1);
01427   }
01428 
01429   // Set desired velocity after acceleration is completed
01430   //*dw = max_velocity;
01431   dw[0] = (WORD) (max_velocity & 0x0000FFFF);
01432   dw[1] = (WORD) (max_velocity >> 16) ;
01433   n = WriteObject( 0x6081, 0x00, dw ); //0x60FF for Profile Velocity Mode?
01434   if (n<0) {
01435     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01436             __func__, n, __FILE__, __LINE__);
01437     return(-1);
01438   }
01439 
01440   dw[0] = (WORD) (acceleration & 0x0000FFFF);
01441   dw[1] = (WORD) (acceleration >> 16) ;
01442   n = WriteObject( 0x6083, 0x00, dw );
01443   if (n<0) {
01444     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n",
01445             __func__, n, __FILE__, __LINE__);
01446     return(-1);
01447   }
01448 
01449   dw[0] = (WORD) (deceleration & 0x0000FFFF);
01450   dw[1] = (WORD) (deceleration >> 16) ;
01451   n = WriteObject( 0x6084, 0x00, dw );
01452   if (n<0) {
01453     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n",
01454             __func__, n, __FILE__, __LINE__);
01455     return(-1);
01456   }
01457 
01458   return 0;
01459 }
01460 
01461 
01462 /* run the HomingMode, get the coordinate system zeropoint correct 
01463 
01464  this is done as shown in "EPOS Application Note: device Programming,
01465  3: Homing Mode"
01466 
01467 */
01468 int doHoming(int method, long int start){
01469 
01470   WORD dw[2] = {0x0000, 0x0000};
01471   WORD w = 0x0000;
01472   int n, status=0;
01473   //move motor to a pre-defined position before the reference
01474   //point. This will speed-up things if the coordinates are not too
01475   //wrong.
01476 
01477   // extra setup as done by Jonatan: set software limits
01478   {
01479     // Set no software limits:
01480     /* dw[1] = 0x8000; */
01481     /* dw[0] = 0x0000; */
01482     /* n = WriteObject(0x607d, 0x01, dw ); */
01483     
01484     //set software limits to +-7490
01485     {
01486       //WORD dw[2];
01487       //0001 1101 0100 0010 = +7490
01488       //1110 0010 1011 1110 = -7490?
01489 
01490       dw[1] = 0xFFFF;
01491       dw[0] = 0xE2BE;
01492       /* int32_t d = 0; */
01493       /* d += dw[1] << 16; */
01494       /* d += dw[0]; */
01495       /* printf( "test d = %d\n", d );     */
01496       n = WriteObject(0x607d, 0x01, dw );
01497 
01498       dw[1] = 0x0000;
01499       dw[0] = 0x1D42;
01500       /* d = 0; */
01501       /* d += dw[1] << 16; */
01502       /* d += dw[0]; */
01503       /* printf( "test d = %d\n", d );     */
01504       n = WriteObject(0x607d, 0x02, dw );
01505     }
01506     
01507   }  
01508 
01509   
01510   if ( moveAbsolute(start) ) {
01511     fprintf(stderr, "ERROR: could not move to homing starting point!\n");
01512     fprintf(stderr, "       (problem at %s; %s line %d)\n",
01513             __func__, __FILE__, __LINE__);
01514     return(-1);
01515   }
01516   // wait for positioning to finish, set timeout to approx. 30sec
01517   // CAUSES BIG PROBLEMS IF WE DO NOT WAIT!
01518   waitForTarget(30);
01519   //monitorStatus();
01520 
01521      
01522   // switch to homing mode
01523   if( setOpMode(E_HOMING) ) {
01524     fprintf(stderr, "ERROR: problem at %s; %s line %d\n",
01525             __func__, __FILE__, __LINE__);
01526     return(-1);
01527   }
01528 
01529   
01530   // homing speeds are left at default values.. (firmware 14.1.86)
01531   
01532 
01533   // set homing method
01534   dw[0] = method; // NO hex number here! 
01535   dw[1] = 0x0000; // high WORD of DWORD is not used here
01536   n = WriteObject(0x6098, 0x00, dw );
01537   if (n<0) {
01538     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01539             __func__, n, __FILE__, __LINE__);
01540     return(-1);
01541   }
01542   checkEPOSerror();
01543     
01544 
01545   // switch on
01546   dw[0] = 0x000f;
01547   dw[1] = 0x0000; // high WORD of DWORD is not used here
01548   n = WriteObject(0x6040, 0x00, dw );
01549   if (n<0) {
01550     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01551             __func__, n, __FILE__, __LINE__);
01552     return(-1);
01553   }
01554   // start homing mode
01555   dw[0] = 0x001f;
01556   dw[1] = 0x0000; // high WORD of DWORD is not used here
01557   n = WriteObject(0x6040, 0x00, dw );
01558   if (n<0) {
01559     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01560             __func__, n, __FILE__, __LINE__);
01561     return(-1);
01562   }
01563   
01564 
01565   checkEPOSerror();
01566   
01567 
01568   //read/print status
01569   status = monitorHomingStatus();
01570   if ( status ) {
01571     // something was wrong during homing...
01572     if (status == 1) {
01573       fprintf(stderr, "We did more that 2 complete turns without finding the home switch!\n");
01574       fprintf(stderr, "\aDEVICE IS BROKEN!!!\n");
01575       return (-2); //exit(2);
01576     }
01577     else {
01578       fprintf(stderr, "got %d as response from monitorHoming()...this is BAD!\n", status);
01579       fprintf(stderr, "[ %s: at %s, line %d ]\n", 
01580               __func__, __FILE__, __LINE__);
01581     }
01582   }
01583 
01584   readStatusword(&w);
01585   if ( (w & E_BIT13) == E_BIT13) {
01586     fprintf(stderr, "\a *** got a HomingError! ***\n");
01587     return(-1);
01588   }
01589   
01590   if ( (w & E_BIT12)  == E_BIT12) {
01591     //printf("homing finished!\n");
01592     return(0);
01593   } else {
01594     //  can this be reached? position finished, no homing error but
01595     //  homing NOT finished? I guess not..
01596     return(-5);
01597   }
01598 }
01599 
01600 
01601 
01602 
01603 
01604 
01605 int moveRelative(long int steps){
01606 
01607   WORD dw[2];
01608   int n = 0;
01609 
01610   // check, if we are in Profile Position Mode
01611   if (readOpMode() != E_PROFPOS) {
01612     if( setOpMode(E_PROFPOS) ) {
01613       fprintf(stderr, "ERROR: problem at %s; %s line %d\n",
01614               __func__, __FILE__, __LINE__);
01615       return(-1);
01616     }
01617   }
01618 
01619 
01620   // write intended target position
01621   // firmware 14.1.70
01622   dw[0] = (WORD) (steps & 0x0000FFFF);
01623   dw[1] = (WORD) (steps >> 16) ;
01624 
01625   n = WriteObject(0x607A, 0x00, dw );
01626   if (n<0) {
01627     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01628             __func__, n, __FILE__, __LINE__);
01629     return(-1);
01630   }
01631   checkEPOSerror();
01632 
01633   // switch to relative positioning BY WRITING TO CONTROLWORD, finish
01634   // possible ongoing operation first!  ->maxon applicattion note:
01635   // device programming 2.1
01636   dw[0] = 0x005f;
01637   dw[1] = 0x0000; // high WORD of DWORD is not used here
01638   n = WriteObject(0x6040, 0x00, dw );
01639   if (n<0) {
01640     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01641             __func__, n, __FILE__, __LINE__);
01642     return(-1);
01643   }
01644   checkEPOSerror();
01645   
01646   
01647   return(0);
01648 }
01649 
01650 
01651 
01652 int moveAbsolute(long int steps){
01653 
01654   WORD dw[2];
01655   int n = 0;
01656 
01657 #ifdef DEBUG
01658   printf("-> %s(): will move to %ld (%#010lx)\n", __func__, steps, steps);
01659 #endif
01660 
01661   if (false)
01662   {
01663     // check, if we are in Profile Position Mode
01664     //todo Do we really have to check the mode in each call to moveAbsolute?
01665     if (readOpMode() != E_PROFPOS) {
01666       if( setOpMode(E_PROFPOS) ) {
01667         fprintf(stderr, "ERROR: problem at %s; %s line %d\n",
01668                 __func__, __FILE__, __LINE__);
01669         return(-1);
01670       }
01671     }
01672 #ifdef DEBUG
01673     printf("-> OpMode is (now) 'Profile Position Mode'. That's OK!\n");
01674 #endif
01675   }
01676 
01677   // write intended target position, is signed 32bit int
01678   // firmware 14.1.70
01679   dw[0] = (WORD) (steps & 0x0000FFFF);
01680   dw[1] = (WORD) (steps >> 16) ;
01681 
01682 #ifdef DEBUG
01683   printf("-> %s(): dw[0,1] = %#06x  %#06x\n", __func__, dw[0], dw[1]);
01684 #endif
01685 
01686   n = WriteObject(0x607A, 0x00, dw );
01687   if (n<0) {
01688     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01689             __func__, n, __FILE__, __LINE__);
01690     return(-1);
01691   }
01692   checkEPOSerror();
01693 
01694   // switch to absolute positioning, cancel possible ongoing operation
01695   // first!  ->maxon application note: device programming 2.1
01696   dw[0] = 0x3f;
01697   dw[1] = 0x0000; // high WORD of DWORD is not used here
01698   n = WriteObject(0x6040, 0x00, dw );
01699   if (n<0) {
01700     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01701             __func__, n, __FILE__, __LINE__);
01702     return(-1);
01703   }
01704   checkEPOSerror();
01705   
01706  
01707   return(0);
01708 }
01709 
01710 
01711 int moveVelocity(int32_t steps){
01712 
01713   WORD dw[2];
01714   int n = 0;
01715 
01716 #ifdef DEBUG
01717   printf("-> %s(): will move to %ld (%#010lx)\n", __func__, steps, steps);
01718 #endif
01719 
01720 
01721   // check if we are in Profile Velocity Mode
01722   //todo Do we really have to check the mode in each call?
01723   int current_mode;
01724   if (current_mode = readOpMode() != E_PROFVEL) {
01725     if( setOpMode(E_PROFVEL) ) {
01726       fprintf(stderr, "ERROR: problem at %s; %s line %d\n",
01727               __func__, __FILE__, __LINE__);
01728       return(-1);
01729     }
01730   }
01731 #ifdef DEBUG
01732   printf("-> OpMode is (now) 'Profile Velocity Mode'. That's OK!\n");
01733 #endif
01734 
01735 
01736   return 0;
01737   
01738   // write intended target velocity, is signed 32bit int
01739   dw[0] = (WORD) (steps & 0x0000FFFF);
01740   dw[1] = (WORD) (steps >> 16) ;
01741 
01742 #ifdef DEBUG
01743   printf("-> %s(): dw[0,1] = %#06x  %#06x\n", __func__, dw[0], dw[1]);
01744 #endif
01745 
01746   n = WriteObject(0x60FF, 0x00, dw );
01747   if (n<0) {
01748     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01749             __func__, n, __FILE__, __LINE__);
01750     return(-1);
01751   }
01752   checkEPOSerror();
01753 
01754   // switch to absolute positioning, cancel possible ongoing operation
01755   // first!  ->maxon application note: device programming 2.1
01756   dw[0] = 0x3f;
01757   dw[1] = 0x0000; // high WORD of DWORD is not used here
01758   n = WriteObject(0x6040, 0x00, dw );
01759   if (n<0) {
01760     fprintf(stderr, "%s: writeObject() returned %d at %s, line %d\n", 
01761             __func__, n, __FILE__, __LINE__);
01762     return(-1);
01763   }
01764   checkEPOSerror();
01765   
01766  
01767   return(0);
01768 }
01769 
01770 
01771 
01772 // monitor device status
01773 int monitorStatus(){
01774   int  n;
01775   long int postarget, posactual, veldemand, velactual;
01776   short curactual;
01777   WORD status;
01778   //  printf("\nEPOS operating figures:\n");
01779   int i = 0;
01780   do {
01781     i++;
01782     if  ( (n=readTargetPosition( &postarget ) ) ){
01783       printf("ERROR while readActualPosition() [%d]\n", n);
01784       break;
01785     }
01786 /*     if  ( (n=readDemandPosition( &posdemand ) ) ){ */
01787 /*       printf("ERROR while readDemandPosition() [%d]\n", n); */
01788 /*       break; */
01789 /*     } */
01790     if  ( (n=readActualPosition( &posactual ) ) ){
01791       printf("ERROR while readActualPosition() [%d]\n", n);
01792       break;
01793     }
01794     if  ( (n=readDemandVelocity( &veldemand ) ) ){
01795       printf("ERROR while readDemandVelocity() [%d]\n", n);
01796       break;
01797     }
01798     if  ( (n=readActualVelocity( &velactual ) ) ){
01799       printf("ERROR while readActualVelicity() [%d]\n", n);
01800       break;
01801     }
01802     if  ( (n=readActualCurrent( &curactual ) ) ){
01803       printf("ERROR while readActualCurrent() [%d]\n", n);
01804       break;
01805     }
01806     
01807     /* printf("\rEPOS: pos=%+10ld |%+10ld (%ld to go); v= %+4ld | %+4ld[rpm]; I=%+4dmA", */
01808     /*        postarget, posactual,postarget-posactual,  */
01809     /*        veldemand, velactual, curactual); */
01810     /* fflush(stdout); */
01811     
01812     readStatusword(&status);
01813   } while ( ( status & E_BIT10) != E_BIT10) ; // bit 10 says: target reached!
01814   
01815   // update values a last time to get a nicer output:
01816   i++;
01817   if  ( (n=readTargetPosition( &postarget ) ) ){
01818     printf("ERROR while readActualPosition() [%d]\n", n);
01819     
01820   }
01821   if  ( (n=readActualPosition( &posactual ) ) ){
01822     printf("ERROR while readActualPosition() [%d]\n", n);
01823   }
01824   if  ( (n=readDemandVelocity( &veldemand ) ) ){
01825     printf("ERROR while readDemandVelocity() [%d]\n", n);
01826   }
01827   if  ( (n=readActualVelocity( &velactual ) ) ){
01828     printf("ERROR while readActualVelicity() [%d]\n", n);
01829   }
01830   if  ( (n=readActualCurrent( &curactual ) ) ){
01831     printf("ERROR while readActualCurrent() [%d]\n", n);
01832   }
01833   
01834   /* printf("\r%d EPOS: pos=%+10ld |%+10ld (%ld to go); v= %+4ld | %+4ld[rpm]; I=%+4dmA\n", */
01835   /*        i, postarget, posactual,postarget-posactual,  */
01836   /*        veldemand, velactual, curactual); */
01837   /* printf("target reached\n"); */
01838   
01839   return(0);
01840 }
01841 
01842 
01843 
01844 int monitorHomingStatus(){
01845   int  n;
01846   long int posactual, velactual;
01847   short curactual;
01848   WORD status = 0x0;
01849   //printf("\nEPOS operating figures:\n");
01850   int i = 0;
01851   do {
01852     i++;
01853     if  ( (n=readActualPosition( &posactual ) ) ){
01854       printf("ERROR while readActualPosition() [%d]\n", n);
01855       break;
01856     }
01857     if  ( (n=readActualVelocity( &velactual ) ) ){
01858       printf("ERROR while readActualVelicity() [%d]\n", n);
01859       break;
01860     }
01861     if  ( (n=readActualCurrent( &curactual ) ) ){
01862       printf("ERROR while readActualCurrent() [%d]\n", n);
01863       break;
01864     }
01865 
01866     if (n=readStatusword(&status)){
01867       printf("ERROR while readStatusword() [%d]\n", n);
01868       break;
01869     }
01870 
01871     
01872     /* printf("\r%d EPOS: pos=%+10ld; v =  %+4ldrpm I=%+3dmA status = %#06x ", */
01873     /*        i,  posactual, velactual, curactual, status); */
01874            
01875     fflush(stdout);
01876     
01877     //    readStatusword(&status);
01878     if (n=readStatusword(&status)){
01879       printf("ERROR while readStatusword() [%d]\n", n);
01880       break;
01881     }
01882 
01883     
01884     if ( (status & E_BIT13) == E_BIT13) {
01885       printf("\aHOMING ERROR!\n");
01886       return(-2);
01887     }
01888 
01889   } while ( 
01890            ( ( status & E_BIT10) != E_BIT10)
01891            && ( (status & E_BIT12) != E_BIT12)
01892            );
01893   // bit 10 says: target reached!, bit 12: homing attained
01894   //printEPOSstatusword(status);
01895 
01896   i++;
01897   if  ( (n=readActualPosition( &posactual ) ) ){
01898     printf("ERROR while readActualPosition() [%d]\n", n);
01899   }
01900   if  ( (n=readActualVelocity( &velactual ) ) ){
01901     printf("ERROR while readActualVelicity() [%d]\n", n);
01902   }
01903   if  ( (n=readActualCurrent( &curactual ) ) ){
01904     printf("ERROR while readActualCurrent() [%d]\n", n);
01905   }
01906   
01907   readStatusword(&status);
01908   
01909   
01910   /* printf("\r%d EPOS: pos=%+10ld; v =  %+4ldrpm I=%+3dmA status = %#06x\n", */
01911   /*        i,  posactual, velactual, curactual, status); */
01912   /* printf("homing finished! Position should now be '0'\n"); */
01913   
01914   return(0);
01915 }
01916 
01917 
01918 
01919 
01920 
01921 
01922 /* waits for positoning to finish, argument is timeout in
01923    seconds. give timeout==0 to disable timeout */
01924 int waitForTarget(unsigned int t){
01925   
01926   WORD status;
01927   unsigned int i = 0, st= (unsigned int)1e4;
01928 
01929   do {
01930     if (t != 0){ // use timeout?
01931       if(++i > t*1e2) return(1);
01932     }
01933     usleep(st);
01934     readStatusword(&status);
01935   } while ( ( status & E_BIT10) != E_BIT10) ; // bit 10 says: target reached!
01936   
01937   
01938  return(0);
01939 }
01940 
01941 
01942 
01943 
01944 /* 
01945 *************************************************************
01946             check EPOS error code
01947 ****************************************************************
01948 */
01949 
01950 /* check the global variable E_error for EPOS error code */
01951 int checkEPOSerror(){
01952 
01953   switch(E_error) {
01954   case E_NOERR: 
01955     return(0);
01956 
01957   case E_ONOTEX:
01958     printf("EPOS responds with error: requested object does not exist!\n");
01959     break;
01960   case E_SUBINEX:
01961     printf("EPOS responds with error: requested subindex does not exist!\n");
01962     break;
01963   case E_OUTMEM:
01964     printf("EPOS responds with error: out of memory!\n");
01965     break;
01966   case E_NOACCES:
01967     printf("EPOS responds with error: unsupported access to an object!\n");
01968     break;
01969   case E_WRITEONLY:
01970     printf("EPOS responds with error: attempt to read a write-only object!\n");
01971     break;
01972   case E_READONLY:
01973     printf("EPOS responds with error: attempt to write a read-only object!\n");
01974     break;
01975   case E_PARAMINCOMP:
01976     printf("EPOS responds with error: general parameter incompatibility!\n");
01977     break;
01978   case E_INTINCOMP:
01979     printf("EPOS responds with error: general internal incompatibility in the device!\n");
01980     break;
01981   case E_HWERR:
01982     printf("EPOS responds with error: access failed due to an HARDWARE ERROR!\n");
01983     break;
01984   case E_PRAGNEX:
01985     printf("EPOS responds with error: value range of parameter exeeded!\n");
01986     break;
01987   case E_PARHIGH:
01988     printf("EPOS responds with error: value of parameter written is too high!\n");
01989     break;
01990   case E_PARLOW:
01991     printf("EPOS responds with error: value of parameter written is too low!\n");
01992     break;
01993   case E_PARREL:
01994     printf("EPOS responds with error: maximum value is less than minimum value!\n");
01995     break;
01996   case E_NMTSTATE:
01997     printf("EPOS responds with error: wrong NMT state!\n");
01998     break;
01999   case E_RS232:
02000     printf("EPOS responds with error: rs232 command illegeal!\n");
02001     break;
02002   case E_PASSWD:
02003     printf("EPOS responds with error: password incorrect!\n");
02004     break;
02005   case E_NSERV:
02006     printf("EPOS responds with error: device not in service mode!\n");
02007     break;
02008   case E_NODEID:
02009     printf("EPOS responds with error: error in Node-ID!\n");
02010     break;
02011   default:
02012     fprintf(stderr, "EPOS responds with error: unknown EPOS error code: %#lx\n",
02013             E_error);
02014     break;
02015   }
02016   return(-1);
02017 }
02018 
02019 
02020 
02021 /* 
02022 *************************************************************
02023             basic I/O functions
02024 ****************************************************************
02025 */
02026 
02027 
02028 /*  write a single BYTE to EPOS */
02029 int writeBYTE(BYTE *c){
02030 #ifdef DDEBUG
02031     printf("sending %#04x \n", *c);
02032 #endif
02033   if (  write(ep, c, 1) <= 0 ) {
02034     perror("write ");
02035     return(-1);
02036   }
02037   return(0);
02038 }
02039 
02040 
02041 
02042 /*  write a single WORD to EPOS */
02043 int writeWORD(WORD *w){
02044 #ifdef DDEBUG
02045   printf("sending %#06x \n", *w);
02046 #endif
02047      
02048   if (  write(ep, w, 2) <= 0  ) {
02049     perror("write ");
02050     return(-1);
02051   }
02052   return(0);
02053 }
02054 
02055 
02056 
02058 int readBYTE(BYTE *c){
02059 
02060   int i,n;
02061   
02062   
02063   for( i=0; i< NTRY; i++ ) {
02064     n = read(ep, c, 1);
02065     int errsv = errno;
02066     if ( n < 0 && errsv != EAGAIN) {
02067       perror("read ");
02068       return(-2);
02069     }
02070 
02071     if (n > 0) {
02072 #ifdef DDEBUG
02073       printf("<< receiving: %#04x\n", *c);
02074 #endif
02075       return(0);
02076     }
02077     else {      // 'else' is here equivalent to n==0
02078       if (false){
02079         if (gMarker==0){
02080           printf("/\b");
02081           fflush(stdout);
02082           gMarker=1;
02083         }
02084         else {
02085           printf("\\\b");
02086           fflush(stdout);
02087           gMarker = 0;
02088         }
02089       }
02090       usleep(TRYSLEEP); /* sleep 100ms; EPOS gives timeout after 500ms*/
02091     }
02092   }
02093   
02094   // timeout
02095   return(-1);
02096 }
02097 
02098 
02099 
02100 /*  read a single WORD from EPOS, timeout implemented */
02101 int readWORD(WORD *w){
02102 
02103   int i,n;
02104 
02105   for( i=0; i< NTRY; i++ ) {
02106     n = read(ep, w, sizeof(WORD) );
02107     int errsv = errno;
02108     if ( n < 0 && errsv != EAGAIN) {
02109       perror("read ");
02110       return(-2);
02111     }
02112     if (n > 0) {
02113 #ifdef DDEBUG
02114       printf("<<  receiving: %#04x\n", *w);
02115 #endif
02116       return(0);
02117     }
02118     else {
02119       if (false){
02120         if (gMarker==0){
02121           printf("/\b");
02122           fflush(stdout);
02123           gMarker = 1;
02124         }
02125         else {
02126           printf("\\\b");
02127           fflush(stdout);
02128           gMarker = 0;
02129         }
02130       }
02131       usleep(TRYSLEEP); /* sleep 100ms; EPOS gives timeout after 500ms*/
02132     }
02133   }
02134   // timeout
02135   return(-1);
02136 }
02137 
02138 
02139 
02140 
02141 /* copied from EPOS Communication Guide, p.8 */
02142 WORD CalcFieldCRC(WORD *pDataArray, WORD numberOfWords)
02143 {
02144   WORD shifter, c;
02145   WORD carry;
02146   WORD CRC = 0;
02147 
02148  
02149   //Calculate pDataArray Word by Word
02150   while(numberOfWords--)
02151     {
02152       shifter = 0x8000;                 //Initialize BitX to Bit15
02153       c = *pDataArray++;                //Copy next DataWord to c
02154       do
02155         {
02156           carry = CRC & 0x8000;    //Check if Bit15 of CRC is set
02157           CRC <<= 1;               //CRC = CRC * 2
02158           if(c & shifter) CRC++;   //CRC = CRC + 1, if BitX is set in c
02159           if(carry) CRC ^= 0x1021; //CRC = CRC XOR G(x), if carry is true
02160           shifter >>= 1;           //Set BitX to next lower Bit,
02161                                    //shifter = shifter/2
02162         } while(shifter);
02163     }
02164 
02165   //printf("checksum == %#06x\n", CRC);
02166   return CRC;
02167 }
02168 
02169 
02170 
02171 
02172 
02173 /*  send command to EPOS, taking care of all neccessary 'ack' and
02174    checksum tests*/
02175 int sendCom(WORD *frame){
02176   
02177   BYTE c = 0x00;
02178   short i, len;
02179   int n = 0;
02180 
02181   // need LSB of header WORD, contains (len-1). Complete Frame is
02182   // (len-1) +3 WORDS long
02183   len = ( ( frame[0] & 0x00FF) ) +3 ;
02184   /*
02185     printf("frame[0] = %#x; shifted = %#x; framelength = %d\n", 
02186          frame[0], (frame[0] & 0x00FF),  len); 
02187   */
02188 
02189   // add checksum to frame
02190   frame[len-1] =  CalcFieldCRC(frame, len);
02191 
02192 #ifdef DEBUG
02193   printf(">> ");
02194   for (i=0; i<len; ++i){
02195     printf( "%#06x ", frame[i] );
02196   }
02197   printf("\n");
02198 #endif
02199 
02200   /* sending to EPOS */
02201   //send header:
02202   c = (frame[0] & 0xFF00) >> 8 ;  //LSB
02203   if ( writeBYTE(&c) ) perror("writeByte");
02204 
02205   c = 0x77; // 0x77 is not used by EPOS
02206   // wait for "Ready Ack 'O'"
02207   if ( (n=readBYTE(&c))  < 0  ) 
02208     fprintf(stderr, "readBYTE() returnd %d at %s, line %d\n", 
02209             n, __func__, __LINE__);
02210 
02211   if (c != E_OK) {
02212     if (c == 0x77) {
02213       fprintf(stderr, "ERROR: no reply from EPOS recieved, is it on-line?\n");
02214       return(-2);//exit(2);
02215     }
02216     printf("EPOS not ready, reply was: %#04x\n", c);
02217     return(-1);
02218     
02219   }
02220   
02221   c = (frame[0] & 0x00FF)  ;  //MSB
02222   if ( writeBYTE(&c) ) perror("writeBYTE");
02223 
02224   // header done, data + CRC will follow
02225   for (i=1; i<len; i++) {
02226     if ( writeWORD(frame+i) ) perror("writeWORD");
02227   }
02228   
02229   // wait for "End Ack 'O'"
02230   if ( readBYTE(&c)  < 0  ) perror("readBYTE");
02231   if (c != E_OK) {
02232     printf("EPOS says: CRCerror!\n");
02233     return(-1);
02234   }
02235   return(0);
02236 }
02237 
02238 
02239 
02240 
02241 
02252 int readAnswer(WORD **ptr){
02253 
02254   int i;
02255   BYTE c;
02256   WORD first=0x00 , w,  crc, framelen;
02257   static WORD *ans;
02258 
02259   E_error = 0x00;
02260 
02261   /*
02262   printf("******** sub: ptr= %p  &ptr = %p\n", ptr, &ptr);
02263   printf("******** sub: ans   = %p  &ans = %p\n", ans, &ans);
02264   */
02265 
02266   readBYTE(&c);
02267   first = (0xFF00 & c) << 8;
02268   //printf("first answer: %#04x; first: %#06x\n", c, first);
02269 
02270 
02271   if (c != E_ANS) {
02272     fprintf(stderr, "EPOS says: %#04x. This is no answer frame! \n", c);
02273     ptr = NULL;
02274     return(-1);
02275   }
02276   c = E_OK;
02277   writeBYTE(&c);
02278   
02279   // here is the (len-1) value coming
02280   readBYTE(&c);
02281   
02282   first = (0x00FF & c) ;
02283   //printf("second answer: %#04x; first: %#06x\n", c, first);
02284   
02285   framelen = c + 3;
02286   
02287   checkPtr( ans = (WORD*)malloc( framelen * sizeof(WORD)) );
02288   
02289   ans[0] = first;
02290   
02291   for(i=1; i<framelen; i++){
02292     readWORD(&w);
02293     ans[i] = w;
02294   }
02295 #ifdef DEBUG
02296   printf("\n<< ");
02297   for(i=0; i<(framelen); i++){
02298     printf("%#06x ", ans[i]);
02299   }
02300   printf("\n"); fflush(stdout);
02301   
02302 #endif
02303 
02304   // compute checksum
02305   crc = ans[framelen-1];  
02306 #ifdef DDEBUG
02307   printf("got this CRC: %#06x\n", crc);
02308 #endif
02309   ans[framelen-1] =  0x0000;
02310   ans[framelen-1] = CalcFieldCRC(ans, framelen);
02311 
02312 
02313   if (crc == ans[framelen-1]) {
02314     c = E_OK;
02315     writeBYTE(&c);
02316 #ifdef DEBUG
02317     printf("CRC test OK!\n");
02318 #endif
02319   }
02320   else {
02321     c = E_FAIL;
02322     writeBYTE(&c);
02323     fprintf(stderr, "CRC test FAILED!\n");
02324     ptr = NULL;
02325     return(-1);
02326   }
02327   
02328   
02329   /* check for error code */
02330   
02331   /* just to get the bit's at the right place...*/
02332   //ans[1] = 0x1234; ans[2] = 0xABCD; 
02333   E_error = ans[1] | (ans[2] << 16) ;
02334   //printf(" xxxxxxx ->%#010x<-\n", E_error);
02335   
02336 
02337 
02338 
02339   *ptr = ans;
02340   /*
02341   printf("******** sub: ptr= %p  &ptr = %p\n", ptr, &ptr);
02342   printf("******** sub: ans   = %p  &ans = %p\n", ans, &ans);
02343   */
02344   return(framelen);
02345 }
02346 
02347 
02348 
02349 
02350 
02351 
02352 int ReadObject(WORD index, BYTE subindex, WORD **ptr ){
02353 
02354   WORD frame[4];
02355   int n = 0;
02356 
02357   frame[0] = 0x1001; // fixed, ReadObject, (len-1) == 1
02358   frame[1] = index;
02359   frame[2] = (0x0000 | subindex); /* high BYTE: 0x00(Node-ID == 0) 
02360                                       low BYTE: subindex */
02361   frame[3] = 0x000; // ZERO word, will be filled with checksum
02362 
02363   if( (n = sendCom(frame)) < 0){
02364     fprintf(stderr, " *** %s: problems with sendCom(), return value was %d ***\n ",
02365             __func__, n);
02366     return(-1);
02367   }
02368 
02369   // read response
02370   return( readAnswer(ptr) );
02371   
02372 }
02373 
02374 
02375 
02376 
02377 
02378 
02393 int WriteObject(WORD index, BYTE subindex, WORD *data) {
02394 
02395   WORD frame[6];
02396   WORD *ans = NULL;
02397   int n = 0;
02398   
02399 
02400   frame[0] = 0x1103; // fixed, WriteObject, (len-1) == 3
02401   frame[1] = index;
02402   frame[2] = (0x0000 | subindex); /* high BYTE: 0x00(Node-ID == 0) 
02403                                       low BYTE: subindex */
02404   // data to transmit
02405   frame[3] = data[0];
02406   frame[4] = data[1];
02407 
02408   frame[5] = 0x00; // ZERO word, will be filled with checksum
02409 
02410   if( (n = sendCom(frame)) < 0){
02411     fprintf(stderr, " *** %s: problems with sendCom(), return value was %d ***\n ",  __func__, n);
02412     return(-1);
02413   }
02414 
02415 
02416   // read response
02417   checkPtr( ans = (WORD*)calloc(3, sizeof(WORD) ) );
02418   
02419   if ( (n = readAnswer(&ans) )  <0 ){
02420     fprintf(stderr, " *** %s: problems with readAnswer(), return value was %d ***\n ",  __func__, n);
02421     free(ans);
02422     return(-1);
02423   }
02424   
02425   return( checkEPOSerror() );
02426   
02427 }
02428  
02429  
02430  
02431  
02432  
02433  
02434 /* compare WORD a with WORD b bitwise */
02435 int bitcmp(WORD a, WORD b){
02436   if ( (a & b) == b ) return(1);
02437   else return(0);
02438 }
02439     
02440  
02441  
02442  
02443 void checkPtr(void* ptr){
02444   if (ptr == NULL){
02445     fprintf(stderr, "malloc failed!\n");
02446     exit(-1);
02447   }
02448 }
02449 
02450 
02451 
02452 
02453 
02454 
02455 
02456 
02457 
02460 int InitiateSegmentedRead(WORD index, BYTE subindex ){
02461 
02462   WORD frame[4], **ptr=NULL;
02463   int n=0;
02464 
02465   frame[0] = 0x1201; // fixed, opCode==0x12, (len-1) == 1
02466   frame[1] = index;
02467   frame[2] = 0x0000 | subindex; /* high BYTE: 0x00 (Node-ID == 0) 
02468                                     low BYTE: subindex */
02469   frame[3] = 0x000; // ZERO word, will be filled with checksum
02470 
02471   if( (n = sendCom(frame)) < 0){
02472     fprintf(stderr, " *** %s: problems with sendCom(), return value was %d ***\n ",  __func__, n);
02473     return(-1);
02474   }
02475   
02476   // read response
02477   return( readAnswer(ptr) );  // answer contains only DWORD ErrorCode
02478                               // here...
02479 }
02480 
02481 
02482 
02491 int SegmentRead(WORD **ptr){
02492 
02493   WORD frame[3];
02494   int n = 0;
02495 
02496   frame[0] = 0x1400; // fixed, opCode==0x14, (len-1) == 0
02497   frame[1] = 0x0000; // WHAT IS THE 'TOGGLE' BIT????
02498   frame[2] = 0x0000;  // ZERO word, will be filled with checksum
02499 
02500   if( (n = sendCom(frame)) < 0){
02501     fprintf(stderr, " *** %s: problems with sendCom(), return value was %d ***\n ",  __func__, n);
02502     return(-1);
02503   }
02504   
02505 
02506   if ( (n = readAnswer(ptr)) < 0){
02507     fprintf(stderr, " *** %s: problems with readAns(), return value was %d ***\n ",  __func__, n);
02508     return(-1);
02509   }
02510   
02511 
02512   return(0);
02513 }
02514 
02515 
02516 
02517 
02518 
02519 
02520 
02521 
02522 


epos_driver
Author(s): Tomasz Kucner , Martin Magnusson , Hakan Almqvist , Marcus Hauser
autogenerated on Fri Aug 28 2015 10:38:28