Files

1270 lines
36 KiB
C

//Author: LabJack
//April 6, 2011
//Example U6 helper functions. Function descriptions are in the u6.h file.
#include "u6.h"
#include <stdlib.h>
u6CalibrationInfo U6_CALIBRATION_INFO_DEFAULT = {
6,
1,
//Nominal Values
{0.00031580578,
-10.5869565220,
0.000031580578,
-1.05869565220,
0.0000031580578,
-0.105869565220,
0.00000031580578,
-0.0105869565220,
-.000315805800,
33523.0,
-.0000315805800,
33523.0,
-.00000315805800,
33523.0,
-.000000315805800,
33523.0,
13200.0,
0.0,
13200.0,
0.0,
0.00001,
0.0002,
-92.379,
465.129,
0.00031580578,
-10.5869565220,
0.000031580578,
-1.05869565220,
0.0000031580578,
-0.105869565220,
0.00000031580578,
-0.0105869565220,
-.000315805800,
33523.0,
-.0000315805800,
33523.0,
-.00000315805800,
33523.0,
-.000000315805800,
33523.0}
};
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 sendBuffer[26], recBuffer[38];
uint16 checksumTotal = 0;
uint32 dev, numDevices = 0;
int i;
HANDLE hDevice = 0;
numDevices = LJUSB_GetDevCount(U6_PRODUCT_ID);
if( numDevices == 0 )
{
printf("Open error: No U6 devices could be found\n");
return NULL;
}
for( dev = 1; dev <= numDevices; dev++ )
{
hDevice = LJUSB_OpenDevice(dev, 0, U6_PRODUCT_ID);
if( hDevice != NULL )
{
if( localID < 0 )
{
return hDevice;
}
else
{
checksumTotal = 0;
//setting up a U6Config
sendBuffer[1] = (uint8)(0xF8);
sendBuffer[2] = (uint8)(0x0A);
sendBuffer[3] = (uint8)(0x08);
for( i = 6; i < 26; i++ )
sendBuffer[i] = (uint8)(0x00);
extendedChecksum(sendBuffer, 26);
if( LJUSB_Write(hDevice, sendBuffer, 26) != 26 )
goto locid_error;
if( LJUSB_Read(hDevice, recBuffer, 38) != 38 )
goto locid_error;
checksumTotal = extendedChecksum16(recBuffer, 38);
if( (uint8)((checksumTotal / 256) & 0xff) != recBuffer[5] )
goto locid_error;
if( (uint8)(checksumTotal & 0xff) != recBuffer[4] )
goto locid_error;
if( extendedChecksum8(recBuffer) != recBuffer[0] )
goto locid_error;
if( recBuffer[1] != (uint8)(0xF8) || recBuffer[2] != (uint8)(0x10) ||
recBuffer[3] != (uint8)(0x08) )
goto locid_error;
if( recBuffer[6] != 0 )
goto locid_error;
//Check locasl ID and serial number
if( (int)recBuffer[21] == localID ||
(int)(recBuffer[15] + recBuffer[16]*256 + recBuffer[17]*65536 + recBuffer[18]*16777216) == 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 U6 with a local ID or serial number of %d\n", localID);
return NULL;
locid_error:
printf("Open error: problem when checking local ID\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 isCalibrationInfoValid(u6CalibrationInfo *caliInfo)
{
if( caliInfo == NULL )
goto invalid;
if( caliInfo->prodID != 6 )
goto invalid;
return 1;
invalid:
printf("Error: Invalid calibration info.\n");
return 0;
}
long isTdacCalibrationInfoValid(u6TdacCalibrationInfo *caliInfo)
{
if( caliInfo == NULL )
goto invalid;
if( caliInfo->prodID != 6 )
goto invalid;
return 1;
invalid:
printf("Error: Invalid LJTDAC calibration info.\n");
return 0;
}
long getCalibrationInfo(HANDLE hDevice, u6CalibrationInfo *caliInfo)
{
uint8 sendBuffer[64], recBuffer[64];
int sentRec = 0, offset = 0, i = 0;
/* sending ConfigU6 command to get see if hi res */
sendBuffer[1] = (uint8)(0xF8); //command byte
sendBuffer[2] = (uint8)(0x0A); //number of data words
sendBuffer[3] = (uint8)(0x08); //extended command number
//setting WriteMask0 and all other bytes to 0 since we only want to read the response
for( i = 6; i < 26; i++ )
sendBuffer[i] = 0;
extendedChecksum(sendBuffer, 26);
sentRec = LJUSB_Write(hDevice, sendBuffer, 26);
if( sentRec < 26 )
{
if( sentRec == 0 )
goto writeError0;
else
goto writeError1;
}
sentRec = LJUSB_Read(hDevice, recBuffer, 38);
if( sentRec < 38 )
{
if( sentRec == 0 )
goto readError0;
else
goto readError1;
}
if( recBuffer[1] != (uint8)(0xF8) || recBuffer[2] != (uint8)(0x10) || recBuffer[3] != (uint8)(0x08) )
goto commandByteError;
caliInfo->hiRes = (((recBuffer[37]&8) == 8)?1:0);
for( i = 0; i < 10; i++ )
{
/* reading block i from memory */
sendBuffer[1] = (uint8)(0xF8); //command byte
sendBuffer[2] = (uint8)(0x01); //number of data words
sendBuffer[3] = (uint8)(0x2D); //extended command number
sendBuffer[6] = 0;
sendBuffer[7] = (uint8)i; //Blocknum = i
extendedChecksum(sendBuffer, 8);
sentRec = LJUSB_Write(hDevice, sendBuffer, 8);
if( sentRec < 8 )
{
if( sentRec == 0 )
goto writeError0;
else
goto writeError1;
}
sentRec = LJUSB_Read(hDevice, recBuffer, 40);
if( sentRec < 40 )
{
if( sentRec == 0 )
goto readError0;
else
goto readError1;
}
if( recBuffer[1] != (uint8)(0xF8) || recBuffer[2] != (uint8)(0x11) || recBuffer[3] != (uint8)(0x2D) )
goto commandByteError;
offset = i*4;
//block data starts on byte 8 of the buffer
caliInfo->ccConstants[offset] = FPuint8ArrayToFPDouble(recBuffer + 8, 0);
caliInfo->ccConstants[offset + 1] = FPuint8ArrayToFPDouble(recBuffer + 8, 8);
caliInfo->ccConstants[offset + 2] = FPuint8ArrayToFPDouble(recBuffer + 8, 16);
caliInfo->ccConstants[offset + 3] = FPuint8ArrayToFPDouble(recBuffer + 8, 24);
}
caliInfo->prodID = 6;
return 0;
writeError0:
printf("Error : getCalibrationInfo write failed\n");
return -1;
writeError1:
printf("Error : getCalibrationInfo did not write all of the buffer\n");
return -1;
readError0:
printf("Error : getCalibrationInfo read failed\n");
return -1;
readError1:
printf("Error : getCalibrationInfo did not read all of the buffer\n");
return -1;
commandByteError:
printf("Error : getCalibrationInfo received wrong command bytes for ReadMem\n");
return -1;
}
long getTdacCalibrationInfo(HANDLE hDevice, u6TdacCalibrationInfo *caliInfo, uint8 DIOAPinNum)
{
int err;
uint8 options, speedAdjust, sdaPinNum, sclPinNum;
uint8 address, numByteToSend, numBytesToReceive, errorcode;
uint8 bytesCommand[1], bytesResponse[32], 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 = 6;
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 getAinVoltCalibrated(u6CalibrationInfo *caliInfo, int resolutionIndex, int gainIndex, int bits24, uint32 bytesVolt, double *analogVolt)
{
double value = 0;
int indexAdjust = 0;
if( isCalibrationInfoValid(caliInfo) == 0 )
return -1;
value = (double)bytesVolt;
if( bits24)
value = value/256.0;
if( gainIndex > 4 )
{
printf("getAinVoltCalibrated error: invalid gain index.\n");
return -1;
}
if( resolutionIndex > 8 )
indexAdjust = 24;
if( value < caliInfo->ccConstants[indexAdjust + gainIndex*2 + 9] )
*analogVolt = (caliInfo->ccConstants[indexAdjust + gainIndex*2 + 9] - value) * caliInfo->ccConstants[indexAdjust + gainIndex*2 + 8];
else
*analogVolt = (value - caliInfo->ccConstants[indexAdjust + gainIndex*2 + 9]) * caliInfo->ccConstants[indexAdjust + gainIndex*2];
return 0;
}
long getDacBinVoltCalibrated8Bit(u6CalibrationInfo *caliInfo, int dacNumber, double analogVolt, uint8 *bytesVolt8)
{
uint16 u16BytesVolt = 0;
if( getDacBinVoltCalibrated16Bit(caliInfo, dacNumber, analogVolt, &u16BytesVolt) != -1 )
{
*bytesVolt8 = (uint8)(u16BytesVolt/256);
return 0;
}
return -1;
}
long getDacBinVoltCalibrated16Bit(u6CalibrationInfo *caliInfo, int dacNumber, double analogVolt, uint16 *bytesVolt16)
{
uint32 dBytesVolt;
if( isCalibrationInfoValid(caliInfo) == 0 )
return -1;
if( dacNumber < 0 || dacNumber > 2 )
{
printf("getDacBinVoltCalibrated error: invalid channelNumber.\n");
return -1;
}
dBytesVolt = analogVolt*caliInfo->ccConstants[16 + dacNumber*2] + caliInfo->ccConstants[17 + dacNumber*2];
//Checking to make sure bytesVolt will be a value between 0 and 65535.
if( dBytesVolt > 65535 )
dBytesVolt = 65535;
*bytesVolt16 = (uint16)dBytesVolt;
return 0;
}
long getTempKCalibrated(u6CalibrationInfo *caliInfo, int resolutionIndex, int gainIndex, int bits24, uint32 bytesTemp, double *kelvinTemp)
{
double value;
//convert to voltage first
if( getAinVoltCalibrated(caliInfo, resolutionIndex, gainIndex, bits24, bytesTemp, &value) == -1 )
return -1;
*kelvinTemp = caliInfo->ccConstants[22]*value + caliInfo->ccConstants[23];
return 0;
}
long getTdacBinVoltCalibrated(u6TdacCalibrationInfo *caliInfo, int dacNumber, double analogVolt, uint16 *bytesVolt)
{
uint32 dBytesVolt;
if( isTdacCalibrationInfoValid(caliInfo) == 0 )
return -1;
if( dacNumber < 0 || dacNumber > 2 )
{
printf("getTdacBinVoltCalibrated error: invalid channelNumber.\n");
return -1;
}
dBytesVolt = analogVolt*caliInfo->ccConstants[dacNumber*2] + caliInfo->ccConstants[dacNumber*2 + 1];
//Checking to make sure bytesVolt will be a value between 0 and 65535.
if( dBytesVolt > 65535 )
dBytesVolt = 65535;
*bytesVolt = (uint16)dBytesVolt;
return 0;
}
long getAinVoltUncalibrated(int resolutionIndex, int gainIndex, int bits24, uint32 bytesVolt, double *analogVolt)
{
return getAinVoltCalibrated(&U6_CALIBRATION_INFO_DEFAULT, resolutionIndex, gainIndex, bits24, bytesVolt, analogVolt);
}
long getDacBinVoltUncalibrated8Bit(int dacNumber, double analogVolt, uint8 *bytesVolt8)
{
return getDacBinVoltCalibrated8Bit(&U6_CALIBRATION_INFO_DEFAULT, dacNumber, analogVolt, bytesVolt8);
}
long getDacBinVoltUncalibrated16Bit(int dacNumber, double analogVolt, uint16 *bytesVolt16)
{
return getDacBinVoltCalibrated16Bit(&U6_CALIBRATION_INFO_DEFAULT, dacNumber, analogVolt, bytesVolt16);
}
long getTempKUncalibrated(int resolutionIndex, int gainIndex, int bits24, uint32 bytesTemp, double *kelvinTemp)
{
return getTempKCalibrated(&U6_CALIBRATION_INFO_DEFAULT, resolutionIndex, gainIndex, bits24, 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 U6
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 U6
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 & 255) != 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
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, u6CalibrationInfo *CalibrationInfo, long ChannelP, long ChannelN, double *Voltage, long Range, long Resolution, long Settling, long Binary, long Reserved1, long Reserved2)
{
uint8 diff, gain, Errorcode, ErrorFrame;
uint8 sendDataBuff[4], recDataBuff[5];
uint32 bytesV;
if( isCalibrationInfoValid(CalibrationInfo) == 0 )
{
printf("eAIN error: Invalid calibration information.\n");
return -1;
}
//Checking if acceptable positive channel
if( ChannelP < 0 || ChannelP > 143 )
{
printf("eAIN error: Invalid ChannelP value.\n");
return -1;
}
//Checking if single ended or differential readin
if( ChannelN == 0 || ChannelN == 15 )
{
//Single ended reading
diff = 0;
}
else if( (ChannelN&1) == 1 && ChannelN == ChannelP + 1 )
{
//Differential reading
diff = 1;
}
else
{
printf("eAIN error: Invalid ChannelN value.\n");
return -1;
}
if( Range == LJ_rgAUTO )
gain = 15;
else if( Range == LJ_rgBIP10V )
gain = 0;
else if( Range == LJ_rgBIP1V )
gain = 1;
else if( Range == LJ_rgBIPP1V )
gain = 2;
else if( Range == LJ_rgBIPP01V )
gain = 3;
else
{
printf("eAIN error: Invalid Range value\n");
return -1;
}
if( Resolution < 0 || Resolution > 13 )
{
printf("eAIN error: Invalid Resolution value\n");
return -1;
}
if( Settling < 0 || Settling > 4 )
{
printf("eAIN error: Invalid Settling value\n");
return -1;
}
/* Setting up Feedback command to read analog input */
sendDataBuff[0] = 3; //IOType is AIN24AR
sendDataBuff[1] = (uint8)ChannelP; //Positive channel
sendDataBuff[2] = (uint8)Resolution + gain*16; //Res Index (0-3), Gain Index (4-7)
sendDataBuff[3] = (uint8)Settling + diff*128; //Settling factor (0-2), Differential (7)
if( ehFeedback(Handle, sendDataBuff, 4, &Errorcode, &ErrorFrame, recDataBuff, 5) < 0 )
return -1;
if( Errorcode )
return (long)Errorcode;
bytesV = recDataBuff[0] + ((uint32)recDataBuff[1])*256 + ((uint32)recDataBuff[2])*65536;
gain = recDataBuff[3]/16;
if( Binary != 0 )
{
*Voltage = (double)bytesV;
}
else
{
if( ChannelP == 14 )
{
if( getTempKCalibrated(CalibrationInfo, Resolution, gain, 1, bytesV, Voltage) < 0 )
return -1;
}
else
{
gain = recDataBuff[3]/16;
if( getAinVoltCalibrated(CalibrationInfo, Resolution, gain, 1, bytesV, Voltage) < 0 )
return -1;
}
}
return 0;
}
long eDAC(HANDLE Handle, u6CalibrationInfo *CalibrationInfo, long Channel, double Voltage, long Binary, long Reserved1, long Reserved2)
{
uint8 Errorcode, ErrorFrame;
uint8 sendDataBuff[3];
uint16 bytesV;
long sendSize;
if( isCalibrationInfoValid(CalibrationInfo) == 0 )
{
printf("eDAC error: Invalid calibration information.\n");
return -1;
}
if( Channel < 0 || Channel > 1 )
{
printf("eDAC error: Invalid Channel.\n");
return -1;
}
sendSize = 3;
sendDataBuff[0] = 38 + Channel; //IOType is DAC0/1 (16 bit)
if( getDacBinVoltCalibrated16Bit(CalibrationInfo, (int)Channel, Voltage, &bytesV) < 0 )
return -1;
sendDataBuff[1] = (uint8)(bytesV&255); //Value LSB
sendDataBuff[2] = (uint8)((bytesV&65280)/256); //Value MSB
if( ehFeedback(Handle, sendDataBuff, sendSize, &Errorcode, &ErrorFrame, NULL, 0) < 0 )
return -1;
if( Errorcode )
return (long)Errorcode;
return 0;
}
long eDI(HANDLE Handle, long Channel, long *State)
{
uint8 sendDataBuff[4], recDataBuff[1];
uint8 Errorcode, ErrorFrame;
if( Channel < 0 || Channel > 19 )
{
printf("eDI error: Invalid Channel.\n");
return -1;
}
/* Setting up Feedback command to set digital Channel to input and to read from it */
sendDataBuff[0] = 13; //IOType is BitDirWrite
sendDataBuff[1] = Channel; //IONumber(bits 0-4) + Direction (bit 7)
sendDataBuff[2] = 10; //IOType is BitStateRead
sendDataBuff[3] = Channel; //IONumber
if( ehFeedback(Handle, sendDataBuff, 4, &Errorcode, &ErrorFrame, recDataBuff, 1) < 0 )
return -1;
if( Errorcode )
return (long)Errorcode;
*State = recDataBuff[0];
return 0;
}
long eDO(HANDLE Handle, long Channel, long State)
{
uint8 Errorcode, ErrorFrame;
uint8 sendDataBuff[4];
if( Channel < 0 || Channel > 19 )
{
printf("eD0 error: Invalid Channel\n");
return -1;
}
/* Setting up Feedback command to set digital Channel to output and to set the state */
sendDataBuff[0] = 13; //IOType is BitDirWrite
sendDataBuff[1] = Channel + 128; //IONumber(bits 0-4) + Direction (bit 7)
sendDataBuff[2] = 11; //IOType is BitStateWrite
sendDataBuff[3] = Channel + 128*((State > 0) ? 1 : 0); //IONumber(bits 0-4) + State (bit 7)
if( ehFeedback(Handle, sendDataBuff, 4, &Errorcode, &ErrorFrame, NULL, 0) < 0 )
return -1;
if( Errorcode )
return (long)Errorcode;
return 0;
}
long eTCConfig(HANDLE Handle, long *aEnableTimers, long *aEnableCounters, long TCPinOffset, long TimerClockBaseIndex, long TimerClockDivisor, long *aTimerModes, double *aTimerValues, long Reserved1, long Reserved2)
{
uint8 sendDataBuff[20];
uint8 numTimers, counters, cNumTimers, cCounters, cPinOffset, Errorcode, ErrorFrame;
int sendDataBuffSize, i;
long error;
if( TCPinOffset < 0 || TCPinOffset > 8)
{
printf("eTCConfig error: Invalid TCPinOffset.\n");
return -1;
}
/* ConfigTimerClock */
if( TimerClockBaseIndex == LJ_tc4MHZ || TimerClockBaseIndex == LJ_tc12MHZ || TimerClockBaseIndex == LJ_tc48MHZ ||
TimerClockBaseIndex == LJ_tc1MHZ_DIV || TimerClockBaseIndex == LJ_tc4MHZ_DIV || TimerClockBaseIndex == LJ_tc12MHZ_DIV ||
TimerClockBaseIndex == LJ_tc48MHZ_DIV )
TimerClockBaseIndex = TimerClockBaseIndex - 20;
error = ehConfigTimerClock(Handle, (uint8)(TimerClockBaseIndex + 128), (uint8)TimerClockDivisor, NULL, NULL);
if( error != 0 )
return error;
numTimers = 0;
counters = 0;
for( i = 0; i < 4; i++ )
{
if( aEnableTimers[i] != 0 )
numTimers++;
else
i = 999;
}
for( i = 0; i < 2; i++ )
{
if( aEnableCounters[i] != 0 )
{
counters += pow(2, i);
}
}
error = ehConfigIO(Handle, 1, numTimers, counters, TCPinOffset, &cNumTimers, &cCounters, &cPinOffset);
if( error != 0 )
return error;
if( numTimers > 0 )
{
/* Feedback */
for( i = 0; i < 8; i++ )
sendDataBuff[i] = 0;
for( i = 0; i < numTimers; i++ )
{
sendDataBuff[i*4] = 43 + i*2; //TimerConfig
sendDataBuff[1 + i*4] = (uint8)aTimerModes[i]; //TimerMode
sendDataBuff[2 + i*4] = (uint8)(((long)aTimerValues[i])&0x00ff); //Value LSB
sendDataBuff[3 + i*4] = (uint8)((((long)aTimerValues[i])&0xff00)/256); //Value MSB
}
sendDataBuffSize = 4*numTimers;
if( ehFeedback(Handle, sendDataBuff, sendDataBuffSize, &Errorcode, &ErrorFrame, NULL, 0) < 0 )
return -1;
if( Errorcode )
return (long)Errorcode;
}
return 0;
}
long eTCValues(HANDLE Handle, long *aReadTimers, long *aUpdateResetTimers, long *aReadCounters, long *aResetCounters, double *aTimerValues, double *aCounterValues, long Reserved1, long Reserved2)
{
uint8 Errorcode, ErrorFrame;
uint8 sendDataBuff[20], recDataBuff[24];
int sendDataBuffSize, recDataBuffSize, i, j;
int numTimers, dataCountCounter, dataCountTimer;
/* Feedback */
numTimers = 0;
dataCountCounter = 0;
dataCountTimer = 0;
sendDataBuffSize = 0;
recDataBuffSize = 0;
for( i = 0; i < 4; i++ )
{
if( aReadTimers[i] != 0 || aUpdateResetTimers[i] != 0 )
{
sendDataBuff[sendDataBuffSize] = 42 + i*2; //Timer
sendDataBuff[1 + sendDataBuffSize] = ((aUpdateResetTimers[i] != 0) ? 1 : 0); //UpdateReset
sendDataBuff[2 + sendDataBuffSize] = (uint8)(((long)aTimerValues[i])&0x00ff); //Value LSB
sendDataBuff[3 + sendDataBuffSize] = (uint8)((((long)aTimerValues[i])&0xff00)/256); //Value MSB
sendDataBuffSize += 4;
recDataBuffSize += 4;
numTimers++;
}
}
for( i = 0; i < 2; i++ )
{
if( aReadCounters[i] != 0 || aResetCounters[i] != 0 )
{
sendDataBuff[sendDataBuffSize] = 54 + i; //Counter
sendDataBuff[1 + sendDataBuffSize] = ((aResetCounters[i] != 0) ? 1 : 0); //Reset
sendDataBuffSize += 2;
recDataBuffSize += 4;
}
}
if( ehFeedback(Handle, sendDataBuff, sendDataBuffSize, &Errorcode, &ErrorFrame, recDataBuff, recDataBuffSize) < 0 )
return -1;
if( Errorcode )
return (long)Errorcode;
for( i = 0; i < 4; i++ )
{
aTimerValues[i] = 0;
if( aReadTimers[i] != 0 )
{
for( j = 0; j < 4; j++ )
aTimerValues[i] += (double)((long)recDataBuff[j + dataCountTimer*4]*pow(2, 8*j));
}
if( aReadTimers[i] != 0 || aUpdateResetTimers[i] != 0 )
dataCountTimer++;
if( i < 2 )
{
aCounterValues[i] = 0;
if( aReadCounters[i] != 0 )
{
for( j = 0; j < 4; j++ )
aCounterValues[i] += (double)((long)recDataBuff[j + numTimers*4 + dataCountCounter*4]*pow(2, 8*j));
}
if( aReadCounters[i] != 0 || aResetCounters[i] != 0 )
dataCountCounter++;
}
}
return 0;
}
long ehConfigIO(HANDLE hDevice, uint8 inWriteMask, uint8 inNumberTimersEnabled, uint8 inCounterEnable, uint8 inPinOffset, uint8 *outNumberTimersEnabled, uint8 *outCounterEnable, uint8 *outPinOffset)
{
uint8 sendBuff[16], recBuff[16];
uint16 checksumTotal;
int sendChars, recChars, i;
sendBuff[1] = (uint8)(0xF8); //Command byte
sendBuff[2] = (uint8)(0x05); //Number of data words
sendBuff[3] = (uint8)(0x0B); //Extended command number
sendBuff[6] = inWriteMask; //Writemask
sendBuff[7] = inNumberTimersEnabled;
sendBuff[8] = inCounterEnable;
sendBuff[9] = inPinOffset;
for( i = 10; i < 16; i++ )
sendBuff[i] = 0;
extendedChecksum(sendBuff, 16);
//Sending command to U6
if( (sendChars = LJUSB_Write(hDevice, sendBuff, 16)) < 16 )
{
if( sendChars == 0 )
printf("ehConfigIO error : write failed\n");
else
printf("ehConfigIO error : did not write all of the buffer\n");
return -1;
}
//Reading response from U6
if( (recChars = LJUSB_Read(hDevice, recBuff, 16)) < 16 )
{
if( recChars == 0 )
printf("ehConfigIO error : read failed\n");
else
printf("ehConfigIO error : did not read all of the buffer\n");
return -1;
}
checksumTotal = extendedChecksum16(recBuff, 16);
if( (uint8)((checksumTotal / 256 ) & 0xff) != recBuff[5] )
{
printf("ehConfigIO error : read buffer has bad checksum16(MSB)\n");
return -1;
}
if( (uint8)(checksumTotal & 0xff) != recBuff[4] )
{
printf("ehConfigIO error : read buffer has bad checksum16(LBS)\n");
return -1;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("ehConfigIO error : read buffer has bad checksum8\n");
return -1;
}
if( recBuff[1] != (uint8)(0xF8) || recBuff[2] != (uint8)(0x05) || recBuff[3] != (uint8)(0x0B) )
{
printf("ehConfigIO error : read buffer has wrong command bytes\n");
return -1;
}
if( recBuff[6] != 0 )
{
printf("ehConfigIO error : read buffer received errorcode %d\n", recBuff[6]);
return (int)recBuff[6];
}
if( outNumberTimersEnabled != NULL )
*outNumberTimersEnabled = recBuff[7];
if( outCounterEnable != NULL )
*outCounterEnable = recBuff[8];
if( outPinOffset != NULL)
*outPinOffset = recBuff[9];
return 0;
}
long ehConfigTimerClock(HANDLE hDevice, uint8 inTimerClockConfig, uint8 inTimerClockDivisor, uint8 *outTimerClockConfig, uint8 *outTimerClockDivisor)
{
uint8 sendBuff[10], recBuff[10];
uint16 checksumTotal;
int sendChars, recChars;
sendBuff[1] = (uint8)(0xF8); //Command byte
sendBuff[2] = (uint8)(0x02); //Number of data words
sendBuff[3] = (uint8)(0x0A); //Extended command number
sendBuff[6] = 0; //Reserved
sendBuff[7] = 0; //Reserved
sendBuff[8] = inTimerClockConfig; //TimerClockConfig
sendBuff[9] = inTimerClockDivisor; //TimerClockDivisor
extendedChecksum(sendBuff, 10);
//Sending command to U6
if( (sendChars = LJUSB_Write(hDevice, sendBuff, 10)) < 10 )
{
if( sendChars == 0 )
printf("ehConfigTimerClock error : write failed\n");
else
printf("ehConfigTimerClock error : did not write all of the buffer\n");
return -1;
}
//Reading response from U6
if( (recChars = LJUSB_Read(hDevice, recBuff, 10)) < 10 )
{
if( recChars == 0 )
printf("ehConfigTimerClock error : read failed\n");
else
printf("ehConfigTimerClock error : did not read all of the buffer\n");
return -1;
}
checksumTotal = extendedChecksum16(recBuff, 10);
if( (uint8)((checksumTotal / 256 ) & 0xff) != recBuff[5] )
{
printf("ehConfigTimerClock error : read buffer has bad checksum16(MSB)\n");
return -1;
}
if( (uint8)(checksumTotal & 0xff) != recBuff[4] )
{
printf("ehConfigTimerClock error : read buffer has bad checksum16(LBS)\n");
return -1;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("ehConfigTimerClock error : read buffer has bad checksum8\n");
return -1;
}
if( recBuff[1] != (uint8)(0xF8) || recBuff[2] != (uint8)(0x02) || recBuff[3] != (uint8)(0x0A) )
{
printf("ehConfigTimerClock error : read buffer has wrong command bytes\n");
return -1;
}
if( outTimerClockConfig != NULL )
*outTimerClockConfig = recBuff[8];
if( outTimerClockDivisor != NULL )
*outTimerClockDivisor = recBuff[9];
if( recBuff[6] != 0 )
{
printf("ehConfigTimerClock error : read buffer received errorcode %d\n", recBuff[6]);
return recBuff[6];
}
return 0;
}
long ehFeedback(HANDLE hDevice, uint8 *inIOTypesDataBuff, long inIOTypesDataSize, uint8 *outErrorcode, uint8 *outErrorFrame, uint8 *outDataBuff, long outDataSize)
{
uint8 *sendBuff, *recBuff;
uint16 checksumTotal;
int sendChars, recChars, i, sendDWSize, recDWSize, commandBytes, ret;
ret = 0;
commandBytes = 6;
if( ((sendDWSize = inIOTypesDataSize + 1)%2) != 0 )
sendDWSize++;
if( ((recDWSize = outDataSize + 3)%2) != 0 )
recDWSize++;
sendBuff = (uint8 *)malloc(sizeof(uint8)*(commandBytes + sendDWSize));
recBuff = (uint8 *)malloc(sizeof(uint8)*(commandBytes + recDWSize));
if( sendBuff == NULL || recBuff == NULL )
{
ret = -1;
goto cleanmem;
}
sendBuff[sendDWSize + commandBytes - 1] = 0;
/* Setting up Feedback command */
sendBuff[1] = (uint8)(0xF8); //Command byte
sendBuff[2] = sendDWSize/2; //Number of data words (.5 word for echo, 1.5
//words for IOTypes)
sendBuff[3] = (uint8)(0x00); //Extended command number
sendBuff[6] = 0; //Echo
for( i = 0; i < inIOTypesDataSize; i++ )
sendBuff[i+commandBytes+1] = inIOTypesDataBuff[i];
extendedChecksum(sendBuff, (sendDWSize+commandBytes));
//Sending command to U6
if( (sendChars = LJUSB_Write(hDevice, sendBuff, (sendDWSize+commandBytes))) < sendDWSize+commandBytes )
{
if( sendChars == 0 )
printf("ehFeedback error : write failed\n");
else
printf("ehFeedback error : did not write all of the buffer\n");
ret = -1;
goto cleanmem;
}
//Reading response from U6
if( (recChars = LJUSB_Read(hDevice, recBuff, (commandBytes+recDWSize))) < commandBytes+recDWSize )
{
if( recChars == -1 )
{
printf("ehFeedback error : read failed\n");
ret = -1;
goto cleanmem;
}
else if( recChars < 8 )
{
printf("ehFeedback error : response buffer is too small\n");
for( i = 0; i < recChars; i++ )
printf("%d ", recBuff[i]);
ret = -1;
goto cleanmem;
}
else
printf("ehFeedback error : did not read all of the expected buffer (received %d, expected %d )\n", recChars, commandBytes+recDWSize);
}
checksumTotal = extendedChecksum16(recBuff, recChars);
if( (uint8)((checksumTotal / 256 ) & 0xff) != recBuff[5] )
{
printf("ehFeedback error : read buffer has bad checksum16(MSB)\n");
ret = -1;
goto cleanmem;
}
if( (uint8)(checksumTotal & 0xff) != recBuff[4] )
{
printf("ehFeedback error : read buffer has bad checksum16(LBS)\n");
ret = -1;
goto cleanmem;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("ehFeedback error : read buffer has bad checksum8\n");
ret = -1;
goto cleanmem;
}
if( recBuff[1] != (uint8)(0xF8) || recBuff[3] != (uint8)(0x00) )
{
printf("ehFeedback error : read buffer has wrong command bytes \n");
ret = -1;
goto cleanmem;
}
*outErrorcode = recBuff[6];
*outErrorFrame = recBuff[7];
for( i = 0; i+commandBytes+3 < recChars && i < outDataSize; i++ )
outDataBuff[i] = recBuff[i+commandBytes+3];
cleanmem:
free(sendBuff);
free(recBuff);
sendBuff = NULL;
recBuff = NULL;
return ret;
}