Files
2021-05-26 15:51:40 +02:00

332 lines
12 KiB
C

//Author: LabJack
//December 27, 2011
//Communicates with an LJTick-DAC using low level functions. The LJTDAC should
//be plugged into FIO4/FIO5 for this example.
//Tested with U3 firmware V1.44, and requires hardware version 1.21 or greater.
#include "u3.h"
#include <unistd.h>
int configIO_example(HANDLE hDevice);
int checkI2CErrorcode(uint8 errorcode);
int LJTDAC_example(HANDLE hDevice, u3TdacCalibrationInfo *caliInfo);
int main(int argc, char **argv)
{
HANDLE hDevice;
u3TdacCalibrationInfo caliInfo;
//Opening first found U3 over USB
if( (hDevice = openUSBConnection(-1)) == NULL )
goto done;
if( configIO_example(hDevice) != 0 )
goto close;
//Getting calibration information from LJTDAC
if( getTdacCalibrationInfo(hDevice, &caliInfo, 4) < 0 )
goto close;
LJTDAC_example(hDevice, &caliInfo);
close:
closeUSBConnection(hDevice);
done:
return 0;
}
//Sends a ConfigIO low-level command that configures the FIO4 and FIO5 lines to
//digital.
int configIO_example(HANDLE hDevice)
{
uint8 sendBuff[12], recBuff[12];
uint16 checksumTotal;
int sendChars, recChars;
sendBuff[1] = (uint8)(0xF8); //Command byte
sendBuff[2] = (uint8)(0x03); //Number of data words
sendBuff[3] = (uint8)(0x0B); //Extended command number
sendBuff[6] = 7; //Writemask : Setting writemask for TimerCounterConfig (bit 0),
// DAC1Enable (bit 1) and FIOAnalog (bit 2)
sendBuff[7] = 0; //Reserved
sendBuff[8] = 64; //TimerCounterConfig : disable timers and counters. set
// TimerCounterPinOffset to 4 (bits 4-7)
sendBuff[9] = 0; //DAC1 enable : disabling
sendBuff[10] = 0; //FIOAnalog : setting FIO channels to digital
sendBuff[11] = 0; //EIOAnalog : Not setting anything
extendedChecksum(sendBuff, 12);
//Sending command to U3
if( (sendChars = LJUSB_Write(hDevice, sendBuff, 12)) < 12 )
{
if( sendChars == 0 )
printf("ConfigIO error : write failed\n");
else
printf("ConfigIO error : did not write all of the buffer\n");
return -1;
}
//Reading response from U3
if( (recChars = LJUSB_Read(hDevice, recBuff, 12)) < 12 )
{
if( recChars == 0 )
printf("ConfigIO error : read failed\n");
else
printf("ConfigIO error : did not read all of the buffer\n");
return -1;
}
checksumTotal = extendedChecksum16(recBuff, 12);
if( (uint8)((checksumTotal / 256 ) & 0xFF) != recBuff[5] )
{
printf("ConfigIO error : read buffer has bad checksum16(MSB)\n");
return -1;
}
if( (uint8)(checksumTotal & 0xFF) != recBuff[4] )
{
printf("ConfigIO error : read buffer has bad checksum16(LBS)\n");
return -1;
}
if( extendedChecksum8(recBuff) != recBuff[0] )
{
printf("ConfigIO error : read buffer has bad checksum8\n");
return -1;
}
if( recBuff[1] != (uint8)(0xF8) || recBuff[2] != (uint8)(0x03) || recBuff[3] != (uint8)(0x0B) )
{
printf("ConfigIO error : read buffer has wrong command bytes\n");
return -1;
}
if( recBuff[6] != 0 )
{
printf("ConfigIO error : read buffer received errorcode %d\n", recBuff[6]);
return -1;
}
if( recBuff[8] != 64 )
{
printf("ConfigIO error : TimerCounterConfig did not get set correctly\n");
return -1;
}
if( recBuff[10] != 0 && recBuff[10] != (uint8)(0x0F) )
{
printf("ConfigIO error : FIOAnalog did not set correctly\n");
return -1;
}
return 0;
}
int checkI2CErrorcode(uint8 errorcode)
{
if(errorcode != 0)
{
printf("I2C error : received errorcode %d in response\n", errorcode);
return -1;
}
return 0;
}
int LJTDAC_example(HANDLE hDevice, u3TdacCalibrationInfo *caliInfo)
{
uint8 options, speedAdjust, sdaPinNum, sclPinNum;
uint8 address, numBytesToSend, numBytesToReceive, errorcode;
uint8 bytesCommand[5], bytesResponse[64], ackArray[4];
uint16 binaryVoltage;
int err, i;
err = 0;
//Setting up parts I2C command that will remain the same throughout this
//example
options = 0; //I2COptions : 0
speedAdjust = 0; //SpeedAdjust : 0 (for max communication speed of about
//130 kHz)
sdaPinNum = 5; //SDAPinNum : FIO5 connected to pin DIOB
sclPinNum = 4; //SCLPinNum : FIO4 connected to pin DIOA
/* Set DACA to 1.2 volts. */
//Setting up I2C command
//Make note that the I2C command can only update 1 DAC channel at a time.
address = (uint8)(0x24); //Address : h0x24 is the address for DAC
numBytesToSend = 3; //NumI2CByteToSend : 3 bytes to specify DACA and the
//value
numBytesToReceive = 0; //NumI2CBytesToReceive : 0 since we are only setting
//the value of the DAC
bytesCommand[0] = (uint8)(0x30); //LJTDAC command byte : h0x30 (DACA)
getTdacBinVoltCalibrated(caliInfo, 0, 1.2, &binaryVoltage);
bytesCommand[1] = (uint8)(binaryVoltage/256); //value (high)
bytesCommand[2] = (uint8)(binaryVoltage & (0x00FF)); //value (low)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
printf("DACA set to 1.2 volts\n\n");
/* Set DACB to 2.3 volts. */
//Setting up I2C command
address = (uint8)(0x24); //Address : h0x24 is the address for DAC
numBytesToSend = 3; //NumI2CByteToSend : 3 bytes to specify DACB and the
//value
numBytesToReceive = 0; //NumI2CBytesToReceive : 0 since we are only setting
//the value of the DAC
bytesCommand[0] = (uint8)(0x31); //LJTDAC command byte : h0x31 (DACB)
getTdacBinVoltCalibrated(caliInfo, 1, 2.3, &binaryVoltage);
bytesCommand[1] = (uint8)(binaryVoltage/256); //value (high)
bytesCommand[2] = (uint8)(binaryVoltage & (0x00FF)); //value (low)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
printf("DACB set to 2.3 volts\n\n");
/* More advanced operations. */
/* Display LJTDAC calibration constants. Code for getting the calibration
* constants is in the getLJTDACCalibrationInfo function in the u3.c file.
*/
printf("DACA Slope = %.1f bits/volt\n", caliInfo->ccConstants[0]);
printf("DACA Offset = %.1f bits\n", caliInfo->ccConstants[1]);
printf("DACB Slope = %.1f bits/volt\n", caliInfo->ccConstants[2]);
printf("DACB Offset = %.1f bits\n\n", caliInfo->ccConstants[3]);
/* Read the serial number. */
//Setting up I2C command
address = (uint8)(0xA0); //Address : h0xA0 is the address for EEPROM
numBytesToSend = 1; //NumI2CByteToSend : 1 byte for the EEPROM address
numBytesToReceive = 4; //NumI2CBytesToReceive : getting 4 bytes starting at
//EEPROM address specified in I2CByte0
bytesCommand[0] = 96; //I2CByte0 : Memory Address, starting at address 96
//(Serial Number)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
printf("LJTDAC Serial Number = %u\n\n", (bytesResponse[0] + bytesResponse[1]*256 + bytesResponse[2]*65536 + bytesResponse[3]*16777216));
/* User memory example. We will read the memory, update a few elements, and
* write the memory. The user memory is just stored as bytes, so almost any
* information can be put in there such as integers, doubles, or strings.
*/
/* Read the user memory : need to perform 2 I2C calls since command/response
packets can only be 64 bytes in size */
//Setting up 1st I2C command
address = (uint8)(0xA0); //Address : h0xA0 is the address for EEPROM
numBytesToSend = 1; //NumI2CByteToSend : 1 byte for the EEPROM address
numBytesToReceive = 52; //NumI2CBytesToReceive : getting 52 bytes starting
//at EEPROM address specified in I2CByte0
bytesCommand[0] = 0; //I2CByte0 : Memory Address, starting at address 0
//(User Area)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
//Setting up 2nd I2C command
numBytesToReceive = 12; //NumI2CBytesToReceive : getting 12 bytes starting
//at EEPROM address specified in I2CByte0
bytesCommand[0] = 52; //I2CByte0 : Memory Address, starting at address 52
//(User Area)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse + 52);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
//Display the first 4 elements.
printf("Read User Mem [0-3] = %d, %d, %d, %d\n", bytesResponse[0], bytesResponse[1], bytesResponse[2], bytesResponse[3]);
/* Create 4 new pseudo-random numbers to write. We will update the first
* 4 elements of user memory, but the rest will be unchanged. */
//Setting up I2C command
address = (uint8)(0xA0); //Address : h0xA0 is the address for EEPROM
numBytesToSend = 5; //NumI2CByteToSend : 1 byte for the EEPROM address and
//the rest for the bytes to write
numBytesToReceive = 0; //NumI2CBytesToReceive : 0 since we are only writing to memory
bytesCommand[0] = 0; //I2CByte0 : Memory Address, starting at address 0
//(User Area)
srand((unsigned int)getTickCount());
for(i = 1; i < 5; i++)
{
//I2CByte : byte in user memory
bytesCommand[i] = (uint8)(255 * ((float)rand()/RAND_MAX));
}
printf("Write User Mem [0-3] = %d, %d, %d, %d\n", bytesCommand[1], bytesCommand[2], bytesCommand[3], bytesCommand[4]);
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
//Delay for 2 ms to allow the EEPROM to finish writing.
//Re-read the user memory.
usleep(2000);
//Setting up 1st I2C command
address = (uint8)(0xA0); //Address : h0xA0 is the address for EEPROM
numBytesToSend = 1; //NumI2CByteToSend : 1 byte for the EEPROM address
numBytesToReceive = 52; //NumI2CBytesToReceive : getting 52 bytes starting
//at EEPROM address specified in I2CByte0
bytesCommand[0] = 0; //I2CByte0 : Memory Address, starting at address 0
//(User Area)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
//Setting up 2nd I2C command
numBytesToReceive = 12; //NumI2CBytesToReceive : getting 12 bytes starting
//at EEPROM address specified in I2CByte0
bytesCommand[0] = 52; //I2CByte0 : Memory Address, starting at address 52
//(User Area)
//Performing I2C low-level call
err = I2C(hDevice, options, speedAdjust, sdaPinNum, sclPinNum, address, numBytesToSend, numBytesToReceive, bytesCommand, &errorcode, ackArray, bytesResponse + 52);
if( checkI2CErrorcode(errorcode) == -1 || err == -1 )
return -1;
//Display the first 4 elements.
printf("Read User Mem [0-3] = %d, %d, %d, %d\n", bytesResponse[0], bytesResponse[1], bytesResponse[2], bytesResponse[3]);
return err;
}