Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

simdio.c

Go to the documentation of this file.
00001 /*
00002   simio.c
00003 
00004   Simulated external digital IO interface
00005 
00006   Modification history:
00007 
00008   27-Jul-2000 WPS added compile-switched stat'ing of switch files using
00009   USE_STAT_FILES
00010   20-Mar-2000 WPS added unused attribute to ident to avoid 'defined but not used' compiler warning
00011   21-Sep-1999  WPS eliminate sscanf and printf calls not supported under CE.
00012   15-Sep-1999  FMP bracketed printing with check for EMC_DEBUG &
00013   EMC_DEBUG_IO_POINTS
00014   7-Aug-1998  FMP created from simio.c
00015   */
00016 
00017 /* Define this if you want to test limit switches, home switches by
00018    touching files and having stat() look for them. On an NFS file system,
00019    this can generate lots of traffic.
00020    Otherwise, the functions will just return "normal" status. */
00021 #if !defined(rtlinux) && !defined(rtai)
00022 #define USE_STAT_FILES
00023 #define NAMELEN 8               /* length of stat file names */
00024 #endif
00025 
00026 #if !defined(rtlinux) && !defined(rtai)
00027 #include <stdlib.h>             /* strtod */
00028 #endif
00029 #if !defined(rtlinux) && !defined(rtai)
00030 #ifndef UNDER_CE
00031 #include <stdio.h>              /* printf() */
00032 #endif
00033 #ifdef USE_STAT_FILES
00034 #include <string.h>
00035 #include <sys/stat.h>
00036 #endif
00037 #include "rcs_prnt.hh"          /* rcs_print() */
00038 #include "emcglb.h"             /* EMC_DEBUG, EMC_DEBUG_IO_POINTS */
00039 #endif
00040 #include "sim.h"                /* these decls */
00041 
00042 /* ident tag */
00043 #ifndef __GNUC__
00044 #ifndef __attribute__
00045 #define __attribute__(x)
00046 #endif
00047 #endif
00048 
00049 static char __attribute__((unused))  ident[] = "$Id: simdio.c,v 1.9 2001/06/29 20:27:29 wshackle Exp $";
00050 
00051 /*
00052   digital IO model
00053 
00054   Provides for simulated digital ins, outs
00055   */
00056 
00057 #define SIM_DIO_INPUT_BYTES 4   /* bytes of digital ins */
00058 #define SIM_DIO_OUTPUT_BYTES 4  /* bytes of digital outs */
00059 
00060 #define SIM_DIO_MAX_INPUTS (SIM_DIO_INPUT_BYTES * 8)
00061 #define SIM_DIO_MAX_OUTPUTS (SIM_DIO_OUTPUT_BYTES * 8)
00062 
00063 /* the actual digital ins, outs */
00064 
00065 static unsigned char simDioInputs[SIM_DIO_INPUT_BYTES];
00066 static unsigned char simDioOutputs[SIM_DIO_OUTPUT_BYTES];
00067 
00068 #define SIM_MAX_POS_FIELDS 20
00069 
00070 #ifndef SIM_MAX_AXIS
00071 #define SIM_MAX_AXIS 8
00072 #endif
00073 
00074 struct sim_dio_position_field {
00075   int start_axis_flags; // Which fields to compare/ignore in end pos
00076   int end_axis_flags; // Which fields to compare/ignore in end pos
00077   double start_pos[SIM_MAX_AXIS];
00078   double end_pos[SIM_MAX_AXIS];
00079 };
00080 
00081 
00082 struct sim_dio_config {
00083   int use_stat_file;
00084   int use_pos_fields;
00085   int number_of_position_fields;
00086   int polarity;
00087   struct sim_dio_position_field pos_field[SIM_MAX_POS_FIELDS];
00088 };
00089 
00090 
00091 #if !defined(rtlinux) && !defined(rtai)
00092  
00093 static struct sim_dio_config dio_config[SIM_DIO_MAX_INPUTS];
00094 
00095 
00096 #include "inifile.h"
00097 
00098 static int btostr(char * s, unsigned char b)
00099 {
00100   int t;
00101 
00102   for (t = 7; t >= 0; t--) {
00103     s[t] = b % 2 ? '1' : '0';
00104     b >>= 1;
00105   }
00106   s[8] = 0;                     /* null terminate */
00107 
00108   return 0;
00109 }
00110 
00111 
00112 static const char *posDelimiters=" \t\r\n";
00113 
00114 static int readPositionFile(int index, const char *filename)
00115 {
00116   FILE *f;
00117   int pos_fields_read;
00118   int axis;
00119   char *token;
00120   char linebuf[256];
00121 
00122   f = fopen(filename,"r");
00123   if(NULL == f)
00124     {
00125       return -1;
00126     }
00127 
00128   pos_fields_read = 0;
00129   while(!feof(f) && pos_fields_read < SIM_MAX_POS_FIELDS)
00130     {
00131       dio_config[index].pos_field[pos_fields_read].start_axis_flags = 0;
00132       dio_config[index].pos_field[pos_fields_read].end_axis_flags = 0;
00133       
00134       fgets(linebuf,256,f);
00135       while(NULL != strchr("#;\r\n \t",linebuf[0]))
00136         {
00137           fgets(linebuf,256,0);
00138           if(feof(f))
00139             {
00140             break;
00141             }
00142         }
00143       token = strtok(linebuf,posDelimiters);
00144       for(axis = 0; NULL != token && axis < SIM_MAX_AXIS;
00145           axis++,  token = strtok(NULL,posDelimiters) )
00146         {
00147           if(!strcmp(token,"*"))
00148             {
00149               continue;
00150             }
00151           dio_config[index].pos_field[pos_fields_read].start_pos[axis] =
00152             strtod(token,NULL);
00153           dio_config[index].pos_field[pos_fields_read].start_axis_flags |= (1 << axis);
00154         }
00155       fgets(linebuf,256,f);
00156       while(NULL != strchr("#;\r\n \t",linebuf[0]))
00157         {
00158           fgets(linebuf,256,0);
00159           if(feof(f))
00160             {
00161             break;
00162             }
00163         }
00164       token = strtok(linebuf,posDelimiters);
00165       for(axis = 0; NULL != token && axis < SIM_MAX_AXIS;
00166           axis++,  token = strtok(NULL,posDelimiters) )
00167         {
00168           if(!strcmp(token,"*"))
00169             {
00170               continue;
00171             }
00172           dio_config[index].pos_field[pos_fields_read].end_pos[axis] =
00173             strtod(token,NULL);
00174           dio_config[index].pos_field[pos_fields_read].end_axis_flags |= (1 << axis);
00175         }
00176       pos_fields_read++;
00177     }
00178 
00179   dio_config[index].number_of_position_fields = pos_fields_read;
00180   dio_config[index].use_pos_fields =1;
00181   fclose(f);
00182 
00183   return 0;
00184 }
00185 
00186 static int simDioIniLoad(const char *filename)
00187 {
00188   FILE *f;
00189   const char *inistring;
00190   char section[40];
00191   int i;
00192   int byte;
00193   unsigned char mask = 0x01;
00194 
00195   // open it
00196   if(  (f = fopen(filename,"r")) == NULL) {
00197     return -1;
00198   }
00199 
00200   for( i = 0; i < SIM_DIO_MAX_INPUTS; i++)
00201     {
00202       sprintf(section,"SIM_DIO_%d",i);
00203 
00204       dio_config[i].use_stat_file = 0;
00205       dio_config[i].use_pos_fields = 0;      
00206       dio_config[i].polarity = 0;      
00207 
00208       if (NULL != (inistring = iniFind(f,"POLARITY", section))) 
00209         {
00210           if (1 != sscanf(inistring, "%i", &dio_config[i].polarity)) 
00211             {
00212             dio_config[i].polarity = 0;
00213             }
00214           byte = i / 8;
00215           mask <<= i % 8;
00216           if(dio_config[i].polarity)
00217             {
00218               simDioInputs[byte] |= mask;
00219             }
00220           else
00221             {
00222               simDioInputs[byte] &= ~mask;
00223             }
00224         }
00225       
00226       if (NULL != (inistring = iniFind(f,"USE_STAT_FILE", section))) 
00227         {
00228           // copy to global
00229           if (1 != sscanf(inistring, "%i", &dio_config[i].use_stat_file)) 
00230             {
00231               dio_config[i].use_stat_file = 0;
00232             }
00233         }
00234       if (NULL != (inistring = iniFind(f,"POSITION_FILE", section))) 
00235         {
00236           readPositionFile(i,inistring);
00237         }
00238       
00239     }
00240 
00241   fclose(f);
00242 
00243   return 0;
00244 }
00245 
00246 
00247 
00248 #endif
00249 
00250 static void printDioOutputs(void)
00251 {
00252 #if !defined(rtlinux) && !defined(rtai)
00253   int t;
00254   char byteString[9];
00255 
00256   if (EMC_DEBUG & EMC_DEBUG_IO_POINTS) {
00257     for (t = SIM_DIO_OUTPUT_BYTES - 1; t >= 0; t--) {
00258       btostr(byteString, simDioOutputs[t]);
00259       rcs_print("%s ", byteString);
00260     }
00261   rcs_print("\n");
00262   }
00263 #endif
00264 }
00265 
00266 int simDioInit(const char * filename)
00267 {
00268 #if !defined(rtlinux) && !defined(rtai)
00269   printf("simDioInit(%s)\n",filename);
00270   simDioIniLoad(filename);
00271 #endif
00272 
00273   return 0;
00274 }
00275 
00276 int simDioQuit()
00277 {
00278   return 0;
00279 }
00280 
00281 int simDioMaxInputs()
00282 {
00283   return SIM_DIO_MAX_INPUTS;
00284 }
00285 
00286 int simDioMaxOutputs()
00287 {
00288   return SIM_DIO_MAX_OUTPUTS;
00289 }
00290 
00291 #ifdef USE_STAT_FILES
00292 static int current_pos_in_field(int index)
00293 {
00294   int i,j;
00295   int in_this_field;
00296 
00297   if (index < 0 ||
00298       index >= SIM_DIO_MAX_INPUTS) 
00299     {
00300       return -1;
00301     }
00302   
00303   if( dio_config[index].number_of_position_fields > SIM_MAX_POS_FIELDS)
00304     {
00305       dio_config[index].number_of_position_fields = SIM_MAX_POS_FIELDS;
00306       return -1;
00307     }
00308 
00309       
00310   for(j = 0; j < dio_config[index].number_of_position_fields; j++)
00311     {
00312       in_this_field = 1;
00313       for( i = 0; i < SIM_MAX_AXIS; i++)
00314         {
00315           if(
00316              simPos[i] < dio_config[index].pos_field[j].start_pos[i] &&
00317              (dio_config[index].pos_field[j].start_axis_flags & (1 << i))
00318              )
00319             {
00320               in_this_field = 0;
00321               break;
00322             }
00323           if(
00324              simPos[i] > dio_config[index].pos_field[j].end_pos[i] &&
00325              (dio_config[index].pos_field[j].end_axis_flags & (1 << i))
00326              )
00327             {
00328               in_this_field = 0;
00329               break;
00330             }
00331         }
00332       if(in_this_field)
00333         {
00334           return 1;
00335         }
00336     }
00337   return 0;
00338 }
00339 #endif
00340 
00341 
00342 int simDioRead(int index, int *value)
00343 {
00344   int byte;
00345   unsigned char mask = 0x01;
00346 #ifdef USE_STAT_FILES
00347   struct stat buf;
00348   char diFile[NAMELEN];
00349 #endif
00350 
00351   if (index < 0 ||
00352       index >= SIM_DIO_MAX_INPUTS) {
00353     return -1;
00354   }
00355 
00356   byte = index / 8;
00357   mask <<= index % 8;
00358 
00359 #ifdef USE_STAT_FILES
00360   if(dio_config[index].use_stat_file) {
00361     /* to test Digital IO logic, this code tests for the existence
00362        of file "di<n>" for home switch on axis n.
00363        During controller debug, touch these files to create them
00364        and the controller should see the corresponding input go high. */
00365     
00366 #ifndef UNDER_CE
00367     sprintf(diFile, "di%d", index);
00368 #else
00369     strcpy(diFile,"di");
00370     _itoa(index, diFile+2,10);
00371 #endif
00372     
00373     if (0 == stat(diFile, &buf) == dio_config[index].polarity)
00374       {
00375         /* file exists */
00376       simDioInputs[byte] |= mask;
00377       }
00378     else
00379       {
00380         simDioInputs[byte] &= ~mask;
00381       }
00382   }
00383   else if(dio_config[index].use_pos_fields) {
00384     if(current_pos_in_field(index) == dio_config[index].polarity)
00385       {
00386         simDioInputs[byte] |= mask;
00387       }
00388     else
00389       {
00390         simDioInputs[byte] &= ~mask;
00391       }
00392   }
00393 #endif
00394 
00395 
00396   *value = (simDioInputs[byte] & mask) == 0 ? 0 : 1;
00397 
00398   return 0;
00399 }
00400 
00401 int simDioWrite(int index, int value)
00402 {
00403   int byte;
00404   unsigned char mask = 0x01;
00405 
00406   if (index < 0 ||
00407       index >= SIM_DIO_MAX_OUTPUTS) {
00408     return -1;
00409   }
00410 
00411   byte = index / 8;
00412   mask <<= index % 8;
00413 
00414   if (value) {
00415     simDioOutputs[byte] |= mask;
00416   }
00417   else {
00418     simDioOutputs[byte] &= ~mask;
00419   }
00420 
00421   printDioOutputs();
00422 
00423   return 0;
00424 }
00425 
00426 int simDioCheck(int index, int *value)
00427 {
00428   int byte;
00429   unsigned char mask = 0x01;
00430 
00431   if (index < 0 ||
00432       index >= SIM_DIO_MAX_INPUTS) {
00433     return -1;
00434   }
00435 
00436   byte = index / 8;
00437   mask <<= index % 8;
00438 
00439   *value = (simDioOutputs[byte] & mask) == 0 ? 0 : 1;
00440 
00441   return 0;
00442 }
00443 
00444 int simDioByteRead(int index, unsigned char *byte)
00445 {
00446   if (index < 0 ||
00447       index >= SIM_DIO_INPUT_BYTES) {
00448     return -1;
00449   }
00450 
00451   *byte = simDioInputs[index];
00452 
00453   return 0;
00454 }
00455 
00456 int simDioShortRead(int index, unsigned short *sh)
00457 {
00458   index *= sizeof(unsigned short); /* convert to byte index */
00459 
00460   if (index < 0 ||
00461       index >= SIM_DIO_INPUT_BYTES) {
00462     return -1;
00463   }
00464 
00465   *sh = *((unsigned short *) &simDioInputs[index]);
00466 
00467   return 0;
00468 }
00469 
00470 int simDioWordRead(int index, unsigned int *word)
00471 {
00472   index *= sizeof(unsigned int); /* convert to byte index */
00473 
00474   if (index < 0 ||
00475       index >= SIM_DIO_INPUT_BYTES) {
00476     return -1;
00477   }
00478 
00479   *word = *((unsigned int *) &simDioInputs[index]);
00480 
00481   return 0;
00482 }
00483 
00484 int simDioByteWrite(int index, unsigned char byte)
00485 {
00486   if (index < 0 ||
00487       index >= SIM_DIO_INPUT_BYTES) {
00488     return -1;
00489   }
00490 
00491   simDioInputs[index] = byte;
00492 
00493   printDioOutputs();
00494 
00495   return 0;
00496 }
00497 
00498 int simDioShortWrite(int index, unsigned short sh)
00499 {
00500   index *= sizeof(unsigned short); /* convert to byte index */
00501 
00502   if (index < 0 ||
00503       index >= SIM_DIO_INPUT_BYTES) {
00504     return -1;
00505   }
00506 
00507   *((unsigned short *) &simDioInputs[index]) = sh;
00508 
00509   printDioOutputs();
00510 
00511   return 0;
00512 }
00513 
00514 int simDioWordWrite(int index, unsigned int word)
00515 {
00516   index *= sizeof(unsigned int); /* convert to byte index */
00517 
00518   if (index < 0 ||
00519       index >= SIM_DIO_INPUT_BYTES) {
00520     return -1;
00521   }
00522 
00523   *((unsigned int *) &simDioInputs[index]) = word;
00524 
00525   printDioOutputs();
00526 
00527   return 0;
00528 }
00529 
00530 int simDioByteCheck(int index, unsigned char *byte)
00531 {
00532   if (index < 0 ||
00533       index >= SIM_DIO_OUTPUT_BYTES) {
00534     return -1;
00535   }
00536 
00537   *byte = simDioOutputs[index];
00538 
00539   return 0;
00540 }
00541 
00542 int simDioShortCheck(int index, unsigned short *sh)
00543 {
00544   index *= sizeof(unsigned short); /* convert to byte index */
00545 
00546   if (index < 0 ||
00547       index >= SIM_DIO_OUTPUT_BYTES) {
00548     return -1;
00549   }
00550 
00551   *sh = * ((unsigned short *) &simDioOutputs[index]);
00552 
00553   return 0;
00554 }
00555 
00556 int simDioWordCheck(int index, unsigned int *word)
00557 {
00558   index *= sizeof(unsigned int); /* convert to byte index */
00559 
00560   if (index < 0 ||
00561       index >= SIM_DIO_OUTPUT_BYTES) {
00562     return -1;
00563   }
00564 
00565   *word = * ((unsigned int *) &simDioOutputs[index]);
00566 
00567   return 0;
00568 }
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 

Generated on Sun Dec 2 15:27:43 2001 for EMC by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001