1270 lines
36 KiB
C
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;
|
|
}
|