aboutsummaryrefslogtreecommitdiffstats
path: root/cphidgetled.c
diff options
context:
space:
mode:
authorJonathan McCrohan <jmccrohan@gmail.com>2012-04-14 12:56:48 +0100
committerJonathan McCrohan <jmccrohan@gmail.com>2012-04-14 12:56:48 +0100
commit0b624384cd52be20e61284551d832b499d7b7707 (patch)
tree6f95a4bbef47abc9720b96c0722e8f632aef228a /cphidgetled.c
downloadlibphidget21-0b624384cd52be20e61284551d832b499d7b7707.tar.gz
Imported Upstream version 2.1.8.20120216upstream/2.1.8.20120216
Diffstat (limited to 'cphidgetled.c')
-rw-r--r--cphidgetled.c669
1 files changed, 669 insertions, 0 deletions
diff --git a/cphidgetled.c b/cphidgetled.c
new file mode 100644
index 0000000..4bcbfc6
--- /dev/null
+++ b/cphidgetled.c
@@ -0,0 +1,669 @@
+#include "stdafx.h"
+#include "cphidgetled.h"
+#include "cusb.h"
+#include "csocket.h"
+#include "cthread.h"
+
+// === Internal Functions === //
+
+//clearVars - sets all device variables to unknown state
+CPHIDGETCLEARVARS(LED)
+ int i = 0;
+
+ phid->changeRequests=PUNK_BOOL;
+
+ for(i=0;i<LED_MAXLEDS;i++)
+ {
+ phid->changedLED_Power[i] = PUNK_BOOL;
+ phid->LED_Power[i] = PUNI_INT;
+ phid->nextLED_Power[i] = PUNK_INT;
+
+ phid->LED_PowerEcho[i] = PUNK_INT;
+ phid->outputEnabledEcho[i] = PUNK_BOOL;
+ phid->ledOpenDetectEcho[i] = PUNK_BOOL;
+
+ phid->lastLED_Power[i] = PUNK_INT;
+ }
+ phid->voltage = PHIDGET_LED_VOLTAGE_2_75V;
+ phid->currentLimit = PHIDGET_LED_CURRENT_LIMIT_20mA;
+ phid->faultEcho = PUNK_BOOL;
+ phid->TSDCount=0;
+ phid->PGoodErrState = PFALSE;
+ phid->powerGoodEcho = PUNK_BOOL;
+ phid->outputEnableEcho = PUNK_BOOL;
+ phid->currentLimitEcho = -1;
+ phid->voltageEcho = -1;
+
+ return EPHIDGET_OK;
+}
+
+//initAfterOpen - sets up the initial state of an object, reading in packets from the device if needed
+// used during attach initialization - on every attach
+CPHIDGETINIT(LED)
+ int i = 0;
+
+ TESTPTR(phid);
+
+ //set data arrays to unknown
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64:
+ for(i=0;i<phid->phid.attr.led.numLEDs;i++)
+ {
+ phid->changedLED_Power[i] = PFALSE;
+ phid->LED_Power[i] = PUNK_INT;
+ phid->nextLED_Power[i] = PUNK_INT;
+ }
+ break;
+ case PHIDID_LED_64_ADV:
+ if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
+ {
+ for(i=0;i<phid->phid.attr.led.numLEDs;i++)
+ {
+ phid->changedLED_Power[i] = PFALSE;
+ phid->LED_Power[i] = PUNK_INT;
+ phid->nextLED_Power[i] = PUNK_INT;
+
+ phid->LED_PowerEcho[i] = PUNK_INT;
+ phid->outputEnabledEcho[i] = PUNK_BOOL;
+ phid->ledOpenDetectEcho[i] = PUNK_BOOL;
+
+ phid->lastLED_Power[i] = PUNK_INT;
+ }
+ phid->voltage = PHIDGET_LED_VOLTAGE_2_75V;
+ phid->currentLimit = PHIDGET_LED_CURRENT_LIMIT_20mA;
+
+ phid->faultEcho = PUNK_BOOL;
+ phid->powerGoodEcho = PUNK_BOOL;
+ phid->PGoodErrState = PFALSE;
+ phid->outputEnableEcho = PUNK_BOOL;
+ phid->voltageEcho = -1;
+ phid->currentLimitEcho = -1;
+
+ phid->TSDCount=0;
+ phid->TSDClearCount = 0;
+ phid->lastOutputPacket = 0;
+ }
+ else
+ return EPHIDGET_BADVERSION;
+ break;
+ default:
+ return EPHIDGET_UNEXPECTED;
+ }
+ phid->changeRequests=0;
+ phid->controlPacketWaiting = PFALSE;
+
+ //issue a read - fill in data
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64_ADV:
+ //need two reads to get the full state
+ CPhidget_read((CPhidgetHandle)phid);
+ CPhidget_read((CPhidgetHandle)phid);
+ for(i=0;i<phid->phid.attr.led.numLEDs;i++)
+ {
+ if(phid->outputEnabledEcho[i] == PTRUE)
+ phid->LED_Power[i] = phid->LED_PowerEcho[i];
+ else
+ phid->LED_Power[i] = 0;
+
+ phid->lastLED_Power[i] = phid->LED_PowerEcho[i];
+ }
+ if(phid->voltageEcho != -1)
+ phid->voltage = phid->voltageEcho;
+ if(phid->currentLimitEcho != -1)
+ phid->currentLimit = phid->currentLimitEcho;
+ break;
+ case PHIDID_LED_64:
+ default:
+ break;
+ }
+
+ return EPHIDGET_OK;
+}
+
+//dataInput - parses device packets
+CPHIDGETDATA(LED)
+ int i = 0;
+ char error_buffer[50];
+
+ if (length < 0) return EPHIDGET_INVALIDARG;
+ TESTPTR(phid);
+ TESTPTR(buffer);
+
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64_ADV:
+ if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
+ {
+ switch(buffer[0] & 0x80)
+ {
+ case LED64_IN_LOW_PACKET:
+ //PowerGood
+ if(buffer[0] & LED64_PGOOD_FLAG)
+ {
+ phid->PGoodErrState = PFALSE;
+ phid->powerGoodEcho = PTRUE;
+ }
+ else
+ {
+ phid->powerGoodEcho = PFALSE;
+ }
+
+ //all outputs enabled (power on/off)
+ if(buffer[0] & LED64_OE_FLAG)
+ phid->outputEnableEcho = PTRUE;
+ else
+ phid->outputEnableEcho = PFALSE;
+
+ //fault
+ if(buffer[0] & LED64_FAULT_FLAG)
+ phid->faultEcho = PTRUE;
+ else
+ phid->faultEcho = PFALSE;
+
+ //current limit
+ if(buffer[0] & LED64_CURSELA_FLAG)
+ {
+ if(buffer[0] & LED64_CURSELB_FLAG)
+ phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_80mA;
+ else
+ phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_40mA;
+ }
+ else if (buffer[0] & LED64_CURSELB_FLAG)
+ phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_60mA;
+ else
+ phid->currentLimitEcho = PHIDGET_LED_CURRENT_LIMIT_20mA;
+
+ //voltage
+ if(buffer[0] & LED64_PWRSELA_FLAG)
+ {
+ if(buffer[0] & LED64_PWRSELB_FLAG)
+ phid->voltageEcho = PHIDGET_LED_VOLTAGE_5_0V;
+ else
+ phid->voltageEcho = PHIDGET_LED_VOLTAGE_2_75V;
+ }
+ else if (buffer[0] & LED64_PWRSELB_FLAG)
+ phid->voltageEcho = PHIDGET_LED_VOLTAGE_3_9V;
+ else
+ phid->voltageEcho = PHIDGET_LED_VOLTAGE_1_7V;
+
+ for(i=0;i<phid->phid.attr.led.numLEDs;i++)
+ {
+ phid->outputEnabledEcho[i] = (buffer[(i/8)+1] & (1 << (i%8))) ? 1 : 0;
+ phid->ledOpenDetectEcho[i] = (buffer[(i/8)+9] & (1 << (i%8))) ? 1 : 0;
+ }
+
+ //1st 24 LED powers
+ for(i=0;i<24;i++)
+ {
+ double ledPowerTemp;
+ ledPowerTemp = ((double)buffer[i+17] / 127.0) * 100.0;
+ phid->LED_PowerEcho[i] = round(ledPowerTemp);
+ }
+
+ //We can guess that the fault is a TSD if there is no LOD
+ if(phid->faultEcho)
+ {
+ phid->TSDCount++;
+ phid->TSDClearCount = 30; //500ms of no faults before we clear it
+
+ for(i=0;i<phid->phid.attr.led.numLEDs;i++)
+ {
+ if(phid->ledOpenDetectEcho[i])
+ phid->TSDCount = 0;
+ }
+
+ //send out some error events on faults
+ //TODO: we could also send LED Open Detect?
+
+ //we have counted three fault flags with no LODs - TSD - only one error event is thrown until this is cleared
+ //less then 3 counts, and it could be a false positive
+ //if outputs are not enabled then the fault should be guaranteed as a TSD
+ if(phid->TSDCount == 3 || (phid->TSDCount < 3 && phid->outputEnableEcho == PFALSE))
+ {
+ phid->TSDCount = 3;
+ FIRE_ERROR(EEPHIDGET_OVERTEMP, "Thermal Shutdown detected.");
+ }
+ }
+ else
+ {
+ if(phid->TSDClearCount > 0)
+ phid->TSDClearCount--;
+ else
+ phid->TSDCount=0;
+ }
+
+ if(!phid->powerGoodEcho && phid->PGoodErrState == PFALSE)
+ {
+ phid->PGoodErrState = PTRUE;
+ FIRE_ERROR(EEPHIDGET_BADPOWER, "Bad power supply detected.");
+ }
+
+ break;
+ case LED64_IN_HIGH_PACKET:
+
+ //last 40 LED powers
+ for(i=24;i<phid->phid.attr.led.numLEDs;i++)
+ {
+ double ledPowerTemp;
+ ledPowerTemp = ((double)buffer[i-23] / 127.0) * 100.0;
+ phid->LED_PowerEcho[i] = round(ledPowerTemp);
+ }
+
+ break;
+ }
+ }
+ else
+ return EPHIDGET_UNEXPECTED;
+ break;
+ case PHIDID_LED_64:
+ default:
+ return EPHIDGET_UNEXPECTED;
+ }
+
+ return EPHIDGET_OK;
+}
+
+//eventsAfterOpen - sends out an event for all valid data, used during attach initialization - not used
+CPHIDGETINITEVENTS(LED)
+ phid = 0;
+ return EPHIDGET_OK;
+}
+
+//getPacket - used by write thread to get the next packet to send to device
+CGETPACKET(LED)
+ int i = 0;
+ int numLeds = 0;
+
+ CPhidgetLEDHandle phid = (CPhidgetLEDHandle)phidG;
+
+ TESTPTRS(phid, buf)
+ TESTPTR(lenp)
+
+ if (*lenp < phid->phid.outputReportByteLength)
+ return EPHIDGET_INVALIDARG;
+
+ CThread_mutex_lock(&phid->phid.outputLock);
+
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64:
+ if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 300))
+ {
+
+ //construct the packet, with up to 4 LED sets
+ for (i = 0; i < phid->phid.attr.led.numLEDs; i++)
+ {
+ if (phid->changedLED_Power[i] && numLeds < 4) {
+ phid->LED_Power[i] = phid->nextLED_Power[i];
+ phid->changedLED_Power[i] = PFALSE;
+ phid->nextLED_Power[i] = PUNK_INT;
+ buf[numLeds*2] = i;
+ //0-100 -> 0-63
+ buf[numLeds*2+1] = (unsigned char)round((phid->LED_Power[i] / 100.0) * 63.0);
+ numLeds++;
+ phid->changeRequests--;
+ }
+ }
+
+ //fill up any remaining buffer space with valid data - sending 0's will mess things up
+ for(numLeds=numLeds;numLeds<4;numLeds++)
+ {
+ buf[numLeds*2] = buf[(numLeds-1)*2];
+ buf[numLeds*2+1] = buf[(numLeds-1)*2+1];
+ }
+ }
+ else
+ return EPHIDGET_UNEXPECTED;
+ break;
+ case PHIDID_LED_64_ADV:
+ if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
+ {
+ //control packet
+ if(phid->controlPacketWaiting)
+ {
+
+ buf[0] = LED64_CONTROL_PACKET;
+
+ buf[1] = 0;
+
+ switch(phid->currentLimit)
+ {
+ case PHIDGET_LED_CURRENT_LIMIT_20mA:
+ break;
+ case PHIDGET_LED_CURRENT_LIMIT_40mA:
+ buf[1] |= LED64_CURSELA_FLAG;
+ break;
+ case PHIDGET_LED_CURRENT_LIMIT_60mA:
+ buf[1] |= LED64_CURSELB_FLAG;
+ break;
+ case PHIDGET_LED_CURRENT_LIMIT_80mA:
+ buf[1] |= (LED64_CURSELA_FLAG | LED64_CURSELB_FLAG);
+ break;
+ }
+
+ switch(phid->voltage)
+ {
+ case PHIDGET_LED_VOLTAGE_1_7V:
+ break;
+ case PHIDGET_LED_VOLTAGE_2_75V:
+ buf[1] |= LED64_PWRSELA_FLAG;
+ break;
+ case PHIDGET_LED_VOLTAGE_3_9V:
+ buf[1] |= LED64_PWRSELB_FLAG;
+ break;
+ case PHIDGET_LED_VOLTAGE_5_0V:
+ buf[1] |= (LED64_PWRSELA_FLAG | LED64_PWRSELB_FLAG);
+ break;
+ }
+
+ phid->controlPacketWaiting = PFALSE;
+ }
+ //LED packet
+ else
+ {
+ int bright_packet = PFALSE;
+ int output_upper = PFALSE;
+ int output_lower = PFALSE;
+ //decide if we need to use a normal brightness packet, or if we can use a high efficiency output packet
+ for (i = 0; i < phid->phid.attr.led.numLEDs; i++)
+ {
+ if(phid->changedLED_Power[i])
+ {
+ if((phid->nextLED_Power[i] != phid->lastLED_Power[i]) && phid->nextLED_Power[i] != 0)
+ bright_packet = PTRUE;
+ else
+ {
+ if(i<32)
+ output_lower = PTRUE;
+ else
+ output_upper = PTRUE;
+ }
+ }
+ }
+
+ //only sends brightness changes - not changes between 0 and a brightness
+ if(bright_packet)
+ {
+ //construct the packet, with up to 4 LED sets
+ for (i = 0; i < phid->phid.attr.led.numLEDs; i++)
+ {
+ if (phid->changedLED_Power[i] && numLeds < 4 && phid->nextLED_Power[i] != 0) {
+ phid->LED_Power[i] = phid->nextLED_Power[i];
+ phid->lastLED_Power[i] = phid->nextLED_Power[i];
+ phid->changedLED_Power[i] = PFALSE;
+ phid->nextLED_Power[i] = PUNK_INT;
+ buf[numLeds*2] = i;
+ //0-100 -> 0-127
+ buf[numLeds*2+1] = (unsigned char)round((phid->LED_Power[i] / 100.0) * 127.0);
+ if(buf[numLeds*2+1])
+ buf[numLeds*2+1] |= 0x80; //this turns the LED on when set brightness > 0;
+ numLeds++;
+ phid->changeRequests--;
+ }
+ }
+
+ //fill up any remaining buffer space with valid data - sending 0's will mess things up
+ //this just replicates data - doesn't send anything
+ for(numLeds=numLeds;numLeds<4;numLeds++)
+ {
+ buf[numLeds*2] = buf[(numLeds-1)*2];
+ buf[numLeds*2+1] = buf[(numLeds-1)*2+1];
+ }
+ }
+ else
+ {
+ //send lower packet
+ if((phid->lastOutputPacket == 0 && output_lower) || (phid->lastOutputPacket != 0 && !output_upper))
+ {
+ buf[0] = LED64_OUTLOW_PACKET;
+ for(i = 0;i<32;i++)
+ {
+ if(phid->changedLED_Power[i])
+ {
+ phid->changeRequests--;
+ phid->LED_Power[i] = phid->nextLED_Power[i];
+ phid->changedLED_Power[i] = PFALSE;
+ phid->nextLED_Power[i] = PUNK_INT;
+ }
+ if(phid->LED_Power[i] > 0)
+ buf[i/8 + 1] |= (1 << (i%8));
+ }
+ phid->lastOutputPacket = 1;
+ }
+ //send upper packet
+ else
+ {
+ buf[0] = LED64_OUTHIGH_PACKET;
+ for(i = 32;i<64;i++)
+ {
+ if(phid->changedLED_Power[i])
+ {
+ phid->changeRequests--;
+ phid->LED_Power[i] = phid->nextLED_Power[i];
+ phid->changedLED_Power[i] = PFALSE;
+ phid->nextLED_Power[i] = PUNK_INT;
+ }
+ if(phid->LED_Power[i] > 0)
+ buf[i/8 - 3] |= (1 << (i%8));
+ }
+ phid->lastOutputPacket = 0;
+ }
+ }
+ }
+ }
+ else
+ return EPHIDGET_UNEXPECTED;
+ break;
+ default:
+ return EPHIDGET_UNEXPECTED;
+ }
+
+ //if there are still pending sets, signal the event again (which will tell write thread to call this funciton again)
+ if(phid->changeRequests)
+ CThread_set_event(&phid->phid.writeAvailableEvent);
+
+ *lenp = phid->phid.outputReportByteLength;
+
+ CThread_mutex_unlock(&phid->phid.outputLock);
+
+ return EPHIDGET_OK;
+}
+
+//sendpacket - sends a packet to the device asynchronously, blocking if the 1-packet queue is full
+// -every LED has its own 1 state mini-queue
+static int CCONV CPhidgetLED_sendpacket(CPhidgetLEDHandle phid,
+ unsigned int index, unsigned int power)
+{
+ int waitReturn;
+ CThread_mutex_lock(&phid->phid.writelock);
+again:
+ if (!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG))
+ {
+ CThread_mutex_unlock(&phid->phid.writelock);
+ return EPHIDGET_NOTATTACHED;
+ }
+ CThread_mutex_lock(&phid->phid.outputLock);
+ //if we have already requested a change on this LED
+ if (phid->changedLED_Power[index]) {
+ //and it was different then this time
+ if (phid->nextLED_Power[index] != power) {
+ CThread_mutex_unlock(&phid->phid.outputLock);
+ //then wait for it to get written
+ waitReturn = CThread_wait_on_event(&phid->phid.writtenEvent, 2500);
+ switch(waitReturn)
+ {
+ case WAIT_OBJECT_0:
+ break;
+ case WAIT_ABANDONED:
+ CThread_mutex_unlock(&phid->phid.writelock);
+ return EPHIDGET_UNEXPECTED;
+ case WAIT_TIMEOUT:
+ CThread_mutex_unlock(&phid->phid.writelock);
+ return EPHIDGET_TIMEOUT;
+ }
+ //and try again
+ goto again;
+ } else {
+ CThread_mutex_unlock(&phid->phid.outputLock);
+ CThread_mutex_unlock(&phid->phid.writelock);
+ return EPHIDGET_OK;
+ }
+ //otherwise
+ } else {
+ //if it's different then current, queue it up
+ if (phid->LED_Power[index] != power) {
+ phid->changeRequests++;
+ phid->changedLED_Power[index] = PTRUE;
+ phid->nextLED_Power[index] = power;
+ CThread_reset_event(&phid->phid.writtenEvent);
+ CThread_mutex_unlock(&phid->phid.outputLock);
+ CThread_set_event(&phid->phid.writeAvailableEvent);
+ }
+ //if it's the same, just return
+ else
+ {
+ CThread_mutex_unlock(&phid->phid.outputLock);
+ CThread_mutex_unlock(&phid->phid.writelock);
+ return EPHIDGET_OK;
+ }
+ }
+ CThread_mutex_unlock(&phid->phid.writelock);
+ return EPHIDGET_OK;
+}
+
+// === Exported Functions === //
+
+//create and initialize a device structure
+CCREATE(LED, PHIDCLASS_LED)
+
+CGET(LED,LEDCount,int)
+ TESTPTRS(phid,pVal)
+ TESTDEVICETYPE(PHIDCLASS_LED)
+ TESTATTACHED
+
+ MASGN(phid.attr.led.numLEDs)
+}
+
+CGETINDEX(LED,DiscreteLED,int)
+ TESTPTRS(phid,pVal)
+ TESTDEVICETYPE(PHIDCLASS_LED)
+ TESTATTACHED
+ TESTINDEX(phid.attr.led.numLEDs)
+ TESTMASGN(LED_Power[Index], PUNK_INT)
+
+ MASGN(LED_Power[Index])
+}
+CSETINDEX(LED,DiscreteLED,int)
+ TESTPTR(phid)
+ TESTDEVICETYPE(PHIDCLASS_LED)
+ TESTATTACHED
+ TESTINDEX(phid.attr.led.numLEDs)
+ TESTRANGE(0, 100)
+
+ if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
+ ADDNETWORKKEYINDEXED(Brightness, "%d", LED_Power);
+ else
+ return CPhidgetLED_sendpacket(phid, Index, newVal);
+
+ return EPHIDGET_OK;
+}
+
+CGET(LED,CurrentLimit,CPhidgetLED_CurrentLimit)
+ TESTPTRS(phid,pVal)
+ TESTDEVICETYPE(PHIDCLASS_LED)
+ TESTATTACHED
+
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64_ADV:
+ MASGN(currentLimitEcho)
+ case PHIDID_LED_64:
+ default:
+ return EPHIDGET_UNSUPPORTED;
+ }
+}
+CSET(LED,CurrentLimit,CPhidgetLED_CurrentLimit)
+ TESTPTR(phid)
+ TESTDEVICETYPE(PHIDCLASS_LED)
+ TESTATTACHED
+
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64_ADV:
+
+ TESTRANGE(PHIDGET_LED_CURRENT_LIMIT_20mA, PHIDGET_LED_CURRENT_LIMIT_80mA)
+
+ if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
+ ADDNETWORKKEY(CurrentLimit, "%d", currentLimit);
+ else
+ {
+ CThread_mutex_lock(&phid->phid.writelock);
+ CThread_mutex_lock(&phid->phid.outputLock);
+ phid->currentLimit = newVal;
+ phid->controlPacketWaiting = PTRUE;
+ CThread_mutex_unlock(&phid->phid.outputLock);
+ CThread_set_event(&phid->phid.writeAvailableEvent);
+ CThread_mutex_unlock(&phid->phid.writelock);
+ }
+ break;
+ case PHIDID_LED_64:
+ default:
+ return EPHIDGET_UNSUPPORTED;
+ }
+
+ return EPHIDGET_OK;
+}
+
+CGET(LED,Voltage,CPhidgetLED_Voltage)
+ TESTPTRS(phid,pVal)
+ TESTDEVICETYPE(PHIDCLASS_LED)
+ TESTATTACHED
+
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64_ADV:
+ MASGN(voltageEcho)
+ case PHIDID_LED_64:
+ default:
+ return EPHIDGET_UNSUPPORTED;
+ }
+}
+CSET(LED,Voltage,CPhidgetLED_Voltage)
+ TESTPTR(phid)
+ TESTDEVICETYPE(PHIDCLASS_LED)
+ TESTATTACHED
+
+ switch(phid->phid.deviceIDSpec)
+ {
+ case PHIDID_LED_64_ADV:
+
+ TESTRANGE(PHIDGET_LED_CURRENT_LIMIT_20mA, PHIDGET_LED_CURRENT_LIMIT_80mA)
+
+ if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
+ ADDNETWORKKEY(Voltage, "%d", voltage);
+ else
+ {
+ CThread_mutex_lock(&phid->phid.writelock);
+ CThread_mutex_lock(&phid->phid.outputLock);
+ phid->voltage = newVal;
+ phid->controlPacketWaiting = PTRUE;
+ CThread_mutex_unlock(&phid->phid.outputLock);
+ CThread_set_event(&phid->phid.writeAvailableEvent);
+ CThread_mutex_unlock(&phid->phid.writelock);
+ }
+ break;
+ case PHIDID_LED_64:
+ default:
+ return EPHIDGET_UNSUPPORTED;
+ }
+
+ return EPHIDGET_OK;
+}
+
+// === Deprecated Functions === //
+
+CGET(LED,NumLEDs,int)
+ return CPhidgetLED_getLEDCount(phid, pVal);
+}