cphidgetbridge.c
Go to the documentation of this file.
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 // === Internal Functions === //
00010 
00011 //clearVars - sets all device variables to unknown state
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 //initAfterOpen - sets up the initial state of an object, reading in packets from the device if needed
00036 //                                used during attach initialization - on every attach
00037 CPHIDGETINIT(Bridge)
00038         int i;
00039         TESTPTR(phid);
00040 
00041         //Make sure no old writes are still pending
00042         phid->outputPacketLen = 0;
00043 
00044         //Setup max/min values
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         //read in initial state - read until it returns 0
00078         while(CPhidget_read((CPhidgetHandle)phid)) SLEEP(8);
00079 
00080         //recover what we can, set others to unknown
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 //dataInput - parses device packets
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                                 //Output Data Rate (Hz) = dataRateRaw * 8
00113                                 dataRateRaw = ((buffer[4] & 0x03) << 8) + buffer[5];
00114                                 //in ms
00115                                 phid->dataRateEcho = dataRateRaw * 8;
00116 
00117                                 for (i = 0; i<phid->phid.attr.bridge.numBridgeInputs; i++)
00118                                 {
00119                                         //gain
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                                                 //with PGA, allow +-99.5%, because if doesn't clamp properly
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))) //enabled and have data
00168                                         {
00169                                                 //Don't count data this time - wait for next event
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                                         //decrement until 0 - this is related to a firmware bug
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         //Send out events
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 //eventsAfterOpen - sends out an event for all valid data, used during attach initialization
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 //getPacket - used by write thread to get the next packet to send to device
00263 CGETPACKET_BUF(Bridge)
00264 
00265 //sendpacket - sends a packet to the device asynchronously, blocking if the 1-packet queue is full
00266 CSENDPACKET_BUF(Bridge)
00267 
00268 //makePacket - constructs a packet using current device state
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                                 //ms->raw
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                                         //Deal with some firmware bugs
00290                                         if(phid->phid.deviceUID == PHIDUID_BRIDGE_4INPUT_GAINBUG)
00291                                         {
00292                                                 if(phid->gain[i] != phid->gainEcho[i])
00293                                                 {
00294                                                         //anytime we change gain on any channel, we have to enable channel 0, and leave it enabled for at least 250ms
00295                                                         phid->ch0EnableOverride = 256 / 8; //USB interval is 8ms, this is decremented by one each DATA packet until it gets back to 0.
00296                                                 }
00297 
00298                                                 if(phid->enabledEcho[i] == PFALSE && phid->enabled[i] == PTRUE)
00299                                                 {
00300                                                         //1st data after a channel is enabled can be bad, so we just ignore this.
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                                 //Deal with some firmware bugs
00334                                 if(phid->phid.deviceUID == PHIDUID_BRIDGE_4INPUT_GAINBUG && phid->ch0EnableOverride)
00335                                 {
00336                                         //override and enable ch0
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 // === Exported Functions === //
00353 
00354 //create and initialize a device structure
00355 CCREATE(Bridge, PHIDCLASS_BRIDGE)
00356 
00357 //event setup functions
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 }


pedal_monitor
Author(s): Pedro Mendes
autogenerated on Fri Jun 6 2014 18:37:20