00001 #include <string.h>
00002 #include <assert.h>
00003 #include "stdafx.h"
00004 #include "cphidgetbridge.h"
00005 #include "cusb.h"
00006 #include "csocket.h"
00007 #include "cthread.h"
00008
00009
00010
00011
00012 CPHIDGETCLEARVARS(Bridge)
00013 int i = 0;
00014
00015 for (i = 0; i<BRIDGE_MAXINPUTS; i++)
00016 {
00017 phid->bridgeMin[i] = PUNI_DBL;
00018 phid->bridgeMax[i] = PUNI_DBL;
00019 phid->enabledEcho[i] = PUNI_BOOL;
00020 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_UNKNOWN;
00021 phid->bridgeValue[i] = PUNI_DBL;
00022
00023 phid->enabled[i] = PUNK_BOOL;
00024 phid->gain[i] = PHIDGET_BRIDGE_GAIN_UNKNOWN;
00025 phid->chEnabledBugNotValid[i] = PFALSE;
00026 }
00027 phid->ch0EnableOverride = 0;
00028 phid->dataRateEcho = PUNI_INT;
00029 phid->dataRateMin = PUNI_INT;
00030 phid->dataRateMax = PUNI_INT;
00031
00032 return EPHIDGET_OK;
00033 }
00034
00035
00036
00037 CPHIDGETINIT(Bridge)
00038 int i;
00039 TESTPTR(phid);
00040
00041
00042 phid->outputPacketLen = 0;
00043
00044
00045 switch(phid->phid.deviceIDSpec)
00046 {
00047 case PHIDID_BRIDGE_4INPUT:
00048 switch(phid->phid.deviceUID)
00049 {
00050 case PHIDUID_BRIDGE_4INPUT_GAINBUG:
00051 case PHIDUID_BRIDGE_4INPUT:
00052 phid->dataRateMin = 1000;
00053 phid->dataRateMax = 8;
00054 break;
00055 default:
00056 return EPHIDGET_BADVERSION;
00057 }
00058 break;
00059 default:
00060 return EPHIDGET_UNEXPECTED;
00061 }
00062
00063 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00064 {
00065 phid->bridgeMin[i] = PUNK_DBL;
00066 phid->bridgeMax[i] = PUNK_DBL;
00067 phid->bridgeValue[i] = PUNK_DBL;
00068 phid->enabledEcho[i] = PUNK_BOOL;
00069 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_UNKNOWN;
00070 phid->outOfRange[i] = PFALSE;
00071 phid->lastOutOfRange[i] = PFALSE;
00072 phid->chEnabledBugNotValid[i] = PFALSE;
00073 }
00074 phid->ch0EnableOverride = 0;
00075 phid->dataRateEcho = PUNK_INT;
00076
00077
00078 while(CPhidget_read((CPhidgetHandle)phid)) SLEEP(8);
00079
00080
00081 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00082 {
00083 phid->enabled[i] = phid->enabledEcho[i];
00084 phid->gain[i] = phid->gainEcho[i];
00085 }
00086 phid->dataRate = phid->dataRateEcho;
00087
00088 return EPHIDGET_OK;
00089 }
00090
00091
00092 CPHIDGETDATA(Bridge)
00093 int i = 0;
00094 int bridgeRawVal;
00095 double bridgeVal;
00096 int dataRateRaw;
00097 double gain;
00098 int roundingFactor = 0;
00099 unsigned char err = PFALSE;
00100 char error_buffer[200];
00101 double bridgeval[BRIDGE_MAXINPUTS];
00102
00103 if (length < 0) return EPHIDGET_INVALIDARG;
00104 TESTPTR(phid);
00105 TESTPTR(buffer);
00106
00107 switch(phid->phid.deviceUID)
00108 {
00109 case PHIDUID_BRIDGE_4INPUT_GAINBUG:
00110 case PHIDUID_BRIDGE_4INPUT:
00111 {
00112
00113 dataRateRaw = ((buffer[4] & 0x03) << 8) + buffer[5];
00114
00115 phid->dataRateEcho = dataRateRaw * 8;
00116
00117 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00118 {
00119
00120 switch(buffer[(i/2)+2] >> (i%2?0:4) & 0x0F)
00121 {
00122 case 0x00:
00123 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_1;
00124 gain = 1;
00125 roundingFactor = 5;
00126 break;
00127 case 0x03:
00128 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_8;
00129 gain = 8;
00130 roundingFactor = 6;
00131 break;
00132 case 0x04:
00133 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_16;
00134 gain = 16;
00135 roundingFactor = 7;
00136 break;
00137 case 0x05:
00138 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_32;
00139 gain = 32;
00140 roundingFactor = 7;
00141 break;
00142 case 0x06:
00143 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_64;
00144 gain = 64;
00145 roundingFactor = 7;
00146 break;
00147 case 0x07:
00148 phid->gainEcho[i] = PHIDGET_BRIDGE_GAIN_128;
00149 gain = 128;
00150 roundingFactor = 8;
00151 break;
00152 }
00153
00154 if(gain == 1)
00155 {
00156 phid->bridgeMax[i] = 1000;
00157 phid->bridgeMin[i] = -1000;
00158 }
00159 else
00160 {
00161
00162 phid->bridgeMax[i] = 995/gain;
00163 phid->bridgeMin[i] = -995/gain;
00164 }
00165
00166 phid->enabledEcho[i] = (buffer[0] & (0x01 << i)) ? PTRUE : PFALSE;
00167 if(phid->enabledEcho[i] && (buffer[0] & (0x10 << i)))
00168 {
00169
00170 if(phid->chEnabledBugNotValid[i] == PTRUE)
00171 {
00172 bridgeval[i] = PUNK_DBL;
00173 phid->chEnabledBugNotValid[i] = PFALSE;
00174 }
00175 else
00176 {
00177 bridgeRawVal = (buffer[i*3 + 6] << 16) + (buffer[i*3 + 7] << 8) + buffer[i*3 + 8];
00178 bridgeVal = round_double(((bridgeRawVal - 0x800000) / (double)0x800000) * 1000.0 / (double)gain, roundingFactor);
00179
00180 err = (buffer[1] & (0x01 << i)) ? PTRUE : PFALSE;
00181
00182 if(err || bridgeVal > phid->bridgeMax[i] || bridgeVal < phid->bridgeMin[i])
00183 {
00184 bridgeval[i] = PUNK_DBL;
00185
00186 if(!phid->lastOutOfRange[i])
00187 {
00188 if(bridgeVal > phid->bridgeMax[i])
00189 {
00190 FIRE_ERROR(EEPHIDGET_OUTOFRANGE, "Overrange condition detected on input %d, try lowering the gain.",i);
00191 }
00192 else if(bridgeVal < phid->bridgeMin[i])
00193 {
00194 FIRE_ERROR(EEPHIDGET_OUTOFRANGE, "Underrange condition detected on input %d, try lowering the gain.",i);
00195 }
00196 }
00197 phid->lastOutOfRange[i] = PTRUE;
00198 }
00199 else
00200 {
00201 if(phid->lastOutOfRange[i])
00202 {
00203 FIRE_ERROR(EEPHIDGET_OUTOFRANGE, "Input %d out of range state ended.", i);
00204 }
00205 phid->lastOutOfRange[i] = PFALSE;
00206
00207 bridgeval[i] = bridgeVal;
00208 }
00209 }
00210 }
00211 else if(!phid->enabledEcho[i])
00212 {
00213 bridgeval[i] = PUNK_DBL;
00214 }
00215 else
00216 bridgeval[i] = PUNI_DBL;
00217
00218
00219 if(phid->ch0EnableOverride)
00220 phid->ch0EnableOverride--;
00221 }
00222 }
00223 break;
00224 default:
00225 return EPHIDGET_UNEXPECTED;
00226 }
00227
00228 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00229 {
00230 if (bridgeval[i] != PUNI_DBL)
00231 {
00232 phid->bridgeValue[i] = bridgeval[i];
00233 }
00234 }
00235
00236
00237 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00238 {
00239 if (bridgeval[i] != PUNI_DBL &&phid->bridgeValue[i] != PUNK_DBL)
00240 {
00241 FIRE(BridgeData, i, phid->bridgeValue[i]);
00242 }
00243 }
00244
00245 return EPHIDGET_OK;
00246 }
00247
00248
00249 CPHIDGETINITEVENTS(Bridge)
00250
00251 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00252 {
00253 if (phid->bridgeValue[i] != PUNK_DBL)
00254 {
00255 FIRE(BridgeData, i, phid->bridgeValue[i]);
00256 }
00257 }
00258
00259 return EPHIDGET_OK;
00260 }
00261
00262
00263 CGETPACKET_BUF(Bridge)
00264
00265
00266 CSENDPACKET_BUF(Bridge)
00267
00268
00269 CMAKEPACKET(Bridge)
00270 TESTPTRS(phid, buffer);
00271
00272 switch(phid->phid.deviceUID)
00273 {
00274 case PHIDUID_BRIDGE_4INPUT_GAINBUG:
00275 case PHIDUID_BRIDGE_4INPUT:
00276 {
00277 int i;
00278 int dataRateRaw;
00279 int gainRaw;
00280
00281
00282 dataRateRaw = phid->dataRate / 8;
00283
00284 buffer[0] = 0;
00285 buffer[1] = 0;
00286 buffer[2] = 0;
00287 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00288 {
00289
00290 if(phid->phid.deviceUID == PHIDUID_BRIDGE_4INPUT_GAINBUG)
00291 {
00292 if(phid->gain[i] != phid->gainEcho[i])
00293 {
00294
00295 phid->ch0EnableOverride = 256 / 8;
00296 }
00297
00298 if(phid->enabledEcho[i] == PFALSE && phid->enabled[i] == PTRUE)
00299 {
00300
00301 phid->chEnabledBugNotValid[i] = PTRUE;
00302 }
00303 }
00304
00305 if(phid->enabled[i])
00306 buffer[0] |= (0x01<<i);
00307
00308 switch(phid->gain[i])
00309 {
00310 case PHIDGET_BRIDGE_GAIN_1:
00311 case PHIDGET_BRIDGE_GAIN_UNKNOWN:
00312 gainRaw = 0x00;
00313 break;
00314 case PHIDGET_BRIDGE_GAIN_8:
00315 gainRaw = 0x03;
00316 break;
00317 case PHIDGET_BRIDGE_GAIN_16:
00318 gainRaw = 0x04;
00319 break;
00320 case PHIDGET_BRIDGE_GAIN_32:
00321 gainRaw = 0x05;
00322 break;
00323 case PHIDGET_BRIDGE_GAIN_64:
00324 gainRaw = 0x06;
00325 break;
00326 case PHIDGET_BRIDGE_GAIN_128:
00327 gainRaw = 0x07;
00328 break;
00329 }
00330 buffer[(i/2)+1] |= gainRaw << (i%2?0:4);
00331 }
00332
00333
00334 if(phid->phid.deviceUID == PHIDUID_BRIDGE_4INPUT_GAINBUG && phid->ch0EnableOverride)
00335 {
00336
00337 buffer[0] |= 0x01;
00338 }
00339
00340 buffer[3] = dataRateRaw & 0xFF;
00341 buffer[4] = (dataRateRaw >> 8) & 0x03;
00342
00343 }
00344 break;
00345 default:
00346 return EPHIDGET_UNEXPECTED;
00347 }
00348
00349 return EPHIDGET_OK;
00350 }
00351
00352
00353
00354
00355 CCREATE(Bridge, PHIDCLASS_BRIDGE)
00356
00357
00358 CFHANDLE(Bridge, BridgeData, int, double)
00359
00360 CGET(Bridge,InputCount,int)
00361 TESTPTRS(phid,pVal)
00362 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00363 TESTATTACHED
00364
00365 MASGN(phid.attr.bridge.numBridgeInputs)
00366 }
00367
00368 CGETINDEX(Bridge,BridgeValue,double)
00369 TESTPTRS(phid,pVal)
00370 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00371 TESTATTACHED
00372 TESTINDEX(phid.attr.bridge.numBridgeInputs)
00373 TESTMASGN(bridgeValue[Index], PUNK_DBL)
00374
00375 MASGN(bridgeValue[Index])
00376 }
00377
00378 CGETINDEX(Bridge,BridgeMax,double)
00379 TESTPTRS(phid,pVal)
00380 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00381 TESTATTACHED
00382 TESTINDEX(phid.attr.bridge.numBridgeInputs)
00383 TESTMASGN(bridgeMax[Index], PUNK_DBL)
00384
00385 MASGN(bridgeMax[Index])
00386 }
00387
00388 CGETINDEX(Bridge,BridgeMin,double)
00389 TESTPTRS(phid,pVal)
00390 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00391 TESTATTACHED
00392 TESTINDEX(phid.attr.bridge.numBridgeInputs)
00393 TESTMASGN(bridgeMin[Index], PUNK_DBL)
00394
00395 MASGN(bridgeMin[Index])
00396 }
00397
00398 CGETINDEX(Bridge,Enabled,int)
00399 TESTPTRS(phid,pVal)
00400 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00401 TESTATTACHED
00402 TESTINDEX(phid.attr.bridge.numBridgeInputs)
00403 TESTMASGN(enabledEcho[Index], PUNK_BOOL)
00404
00405 MASGN(enabledEcho[Index])
00406 }
00407 CSETINDEX(Bridge,Enabled,int)
00408 TESTPTR(phid)
00409 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00410 TESTATTACHED
00411 TESTRANGE(PFALSE, PTRUE)
00412 TESTINDEX(phid.attr.bridge.numBridgeInputs)
00413
00414 if(newVal == PFALSE) phid->bridgeValue[Index] = PUNK_DBL;
00415
00416 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00417 ADDNETWORKKEYINDEXED(Enabled, "%d", enabled);
00418 else
00419 SENDPACKET(Bridge, enabled[Index]);
00420
00421 return EPHIDGET_OK;
00422 }
00423
00424 CGETINDEX(Bridge,Gain,CPhidgetBridge_Gain)
00425 TESTPTRS(phid,pVal)
00426 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00427 TESTATTACHED
00428 TESTINDEX(phid.attr.bridge.numBridgeInputs)
00429 TESTMASGN(gainEcho[Index], PHIDGET_BRIDGE_GAIN_UNKNOWN)
00430
00431 MASGN(gainEcho[Index])
00432 }
00433 CSETINDEX(Bridge,Gain,CPhidgetBridge_Gain)
00434 TESTPTR(phid)
00435 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00436 TESTATTACHED
00437 TESTRANGE(PHIDGET_BRIDGE_GAIN_1, PHIDGET_BRIDGE_GAIN_128)
00438 TESTINDEX(phid.attr.bridge.numBridgeInputs)
00439
00440 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00441 ADDNETWORKKEYINDEXED(Gain, "%d", gain);
00442 else
00443 SENDPACKET(Bridge, gain[Index]);
00444
00445 return EPHIDGET_OK;
00446 }
00447
00448 CSET(Bridge,DataRate,int)
00449 TESTPTR(phid)
00450 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00451 TESTATTACHED
00452 TESTRANGE(phid->dataRateMax, phid->dataRateMin)
00453
00454 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00455 ADDNETWORKKEY(DataRate, "%d", dataRate);
00456 else
00457 SENDPACKET(Bridge, dataRate);
00458
00459 return EPHIDGET_OK;
00460 }
00461 CGET(Bridge,DataRate,int)
00462 TESTPTRS(phid,pVal)
00463 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00464 TESTATTACHED
00465 TESTMASGN(dataRateEcho, PUNK_INT)
00466
00467 MASGN(dataRateEcho)
00468 }
00469
00470 CGET(Bridge,DataRateMax,int)
00471 TESTPTRS(phid,pVal)
00472 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00473 TESTATTACHED
00474 TESTMASGN(dataRateMax, PUNK_INT)
00475
00476 MASGN(dataRateMax)
00477 }
00478
00479 CGET(Bridge,DataRateMin,int)
00480 TESTPTRS(phid,pVal)
00481 TESTDEVICETYPE(PHIDCLASS_BRIDGE)
00482 TESTATTACHED
00483 TESTMASGN(dataRateMin, PUNK_INT)
00484
00485 MASGN(dataRateMin)
00486 }