00001 #include "stdafx.h"
00002 #include "cphidgetanalog.h"
00003 #include "cusb.h"
00004 #include "csocket.h"
00005 #include "cthread.h"
00006
00007
00008
00009
00010 CPHIDGETCLEARVARS(Analog)
00011 int i = 0;
00012
00013 for(i=0;i<ANALOG_MAXOUTPUTS;i++)
00014 {
00015 phid->changedVoltage[i] = PUNK_BOOL;
00016 phid->nextVoltage[i] = PUNK_DBL;
00017
00018 phid->changedEnabled[i] = PUNK_BOOL;
00019 phid->nextEnabled[i] = PUNK_BOOL;
00020
00021 phid->enabled[i] = PUNK_BOOL;
00022 phid->voltage[i] = PUNK_DBL;
00023
00024 phid->voltageEcho[i] = PUNI_DBL;
00025 phid->enabledEcho[i] = PUNI_BOOL;
00026 }
00027 phid->voltageMax = PUNI_DBL;
00028 phid->voltageMin = PUNI_DBL;
00029
00030 return EPHIDGET_OK;
00031 }
00032
00033
00034
00035 CPHIDGETINIT(Analog)
00036 int i = 0;
00037
00038 TESTPTR(phid);
00039
00040
00041 switch(phid->phid.deviceIDSpec)
00042 {
00043 case PHIDID_ANALOG_4OUTPUT:
00044 if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
00045 {
00046 for(i=0;i<phid->phid.attr.analog.numAnalogOutputs;i++)
00047 {
00048 phid->changedVoltage[i] = PFALSE;
00049 phid->nextVoltage[i] = PUNK_DBL;
00050
00051 phid->changedEnabled[i] = PFALSE;
00052 phid->nextEnabled[i] = PUNK_BOOL;
00053
00054 phid->enabled[i] = PUNK_BOOL;
00055 phid->voltage[i] = PUNK_DBL;
00056
00057 phid->voltageEcho[i] = PUNK_DBL;
00058 phid->enabledEcho[i] = PUNK_BOOL;
00059
00060 phid->lastOvercurrent[i] = PFALSE;
00061 }
00062 phid->voltageMax = 10;
00063 phid->voltageMin = -10;
00064
00065 phid->lastTsd = PFALSE;
00066 }
00067 else
00068 return EPHIDGET_BADVERSION;
00069 break;
00070 default:
00071 return EPHIDGET_UNEXPECTED;
00072 }
00073 phid->controlPacketWaiting = PFALSE;
00074
00075
00076 CPhidget_read((CPhidgetHandle)phid);
00077 for(i=0;i<phid->phid.attr.analog.numAnalogOutputs;i++)
00078 {
00079 phid->voltage[i] = phid->voltageEcho[i];
00080 phid->enabled[i] = phid->enabledEcho[i];
00081 }
00082
00083 return EPHIDGET_OK;
00084 }
00085
00086
00087 CPHIDGETDATA(Analog)
00088 int i = 0;
00089 char error_buffer[128];
00090 unsigned char overcurrent[ANALOG_MAXOUTPUTS] = {PFALSE};
00091 unsigned char tsd = PFALSE;
00092 int iVoltage;
00093
00094 if (length < 0) return EPHIDGET_INVALIDARG;
00095 TESTPTR(phid);
00096 TESTPTR(buffer);
00097
00098 switch(phid->phid.deviceIDSpec)
00099 {
00100 case PHIDID_ANALOG_4OUTPUT:
00101 if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
00102 {
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 for (i = 0; i < phid->phid.attr.analog.numAnalogOutputs; i++)
00115 {
00116 iVoltage = (((signed char)buffer[i*2 + 3]) << 4) + (buffer[i*2 + 2] >> 4);
00117 phid->voltageEcho[i] = round_double((iVoltage * 10 / 2047.0), 3);
00118 phid->enabledEcho[i] = (buffer[0] & (0x01 << i)) ? PTRUE : PFALSE;
00119 overcurrent[i] = (buffer[0] & (0x10 << i)) ? PTRUE : PFALSE;
00120 }
00121 tsd = buffer[1];
00122 }
00123 else
00124 return EPHIDGET_UNEXPECTED;
00125 break;
00126 default:
00127 return EPHIDGET_UNEXPECTED;
00128 }
00129
00130 for (i = 0; i < phid->phid.attr.analog.numAnalogOutputs; i++)
00131 {
00132 if(overcurrent[i] && !phid->lastOvercurrent[i])
00133 {
00134 FIRE_ERROR(EEPHIDGET_OVERCURRENT, "Output %d is trying to draw > 20mA - possible short circuit.", i);
00135 }
00136 else if(!overcurrent[i] && phid->lastOvercurrent[i])
00137 {
00138 FIRE_ERROR(EEPHIDGET_OK, "Output %d overcurrent state ended.", i);
00139 }
00140 phid->lastOvercurrent[i] = overcurrent[i];
00141 }
00142 if(tsd && !phid->lastTsd)
00143 {
00144 FIRE_ERROR(EEPHIDGET_OVERTEMP, "Thermal shutdown detected. All outputs have been disabled.");
00145 }
00146 else if(!tsd && phid->lastTsd)
00147 {
00148 FIRE_ERROR(EEPHIDGET_OK, "Thermal shutdown state ended.");
00149 }
00150 phid->lastTsd = tsd;
00151
00152 return EPHIDGET_OK;
00153 }
00154
00155
00156 CPHIDGETINITEVENTS(Analog)
00157 phid = 0;
00158 return EPHIDGET_OK;
00159 }
00160
00161
00162 CGETPACKET(Analog)
00163 int i = 0;
00164 int iVoltage;
00165
00166 CPhidgetAnalogHandle phid = (CPhidgetAnalogHandle)phidG;
00167
00168 TESTPTRS(phid, buf)
00169 TESTPTR(lenp)
00170
00171 if (*lenp < phid->phid.outputReportByteLength)
00172 return EPHIDGET_INVALIDARG;
00173
00174 CThread_mutex_lock(&phid->phid.outputLock);
00175
00176 switch(phid->phid.deviceIDSpec)
00177 {
00178 case PHIDID_ANALOG_4OUTPUT:
00179 if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
00180 {
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 for (i = 0; i < phid->phid.attr.analog.numAnalogOutputs; i++)
00191 {
00192 if (phid->changedVoltage[i]) {
00193 phid->voltage[i] = phid->nextVoltage[i];
00194 phid->changedVoltage[i] = PFALSE;
00195 phid->nextVoltage[i] = PUNK_DBL;
00196 }
00197 if (phid->changedEnabled[i]) {
00198 phid->enabled[i] = phid->nextEnabled[i];
00199 phid->changedEnabled[i] = PFALSE;
00200 phid->nextEnabled[i] = PUNK_BOOL;
00201 }
00202
00203 iVoltage = round(phid->voltage[i] * 2047 / 10.0);
00204 buf[i*2] = iVoltage << 4;
00205 buf[i*2 + 1] = iVoltage >> 4;
00206 if(phid->enabled[i])
00207 buf[0] |= 1<<i;
00208 }
00209 }
00210 else
00211 return EPHIDGET_UNEXPECTED;
00212 break;
00213 default:
00214 return EPHIDGET_UNEXPECTED;
00215 }
00216
00217 *lenp = phid->phid.outputReportByteLength;
00218
00219 CThread_mutex_unlock(&phid->phid.outputLock);
00220
00221 return EPHIDGET_OK;
00222 }
00223
00224
00225
00226 static int CCONV CPhidgetAnalog_sendPacket_setVoltage(CPhidgetAnalogHandle phid, unsigned int index, double voltage)
00227 {
00228 int waitReturn;
00229 CThread_mutex_lock(&phid->phid.writelock);
00230 again:
00231 if (!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG))
00232 {
00233 CThread_mutex_unlock(&phid->phid.writelock);
00234 return EPHIDGET_NOTATTACHED;
00235 }
00236 CThread_mutex_lock(&phid->phid.outputLock);
00237
00238 if (phid->changedVoltage[index]) {
00239
00240 if (phid->nextVoltage[index] != voltage) {
00241 CThread_mutex_unlock(&phid->phid.outputLock);
00242
00243 waitReturn = CThread_wait_on_event(&phid->phid.writtenEvent, 2500);
00244 switch(waitReturn)
00245 {
00246 case WAIT_OBJECT_0:
00247 break;
00248 case WAIT_ABANDONED:
00249 CThread_mutex_unlock(&phid->phid.writelock);
00250 return EPHIDGET_UNEXPECTED;
00251 case WAIT_TIMEOUT:
00252 CThread_mutex_unlock(&phid->phid.writelock);
00253 return EPHIDGET_TIMEOUT;
00254 }
00255
00256 goto again;
00257 } else {
00258 CThread_mutex_unlock(&phid->phid.outputLock);
00259 CThread_mutex_unlock(&phid->phid.writelock);
00260 return EPHIDGET_OK;
00261 }
00262
00263 } else {
00264
00265 if (phid->voltage[index] != voltage) {
00266 phid->changedVoltage[index] = PTRUE;
00267 phid->nextVoltage[index] = voltage;
00268 CThread_reset_event(&phid->phid.writtenEvent);
00269 CThread_mutex_unlock(&phid->phid.outputLock);
00270 CThread_set_event(&phid->phid.writeAvailableEvent);
00271 }
00272
00273 else
00274 {
00275 CThread_mutex_unlock(&phid->phid.outputLock);
00276 CThread_mutex_unlock(&phid->phid.writelock);
00277 return EPHIDGET_OK;
00278 }
00279 }
00280 CThread_mutex_unlock(&phid->phid.writelock);
00281 return EPHIDGET_OK;
00282 }
00283
00284
00285
00286 static int CCONV CPhidgetAnalog_sendPacket_setEnabled(CPhidgetAnalogHandle phid, unsigned int index, int enabled)
00287 {
00288 int waitReturn;
00289 CThread_mutex_lock(&phid->phid.writelock);
00290 again:
00291 if (!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG))
00292 {
00293 CThread_mutex_unlock(&phid->phid.writelock);
00294 return EPHIDGET_NOTATTACHED;
00295 }
00296 CThread_mutex_lock(&phid->phid.outputLock);
00297
00298 if (phid->changedEnabled[index]) {
00299
00300 if (phid->nextEnabled[index] != enabled) {
00301 CThread_mutex_unlock(&phid->phid.outputLock);
00302
00303 waitReturn = CThread_wait_on_event(&phid->phid.writtenEvent, 2500);
00304 switch(waitReturn)
00305 {
00306 case WAIT_OBJECT_0:
00307 break;
00308 case WAIT_ABANDONED:
00309 CThread_mutex_unlock(&phid->phid.writelock);
00310 return EPHIDGET_UNEXPECTED;
00311 case WAIT_TIMEOUT:
00312 CThread_mutex_unlock(&phid->phid.writelock);
00313 return EPHIDGET_TIMEOUT;
00314 }
00315
00316 goto again;
00317 } else {
00318 CThread_mutex_unlock(&phid->phid.outputLock);
00319 CThread_mutex_unlock(&phid->phid.writelock);
00320 return EPHIDGET_OK;
00321 }
00322
00323 } else {
00324
00325 if (phid->enabled[index] != enabled) {
00326 phid->changedEnabled[index] = PTRUE;
00327 phid->nextEnabled[index] = enabled;
00328 CThread_reset_event(&phid->phid.writtenEvent);
00329 CThread_mutex_unlock(&phid->phid.outputLock);
00330 CThread_set_event(&phid->phid.writeAvailableEvent);
00331 }
00332
00333 else
00334 {
00335 CThread_mutex_unlock(&phid->phid.outputLock);
00336 CThread_mutex_unlock(&phid->phid.writelock);
00337 return EPHIDGET_OK;
00338 }
00339 }
00340 CThread_mutex_unlock(&phid->phid.writelock);
00341 return EPHIDGET_OK;
00342 }
00343
00344
00345
00346
00347 CCREATE(Analog, PHIDCLASS_ANALOG)
00348
00349 CGET(Analog,OutputCount,int)
00350 TESTPTRS(phid,pVal)
00351 TESTDEVICETYPE(PHIDCLASS_ANALOG)
00352 TESTATTACHED
00353
00354 MASGN(phid.attr.analog.numAnalogOutputs)
00355 }
00356
00357 CGETINDEX(Analog,Voltage,double)
00358 TESTPTRS(phid,pVal)
00359 TESTDEVICETYPE(PHIDCLASS_ANALOG)
00360 TESTATTACHED
00361 TESTINDEX(phid.attr.analog.numAnalogOutputs)
00362 TESTMASGN(voltageEcho[Index], PUNK_DBL)
00363
00364 MASGN(voltageEcho[Index])
00365 }
00366
00367 CSETINDEX(Analog,Voltage,double)
00368 TESTPTR(phid)
00369 TESTDEVICETYPE(PHIDCLASS_ANALOG)
00370 TESTATTACHED
00371 TESTRANGE(phid->voltageMin, phid->voltageMax)
00372 TESTINDEX(phid.attr.analog.numAnalogOutputs)
00373
00374 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00375 ADDNETWORKKEYINDEXED(Voltage, "%lf", voltage);
00376 else
00377 return CPhidgetAnalog_sendPacket_setVoltage(phid, Index, newVal);
00378
00379 return EPHIDGET_OK;
00380 }
00381
00382 CGETINDEX(Analog,VoltageMax,double)
00383 TESTPTRS(phid,pVal)
00384 TESTDEVICETYPE(PHIDCLASS_ANALOG)
00385 TESTATTACHED
00386 TESTINDEX(phid.attr.analog.numAnalogOutputs)
00387 TESTMASGN(voltageMax, PUNK_DBL)
00388
00389 MASGN(voltageMax)
00390 }
00391
00392 CGETINDEX(Analog,VoltageMin,double)
00393 TESTPTRS(phid,pVal)
00394 TESTDEVICETYPE(PHIDCLASS_ANALOG)
00395 TESTATTACHED
00396 TESTINDEX(phid.attr.analog.numAnalogOutputs)
00397 TESTMASGN(voltageMin, PUNK_DBL)
00398
00399 MASGN(voltageMin)
00400 }
00401
00402 CGETINDEX(Analog,Enabled,int)
00403 TESTPTRS(phid,pVal)
00404 TESTDEVICETYPE(PHIDCLASS_ANALOG)
00405 TESTATTACHED
00406 TESTINDEX(phid.attr.analog.numAnalogOutputs)
00407 TESTMASGN(enabledEcho[Index], PUNK_BOOL)
00408
00409 MASGN(enabledEcho[Index])
00410 }
00411 CSETINDEX(Analog,Enabled,int)
00412 TESTPTR(phid)
00413 TESTDEVICETYPE(PHIDCLASS_ANALOG)
00414 TESTATTACHED
00415 TESTRANGE(PFALSE, PTRUE)
00416 TESTINDEX(phid.attr.analog.numAnalogOutputs)
00417
00418 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00419 ADDNETWORKKEYINDEXED(Enabled, "%d", enabled);
00420 else
00421 return CPhidgetAnalog_sendPacket_setEnabled(phid, Index, newVal);
00422
00423 return EPHIDGET_OK;
00424 }