00001 #include "stdafx.h"
00002 #include "cphidgetencoder.h"
00003 #include <stdio.h>
00004 #include "cusb.h"
00005 #include "csocket.h"
00006 #include "cthread.h"
00007
00008
00009
00010
00011 CPHIDGETCLEARVARS(Encoder)
00012 int i = 0;
00013 for (i = 0; i<ENCODER_MAXINPUTS; i++)
00014 {
00015 phid->inputState[i] = PUNK_BOOL;
00016 }
00017 for (i = 0; i<ENCODER_MAXENCODERS; i++)
00018 {
00019 phid->encoderPosition[i] = 0;
00020 phid->encoderTimeStamp[i] = PUNK_INT;
00021 phid->indexPosition[i] = PUNK_INT;
00022 phid->enableStateEcho[i] = PUNI_BOOL;
00023 }
00024 return EPHIDGET_OK;
00025 }
00026
00027
00028
00029 CPHIDGETINIT(Encoder)
00030 int i = 0;
00031 unsigned char buffer[8] = { 0 };
00032 int result;
00033
00034 TESTPTR(phid);
00035
00036
00037 phid->outputPacketLen = 0;
00038
00039
00040 for (i = 0; i<phid->phid.attr.encoder.numInputs; i++)
00041 {
00042 phid->inputState[i] = PUNK_BOOL;
00043 }
00044 for (i = 0; i<phid->phid.attr.encoder.numEncoders; i++)
00045 {
00046 phid->encoderPosition[i] = 0;
00047 phid->encoderTimeStamp[i] = PUNK_INT;
00048 phid->indexPosition[i] = PUNK_INT;
00049 switch(phid->phid.deviceIDSpec) {
00050 case PHIDID_ENCODER_HS_4ENCODER_4INPUT:
00051 phid->enableState[i] = PUNK_BOOL;
00052 phid->enableStateEcho[i] = PUNK_BOOL;
00053 break;
00054 case PHIDID_ENCODER_1ENCODER_1INPUT:
00055 case PHIDID_ENCODER_HS_1ENCODER:
00056 phid->enableState[i] = PTRUE;
00057 phid->enableStateEcho[i] = PTRUE;
00058 break;
00059 default:
00060 break;
00061 }
00062 }
00063
00064
00065 switch(phid->phid.deviceIDSpec) {
00066 case PHIDID_ENCODER_1ENCODER_1INPUT:
00067 if (phid->phid.deviceVersion <= 100)
00068 {
00069 ZEROMEM(buffer,8);
00070 LOG(PHIDGET_LOG_INFO,"Sending workaround startup packet");
00071 if ((result = CUSBSendPacket((CPhidgetHandle)phid, buffer)) != EPHIDGET_OK)
00072 return result;
00073 }
00074 break;
00075 case PHIDID_ENCODER_HS_1ENCODER:
00076 case PHIDID_ENCODER_HS_4ENCODER_4INPUT:
00077 default:
00078 break;
00079 }
00080
00081
00082 switch(phid->phid.deviceIDSpec) {
00083 case PHIDID_ENCODER_HS_4ENCODER_4INPUT:
00084 if (phid->phid.deviceVersion >= 100 && phid->phid.deviceVersion < 200)
00085 {
00086 CPhidget_read((CPhidgetHandle)phid);
00087 }
00088 break;
00089 case PHIDID_ENCODER_1ENCODER_1INPUT:
00090 case PHIDID_ENCODER_HS_1ENCODER:
00091 default:
00092 break;
00093 }
00094
00095
00096 for (i = 0; i<phid->phid.attr.encoder.numEncoders; i++)
00097 {
00098 phid->enableState[i] = phid->enableStateEcho[i];
00099 }
00100
00101 return EPHIDGET_OK;
00102 }
00103
00104
00105 CPHIDGETDATA(Encoder)
00106 int i=0,j=0;
00107
00108 unsigned char input[ENCODER_MAXINPUTS];
00109 unsigned char indexTrue[ENCODER_MAXINPUTS];
00110 unsigned char enabledEcho[ENCODER_MAXINPUTS];
00111 short positionChange[ENCODER_MAXENCODERS];
00112 short indexChange[ENCODER_MAXENCODERS];
00113 int packetTime[ENCODER_MAXENCODERS];
00114 int curTime[ENCODER_MAXENCODERS];
00115 unsigned short timeChange = 0, timeStamp = 0;
00116 int timeChangeInt[ENCODER_MAXENCODERS];
00117
00118 unsigned char lastInputState[ENCODER_MAXINPUTS];
00119
00120 if (length<0) return EPHIDGET_INVALIDARG;
00121 TESTPTR(phid);
00122 TESTPTR(buffer);
00123
00124 ZEROMEM(input, sizeof(input));
00125 ZEROMEM(positionChange, sizeof(positionChange));
00126 ZEROMEM(lastInputState, sizeof(lastInputState));
00127 ZEROMEM(indexTrue, sizeof(indexTrue));
00128 ZEROMEM(indexChange, sizeof(indexChange));
00129 ZEROMEM(packetTime, sizeof(packetTime));
00130 ZEROMEM(curTime, sizeof(curTime));
00131 ZEROMEM(timeChangeInt, sizeof(timeChangeInt));
00132
00133 switch(phid->phid.deviceIDSpec)
00134 {
00135 case PHIDID_ENCODER_1ENCODER_1INPUT:
00136
00137 if (phid->phid.deviceVersion < 110)
00138 {
00139 if (buffer[1] & 0x04)
00140 input[0] = PFALSE;
00141 else
00142 input[0] = PTRUE;
00143
00144 positionChange[0] = (signed char)buffer[2];
00145
00146 timeStamp = (((unsigned short)buffer[4]) << 8) + buffer[3];
00147 }
00148
00149 else if (phid->phid.deviceVersion >= 110 && phid->phid.deviceVersion < 300)
00150 {
00151 if (buffer[1] & 0x01)
00152 input[0] = PFALSE;
00153 else
00154 input[0] = PTRUE;
00155
00156 positionChange[0] = (signed char)buffer[4];
00157
00158 timeStamp = (((unsigned short)buffer[3]) << 8) + buffer[2];
00159 }
00160 else
00161 return EPHIDGET_UNEXPECTED;
00162 break;
00163 case PHIDID_ENCODER_HS_1ENCODER:
00164
00165 if (phid->phid.deviceVersion >= 300 && phid->phid.deviceVersion < 400) {
00166
00167
00168
00169 for (i = 0, j = 1; i < (phid->phid.attr.encoder.numInputs); i++, j<<=1)
00170 {
00171 if (buffer[1] & j)
00172 input[i] = PFALSE;
00173 else
00174 input[i] = PTRUE;
00175 }
00176
00177
00178 for(i=0;i<phid->phid.attr.encoder.numEncoders;i++) {
00179 positionChange[i] = (((unsigned short)buffer[2*i+5]) << 8) + buffer[2*i+4];
00180 }
00181
00182 timeStamp = (((unsigned short)buffer[3]) << 8) + buffer[2];
00183 }
00184 else
00185 return EPHIDGET_UNEXPECTED;
00186 break;
00187 case PHIDID_ENCODER_HS_4ENCODER_4INPUT:
00188
00189 if (phid->phid.deviceVersion >= 100 && phid->phid.deviceVersion < 200)
00190 {
00191
00192 for(i=0;i<phid->phid.attr.encoder.numEncoders;i++) {
00193 positionChange[i] = (((unsigned short)buffer[10*i+0]) << 8) + buffer[10*i+1] - 0x7fff;
00194 indexChange[i] = (((unsigned short)buffer[10*i+2]) << 8) + buffer[10*i+3] - 0x7fff;
00195 packetTime[i] = (((int)buffer[10*i+4]) << 16) + (((unsigned short)buffer[10*i+5]) << 8) + buffer[10*i+6];
00196 curTime[i] = (((unsigned short)buffer[10*i+7]) << 8) + buffer[10*i+8];
00197 indexTrue[i] = (buffer[10*i+9] & 0x01) ? PTRUE : PFALSE;
00198 enabledEcho[i] = (buffer[10*i+9] & 0x02) ? PTRUE : PFALSE;
00199 if (buffer[10*i+9] & 0x04)
00200 input[i] = PFALSE;
00201 else
00202 input[i] = PTRUE;
00203 }
00204 }
00205 else
00206 return EPHIDGET_UNEXPECTED;
00207 break;
00208 default:
00209 return EPHIDGET_UNEXPECTED;
00210 }
00211
00212
00213 for (i = 0; i < phid->phid.attr.encoder.numInputs; i++)
00214 {
00215 lastInputState[i] = phid->inputState[i];
00216 phid->inputState[i] = input[i];
00217 }
00218 for(i=0; i < phid->phid.attr.encoder.numEncoders; i++)
00219 {
00220
00221 if((positionChange[i] > 0 && (phid->encoderPosition[i] + positionChange[i]) < phid->encoderPosition[i])
00222 || (positionChange[i] < 0 && (phid->encoderPosition[i] + positionChange[i]) > phid->encoderPosition[i]))
00223 {
00224 char error_buffer[50];
00225 FIRE_ERROR(EEPHIDGET_WRAP, "Encoder %d position is wrapping around.", i);
00226 }
00227
00228 phid->encoderPosition[i] += positionChange[i];
00229
00230
00231 switch(phid->phid.deviceIDSpec)
00232 {
00233 case PHIDID_ENCODER_1ENCODER_1INPUT:
00234 case PHIDID_ENCODER_HS_1ENCODER:
00235
00236 timeChange = (timeStamp - phid->encoderTimeStamp[i]);
00237
00238
00239 if (timeChange > 30000 || phid->encoderTimeStamp[i] == PUNK_INT)
00240 timeChangeInt[i] = PUNK_INT;
00241 else
00242 timeChangeInt[i] = timeChange;
00243
00244 phid->encoderTimeStamp[i] = timeStamp;
00245 break;
00246 case PHIDID_ENCODER_HS_4ENCODER_4INPUT:
00247
00248 if (phid->encoderTimeStamp[i] == PUNK_INT)
00249 phid->encoderTimeStamp[i] = 0;
00250
00251 phid->encoderTimeStamp[i] += packetTime[i];
00252
00253 if(positionChange[i] != 0)
00254 {
00255 timeChangeInt[i] = phid->encoderTimeStamp[i] - curTime[i];
00256
00257 timeChangeInt[i] = round(timeChangeInt[i] / 12.0);
00258
00259 phid->encoderTimeStamp[i] = curTime[i];
00260 }
00261
00262 if(indexTrue[i])
00263 phid->indexPosition[i] = phid->encoderPosition[i] - indexChange[i];
00264
00265 phid->enableStateEcho[i] = enabledEcho[i];
00266 break;
00267 default:
00268 return EPHIDGET_UNEXPECTED;
00269 }
00270 }
00271
00272
00273 for (i = 0; i < phid->phid.attr.encoder.numInputs; i++)
00274 {
00275 if(phid->inputState[i] != lastInputState[i])
00276 FIRE(InputChange, i, phid->inputState[i]);
00277 }
00278 for(i=0; i < phid->phid.attr.encoder.numEncoders; i++)
00279 {
00280 if(positionChange[i] != 0)
00281 FIRE(PositionChange, i, timeChangeInt[i], positionChange[i]);
00282 if(indexTrue[i])
00283 FIRE(Index, i, phid->indexPosition[i]);
00284 }
00285
00286 return EPHIDGET_OK;
00287 }
00288
00289
00290 CPHIDGETINITEVENTS(Encoder)
00291
00292 for (i = 0; i < phid->phid.attr.encoder.numInputs; i++)
00293 {
00294 if (phid->inputState[i] != PUNK_BOOL)
00295 {
00296 FIRE(InputChange, i, phid->inputState[i]);
00297 }
00298 }
00299 return EPHIDGET_OK;
00300 }
00301
00302
00303 CGETPACKET_BUF(Encoder)
00304
00305
00306 CSENDPACKET_BUF(Encoder)
00307
00308
00309 CMAKEPACKET(Encoder)
00310 int i = 0, j = 0;
00311
00312 TESTPTRS(phid, buffer);
00313
00314 switch(phid->phid.deviceIDSpec)
00315 {
00316 case PHIDID_ENCODER_HS_4ENCODER_4INPUT:
00317 if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
00318 {
00319
00320 for (i = 0; i<phid->phid.attr.encoder.numEncoders; i++)
00321 {
00322 if (phid->enableState[i] == PUNK_BOOL)
00323 phid->enableState[i] = PFALSE;
00324 }
00325
00326
00327 for (i = 0, j = 1; i < phid->phid.attr.encoder.numEncoders; i++, j<<=1)
00328 {
00329 if (phid->enableState[i])
00330 buffer[0] |= j;
00331 }
00332 }
00333 else
00334 return EPHIDGET_UNEXPECTED;
00335 break;
00336 case PHIDID_ENCODER_HS_1ENCODER:
00337 case PHIDID_ENCODER_1ENCODER_1INPUT:
00338 return EPHIDGET_UNSUPPORTED;
00339 default:
00340 return EPHIDGET_UNEXPECTED;
00341 }
00342 return EPHIDGET_OK;
00343 }
00344
00345
00346
00347
00348 CCREATE(Encoder, PHIDCLASS_ENCODER)
00349
00350
00351 CFHANDLE(Encoder, InputChange, int, int)
00352 CFHANDLE(Encoder, PositionChange, int, int, int)
00353 CFHANDLE(Encoder, Index, int, int)
00354
00355 CGET(Encoder,InputCount,int)
00356 TESTPTRS(phid,pVal)
00357 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00358 TESTATTACHED
00359
00360 MASGN(phid.attr.encoder.numInputs)
00361 }
00362
00363 CGETINDEX(Encoder,InputState,int)
00364 TESTPTRS(phid,pVal)
00365 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00366 TESTATTACHED
00367 TESTINDEX(phid.attr.encoder.numInputs)
00368 TESTMASGN(inputState[Index], PUNK_BOOL)
00369
00370 MASGN(inputState[Index])
00371 }
00372
00373 CGET(Encoder,EncoderCount,int)
00374 TESTPTRS(phid,pVal)
00375 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00376 TESTATTACHED
00377
00378 MASGN(phid.attr.encoder.numEncoders)
00379 }
00380
00381 CGETINDEX(Encoder,Position,int)
00382 TESTPTRS(phid,pVal)
00383 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00384 TESTATTACHED
00385 TESTINDEX(phid.attr.encoder.numEncoders)
00386
00387 MASGN(encoderPosition[Index])
00388 }
00389 CSETINDEX(Encoder,Position,int)
00390 TESTPTR(phid)
00391 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00392 TESTATTACHED
00393 TESTINDEX(phid.attr.encoder.numEncoders)
00394
00395 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00396 ADDNETWORKKEYINDEXED(ResetPosition, "%d", encoderPosition);
00397 else
00398 phid->encoderPosition[Index] = newVal;
00399
00400 return EPHIDGET_OK;
00401 }
00402
00403 CGETINDEX(Encoder,IndexPosition,int)
00404 TESTPTRS(phid,pVal)
00405 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00406 TESTATTACHED
00407 TESTINDEX(phid.attr.encoder.numEncoders)
00408 TESTMASGN(indexPosition[Index], PUNK_INT)
00409
00410 MASGN(indexPosition[Index])
00411 }
00412
00413 CGETINDEX(Encoder,Enabled,int)
00414 TESTPTRS(phid,pVal)
00415 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00416 TESTATTACHED
00417 TESTINDEX(phid.attr.encoder.numEncoders)
00418 TESTMASGN(enableStateEcho[Index], PUNK_BOOL)
00419
00420 MASGN(enableStateEcho[Index])
00421 }
00422 CSETINDEX(Encoder,Enabled,int)
00423 TESTPTR(phid)
00424 TESTDEVICETYPE(PHIDCLASS_ENCODER)
00425 TESTATTACHED
00426
00427
00428 switch(phid->phid.deviceIDSpec) {
00429 case PHIDID_ENCODER_HS_4ENCODER_4INPUT:
00430 TESTINDEX(phid.attr.encoder.numEncoders)
00431 TESTRANGE(PFALSE, PTRUE)
00432 if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
00433 ADDNETWORKKEYINDEXED(Enabled, "%d", enableState);
00434 else
00435 SENDPACKET(Encoder, enableState[Index]);
00436 return EPHIDGET_OK;
00437 case PHIDID_ENCODER_1ENCODER_1INPUT:
00438 case PHIDID_ENCODER_HS_1ENCODER:
00439 default:
00440 return EPHIDGET_UNSUPPORTED;
00441 }
00442
00443 }
00444
00445
00446
00447 CGETINDEX(Encoder,EncoderPosition,int)
00448 return CPhidgetEncoder_getPosition(phid, Index, pVal);
00449 }
00450 CSETINDEX(Encoder,EncoderPosition,int)
00451 return CPhidgetEncoder_setPosition(phid, Index, newVal);
00452 }
00453 CGET(Encoder,NumInputs,int)
00454 return CPhidgetEncoder_getInputCount(phid, pVal);
00455 }
00456 CGET(Encoder,NumEncoders,int)
00457 return CPhidgetEncoder_getEncoderCount(phid, pVal);
00458 }