Files

1075 lines
30 KiB
C

//Author: LabJack
//May 25, 2011
//Example UE9 helper functions. Function descriptions are in ue9.h.
#include "ue9.h"
ue9CalibrationInfo UE9_CALIBRATION_INFO_DEFAULT = {
9,
//Nominal Values
{ 0.000077503,
-0.012,
0.000038736,
-0.012,
0.000019353,
-0.012,
0.0000096764,
-0.012,
0.00015629,
-5.176,
842.59,
0.0,
842.259,
0.0,
0.012968,
0.012968,
298.15,
2.43,
0.0,
1.215,
0.00009272,
0.000077503,
-0.012,
0.00015629,
-5.176}
};
void normalChecksum(uint8 *b, int n)
{
b[0] = normalChecksum8(b,n);
}
void extendedChecksum(uint8 *b, int n)
{
uint16 a;
a = extendedChecksum16(b,n);
b[4] = (uint8)(a & 0xFF);
b[5] = (uint8)((a/256) & 0xFF);
b[0] = extendedChecksum8(b);
}
uint8 normalChecksum8(uint8 *b, int n)
{
int i;
uint16 a, bb;
//Sums bytes 1 to n-1 unsigned to a 2 byte value. Sums quotient and
//remainder of 256 division. Again, sums quotient and remainder of
//256 division.
for( i = 1, a = 0; i < n; i++ )
a += (uint16)b[i];
bb = a/256;
a = (a - 256*bb) + bb;
bb = a/256;
return (uint8)((a - 256*bb) + bb);
}
uint16 extendedChecksum16(uint8 *b, int n)
{
int i, a = 0;
//Sums bytes 6 to n-1 to a unsigned 2 byte value
for( i = 6; i < n; i++ )
a += (uint16)b[i];
return a;
}
uint8 extendedChecksum8(uint8 *b)
{
int i, a, bb;
//Sums bytes 1 to 5. Sums quotient and remainder of 256 division. Again, sums
//quotient and remainder of 256 division.
for( i = 1, a = 0; i < 6; i++ )
a += (uint16)b[i];
bb = a/256;
a = (a - 256*bb) + bb;
bb = a/256;
return (uint8)((a - 256*bb) + bb);
}
HANDLE openUSBConnection(int localID)
{
BYTE buffer[38];
uint16 checksumTotal = 0;
uint32 numDevices = 0;
uint32 dev;
int i, serial;
HANDLE hDevice = 0;
numDevices = LJUSB_GetDevCount(UE9_PRODUCT_ID);
if( numDevices == 0 )
{
printf("Open error: No UE9 devices could be found\n");
return NULL;
}
for( dev = 1; dev <= numDevices; dev++ )
{
hDevice = LJUSB_OpenDevice(dev, 0, UE9_PRODUCT_ID);
if( hDevice != NULL )
{
if( localID < 0 )
{
return hDevice;
}
else
{
checksumTotal = 0;
//Setting up a CommConfig command
buffer[1] = (BYTE)(0x78);
buffer[2] = (BYTE)(0x10);
buffer[3] = (BYTE)(0x01);
for( i = 6; i < 38; i++ )
buffer[i] = (BYTE)(0x00);
extendedChecksum(buffer,38);
if( LJUSB_Write(hDevice, buffer, 38) != 38 )
goto locid_error;
for( i = 0; i < 38; i++ )
buffer[i] = 0;
if( LJUSB_Read(hDevice, buffer, 38) != 38 )
goto locid_error;
checksumTotal = extendedChecksum16(buffer, 38);
if( (BYTE)((checksumTotal / 256) & 0xFF) != buffer[5] )
goto locid_error;
if( (BYTE)(checksumTotal & 0xFF) != buffer[4] )
goto locid_error;
if( extendedChecksum8(buffer) != buffer[0] )
goto locid_error;
if( buffer[1] != (BYTE)(0x78) || buffer[2] != (BYTE)(0x10) || buffer[3] != (BYTE)(0x01) )
goto locid_error;
//Check local ID
if( (int)buffer[8] == localID )
return hDevice;
//Check serial number
serial = buffer[28] + buffer[29]*256 + buffer[30]*65536 + 0x10000000;
if( serial == localID )
return hDevice;
//No matches. Not our device.
LJUSB_CloseDevice(hDevice);
} //else localID >= 0 end
} //if hDevice != NULL end
} //for end
printf("Open error: could not find a UE9 with a local ID or serial number of %d\n", localID);
return NULL;
locid_error:
printf("Open error: problem when checking local ID and serial number\n");
return NULL;
}
void closeUSBConnection(HANDLE hDevice)
{
LJUSB_CloseDevice(hDevice);
}
long getTickCount()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
}
long getCalibrationInfo(HANDLE hDevice, ue9CalibrationInfo *caliInfo)
{
BYTE sendBuffer[8], recBuffer[136];
int sentRec = 0, i = 0, j = 0, ccTotal = 0, count = 0;
/* Setting up command */
sendBuffer[1] = (BYTE)(0xF8); //command byte
sendBuffer[2] = (BYTE)(0x01); //number of data words
sendBuffer[3] = (BYTE)(0x2A); //extended command number
sendBuffer[6] = (BYTE)(0x00);
for( i = 0; i < 5; i++ )
{
/* Reading block 1 from memory */
sendBuffer[7] = (BYTE)i; //Blocknum = i
extendedChecksum(sendBuffer, 8);
sentRec = LJUSB_Write(hDevice, sendBuffer, 8);
if( sentRec < 8 )
{
if( sentRec == 0 )
printf("getCalibrationInfo error : write failed\n");
else
printf("getCalibrationInfo error : did not write all of the buffer\n");
return -1;
}
sentRec = LJUSB_Read(hDevice, recBuffer, 136);
if( sentRec < 136 )
{
if( sentRec == 0 )
printf("getCalibrationInfo Error : read failed\n");
else
printf("getCalibrationInfo Error : did not read all of the buffer\n");
}
if( recBuffer[1] != (BYTE)(0xF8) || recBuffer[2] != (BYTE)(0x41) || recBuffer[3] != (BYTE)(0x2A) )
{
printf("getCalibrationInfo error: incorrect command bytes for ReadMem response");
return -1;
}
//Reading out calbration constants
if( i == 0 )
ccTotal = 8;
if( i == 1 )
ccTotal = 2;
if( i == 2 )
ccTotal = 13;
if( i == 3 )
ccTotal = 2;
if( i == 4 )
ccTotal = 2;
for( j = 0; j < ccTotal; j++ )
{
if( i != 2 || (i == 2 && j != 5 && j != 7) )
{
//Block data starts on byte 8 of the buffer
caliInfo->ccConstants[count] = FPuint8ArrayToFPDouble(recBuffer + 8, j*8);
count++;
}
}
}
caliInfo->prodID = 9;
return 0;
}
long getTdacCalibrationInfo(HANDLE hDevice, ue9TdacCalibrationInfo *caliInfo, uint8 DIOAPinNum)
{
int err;
uint8 options, speedAdjust, sdaPinNum, sclPinNum;
uint8 address, numByteToSend, numBytesToReceive, errorcode;
uint8 bytesCommand[1];
uint8 bytesResponse[32];
uint8 ackArray[4];
err = 0;
//Setting up I2C command for LJTDAC
options = 0; //I2COptions : 0
speedAdjust = 0; //SpeedAdjust : 0 (for max communication speed of about 130 kHz)
sdaPinNum = DIOAPinNum+1; //SDAPinNum : FIO channel connected to pin DIOB
sclPinNum = DIOAPinNum; //SCLPinNum : FIO channel connected to pin DIOA
address = (uint8)(0xA0); //Address : h0xA0 is the address for EEPROM
numByteToSend = 1; //NumI2CByteToSend : 1 byte for the EEPROM address
numBytesToReceive = 32; //NumI2CBytesToReceive : getting 32 bytes starting at EEPROM address specified in I2CByte0
bytesCommand[0] = 64; //I2CByte0 : Memory Address (starting at address 64 (DACA Slope)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numByteToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse);
if( errorcode != 0 )
{
printf("Getting LJTDAC calibration info error : received errorcode %d in response\n", errorcode);
err = -1;
}
if( err == -1 )
return err;
caliInfo->ccConstants[0] = FPuint8ArrayToFPDouble(bytesResponse, 0);
caliInfo->ccConstants[1] = FPuint8ArrayToFPDouble(bytesResponse, 8);
caliInfo->ccConstants[2] = FPuint8ArrayToFPDouble(bytesResponse, 16);
caliInfo->ccConstants[3] = FPuint8ArrayToFPDouble(bytesResponse, 24);
caliInfo->prodID = 9;
return err;
}
double FPuint8ArrayToFPDouble(uint8 *buffer, int startIndex)
{
uint32 resultDec = 0, resultWh = 0;
resultDec = (uint32)buffer[startIndex] |
((uint32)buffer[startIndex + 1] << 8) |
((uint32)buffer[startIndex + 2] << 16) |
((uint32)buffer[startIndex + 3] << 24);
resultWh = (uint32)buffer[startIndex + 4] |
((uint32)buffer[startIndex + 5] << 8) |
((uint32)buffer[startIndex + 6] << 16) |
((uint32)buffer[startIndex + 7] << 24);
return ( (double)((int)resultWh) + (double)(resultDec)/4294967296.0 );
}
long isCalibrationInfoValid(ue9CalibrationInfo *caliInfo)
{
if( caliInfo == NULL )
goto invalid;
if( caliInfo->prodID != 9 )
goto invalid;
return 1;
invalid:
printf("Error: Invalid calibration info.\n");
return 0;
}
long isTdacCalibrationInfoValid(ue9TdacCalibrationInfo *caliInfo)
{
if( caliInfo == NULL )
goto invalid;
if( caliInfo->prodID != 9 )
goto invalid;
return 1;
invalid:
printf("Error: Invalid LJTDAC calibration info.\n");
return 0;
}
long getAinVoltCalibrated(ue9CalibrationInfo *caliInfo, uint8 gainBip, uint8 resolution, uint16 bytesVolt, double *analogVolt)
{
if( isCalibrationInfoValid(caliInfo) == 0 )
return -1;
if( resolution < 18 )
{
if( gainBip <= 3 || gainBip == 8 )
{
if( gainBip == 8 )
gainBip = 4; //setting this for index purposes
*analogVolt = (caliInfo->ccConstants[gainBip*2]*bytesVolt) + caliInfo->ccConstants[gainBip*2 + 1];
return 0;
}
else
goto invalidGainBip;
}
else //UE9 Pro high res
{
if( gainBip == 0 || gainBip == 8 )
{
if( gainBip == 8 )
gainBip = 1; //setting this for index purposes
*analogVolt = (caliInfo->ccConstants[gainBip*2 + 21]*bytesVolt) + caliInfo->ccConstants[gainBip*2 + 22];
return 0;
}
else
goto invalidGainBip;
}
invalidGainBip:
printf("getAinVoltCalibrated error: invalid GainBip.\n");
return -1;
}
long getDacBinVoltCalibrated(ue9CalibrationInfo *caliInfo, int dacNumber, double analogVolt, uint16 *bytesVolt)
{
double tBytesVolt;
if( isCalibrationInfoValid(caliInfo) == 0 )
return -1;
if( dacNumber < 0 || dacNumber > 2 )
{
printf("getDacBinVoltCalibrated error: invalid channelNumber.\n");
return -1;
}
tBytesVolt = analogVolt*caliInfo->ccConstants[10 + dacNumber*2] + caliInfo->ccConstants[11 + dacNumber*2];
//Checking to make sure bytesVoltage will be a value between 0 and 4095, or
//that a uint16 overflow does not occur. A too high analogVoltage (above 5
//volts) or too low analogVoltage (below 0 volts) will cause a value not
//between 0 and 4095.
if( tBytesVolt < 0 )
tBytesVolt = 0;
if( tBytesVolt > 4095 )
tBytesVolt = 4095;
*bytesVolt = (uint16)tBytesVolt;
return 0;
}
long getTdacBinVoltCalibrated(ue9TdacCalibrationInfo *caliInfo, int dacNumber, double analogVolt, uint16 *bytesVolt)
{
uint32 tBytesVolt;
if( isTdacCalibrationInfoValid(caliInfo) == 0 )
return -1;
if( dacNumber < 0 || dacNumber > 2 )
{
printf("getTdacBinVoltCalibrated error: invalid channelNumber.\n");
return -1;
}
tBytesVolt = analogVolt*caliInfo->ccConstants[dacNumber*2] + caliInfo->ccConstants[dacNumber*2 + 1];
//Checking to make sure bytesVolt will be a value between 0 and 65535.
if( tBytesVolt > 65535 )
tBytesVolt = 65535;
*bytesVolt = (uint16)tBytesVolt;
return 0;
}
long getTempKCalibrated(ue9CalibrationInfo *caliInfo, int powerLevel, uint16 bytesTemp, double *kelvinTemp)
{
if( isCalibrationInfoValid(caliInfo) == 0 )
return -1;
if( powerLevel == 0 || powerLevel == 1 )
{
*kelvinTemp = caliInfo->ccConstants[14 + powerLevel]*bytesTemp;
return 0;
}
else
{
printf("getTempKCalibrated error: invalid powerLevel.\n");
return -1;
}
}
long getAinVoltUncalibrated(uint8 gainBip, uint8 resolution, uint16 bytesVolt, double *analogVolt)
{
return getAinVoltCalibrated(&UE9_CALIBRATION_INFO_DEFAULT, gainBip, resolution, bytesVolt, analogVolt);
}
long getDacBinVoltUncalibrated(int dacNumber, double analogVolt, uint16 *bytesVolt)
{
return getDacBinVoltCalibrated(&UE9_CALIBRATION_INFO_DEFAULT, dacNumber, analogVolt, bytesVolt);
}
long getTempKUncalibrated(int powerLevel, uint16 bytesTemp, double *kelvinTemp)
{
return getTempKCalibrated(&UE9_CALIBRATION_INFO_DEFAULT, powerLevel, bytesTemp, kelvinTemp);
}
long I2C(HANDLE hDevice, uint8 I2COptions, uint8 SpeedAdjust, uint8 SDAPinNum, uint8 SCLPinNum, uint8 Address, uint8 NumI2CBytesToSend, uint8 NumI2CBytesToReceive, uint8 *I2CBytesCommand, uint8 *Errorcode, uint8 *AckArray, uint8 *I2CBytesResponse)
{
uint8 *sendBuff, *recBuff;
uint16 checksumTotal = 0;
uint32 ackArrayTotal, expectedAckArray;
int sendChars, recChars, sendSize, recSize, i, ret;
*Errorcode = 0;
ret = 0;
sendSize = 6 + 8 + ((NumI2CBytesToSend%2 != 0)?(NumI2CBytesToSend + 1):(NumI2CBytesToSend));
recSize = 6 + 6 + ((NumI2CBytesToReceive%2 != 0)?(NumI2CBytesToReceive + 1):(NumI2CBytesToReceive));
sendBuff = (uint8 *)malloc(sizeof(uint8)*sendSize);
recBuff = (uint8 *)malloc(sizeof(uint8)*recSize);
sendBuff[sendSize - 1] = 0;
//I2C command
sendBuff[1] = (uint8)(0xF8); //Command byte
sendBuff[2] = (sendSize - 6)/2; //Number of data words = 4 + NumI2CBytesToSend
sendBuff[3] = (uint8)(0x3B); //Extended command number
sendBuff[6] = I2COptions; //I2COptions
sendBuff[7] = SpeedAdjust; //SpeedAdjust
sendBuff[8] = SDAPinNum; //SDAPinNum
sendBuff[9] = SCLPinNum; //SCLPinNum
sendBuff[10] = Address; //Address
sendBuff[11] = 0; //Reserved
sendBuff[12] = NumI2CBytesToSend; //NumI2CByteToSend
sendBuff[13] = NumI2CBytesToReceive; //NumI2CBytesToReceive
for( i = 0; i < NumI2CBytesToSend; i++ )
sendBuff[14 + i] = I2CBytesCommand[i]; //I2CByte
extendedChecksum(sendBuff, sendSize);
//Sending command to UE9
sendChars = LJUSB_Write(hDevice, sendBuff, sendSize);
if( sendChars < sendSize )
{
if( sendChars == 0 )
printf("I2C Error : write failed\n");
else
printf("I2C Error : did not write all of the buffer\n");
ret = -1;
goto cleanmem;
}
//Reading response from UE9
recChars = LJUSB_Read(hDevice, recBuff, recSize);
if( recChars < recSize )
{
if( recChars == 0 )
printf("I2C Error : read failed\n");
else
{
printf("I2C Error : did not read all of the buffer\n");
if( recChars >= 12 )
*Errorcode = recBuff[6];
}
ret = -1;
goto cleanmem;
}
*Errorcode = recBuff[6];
AckArray[0] = recBuff[8];
AckArray[1] = recBuff[9];
AckArray[2] = recBuff[10];
AckArray[3] = recBuff[11];
for( i = 0; i < NumI2CBytesToReceive; i++ )
I2CBytesResponse[i] = recBuff[12 + i];
if( (uint8)(extendedChecksum8(recBuff)) != recBuff[0] )
{
printf("I2C Error : read buffer has bad checksum (%d)\n", recBuff[0]);
ret = -1;
}
if( recBuff[1] != (uint8)(0xF8) )
{
printf("I2C Error : read buffer has incorrect command byte (%d)\n", recBuff[1]);
ret = -1;
}
if( recBuff[2] != (uint8)((recSize - 6)/2) )
{
printf("I2C Error : read buffer has incorrect number of data words (%d)\n", recBuff[2]);
ret = -1;
}
if( recBuff[3] != (uint8)(0x3B) )
{
printf("I2C Error : read buffer has incorrect extended command number (%d)\n", recBuff[3]);
ret = -1;
}
checksumTotal = extendedChecksum16(recBuff, recSize);
if( (uint8)((checksumTotal / 256) & 0xFF) != recBuff[5] || (uint8)(checksumTotal & 0xFF) != recBuff[4] )
{
printf("I2C error : read buffer has bad checksum16 (%u)\n", checksumTotal);
ret = -1;
}
//ackArray should ack the Address byte in the first ack bit, but did not until control firmware 1.84
ackArrayTotal = AckArray[0] + AckArray[1]*256 + AckArray[2]*65536 + AckArray[3]*16777216;
expectedAckArray = pow(2.0, NumI2CBytesToSend+1) - 1;
if( ackArrayTotal != expectedAckArray )
printf("I2C error : expected an ack of %u, but received %u\n", expectedAckArray, ackArrayTotal);
cleanmem:
free(sendBuff);
free(recBuff);
sendBuff = NULL;
recBuff = NULL;
return ret;
}
long eAIN(HANDLE Handle, ue9CalibrationInfo *CalibrationInfo, long ChannelP, long ChannelN, double *Voltage, long Range, long Resolution, long Settling, long Binary, long Reserved1, long Reserved2)
{
uint8 IOType, Channel, AINM, AINH, ainGain;
uint16 bytesVT;
if( isCalibrationInfoValid(CalibrationInfo) == 0 )
{
printf("eAIN error: calibration information is required");
return -1;
}
if( Range == LJ_rgBIP5V )
ainGain = 8;
else if( Range == LJ_rgUNI5V )
ainGain = 0;
else if( Range == LJ_rgUNI2P5V )
ainGain = 1;
else if( Range == LJ_rgUNI1P25V )
ainGain = 2;
else if( Range == LJ_rgUNIP625V )
ainGain = 3;
else
{
printf("eAIN error: Invalid Range\n");
return -1;
}
if( ehSingleIO(Handle, 4, (uint8)ChannelP, ainGain, (uint8)Resolution, (uint8)Settling, &IOType, &Channel, NULL, &AINM, &AINH) < 0 )
return -1;
bytesVT = AINM + AINH*256;
if( Binary != 0 )
{
*Voltage = (double)bytesVT;
}
else
{
if( ChannelP == 133 || ChannelP == 141 )
{
if( getTempKCalibrated(CalibrationInfo, 0, bytesVT, Voltage) < 0 )
return -1;
}
else
{
if( getAinVoltCalibrated(CalibrationInfo, ainGain, (uint8)Resolution, bytesVT, Voltage) < 0 )
return -1;
}
}
return 0;
}
long eDAC(HANDLE Handle, ue9CalibrationInfo *CalibrationInfo, long Channel, double Voltage, long Binary, long Reserved1, long Reserved2)
{
uint8 IOType, channel;
uint16 bytesVoltage;
if( isCalibrationInfoValid(CalibrationInfo) == 0 )
{
printf("eDAC error: calibration information is required");
return -1;
}
if( getDacBinVoltCalibrated(CalibrationInfo, (uint8)Channel, Voltage, &bytesVoltage) < 0 )
return -1;
return ehSingleIO(Handle, 5, (uint8)Channel, (uint8)( bytesVoltage & (0x00FF) ), (uint8)(( bytesVoltage /256 ) + 192), 0, &IOType, &channel, NULL, NULL, NULL);
}
long eDI(HANDLE Handle, long Channel, long *State)
{
uint8 state;
if( Channel > 22 )
{
printf("eDI error: Invalid Channel");
return -1;
}
if( ehDIO_Feedback(Handle, (uint8)Channel, 0, &state) < 0 )
return -1;
*State = state;
return 0;
}
long eDO(HANDLE Handle, long Channel, long State)
{
uint8 state;
state = (uint8)State;
if( Channel > 22 )
{
printf("eDO error: Invalid Channel");
return -1;
}
return ehDIO_Feedback(Handle, (uint8)Channel, 1, &state);
}
long eTCConfig(HANDLE Handle, long *aEnableTimers, long *aEnableCounters, long TCPinOffset, long TimerClockBaseIndex, long TimerClockDivisor, long *aTimerModes, double *aTimerValues, long Reserved1, long Reserved2)
{
uint8 enableMask, timerMode[6], counterMode[2];
uint16 timerValue[6];
int numTimers, numTimersStop, i;
//Setting EnableMask
enableMask = 128; //Bit 7: UpdateConfig
if(aEnableCounters[1] != 0)
enableMask += 16; //Bit 4: Enable Counter1
if(aEnableCounters[0] != 0)
enableMask += 8; //Bit 3: Enable Counter0
numTimers = 0;
numTimersStop = 0;
for( i = 0; i < 6; i++ )
{
if( aEnableTimers[i] != 0 && numTimersStop == 0 )
{
numTimers++;
timerMode[i] = (uint8)aTimerModes[i]; //TimerMode
timerValue[i] = (uint16)aTimerValues[i]; //TimerValue
}
else
{
numTimersStop = 1;
timerMode[i] = 0;
timerValue[i] = 0;
}
}
enableMask += numTimers; //Bits 2-0: Number of Timers
counterMode[0] = 0; //Counter0Mode
counterMode[1] = 0; //Counter1Mode
return ehTimerCounter(Handle, (uint8)TimerClockDivisor, enableMask, (uint8)TimerClockBaseIndex, 0, timerMode, timerValue, counterMode, NULL, NULL);
}
long eTCValues(HANDLE Handle, long *aReadTimers, long *aUpdateResetTimers, long *aReadCounters, long *aResetCounters, double *aTimerValues, double *aCounterValues, long Reserved1, long Reserved2)
{
uint8 updateReset, timerMode[6], counterMode[2];
uint16 timerValue[6];
uint32 timer[6], counter[2];
int i;
long errorcode;
//UpdateReset
updateReset = 0;
for( i = 0; i < 6; i++ )
{
updateReset += ((aUpdateResetTimers[i] != 0) ? pow(2, i) : 0);
timerMode[i] = 0;
timerValue[i] = 0;
}
for( i = 0; i < 2; i++ )
{
updateReset += ((aResetCounters[i] != 0) ? pow(2, 6 + i) : 0);
counterMode[i] = 0;
}
if( (errorcode = ehTimerCounter(Handle, 0, 0, 0, updateReset, timerMode, timerValue, counterMode, timer, counter)) != 0 )
return errorcode;
for( i = 0; i < 6; i++ )
aTimerValues[i] = timer[i];
for( i = 0; i < 2; i++ )
aCounterValues[i] = counter[i];
return 0;
}
long ehSingleIO(HANDLE hDevice, uint8 inIOType, uint8 inChannel, uint8 inDirBipGainDACL, uint8 inStateResDACH, uint8 inSettlingTime, uint8 *outIOType, uint8 *outChannel, uint8 *outDirAINL, uint8 *outStateAINM, uint8 *outAINH)
{
BYTE sendBuff[8], recBuff[8];
int sendChars, recChars;
sendBuff[1] = (BYTE)(0xA3); //Command byte
sendBuff[2] = inIOType; //IOType
sendBuff[3] = inChannel; //Channel
sendBuff[4] = inDirBipGainDACL; //Dir/BipGain/DACL
sendBuff[5] = inStateResDACH; //State/Resolution/DACH
sendBuff[6] = inSettlingTime; //Settling time
sendBuff[7] = 0; //Reserved
sendBuff[0] = normalChecksum8(sendBuff, 8);
//Sending command to UE9
sendChars = LJUSB_Write(hDevice, sendBuff, 8);
if( sendChars < 8 )
{
if( sendChars == 0 )
printf("SingleIO error : write failed\n");
else
printf("SingleIO error : did not write all of the buffer\n");
return -1;
}
//Reading response from UE9
recChars = LJUSB_Read(hDevice, recBuff, 8);
if( recChars < 8 )
{
if( recChars == 0 )
printf("SingleIO error : read failed\n");
else
printf("SingleIO error : did not read all of the buffer\n");
return -1;
}
if( (BYTE)(normalChecksum8(recBuff, 8)) != recBuff[0] )
{
printf("SingleIO error : read buffer has bad checksum\n");
return -1;
}
if( recBuff[1] != (BYTE)(0xA3) )
{
printf("SingleIO error : read buffer has wrong command byte\n");
return -1;
}
if( outIOType != NULL )
*outIOType = recBuff[2];
if( outChannel != NULL )
*outChannel = recBuff[3];
if( outDirAINL != NULL )
*outDirAINL = recBuff[4];
if( outStateAINM != NULL )
*outStateAINM = recBuff[5];
if( outAINH != NULL )
*outAINH = recBuff[6];
return 0;
}
long ehDIO_Feedback(HANDLE hDevice, uint8 channel, uint8 direction, uint8 *state)
{
BYTE sendBuff[34], recBuff[64];
BYTE tempDir, tempState, tempByte;
uint16 checksumTotal;
int sendChars, recChars, i;
sendBuff[1] = (BYTE)(0xF8); //Command byte
sendBuff[2] = (BYTE)(0x0E); //Number of data words
sendBuff[3] = (BYTE)(0x00); //Extended command number
for( i = 6; i < 34; i++ )
sendBuff[i] = 0;
tempDir = ((direction < 1) ? 0 : 1);
tempState = ((*state < 1) ? 0 : 1);
if( channel <= 7 )
{
tempByte = pow(2, channel);
sendBuff[6] = tempByte;
if( tempDir )
sendBuff[7] = tempByte;
if( tempState )
sendBuff[8] = tempByte;
}
else if( channel <= 15 )
{
tempByte = pow(2, (channel - 8));
sendBuff[9] = tempByte;
if( tempDir )
sendBuff[10] = tempByte;
if( tempState )
sendBuff[11] = tempByte;
}
else if( channel <= 19 )
{
tempByte = pow(2, (channel - 16));
sendBuff[12] = tempByte;
if( tempDir )
sendBuff[13] = tempByte*16;
if( tempState )
sendBuff[13] += tempByte;
}
else if( channel <= 22 )
{
tempByte = pow(2, (channel - 20));
sendBuff[14] = tempByte;
if( tempDir )
sendBuff[15] = tempByte*16;
if( tempState )
sendBuff[15] += tempByte;
}
else
{
printf("DIO Feedback error: Invalid Channel\n");
return -1;
}
extendedChecksum(sendBuff, 34);
//Sending command to UE9
sendChars = LJUSB_Write(hDevice, sendBuff, 34);
if( sendChars < 34 )
{
if( sendChars == 0 )
printf("DIO Feedback error : write failed\n");
else
printf("DIO Feedback error : did not write all of the buffer\n");
return -1;
}
//Reading response from UE9
recChars = LJUSB_Read(hDevice, recBuff, 64);
if( recChars < 64 )
{
if( recChars == 0 )
printf("DIO Feedback error : read failed\n");
else
printf("DIO Feedback error : did not read all of the buffer\n");
return -1;
}
checksumTotal = extendedChecksum16(recBuff, 64);
if( (BYTE)((checksumTotal / 256) & 0xFF) != recBuff[5] )
{
printf("DIO Feedback error : read buffer has bad checksum16(MSB)\n");
return -1;
}
if( (BYTE)(checksumTotal & 0xFF) != recBuff[4] )
{
printf("DIO Feedback error : read buffer has bad checksum16(LSB)\n");
return -1;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("DIO Feedback error : read buffer has bad checksum8\n");
return -1;
}
if( recBuff[1] != (BYTE)(0xF8) || recBuff[2] != (BYTE)(0x1D) || recBuff[3] != (BYTE)(0x00) )
{
printf("DIO Feedback error : read buffer has wrong command bytes\n");
return -1;
}
if( channel <= 7 )
*state = ((recBuff[7] & tempByte) ? 1 : 0);
else if( channel <= 15 )
*state = ((recBuff[9] & tempByte) ? 1 : 0);
else if( channel <= 19 )
*state = ((recBuff[10] & tempByte) ? 1 : 0);
else if( channel <= 22 )
*state = ((recBuff[11] & tempByte) ? 1 : 0);
return 0;
}
long ehTimerCounter(HANDLE hDevice, uint8 inTimerClockDivisor, uint8 inEnableMask, uint8 inTimerClockBase, uint8 inUpdateReset, uint8 *inTimerMode, uint16 *inTimerValue, uint8 *inCounterMode, uint32 *outTimer, uint32 *outCounter)
{
BYTE sendBuff[30], recBuff[40];
uint16 checksumTotal;
int sendChars, recChars, i, j;
sendBuff[1] = (BYTE)(0xF8); //Command byte
sendBuff[2] = (BYTE)(0x0C); //Number of data words
sendBuff[3] = (BYTE)(0x18); //Extended command number
sendBuff[6] = inTimerClockDivisor; //TimerClockDivisor
sendBuff[7] = inEnableMask; //EnableMask
sendBuff[8] = inTimerClockBase; //TimerClockBase
sendBuff[9] = inUpdateReset; //UpdateReset
for( i = 0; i < 6; i++ )
{
sendBuff[10 + i*3] = inTimerMode[i]; //TimerMode
sendBuff[11 + i*3] = (BYTE)(inTimerValue[i] & 0x00FF); //TimerValue (low byte)
sendBuff[12 + i*3] = (BYTE)((inTimerValue[i] & 0xFF00)/256); //TimerValue (high byte)
}
for( i = 0; i < 2; i++ )
sendBuff[28 + i] = inCounterMode[i]; //CounterMode
extendedChecksum(sendBuff, 30);
//Sending command to UE9
sendChars = LJUSB_Write(hDevice, sendBuff, 30);
if( sendChars < 30 )
{
if( sendChars == 0 )
printf("ehTimerCounter error : write failed\n");
else
printf("ehTimerCounter error : did not write all of the buffer\n");
return -1;
}
//Reading response from UE9
recChars = LJUSB_Read(hDevice, recBuff, 40);
if( recChars < 40 )
{
if( recChars == 0 )
printf("ehTimerCounter error : read failed\n");
else
printf("ehTimerCounter error : did not read all of the buffer\n");
return -1;
}
checksumTotal = extendedChecksum16(recBuff, 40);
if( (BYTE)((checksumTotal / 256) & 0xFF) != recBuff[5] )
{
printf("ehTimerCounter error : read buffer has bad checksum16(MSB)\n");
return -1;
}
if( (BYTE)(checksumTotal & 0xFF) != recBuff[4] )
{
printf("ehTimerCounter error : read buffer has bad checksum16(LBS)\n");
return -1;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("ehTimerCounter error : read buffer has bad checksum8\n");
return -1;
}
if( recBuff[1] != (BYTE)(0xF8) || recBuff[2] != (BYTE)(0x11) || recBuff[3] != (BYTE)(0x18) )
{
printf("ehTimerCounter error : read buffer has wrong command bytes for TimerCounter\n");
return -1;
}
if( outTimer != NULL )
{
for( i = 0; i < 6; i++ )
{
outTimer[i] = 0;
for( j = 0; j < 4; j++ )
outTimer[i] += recBuff[8 + j + i*4] * pow(2, 8*j);
}
}
if( outCounter != NULL )
{
for( i = 0; i < 2; i++ )
{
outCounter[i] = 0;
for( j = 0; j < 4; j++ )
outCounter[i] += recBuff[32 + j + i*4] * pow(2, 8*j);
}
}
return recBuff[6];
}