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 }