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 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArVersalogicIO.h"
00029 #include "ariaInternal.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
00054 ArMutex ArVersalogicIO::myMutex;
00055
00065 AREXPORT ArVersalogicIO::ArVersalogicIO(const char * dev) :
00066 myDisconnectCB(this, &ArVersalogicIO::closeIO)
00067 {
00068 myNumBanks = 0;
00069
00070 myDigitalBank0 = 0;
00071 myDigitalBank1 = 0;
00072 myDigitalBank2 = 0;
00073 myDigitalBank3 = 0;
00074
00075 ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: opening device %s", dev);
00076 myFD = open(dev, O_RDWR);
00077
00078 if (myFD == -1)
00079 {
00080 ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: open %s failed. Disabling class", dev);
00081 myEnabled = false;
00082 }
00083 else
00084 {
00085 if(ioctl(myFD, DIGITAL_GET_NUM_BANKS, &myNumBanks))
00086 ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: failed to get the number of digital IO banks");
00087
00088 int i;
00089 for(i=0;i<myNumBanks;i++)
00090 setDigitalBankDirection(i, DIGITAL_INPUT);
00091 myEnabled = true;
00092
00093
00094 double val;
00095 ArLog::log(ArLog::Verbose, "ArVersalogicIO::ArVersalogicIO: testing analog functionality");
00096 if ((ioctl(myFD, ANALOG_SET_PORT, 0) != 0) || (ioctl(myFD,ANALOG_GET_VALUE, &val) != 0))
00097 {
00098 ArLog::log(ArLog::Verbose, "ArVersalogicIO::ArVersalogicIO: analog conversion failed. Disabling analog functionality");
00099 myAnalogEnabled = false;
00100 }
00101 else
00102 {
00103 ArLog::log(ArLog::Verbose, "ArVersalogicIO::ArVersalogicIO: analog conversion succeeded.");
00104 myAnalogEnabled = true;
00105 }
00106
00107 Aria::addExitCallback(&myDisconnectCB);
00108 ArLog::log(ArLog::Terse, "ArVersalogicIO::ArVersalogicIO: device opened");
00109 }
00110 }
00111
00114 AREXPORT ArVersalogicIO::~ArVersalogicIO(void)
00115 {
00116 if (myEnabled)
00117 closeIO();
00118 }
00119
00122 AREXPORT bool ArVersalogicIO::closeIO(void)
00123 {
00124 myEnabled = false;
00125
00126 if (close(myFD) == -1)
00127 {
00128 ArLog::log(ArLog::Terse, "ArVersalogicIO::~ArVersalogicIO: close failed on file descriptor!");
00129 return false;
00130 }
00131 else
00132 {
00133 ArLog::log(ArLog::Terse, "ArVersalogicIO::~ArVersalogicIO: closed device");
00134 return true;
00135 }
00136 }
00137
00144 AREXPORT bool ArVersalogicIO::getAnalogValueRaw(int port, int *val)
00145 {
00146 if (!myEnabled || !myAnalogEnabled)
00147 return false;
00148
00149 unsigned int tmp;
00150
00151 if (ioctl(myFD, ANALOG_SET_PORT, port) != 0)
00152 {
00153 ArLog::log(ArLog::Terse, "ArVersalogicIO::getAnalogValueRaw: failed to set analog port %d", port);
00154 return false;
00155 }
00156
00157 if (ioctl(myFD, ANALOG_GET_VALUE, &tmp) != 0)
00158 {
00159 ArLog::log(ArLog::Terse, "ArVersalogicIO::getAnalogValueRaw: failed to get analog port %d", port);
00160 return false;
00161 }
00162
00163 *val = (int) tmp;
00164
00165 return true;
00166 }
00167
00175 AREXPORT bool ArVersalogicIO::getAnalogValue(int port, double *val)
00176 {
00177 int tmp;
00178
00179
00180 if (getAnalogValueRaw(port, &tmp)) {
00181 *val = 5 * (tmp/4096.0);
00182 return true;
00183 }
00184 else {
00185 return false;
00186 }
00187 }
00188
00189
00190 AREXPORT ArVersalogicIO::Direction ArVersalogicIO::getDigitalBankDirection(int bank)
00191 {
00192 return DIGITAL_OUTPUT;
00193 }
00194
00195 AREXPORT bool ArVersalogicIO::setDigitalBankDirection(int bank, Direction dir)
00196 {
00197 if (!myEnabled)
00198 return false;
00199
00200 if (dir == DIGITAL_INPUT)
00201 {
00202 if (ioctl(myFD, DIGITAL_SET_BANK_DIR_IN, bank) != 0)
00203 return false;
00204 }
00205 else if (dir == DIGITAL_OUTPUT)
00206 {
00207 if (ioctl(myFD, DIGITAL_SET_BANK_DIR_OUT, bank) != 0)
00208 return false;
00209 }
00210 else
00211 {
00212 ArLog::log(ArLog::Verbose, "ArVersalogicIO::setDigitalBankDirection: invalid argument for direction");
00213 return false;
00214 }
00215
00216 return true;
00217 }
00218
00224 AREXPORT bool ArVersalogicIO::getDigitalBankInputs(int bank, unsigned char *val)
00225 {
00226 if (!myEnabled)
00227 return false;
00228
00229 if (bank < 0 || bank > myNumBanks - 1)
00230 return false;
00231
00232 unsigned char tmp;
00233 switch (bank)
00234 {
00235 case 0:
00236 if (ioctl(myFD, DIGITAL_GET_BANK0, &tmp) != 0)
00237 return false;
00238 break;
00239 case 1:
00240 if (ioctl(myFD, DIGITAL_GET_BANK1, &tmp) != 0)
00241 return false;
00242 break;
00243 case 2:
00244 if (ioctl(myFD, DIGITAL_GET_BANK2, &tmp) != 0)
00245 return false;
00246 break;
00247 case 3:
00248 if (ioctl(myFD, DIGITAL_GET_BANK3, &tmp) != 0)
00249 return false;
00250 break;
00251 default:
00252 return false;
00253 }
00254
00255
00256 *val = ~tmp;
00257 return true;
00258 }
00259
00260
00268 AREXPORT bool ArVersalogicIO::getDigitalBankOutputs(int bank, unsigned char *val)
00269 {
00270 if (!myEnabled)
00271 return false;
00272
00273 if (bank < 0 || bank > myNumBanks - 1)
00274 return false;
00275
00276
00277 switch (bank)
00278 {
00279 case 0:
00280 *val = myDigitalBank0;
00281 break;
00282 case 1:
00283 *val = myDigitalBank1;
00284 break;
00285 case 2:
00286 *val = myDigitalBank2;
00287 break;
00288 case 3:
00289 *val = myDigitalBank3;
00290 break;
00291 }
00292
00293 return true;
00294 }
00295
00304 AREXPORT bool ArVersalogicIO::setDigitalBankOutputs(int bank, unsigned char val)
00305 {
00306 if (!myEnabled)
00307 return false;
00308
00309 if (bank < 0 || bank > myNumBanks - 1)
00310 return false;
00311
00312
00313 switch (bank)
00314 {
00315 case 0:
00316 if (ioctl(myFD, DIGITAL_SET_BANK0, ~val) != 0)
00317 return false;
00318 myDigitalBank0 = val;
00319 break;
00320 case 1:
00321 if (ioctl(myFD, DIGITAL_SET_BANK1, ~val) != 0)
00322 return false;
00323 myDigitalBank1 = val;
00324 break;
00325 case 2:
00326 if (ioctl(myFD, DIGITAL_SET_BANK2, ~val) != 0)
00327 return false;
00328 myDigitalBank2 = val;
00329 break;
00330 case 3:
00331 if (ioctl(myFD, DIGITAL_SET_BANK3, ~val) != 0)
00332 return false;
00333 myDigitalBank3 = val;
00334 break;
00335 default:
00336 return false;
00337 }
00338
00339 return true;
00340 }
00341
00348 AREXPORT bool ArVersalogicIO::getSpecialControlRegister(unsigned char *val)
00349 {
00350 if (!myEnabled)
00351 return false;
00352
00353 unsigned char tmp;
00354 if (ioctl(myFD, GET_SPECIAL_CONTROL_REGISTER, &tmp) != 0)
00355 return false;
00356
00357 *val = tmp;
00358 return true;
00359 }