00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArVersalogicIO.h"
00030 
00031 #include <sys/ioctl.h>
00032 #include <fcntl.h>
00033 
00034 
00035 
00036 #define AMRIO_MAJOR_NUM       (250)
00037 #define AMRIO_MODULE_NAME     ("amrio")
00038 
00039 #define ANALOG_GET_VALUE                _IOWR('v', 1, unsigned int)
00040 #define ANALOG_SET_PORT                 _IOWR('v', 2, unsigned char)
00041 #define DIGITAL_GET_NUM_BANKS           _IOWR('v', 3, int)
00042 #define DIGITAL_SET_BANK0               _IOWR('v', 4, unsigned char)
00043 #define DIGITAL_SET_BANK1               _IOWR('v', 5, unsigned char)
00044 #define DIGITAL_SET_BANK2               _IOWR('v', 6, unsigned char)
00045 #define DIGITAL_SET_BANK3               _IOWR('v', 7, unsigned char)
00046 #define DIGITAL_SET_BANK_DIR_IN         _IOWR('v', 8, int)
00047 #define DIGITAL_SET_BANK_DIR_OUT        _IOWR('v', 9, int)
00048 #define DIGITAL_GET_BANK0               _IOWR('v', 10, unsigned char)
00049 #define DIGITAL_GET_BANK1               _IOWR('v', 11, unsigned char)
00050 #define DIGITAL_GET_BANK2               _IOWR('v', 12, unsigned char)
00051 #define DIGITAL_GET_BANK3               _IOWR('v', 13, unsigned char)
00052 #define GET_SPECIAL_CONTROL_REGISTER    _IOWR('v', 14, unsigned char)
00053 
00063 ArMutex ArVersalogicIO::myMutex;
00064 ArVersalogicIO::ArVersalogicIO(const char * dev)
00065 {
00066   ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: about to open device");
00067   myFD = open(dev, O_RDWR);
00068   ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: just opened device");
00069   myNumBanks = 0;
00070 
00071   myDigitalBank0 = 0;
00072   myDigitalBank1 = 0;
00073   myDigitalBank2 = 0;
00074   myDigitalBank3 = 0;
00075 
00076   if (myFD == -1)
00077   {
00078     ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: open %s failed.  Disabling class", dev);
00079     myEnabled = false;
00080   }
00081   else
00082   {
00083     if(ioctl(myFD, DIGITAL_GET_NUM_BANKS, &myNumBanks))
00084       ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: failed to get the number of digital IO banks");
00085     
00086     int i;
00087     for(i=0;i<myNumBanks;i++)
00088       setDigitalBankDirection(i, DIGITAL_INPUT);
00089     myEnabled = true;
00090 
00091     
00092     double val;
00093     if (!ioctl(myFD, ANALOG_SET_PORT, 0) || !ioctl(myFD,ANALOG_GET_VALUE, &val))
00094     {
00095       ArLog::log(ArLog::Verbose, "ArVersalogicIO:ArVersalogicIO: analog conversion failed.  Disabling analog functionality");
00096       myAnalogEnabled = false;
00097     }
00098     else
00099       myAnalogEnabled = true;
00100   }
00101 }
00102 
00105 ArVersalogicIO::~ArVersalogicIO(void)
00106 {
00107   if (myEnabled)
00108   {
00109     if (close(myFD) == -1)
00110       ArLog::log(ArLog::Terse, "ArVersalogicIO::~ArVersalogicIO: close failed on file descriptor!");
00111     ArLog::log(ArLog::Terse, "ArVersalogicIO::~ArVersalogicIO: just closed the device");
00112   }
00113 }
00114 
00121 bool ArVersalogicIO::getAnalogValue(int port, double *val)
00122 {
00123   if (!myEnabled || !myAnalogEnabled)
00124     return false;
00125 
00126   double tmp;
00127 
00128   if (ioctl(myFD, ANALOG_SET_PORT, port) != 0)
00129   {
00130     ArLog::log(ArLog::Terse, "ArVersalogicIO::getAnalogValue: failed to set analog port %d", port);
00131     return false;
00132   }
00133 
00134   if (ioctl(myFD, ANALOG_GET_VALUE, tmp) != 0)
00135     return false;
00136 
00137   *val = tmp;
00138   return true;
00139 }
00140 
00141 
00142 ArVersalogicIO::Direction ArVersalogicIO::getDigitalBankDirection(int bank)
00143 {
00144   return DIGITAL_OUTPUT;
00145 }
00146 
00147 bool ArVersalogicIO::setDigitalBankDirection(int bank, Direction dir)
00148 {
00149   if (!myEnabled)
00150     return false;
00151 
00152   if (dir == DIGITAL_INPUT)
00153   {
00154     if (ioctl(myFD, DIGITAL_SET_BANK_DIR_IN, bank) != 0)
00155       return false;
00156   }
00157   else if (dir == DIGITAL_OUTPUT)
00158   {
00159     if (ioctl(myFD, DIGITAL_SET_BANK_DIR_OUT, bank) != 0)
00160       return false;
00161   }
00162   else
00163   {
00164     ArLog::log(ArLog::Verbose, "ArVersalogicIO::setDigitalBankDirection: invalid argument for direction");
00165     return false;
00166   }
00167 
00168   return true;
00169 }
00170 
00176 bool ArVersalogicIO::getDigitalBankInputs(int bank, unsigned char *val)
00177 {
00178   if (!myEnabled)
00179     return false;
00180 
00181   if (bank < 0 || bank > myNumBanks - 1)
00182     return false;
00183 
00184   unsigned char tmp;
00185   switch (bank)
00186   {
00187     case 0:
00188       if (ioctl(myFD, DIGITAL_GET_BANK0, &tmp) != 0)
00189         return false;
00190       break;
00191     case 1:
00192       if (ioctl(myFD, DIGITAL_GET_BANK1, &tmp) != 0)
00193         return false;
00194       break;
00195     case 2:
00196       if (ioctl(myFD, DIGITAL_GET_BANK2, &tmp) != 0)
00197         return false;
00198       break;
00199     case 3:
00200       if (ioctl(myFD, DIGITAL_GET_BANK3, &tmp) != 0)
00201         return false;
00202       break;
00203     default:
00204       return false;
00205   }
00206 
00207   
00208   *val = ~tmp;
00209   return true;
00210 }
00211 
00212 
00220 bool ArVersalogicIO::getDigitalBankOutputs(int bank, unsigned char *val)
00221 {
00222   if (!myEnabled)
00223     return false;
00224 
00225   if (bank < 0 || bank > myNumBanks - 1)
00226     return false;
00227 
00228   
00229   switch (bank)
00230   {
00231     case 0:
00232       *val = myDigitalBank0;
00233       break;
00234     case 1:
00235       *val = myDigitalBank1;
00236       break;
00237     case 2:
00238       *val = myDigitalBank2;
00239       break;
00240     case 3:
00241       *val = myDigitalBank3;
00242       break;
00243   }
00244 
00245   return true;
00246 }
00247 
00256 bool ArVersalogicIO::setDigitalBankOutputs(int bank, unsigned char val)
00257 {
00258   if (!myEnabled)
00259     return false;
00260 
00261   if (bank < 0 || bank > myNumBanks - 1)
00262     return false;
00263 
00264   
00265   switch (bank)
00266   {
00267     case 0:
00268       if (ioctl(myFD, DIGITAL_SET_BANK0, ~val) != 0)
00269         return false;
00270       myDigitalBank0 = val;
00271       break;
00272     case 1:
00273       if (ioctl(myFD, DIGITAL_SET_BANK1, ~val) != 0)
00274         return false;
00275       myDigitalBank1 = val;
00276       break;
00277     case 2:
00278       if (ioctl(myFD, DIGITAL_SET_BANK2, ~val) != 0)
00279         return false;
00280       myDigitalBank2 = val;
00281       break;
00282     case 3:
00283       if (ioctl(myFD, DIGITAL_SET_BANK3, ~val) != 0)
00284         return false;
00285       myDigitalBank3 = val;
00286       break;
00287     default:
00288       return false;
00289   }
00290 
00291   return true;
00292 }
00293 
00300 bool ArVersalogicIO::getSpecialControlRegister(unsigned char *val)
00301 {
00302   if (!myEnabled)
00303     return false;
00304 
00305   unsigned char tmp;
00306   if (ioctl(myFD, GET_SPECIAL_CONTROL_REGISTER, &tmp) != 0)
00307     return false;
00308 
00309   *val = tmp;
00310   return true;
00311 }