Initial commit

This commit is contained in:
Saeid Bazazzadeh 2018-05-01 12:02:27 -04:00
commit f7555d73db
243 changed files with 41822 additions and 0 deletions

48
.gitignore vendored Normal file
View File

@ -0,0 +1,48 @@
.deps
.libs
Makefile
Makefile.in
*.la
*.lo
*.o
libtool
ltmain.sh
missing
stamp-h1
m4/
autom4te.cache
INSTALL
install-sh
depcomp
configure
aclocal.m4
compile
config.guess
config.h*
config.log
config.status
config.sub
ar-lib
*.exe
*.pc
doc/html
*.plg
*.ncb
*.opt
Debug
Release
*.user
*.suo
*.sdf
*.opensdf
*.patch
*~
*.bz2
libuldaq.pc.in
.dirstamp
src/*.sh
examples/*
!examples/*.c
!examples/*.h
!examples/*.am

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Measurement Computing
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

56
Makefile.am Normal file
View File

@ -0,0 +1,56 @@
AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip subdir-objects
ACLOCAL_AMFLAGS = -I m4
DISTCLEANFILES = libuldaq.pc
SUBDIRS = src
if BUILD_EXAMPLES
SUBDIRS += examples
endif
EXTRA_DIST = doc/Doxyfile
dist_doc_DATA = README.md
pkgconfigdir=$(libdir)/pkgconfig
dist_pkgconfig_DATA=libuldaq.pc
fpgadatadir=/etc/uldaq/fpga
dist_fpgadata_DATA=fpga/USB_1208HS.rbf\
fpga/USB_1608G_2.rbf\
fpga/USB_1608G.rbf\
fpga/USB_1808.bin\
fpga/usb_2020.bin\
fpga/USB_26xx.rbf\
fpga/USB_CTR.bin\
fpga/USB_DIO32HS.bin
if OS_LINUX
rulesdatadir=/lib/udev/rules.d/
dist_rulesdata_DATA=rules/50-uldaq.rules
endif
dist-hook:
chmod u+w $(distdir)/examples/*.c
chmod u+w $(distdir)/examples/*.h
.PHONY: dist-up
reldir = .release/$(distdir)
dist-up: dist
rm -rf $(reldir)
mkdir -p $(reldir)
cp $(distdir).tar.bz2 $(reldir)
if OS_LINUX
install-data-hook:
udevadm control --reload-rules && \
test -f "/etc/redhat-release" && echo "/usr/local/lib" > /etc/ld.so.conf.d/uldaq.conf || echo "" && \
ldconfig
endif
if OS_LINUX
uninstall-hook:
test -f "/etc/ld.so.conf.d/uldaq.conf" && rm "/etc/ld.so.conf.d/uldaq.conf" || echo ""
endif

129
README.md Normal file
View File

@ -0,0 +1,129 @@
## MCC Universal Library for Linux (uldaq)
**Info:** Contains a library to access and control supported Measurement Computing DAQ devices over the Linux platform. The UL for Linux binary name is libuldaq.
**Author:** Measurement Computing
## About
The **uldaq** package contains programming libraries and components for developing applications using C/C++ on Linux Operating Systems. An API (Application Programming Interface) for interacting with the library in Python is available as an additional installation. This package was created and is supported by MCC.
### Prerequisites:
---------------
Building the **uldaq** package requires C/C++ compilers, make tool, and the development package for libusb. The following describes how these prerequisites can be installed on different Linux distributions.
- Debian-based Linux distributions such as Ubuntu, Raspbian
```
$ sudo apt-get install gcc g++ make
$ sudo apt-get install libusb-1.0-0-dev
```
- Red Hat-based Linux distributions such as Fedora, CentOS
```
$ sudo yum install gcc gcc-c++ make
$ sudo yum install libusbx-devel
```
- OpenSUSE
```
$ sudo zypper install gcc gcc-c++ make
$ sudo zypper install libusb-devel
```
### Build Instructions
---------------------
1. Download the latest version of **uldaq**:
```
Linux
    $ wget https://github.com/mccdaq/uldaq/releases/download/v1.0.0/libuldaq-1.0.0.tar.bz2
```
2. Extract the tar file:
```
 $ tar -xvjf libuldaq-1.0.0.tar.bz2
```
3. Run the following commands to build and install the library:
```
 $ cd libuldaq-1.0.0.tar.bz2
 $ ./configure && make
$ sudo make install
```
**Note:** To install the Python interface, follow the above [build instructions](#build-instructions) then go to https://pypi.org/project/uldaq/ for further installation.
### Examples
The C examples are located in the examples folder. Run the following commands to execute the analog input example:
```
$ cd examples
$ ./AIn
```
Refer to the **uldaq** [PyPI](https://pypi.org/project/uldaq/) page for instructions on installing Python examples.
### Usage
The following is a basic C example of using the Universal Library for Linux to perform analog input. Further examples are available in the Examples folder.
``` C
#include <stdio.h>
#include "uldaq.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
unsigned int numDevs = MAX_DEV_COUNT;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceHandle handle = 0;
int chan = 0;
double data = 0;
UlError err = ERR_NO_ERROR;
// Get descriptors for all of the available DAQ devices
ulGetDaqDeviceInventory(ANY_IFC, devDescriptors, &numDevs);
// verify at least one DAQ device is detected
if (numDevs)
{
// get a handle to the DAQ device associated with the first descriptor
handle = ulCreateDaqDevice(devDescriptors[0]);
// check if the DAQ device handle is valid
if (handle)
{
// establish a connection to the DAQ device
err = ulConnectDaqDevice(handle);
// read data for the first 4 analog input channels
for (chan = 0; chan <= 3; chan++)
{
err = ulAIn(handle, chan, AI_SINGLE_ENDED, BIP5VOLTS, AIN_FF_DEFAULT, &data);
printf("Channel(%d) Data: %10.6f\n", chan, data);
}
ulDisconnectDaqDevice(handle);
ulReleaseDaqDevice(handle);
}
}
return 0;
}
```
### Support/Feedback
The **uldaq** package is supported by MCC. For support for uldaq, contact technical through [support page](https://www.mccdaq.com/support/support_form.aspx). Please include detailed steps on how to reproduce the problem in your request.
### Documentation
Online help for the Universal Library for Linux is available for [C/C++](https://www.mccdaq.com/PDFs/Manuals/UL-Linux/c/index.html) and [Python](https://www.mccdaq.com/PDFs/Manuals/UL-Linux/python/index.html).
If Doxygen is installed and you wish to build the API documentation on your system, run the following commands:
```
$ cd doc
$ doxygen Doxyfile
```

92
configure.ac Normal file
View File

@ -0,0 +1,92 @@
m4_define([LIBUL_MAJOR], 1)
m4_define([LIBUL_MINOR], 0)
m4_define([LIBUL_MICRO], 0)
m4_define([LIBUL_RC],)
AC_INIT([libuldaq],[LIBUL_MAJOR[.]LIBUL_MINOR[.]LIBUL_MICRO[]LIBUL_RC],[info@mccdaq.com],[libuldaq],[http://www.mccdaq.com])
# Library versioning
# These numbers should be tweaked on every release. Read carefully:
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
# http://sourceware.org/autobook/autobook/autobook_91.html
lt_current=1
lt_revision=0
lt_age=0
LTLDFLAGS="-version-info ${lt_current}:${lt_revision}:${lt_age}"
CFLAGS='-O3'
CXXFLAGS='-O3'
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AM_PROG_AR
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AC_PREREQ([2.69])
AC_PROG_CXX
AC_PROG_CC
LT_INIT
libul_lib_error() {
echo ""
echo " Library $1 was not found on this system."
echo " Please install it and re-run ./configure"
echo ""
exit 1
}
AC_MSG_CHECKING([operating system])
AC_MSG_RESULT($host)
case $host in
*-linux*)
AC_MSG_RESULT([ Linux])
AC_DEFINE(OS_LINUX, 1, [Linux implementations])
AC_SUBST(OS_LINUX)
backend="linux"
os="linux"
;;
*-darwin*)
AC_MSG_RESULT([ Mac OS X])
AC_DEFINE(OS_DARWIN, 1, [Mac implementation])
AC_SUBST(OS_DARWIN)
backend="mac"
os="darwin"
LIBS="${LIBS} -framework IOKit -framework CoreFoundation"
;;
*)
AC_MSG_ERROR([UL for Linux is not supported on your operating system yet])
esac
# Checks for libraries.
AC_CHECK_LIB([usb-1.0], [libusb_init], [], [libul_lib_error libusb-1.0])
AC_CHECK_HEADERS([libusb-1.0/libusb.h], [], [libul_lib_error libusb-1.0])
# OS info for Automake
AM_CONDITIONAL(OS_LINUX, test "x$os" = xlinux)
AM_CONDITIONAL(OS_DARWIN, test "x$os" = xdarwin)
# Examples build
AC_ARG_ENABLE([disable-examples-build], [AS_HELP_STRING([--disable-examples-build],
[disable building example applications [default=no]])],
[disable_build_examples=$enableval],
[disable_build_examples=no])
AM_CONDITIONAL(BUILD_EXAMPLES, test "x$disable_build_examples" != xyes)
# Debug enable
AC_ARG_ENABLE([debug], [AS_HELP_STRING([--debug],
[turn on debugging [default=no]])],
[debug=$enableval],
[debug=no])
AM_CONDITIONAL(DEBUG, test "x$debug" != xno)
AC_SUBST(LTLDFLAGS)
AC_CONFIG_FILES([libuldaq.pc])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([examples/Makefile])
AC_OUTPUT

2350
doc/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

158
examples/AIn.c Normal file
View File

@ -0,0 +1,158 @@
/*
UL call demonstrated: ulAIn()
Purpose: Reads the user-specified A/D input channels
Demonstration: Displays the analog input data for each of
the user-specified channels using the first
supported range and input mode
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an analog input subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Get the first supported analog range
6. Call ulAIn() for each channel specified to read a value from the A/D input channel
7. Display the data for each channel
8. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
// set some variables used to acquire data
int lowChan = 0;
int highChan = 3;
int chan = 0;
AiInputMode inputMode = AI_DIFFERENTIAL;
Range range = BIP10VOLTS;
AInFlag flags = AIN_FF_DEFAULT;
int hasAI = 0;
int numberOfChannels = 0;
char inputModeStr[MAX_STR_LENGTH];
char rangeStr[MAX_STR_LENGTH];
int i = 0;
double data = 0;
UlError err = ERR_NO_ERROR;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports analog input
err = getDevInfoHasAi(daqDeviceHandle, &hasAI);
if (!hasAI)
{
printf("\nThe specified DAQ device does not support analog input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the first supported analog input mode
err = getAiInfoFirstSupportedInputMode(daqDeviceHandle, &numberOfChannels, &inputMode, inputModeStr);
if (highChan >= numberOfChannels)
highChan = numberOfChannels - 1;
// get the first supported analog input range
err = getAiInfoFirstSupportedRange(daqDeviceHandle, inputMode, &range, rangeStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulAIn()\n");
printf(" Channels: %d - %d\n", lowChan, highChan);
printf(" Input mode: %s\n", inputModeStr);
printf(" Range: %s\n", rangeStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
while(err == ERR_NO_ERROR && !enter_press())
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
// display data for the first 4 analog input channels
for (chan = lowChan; chan <= highChan; chan++)
{
err = ulAIn(daqDeviceHandle, chan, inputMode, range, flags, &data);
if(err == ERR_NO_ERROR)
printf("Channel(%d) Data: %10.6f\n", chan, data);
}
usleep(100000);
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
if(daqDeviceHandle)
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

224
examples/AInScan.c Normal file
View File

@ -0,0 +1,224 @@
/*
UL call demonstrated: ulAInScan()
Purpose: Performs a continuous scan of the range
of A/D input channels
Demonstration: Displays the analog input data for the
range of user-specified channels using
the first supported range and input mode
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an analog input subsystem
4. Verify the analog input subsystem has a hardware pacer
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Get the first supported analog range
7. Call ulAInScan() to start the scan of A/D input channels
8. Call ulAInScanStatus() to check the status of the background operation
9. Display the data for each channel
10. Call ulAInScanStop() to stop the background operation
11. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
// set some variables that are used to acquire data
int lowChan = 0;
int highChan = 3;
AiInputMode inputMode = AI_SINGLE_ENDED;
Range range = BIP10VOLTS;
int samplesPerChannel = 10000;
double rate = 1000;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
AInScanFlag flags = AINSCAN_FF_DEFAULT;
int hasAI = 0;
int hasPacer = 0;
int numberOfChannels = 0;
int index = 0;
char inputModeStr[MAX_STR_LENGTH];
char rangeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
int chanCount = 0;
double* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified device supports analog input
err = getDevInfoHasAi(daqDeviceHandle, &hasAI);
if (!hasAI)
{
printf("\nThe specified DAQ device does not support analog input\n");
goto end;
}
// verify the specified device supports hardware pacing for analog input
err = getAiInfoHasPacer(daqDeviceHandle, &hasPacer);
if (!hasPacer)
{
printf("\nThe specified DAQ device does not support hardware paced analog input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the first supported analog input mode
err = getAiInfoFirstSupportedInputMode(daqDeviceHandle, &numberOfChannels, &inputMode, inputModeStr);
if (highChan >= numberOfChannels)
highChan = numberOfChannels - 1;
chanCount = highChan - lowChan + 1;
// allocate a buffer to receive the data
buffer = (double*) malloc(chanCount * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
// get the first supported analog input range
err = getAiInfoFirstSupportedRange(daqDeviceHandle, inputMode, &range, rangeStr);
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulAInscan()\n");
printf(" Channels: %d - %d\n", lowChan, highChan);
printf(" Input mode: %s\n", inputModeStr);
printf(" Range: %s\n", rangeStr);
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
// clear the display
ret = system("clear");
// start the acquisition
err = ulAInScan(daqDeviceHandle, lowChan, highChan, inputMode, range, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
// get the initial status of the acquisition
ulAInScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulAInScanStatus(daqDeviceHandle, &status, &transferStatus);
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
// display the data
for (i = 0; i < chanCount; i++)
{
printf("chan %d = %10.6f\n",
i + lowChan,
buffer[index + i]);
}
usleep(100000);
}
// stop the acquisition if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
err = ulAInScanStop(daqDeviceHandle);
}
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
if(daqDeviceHandle)
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

View File

@ -0,0 +1,289 @@
/*
UL call demonstrated: ulEnableEvent() and ulAInScanWait()
Purpose: Use events to determine when data is available
Demonstration: Use the a callback function to display the
the data for a user-specified range of
A/D channels
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an analog input subsystem
3. Verify the analog input subsystem has a hardware pacer
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Initialize the ScanEventParameters structure used to pass parameters to the callback function
6. Call ulEnableEvent() to enable the DE_ON_DATA_AVAILABLE event
7. Call ulAInScan() to start the finite scan of A/D input channels
8. Call ulAInScanWait() to wait for the finite scan to complete
9. The callback is called each time 100 samples are available to allow the data to be displayed
10. Call ulAinScanStop() to stop the background operation
11. Call ulDisconnectDaqDevice and ulReleaseDaqDevice() before exiting the process
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
double rate = 1000;
void eventCallbackFunction(DaqDeviceHandle daqDeviceHandle, DaqEventType eventType, unsigned long long eventData, void* userData);
struct ScanEventParameters
{
double* buffer; // data buffer
int lowChan; // first channel in acquisition
int highChan; // last channel in acquisition
};
typedef struct ScanEventParameters ScanEventParameters;
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
ScanEventParameters scanEventParameters;
// set some variables that are used to acquire data
int lowChan = 0;
int highChan = 3;
AiInputMode inputMode = AI_SINGLE_ENDED;
Range range = BIP10VOLTS;
int samplesPerChannel = 10000;
AInScanFlag flags = AINSCAN_FF_DEFAULT;
DaqEventType eventTypes = (DaqEventType) (DE_ON_DATA_AVAILABLE | DE_ON_INPUT_SCAN_ERROR | DE_ON_END_OF_INPUT_SCAN);
// set the scan options for a FINITE scan ... to set the scan options for
// a continuous scan, uncomment the line that or's the SO_CONTINUOUS option
// into to the scanOptions variable
//
// if this is changed to a CONTINUOUS scan, then changes will need to be made
// to the event handler (eventCallbackFunction) to account for the buffer wrap
// around condition
ScanOption scanOptions = SO_DEFAULTIO;
//scanOptions |= SO_CONTINUOUS;
int hasAI = 0;
int hasPacer = 0;
int numberOfChannels = 0;
int availableSampeCount = 0;
char inputModeStr[MAX_STR_LENGTH];
char rangeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
// allocate a buffer to receive the data
int chanCount = 0;
double* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports analog input
err = getDevInfoHasAi(daqDeviceHandle, &hasAI);
if (!hasAI)
{
printf("\nThe specified DAQ device does not support analog input\n");
goto end;
}
// verify the device supports hardware pacing for analog input
err = getAiInfoHasPacer(daqDeviceHandle, &hasPacer);
if (!hasPacer)
{
printf("The specified DAQ device does not support hardware paced analog input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the first supported analog input mode
err = getAiInfoFirstSupportedInputMode(daqDeviceHandle, &numberOfChannels, &inputMode, inputModeStr);
if (highChan >= numberOfChannels)
highChan = numberOfChannels - 1;
chanCount = highChan - lowChan + 1;
// allocate a buffer to receive the data
buffer = (double*) malloc(chanCount * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
// store the scan event parameters for use in the callback function
scanEventParameters.buffer = buffer;
scanEventParameters.lowChan = lowChan;
scanEventParameters.highChan = highChan;
// enable the event to be notified every time 100 samples are available
availableSampeCount = 100;
err = ulEnableEvent(daqDeviceHandle, eventTypes, availableSampeCount, eventCallbackFunction, &scanEventParameters);
// get the first supported analog input range
err = getAiInfoFirstSupportedRange(daqDeviceHandle, inputMode, &range, rangeStr);
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulEnableEvent()\n");
printf(" Channels: %d - %d\n", lowChan, highChan);
printf(" Input mode: %s\n", inputModeStr);
printf(" Range: %s\n", rangeStr);
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
// clear the display
ret = system("clear");
// start the finite acquisition
err = ulAInScan(daqDeviceHandle, lowChan, highChan, inputMode, range, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
// wait here until scan is done ... events will be handled in the event handler
// (eventCallbackFunction) until the background scan completes
int timeToWait = -1;
err = ulAInScanWait(daqDeviceHandle, WAIT_UNTIL_DONE, 0, timeToWait);
if (err != ERR_NO_ERROR)
{
printf ("ulAInScanWait error = %d\n", err);
}
err = ulAInScanStop(daqDeviceHandle);
}
// disable events
ulDisableEvent(daqDeviceHandle, eventTypes);
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
if(daqDeviceHandle)
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}
void eventCallbackFunction(DaqDeviceHandle daqDeviceHandle, DaqEventType eventType, unsigned long long eventData, void* userData)
{
char eventTypeStr[MAX_STR_LENGTH];
UlError err = ERR_NO_ERROR;
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
ConvertEventTypesToString(eventType, eventTypeStr);
printf("eventType: %s \n", eventTypeStr);
if (eventType == DE_ON_DATA_AVAILABLE)
{
ScanEventParameters* scanEventParameters = (ScanEventParameters*) userData;
long long totalSamples = eventData;
int i;
long long index = 0;
int chanCount = scanEventParameters->highChan - scanEventParameters->lowChan + 1;;
printf("eventData: %lld \n\n", eventData);
printf("actual scan rate = %f\n\n", rate);
// if this example is changed to a CONTINUOUS scan, then you will need
// to maintain the index of where the data is being written to the buffer
// to handle the buffer wrap around condition
index = (totalSamples * chanCount) - chanCount;
printf("currentIndex = %lld \n\n", index);
for (i = 0; i < chanCount; i++)
{
printf("chan %d = %10.6f\n",
i + scanEventParameters->lowChan,
scanEventParameters->buffer[index + i]);
}
}
if(eventType == DE_ON_INPUT_SCAN_ERROR)
{
err = (UlError) eventData;
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
if (eventType == DE_ON_END_OF_INPUT_SCAN)
{
printf("\nThe scan using device handle %lld is complete \n", daqDeviceHandle);
}
}

275
examples/AInScanWithQueue.c Normal file
View File

@ -0,0 +1,275 @@
/*
UL call demonstrated: ulAInLoadQueue()
Purpose: Set up the queue with available ranges
and input modes
Demonstration: Initialize and load the queue
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an analog input subsystem
4. Verify the analog input subsystem has a hardware pacer
5. Get the supported ranges
6. Get the supported queue types
7. Setup the queue structure array
8. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
9. Call ulAInLoadQueue() to load the queue
10. Call ulAInScan() to start the scan of A/D input channels
11. Call ulAiScanStatus to check the status of the background operation
12. Display the data for each channel
13. Call ulAinScanStop() to stop the background operation
14. Call ulDisconnectDaqDevice and ulReleaseDaqDevice() before exiting the process
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_RANGE_COUNT 8
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
#define MAX_QUEUE_SIZE 8 // arbitrary limit for the size for the queue
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
// when using the queue, the lowChan, highChan, inputMode, and range
// parameters are ignored since they are specified in queueArray
int lowChan = 0;
int highChan = 3;
AiInputMode inputMode = AI_SINGLE_ENDED;
Range range = BIP10VOLTS;
// set some variables that are used to acquire data
int samplesPerChannel = 10000;
double rate = 1000;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
AInScanFlag flags = AINSCAN_FF_DEFAULT;
Range ranges[MAX_RANGE_COUNT];
int hasAI = 0;
int hasPacer = 0;
int numRanges = 0;
int numberOfChannels = 0;
int queueTypes;
int index = 0;
char rangeStr[MAX_STR_LENGTH];
char inputModeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
int chanCount = 0;
double *buffer = NULL;
AiQueueElement queueArray[MAX_QUEUE_SIZE];
UlError err = ERR_NO_ERROR;
int __attribute__ ((unused))ret;
char c;
int i = 0;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if(err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ devices are connected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;;
}
// verify the specified DAQ device supports analog input
err = getDevInfoHasAi(daqDeviceHandle, &hasAI);
if (!hasAI)
{
printf("\nThe specified DAQ device does not support analog input\n");
goto end;
}
// verify the specified device supports hardware pacing for analog input
err = getAiInfoHasPacer(daqDeviceHandle, &hasPacer);
if (!hasPacer)
{
printf("\nThe specified DAQ device does not support hardware paced analog input\n");
goto end;
}
// get the analog input ranges
err = getAiInfoRanges(daqDeviceHandle, inputMode, &numRanges, ranges);
// get the queue types
err = getAiInfoQueueTypes(daqDeviceHandle, &queueTypes);
// get the first supported analog input mode
err = getAiInfoFirstSupportedInputMode(daqDeviceHandle, &numberOfChannels, &inputMode, inputModeStr);
if (highChan >= numberOfChannels)
highChan = numberOfChannels - 1;
if (highChan >= MAX_QUEUE_SIZE)
highChan = MAX_QUEUE_SIZE - 1;
chanCount = highChan - lowChan + 1;
// does the device support a queue
if (queueTypes == 0)
{
printf("\nThe specified DAQ device does not support a queue\n");
goto end;
}
// assign each channel in the queue an input mode (SE/DIFF) and a range ... if
// multiple ranges are supported, we will cycle through them and repeat ranges if the
// number of channels exceeds the number of ranges
//
// this block of code could be used to set other queue elements such as the input mode
// and channel list
for (i=0; i<chanCount; i++)
{
queueArray[i].channel = i;
queueArray[i].inputMode = inputMode;
queueArray[i].range = ranges[i % numRanges];
}
// allocate a buffer to receive the data
buffer = (double*) malloc(chanCount * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
err = ulAInLoadQueue(daqDeviceHandle, queueArray, chanCount);
if (err != ERR_NO_ERROR)
goto end;
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulAInLoadQueue()\n");
printf(" Channels: %d - %d\n", lowChan, highChan);
for (i = 0; i < chanCount; i++)
{
ConvertInputModeToString(queueArray[i].inputMode, inputModeStr);
ConvertRangeToString(queueArray[i].range, rangeStr);
printf(" Channel %d: Input mode: %s, Range = %s\n", queueArray[i].channel, inputModeStr, rangeStr);
}
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
// clear the display
ret = system("clear");
// start the acquisition
//
// when using the queue, the lowChan, highChan, inputMode, and range
// parameters are ignored since they are specified in queueArray
err = ulAInScan(daqDeviceHandle, lowChan, highChan, inputMode, range, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
// get the initial status of the acquisition
ulAInScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulAInScanStatus(daqDeviceHandle, &status, &transferStatus);
if(err == ERR_NO_ERROR)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
// display the data
for (i = 0; i < chanCount; i++)
{
printf("chan %d = %10.6f\n",
i + lowChan,
buffer[index + i]);
}
usleep(100000);
}
}
// stop the acquisition if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
ulAInScanStop(daqDeviceHandle);
}
}
// disconnect from the device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the device
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

View File

@ -0,0 +1,239 @@
/*
Wrapper call demonstrated: ulAInSetTrigger()
Purpose: Setup an external trigger
Demonstration: Uses the first available trigger type to
set up an external trigger that is used
to start a scan
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an analog input subsystem
3. Verify the analog input subsystem has a hardware pacer
4. Get the supported trigger types
5. Get the supported queue types
6. Fill the channel array
7. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
8. Call ulAInSetTrigger to set the external trigger
9. Call ulAInScan() to start the scan of A/D input channels
10. Call ulAiScanStatus to check the status of the background operation
11. Display the data for each channel
12. Call ulAinScanStop() to stop the background operation
13. Call ulDisconnectDaqDevice and ulReleaseDaqDevice() before exiting the process
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
// set some variables that are used to acquire data
int lowChan = 0;
int highChan = 3;
AiInputMode inputMode = AI_SINGLE_ENDED;
Range range = BIP10VOLTS;
int samplesPerChannel = 10000;
double rate = 1000;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS | SO_EXTTRIGGER);
AInScanFlag flags = AINSCAN_FF_DEFAULT;
int hasAI = 0;
int numberOfChannels = 0;
TriggerType triggerType;
int index = 0;
char inputModeStr[MAX_STR_LENGTH];
char rangeStr[MAX_STR_LENGTH];
char triggerTypeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
// allocate a buffer to receive the data
int chanCount = 0;
double *buffer = NULL;
UlError err = ERR_NO_ERROR;
int __attribute__ ((unused))ret;
char c;
int i = 0;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified device supports analog input
err = getDevInfoHasAi(daqDeviceHandle, &hasAI);
if (!hasAI)
{
printf("\nThe specified DAQ device does not support analog input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
{
goto end;
}
// get the first supported analog input mode
err = getAiInfoFirstSupportedInputMode(daqDeviceHandle, &numberOfChannels, &inputMode, inputModeStr);
if (highChan >= numberOfChannels)
highChan = numberOfChannels - 1;
chanCount = highChan - lowChan + 1;
// allocate a buffer to receive the data
buffer = (double*) malloc(chanCount * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
// get the first supported analog input range
err = getAiInfoFirstSupportedRange(daqDeviceHandle, inputMode, &range, rangeStr);
// get the first supported trigger type (this returns a digital trigger type)
getAiInfoFirstTriggerType(daqDeviceHandle, &triggerType, triggerTypeStr);
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulAInSetTrigger()\n");
printf(" Channels: %d - %d\n", lowChan, highChan);
printf(" Input mode: %s\n", inputModeStr);
printf(" Range: %s\n", rangeStr);
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf(" Trigger type: %s\n", triggerTypeStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
// clear the display
ret = system("clear");
// set the trigger
//
// this example uses the default values for setting the trigger so there is no need to call this function ...
// if you want to change the trigger type (or any other trigger parameter), uncomment this function call and
// change the trigger type (or any other parameter)
//err = ulAInSetTrigger( daqDeviceHandle, triggerType, 0, 0.0, 0.0, 0);
// start the acquisition
err = ulAInScan(daqDeviceHandle, lowChan, highChan, inputMode, range, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
// get the initial status of the acquisition
ulAInScanStatus(daqDeviceHandle, &status, &transferStatus);
printf ("Hit 'Enter' to quit waiting for trigger\n\n");
printf ("Waiting for trigger ...\n");
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulAInScanStatus(daqDeviceHandle, &status, &transferStatus);
index = transferStatus.currentIndex;
if(err == ERR_NO_ERROR && index >= 0)
{
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
// display the data
for (i = 0; i < chanCount; i++)
{
printf("chan %d = %f10.6\n",
i + lowChan,
buffer[index + i]);
}
usleep(100000);
}
}
if (index < 0)
printf("Trigger cancelled by user\n");
// stop the acquisition if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
err = ulAInScanStop(daqDeviceHandle);
}
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

148
examples/AOut.c Normal file
View File

@ -0,0 +1,148 @@
/*
UL call demonstrated: ulAOut()
Purpose: Writes an A/D output channel
Demonstration: Writes the analog output data to a
user-specified channel
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an analog output subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Enter a value to output for the A/D channel
6. Call ulAOut() to write a value to an A/D output channel
7. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int channel = 0;
Range range = BIP10VOLTS;
AOutFlag flags = AOUT_FF_DEFAULT;
int hasAO = 0;
double min = 0.0;
double max = 0.0;
char rangeStr[MAX_STR_LENGTH];
char * p;
char dataStr[MAX_STR_LENGTH];
double data = 0.0;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__ ((unused))ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports analog output
err = getDevInfoHasAo(daqDeviceHandle, &hasAO);
if (!hasAO)
{
printf("\nThe DAQ device does not support analog output\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
getAoInfoFirstSupportedRange(daqDeviceHandle, &range, rangeStr);
ConvertRangeToMinMax(range, &min, &max);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulAOut()\n");
printf(" Channel: 0\n");
printf(" Range: %s\n\n", rangeStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
// clear the display
ret = system("clear");
while(err == ERR_NO_ERROR && !enter_press())
{
// reset the cursor to the top of the display and
// show the termination message
cursorUp();
clearEOL();
resetCursor();
printf ("Enter a value between %f and %f volts (or non-numeric character to exit): ", min, max);
ret = scanf ("%s", dataStr);
strtod(dataStr, &p);
if (*p != '\0')
break;
data = atof(dataStr);
err = ulAOut(daqDeviceHandle, channel, range, flags, data);
usleep(100000);
}
end:
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

237
examples/AOutScan.c Normal file
View File

@ -0,0 +1,237 @@
/*
UL call demonstrated: ulAOutScan()
Purpose: Continuously output a waveform
on a D/A output channel
Demonstration: Outputs user generated data
on analog output channel 0
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an analog output subsystem
3. Verify the analog output subsystem has a hardware pacer
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Get the first supported analog range
6. Call ulAOutScan() to start the scan of D/A output channels
7. Call ulAOutScanStatus() to check the status of the background operation
8. Call ulAOutScanStop() to stop the background operation
9. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "uldaq.h"
#include "utility.h"
// prototypes
void CreateOutputData(int numberOfSamplesPerChannel, int chanCount, Range range, double* buffer);
// constants
#define MAX_DEV_COUNT 100
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int lowChan = 0;
int highChan = 0;
Range range = BIP10VOLTS;
const int samplesPerChannel = 1000;
double rate = 1000;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
AOutScanFlag flags = AOUTSCAN_FF_DEFAULT;
int hasAO = 0;
int hasPacer = 0;
int index = 0;
char rangeStr[MAX_STR_LENGTH];
// allocate a buffer for the data to be output
const int chanCount = highChan - lowChan + 1;
double* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports analog output
err = getDevInfoHasAo(daqDeviceHandle, &hasAO);
if (!hasAO)
{
printf("\nThis device does not support analog output\n");
goto end;
}
// verify the specified DAQ device supports hardware pacing for analog output
err = getAoInfoHasPacer(daqDeviceHandle, &hasPacer);
if (!hasPacer)
{
printf("\nThe specified DAQ device does not support hardware paced analog output\n");
goto end;
}
// allocate a buffer for the output data
buffer = (double*) malloc(chanCount * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
// get the first supported output range
err = getAoInfoFirstSupportedRange(daqDeviceHandle, &range, rangeStr);
// fill the buffer with data
CreateOutputData(samplesPerChannel, chanCount, range, buffer);
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// create a connection to the device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulAOutscan()\n");
printf(" Channels: %d - %d\n", lowChan, highChan);
printf(" Range: %s\n", rangeStr);
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
// clear the display
ret = system("clear");
// start the output
err = ulAOutScan(daqDeviceHandle, lowChan, highChan, range, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
// get the initial status of the acquisition
ulAOutScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulAOutScanStatus(daqDeviceHandle, &status, &transferStatus);
if(err == ERR_NO_ERROR)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
usleep(100000);
}
}
// stop the output if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
err = ulAOutScanStop(daqDeviceHandle);
}
}
end:
// disconnect from the device
ulDisconnectDaqDevice(daqDeviceHandle);
// release the handle to the device
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}
void CreateOutputData(int numberOfSamplesPerChannel, int chanCount, Range range, double* buffer)
{
const double twoPI = 2 * M_PI;
int i, j;
double min = 0.0;
double max = 0.0;
ConvertRangeToMinMax(range, &min, &max);
double amplitude = max - min;
double f = twoPI / numberOfSamplesPerChannel;
double phase = 0.0;
double offset = (min == 0) ? amplitude/2 : 0;
for (i=0; i<numberOfSamplesPerChannel; i++)
{
for (j=0; j<chanCount; j++)
{
*buffer++ = (double) ((sin(phase) * amplitude/2) + offset);
}
phase += f;
if( phase > twoPI )
phase = phase - twoPI;
}
}

153
examples/CIn.c Normal file
View File

@ -0,0 +1,153 @@
/*
UL call demonstrated: ulCIn()
Purpose: Reads a counter input channel
Demonstration: Displays the event counter input data
on a user-specified channel
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has a counter input subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Call ulCClear() to clear the counter (set it to 0)
6. Call ulCIn() to read a value from a counter channel
7. Display the data for the specified counter
8. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_EVENT_COUNTERS 2
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int ctrNumber = 0;
int numberOfCounters = 0;
int eventCounters[MAX_EVENT_COUNTERS];
int hasCTR = 0;
unsigned long long data = 0;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports counter input
err = getDevInfoHasCtr(daqDeviceHandle, &hasCTR);
if (!hasCTR)
{
printf("\nThe specified DAQ device does not support counter input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
getCtrInfoSupportedEventCounters(daqDeviceHandle, eventCounters, &numberOfCounters);
if (numberOfCounters == 0)
{
printf("\nThe specified DAQ device does not support event counters\n");
goto end;
}
if (ctrNumber >= numberOfCounters)
ctrNumber = numberOfCounters - 1;
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulCIn()\n");
printf(" Counter: %d\n", ctrNumber);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
// clear the counter
err = ulCClear(daqDeviceHandle, ctrNumber);
if (err != ERR_NO_ERROR)
goto end;
while(err == ERR_NO_ERROR && !enter_press())
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
err = ulCIn(daqDeviceHandle, ctrNumber, &data);
// display data for the counter channel
if(err == ERR_NO_ERROR)
{
printf("Counter(%d) Data: %lld\n", ctrNumber, data);
}
usleep(100000);
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

220
examples/CInScan.c Normal file
View File

@ -0,0 +1,220 @@
/*
UL call demonstrated: ulCInScan()
Purpose: Performs a continuous scan of the
first supported event counter channel
Demonstration: Displays the event counter data for
the first supported event counter
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an counter input subsystem
4. Verify the counter input subsystem has a hardware pacer
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Call ulCInScan() to start the scan of A/D input channels
7. Call ulCInScanStatus() to check the status of the background operation
8. Display the data for each channel
9. Call ulCInScanStop() to stop the background operation
10. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_SCAN_OPTIONS_LENGTH 256
#define MAX_EVENT_COUNTERS 8
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
// set some variables that are used to acquire data
int lowCtr = 0;
int highCtr = 1;
int chanCount = 0;
const int samplesPerCounter = 10000;
double rate = 1000;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
CInScanFlag flags = CINSCAN_FF_DEFAULT;
int hasCI = 0;
int hasPacer = 0;
int index = 0;
int numberOfCounters = 0;
int eventCounters[MAX_EVENT_COUNTERS];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
unsigned long long* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports counter input
err = getDevInfoHasCtr(daqDeviceHandle, &hasCI);
if (!hasCI)
{
printf("\nThe specified DAQ device does not support counter input\n");
goto end;
}
// verify the specified DAQ device supports hardware pacing for analog input
err = getCtrInfoHasPacer(daqDeviceHandle, &hasPacer);
if (!hasPacer)
{
printf("\nThe specified DAQ device does not support hardware paced counter input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the counter numbers for the supported event counters
getCtrInfoSupportedEventCounters(daqDeviceHandle, eventCounters, &numberOfCounters);
if (numberOfCounters == 0)
{
printf("\nThe specified DAQ device does not support event counters\n");
goto end;
}
if (highCtr >= numberOfCounters)
highCtr = numberOfCounters - 1;
chanCount = highCtr - lowCtr + 1;
// allocate a buffer to receive the data
buffer = (unsigned long long*) malloc(numberOfCounters * samplesPerCounter * sizeof(unsigned long long));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulCInscan()\n");
printf(" Counter: %d - %d\n", lowCtr, highCtr);
printf(" Samples per channel: %d\n", samplesPerCounter);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
// start the acquisition
err = ulCInScan(daqDeviceHandle, lowCtr, highCtr, samplesPerCounter, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
// get the initial status of the acquisition
ulCInScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulCInScanStatus(daqDeviceHandle, &status, &transferStatus);
if(err == ERR_NO_ERROR)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
// display the data
for (i = 0; i < chanCount; i++)
{
printf("chan %d = %lld\n",
i + lowCtr,
buffer[index + i]);
}
usleep(100000);
}
}
// stop the acquisition if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
err = ulCInScanStop(daqDeviceHandle);
}
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

View File

@ -0,0 +1,260 @@
/*
UL call demonstrated: ulCInConfigScan()
Purpose: Performs a continuous scan of the
specified encoder channels
Demonstration: Displays the counter data for
the specified encoders
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has a counter input subsystem
4. Verify the counter input subsystem has a hardware pacer
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Get the counter numbers for the supported encoders
7. Call ulCConfigScan() to configure the encoder channel
8. Call ulCInScan() to start the scan of encoder channels
9. Call ulCInScanStatus() to check the status of the background operation
10. Display the data for each channel
11. Call ulCInScanStop() to stop the background operation
12. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_SCAN_OPTIONS_LENGTH 256
#define MAX_ENCODER_COUNTERS 2
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
// set some variables that are used to acquire data
int lowCtr = 0;
int highCtr = 0;
int firstEncoder = 0;
int encoderCount = MAX_ENCODER_COUNTERS;
const int samplesPerCounter = 10000;
double rate = 1000;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
CInScanFlag flags = CINSCAN_FF_DEFAULT;
// encoder settings
CounterMeasurementType type = CMT_ENCODER;
CounterMeasurementMode mode = (CounterMeasurementMode) (CMM_ENCODER_X1 | CMM_ENCODER_CLEAR_ON_Z);
CounterEdgeDetection edgeDetection = CED_RISING_EDGE;
CounterTickSize tickSize = CTS_TICK_20ns;
CounterDebounceMode debounceMode = CDM_NONE;
CounterDebounceTime debounceTime = CDT_DEBOUNCE_0ns;
CConfigScanFlag configFlags = CF_DEFAULT;
int hasCI = 0;
int hasPacer = 0;
int index = 0;
int numberOfEncoders = 0;
int encoderCounters[MAX_ENCODER_COUNTERS];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
unsigned long long* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the device\n");
goto end;
}
// verify the specified DAQ device supports counter input
err = getDevInfoHasCtr(daqDeviceHandle, &hasCI);
if (!hasCI)
{
printf("\nThe specified DAQ device does not support counter input\n");
goto end;
}
// verify the specified DAQ device supports hardware pacing for counters
err = getCtrInfoHasPacer(daqDeviceHandle, &hasPacer);
if (!hasPacer)
{
printf("\nThe specified DAQ device does not support hardware paced counter input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// create a connection to the device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the counter numbers for the supported encoders
err = getCtrInfoSupportedEncoderCounters(daqDeviceHandle, encoderCounters, &numberOfEncoders);
if (numberOfEncoders == 0)
{
printf("\nThe specified DAQ device does not support encoder channels\n");
goto end;
}
if (numberOfEncoders > MAX_ENCODER_COUNTERS)
numberOfEncoders = MAX_ENCODER_COUNTERS;
// verify that the low_encoder number is valid
firstEncoder = encoderCounters[0];
if (lowCtr < firstEncoder)
lowCtr = firstEncoder;
if (lowCtr > firstEncoder + numberOfEncoders - 1)
lowCtr = firstEncoder;
// Verify that the encoder count is valid
if (encoderCount > numberOfEncoders)
encoderCount = numberOfEncoders;
// set the high_encoder channel
highCtr = lowCtr + encoderCount - 1;
if (highCtr > firstEncoder + numberOfEncoders - 1)
highCtr = firstEncoder + numberOfEncoders - 1;
// update the actual number of encoders being used
encoderCount = highCtr - lowCtr + 1;
// configure the encoders
for (i = 0; i < encoderCount; i++)
{
err = ulCConfigScan(daqDeviceHandle, i + lowCtr, type, mode, edgeDetection, tickSize, debounceMode, debounceTime, configFlags);
}
// allocate a buffer to receive the data
buffer = (unsigned long long*) malloc(encoderCount * samplesPerCounter * sizeof(unsigned long long));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulCConfigScan()\n");
printf(" Counter: %d - %d\n", lowCtr, highCtr);
printf(" Samples per channel: %d\n", samplesPerCounter);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
// start the acquisition
err = ulCInScan(daqDeviceHandle, lowCtr, highCtr, samplesPerCounter, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
int i = 0;
// get the initial status of the acquisition
ulCInScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulCInScanStatus(daqDeviceHandle, &status, &transferStatus);
if(err == ERR_NO_ERROR)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
// display the data
for (i = 0; i < encoderCount; i++)
{
clearEOL();
printf("chan %d = %llu \n",
i + lowCtr,
buffer[index + i]);
}
usleep(100000);
}
}
// stop the acquisition if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
err = ulCInScanStop(daqDeviceHandle);
}
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

173
examples/DBitIn.c Normal file
View File

@ -0,0 +1,173 @@
/*
UL call demonstrated: ulDBitIn()
Purpose: Reads the values of the bits for the
first digital port
Demonstration: Displays the value of each bit in the
first digital port
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an digital input subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Get the first supported digital port
6. Get the number of bits for the digital port
7. Call ulDConfigBit (if supported - otherwise - ulDConfigPort) to configure each bit for input
8. Call ulDBitIn() to read a value for each bit in the digital port
9. Display the data for each bit
10. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int hasDIO = 0;
int bitsPerPort = 0;
DigitalPortType portType = AUXPORT;
DigitalPortIoType portIoType = DPIOT_IN;
char portTypeStr[MAX_STR_LENGTH];
char portIoTypeStr[MAX_STR_LENGTH];
int bitNumber;
unsigned int data = 0;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports digital input
err = getDevInfoHasDio(daqDeviceHandle, &hasDIO);
if (!hasDIO)
{
printf("\nThe specified DAQ device does not support digital I/O\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the port types for the device (AUXPORT0, FIRSTPORTA, ...)
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
// get the port IO type
err = getDioInfoPortIoType(daqDeviceHandle, &portIoType, portIoTypeStr);
// get the number of bits for the first port (port index = 0)
err = getDioInfoNumberOfBitsForFirstPort(daqDeviceHandle, &bitsPerPort);
// if the port is bit configurable, then configure the individual bits
// for input; otherwise, configure the entire port for input
if (portIoType == DPIOT_BITIO)
{
// configure all of the bits for input for the port
for (bitNumber= 0; bitNumber < bitsPerPort; bitNumber++)
{
err = ulDConfigBit(daqDeviceHandle, portType, bitNumber, DD_INPUT);
if (err != ERR_NO_ERROR)
break;
}
}
else
{
// configure the entire port for input
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
}
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDBitIn()\n");
printf(" Port: %s\n", portTypeStr);
printf(" Port I/O type: %s\n", portIoTypeStr);
printf(" Bits: %d\n", bitsPerPort);
printf("Hit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
while(err == ERR_NO_ERROR && !enter_press())
{
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
// read each of the bits from the first port
for (bitNumber = 0; bitNumber < bitsPerPort; bitNumber++)
{
err = ulDBitIn(daqDeviceHandle, portType, bitNumber, &data);
if(err == ERR_NO_ERROR)
{
printf("Bit Number: %d: Data: %d\n", bitNumber, data);
}
}
usleep(100000);
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

190
examples/DBitOut.c Normal file
View File

@ -0,0 +1,190 @@
/*
UL call demonstrated: ulDBitOut()
Purpose: Writes a value to each of the bits for the
first digital port
Demonstration: Writes the value of each bit in the
first digital port
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an digital input subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Get the first supported digital port
6. Get the number of bits for the digital port
7. Call ulDConfigBit (if supported - otherwise - ulDConfigPort) to configure each bit for output
8. Call ulDBitOut() to write a value for each bit in the digital port
9. Display the data for each bit
10. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int hasDIO = 0;
int bitsPerPort = 0;
DigitalPortType portType = AUXPORT;
DigitalPortIoType portIoType = DPIOT_IN;
int maxPortValue = 0;
char portTypeStr[MAX_STR_LENGTH];
char portIoTypeStr[MAX_STR_LENGTH];
int bitNumber;
char * p;
char dataStr[MAX_STR_LENGTH];
unsigned int data = 0;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports digital output
err = getDevInfoHasDio(daqDeviceHandle, &hasDIO);
if (!hasDIO)
{
printf("\nThe DAQ device does not support digital I/O\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the port types for the device (AUXPORT0, FIRSTPORTA, ...)
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
// get the port IO type
err = getDioInfoPortIoType(daqDeviceHandle, &portIoType, portIoTypeStr);
// get the number of bits for the first port (port index = 0)
err = getDioInfoNumberOfBitsForFirstPort(daqDeviceHandle, &bitsPerPort);
// if the port is bit configurable, then configure the individual bits
// for output; otherwise, configure the entire port for output
if (portIoType == DPIOT_BITIO)
{
// configure all of the bits for output for the port
for (bitNumber= 0; bitNumber < bitsPerPort; bitNumber++)
{
err = ulDConfigBit(daqDeviceHandle, portType, bitNumber, DD_OUTPUT);
if (err != ERR_NO_ERROR)
break;
}
}
else
{
// configure the entire port for output
err = ulDConfigPort(daqDeviceHandle, portType, DD_OUTPUT);
}
// calculate the max value for the port
maxPortValue = pow((double)2.0, (double)bitsPerPort) - 1;
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDBitOut()\n");
printf(" Port: %s\n", portTypeStr);
printf(" Port I/O type: %s\n", portIoTypeStr);
printf(" Bits: %d\n", bitsPerPort);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
while(err == ERR_NO_ERROR && err == ERR_NO_ERROR)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
clearEOL();
printf ("Enter a value between 0 and %d (or non-numeric character to exit): " , maxPortValue);
ret = scanf ("%s", dataStr);
strtod(dataStr, &p);
if (*p != '\0')
break;
data = atoi(dataStr);
for (bitNumber = 0; bitNumber < bitsPerPort; bitNumber++)
{
unsigned int bitValue = (data >> bitNumber) & 1;
err = ulDBitOut(daqDeviceHandle, portType, bitNumber, bitValue);
clearEOL();
printf("Bit %d = %d\n", bitNumber, bitValue);
}
usleep(100000);
}
// before leaving, configure the entire port for input
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

140
examples/DIn.c Normal file
View File

@ -0,0 +1,140 @@
/*
UL call demonstrated: ulDIn()
Purpose: Reads the value of the first supported
digital port
Demonstration: Displays the value of the first digital
port
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an digital input subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Get the first supported digital port
7. Call ulDConfigPort to configure the port for input
8. Call ulDIn() to read a value from the digital port
9. Display the data for the port
10. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int hasDIO = 0;
DigitalPortType portType = AUXPORT;
char portTypeStr[MAX_STR_LENGTH];
unsigned long long data = 0;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the device supports digital input
err = getDevInfoHasDio(daqDeviceHandle, &hasDIO);
if (!hasDIO)
{
printf("\nThe specified DAQ device does not support digital I/O\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the port types for the device (AUXPORT0, FIRSTPORTA, ...)
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
// configure the first port for input
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDIn()\n");
printf(" Port: %s\n", portTypeStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
while(err == ERR_NO_ERROR && !enter_press())
{
// read the port
err = ulDIn(daqDeviceHandle, portType, &data);
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
clearEOL();
printf("Data: %lld (0x%llx)\n", data, data);
usleep(100000);
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

206
examples/DInScan.c Normal file
View File

@ -0,0 +1,206 @@
/*
UL call demonstrated: ulDInScan()
Purpose: Performs a continuous scan of the
first digital port
Demonstration: Displays the digital input data for
the first digital port
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an digital input subsystem
4. Verify the digital input subsystem has a hardware pacer
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Call ulDConfigPort to configure the port for input
7. Call ulDInScan() to start the scan of the DIO subsystem
8. Call ulDInScanStatus() to check the status of the background operation
9. Display the data for each channel
10. Call ulDInScanStop() to stop the background operation
11. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
DigitalPortType lowPort = AUXPORT;
DigitalPortType highPort = AUXPORT;
int samplesPerPort = 1000;
double rate = 100;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
DInScanFlag flags = DINSCAN_FF_DEFAULT;
int hasDIO = 0;
int hasPacer = 0;
int index = 0;
char portTypeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
DigitalPortType portType = AUXPORT;
int chanCount = 1;
unsigned long long* buffer;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
{
goto end;
}
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports digital input
err = getDevInfoHasDio(daqDeviceHandle, &hasDIO);
if (!hasDIO)
{
printf("\nThe specified DAQ device does not support digital I/O\n");
goto end;
}
// verify the device supports hardware pacing
err = getDioInfoHasPacer(daqDeviceHandle, DD_INPUT, &hasPacer);
if (!hasPacer)
{
printf("\nThe specified DAQ device does not support hardware paced digital input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
lowPort = portType;
highPort = portType;
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
// allocate a buffer to receive the data
buffer = (unsigned long long* ) malloc(chanCount * samplesPerPort * sizeof(unsigned long long));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDInScan()\n");
printf(" Port: %s\n", portTypeStr);
printf(" Samples per port: %d\n", samplesPerPort);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
err = ulDInScan(daqDeviceHandle, lowPort, highPort, samplesPerPort, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
int i = 0;
ulDInScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
err = ulDInScanStatus(daqDeviceHandle, &status, &transferStatus);
if(err == ERR_NO_ERROR)
{
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
// display the data
for (i = 0; i < chanCount; i++)
{
clearEOL();
printf("chan %d = 0x%llx\n",
i + lowPort,
buffer[index + i]);
}
usleep(100000);
}
}
ulDInScanStop(daqDeviceHandle);
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

166
examples/DOut.c Normal file
View File

@ -0,0 +1,166 @@
/*
UL call demonstrated: ulDOut()
Purpose: Writes the first digital port
Demonstration: Writes the digital data to the
first digital port
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an digital output subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Get the first supported digital port
7. Call ulDConfigPort to configure the port for output
8. Call ulDOut() to write a value to the digital port
9. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int hasDIO = 0;
int bitsPerPort = 0;
DigitalPortType portType = AUXPORT;
char portTypeStr[MAX_STR_LENGTH];
unsigned long long maxPortValue = 0;
char * p;
char dataStr[MAX_STR_LENGTH];
unsigned long long data = 0;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports digital output
err = getDevInfoHasDio(daqDeviceHandle, &hasDIO);
if (!hasDIO)
{
printf("\nThe DAQ device does not support digital I/O\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the port types for the device (AUXPORT0, FIRSTPORTA, ...)
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
// get the number of bits for the first port
err = getDioInfoNumberOfBitsForFirstPort(daqDeviceHandle, &bitsPerPort);
// configure the first port for output
err = ulDConfigPort(daqDeviceHandle, portType, DD_OUTPUT);
// calculate the max value for the port
maxPortValue = (unsigned long long) pow(2.0, (double)bitsPerPort) - 1;
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDOut()\n");
printf(" Port: %s\n", portTypeStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
while(err == ERR_NO_ERROR)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
clearEOL();
printf ("Enter a value between 0 and %llu (or non-numeric character to exit): ", maxPortValue);
ret = scanf ("%s", dataStr);
strtod(dataStr, &p);
if (*p != '\0')
break;
data = atoll(dataStr);
if (data > maxPortValue)
{
clearEOL();
printf ("Invalid value entered\n");
}
else
{
clearEOL();
err = ulDOut(daqDeviceHandle, portType, data);
}
usleep(100000);
}
// before leaving, configure the entire first port for input
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

228
examples/DOutScan.c Normal file
View File

@ -0,0 +1,228 @@
/*
UL call demonstrated: ulDOutScan()
Purpose: Continuously output user generated
data on the first digital port
Demonstration: Outputs user specified data
on the first digital port
Steps:digital
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an digital output subsystem
4. Verify the digital output subsystem has a hardware pacer
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Call ulDConfigPort to configure the port for output
7. Generate the data to be output
8. Call ulDOutScan() to start the scan for the DIO subsystem
9. Call ulDOutScanStatus() to check the status of the background operation
10. Call ulDOutScanStop() to stop the background operation
11. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "uldaq.h"
#include "utility.h"
// prototypes
void CreateOutputData(int samplesPerPort, long long bitsPerPort, unsigned long long* buffer);
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
DigitalPortType lowPort = AUXPORT;
DigitalPortType highPort = AUXPORT;
const int samplesPerPort = 1000;
double rate = 1000;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
DOutScanFlag flags = DOUTSCAN_FF_DEFAULT;
int hasDIO = 0;
int hasPacer = 0;
int index = 0;
int bitsPerPort = 0;
char portTypeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
DigitalPortType portType = AUXPORT;
int chanCount = 1;
unsigned long long* buffer;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports the DIO subsystem
err = getDevInfoHasDio(daqDeviceHandle, &hasDIO);
if (!hasDIO)
{
printf("\nThis device does not support digital I/O\n");
goto end;
}
// verify the specified DAQ device supports hardware output pacing
err = getDioInfoHasPacer(daqDeviceHandle, DD_OUTPUT, &hasPacer);
if (!hasPacer)
{
printf("\nThe specified DAQ device does not support hardware paced digital output\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the first supported port type
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
lowPort = portType;
highPort = portType;
// get the number of bits in the port
err = getDioInfoNumberOfBitsForFirstPort(daqDeviceHandle, &bitsPerPort);
err = ulDConfigPort(daqDeviceHandle, portType, DD_OUTPUT);
// allocate a buffer for the output data
buffer = (unsigned long long*) malloc(chanCount * samplesPerPort * sizeof(unsigned long long));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
CreateOutputData(samplesPerPort, bitsPerPort, buffer);
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDOutscan()\n");
printf(" Port: %s\n", portTypeStr);
printf(" Bits per port: %d\n", bitsPerPort);
printf(" Samples per port: %d\n", samplesPerPort);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
// start the output
err = ulDOutScan(daqDeviceHandle, lowPort, highPort, samplesPerPort, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
ulDOutScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
err = ulDOutScanStatus(daqDeviceHandle, &status, &transferStatus);
if(err == ERR_NO_ERROR)
{
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
usleep(10000);
}
}
ulDOutScanStop(daqDeviceHandle);
}
// before leaving, configure the entire first port for input
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}
void CreateOutputData(int samplesPerPort, long long bitsPerPort, unsigned long long* buffer)
{
const double twoPI = 2 * M_PI;
int sample;
double amplitude = pow((double)2.0, bitsPerPort) - 1;
double f = twoPI / samplesPerPort;
double phase = 0.0;
for (sample=0; sample<samplesPerPort; sample++)
{
*buffer++ = (unsigned long long) (sin(phase) * amplitude/2 + (amplitude / 2));
phase += f;
if( phase > twoPI )
phase = phase - twoPI;
}
}

363
examples/DaqInScan.c Normal file
View File

@ -0,0 +1,363 @@
/*
UL call demonstrated: ulDaqInScan()
Purpose: Performs a continuous scan of the available
analog, digital, and/or counter input subsystems
Demonstration: Displays the analog, digital, and counter
input data on the specified channels
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an DAQ input subsystem
4. Get the channel types supported by the DAQ input subsystem
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Configure the available analog, digital, and counter channels
7. Call ulDaqInScan() to start the scan
8. Call ulDaqInScanStatus to check the status of the background operation
9. Display the data for each channel
10. Call ulDaqInScanStop() to stop the background operation
11. Call ulDisconnectDaqDevice and ulReleaseDaqDevice() before exiting the process
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
// prototypes
UlError ConfigureAnalogInputChannels(int numberOfChannels, Range range, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex);
UlError ConfigureDigitalInputChannel(DaqDeviceHandle daqDeviceHandle, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex);
UlError ConfigureCounterInputChannels(DaqDeviceHandle daqDeviceHandle, int numberOfChannels, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex);
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
int main(void)
{
int descriptorIndex = 0;
AiInputMode inputMode = AI_SINGLE_ENDED;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int samplesPerChannel = 10000;
double rate = 1000;
Range range = BIP10VOLTS;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
DaqInScanFlag flags = DAQINSCAN_FF_DEFAULT;
int numberOfAiChannels = 3;
int numberOfScanChannels = 3;
int hasDAQI = 0;
int index = 0;
int chanTypesMask = 0;
char inputModeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
char daqiChannelTypeStr[MAX_SCAN_OPTIONS_LENGTH];
char rangeStr[MAX_SCAN_OPTIONS_LENGTH];
DaqInChanDescriptor scanDescriptors[numberOfScanChannels];
int scanDescriptorIndex = 0;
double* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified device supports analog input
err = getDevInfoHasDaqi(daqDeviceHandle, &hasDAQI);
if (!hasDAQI)
{
printf("\nThe specified DAQ device does not support DAQ input\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the channel types supported by the DAQ input subsystem
err = getDaqiChannelTypes(daqDeviceHandle, &chanTypesMask);
if (chanTypesMask == 0)
{
printf("\nDaqInScan is not supported by the specified DAQ device\n");
goto end;
}
// configure the analog channels
if (chanTypesMask & DAQI_ANALOG_SE)
{
// get the first supported analog input mode
err = getAiInfoFirstSupportedInputMode(daqDeviceHandle, &numberOfAiChannels, &inputMode, inputModeStr);
// get the first supported input range
getAiInfoFirstSupportedRange(daqDeviceHandle, inputMode, &range, rangeStr);
err = ConfigureAnalogInputChannels(1, range, scanDescriptors, &scanDescriptorIndex);
}
else
{
// no analog channels so decrement the count
numberOfScanChannels--;
}
// configure the digital channels
if ((chanTypesMask & DAQI_DIGITAL) && err == ERR_NO_ERROR)
{
err = ConfigureDigitalInputChannel(daqDeviceHandle, scanDescriptors, &scanDescriptorIndex);
}
else
{
// no digital channels so decrement the count
numberOfScanChannels--;
}
// configure the counter channels
if ((chanTypesMask & DAQI_CTR32) && err == ERR_NO_ERROR)
{
err = ConfigureCounterInputChannels(daqDeviceHandle, 1, scanDescriptors, &scanDescriptorIndex);
}
else
{
// no counter channels so decrement the count
numberOfScanChannels--;
}
// allocate a buffer to receive the data
buffer = (double*) malloc(numberOfScanChannels * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDaqInScan()\n");
printf(" Number of scan channels: %d\n", numberOfScanChannels);
for (i=0; i<numberOfScanChannels; i++)
{
ConvertDaqIChanTypeToString(scanDescriptors[i].type, daqiChannelTypeStr);
if (scanDescriptors[i].type == DAQI_ANALOG_SE || scanDescriptors[i].type == DAQI_ANALOG_DIFF)
{
ConvertRangeToString(scanDescriptors[i].range, rangeStr);
printf(" ScanChannel %d: type = %s, channel = %d, range = %s\n", i, daqiChannelTypeStr, scanDescriptors[i].channel, rangeStr);
}
else
{
printf(" ScanChannel %d: type = %s, channel = %d\n", i, daqiChannelTypeStr, scanDescriptors[i].channel);
}
}
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
// start the acquisition
err = ulDaqInScan(daqDeviceHandle, scanDescriptors, numberOfScanChannels, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
int i = 0;
// get the initial status of the acquisition
ulDaqInScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulDaqInScanStatus(daqDeviceHandle, &status, &transferStatus);
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
// display the data
for (i = 0; i < numberOfScanChannels; i++)
{
if (scanDescriptors[i].type == DAQI_ANALOG_SE || scanDescriptors[i].type == DAQI_ANALOG_DIFF)
{
printf("chan (%s%d) = %10.6f\n",
"Ai", scanDescriptors[i].channel,
buffer[index + i]);
}
else
{
printf("chan (%s%d) = %lld \n",
(scanDescriptors[i].type == DAQI_DIGITAL) ? "Di" : "Ci", scanDescriptors[i].channel,
(long long)buffer[index + i]);
}
usleep(100000);
}
}
// stop the acquisition if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
err = ulDaqInScanStop(daqDeviceHandle);
}
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}
UlError ConfigureAnalogInputChannels(int numberOfChannels, Range range, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
int numberOfAnalogChans = 0;
int i;
int index = *scanDesriptorIndex;
// fill a descriptor for each channel
for ( i = 0; i < numberOfChannels; i++)
{
descriptors[index].channel = i;
descriptors[index].type = DAQI_ANALOG_SE;
descriptors[index].range = range;
index++;
numberOfAnalogChans++;
if (numberOfAnalogChans == numberOfChannels)
break;
}
*scanDesriptorIndex = index;
return err;
}
UlError ConfigureDigitalInputChannel(DaqDeviceHandle daqDeviceHandle, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
DigitalPortType portType;
char portTypeStr[MAX_STR_LENGTH];
int index = *scanDesriptorIndex;
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
// configure the port for input
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
descriptors[index].channel = portType;
descriptors[index].type = DAQI_DIGITAL;
index++;
*scanDesriptorIndex = index;
return err;
}
UlError ConfigureCounterInputChannels(DaqDeviceHandle daqDeviceHandle, int numberOfChannels, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
int numberOfCounters = 0;
int numberOfEventCounters = 0;
int i;
int index = *scanDesriptorIndex;
// get the number of counter channels
err = getCtrInfoNumberOfChannels(daqDeviceHandle, &numberOfCounters);
// allocate memory to store the port types
int measurementTypes;
// fill a descriptor for each channel
for (i = 0; i < numberOfCounters; i++)
{
err = getCtrInfoMeasurementTypes(daqDeviceHandle, i, &measurementTypes);
if (measurementTypes & CMT_COUNT)
{
descriptors[index].channel = i;
descriptors[index].type = DAQI_CTR32;
index++;
numberOfEventCounters++;
if (numberOfEventCounters == numberOfChannels)
break;
}
}
*scanDesriptorIndex = index;
return err;
}

View File

@ -0,0 +1,396 @@
/*
UL call demonstrated: ulDaqInSetTrigger()
Purpose: ulDaqInSetTrigger
Demonstration: Uses the first available trigger type to
set up an external trigger that is used
to start a scan of the available analog,
digital, and/or counter subsystems
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has an DAQ input subsystem
4. Get the channel types supported by the DAQ input subsystem
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Configure the available analog, digital, and counter channels
7. Call ulDaqInSetTrigger to set the external trigger
8. Call ulDaqInScan() to start the scan
9. Call ulDaqInScanStatus to check the status of the background operation
10. Display the data for each channel
11. Call ulDaqInScanStop() to stop the background operation
12. Call ulDisconnectDaqDevice and ulReleaseDaqDevice() before exiting the process
*/
#include <stdio.h>
#include <stdlib.h>
#include "uldaq.h"
#include "utility.h"
// prototypes
UlError ConfigureAnalogInputChannels(int numberOfChannels, Range range, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex);
UlError ConfigureDigitalInputChannel(DaqDeviceHandle daqDeviceHandle, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex);
UlError ConfigureCounterInputChannels(DaqDeviceHandle daqDeviceHandle, int numberOfChannels, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex);
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
int main(void)
{
int descriptorIndex = 0;
AiInputMode inputMode = AI_SINGLE_ENDED;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int samplesPerChannel = 10000;
double rate = 1000;
Range range = BIP10VOLTS;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS | SO_EXTTRIGGER);
DaqInScanFlag flags = DAQINSCAN_FF_DEFAULT;
int numberOfAiChannels = 3;
int numberOfScanChannels = 3;
int hasDAQI = 0;
int index = 0;
int chanTypesMask = 0;
TriggerType triggerType;
char inputModeStr[MAX_STR_LENGTH];
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
char daqiChannelTypeStr[MAX_SCAN_OPTIONS_LENGTH];
char rangeStr[MAX_SCAN_OPTIONS_LENGTH];
char triggerTypeStr[MAX_SCAN_OPTIONS_LENGTH];
DaqInChanDescriptor scanDescriptors[numberOfScanChannels];
// uncomment this line if you want to change the trigger channel from an
// external trigger to an analog channel
//DaqInChanDescriptor dummyDesc;
int scanDescriptorIndex = 0;
double* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified device supports analog input
err = getDevInfoHasDaqi(daqDeviceHandle, &hasDAQI);
if (!hasDAQI)
{
printf("\nThe specified DAQ device does not support DAQ input\n");
goto end;
}
// get the first supported trigger type
err = getDaqiInfoFirstTriggerType(daqDeviceHandle, &triggerType, triggerTypeStr);
if (err != ERR_NO_ERROR)
{
printf("\nThe specified DAQ device does not support an external trigger\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the channel types supported by the DAQ input subsystem
err = getDaqiChannelTypes(daqDeviceHandle, &chanTypesMask);
if (chanTypesMask == 0)
{
printf("\nDaqInScan is not supported by the specified DAQ device\n");
goto end;
}
// configure the analog channels
if (chanTypesMask & DAQI_ANALOG_SE)
{
// get the first supported analog input mode
err = getAiInfoFirstSupportedInputMode(daqDeviceHandle, &numberOfAiChannels, &inputMode, inputModeStr);
// get the first supported input range
getAiInfoFirstSupportedRange(daqDeviceHandle, inputMode, &range, rangeStr);
err = ConfigureAnalogInputChannels(1, range, scanDescriptors, &scanDescriptorIndex);
}
else
{
// no analog channels so decrement the count
numberOfScanChannels--;
}
// configure the digital channels
if ((chanTypesMask & DAQI_DIGITAL) && err == ERR_NO_ERROR)
{
err = ConfigureDigitalInputChannel(daqDeviceHandle, scanDescriptors, &scanDescriptorIndex);
}
else
{
// no digital channels so decrement the count
numberOfScanChannels--;
}
// configure the counter channels
if ((chanTypesMask & DAQI_CTR32) && err == ERR_NO_ERROR)
{
err = ConfigureCounterInputChannels(daqDeviceHandle, 1, scanDescriptors, &scanDescriptorIndex);
}
else
{
// no counter channels so decrement the count
numberOfScanChannels--;
}
// since this example uses the external trigger, a descriptor for the trigger channel
// is not required ... this parameter is only used for an analog trigger channel
//
// if you want to change the trigger type (or any other trigger parameter), uncomment this
// function call and change the trigger type (or any other parameter)
//err = ulDaqInSetTrigger( daqDeviceHandle, triggerType, dummyDesc, 0.0, 0.0, 0);
// allocate a buffer to receive the data
buffer = (double*) malloc(numberOfScanChannels * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDaqInSetTrigger()\n");
printf(" Number of scan channels: %d\n", numberOfScanChannels);
for (i=0; i<numberOfScanChannels; i++)
{
ConvertDaqIChanTypeToString(scanDescriptors[i].type, daqiChannelTypeStr);
if (scanDescriptors[i].type == DAQI_ANALOG_SE || scanDescriptors[i].type == DAQI_ANALOG_DIFF)
{
ConvertRangeToString(scanDescriptors[i].range, rangeStr);
printf(" ScanChannel %d: type = %s, channel = %d, range = %s\n", i, daqiChannelTypeStr, scanDescriptors[i].channel, rangeStr);
}
else
{
printf(" ScanChannel %d: type = %s, channel = %d\n", i, daqiChannelTypeStr, scanDescriptors[i].channel);
}
}
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf(" Trigger type: %s\n", triggerTypeStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
// clear the display
ret = system("clear");
err = ulDaqInScan(daqDeviceHandle, scanDescriptors, numberOfScanChannels, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
int i = 0;
// get the initial status of the acquisition
ulDaqInScanStatus(daqDeviceHandle, &status, &transferStatus);
printf ("Hit 'Enter' to quit waiting for trigger\n\n");
printf ("Waiting for trigger ...\n");
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the acquisition
err = ulDaqInScanStatus(daqDeviceHandle, &status, &transferStatus);
index = transferStatus.currentIndex;
if(err == ERR_NO_ERROR && index >= 0)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
printf("currentScanCount = %llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %d \n\n", index);
// display the data
for (i = 0; i < numberOfScanChannels; i++)
{
if (scanDescriptors[i].type == DAQI_ANALOG_SE ||scanDescriptors[i].type == DAQI_ANALOG_DIFF)
{
printf("chan (%s%d) = %10.6f\n",
"Ai", scanDescriptors[i].channel,
buffer[index + i]);
}
else
{
printf("chan (%s%d) = %lld\n",
(scanDescriptors[i].type == DAQI_DIGITAL) ? "Di" : "Ci", scanDescriptors[i].channel,
(long long)buffer[index + i]);
}
}
usleep(100000);
}
}
if (index < 0)
printf("Trigger cancelled by user\n");
// stop the acquisition if it is still running
if (status == SS_RUNNING && err == ERR_NO_ERROR)
{
err = ulDaqInScanStop(daqDeviceHandle);
}
}
// disconnect from the device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the device
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}
UlError ConfigureAnalogInputChannels(int numberOfChannels, Range range, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
int numbeOfAnalogChans = 0;
int i;
int index = *scanDesriptorIndex;
// fill a descriptor for each channel
for ( i = 0; i < numberOfChannels; i++)
{
descriptors[index].channel = i;
descriptors[index].type = DAQI_ANALOG_SE;
descriptors[index].range = range;
index++;
numbeOfAnalogChans++;
if (numbeOfAnalogChans == numberOfChannels)
break;
}
*scanDesriptorIndex = index;
return err;
}
UlError ConfigureDigitalInputChannel(DaqDeviceHandle daqDeviceHandle, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
DigitalPortType portType;
char portTypeStr[MAX_STR_LENGTH];
int index = *scanDesriptorIndex;
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
// configure the port for input
err = ulDConfigPort(daqDeviceHandle, portType, DD_INPUT);
descriptors[index].channel = portType;
descriptors[index].type = DAQI_DIGITAL;
index++;
*scanDesriptorIndex = index;
return err;
}
UlError ConfigureCounterInputChannels(DaqDeviceHandle daqDeviceHandle, int numberOfChannels, DaqInChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
int numberOfCounters = 0;
int numberOfEventCounters = 0;
int measurementTypes;
int i;
int index = *scanDesriptorIndex;
// get the number of counter channels
err = getCtrInfoNumberOfChannels(daqDeviceHandle, &numberOfCounters);
// fill a descriptor for each channel
for (i = 0; i < numberOfCounters; i++)
{
err = getCtrInfoMeasurementTypes(daqDeviceHandle, i, &measurementTypes);
if (measurementTypes & CMT_COUNT)
{
descriptors[index].channel = i;
descriptors[index].type = DAQI_CTR32;
index++;
numberOfEventCounters++;
if (numberOfEventCounters == numberOfChannels)
break;
}
}
*scanDesriptorIndex = index;
return err;
}

353
examples/DaqOutScan.c Normal file
View File

@ -0,0 +1,353 @@
/*
UL call demonstrated: ulDaqOutScan()
Purpose: Continuously output user generated data
on available D/A, and DIO output channels
Demonstration: Outputs user generated data on available
output channels
Steps:
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has a DAQ output subsystem
4. Get the channel types supported by the DAQ output subsystem
5. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
6. Configure the analog and digital channels
7. Call ulDaqOutScan() to start the scan
8. Call ulDaqOutScanStatus to check the status of the background operation
9. Display the data for each channel
10. Call ulDaqOutScanStop() to stop the background operation
11. Call ulDisconnectDaqDevice and ulReleaseDaqDevice() before exiting the process
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "uldaq.h"
#include "utility.h"
// prototypes
UlError ConfigureAnalogOutputChannels(int numberOfChannels, Range range, DaqOutChanDescriptor* descriptors, int* scanDesriptorIndex);
UlError ConfigureDigitalOutputChannels(DaqDeviceHandle daqDeviceHandle, DaqOutChanDescriptor* descriptors, int* scanDesriptorIndex);
void CreateOutputData(int numberOfChannels, DaqOutChanDescriptor* descriptors, int numberOfSamplesPerChannel, Range range, long long bitsPerPort, double* buffer);
#define MAX_DEV_COUNT 100
#define MAX_STR_LENGTH 64
#define MAX_SCAN_OPTIONS_LENGTH 256
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int samplesPerChannel = 1000;
double rate = 1000;
Range range = BIP10VOLTS;
ScanOption scanOptions = (ScanOption) (SO_DEFAULTIO | SO_CONTINUOUS);
DaqOutScanFlag flags = DAQOUTSCAN_FF_DEFAULT;
int numberOfScanChannels = 2;
int hasDAQO = 0;
int index = 0;
int chanTypesMask = 0;
int bitsPerPort = 0;
char scanOptionsStr[MAX_SCAN_OPTIONS_LENGTH];
char daqoChannelTypeStr[MAX_SCAN_OPTIONS_LENGTH];
char rangeStr[MAX_SCAN_OPTIONS_LENGTH];
DaqOutChanDescriptor scanDescriptors[numberOfScanChannels];
int scanDescriptorIndex = 0;
double* buffer = NULL;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the DAQ device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified device supports analog output
err = getDevInfoHasDaqo(daqDeviceHandle, &hasDAQO);
if (!hasDAQO)
{
printf("\nThe specified DAQ device does not support DAQ output\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
// get the channel types supported by the DAQ output subsystem
err = getDaqoChannelTypes(daqDeviceHandle, &chanTypesMask);
if (chanTypesMask == 0)
{
printf("\nDaqOutScan is not supported by the specified DAQ device\n");
goto end;
}
// configure the analog channels
if (chanTypesMask & DAQO_ANALOG)
{
// get the first supported output range
getAoInfoFirstSupportedRange(daqDeviceHandle, &range, rangeStr);
err = ConfigureAnalogOutputChannels(1, range, scanDescriptors, &scanDescriptorIndex);
}
else
{
// no analog channels so decrement the count
numberOfScanChannels--;
}
// configure the digital channels
if ((chanTypesMask & DAQO_DIGITAL) && err == ERR_NO_ERROR)
{
err = ConfigureDigitalOutputChannels(daqDeviceHandle, scanDescriptors, &scanDescriptorIndex);
// get the number of bits in the port
err = getDioInfoNumberOfBitsForFirstPort(daqDeviceHandle, &bitsPerPort);
}
else
{
// no digital channels so decrement the count
numberOfScanChannels--;
}
// allocate a buffer for the output data
buffer = (double*) malloc(numberOfScanChannels * samplesPerChannel * sizeof(double));
if(buffer == 0)
{
printf("\nOut of memory, unable to create scan buffer\n");
goto end;
}
// fill the buffer with data
CreateOutputData(numberOfScanChannels, scanDescriptors, samplesPerChannel, range, bitsPerPort, buffer);
ConvertScanOptionsToString(scanOptions, scanOptionsStr);
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulDaqOutScan()\n");
printf(" Number of scan channels: %d\n", numberOfScanChannels);
for (i = 0; i < numberOfScanChannels; i++)
{
ConvertDaqOChanTypeToString(scanDescriptors[i].type, daqoChannelTypeStr);
if (scanDescriptors[i].type == DAQO_ANALOG)
{
ConvertRangeToString(scanDescriptors[i].range, rangeStr);
printf(" ScanChannel %d: type = %s, channel = %d, range = %s\n", i, daqoChannelTypeStr, scanDescriptors[i].channel, rangeStr);
}
else
{
printf(" ScanChannel %d: type = %s, channel = %d\n", i, daqoChannelTypeStr, scanDescriptors[i].channel);
}
}
printf(" Samples per channel: %d\n", samplesPerChannel);
printf(" Rate: %f\n", rate);
printf(" Scan options: %s\n", scanOptionsStr);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
// start the output
err = ulDaqOutScan(daqDeviceHandle, scanDescriptors, numberOfScanChannels, samplesPerChannel, &rate, scanOptions, flags, buffer);
if(err == ERR_NO_ERROR)
{
ScanStatus status;
TransferStatus transferStatus;
// get the initial status of the background operation
ulDaqOutScanStatus(daqDeviceHandle, &status, &transferStatus);
while(status == SS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// get the current status of the background operation
err = ulDaqOutScanStatus(daqDeviceHandle, &status, &transferStatus);
if(err == ERR_NO_ERROR)
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Hit 'Enter' to terminate the process\n\n");
printf("actual scan rate = %f\n\n", rate);
index = transferStatus.currentIndex;
printf("currentScanCount = %10llu \n", transferStatus.currentScanCount);
printf("currentTotalCount = %10llu \n", transferStatus.currentTotalCount);
printf("currentIndex = %10d \n\n", index);
usleep(100000);
}
}
ulDaqOutScanStop(daqDeviceHandle);
}
// before leaving, configure the digital port for input
for (i = 0; i < numberOfScanChannels; i++)
{
if (scanDescriptors[i].type == DAQO_DIGITAL)
{
err = ulDConfigPort(daqDeviceHandle, (DigitalPortType) scanDescriptors[i].channel, DD_INPUT);
}
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
// release the scan buffer
if(buffer)
free(buffer);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}
UlError ConfigureAnalogOutputChannels(int numberOfChannels, Range range, DaqOutChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
int numbeOfAnalogChans = 0;
int i;
int index = *scanDesriptorIndex;
// fill a descriptor for each channel
for (i = 0; i< numberOfChannels; i++)
{
descriptors[index].channel = i;
descriptors[index].type = DAQO_ANALOG;
descriptors[index].range = range;
index++;
numbeOfAnalogChans++;
if (numbeOfAnalogChans == numberOfChannels)
break;
}
*scanDesriptorIndex = index;
return err;
}
UlError ConfigureDigitalOutputChannels(DaqDeviceHandle daqDeviceHandle, DaqOutChanDescriptor* descriptors, int* scanDesriptorIndex)
{
UlError err = ERR_NO_ERROR;
DigitalPortType portType;
char portTypeStr[MAX_STR_LENGTH];
int index = *scanDesriptorIndex;
err = getDioInfoFirstSupportedPortType(daqDeviceHandle, &portType, portTypeStr);
// configure the port for output
err = ulDConfigPort(daqDeviceHandle, portType, DD_OUTPUT);
descriptors[index].channel = portType;
descriptors[index].type = DAQO_DIGITAL;
index++;
*scanDesriptorIndex = index;
return err;
}
void CreateOutputData(int numberOfChannels, DaqOutChanDescriptor* descriptors, int numberOfSamplesPerChannel, Range range, long long bitsPerPort, double* buffer)
{
const double twoPI = 2 * M_PI;
int sample, channel;
double min = 0.0;
double max = 0.0;
ConvertRangeToMinMax(range, &min, &max);
double f = twoPI / numberOfSamplesPerChannel;
double analogAmplitude = max - min ;
double digitalAmplitude = pow((double)2.0, bitsPerPort) - 1;;
double phase = 0.0;
int index = 0;
for (sample = 0; sample < numberOfSamplesPerChannel; sample++)
{
for (channel = 0; channel < numberOfChannels; channel++)
{
if (descriptors[channel].type == DAQO_ANALOG)
{
double value = (double) (sin(phase) * analogAmplitude/2);
if (channel== 0)
{
buffer[index++] = value;
}
else
{
buffer[index++] = value/2;
}
}
else
{
buffer[index++] = (sin(phase) * digitalAmplitude/2 + (digitalAmplitude / 2));
}
}
phase += f;
if( phase > twoPI )
phase = phase - twoPI;
}
}

42
examples/Makefile.am Normal file
View File

@ -0,0 +1,42 @@
AM_CPPFLAGS = -I$(top_srcdir)/src
LDADD = ../src/libuldaq.la
noinst_PROGRAMS = AIn AInScan AInScanWithEvents AInScanWithQueue AInScanWithTrigger\
AOut AOutScan\
CIn CInScan CInScanWithEncoder\
DaqInScan DaqInScanWithTrigger\
DaqOutScan\
DIn DBitIn DInScan DOut DBitOut DOutScan\
TmrPulseOut
AIn_SOURCES = AIn.c utility.h
AInScan_SOURCES = AInScan.c
AInScanWithEvents_SOURCES = AInScanWithEvents.c
AInScanWithQueue_SOURCES = AInScanWithQueue.c
AInScanWithTrigger_SOURCES = AInScanWithTrigger.c
AOut_SOURCES = AOut.c
AOutScan_LDADD = $(LDADD) -lm
AOutScan_SOURCES = AOutScan.c
CIn_SOURCES = CIn.c
CInScan_SOURCES = CInScan.c
CInScanWithEncoder_SOURCES = CInScanWithEncoder.c
DaqInScan_SOURCES = DaqInScan.c
DaqInScanWithTrigger_SOURCES = DaqInScanWithTrigger.c
DaqOutScan_LDADD = $(LDADD) -lm
DaqOutScan_SOURCES = DaqOutScan.c
DIn_SOURCES = DIn.c
DBitIn_SOURCES = DBitIn.c
DInScan_SOURCES = DInScan.c
DOut_LDADD = $(LDADD) -lm
DOut_SOURCES = DOut.c
DBitOut_LDADD = $(LDADD) -lm
DBitOut_SOURCES = DBitOut.c
DOutScan_LDADD = $(LDADD) -lm
DOutScan_SOURCES = DOutScan.c
TmrPulseOut_SOURCES = TmrPulseOut.c

194
examples/TmrPulseOut.c Normal file
View File

@ -0,0 +1,194 @@
/*
UL call demonstrated: ulTmrPulseOutStart()
Purpose: Generate an output pulse using the
specified timer
Demonstration: Outputs user defined pulse on the
specified timer
Steps:digital
1. Call ulGetDaqDeviceInventory() to get the list of available DAQ devices
2. Call ulCreateDaqDevice() to to get a handle for the first DAQ device
3. Verify the DAQ device has a timer output subsystem
4. Call ulConnectDaqDevice() to establish a UL connection to the DAQ device
5. Call ulTmrPulseOutStart() to start output pulse for the specified timer
6. Call ulTmrPulseOutStatus(), if it is supported, to monitor the status of the
pulse output
7. Call ulTmrPulseOutStop() to stop the output pulse
8. Call ulDisconnectDaqDevice() and ulReleaseDaqDevice() before exiting the process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "uldaq.h"
#include "utility.h"
#define MAX_DEV_COUNT 100
int main(void)
{
int descriptorIndex = 0;
DaqDeviceDescriptor devDescriptors[MAX_DEV_COUNT];
DaqDeviceInterface interfaceType = ANY_IFC;
DaqDeviceHandle daqDeviceHandle = 0;
unsigned int numDevs = MAX_DEV_COUNT;
int timerNumber = 0;
double frequency = 1000.0;
double dutyCycle = .5;
unsigned long long pulseCount = 0;
double initialDelay = 0.0;
TmrIdleState idleState = TMRIS_LOW;
PulseOutOption options = PO_DEFAULT;
int hasTMR = 0;
UlError err = ERR_NO_ERROR;
int i = 0;
int __attribute__((unused)) ret;
char c;
// Get descriptors for all of the available DAQ devices
err = ulGetDaqDeviceInventory(interfaceType, devDescriptors, &numDevs);
if (err != ERR_NO_ERROR)
goto end;
// verify at least one DAQ device is detected
if (numDevs == 0)
{
printf("No DAQ device is detected\n");
goto end;
}
printf("Found %d DAQ device(s)\n", numDevs);
for (i = 0; i < (int) numDevs; i++)
printf(" %s: (%s)\n", devDescriptors[i].productName, devDescriptors[i].uniqueId);
// get a handle to the device associated with the first descriptor
daqDeviceHandle = ulCreateDaqDevice(devDescriptors[descriptorIndex]);
if (daqDeviceHandle == 0)
{
printf ("\nUnable to create a handle to the specified DAQ device\n");
goto end;
}
// verify the specified DAQ device supports timer output
err = getDevInfoHasTmr(daqDeviceHandle, &hasTMR);
if (!hasTMR)
{
printf("\nThe specified DAQ device does not support timer output\n");
goto end;
}
printf("\nConnecting to device %s - please wait ...\n", devDescriptors[descriptorIndex].devString);
// establish a connection to the specified DAQ device
err = ulConnectDaqDevice(daqDeviceHandle);
if (err != ERR_NO_ERROR)
goto end;
printf("\n%s ready\n", devDescriptors[descriptorIndex].devString);
printf(" Function demonstrated: ulTmrPulseOutStart()\n");
printf(" Channel: %d\n", timerNumber);
printf(" Frequency: %f\n", frequency);
printf(" Duty cycle: %f\n", dutyCycle);
printf("\nHit ENTER to continue\n");
ret = scanf("%c", &c);
ret = system("clear");
err = ulTmrPulseOutStart(daqDeviceHandle, timerNumber, &frequency, &dutyCycle, pulseCount, &initialDelay, idleState, options);
if(err == ERR_NO_ERROR)
{
TmrStatus status = TMRS_RUNNING;
err = ulTmrPulseOutStatus(daqDeviceHandle, timerNumber, &status);
if (status == TMRS_RUNNING)
{
// if the status is RUNNING, then this timer does support the ulTmrPulseOutStatus()
// function so we will call the function to determine if the pulse output is stopped
// due to an error
while(status == TMRS_RUNNING && err == ERR_NO_ERROR && !enter_press())
{
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Status = TMRS_RUNNING\n");
printf("Outputting %f Hz pulse with duty cycle %.3f for timer %d ...\n\n", frequency, dutyCycle, timerNumber);
printf("Hit 'Enter' to terminate the process and stop the timer output\n");
usleep(100000);
err = ulTmrPulseOutStatus(daqDeviceHandle, timerNumber, &status);
}
// stop the output if it is still running
if (status == TMRS_RUNNING && err == ERR_NO_ERROR)
{
err = ulTmrPulseOutStop(daqDeviceHandle, timerNumber);
}
}
else
{
// if the status is IDLE, then this timer does not support the ulTmrPulseOutStatus()
// function so we will wait for user input to stop the pulse output
// reset the cursor to the top of the display and
// show the termination message
resetCursor();
printf("Outputting %f Hz pulse with duty cycle %.3f for timer %d ...\n\n", frequency, dutyCycle, timerNumber);
printf("Hit 'Enter' to terminate the process and stop the timer output\n");
while (!enter_press())
{
usleep(100000);
}
// stop the output if it is still running
err = ulTmrPulseOutStop(daqDeviceHandle, timerNumber);
}
for (i = 0; i < 5; i++)
{
cursorUp();
clearEOL();
}
resetCursor();
printf("Status = TMRS_IDLE\n");
}
// disconnect from the DAQ device
ulDisconnectDaqDevice(daqDeviceHandle);
end:
// release the handle to the DAQ device
ulReleaseDaqDevice(daqDeviceHandle);
if(err != ERR_NO_ERROR)
{
char errMsg[ERR_MSG_LEN];
ulGetErrMsg(err, errMsg);
printf("Error Code: %d \n", err);
printf("Error Message: %s \n", errMsg);
}
return 0;
}

1123
examples/utility.h Normal file

File diff suppressed because it is too large Load Diff

BIN
fpga/USB_1208HS.rbf Normal file

Binary file not shown.

BIN
fpga/USB_1608G.rbf Normal file

Binary file not shown.

BIN
fpga/USB_1608G_2.rbf Normal file

Binary file not shown.

BIN
fpga/USB_1808.bin Normal file

Binary file not shown.

BIN
fpga/USB_26xx.rbf Normal file

Binary file not shown.

BIN
fpga/USB_CTR.bin Normal file

Binary file not shown.

BIN
fpga/USB_DIO32HS.bin Normal file

Binary file not shown.

BIN
fpga/usb_2020.bin Normal file

Binary file not shown.

27
rules/50-uldaq.rules Normal file
View File

@ -0,0 +1,27 @@
# allow access to usb devices by non-root users
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="00c4", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="00c5", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="00c6", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="00e8", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="00e9", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="00ea", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0110", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0111", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0112", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0113", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0114", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0118", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0119", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0120", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0121", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0127", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="012b", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="012c", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="012e", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0133", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0134", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0135", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="0136", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="013d", GROUP="adm", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09db", ATTR{idProduct}=="013e", GROUP="adm", MODE="0666"

53
src/AiChanInfo.cpp Normal file
View File

@ -0,0 +1,53 @@
/*
* AiChanInfo.cpp
*
* Created on: Sep 25, 2015
* Author: root
*/
#include "AiChanInfo.h"
namespace ul
{
AiChanInfo::AiChanInfo(int chan)
{
mChanNum = chan;
mTypes = (AiChanType) 0;
}
AiChanInfo::~AiChanInfo()
{
}
void AiChanInfo::addChanMode(AiInputMode mode)
{
mMode.push_back(mode);
}
void AiChanInfo::setChanTypes(long long type)
{
mTypes = (AiChanType) type;
}
AiChanType AiChanInfo::getChanTypes() const
{
return mTypes;
}
int AiChanInfo::getChanNum() const
{
return mChanNum;
}
std::vector<AiInputMode> AiChanInfo::getChanModes() const
{
return mMode;
}
/*
public TcInfo getTcInfo()
{
return mTcInfo;
}*/
} /* namespace ul */

40
src/AiChanInfo.h Normal file
View File

@ -0,0 +1,40 @@
/*
* AiChanInfo.h
*
* Created on: Sep 25, 2015
* Author: root
*/
#ifndef AICHANINFO_H_
#define AICHANINFO_H_
#include "ul_internal.h"
#include <vector>
#include "interfaces/UlAiChanInfo.h"
namespace ul
{
class UL_LOCAL AiChanInfo: public UlAiChanInfo
{
public:
virtual ~AiChanInfo();
AiChanInfo(int chan);
void addChanMode(AiInputMode mode);
void setChanTypes(long long types);
int getChanNum() const;
std::vector<AiInputMode> getChanModes() const;
AiChanType getChanTypes() const;
private:
int mChanNum;
AiChanType mTypes;
std::vector<AiInputMode> mMode;
//TcInfo mTcInfo;
};
} /* namespace ul */
#endif /* AICHANINFO_H_ */

134
src/AiConfig.cpp Normal file
View File

@ -0,0 +1,134 @@
/*
* AiConfig.cpp
*
* Author: Measurement Computing Corporation
*/
#include "AiDevice.h"
#include "AiConfig.h"
namespace ul
{
AiConfig::~AiConfig()
{
}
AiConfig::AiConfig(AiDevice& aiDevice) : mAiDevice(aiDevice)
{
}
void AiConfig::setChanType(int channel, AiChanType chanType)
{
mAiDevice.setCfg_ChanType(channel, chanType);
}
AiChanType AiConfig::getChanType(int channel)
{
return mAiDevice.getCfg_ChanType(channel);
}
void AiConfig::setChanTcType(int channel, TcType tcType)
{
mAiDevice.setCfg_ChanTcType(channel, tcType);
}
TcType AiConfig::getChanTcType(int channel)
{
return mAiDevice.getCfg_ChanTcType(channel);
}
void AiConfig::setChanTempUnit(int channel, TempUnit unit)
{
mAiDevice.setCfg_ChanTempUnit(channel, unit);
}
TempUnit AiConfig::getChanTempUnit(int channel)
{
return mAiDevice.getCfg_ChanTempUnit(channel);
}
void AiConfig::setTempUnit(TempUnit unit)
{
mAiDevice.setCfg_TempUnit(unit);
}
void AiConfig::setAutoZeroMode(AutoZeroMode mode)
{
mAiDevice.setCfg_AutoZeroMode(mode);
}
AutoZeroMode AiConfig::getAutoZeroMode()
{
return mAiDevice.getCfg_AutoZeroMode();
}
void AiConfig::setAdcTimingMode(AdcTimingMode mode)
{
mAiDevice.setCfg_AdcTimingMode(mode);
}
AdcTimingMode AiConfig::getAdcTimingMode()
{
return mAiDevice.getCfg_AdcTimingMode();
}
void AiConfig::setChanIepeMode(int channel, IepeMode mode)
{
mAiDevice.setCfg_ChanIepeMode(channel, mode);
}
IepeMode AiConfig::getChanIepeMode(int channel)
{
return mAiDevice.getCfg_ChanIepeMode(channel);
}
void AiConfig::setChanCouplingMode(int channel, CouplingMode mode)
{
mAiDevice.setCfg_ChanCouplingMode(channel, mode);
}
CouplingMode AiConfig::getChanCouplingMode(int channel)
{
return mAiDevice.getCfg_ChanCouplingMode(channel);
}
void AiConfig::setChanSensorSensitivity(int channel, double sensitivity)
{
mAiDevice.setCfg_ChanSensorSensitivity(channel, sensitivity);
}
double AiConfig::getChanSensorSensitivity(int channel)
{
return mAiDevice.getCfg_ChanSensorSensitivity(channel);
}
void AiConfig::AiConfig::setChanSlope(int channel, double slope)
{
mAiDevice.setCfg_ChanSlope(channel, slope);
}
double AiConfig::getChanSlope(int channel)
{
return mAiDevice.getCfg_ChanSlope(channel);
}
void AiConfig::setChanOffset(int channel, double offset)
{
mAiDevice.setCfg_ChanOffset(channel, offset);
}
double AiConfig::getChanOffset(int channel)
{
return mAiDevice.getCfg_ChanOffset(channel);
}
unsigned long long AiConfig::getCalDate()
{
return mAiDevice.getCfg_CalDate();
}
void AiConfig::getCalDateStr(char* calDate, unsigned int* maxStrLen)
{
return mAiDevice.getCfg_CalDateStr(calDate, maxStrLen);
}
} /* namespace ul */

64
src/AiConfig.h Normal file
View File

@ -0,0 +1,64 @@
/*
* AiConfig.h
*
* Author: Measurement Computing Corporation
*/
#ifndef AICONFIG_H_
#define AICONFIG_H_
#include "interfaces/UlAiConfig.h"
#include "ul_internal.h"
namespace ul
{
class AiDevice;
class UL_LOCAL AiConfig: public UlAiConfig
{
public:
virtual ~AiConfig();
AiConfig(AiDevice& aiDevice);
virtual void setChanType(int channel, AiChanType chanType);
virtual AiChanType getChanType(int channel);
virtual void setChanTcType(int channel, TcType tcType);
virtual TcType getChanTcType(int channel);
virtual void setChanTempUnit(int channel, TempUnit unit);
virtual TempUnit getChanTempUnit(int channel);
virtual void setTempUnit(TempUnit unit);
//virtual TempUnit getTempUnit();
virtual void setAutoZeroMode(AutoZeroMode mode);
virtual AutoZeroMode getAutoZeroMode();
virtual void setAdcTimingMode(AdcTimingMode mode);
virtual AdcTimingMode getAdcTimingMode();
virtual void setChanIepeMode(int channel, IepeMode mode);
virtual IepeMode getChanIepeMode(int channel);
virtual void setChanCouplingMode(int channel, CouplingMode mode);
virtual CouplingMode getChanCouplingMode(int channel);
virtual void setChanSensorSensitivity(int channel, double sensitivity);
virtual double getChanSensorSensitivity(int channel);
virtual void setChanSlope(int channel, double slope);
virtual double getChanSlope(int channel);
virtual void setChanOffset(int channel, double offset);
virtual double getChanOffset(int channel);
virtual unsigned long long getCalDate(); // returns number of seconds since unix epoch
virtual void getCalDateStr(char* calDate, unsigned int* maxStrLen);
private:
AiDevice& mAiDevice;
};
} /* namespace ul */
#endif /* AICONFIG_H_ */

644
src/AiDevice.cpp Normal file
View File

@ -0,0 +1,644 @@
/*
* AiDevice.cpp
*
* Author: Measurement Computing Corporation
*/
#include "AiDevice.h"
#include "UlException.h"
#include <math.h>
#include <algorithm>
#include <bitset>
namespace ul
{
AiDevice::AiDevice(const DaqDevice& daqDevice) : IoDevice(daqDevice), UlAiDevice()
{
mAiConfig = new AiConfig(*this);
mCalDate = 0;
mCalModeEnabled = false;
}
AiDevice::~AiDevice()
{
if(mAiConfig != NULL)
{
delete mAiConfig;
mAiConfig = NULL;
}
}
double AiDevice::aIn(int channel, AiInputMode inputMode, Range range, AInFlag flags)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
double AiDevice::aInScan(int lowChan, int highChan, AiInputMode inputMode, Range range, int samplesPerChan, double rate, ScanOption options, AInScanFlag flags, double data[])
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void AiDevice::aInLoadQueue(AiQueueElement queue[], unsigned int numElements)
{
check_AInLoadQueue_Args(queue, numElements);
if(queue == NULL || numElements == 0) // disable loadqueue
mAQueue.clear();
else
{
mAQueue.clear();
mAQueue.insert(mAQueue.begin(), &queue[0], &queue[numElements]);
}
}
void AiDevice::setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount)
{
check_AInSetTrigger_Args(type, trigChan, level, variance, retriggerCount);
mTrigCfg.type = type;
mTrigCfg.trigChan = trigChan;
mTrigCfg.level = level;
mTrigCfg.variance = variance;
mTrigCfg.retrigCount = retriggerCount;
}
UlError AiDevice::getStatus(ScanStatus* status, TransferStatus* xferStatus)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void AiDevice::stopBackground()
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void AiDevice::check_AIn_Args(int channel, AiInputMode inputMode, Range range, AInFlag flags) const
{
if(!mAiInfo.isInputModeSupported(inputMode))
throw UlException(ERR_BAD_INPUT_MODE);
if(channel < 0 || channel >= mAiInfo.getNumChansByMode(inputMode))
throw UlException(ERR_BAD_AI_CHAN);
if(!mAiInfo.isRangeSupported(inputMode, range))
throw UlException(ERR_BAD_RANGE);
if(~mAiInfo.getAInFlags() & flags)
throw UlException(ERR_BAD_FLAG);
if(getScanState() == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
if((int) mCustomScales.size() < mAiInfo.getNumChans())
throw UlException(ERR_INTERNAL);
}
void AiDevice::check_AInScan_Args(int lowChan, int highChan, AiInputMode inputMode, Range range, int samplesPerChan, double rate, ScanOption options, AInScanFlag flags, double data[]) const
{
int numOfScanChan = 0;
if(!mAiInfo.hasPacer())
throw UlException(ERR_BAD_DEV_TYPE);
if(getScanState() == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(((options & SO_SINGLEIO) && (options & SO_BLOCKIO)) || ((options & SO_SINGLEIO) && (options & SO_BURSTIO)) || ((options & SO_BLOCKIO) && (options & SO_BURSTIO)))
throw UlException(ERR_BAD_OPTION);
if(queueEnabled())
numOfScanChan = queueLength();
else
{
if(!mAiInfo.isInputModeSupported(inputMode))
throw UlException(ERR_BAD_INPUT_MODE);
if(lowChan < 0 || highChan < 0 || lowChan >= mAiInfo.getNumChansByMode(inputMode) || highChan >= mAiInfo.getNumChansByMode(inputMode) || lowChan > highChan )
throw UlException(ERR_BAD_AI_CHAN);
numOfScanChan = highChan - lowChan + 1;
if(!mAiInfo.isRangeSupported(inputMode, range))
throw UlException(ERR_BAD_RANGE);
}
if(data == NULL)
throw UlException(ERR_BAD_BUFFER);
if(~mAiInfo.getScanOptions() & options)
throw UlException(ERR_BAD_OPTION);
if(~mAiInfo.getAInScanFlags() & flags)
throw UlException(ERR_BAD_FLAG);
double throughput = rate * numOfScanChan;
if(!(options & SO_EXTCLOCK))
{
if(((options & SO_BURSTIO) && (rate > mAiInfo.getMaxBurstRate() || throughput > mAiInfo.getMaxBurstThroughput())) || (!(options & SO_BURSTIO) && (rate > mAiInfo.getMaxScanRate() || throughput > mAiInfo.getMaxThroughput())) )
throw UlException(ERR_BAD_RATE);
}
if(rate <= 0.0)
throw UlException(ERR_BAD_RATE);
if(samplesPerChan < mMinScanSampleCount)
throw UlException(ERR_BAD_SAMPLE_COUNT);
long long totalCount = samplesPerChan * numOfScanChan;
if(options & SO_BURSTIO)
{
if(totalCount > (mAiInfo.getFifoSize() / mAiInfo.getSampleSize()))
throw UlException(ERR_BAD_BURSTIO_COUNT);
else if (options & SO_CONTINUOUS)
throw UlException(ERR_BAD_OPTION);
}
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
if((int) mCustomScales.size() < mAiInfo.getNumChans())
throw UlException(ERR_INTERNAL);
}
void AiDevice::check_AInLoadQueue_Args(const AiQueueElement queue[], unsigned int numElements) const
{
if(queue != NULL)
{
if(mAiInfo.getQueueTypes())
{
for(unsigned int i = 0; i < numElements; i++)
{
if(!mAiInfo.isInputModeSupported(queue[i].inputMode))
throw UlException(ERR_BAD_INPUT_MODE);
if(numElements > (unsigned int) mAiInfo.getMaxQueueLength(queue[i].inputMode))
throw UlException(ERR_BAD_QUEUE_SIZE);
if(queue[i].channel < 0 || queue[i].channel >= mAiInfo.getNumChansByMode(queue[i].inputMode))
throw UlException(ERR_BAD_AI_CHAN);
if(!mAiInfo.isRangeSupported(queue[i].inputMode, queue[i].range))
throw UlException(ERR_BAD_RANGE);
}
if(!isValidChanQueue(queue, numElements))
throw UlException(ERR_BAD_AI_CHAN_QUEUE);
if(!isValidGainQueue(queue, numElements))
throw UlException(ERR_BAD_AI_GAIN_QUEUE);
if(!isValidModeQueue(queue, numElements))
throw UlException(ERR_BAD_AI_MODE_QUEUE);
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
}
void AiDevice::check_AInSetTrigger_Args(TriggerType trigType, int trigChan, double level, double variance, unsigned int retriggerCount) const
{
if(mAiInfo.supportsTrigger())
{
if(!(mAiInfo.getTriggerTypes() & trigType))
throw UlException(ERR_BAD_TRIG_TYPE);
std::bitset<32> typeBitSet(trigType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_TRIG_TYPE);
if(retriggerCount > 0 && !(mAiInfo.getScanOptions() & SO_RETRIGGER))
throw UlException(ERR_BAD_RETRIG_COUNT);
//TODO add check for trigChan, lowThreshold and the rest of arguments for USB-2020 and any other devices that support analog trigger
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
bool AiDevice::isValidChanQueue(const AiQueueElement queue[], unsigned int numElements) const
{
bool valid = true;
AiQueueType queueTypes = mAiInfo.getQueueTypes();
if(!(queueTypes & CHAN_QUEUE)) // if channel queue is not supported then make sure channels are consecutive
{
for(unsigned int i = 1; i < numElements; i++)
{
if(queue[i].channel != (queue[i - 1].channel + 1))
{
valid = false;
return valid;
}
}
}
else
{
AiChanQueueLimitation chanQueueLimitations = mAiInfo.getChanQueueLimitations();
if(chanQueueLimitations & UNIQUE_CHAN)
{
for(unsigned int i = 1; i < numElements; i++)
{
for(unsigned int j = 0; j < i; j++)
{
if(queue[i].channel == queue[j].channel)
{
valid = false;
return valid;
}
}
}
}
if(chanQueueLimitations & ASCENDING_CHAN)
{
for(unsigned int i = 1; i < numElements; i++)
{
if(queue[i].channel <= queue[i - 1].channel)
{
valid = false;
return valid;
}
}
}
}
return valid;
}
bool AiDevice::isValidGainQueue(const AiQueueElement queue[], unsigned int numElements) const
{
bool valid = true;
AiQueueType queueTypes = mAiInfo.getQueueTypes();
if(!(queueTypes & GAIN_QUEUE)) // if gain queue is not supported then make sure all gains are the same
{
for(unsigned int i = 1; i < numElements; i++)
{
if(queue[i].range != queue[i - 1].range )
{
valid = false;
return valid;
}
}
}
return valid;
}
bool AiDevice::isValidModeQueue(const AiQueueElement queue[], unsigned int numElements) const
{
bool valid = true;
AiQueueType queueTypes = mAiInfo.getQueueTypes();
if(!(queueTypes & MODE_QUEUE)) // if gain queue is not supported then make sure all gains are the same
{
for(unsigned int i = 1; i < numElements; i++)
{
if(queue[i].inputMode != queue[i - 1].inputMode )
{
valid = false;
return valid;
}
}
}
return valid;
}
double AiDevice::calibrateData(int channel, AiInputMode inputMode, Range range, unsigned int count, long long flags) const
{
double calData = 0;
CalCoef calCoef = getCalCoef(channel, inputMode, range, flags);
calData = (calCoef.slope * count) + calCoef.offset;
if(flags & NOSCALEDATA)
{
unsigned long long maxVal = (1ULL << mAiInfo.getResolution()) - 1;
if(calData > maxVal)
calData = maxVal;
else if(calData < 0)
calData = 0;
}
return calData;
}
CalCoef AiDevice::getCalCoef(int channel, AiInputMode inputMode, Range range, long long flags) const
{
CalCoef coef;
if(mCalCoefs.empty())
const_cast<AiDevice*>(this)->loadAdcCoefficients();
if(!mCalCoefs.empty())
{
double offset = 0;
double scale = 0;
mDaqDevice.getEuScaling(range, scale, offset);
int calCoefIdx = getCalCoefIndex(channel, inputMode, range);
double lsb = scale / pow(2.0, mAiInfo.getResolution());
if (!(flags & NOSCALEDATA))
{
if(flags & NOCALIBRATEDATA)
{
coef.slope = lsb;
coef.offset = offset;
}
else
{
coef.slope = mCalCoefs[calCoefIdx].slope * lsb;
coef.offset = mCalCoefs[calCoefIdx].offset * lsb + offset;
}
}
else
{
if(flags & NOCALIBRATEDATA)
{
coef.slope = 1.0;
coef.offset = 0.0;
}
else
{
coef.slope = mCalCoefs[calCoefIdx].slope;
coef.offset = mCalCoefs[calCoefIdx].offset;
}
}
}
else
throw UlException(ERR_DEAD_DEV);
return coef;
}
std::vector<CalCoef> AiDevice::getScanCalCoefs(int lowChan, int highChan, AiInputMode inputMode, Range range, long long flags) const
{
std::vector<CalCoef> calCoefs;
int chan;
CalCoef calCoef;
if (!queueEnabled())
{
for (chan = lowChan; chan <= highChan; chan++)
{
calCoef = getCalCoef(chan, inputMode, range, flags);
calCoefs.push_back(calCoef);
}
}
else
{
for (unsigned int idx = 0; idx < mAQueue.size(); idx++)
{
calCoef = getCalCoef(mAQueue[idx].channel, mAQueue[idx].inputMode, mAQueue[idx].range, flags);
calCoefs.push_back(calCoef);
}
}
return calCoefs;
}
std::vector<CustomScale> AiDevice::getCustomScales(int lowChan, int highChan) const
{
std::vector<CustomScale> customScales;
int chan;
if (!queueEnabled())
{
for (chan = lowChan; chan <= highChan; chan++)
customScales.push_back(mCustomScales[chan]);
}
else
{
for (unsigned int idx = 0; idx < mAQueue.size(); idx++)
customScales.push_back(mCustomScales[mAQueue[idx].channel]);
}
return customScales;
}
bool AiDevice::queueEnabled() const
{
return (!mAQueue.empty());
}
int AiDevice::queueLength() const
{
return mAQueue.size();
}
double AiDevice::convertTempUnit(double tempC, TempUnit unit)
{
double temp = tempC;
switch(unit)
{
case TU_FAHRENHEIT:
temp = tempC * 1.8 + 32.0;
break;
case TU_KELVIN:
temp = tempC + 273.15;
break;
default:
break;
}
return temp;
}
void AiDevice::initCustomScales()
{
CustomScale coef;
for(int i = 0; i < mAiInfo.getNumChans(); i++)
{
coef.slope = 1.0;
coef.offset = 0;
mCustomScales.push_back(coef);
}
}
////////////////////// Configuration functions /////////////////////////////////
void AiDevice::setCfg_ChanType(int channel, AiChanType chanType)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
AiChanType AiDevice::getCfg_ChanType(int channel) const
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
void AiDevice::setCfg_ChanTcType(int channel, TcType tcType)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
TcType AiDevice::getCfg_ChanTcType(int channel) const
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
void AiDevice::setCfg_TempUnit(TempUnit unit)
{
if( unit < TU_CELSIUS || unit > TU_KELVIN)
throw UlException(ERR_BAD_UNIT);
for(unsigned int i = 0; i < mChanTempUnit.size(); i++)
mChanTempUnit[i] = unit;
}
void AiDevice::setCfg_ChanTempUnit(int channel, TempUnit unit)
{
if(channel < 0 || channel >= (int) mChanTempUnit.size())
throw UlException(ERR_BAD_AI_CHAN);
if( unit < TU_CELSIUS || unit > TU_KELVIN)
throw UlException(ERR_BAD_UNIT);
mChanTempUnit[channel] = unit;
}
TempUnit AiDevice::getCfg_ChanTempUnit(int channel) const
{
if(channel < 0 || channel >= (int) mChanTempUnit.size())
throw UlException(ERR_BAD_AI_CHAN);
return mChanTempUnit[channel];
}
void AiDevice::setCfg_AutoZeroMode(AutoZeroMode mode)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
AutoZeroMode AiDevice::getCfg_AutoZeroMode() const
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
void AiDevice::setCfg_AdcTimingMode(AdcTimingMode mode)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
AdcTimingMode AiDevice::getCfg_AdcTimingMode()
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
void AiDevice::setCfg_ChanIepeMode(int channel, IepeMode mode)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
IepeMode AiDevice::getCfg_ChanIepeMode(int channel)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
void AiDevice::setCfg_ChanCouplingMode(int channel, CouplingMode mode)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
CouplingMode AiDevice::getCfg_ChanCouplingMode(int channel)
{
return CM_DC;
}
void AiDevice::setCfg_ChanSensorSensitivity(int channel, double sensitivity)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
double AiDevice::getCfg_ChanSensorSensitivity(int channel)
{
throw UlException(ERR_CONFIG_NOT_SUPPORTED);
}
void AiDevice::setCfg_ChanSlope(int channel, double slope)
{
if(channel < 0 || channel >= (int) mCustomScales.size())
throw UlException(ERR_BAD_AI_CHAN);
mCustomScales[channel].slope = slope;
}
double AiDevice::getCfg_ChanSlope(int channel)
{
if(channel < 0 || channel >= (int) mCustomScales.size())
throw UlException(ERR_BAD_AI_CHAN);
return mCustomScales[channel].slope;
}
void AiDevice::setCfg_ChanOffset(int channel, double offset)
{
if(channel < 0 || channel >= (int) mCustomScales.size())
throw UlException(ERR_BAD_AI_CHAN);
mCustomScales[channel].offset = offset;
}
double AiDevice::getCfg_ChanOffset(int channel)
{
if(channel < 0 || channel >= (int) mCustomScales.size())
throw UlException(ERR_BAD_AI_CHAN);
return mCustomScales[channel].offset;
}
unsigned long long AiDevice::getCfg_CalDate()
{
mDaqDevice.checkConnection();
return mCalDate;
}
void AiDevice::getCfg_CalDateStr(char* calDate, unsigned int* maxStrLen)
{
mDaqDevice.checkConnection();
long int calDateSec = mCalDate;
// convert seconds to string
struct tm *timeinfo;
timeinfo = localtime(&calDateSec);
char calDateStr[128];
strftime(calDateStr, 128, "%c", timeinfo);
unsigned int len = strlen(calDateStr) + 1;
if(len <= *maxStrLen)
{
memcpy(calDate, calDateStr, len);
*maxStrLen = len;
}
else
{
*maxStrLen = len;
throw UlException(ERR_BAD_BUFFER_SIZE);
}
}
} /* namespace ul */

118
src/AiDevice.h Normal file
View File

@ -0,0 +1,118 @@
/*
* AiDevice.h
*
* Author: Measurement Computing Corporation
*/
#ifndef AIDEVICE_H_
#define AIDEVICE_H_
#include "ul_internal.h"
#include "IoDevice.h"
#include "AiInfo.h"
#include "AiConfig.h"
#include <vector>
namespace ul
{
class UL_LOCAL AiDevice: public IoDevice, public UlAiDevice
{
public:
virtual ~AiDevice();
AiDevice(const DaqDevice& daqDevice);
virtual const UlAiInfo& getAiInfo() { return mAiInfo;}
virtual UlAiConfig& getAiConfig() { return *mAiConfig;}
virtual double aIn(int channel, AiInputMode inputMode, Range range, AInFlag flags);
virtual double aInScan(int lowChan, int highChan, AiInputMode inputMode, Range range, int samplesPerChan, double rate, ScanOption options, AInScanFlag flags, double data[]);
virtual void aInLoadQueue(AiQueueElement queue[], unsigned int numElements);
virtual void setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount);
virtual UlError getStatus(ScanStatus* status, TransferStatus* xferStatus);
virtual void stopBackground();
double convertTempUnit(double tempC, TempUnit unit);
////////////////////// Configuration functions /////////////////////////////////
virtual void setCfg_ChanType(int channel, AiChanType chanType);
virtual AiChanType getCfg_ChanType(int channel) const;
virtual void setCfg_ChanTcType(int channel, TcType tcType);
virtual TcType getCfg_ChanTcType(int channel) const;
virtual void setCfg_TempUnit(TempUnit unit);
//virtual TempUnit getCfg_TempUnit() const;
virtual void setCfg_ChanTempUnit(int channel, TempUnit unit);
virtual TempUnit getCfg_ChanTempUnit(int channel) const;
virtual void setCfg_AutoZeroMode(AutoZeroMode mode);
virtual AutoZeroMode getCfg_AutoZeroMode() const;
virtual void setCfg_AdcTimingMode(AdcTimingMode mode);
virtual AdcTimingMode getCfg_AdcTimingMode();
virtual void setCfg_ChanIepeMode(int channel, IepeMode mdoe);
virtual IepeMode getCfg_ChanIepeMode(int channel);
virtual void setCfg_ChanCouplingMode(int channel, CouplingMode mode);
virtual CouplingMode getCfg_ChanCouplingMode(int channel);
virtual void setCfg_ChanSensorSensitivity(int channel, double sensitivity);
virtual double getCfg_ChanSensorSensitivity(int channel);
virtual void setCfg_ChanSlope(int channel, double slope);
virtual double getCfg_ChanSlope(int channel);
virtual void setCfg_ChanOffset(int channel, double offset);
virtual double getCfg_ChanOffset(int channel);
virtual unsigned long long getCfg_CalDate();
virtual void getCfg_CalDateStr(char* calDate, unsigned int* maxStrLen);
protected:
virtual void loadAdcCoefficients() = 0;
virtual int getCalCoefIndex(int channel, AiInputMode inputMode, Range range) const = 0;
virtual double calibrateData(int channel, AiInputMode inputMode, Range range, unsigned int count, long long flags) const;
virtual CalCoef getCalCoef(int channel, AiInputMode inputMode, Range range, long long flags) const;
std::vector<CalCoef> getScanCalCoefs(int lowChan, int highChan, AiInputMode inputMode, Range range, long long flags) const;
bool queueEnabled() const;
int queueLength() const;
void check_AIn_Args(int channel, AiInputMode inputMode, Range range, AInFlag flags) const;
void check_AInScan_Args(int lowChan, int highChan, AiInputMode inputMode, Range range, int samplesPerChan, double rate, ScanOption options, AInScanFlag flags, double data[]) const;
void check_AInLoadQueue_Args(const AiQueueElement queue[], unsigned int numElements) const;
void check_AInSetTrigger_Args(TriggerType trigtype, int trigChan, double level, double variance, unsigned int retriggerCount) const;
bool isValidChanQueue(const AiQueueElement queue[], unsigned int numElements) const;
bool isValidGainQueue(const AiQueueElement queue[], unsigned int numElements) const;
bool isValidModeQueue(const AiQueueElement queue[], unsigned int numElements) const;
void initCustomScales();
std::vector<CustomScale> getCustomScales(int lowChan, int highChan) const;
void enableCalMode(bool enable) { mCalModeEnabled = enable;}
bool calModeEnabled() const { return mCalModeEnabled;}
virtual void readCalDate() {};
protected:
AiInfo mAiInfo;
AiConfig* mAiConfig;
std::vector<CalCoef> mCalCoefs;
std::vector<CustomScale> mCustomScales;
std::vector<AiQueueElement> mAQueue;
std::vector<TempUnit> mChanTempUnit;
unsigned long long mCalDate; // cal date in sec
private:
bool mCalModeEnabled;
};
} /* namespace ul */
#endif /* AIDEVICE_H_ */

467
src/AiInfo.cpp Normal file
View File

@ -0,0 +1,467 @@
/*
* AiInfo.cpp
*
* Author: root
*/
#include <algorithm>
#include <bitset>
#include "AiInfo.h"
namespace ul
{
AiInfo::AiInfo()
{
mResolution = 0;
mMinScanRate = 0;
mMaxScanRate = 0;
mMaxBurstRate = 0;
mMaxThroughput = 0;
mMaxBurstThroughput = 0;
mScanOptions = SO_DEFAULTIO;
mFifoSize = 0;
mMaxQueueLengthSE = 0;
mMaxQueueLengthDiff = 0;
mMaxQueueLengthPseudoDiff = 0;
mHasPacer = 0;
mHasTempChan = 0;
mCalCoefsCount = 0;
mCalCoefsStartAddr = -1;
mCalDateAddr = -1;
mSampleSize = 0;
mAInFlags = 0;
mAInScanFlags = 0;
mQueueTypes = (AiQueueType) 0;
mChanQueueLimitations = (AiChanQueueLimitation) 0;
mTriggerTypes = TRIG_NONE;
mTypes = (AiChanType) 0;
}
AiInfo::~AiInfo()
{
}
void AiInfo::setNumChans(int numChans)
{
if(mAiChanInfo.size())
mAiChanInfo.clear();
for(int ch = 0; ch < numChans; ch++)
mAiChanInfo.push_back(AiChanInfo(ch));
}
int AiInfo::getNumChans() const
{
return mAiChanInfo.size();
}
void AiInfo::setNumChansByMode(AiInputMode mode, int numChans)
{
for(int ch = 0; ch < numChans; ch++)
mAiChanInfo[ch].addChanMode(mode);
}
int AiInfo::getNumChansByMode(AiInputMode mode) const
{
int numChans = 0;
for(unsigned int ch = 0; ch < mAiChanInfo.size(); ch++)
{
std::vector<AiInputMode> inputModes = mAiChanInfo[ch].getChanModes();
if(std::find(inputModes.begin(), inputModes.end(), mode) != inputModes.end())
numChans++;
}
return numChans;
}
int AiInfo::getNumChansByType(AiChanType chanType) const
{
int numChans = 0;
std::bitset<32> typeBitSet(chanType);
if(typeBitSet.count() == 1)
{
for(unsigned int ch = 0; ch < mAiChanInfo.size(); ch++)
{
AiChanType chanTypes = mAiChanInfo[ch].getChanTypes();
if(chanTypes & chanType)
numChans++;
}
}
return numChans;
}
void AiInfo::setChanTypes(long long type)
{
mTypes = (AiChanType) type;
}
AiChanType AiInfo::getChanTypes() const
{
return mTypes;
}
void AiInfo::setResolution(int resolution)
{
mResolution = resolution;
}
int AiInfo::getResolution() const
{
return mResolution;
}
void AiInfo::setMinScanRate(double minRate)
{
mMinScanRate = minRate;
}
double AiInfo::getMinScanRate() const
{
return mMinScanRate;
}
void AiInfo::setMaxScanRate(double maxRate)
{
mMaxScanRate = maxRate;
}
double AiInfo::getMaxScanRate() const
{
return mMaxScanRate;
}
void AiInfo::setMaxThroughput(double maxThroughput)
{
mMaxThroughput = maxThroughput;
}
double AiInfo::getMaxThroughput() const
{
return mMaxThroughput;
}
void AiInfo::setMaxBurstThroughput(double maxThroughput)
{
mMaxBurstThroughput = maxThroughput;
}
double AiInfo::getMaxBurstThroughput() const
{
return mMaxBurstThroughput;
}
void AiInfo::setMaxBurstRate(double maxRate)
{
mMaxBurstRate = maxRate;
}
double AiInfo::getMaxBurstRate() const
{
return mMaxBurstRate;
}
void AiInfo::setFifoSize(int size)
{
mFifoSize = size;
}
int AiInfo::getFifoSize() const
{
return mFifoSize;
}
void AiInfo::setScanOptions(long long options)
{
mScanOptions = (ScanOption) options;
}
ScanOption AiInfo::getScanOptions() const
{
return mScanOptions;
}
void AiInfo::setAInFlags(long long flags)
{
mAInFlags = flags;
}
long long AiInfo::getAInFlags() const
{
return mAInFlags;
}
void AiInfo::setAInScanFlags(long long flags)
{
mAInScanFlags = flags;
}
long long AiInfo::getAInScanFlags() const
{
return mAInScanFlags;
}
void AiInfo::addRange(AiInputMode mode, Range range)
{
if(mode == AI_SINGLE_ENDED)
{
mSERanges.push_back(range);
}
else if (mode == AI_DIFFERENTIAL)
{
mDiffRanges.push_back(range);
}
else if (mode == AI_PSEUDO_DIFFERENTIAL)
{
mPseudoDiffRanges.push_back(range);
}
}
std::vector<Range> AiInfo::getRanges(AiInputMode mode) const
{
std::vector<Range> modeRanges;
if(mode == AI_SINGLE_ENDED)
modeRanges = mSERanges;
else if (mode == AI_DIFFERENTIAL )
modeRanges = mDiffRanges;
else if (mode == AI_PSEUDO_DIFFERENTIAL)
modeRanges = mPseudoDiffRanges;
return modeRanges;
}
void AiInfo::getRanges(AiInputMode mode, Range ranges[], int* count) const
{
std::vector<Range> modeRanges;
if(mode == AI_SINGLE_ENDED)
modeRanges = mSERanges;
else if (mode == AI_DIFFERENTIAL )
modeRanges = mDiffRanges;
else if (mode == AI_PSEUDO_DIFFERENTIAL)
modeRanges = mPseudoDiffRanges;
if(modeRanges.size() <= (unsigned int)*count )
std::copy(modeRanges.begin(), modeRanges.end(), ranges);
*count = modeRanges.size();
}
int AiInfo::getRangeCountByMode(AiInputMode mode) const
{
return getRanges(mode).size();
}
Range AiInfo::getRangeByMode(AiInputMode mode, unsigned int index) const
{
Range range = (Range) 0;
if(index < getRanges(mode).size())
{
range = getRanges(mode).at(index);
}
return range;
}
void AiInfo::addInputMode(AiInputMode mode)
{
mInputModes.push_back(mode);
}
std::vector<AiInputMode> AiInfo::getInputModes() const
{
return mInputModes;
}
void AiInfo::setTriggerTypes(long long triggerTypes)
{
mTriggerTypes = (TriggerType) triggerTypes;
}
TriggerType AiInfo::getTriggerTypes() const
{
return mTriggerTypes;
}
bool AiInfo::supportsTrigger() const
{
bool supportsTrig = false;
if(mTriggerTypes)
supportsTrig = true;
return supportsTrig;
}
void AiInfo::setMaxQueueLength(AiInputMode mode, int length)
{
if(mode == AI_SINGLE_ENDED)
mMaxQueueLengthSE = length;
else if (mode == AI_DIFFERENTIAL)
mMaxQueueLengthDiff = length;
else if (mode == AI_PSEUDO_DIFFERENTIAL)
mMaxQueueLengthPseudoDiff = length;
}
int AiInfo::getMaxQueueLength(AiInputMode mode) const
{
int length = 0;
if(mode == AI_SINGLE_ENDED)
length = mMaxQueueLengthSE;
else if (mode == AI_DIFFERENTIAL)
length = mMaxQueueLengthDiff;
else if (mode == AI_PSEUDO_DIFFERENTIAL)
length = mMaxQueueLengthPseudoDiff;
return length;
}
void AiInfo::setQueueTypes(long long type)
{
mQueueTypes = (AiQueueType) type;
}
AiQueueType AiInfo::getQueueTypes() const
{
return mQueueTypes;
}
void AiInfo::setChanQueueLimitations(long long limitation)
{
mChanQueueLimitations = (AiChanQueueLimitation) limitation;
}
AiChanQueueLimitation AiInfo::getChanQueueLimitations() const
{
return mChanQueueLimitations;
}
bool AiInfo::hasPacer() const
{
return mHasPacer;
}
void AiInfo::hasPacer(bool hasPacer)
{
mHasPacer = hasPacer;
}
bool AiInfo::hasTempChan() const
{
return mHasTempChan;
}
void AiInfo::hasTempChan(bool hasTempChan)
{
mHasTempChan = hasTempChan;
}
void AiInfo::setChanTypes(int firtChan, int lastChan, long long chanTypes)
{
for(int ch = firtChan; ch <=lastChan; ch++)
mAiChanInfo[ch].setChanTypes(chanTypes);
}
AiChanInfo AiInfo::getChanInfo(int chan) const
{
AiChanInfo aiChanInfo(-1);
if((unsigned int) chan < mAiChanInfo.size())
aiChanInfo = mAiChanInfo[chan];
return aiChanInfo;
}
void AiInfo::setCalCoefCount(int count)
{
mCalCoefsCount = count;
}
int AiInfo::getCalCoefCount() const
{
return mCalCoefsCount;
}
void AiInfo::setCalCoefsStartAddr(int count)
{
mCalCoefsStartAddr = count;
}
int AiInfo::getCalCoefsStartAddr() const
{
return mCalCoefsStartAddr;
}
void AiInfo::setCalDateAddr(int addr)
{
mCalDateAddr = addr;
}
int AiInfo::getCalDateAddr() const
{
return mCalDateAddr;
}
void AiInfo::setSampleSize(int size)
{
mSampleSize = size;
}
int AiInfo::getSampleSize() const
{
return mSampleSize;
}
bool AiInfo::isInputModeSupported(AiInputMode inputMode) const
{
bool supported = false;
std::vector<AiInputMode>::const_iterator itr = std::find(mInputModes.begin(), mInputModes.end(), inputMode);
if(itr != mInputModes.end())
supported = true;
return supported;
}
bool AiInfo::isRangeSupported(AiInputMode inputMode, Range range) const
{
bool supported = false;
std::vector<Range> ranges = getRanges(inputMode);
if(!ranges.empty())
{
std::vector<Range>::const_iterator itr = std::find(ranges.begin(), ranges.end(), range);
if(itr != ranges.end())
supported = true;
}
return supported;
}
/*
void addTcType(int firtChan, int lastChan, TcType tcType)
{
if(mAiChanInfo != null)
{
for(int ch = firtChan; ch <=lastChan; ch++)
mAiChanInfo[ch].getTcInfo().addTcType(tcType);
}
}*/
} /* namespace ul */

132
src/AiInfo.h Normal file
View File

@ -0,0 +1,132 @@
/*
* AiInfo.h
*
* Created on: Sep 24, 2015
* Author: root
*/
#ifndef AIINFO_H_
#define AIINFO_H_
#include "ul_internal.h"
#include "AiChanInfo.h"
#include <vector>
#include "interfaces/UlAiInfo.h"
namespace ul
{
class UL_LOCAL AiInfo: public UlAiInfo
{
public:
AiInfo();
virtual ~AiInfo();
void addRange(AiInputMode mode, Range range);
std::vector<Range> getRanges(AiInputMode mode) const;
void setNumChans(int numChans);
int getNumChans() const;
void setNumChansByMode(AiInputMode mode, int numChans);
int getNumChansByMode(AiInputMode mode) const;
int getNumChansByType(AiChanType chanType) const;
void setChanTypes(long long types);
AiChanType getChanTypes() const;
void setResolution(int resolution);
int getResolution() const;
void setMinScanRate(double minRate);
double getMinScanRate() const;
void setMaxScanRate(double maxRate);
double getMaxScanRate() const;
void setMaxThroughput(double maxThroughput);
double getMaxThroughput() const;
void setMaxBurstThroughput(double maxThroughput);
double getMaxBurstThroughput() const;
void setMaxBurstRate(double maxRate);
double getMaxBurstRate() const;
void setFifoSize(int size);
int getFifoSize() const;
void setScanOptions(long long options);
ScanOption getScanOptions() const;
bool supportsTrigger() const;
void setAInFlags(long long flags);
long long getAInFlags() const;
void setAInScanFlags(long long flags);
long long getAInScanFlags() const;
void addInputMode(AiInputMode mode);
std::vector<AiInputMode> getInputModes() const;
void setMaxQueueLength(AiInputMode mode, int length);
int getMaxQueueLength(AiInputMode mode) const;
void setQueueTypes(long long type);
AiQueueType getQueueTypes() const;
void setChanQueueLimitations(long long limitations);
AiChanQueueLimitation getChanQueueLimitations() const;
void setChanTypes(int firtChan, int lastChan, long long chanTypes);
AiChanInfo getChanInfo(int chan) const;
bool hasPacer() const;
void hasPacer(bool hasPacer);
bool hasTempChan() const;
void hasTempChan(bool hasTempChan);
void getRanges(AiInputMode mode, Range ranges[], int* count) const;
int getRangeCountByMode(AiInputMode mode) const;
Range getRangeByMode(AiInputMode mode, unsigned int index) const;
void setTriggerTypes(long long triggerTypes);
TriggerType getTriggerTypes() const;
void setCalCoefCount(int count);
int getCalCoefCount() const;
void setCalCoefsStartAddr(int count);
int getCalCoefsStartAddr() const;
void setCalDateAddr(int addr);
int getCalDateAddr() const;
void setSampleSize(int size);
int getSampleSize() const;
bool isInputModeSupported(AiInputMode inputMode) const;
bool isRangeSupported(AiInputMode inputMode, Range range) const;
private:
std::vector<AiChanInfo> mAiChanInfo;
std::vector<Range> mSERanges;
std::vector<Range> mDiffRanges;
std::vector<Range> mPseudoDiffRanges;
std::vector<AiInputMode> mInputModes;
AiChanType mTypes;
TriggerType mTriggerTypes;
AiQueueType mQueueTypes;
AiChanQueueLimitation mChanQueueLimitations;
int mResolution;
double mMinScanRate;
double mMaxScanRate;
double mMaxBurstRate;
double mMaxThroughput;
double mMaxBurstThroughput;
ScanOption mScanOptions;
int mFifoSize;
int mMaxQueueLengthSE;
int mMaxQueueLengthDiff;
int mMaxQueueLengthPseudoDiff;
bool mHasPacer;
bool mHasTempChan;
int mCalCoefsCount;
int mCalCoefsStartAddr;
int mCalDateAddr;
int mSampleSize;
long long mAInFlags;
long long mAInScanFlags;
};
} /* namespace ul */
#endif /* AIINFO_H_ */

23
src/AoConfig.cpp Normal file
View File

@ -0,0 +1,23 @@
/*
* AoConfig.cpp
*
* Author: Measurement Computing Corporation
*/
#include "AoConfig.h"
namespace ul
{
AoConfig::AoConfig(AoDevice& aoDevice) : mAoDevice(aoDevice)
{
}
AoConfig::~AoConfig()
{
}
} /* namespace ul */

29
src/AoConfig.h Normal file
View File

@ -0,0 +1,29 @@
/*
* AoConfig.h
*
* Author: Measurement Computing Corporation
*/
#ifndef AOCONFIG_H_
#define AOCONFIG_H_
#include "interfaces/UlAoConfig.h"
#include "ul_internal.h"
namespace ul
{
class AoDevice;
class UL_LOCAL AoConfig: public UlAoConfig
{
public:
AoConfig(AoDevice& aoDevice);
virtual ~AoConfig();
private:
AoDevice& mAoDevice;
};
} /* namespace ul */
#endif /* AOCONFIG_H_ */

345
src/AoDevice.cpp Normal file
View File

@ -0,0 +1,345 @@
/*
* AoDevice.cpp
*
* Author: Measurement Computing Corporation
*/
#include "AoDevice.h"
#include <math.h>
#include <algorithm>
#include <bitset>
#include "UlException.h"
namespace ul
{
AoDevice::AoDevice(const DaqDevice& daqDevice) : IoDevice(daqDevice), UlAoDevice()
{
mAoConfig = new AoConfig(*this);
mCalDate = 0;
}
AoDevice::~AoDevice()
{
if(mAoConfig != NULL)
{
delete mAoConfig;
mAoConfig = NULL;
}
}
void AoDevice::aOut(int channel, Range range, AOutFlag flags, double dataValue)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
double AoDevice::aOutScan(int lowChan, int highChan, Range range, int samplesPerChan, double rate, ScanOption options, AOutScanFlag flags, double data[])
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void AoDevice::setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount)
{
if(mAoInfo.supportsTrigger())
{
check_AOutSetTrigger_Args(type, trigChan, level, variance, retriggerCount);
mTrigCfg.type = type;
mTrigCfg.trigChan = trigChan;
mTrigCfg.level = round(level);
mTrigCfg.variance = round(variance);
mTrigCfg.retrigCount = retriggerCount;
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
UlError AoDevice::getStatus(ScanStatus* status, TransferStatus* xferStatus)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void AoDevice::stopBackground()
{
throw UlException(ERR_BAD_DEV_TYPE);
}
unsigned int AoDevice::calibrateData(int channel, Range range, AOutFlag flags, double data) const
{
CalCoef calCoef = getCalCoef(channel, range, flags);
unsigned int calData = 0;
calData = (calCoef.slope * data) + calCoef.offset + 0.5;
unsigned int maxVal = getMaxOutputValue(range, false);
if(calData > maxVal)
calData = maxVal;
return calData;
}
CalCoef AoDevice::getCalCoef(int channel, Range range, long long flags) const
{
CalCoef coef;
// some devices like usb-1208fs-plus don't have DAC cal coefs, if device does not have cal coefs return default cal coef
if(mAoInfo.getCalCoefCount() <= 0)
return getDefaultCalCoef(channel, range, flags);
if(mCalCoefs.empty())
const_cast<AoDevice*>(this)->loadDacCoefficients();
if(!mCalCoefs.empty())
{
double offset = 0;
double scale = 0;
mDaqDevice.getEuScaling(range, scale, offset);
int calCoefIdx = getCalCoefIndex(channel, range);
unsigned long long fullScaleCount = 1ULL << mAoInfo.getResolution();
double lsb = scale / pow(2.0, mAoInfo.getResolution());
if (!(flags & NOSCALEDATA))
{
if(flags & NOCALIBRATEDATA)
{
coef.slope = 1 / lsb;
coef.offset = ((-offset) / scale) * fullScaleCount;
}
else
{
coef.slope = mCalCoefs[calCoefIdx].slope / lsb;
coef.offset = mCalCoefs[calCoefIdx].offset + mCalCoefs[calCoefIdx].slope * ((-offset) / scale) * fullScaleCount;
}
}
else
{
if(flags & NOCALIBRATEDATA)
{
coef.slope = 1.0;
coef.offset = 0.0;
}
else
{
coef.slope = mCalCoefs[calCoefIdx].slope;
coef.offset = mCalCoefs[calCoefIdx].offset;
}
}
}
else
throw UlException(ERR_DEAD_DEV);
return coef;
}
CalCoef AoDevice::getDefaultCalCoef(int channel, Range range, long long flags) const
{
CalCoef coef;
double offset = 0;
double scale = 0;
mDaqDevice.getEuScaling(range, scale, offset);
unsigned long long fullScaleCount = 1ULL << mAoInfo.getResolution();
double lsb = scale / pow(2.0, mAoInfo.getResolution());
if (!(flags & NOSCALEDATA))
{
coef.slope = 1 / lsb;
coef.offset = ((-offset) / scale) * fullScaleCount;
}
else
{
coef.slope = 1.0;
coef.offset = 0.0;
}
return coef;
}
std::vector<CalCoef> AoDevice::getScanCalCoefs(int lowChan, int highChan, Range range, long long flags) const
{
std::vector<CalCoef> calCoefs;
int chan;
CalCoef calCoef;
for (chan = lowChan; chan <= highChan; chan++)
{
calCoef = getCalCoef(chan, range, flags);
calCoefs.push_back(calCoef);
}
return calCoefs;
}
double AoDevice::getMaxOutputValue(Range range, bool scaled) const
{
unsigned long long maxCount = 0;
double maxOutputVal = 0;
maxCount = (1ULL << mAoInfo.getResolution()) - 1;
if(scaled)
maxOutputVal = toEngUnits(maxCount, range);
else
maxOutputVal = maxCount;
return maxOutputVal;
}
unsigned int AoDevice::fromEngUnits(double engUnits, Range range) const
{
unsigned int counts = 0;
double offset = 0;
double scale = 0;
mDaqDevice.getEuScaling(range, scale, offset);
unsigned int maxVal = getMaxOutputValue(range, false);
offset = -offset;
if (engUnits <= offset)
counts = 0;
else if (engUnits >= (offset + scale * (1 - (1 / maxVal))))
counts = (maxVal - 1.0) + 0.5;
else
counts = (((engUnits - offset) / scale) * maxVal) + 0.5;
return counts;
}
double AoDevice::toEngUnits(unsigned int counts, Range range) const
{
double engUnits = 0;
double offset = 0;
double scale = 0;
mDaqDevice.getEuScaling(range, scale, offset);
unsigned int maxVal = getMaxOutputValue(range, false);
if (counts > maxVal)
engUnits = scale + offset;
else
engUnits = ((double)counts / maxVal) * scale + offset;
return engUnits;
}
void AoDevice::check_AOut_Args(int channel, Range range, AOutFlag flags, double dataValue) const
{
bool scaled = true;
if(flags & NOSCALEDATA)
scaled = false;
double maxDataValue = getMaxOutputValue(range, scaled);
if(channel < 0 || channel >= mAoInfo.getNumChans())
throw UlException(ERR_BAD_AO_CHAN);
if(!mAoInfo.isRangeSupported(range))
throw UlException(ERR_BAD_RANGE);
if (dataValue > maxDataValue)
throw UlException(ERR_BAD_DA_VAL);
if(flags & NOSCALEDATA)
{
if(dataValue < 0)
throw UlException(ERR_BAD_DA_VAL);
}
else
{
double offset = 0;
double scale = 0;
mDaqDevice.getEuScaling(range, scale, offset);
if(dataValue < offset)
throw UlException(ERR_BAD_DA_VAL);
}
if(getScanState() == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void AoDevice::check_AOutScan_Args(int lowChan, int highChan, Range range, int samplesPerChan, double rate, ScanOption options, AOutScanFlag flags, double data[]) const
{
int numOfScanChan = 0;
if(!mAoInfo.hasPacer())
throw UlException(ERR_BAD_DEV_TYPE);
if(getScanState() == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if((options & SO_SINGLEIO) && (options & SO_BLOCKIO))
throw UlException(ERR_BAD_OPTION);
if(lowChan < 0 || highChan < 0 || lowChan > mAoInfo.getNumChans() || highChan >= mAoInfo.getNumChans() || lowChan > highChan )
throw UlException(ERR_BAD_AO_CHAN);
if(!mAoInfo.isRangeSupported(range))
throw UlException(ERR_BAD_RANGE);
numOfScanChan = highChan - lowChan + 1;
if(~mAoInfo.getScanOptions() & options)
throw UlException(ERR_BAD_OPTION);
if(~mAoInfo.getAOutScanFlags() & flags)
throw UlException(ERR_BAD_FLAG);
if(data == NULL)
throw UlException(ERR_BAD_BUFFER);
double throughput = rate * numOfScanChan;
if(!(options & SO_EXTCLOCK))
{
if(rate > mAoInfo.getMaxScanRate() || throughput > mAoInfo.getMaxThroughput())
throw UlException(ERR_BAD_RATE);
}
if(rate <= 0.0)
throw UlException(ERR_BAD_RATE);
if(samplesPerChan < mMinScanSampleCount)
throw UlException(ERR_BAD_SAMPLE_COUNT);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void AoDevice::check_AOutSetTrigger_Args(TriggerType trigType, int trigChan, double level, double variance, unsigned int retriggerCount) const
{
if(mAoInfo.supportsTrigger())
{
if(!(mAoInfo.getTriggerTypes() & trigType) )
throw UlException(ERR_BAD_TRIG_TYPE);
std::bitset<32> typeBitSet(trigType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_TRIG_TYPE);
if(retriggerCount > 0 && !(mAoInfo.getScanOptions() & SO_RETRIGGER))
throw UlException(ERR_BAD_RETRIG_COUNT);
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
} /* namespace ul */

65
src/AoDevice.h Normal file
View File

@ -0,0 +1,65 @@
/*
* AoDevice.h
*
* Created on: Oct 26, 2017
* Author: Measurement Computing Corporation
*/
#ifndef AODEVICE_H_
#define AODEVICE_H_
#include "ul_internal.h"
#include "IoDevice.h"
#include "AoInfo.h"
#include "AoConfig.h"
#include <vector>
#include "interfaces/UlAoDevice.h"
namespace ul
{
class UL_LOCAL AoDevice: public IoDevice, public UlAoDevice
{
public:
AoDevice(const DaqDevice& daqDevice);
virtual ~AoDevice();
virtual const UlAoInfo& getAoInfo() { return mAoInfo;}
virtual UlAoConfig& getAoConfig() { return *mAoConfig;}
virtual void aOut(int channel, Range range, AOutFlag flags, double dataValue);
virtual double aOutScan(int lowChan, int highChan, Range range, int samplesPerChan, double rate, ScanOption options, AOutScanFlag flags, double data[]);
virtual void setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount);
virtual UlError getStatus(ScanStatus* status, TransferStatus* xferStatus);
virtual void stopBackground();
protected:
virtual void loadDacCoefficients() = 0;
virtual int getCalCoefIndex(int channel, Range range) const = 0;
virtual CalCoef getCalCoef(int channel, Range range, long long flags) const;
virtual CalCoef getDefaultCalCoef(int channel, Range range, long long flags) const;
std::vector<CalCoef> getScanCalCoefs(int lowChan, int highChan, Range range, long long flags) const;
virtual unsigned int calibrateData(int channel, Range range, AOutFlag flags, double data) const;
double getMaxOutputValue(Range range, bool scaled) const;
unsigned int fromEngUnits(double engUnits, Range range) const;
double toEngUnits(unsigned int counts, Range range) const;
void check_AOut_Args(int channel, Range range, AOutFlag flags, double dataValue) const;
void check_AOutScan_Args(int lowChan, int highChan, Range range, int samplesPerChan, double rate, ScanOption options, AOutScanFlag flags, double data[]) const;
void check_AOutSetTrigger_Args(TriggerType trigType, int trigChan, double level, double variance, unsigned int retriggerCount) const;
protected:
AoInfo mAoInfo;
AoConfig* mAoConfig;
std::vector<CalCoef> mCalCoefs;
unsigned long long mCalDate; // cal date in sec
};
} /* namespace ul */
#endif /* AODEVICE_H_ */

249
src/AoInfo.cpp Normal file
View File

@ -0,0 +1,249 @@
/*
* AoInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "AoInfo.h"
#include <algorithm>
namespace ul
{
AoInfo::AoInfo()
{
mNumChans = 0;
mResolution = 0;
mMinScanRate = 0;
mMaxScanRate = 0;
mMaxThroughput = 0;
mScanOptions = SO_DEFAULTIO;
mFifoSize = 0;
mHasPacer = 0;
mCalCoefsCount = 0;
mCalCoefsStartAddr = -1;
mCalDateAddr = -1;
mSampleSize = 0;
mAOutFlags = 0;
mAOutScanFlags = 0;
mTriggerTypes = TRIG_NONE;
}
AoInfo::~AoInfo()
{
}
void AoInfo::setNumChans(int numChans)
{
mNumChans = numChans;
}
int AoInfo::getNumChans() const
{
return mNumChans;
}
void AoInfo::setResolution(int resolution)
{
mResolution = resolution;
}
int AoInfo::getResolution() const
{
return mResolution;
}
void AoInfo::setMinScanRate(double minRate)
{
mMinScanRate = minRate;
}
double AoInfo::getMinScanRate() const
{
return mMinScanRate;
}
void AoInfo::setMaxScanRate(double maxRate)
{
mMaxScanRate = maxRate;
}
double AoInfo::getMaxScanRate() const
{
return mMaxScanRate;
}
void AoInfo::setMaxThroughput(double maxThroughput)
{
mMaxThroughput = maxThroughput;
}
double AoInfo::getMaxThroughput() const
{
return mMaxThroughput;
}
void AoInfo::setFifoSize(int size)
{
mFifoSize = size;
}
int AoInfo::getFifoSize() const
{
return mFifoSize;
}
void AoInfo::setScanOptions(long long options)
{
mScanOptions = (ScanOption) options;
}
ScanOption AoInfo::getScanOptions() const
{
return mScanOptions;
}
void AoInfo::setAOutFlags(long long flags)
{
mAOutFlags = flags;
}
long long AoInfo::getAOutFlags() const
{
return mAOutFlags;
}
void AoInfo::setAOutScanFlags(long long flags)
{
mAOutScanFlags = flags;
}
long long AoInfo::getAOutScanFlags() const
{
return mAOutScanFlags;
}
void AoInfo::addRange(Range range)
{
mRanges.push_back(range);
}
std::vector<Range> AoInfo::getRanges() const
{
return mRanges;
}
void AoInfo::getRanges(Range ranges[], int* count) const
{
if(mRanges.size() <= (unsigned int)*count )
std::copy(mRanges.begin(), mRanges.end(), ranges);
*count = mRanges.size();
}
int AoInfo::getRangeCount() const
{
return getRanges().size();
}
Range AoInfo::getRange(unsigned int index) const
{
Range range = (Range) 0;
if(index < getRanges().size())
{
range = getRanges().at(index);
}
return range;
}
void AoInfo::setTriggerTypes(long long triggerTypes)
{
mTriggerTypes = (TriggerType) triggerTypes;
}
TriggerType AoInfo::getTriggerTypes() const
{
return mTriggerTypes;
}
bool AoInfo::supportsTrigger() const
{
bool supportsTrig = false;
if(mTriggerTypes)
supportsTrig = true;
return supportsTrig;
}
bool AoInfo::hasPacer() const
{
return mHasPacer;
}
void AoInfo::hasPacer(bool hasPacer)
{
mHasPacer = hasPacer;
}
void AoInfo::setCalCoefCount(int count)
{
mCalCoefsCount = count;
}
int AoInfo::getCalCoefCount() const
{
return mCalCoefsCount;
}
void AoInfo::setCalCoefsStartAddr(int count)
{
mCalCoefsStartAddr = count;
}
int AoInfo::getCalCoefsStartAddr() const
{
return mCalCoefsStartAddr;
}
void AoInfo::setCalDateAddr(int addr)
{
mCalDateAddr = addr;
}
int AoInfo::getCalDateAddr() const
{
return mCalDateAddr;
}
void AoInfo::setSampleSize(int size)
{
mSampleSize = size;
}
int AoInfo::getSampleSize() const
{
return mSampleSize;
}
bool AoInfo::isRangeSupported(Range range) const
{
bool supported = false;
std::vector<Range> ranges = getRanges();
if(!ranges.empty())
{
std::vector<Range>::const_iterator itr = std::find(ranges.begin(), ranges.end(), range);
if(itr != ranges.end())
supported = true;
}
return supported;
}
} /* namespace ul */

96
src/AoInfo.h Normal file
View File

@ -0,0 +1,96 @@
/*
* AoInfo.h
*
* Created on: Oct 26, 2017
* Author: Measurement Computing Corporation
*/
#ifndef AOINFO_H_
#define AOINFO_H_
#include "ul_internal.h"
#include <vector>
#include "interfaces/UlAoInfo.h"
namespace ul
{
class UL_LOCAL AoInfo: public UlAoInfo
{
public:
AoInfo();
virtual ~AoInfo();
void addRange(Range range);
std::vector<Range> getRanges() const;
void setNumChans(int numChans);
int getNumChans() const;
void setResolution(int resolution);
int getResolution() const;
void setMinScanRate(double minRate);
double getMinScanRate() const;
void setMaxScanRate(double maxRate);
double getMaxScanRate() const;
void setMaxThroughput(double maxThroughput);
double getMaxThroughput() const;
void setFifoSize(int size);
int getFifoSize() const;
void setScanOptions(long long options);
ScanOption getScanOptions() const;
void setAOutFlags(long long flags);
long long getAOutFlags() const;
void setAOutScanFlags(long long flags);
long long getAOutScanFlags() const;
bool hasPacer() const;
void hasPacer(bool hasPacer);
void setTriggerTypes(long long triggerTypes);
TriggerType getTriggerTypes() const;
bool supportsTrigger() const;
void getRanges(Range ranges[], int* count) const;
int getRangeCount() const;
Range getRange(unsigned int index) const;
void setCalCoefCount(int count);
int getCalCoefCount() const;
void setCalCoefsStartAddr(int count);
int getCalCoefsStartAddr() const;
void setCalDateAddr(int addr);
int getCalDateAddr() const;
void setSampleSize(int size);
int getSampleSize() const;
bool isRangeSupported(Range range) const;
private:
std::vector<Range> mRanges;
TriggerType mTriggerTypes;
int mNumChans;
int mResolution;
double mMinScanRate;
double mMaxScanRate;
double mMaxThroughput;
ScanOption mScanOptions;
int mFifoSize;
bool mHasPacer;
int mCalCoefsCount;
int mCalCoefsStartAddr;
int mCalDateAddr;
int mSampleSize;
long long mAOutFlags;
long long mAOutScanFlags;
};
} /* namespace ul */
#endif /* AOINFO_H_ */

302
src/CtrDevice.cpp Normal file
View File

@ -0,0 +1,302 @@
/*
* CtrDevice.cpp
*
* Author: Measurement Computing Corporation
*/
#include "CtrDevice.h"
#include <algorithm>
#include <bitset>
#include "UlException.h"
namespace ul
{
CtrDevice::CtrDevice(const DaqDevice& daqDevice) : IoDevice(daqDevice), UlCtrDevice()
{
}
CtrDevice::~CtrDevice()
{
}
unsigned long long CtrDevice::cIn(int ctrNum)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void CtrDevice::cLoad(int ctrNum, CounterRegisterType regType, unsigned long long loadValue)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void CtrDevice::cClear(int ctrNum)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
unsigned long long CtrDevice::cRead(int ctrNum, CounterRegisterType regType)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
double CtrDevice::cInScan(int lowCtrNum, int highCtrNum, int samplesPerCounter, double rate, ScanOption options, CInScanFlag flags, unsigned long long data[])
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void CtrDevice::cConfigScan(int ctrNum, CounterMeasurementType measureType, CounterMeasurementMode measureMode,
CounterEdgeDetection edgeDetection, CounterTickSize tickSize,
CounterDebounceMode debounceMode, CounterDebounceTime debounceTime, CConfigScanFlag flag)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void CtrDevice::setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount)
{
check_CtrSetTrigger_Args(type, trigChan, level, variance, retriggerCount);
mTrigCfg.type = type;
mTrigCfg.trigChan = trigChan;
mTrigCfg.level = level;
mTrigCfg.variance = variance;
mTrigCfg.retrigCount = retriggerCount;
}
UlError CtrDevice::getStatus(ScanStatus* status, TransferStatus* xferStatus)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void CtrDevice::stopBackground()
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void CtrDevice::initScanCountersState()
{
mScanCtrActive.clear();
for(int ctrNum = 0; ctrNum < mCtrInfo.getNumCtrs(); ctrNum++)
mScanCtrActive.push_back(false);
}
void CtrDevice::setScanCounterActive(int ctrNum)
{
if(ctrNum < mCtrInfo.getNumCtrs())
mScanCtrActive[ctrNum] = true;
}
void CtrDevice::setScanCountersInactive()
{
for(unsigned int ctrNum = 0; ctrNum < mScanCtrActive.size(); ctrNum++)
mScanCtrActive[ctrNum] = false;
}
bool CtrDevice::isScanCounterActive(int ctrNum) const
{
bool active = true;
if(ctrNum < mCtrInfo.getNumCtrs())
active = mScanCtrActive[ctrNum];
return active;
}
void CtrDevice::check_CIn_Args(int ctrNum) const
{
if(ctrNum < 0 || ctrNum >= mCtrInfo.getNumCtrs())
throw UlException(ERR_BAD_CTR);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void CtrDevice::check_CLoad_Args(int ctrNum, CounterRegisterType regType, unsigned long long loadValue) const
{
if(ctrNum < 0 || ctrNum >= mCtrInfo.getNumCtrs())
throw UlException(ERR_BAD_CTR);
unsigned long long maxCtrVal = (1ULL << mCtrInfo.getResolution()) - 1;
if(loadValue > maxCtrVal)
throw UlException(ERR_BAD_CTR_VAL);
std::bitset<32> typeBitSet(regType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_CTR_REG);
if(!(mCtrInfo.getRegisterTypes() & regType) || regType == CRT_COUNT)
throw UlException(ERR_BAD_CTR_REG);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void CtrDevice::check_CClear_Args(int ctrNum) const
{
if(ctrNum < 0 || ctrNum >= mCtrInfo.getNumCtrs())
throw UlException(ERR_BAD_CTR);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void CtrDevice::check_CRead_Args(int ctrNum, CounterRegisterType regType) const
{
if(ctrNum < 0 || ctrNum >= mCtrInfo.getNumCtrs())
throw UlException(ERR_BAD_CTR);
std::bitset<32> typeBitSet(regType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_CTR_REG);
if(!(mCtrInfo.getRegisterTypes() & regType) || regType == CRT_LOAD)
throw UlException(ERR_BAD_CTR_REG);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void CtrDevice::check_CInScan_Args(int lowCtrNum, int highCtrNum, int samplesPerCounter, double rate, ScanOption options, CInScanFlag flags, unsigned long long data[]) const
{
int numOfScanCtr = highCtrNum - lowCtrNum + 1;
if(!mCtrInfo.hasPacer())
throw UlException(ERR_BAD_DEV_TYPE);
if(getScanState() == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(((options & SO_SINGLEIO) && (options & SO_BLOCKIO)) || ((options & SO_SINGLEIO) && (options & SO_BURSTIO)) || ((options & SO_BLOCKIO) && (options & SO_BURSTIO)))
throw UlException(ERR_BAD_OPTION);
if(lowCtrNum < 0 || highCtrNum < 0 || lowCtrNum > mCtrInfo.getNumCtrs() || highCtrNum > mCtrInfo.getNumCtrs() || lowCtrNum > highCtrNum )
throw UlException(ERR_BAD_CTR);
if(data == NULL)
throw UlException(ERR_BAD_BUFFER);
if(~mCtrInfo.getScanOptions() & options)
throw UlException(ERR_BAD_OPTION);
if(~mCtrInfo.getCInScanFlags() & flags)
throw UlException(ERR_BAD_FLAG);
if(((flags & CINSCAN_FF_CTR16_BIT) && (flags & CINSCAN_FF_CTR32_BIT)) ||
((flags & CINSCAN_FF_CTR16_BIT) && (flags & CINSCAN_FF_CTR64_BIT)) ||
((flags & CINSCAN_FF_CTR32_BIT) && (flags & CINSCAN_FF_CTR64_BIT)))
throw UlException(ERR_BAD_FLAG);
double throughput = rate * numOfScanCtr;
if(!(options & SO_EXTCLOCK))
{
if(((options & SO_BURSTIO) && (rate > mCtrInfo.getMaxBurstRate() || throughput > mCtrInfo.getMaxBurstThroughput())) || (!(options & SO_BURSTIO) && (rate > mCtrInfo.getMaxScanRate() || throughput > mCtrInfo.getMaxThroughput())) )
throw UlException(ERR_BAD_RATE);
}
if(rate <= 0.0)
throw UlException(ERR_BAD_RATE);
if(samplesPerCounter < mMinScanSampleCount)
throw UlException(ERR_BAD_SAMPLE_COUNT);
long totalCount = samplesPerCounter * numOfScanCtr;
if(options & SO_BURSTIO)
{
int sampleSize = mCtrInfo.getResolution() / 8;
if(flags & CINSCAN_FF_CTR16_BIT)
sampleSize = 2;
else if(flags & CINSCAN_FF_CTR32_BIT)
sampleSize = 4;
else if(flags & CINSCAN_FF_CTR64_BIT)
sampleSize = 8;
if(totalCount > (mCtrInfo.getFifoSize() / sampleSize))
throw UlException(ERR_BAD_BURSTIO_COUNT);
else if (options & SO_CONTINUOUS)
throw UlException(ERR_BAD_OPTION);
}
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void CtrDevice::check_CConfigScan_Args(int ctrNum, CounterMeasurementType measureType, CounterMeasurementMode measureMode,
CounterEdgeDetection edgeDetection, CounterTickSize tickSize,
CounterDebounceMode debounceMode, CounterDebounceTime debounceTime, CConfigScanFlag flag) const
{
if(ctrNum < 0 || ctrNum >= mCtrInfo.getNumCtrs())
throw UlException(ERR_BAD_CTR);
if(getScanState() == SS_RUNNING && isScanCounterActive(ctrNum))
{
throw UlException(ERR_ALREADY_ACTIVE);
}
if(!(mCtrInfo.getCtrMeasurementTypes(ctrNum) & measureType))
throw UlException(ERR_BAD_CTR_MEASURE_TYPE);
if((measureMode != CMM_DEFAULT) && !(mCtrInfo.getCtrMeasurementModes(measureType) & measureMode))
throw UlException(ERR_BAD_CTR_MEASURE_MODE);
if(edgeDetection < CED_RISING_EDGE || edgeDetection > CED_FALLING_EDGE)
throw UlException(ERR_BAD_EDGE_DETECTION);
if(debounceMode < CDM_NONE || debounceMode > CDM_TRIGGER_BEFORE_STABLE)
throw UlException(ERR_BAD_DEBOUNCE_MODE);
if(debounceMode != CDM_NONE)
{
if (debounceTime == CDT_DEBOUNCE_0ns)
throw UlException(ERR_BAD_DEBOUNCE_TIME);
std::vector<CounterDebounceTime> debounceTimes = mCtrInfo.getDebounceTimes();
if(std::find(debounceTimes.begin(), debounceTimes.end(), debounceTime) == debounceTimes.end())
throw UlException(ERR_BAD_DEBOUNCE_TIME);
}
if(measureType == CMT_PERIOD || measureType == CMT_PULSE_WIDTH || measureType == CMT_TIMING)
{
std::vector<CounterTickSize> tickSizes = mCtrInfo.getTickSizes();
if(std::find(tickSizes.begin(), tickSizes.end(), tickSize) == tickSizes.end())
{
throw UlException(ERR_BAD_TICK_SIZE);
}
}
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void CtrDevice::check_CtrSetTrigger_Args(TriggerType trigType, int trigChan, double level, double variance, unsigned int retriggerCount) const
{
if(mCtrInfo.supportsTrigger())
{
if(!(mCtrInfo.getTriggerTypes() & trigType))
throw UlException(ERR_BAD_TRIG_TYPE);
std::bitset<32> typeBitSet(trigType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_TRIG_TYPE);
if(retriggerCount > 0 && !(mCtrInfo.getScanOptions() & SO_RETRIGGER))
throw UlException(ERR_BAD_RETRIG_COUNT);
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
} /* namespace ul */

68
src/CtrDevice.h Normal file
View File

@ -0,0 +1,68 @@
/*
* CtrDevice.h
*
* Created on: Nov 8, 2017
* Author: Measurement Computing Corporation
*/
#ifndef CTRDEVICE_H_
#define CTRDEVICE_H_
#include "IoDevice.h"
#include "CtrInfo.h"
#include "interfaces/UlCtrDevice.h"
namespace ul
{
class UL_LOCAL CtrDevice: public IoDevice, public UlCtrDevice
{
public:
CtrDevice(const DaqDevice& daqDevice);
virtual ~CtrDevice();
virtual const UlCtrInfo& getCtrInfo() { return mCtrInfo;}
virtual unsigned long long cIn(int ctrNum);
virtual void cLoad(int ctrNum, CounterRegisterType regType, unsigned long long loadValue);
virtual void cClear(int ctrNum);
virtual unsigned long long cRead(int ctrNum, CounterRegisterType regType);
virtual double cInScan(int lowCtrNum, int highCtrNum, int samplesPerCounter, double rate, ScanOption options, CInScanFlag flags, unsigned long long data[]);
virtual void cConfigScan(int ctrNum, CounterMeasurementType measureType, CounterMeasurementMode measureMode,
CounterEdgeDetection edgeDetection, CounterTickSize tickSize,
CounterDebounceMode debounceMode, CounterDebounceTime debounceTime, CConfigScanFlag flag);
virtual void setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount);
virtual UlError getStatus(ScanStatus* status, TransferStatus* xferStatus);
virtual void stopBackground();
void initScanCountersState();
void setScanCounterActive(int ctrNum);
void setScanCountersInactive();
bool isScanCounterActive(int ctrNum) const;
protected:
void check_CIn_Args(int ctrNum) const;
void check_CLoad_Args(int ctrNum, CounterRegisterType regType, unsigned long long loadValue) const;
void check_CClear_Args(int ctrNum) const;
void check_CRead_Args(int ctrNum, CounterRegisterType regType) const;
void check_CInScan_Args(int lowCtr, int highCtr, int samplesPerCounter, double rate, ScanOption options, CInScanFlag flags, unsigned long long data[]) const;
void check_CConfigScan_Args(int ctrNum, CounterMeasurementType measureType, CounterMeasurementMode measureMode,
CounterEdgeDetection edgeDetection, CounterTickSize tickSize,
CounterDebounceMode debounceMode, CounterDebounceTime debounceTime, CConfigScanFlag flag) const;
void check_CtrSetTrigger_Args(TriggerType trigtype, int trigChan, double level, double variance, unsigned int retriggerCount) const;
protected:
CtrInfo mCtrInfo;
private:
std::vector<bool> mScanCtrActive;
};
} /* namespace ul */
#endif /* CTRDEVICE_H_ */

232
src/CtrInfo.cpp Normal file
View File

@ -0,0 +1,232 @@
/*
* CtrInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "CtrInfo.h"
#include <algorithm>
namespace ul
{
CtrInfo::CtrInfo()
{
mNumCtrs = 0;
mResolution = 0;
mMinScanRate = 0;
mMaxScanRate = 0;
mMaxThroughput = 0;
mMaxBurstRate = 0;
mMaxBurstThroughput = 0;
mScanOptions = SO_DEFAULTIO;
mCInScanFlags = 0;
mFifoSize = 0;
mHasPacer = 0;
mTriggerTypes = TRIG_NONE;
mCtrRegTypes = CRT_COUNT;
}
CtrInfo::~CtrInfo()
{
}
void CtrInfo::addCtr(unsigned long long measureTypeMask)
{
mCtrMeasureTypeMasks.push_back(measureTypeMask);
}
int CtrInfo::getNumCtrs() const
{
return mCtrMeasureTypeMasks.size();
}
unsigned long long CtrInfo::getCtrMeasurementTypes(unsigned int ctrNum) const
{
unsigned long long type = 0;
if(ctrNum < mCtrMeasureTypeMasks.size())
type = mCtrMeasureTypeMasks[ctrNum];
return type;
}
void CtrInfo::setCtrMeasurementModes(CounterMeasurementType type ,long long mode)
{
mCtrMeasureModes.insert(std::pair<CounterMeasurementType,CounterMeasurementMode>(type, (CounterMeasurementMode) mode));
}
CounterMeasurementMode CtrInfo::getCtrMeasurementModes(CounterMeasurementType type) const
{
CounterMeasurementMode mode = (CounterMeasurementMode) 0;
std::map<CounterMeasurementType,CounterMeasurementMode>::iterator itr = mCtrMeasureModes.find(type);
if(itr != mCtrMeasureModes.end())
mode = mCtrMeasureModes[type];
return mode;
}
void CtrInfo::setResolution(int resolution)
{
mResolution = resolution;
}
int CtrInfo::getResolution() const
{
return mResolution;
}
void CtrInfo::setMinScanRate(double minRate)
{
mMinScanRate = minRate;
}
double CtrInfo::getMinScanRate() const
{
return mMinScanRate;
}
void CtrInfo::setMaxScanRate(double maxRate)
{
mMaxScanRate = maxRate;
}
double CtrInfo::getMaxScanRate() const
{
return mMaxScanRate;
}
void CtrInfo::setMaxThroughput(double maxThroughput)
{
mMaxThroughput = maxThroughput;
}
double CtrInfo::getMaxThroughput() const
{
return mMaxThroughput;
}
void CtrInfo::setMaxBurstThroughput(double maxThroughput)
{
mMaxBurstThroughput = maxThroughput;
}
double CtrInfo::getMaxBurstThroughput() const
{
return mMaxBurstThroughput;
}
void CtrInfo::setMaxBurstRate(double maxRate)
{
mMaxBurstRate = maxRate;
}
double CtrInfo::getMaxBurstRate() const
{
return mMaxBurstRate;
}
void CtrInfo::setFifoSize(int size)
{
mFifoSize = size;
}
int CtrInfo::getFifoSize() const
{
return mFifoSize;
}
void CtrInfo::setScanOptions(long long options)
{
mScanOptions = (ScanOption) options;
}
ScanOption CtrInfo::getScanOptions() const
{
return mScanOptions;
}
/*
void CtrInfo::addTriggerType(TriggerType triggerType)
{
mTriggerTypes.push_back(triggerType);
}*/
void CtrInfo::setCInScanFlags(long long flags)
{
mCInScanFlags = flags;
}
long long CtrInfo::getCInScanFlags() const
{
return mCInScanFlags;
}
void CtrInfo::setTriggerTypes(long long triggerTypes)
{
mTriggerTypes = (TriggerType) triggerTypes;
}
TriggerType CtrInfo::getTriggerTypes() const
{
return mTriggerTypes;
}
bool CtrInfo::supportsTrigger() const
{
bool supportsTrig = false;
if(mTriggerTypes)
supportsTrig = true;
return supportsTrig;
}
void CtrInfo::setRegisterTypes(long long registerTypes)
{
mCtrRegTypes = (CounterRegisterType) registerTypes;
}
CounterRegisterType CtrInfo::getRegisterTypes() const
{
return mCtrRegTypes;
}
void CtrInfo::addDebounceTime(CounterDebounceTime debounceTime)
{
mCtrDebounceTimes.push_back(debounceTime);
}
std::vector<CounterDebounceTime> CtrInfo::getDebounceTimes() const
{
return mCtrDebounceTimes;
}
void CtrInfo::addTickSize(CounterTickSize tickSize)
{
mCtrTickSizes.push_back(tickSize);
}
std::vector<CounterTickSize> CtrInfo::getTickSizes() const
{
return mCtrTickSizes;
}
bool CtrInfo::hasPacer() const
{
return mHasPacer;
}
void CtrInfo::hasPacer(bool hasPacer)
{
mHasPacer = hasPacer;
}
} /* namespace ul */

87
src/CtrInfo.h Normal file
View File

@ -0,0 +1,87 @@
/*
* CtrInfo.h
*
* Created on: Nov 8, 2017
* Author: Measurement Computing Corporation
*/
#ifndef CTRINFO_H_
#define CTRINFO_H_
#include "ul_internal.h"
#include <vector>
#include <map>
#include "interfaces/UlCtrInfo.h"
namespace ul
{
class UL_LOCAL CtrInfo: public UlCtrInfo
{
public:
CtrInfo();
virtual ~CtrInfo();
void addCtr(unsigned long long measureTypeMask);
int getNumCtrs() const;
unsigned long long getCtrMeasurementTypes(unsigned int ctrNum) const;
void setCtrMeasurementModes(CounterMeasurementType type ,long long mode);
CounterMeasurementMode getCtrMeasurementModes(CounterMeasurementType type) const;
void setResolution(int resolution);
int getResolution() const;
void setMinScanRate(double minRate);
double getMinScanRate() const;
void setMaxScanRate(double maxRate);
double getMaxScanRate() const;
void setMaxThroughput(double maxThroughput);
double getMaxThroughput() const;
void setMaxBurstThroughput(double maxThroughput);
double getMaxBurstThroughput() const;
void setMaxBurstRate(double maxRate);
double getMaxBurstRate() const;
void setFifoSize(int size);
int getFifoSize() const;
void setScanOptions(long long options);
ScanOption getScanOptions() const;
void setCInScanFlags(long long flags);
long long getCInScanFlags() const;
void setRegisterTypes(long long registerTypes);
CounterRegisterType getRegisterTypes() const;
void addDebounceTime(CounterDebounceTime debounceTime);
std::vector<CounterDebounceTime> getDebounceTimes() const;
void addTickSize(CounterTickSize tickSize);
std::vector<CounterTickSize> getTickSizes() const;
bool hasPacer() const;
void hasPacer(bool hasPacer);
void setTriggerTypes(long long triggerTypes);
TriggerType getTriggerTypes() const;
bool supportsTrigger() const;
private:
std::vector<unsigned long long> mCtrMeasureTypeMasks;
mutable std::map<CounterMeasurementType,CounterMeasurementMode> mCtrMeasureModes;
CounterRegisterType mCtrRegTypes;
TriggerType mTriggerTypes;
std::vector<CounterDebounceTime> mCtrDebounceTimes;
std::vector<CounterTickSize> mCtrTickSizes;
int mNumCtrs;
int mResolution;
double mMinScanRate;
double mMaxScanRate;
double mMaxThroughput;
double mMaxBurstRate;
double mMaxBurstThroughput;
ScanOption mScanOptions;
long long mCInScanFlags;
int mFifoSize;
bool mHasPacer;
};
} /* namespace ul */
#endif /* CTRINFO_H_ */

677
src/DaqDevice.cpp Normal file
View File

@ -0,0 +1,677 @@
/*
* DaqDeviceInternal.cpp
*
* Author: Measurement Computing Corporation
*/
#include <sstream>
#include "DaqDevice.h"
#include "DaqDeviceManager.h"
#include "utility/EuScale.h"
#include "utility/UlLock.h"
#include "AiDevice.h"
#include "AoDevice.h"
#include "DioDevice.h"
#include "CtrDevice.h"
#include "TmrDevice.h"
#include "DaqIDevice.h"
#include "DaqODevice.h"
#include "DaqEventHandler.h"
#include "UlException.h"
namespace ul
{
pthread_mutex_t DaqDevice::mDeviceNumberMutex = PTHREAD_MUTEX_INITIALIZER;
unsigned long long DaqDevice::mNextAvailableDeviceNumber = 1;
DaqDevice::DaqDevice(DaqDeviceDescriptor daqDeviceDescriptor): mDaqDeviceDescriptor(daqDeviceDescriptor), mConnected(false),
mAiDevice(NULL), mAoDevice(NULL), mDioDevice(NULL), mCtrDevice(NULL), mTmrDevice(NULL), mDaqIDevice(NULL), mDaqODevice(NULL)
{
mEventHandler = new DaqEventHandler(*this);
mDaqDeviceConfig = new DaqDeviceConfig(*this);
mDaqDeviceInfo.setProductId(daqDeviceDescriptor.productId);
mRawFwVersion = 0;
mRawFpgaVersion = 0;
mRawRadioVersion = 0;
mMemUnlockAddr = -1;
mMemUnlockCode = 0;
mCurrentSuspendCount = 0;
pthread_mutex_lock(&mDeviceNumberMutex);
mDeviceNumber = mNextAvailableDeviceNumber;
mNextAvailableDeviceNumber++;
pthread_mutex_unlock(&mDeviceNumberMutex);
}
DaqDevice::~DaqDevice()
{
if(mAiDevice != NULL)
{
delete mAiDevice;
mAiDevice = NULL;
}
if(mAoDevice != NULL)
{
delete mAoDevice;
mAoDevice = NULL;
}
if(mDioDevice != NULL)
{
delete mDioDevice;
mDioDevice = NULL;
}
if(mCtrDevice != NULL)
{
delete mCtrDevice;
mCtrDevice = NULL;
}
if(mTmrDevice != NULL)
{
delete mTmrDevice;
mTmrDevice = NULL;
}
if(mDaqIDevice != NULL)
{
delete mDaqIDevice;
mDaqIDevice = NULL;
}
if(mDaqODevice != NULL)
{
delete mDaqODevice;
mDaqODevice = NULL;
}
if(mDaqDeviceConfig != NULL)
{
delete mDaqDeviceConfig;
mDaqDeviceConfig = NULL;
}
if(mEventHandler !=NULL)
{
delete mEventHandler;
mEventHandler = NULL;
}
DaqDeviceManager::removeFromCreatedList(mDeviceNumber);
}
DaqDeviceDescriptor DaqDevice::getDescriptor() const
{
return mDaqDeviceDescriptor;
}
void DaqDevice::disconnect()
{
mEventHandler->stop();
disconnectIoDevices();
mConnected = false;
}
double DaqDevice::getClockFreq() const
{
return mDaqDeviceInfo.getClockFreq();
}
void DaqDevice::addMemRegion(MemRegion memRegionType, unsigned long long address, unsigned long long size, long long accessTypes)
{
mDaqDeviceInfo.memInfo()->addMemRegion(memRegionType, address, size, (MemAccessType) accessTypes);
}
void DaqDevice::setAiDevice(AiDevice* aiDevice)
{
mAiDevice = aiDevice;
if(aiDevice != NULL)
mDaqDeviceInfo.hasAiDevice(true);
}
AiDevice* DaqDevice::aiDevice() const
{
return mAiDevice;
}
UlAiDevice& DaqDevice::getAiDevice() const
{
return *mAiDevice;
}
void DaqDevice::setAoDevice(AoDevice* aoDevice)
{
mAoDevice = aoDevice;
if(aoDevice != NULL)
mDaqDeviceInfo.hasAoDevice(true);
}
AoDevice* DaqDevice::aoDevice() const
{
return mAoDevice;
}
UlAoDevice& DaqDevice::getAoDevice() const
{
return *mAoDevice;
}
void DaqDevice::setDioDevice(DioDevice* dioDevice)
{
mDioDevice = dioDevice;
if(dioDevice != NULL)
mDaqDeviceInfo.hasDioDevice(true);
}
DioDevice* DaqDevice::dioDevice() const
{
return mDioDevice;
}
UlDioDevice& DaqDevice::getDioDevice() const
{
return *mDioDevice;
}
UlCtrDevice& DaqDevice::getCtrDevice() const
{
return *mCtrDevice;
}
void DaqDevice::setCtrDevice(CtrDevice* ctrDevice)
{
mCtrDevice = ctrDevice;
if(ctrDevice != NULL)
mDaqDeviceInfo.hasCtrDevice(true);
}
CtrDevice* DaqDevice::ctrDevice() const
{
return mCtrDevice;
}
UlTmrDevice& DaqDevice::getTmrDevice() const
{
return *mTmrDevice;
}
void DaqDevice::setTmrDevice(TmrDevice* tmrDevice)
{
mTmrDevice = tmrDevice;
if(tmrDevice != NULL)
mDaqDeviceInfo.hasTmrDevice(true);
}
TmrDevice* DaqDevice::tmrDevice() const
{
return mTmrDevice;
}
UlDaqIDevice& DaqDevice::getDaqIDevice() const
{
return *mDaqIDevice;
}
void DaqDevice::setDaqIDevice(DaqIDevice* daqIDevice)
{
mDaqIDevice = daqIDevice;
if(daqIDevice != NULL)
mDaqDeviceInfo.hasDaqIDevice(true);
}
DaqIDevice* DaqDevice::daqIDevice() const
{
return mDaqIDevice;
}
UlDaqODevice& DaqDevice::getDaqODevice() const
{
return *mDaqODevice;
}
void DaqDevice::setDaqODevice(DaqODevice* daqODevice)
{
mDaqODevice = daqODevice;
if(daqODevice != NULL)
mDaqDeviceInfo.hasDaqODevice(true);
}
DaqODevice* DaqDevice::daqODevice() const
{
return mDaqODevice;
}
DaqEventHandler* DaqDevice::eventHandler() const
{
return mEventHandler;
}
void DaqDevice::initializeIoDevices()
{
if(mAiDevice != NULL)
mAiDevice->initialize();
if(mAoDevice != NULL)
mAoDevice->initialize();
if(mDioDevice != NULL)
mDioDevice->initialize();
if(mCtrDevice != NULL)
mCtrDevice->initialize();
if(mTmrDevice != NULL)
mTmrDevice->initialize();
if(mDaqIDevice != NULL)
mDaqIDevice->initialize();
if(mDaqODevice != NULL)
mDaqODevice->initialize();
}
void DaqDevice::reconfigureIoDevices()
{
if(mAiDevice != NULL)
mAiDevice->reconfigure();
if(mAoDevice != NULL)
mAoDevice->reconfigure();
if(mDioDevice != NULL)
mDioDevice->reconfigure();
if(mCtrDevice != NULL)
mCtrDevice->reconfigure();
if(mTmrDevice != NULL)
mTmrDevice->reconfigure();
if(mDaqIDevice != NULL)
mDaqIDevice->reconfigure();
if(mDaqODevice != NULL)
mDaqODevice->reconfigure();
}
void DaqDevice::disconnectIoDevices()
{
try
{
if(mAiDevice != NULL)
mAiDevice->disconnect();
if(mAoDevice != NULL)
mAoDevice->disconnect();
if(mDioDevice != NULL)
mDioDevice->disconnect();
if(mCtrDevice != NULL)
mCtrDevice->disconnect();
if(mDaqIDevice != NULL)
mDaqIDevice->disconnect();
if(mDaqODevice != NULL)
mDaqODevice->disconnect();
}
catch(UlException& e)
{
UL_LOG("Ul exception occurred: " << e.what());
}
}
bool DaqDevice::isScanRunning() const
{
bool running = false;
if(mAiDevice != NULL && mAiDevice->getScanState() == SS_RUNNING)
running = true;
else if(mAoDevice != NULL && mAoDevice->getScanState() == SS_RUNNING)
running = true;
else if(mDioDevice != NULL && mDioDevice->getScanState(SD_INPUT) == SS_RUNNING)
running = true;
else if(mDioDevice != NULL && mDioDevice->getScanState(SD_OUTPUT) == SS_RUNNING)
running = true;
else if(mCtrDevice != NULL && mCtrDevice->getScanState() == SS_RUNNING)
running = true;
else if(mDaqIDevice != NULL && mDaqIDevice->getScanState() == SS_RUNNING)
running = true;
else if(mDaqODevice != NULL && mDaqODevice->getScanState() == SS_RUNNING)
running = true;
return running;
}
bool DaqDevice::isScanRunning(FunctionType functionType) const
{
bool running = false;
IoDevice* ioDevice = NULL;
switch(functionType)
{
case FT_AI:
ioDevice = mAiDevice;
break;
case FT_AO:
ioDevice = mAoDevice;
break;
case FT_DI:
case FT_DO:
ioDevice = mDioDevice;
break;
case FT_CTR:
ioDevice = mCtrDevice;
break;
case FT_DAQI:
ioDevice = mDaqIDevice;
break;
case FT_DAQO:
ioDevice = mDaqODevice;
break;
default:
break;
}
if(ioDevice != NULL && ioDevice->getScanState() == SS_RUNNING)
running = true;
return running;
}
void DaqDevice::stopBackground(FunctionType functionType) const
{
IoDevice* ioDevice = NULL;
switch(functionType)
{
case FT_AI:
ioDevice = mAiDevice;
break;
case FT_AO:
ioDevice = mAoDevice;
break;
case FT_DI:
case FT_DO:
ioDevice = mDioDevice;
break;
case FT_CTR:
ioDevice = mCtrDevice;
break;
case FT_DAQI:
ioDevice = mDaqIDevice;
break;
case FT_DAQO:
ioDevice = mDaqODevice;
break;
default:
break;
}
if(ioDevice != NULL)
ioDevice->stopBackground();
else
std::cout << "########## stopBackground not implemented" << std::endl;
}
IoDevice* DaqDevice::getIoDevice(FunctionType functionType) const
{
IoDevice* ioDevice = NULL;
switch(functionType)
{
case FT_AI:
ioDevice = mAiDevice;
break;
case FT_AO:
ioDevice = mAoDevice;
break;
case FT_DI:
case FT_DO:
ioDevice = mDioDevice;
break;
case FT_CTR:
ioDevice = mCtrDevice;
break;
case FT_TMR:
ioDevice = mTmrDevice;
break;
case FT_DAQI:
ioDevice = mDaqIDevice;
break;
case FT_DAQO:
ioDevice = mDaqODevice;
break;
default:
break;
}
if(ioDevice == NULL)
std::cout << "########## getIoDevice not implemented" << std::endl;
return ioDevice;
}
TriggerConfig DaqDevice::getTriggerConfig(FunctionType functionType) const
{
TriggerConfig trigCfg;
if(functionType == FT_AI && mAiDevice)
trigCfg = mAiDevice->getTrigConfig();
else if(functionType == FT_AO && mAiDevice)
trigCfg = mAoDevice->getTrigConfig();
else if(functionType == FT_DI && mDioDevice)
trigCfg = mDioDevice->getTrigConfig(SD_INPUT);
else if(functionType == FT_DO && mDioDevice)
trigCfg = mDioDevice->getTrigConfig(SD_OUTPUT);
else if(functionType == FT_CTR && mCtrDevice)
trigCfg = mCtrDevice->getTrigConfig();
else if(functionType == FT_TMR && mTmrDevice)
trigCfg = mTmrDevice->getTrigConfig();
else if(functionType == FT_DAQI && mDaqIDevice)
trigCfg = mDaqIDevice->getTrigConfig();
else if(functionType == FT_DAQO && mDaqODevice)
trigCfg = mDaqODevice->getTrigConfig();
return trigCfg;
}
void DaqDevice::checkConnection() const
{
if(!mConnected)
{
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
}
void DaqDevice::getEuScaling(Range range, double &scale, double &offset) const
{
EuScale::getEuScaling(range, scale, offset);
}
void DaqDevice::flashLed(int flashCount) const
{
throw UlException(ERR_BAD_DEV_TYPE);
}
////////////////////// Configuration functions /////////////////////////////////
void DaqDevice::getCfg_FwVersionStr(char* fwVerStr, unsigned int* maxStrLen) const
{
if(fwVerStr)
fwVerStr[0] = '\0';
std::stringstream stream;
stream << std::hex << mRawFwVersion;
std::string verStr( stream.str());
while(verStr.length() < 3)
verStr.insert(verStr.begin(), '0');
// fw version is stored in two bytes (Each nibble represents one digit)
verStr.insert(verStr.end() - 2, '.');
if(mRawFwVersion == 0)
verStr = "";
unsigned int len = verStr.size() + 1;
if (len <= *maxStrLen)
{
memcpy(fwVerStr, verStr.c_str(), len);
*maxStrLen = len;
}
else
{
*maxStrLen = len;
throw UlException(ERR_BAD_BUFFER_SIZE);
}
}
void DaqDevice::getCfg_FpgaVersionStr(char* fpgaVerStr, unsigned int* maxStrLen) const
{
if(fpgaVerStr)
fpgaVerStr[0] = '\0';
std::stringstream stream;
stream << std::hex << mRawFpgaVersion;
std::string verStr( stream.str());
while(verStr.length() < 3)
verStr.insert(verStr.begin(), '0');
// fpga version is stored in two bytes (Each nibble represents one digit)
verStr.insert(verStr.end() - 2, '.');
if(mRawFpgaVersion == 0)
verStr = "";
unsigned int len = verStr.size() + 1;
if (len <= *maxStrLen)
{
memcpy(fpgaVerStr, verStr.c_str(), len);
*maxStrLen = len;
}
else
{
*maxStrLen = len;
throw UlException(ERR_BAD_BUFFER_SIZE);
}
}
void DaqDevice::getCfg_RadioVersionStr(char* fpgaVerStr, unsigned int* maxStrLen) const
{
if(fpgaVerStr)
fpgaVerStr[0] = '\0';
std::stringstream stream;
stream << std::hex << mRawRadioVersion;
std::string verStr( stream.str());
while(verStr.length() < 3)
verStr.insert(verStr.begin(), '0');
// radio version is stored in two bytes (Each nibble represents one digit)
verStr.insert(verStr.end() - 2, '.');
if(mRawRadioVersion == 0)
verStr = "";
unsigned int len = verStr.size() + 1;
if (len <= *maxStrLen)
{
memcpy(fpgaVerStr, verStr.c_str(), len);
*maxStrLen = len;
}
else
{
*maxStrLen = len;
throw UlException(ERR_BAD_BUFFER_SIZE);
}
}
int DaqDevice::memRead(MemoryType memType, MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const
{
throw UlException(ERR_BAD_DEV_TYPE);
}
int DaqDevice::memWrite(MemoryType memType, MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const
{
throw UlException(ERR_BAD_DEV_TYPE);
}
int DaqDevice::memRead(MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const
{
check_MemRW_Args(memRegionType, MA_READ, address, buffer, count);
return memRead(MT_EEPROM, memRegionType, address, buffer, count);
}
int DaqDevice::memWrite(MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const
{
check_MemRW_Args(memRegionType, MA_WRITE, address, buffer, count);
return memWrite(MT_EEPROM, memRegionType, address, buffer, count);
}
void DaqDevice::check_MemRW_Args(MemRegion memRegionType, MemAccessType accessType, unsigned int address, unsigned char* buffer, unsigned int count, bool checkAccess) const
{
if(address == (unsigned long long) getMemUnlockAddr())
return;
std::bitset<32> memRegionBitset(mDaqDeviceInfo.memInfo()->getMemRegionTypes());
if((memRegionType & mDaqDeviceInfo.memInfo()->getMemRegionTypes()) || memRegionBitset.count() == 1)
{
UlMemRegionInfo& memRegionInfo = mDaqDeviceInfo.memInfo()->getMemRegionInfo(memRegionType);
if(checkAccess && !(memRegionInfo.getAccessTypes() & accessType))
throw UlException(ERR_MEM_ACCESS_DENIED);
unsigned long long memStartAddr = memRegionInfo.getAddress();
unsigned long long endAddr = memRegionInfo.getAddress() + memRegionInfo.getSize() - 1;
if(address < memStartAddr || address > endAddr)
throw UlException(ERR_BAD_MEM_ADDRESS);
if((address + count - 1) > endAddr)
throw UlException(ERR_BAD_MEM_ADDRESS);
if(buffer == NULL)
throw UlException(ERR_BAD_BUFFER);
}
else
throw UlException(ERR_BAD_MEM_REGION);
if(!isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
} /* namespace ul */

154
src/DaqDevice.h Normal file
View File

@ -0,0 +1,154 @@
/*
* DaqDeviceInternal.h
*
* Created on: Jul 29, 2015
* Author: Measurement Computing Corporation
*/
#ifndef DAQDEVICE_H_
#define DAQDEVICE_H_
#include "DaqDeviceInfo.h"
#include "DaqDeviceConfig.h"
#include "interfaces/UlDaqDevice.h"
#include "uldaq.h"
#include "ul_internal.h"
#include "utility/FnLog.h"
namespace ul
{
class IoDevice;
class AiDevice;
class AoDevice;
class DioDevice;
class CtrDevice;
class TmrDevice;
class DaqIDevice;
class DaqODevice;
class DaqEventHandler;
class UL_LOCAL DaqDevice: public UlDaqDevice
{
public:
DaqDevice(DaqDeviceDescriptor daqDeviceDescriptor);
virtual ~DaqDevice();
virtual void connect()= 0;
virtual void disconnect() = 0;
unsigned int getDeviceType() const { return mDaqDeviceDescriptor.productId; }
long long getDeviceNumber() const {return mDeviceNumber;}
virtual const UlDaqDeviceInfo& getDevInfo() const { return mDaqDeviceInfo;}
virtual UlDaqDeviceConfig& getDevConfig() { return *mDaqDeviceConfig;}
AiDevice* aiDevice() const;
void setAiDevice(AiDevice* aiDevice);
AoDevice* aoDevice() const;
void setAoDevice(AoDevice* aoDevice);
DioDevice* dioDevice() const;
void setDioDevice(DioDevice* dioDevice);
CtrDevice* ctrDevice() const;
void setCtrDevice(CtrDevice* ctrDevice);
TmrDevice* tmrDevice() const;
void setTmrDevice(TmrDevice* tmrDevice);
DaqIDevice* daqIDevice() const;
void setDaqIDevice(DaqIDevice* daqIDevice);
DaqODevice* daqODevice() const;
void setDaqODevice(DaqODevice* daqODevice);
DaqEventHandler* eventHandler() const;
bool isConnected() const { return mConnected;}
void initializeIoDevices();
void reconfigureIoDevices();
void disconnectIoDevices();
//void terminateScans();
bool isScanRunning() const;
bool isScanRunning(FunctionType functionType) const;
void stopBackground(FunctionType functionType) const;
void checkConnection() const;
virtual void flashLed(int flashCount) const;
virtual DaqDeviceDescriptor getDescriptor() const;
void getEuScaling(Range range, double &scale, double &offset) const;
virtual int memRead(MemoryType memType, MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const;
virtual int memWrite(MemoryType memType, MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const;
virtual int memRead(MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const;
virtual int memWrite(MemRegion memRegionType, unsigned int address, unsigned char* buffer, unsigned int count) const;
void setMemUnlockAddr(int addr) { mMemUnlockAddr = addr; }
int getMemUnlockAddr() const { return mMemUnlockAddr; }
void setMemUnlockCode(unsigned int code) { mMemUnlockCode = code; }
unsigned int getMemUnlockCode() const { return mMemUnlockCode; }
void addMemRegion(MemRegion memRegionType, unsigned long long address, unsigned long long size, long long accessTypes);
virtual void setCalOutput (unsigned int index) const { };
// public interface functions
UlAiDevice& getAiDevice() const;
UlAoDevice& getAoDevice() const;
UlDioDevice& getDioDevice() const;
UlCtrDevice& getCtrDevice() const;
UlTmrDevice& getTmrDevice() const;
UlDaqIDevice& getDaqIDevice() const;
UlDaqODevice& getDaqODevice() const;
double getClockFreq() const;
IoDevice* getIoDevice(FunctionType functionType) const;
TriggerConfig getTriggerConfig(FunctionType functionType) const;
////////////////////// Configuration functions /////////////////////////////////
void getCfg_FwVersionStr(char* fpgaVerStr, unsigned int* maxStrLen) const;
void getCfg_FpgaVersionStr(char* fpgaVerStr, unsigned int* maxStrLen) const;
void getCfg_RadioVersionStr(char* fpgaVerStr, unsigned int* maxStrLen) const;
protected:
void check_MemRW_Args(MemRegion memRegionType, MemAccessType accessType, unsigned int address, unsigned char* buffer, unsigned int count, bool checkAccess = true) const;
protected:
DaqDeviceDescriptor mDaqDeviceDescriptor;
bool mConnected;
DaqDeviceInfo mDaqDeviceInfo;
DaqDeviceConfig* mDaqDeviceConfig;
AiDevice* mAiDevice;
AoDevice* mAoDevice;
DioDevice* mDioDevice;
CtrDevice* mCtrDevice;
TmrDevice* mTmrDevice;
DaqIDevice* mDaqIDevice;
DaqODevice* mDaqODevice;
DaqEventHandler* mEventHandler;
unsigned short mRawFwVersion;
unsigned short mRawFpgaVersion;
unsigned short mRawRadioVersion;
mutable unsigned long long mCurrentSuspendCount;
private:
static unsigned long long mNextAvailableDeviceNumber;
static pthread_mutex_t mDeviceNumberMutex;
long long mDeviceNumber;
int mMemUnlockAddr;
unsigned int mMemUnlockCode;
};
} /* namespace ul */
#endif /* DAQDEVICE_H_ */

42
src/DaqDeviceConfig.cpp Normal file
View File

@ -0,0 +1,42 @@
/*
* DaqDeviceConfig.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DaqDevice.h"
#include "DaqDeviceConfig.h"
namespace ul
{
DaqDeviceConfig::DaqDeviceConfig(DaqDevice& daqDevice) : mDaqDevice(daqDevice)
{
}
DaqDeviceConfig::~DaqDeviceConfig()
{
}
void DaqDeviceConfig::getVersionStr(DevVersionType verType, char* verStr, unsigned int* maxStrLen)
{
switch(verType)
{
case DEV_VER_FW_MAIN:
mDaqDevice.getCfg_FwVersionStr(verStr, maxStrLen);
break;
case DEV_VER_FPGA:
mDaqDevice.getCfg_FpgaVersionStr(verStr, maxStrLen);
break;
case DEV_VER_RADIO:
mDaqDevice.getCfg_RadioVersionStr(verStr, maxStrLen);
break;
default:
break;
}
}
} /* namespace ul */

30
src/DaqDeviceConfig.h Normal file
View File

@ -0,0 +1,30 @@
/*
* DaqDeviceConfig.h
*
* Author: Measurement Computing Corporation
*/
#ifndef DAQDEVICECONFIG_H_
#define DAQDEVICECONFIG_H_
#include "interfaces/UlDaqDeviceConfig.h"
#include "ul_internal.h"
namespace ul
{
class DaqDevice;
class UL_LOCAL DaqDeviceConfig: public UlDaqDeviceConfig
{
public:
virtual ~DaqDeviceConfig();
DaqDeviceConfig(DaqDevice& daqDevice);
virtual void getVersionStr(DevVersionType verType, char* verStr, unsigned int* maxStrLen);
private:
DaqDevice& mDaqDevice;
};
} /* namespace ul */
#endif /* DAQDEVICECONFIG_H_ */

54
src/DaqDeviceId.h Normal file
View File

@ -0,0 +1,54 @@
/*
* DaqDeviceId.h
*
* Created on: Jul 30, 2015
* Author: Measurement Computing Corporation
*/
#ifndef DAQDEVICEID_H_
#define DAQDEVICEID_H_
#include <string>
namespace ul
{
class DaqDeviceId
{
public:
enum
{
USB_TC = 0x90,
USB_1208FS_PLUS = 0xe8,
USB_1408FS_PLUS = 0xe9,
USB_1608FS_PLUS = 0xea,
USB_1208HS = 0xc4,
USB_1208HS_2AO = 0xc5,
USB_1208HS_4AO = 0xc6,
USB_1608G = 0x110,
USB_1608GX = 0x111,
USB_1608GX_2AO = 0x112,
USB_2633 = 0x118,
USB_2637 = 0x119,
USB_2623 = 0x120,
USB_2627 = 0x121,
USB_201 = 0x113,
USB_202 = 0x12b,
USB_204 = 0x114,
USB_205 = 0x12c,
USB_CTR08 = 0x127,
USB_CTR04 = 0x12e,
USB_DIO32HS = 0x133,
USB_1608G_2 = 0x134,
USB_1608GX_2 = 0x135,
USB_1608GX_2AO_2 = 0x136,
USB_1808 = 0x13d,
USB_1808X = 0x13e
};
};
} /* namespace ul */
#endif /* DAQDEVICEID_H_ */

25
src/DaqDeviceInfo.cpp Normal file
View File

@ -0,0 +1,25 @@
/*
* DaqDeviceInfo.cpp
*
* Author: root
*/
#include "DaqDeviceInfo.h"
namespace ul
{
DaqDeviceInfo::DaqDeviceInfo():mProductId(0), mHasAiDevice(false), mHasAoDevice(false), mHasDioDevice(false), mHasCioDevice(false), mHasTmrDevice(false),mHasDaqIDevice(false),mHasDaqODevice(false), mClockFreq(0.0)
{
mEventTypes = DE_NONE;
mMemInfo = new DevMemInfo();
}
DaqDeviceInfo::~DaqDeviceInfo()
{
if(mMemInfo)
delete mMemInfo;
}
} /* namespace ul */

67
src/DaqDeviceInfo.h Normal file
View File

@ -0,0 +1,67 @@
/*
* DaqDeviceInfo.h
*
* Author: root
*/
#ifndef DAQDEVICEINFO_H_
#define DAQDEVICEINFO_H_
#include "ul_internal.h"
#include "DevMemInfo.h"
#include "interfaces/UlDaqDeviceInfo.h"
namespace ul
{
class UL_LOCAL DaqDeviceInfo: public UlDaqDeviceInfo
{
public:
virtual ~DaqDeviceInfo();
DaqDeviceInfo();
void setProductId(unsigned int productId) { mProductId = productId; }
unsigned int getProductId() const { return mProductId; }
void hasAiDevice(bool hasAiDevice) { mHasAiDevice = hasAiDevice; }
bool hasAiDevice() const { return mHasAiDevice; }
void hasAoDevice(bool hasAoDevice) { mHasAoDevice = hasAoDevice; }
bool hasAoDevice() const { return mHasAoDevice; }
void hasDioDevice(bool hasDioDevice) { mHasDioDevice = hasDioDevice; }
bool hasDioDevice() const { return mHasDioDevice; }
void hasCtrDevice(bool hasCioDevice) { mHasCioDevice = hasCioDevice; }
bool hasCtrDevice() const { return mHasCioDevice; }
void hasTmrDevice(bool hasTmrDevice) { mHasTmrDevice = hasTmrDevice; }
bool hasTmrDevice() const { return mHasTmrDevice; }
void hasDaqIDevice(bool hasDaqIDevice) { mHasDaqIDevice = hasDaqIDevice; }
bool hasDaqIDevice() const { return mHasDaqIDevice; }
void hasDaqODevice(bool hasDaqODevice) { mHasDaqODevice = hasDaqODevice; }
bool hasDaqODevice() const { return mHasDaqODevice; }
void setClockFreq(double freq) { mClockFreq = freq; };
double getClockFreq() const { return mClockFreq;}
void setEventTypes(long long eventTypes) { mEventTypes = (DaqEventType) eventTypes;}
DaqEventType getEventTypes() const { return mEventTypes;}
DevMemInfo* memInfo() const { return mMemInfo;};
UlDevMemInfo& getMemInfo() const { return *mMemInfo;};
private:
unsigned int mProductId;
bool mHasAiDevice;
bool mHasAoDevice;
bool mHasDioDevice;
bool mHasCioDevice;
bool mHasTmrDevice;
bool mHasDaqIDevice;
bool mHasDaqODevice;
double mClockFreq;
DaqEventType mEventTypes;
DevMemInfo* mMemInfo;
};
} /* namespace ul */
#endif /* DAQDEVICEINFO_H_ */

178
src/DaqDeviceManager.cpp Normal file
View File

@ -0,0 +1,178 @@
/*
* DaqDeviceManager.cpp
*
* Created on: Jul 30, 2015
* Author: Measurement Computing Corporation
*/
#include "DaqDeviceManager.h"
#include "DaqDeviceId.h"
#include "./utility/FnLog.h"
#include <algorithm>
#include <cstring>
namespace ul
{
std::map<int, std::string> DaqDeviceManager::mSupportedDevices;
std::map<long long, DaqDevice*> DaqDeviceManager::mCreatedDevicesMap;
DaqDeviceManager::DaqDeviceManager()
{
}
DaqDeviceManager::~DaqDeviceManager()
{
}
void DaqDeviceManager::addSupportedDaqDevice()
{
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1208FS_PLUS, "USB-1208FS-Plus"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1408FS_PLUS, "USB-1408FS-Plus"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1608FS_PLUS, "USB-1608FS-Plus"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_201, "USB-201"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_202, "USB-202"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_204, "USB-204"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_205, "USB-205"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1208HS, "USB-1208HS"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1208HS_2AO, "USB-1208HS-2AO"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1208HS_4AO, "USB-1208HS-4AO"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1608G, "USB-1608G"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1608G_2, "USB-1608G"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1608GX, "USB-1608GX"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1608GX_2, "USB-1608GX"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1608GX_2AO, "USB-1608GX-2AO"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1608GX_2AO_2, "USB-1608GX-2AO"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1808, "USB-1808"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_1808X, "USB-1808X"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_2623, "USB-2623"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_2627, "USB-2627"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_2633, "USB-2633"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_2637, "USB-2637"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_DIO32HS, "USB-DIO32HS"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_CTR04, "USB-CTR04"));
mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_CTR08, "USB-CTR08"));
// HID devices
//mSupportedDevices.insert(std::pair<int, std::string>(DaqDeviceId::USB_TC, "USB-TC"));
}
bool DaqDeviceManager::isDaqDeviceSupported(int productId)
{
bool supported = false;
if(mSupportedDevices.empty())
addSupportedDaqDevice();
std::map<int, std::basic_string<char> >::iterator itr = mSupportedDevices.find(productId);
if(itr != mSupportedDevices.end())
supported = true;
return supported;
}
std::string DaqDeviceManager::getDeviceName(int productId)
{
std::string deviceName;
std::map<int, std::string>::iterator itr = mSupportedDevices.find(productId);
if(itr != mSupportedDevices.end())
deviceName = itr->second;
return deviceName;
}
void DaqDeviceManager::addToCreatedList(DaqDevice* daqDevice)
{
FnLog log("DaqDeviceManager::addToCreatedList");
mCreatedDevicesMap.insert(std::pair<long long, DaqDevice*>(daqDevice->getDeviceNumber(), daqDevice));
}
void DaqDeviceManager::removeFromCreatedList(long long deviceNumber)//DaqDevice* daqDevice)
{
FnLog log("DaqDeviceManager::removeFromCreatedList");
std::map<long long, DaqDevice*>::iterator itr = mCreatedDevicesMap.find(deviceNumber);
if(itr != mCreatedDevicesMap.end())
{
mCreatedDevicesMap.erase(itr);
}
}
void DaqDeviceManager::releaseDevice(long long deviceNumber)
{
FnLog log("DaqDeviceManager::releaseDevice");
std::map<long long, DaqDevice*>::iterator itr = mCreatedDevicesMap.find(deviceNumber);
if(itr != mCreatedDevicesMap.end())
{
delete (itr->second);
}
// when a device object is deleted, it removes itself from mCreatedDevices list in the DaqDevice destructor
// so there is no need to removed it from the list here. This approach prevents deleting the device again if the users used delete
// instead of DaqDeviceManager::releaseDaqDevice to free DaqDevice objects.
}
DaqDevice* DaqDeviceManager::getActualDeviceHandle(long long deviceNumber)
{
FnLog log("DaqDeviceManager::getActualDeviceHandle");
DaqDevice* daqDevice = NULL;
std::map<long long, DaqDevice*>::iterator itr = mCreatedDevicesMap.find(deviceNumber);
if(itr != mCreatedDevicesMap.end())
daqDevice = itr->second;
return daqDevice;
}
DaqDevice* DaqDeviceManager::getDaqDevice(DaqDeviceDescriptor daqDeviceDescriptor)
{
DaqDevice *daqDevice = NULL;
DaqDeviceDescriptor desc;
for(std::map<long long, DaqDevice*>::iterator itr = mCreatedDevicesMap.begin(); itr != mCreatedDevicesMap.end(); itr++)
{
desc = itr->second->getDescriptor();
if(desc.productId == daqDeviceDescriptor.productId)
{
if(std::memcmp(desc.uniqueId, daqDeviceDescriptor.uniqueId, sizeof(desc.uniqueId)) == 0)
{
daqDevice = itr->second;
break;
}
}
}
return daqDevice;
}
void DaqDeviceManager::releaseDevices()
{
FnLog log("DaqDeviceManager::releaseDevices");
if(mCreatedDevicesMap.size())
UL_LOG("#### " << mCreatedDevices.size() << " lingering device(s) being released: ");
else
UL_LOG("No lingering device found");
//for(unsigned int i = 0; i < mCreatedDevicesMap.size(); i++)
// delete mCreatedDevicesMap[i];
for(std::map<long long, DaqDevice*>::iterator itr = mCreatedDevicesMap.begin(); itr != mCreatedDevicesMap.end(); itr++)
delete itr->second;
// when a device object is deleted, it removes itself from mCreatedDevices list in the DaqDevice destructor
// so there is no need to removed it from the list here. This approach prevents deleting the device again if the users used delete
// instead of DaqDeviceManager::releaseDaqDevice to free DaqDevice objects.2
}
} /* namespace ul */

46
src/DaqDeviceManager.h Normal file
View File

@ -0,0 +1,46 @@
/*
* DaqDeviceManager.h
*
* Created on: Jul 30, 2015
* Author: Measurement Computing Corporation
*/
#ifndef DAQDEVICEMANAGER_H_
#define DAQDEVICEMANAGER_H_
#include "ul_internal.h"
#include "DaqDevice.h"
#include <string>
#include <map>
#include <vector>
namespace ul
{
class UL_LOCAL DaqDeviceManager
{
public:
DaqDeviceManager();
virtual ~DaqDeviceManager();
static bool isDaqDeviceSupported(int productId);
static std::string getDeviceName(int productId);
static void addToCreatedList(DaqDevice* daqDevice);
static void removeFromCreatedList(long long deviceNumber);
static void releaseDevice(long long deviceNumber);
static void releaseDevices();
static DaqDevice* getActualDeviceHandle(long long deviceNumber);
static DaqDevice* getDaqDevice(DaqDeviceDescriptor daqDeviceDescriptor);
private:
static void addSupportedDaqDevice();
private:
static std::map<int, std::string> mSupportedDevices;
static std::map<long long, DaqDevice*> mCreatedDevicesMap;
};
} /* namespace ul */
#endif /* DaqDeviceManager_H_ */

33
src/DaqEvent.h Normal file
View File

@ -0,0 +1,33 @@
/*
* DaqEvent.h
*
* Author: Measurement Computing Corporation
*/
#ifndef DAQEVENT_H_
#define DAQEVENT_H_
struct DaqEvent
{
DaqEventType type;
unsigned long long eventParameter;
DaqEventCallback callbackFunction;
void* userData;
unsigned long long eventData;
bool eventOccured;
DaqEvent()
{
type = (DaqEventType) 0;
eventParameter = 0;
callbackFunction = NULL;
userData = NULL;
eventData = 0;
eventOccured = false;
}
};
typedef struct DaqEvent DaqEvent;
#endif /* DAQEVENT_H_ */

316
src/DaqEventHandler.cpp Normal file
View File

@ -0,0 +1,316 @@
/*
* DaqEventHandler.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DaqEventHandler.h"
#include <sys/resource.h>
#include "./utility/UlLock.h"
namespace ul
{
DaqEventHandler::DaqEventHandler(const DaqDevice& daqDevice) : mDaqDevice(daqDevice)
{
mEnabledEventsTypes = (DaqEventType) 0;
UlLock::initMutex(mEventHandlerMutex, PTHREAD_MUTEX_RECURSIVE);
UlLock::initMutex(mEventMutex, PTHREAD_MUTEX_RECURSIVE);
mEventThreadHandle = 0;
mTerminateEventThread = false;
mDaqEventOccured = false;
mLastEventIndex = 0;
}
DaqEventHandler::~DaqEventHandler()
{
if(mDaqDevice.getDevInfo().getEventTypes())
disableEvent(mDaqDevice.getDevInfo().getEventTypes());
UlLock::destroyMutex(mEventMutex);
UlLock::destroyMutex(mEventHandlerMutex);
}
void DaqEventHandler::start()
{
UlLock lock(mEventHandlerMutex);
if(!mEventThreadHandle)
startEventThread();
}
void DaqEventHandler::stop()
{
UlLock lock(mEventHandlerMutex);
if(mEventThreadHandle)
terminateEventThread();
}
void DaqEventHandler::enableEvent(DaqEventType eventTypes, unsigned long long eventParameter, DaqEventCallback eventCallbackFunc, void* userData)
{
check_EnableEvent_Args(eventTypes, eventParameter, eventCallbackFunc);
UlLock lock(mEventHandlerMutex);
addEnabledEvents(eventTypes, eventParameter, eventCallbackFunc, userData);
if(!mEventThreadHandle)
startEventThread();
}
void DaqEventHandler::disableEvent(DaqEventType eventTypes)
{
check_DisableEvent_Args(eventTypes);
UlLock lock(mEventHandlerMutex);
mEnabledEventsTypes = (DaqEventType)(mEnabledEventsTypes & (~eventTypes));
if(!mEnabledEventsTypes && mEventThreadHandle)
terminateEventThread();
}
void DaqEventHandler::addEnabledEvents(DaqEventType eventTypes, unsigned long long eventParameter, DaqEventCallback eventCalbackFunc, void* userData)
{
std::bitset<MAX_EVENT_TYPE_COUNT> events(eventTypes);
DaqEventType eventType;
int eventIndex;
for(unsigned int i = 0; i < events.size(); i++)
{
if(events[i])
{
eventType = (DaqEventType) (1 << i);
eventIndex = getEventIndex(eventType);
mDaqEvents[eventIndex].type = eventType;
mDaqEvents[eventIndex].eventOccured = false;
mDaqEvents[eventIndex].callbackFunction = eventCalbackFunc;
mDaqEvents[eventIndex].userData = userData;
if( eventType == DE_ON_DATA_AVAILABLE)
mDaqEvents[eventIndex].eventParameter = eventParameter;
}
}
mEnabledEventsTypes = (DaqEventType)(mEnabledEventsTypes | eventTypes);
}
void DaqEventHandler::resetInputEvents(DaqEventType eventTypes)
{
DaqEventType inputEventTypes = (DaqEventType) (eventTypes & (DE_ON_DATA_AVAILABLE | DE_ON_INPUT_SCAN_ERROR | DE_ON_END_OF_INPUT_SCAN));
std::bitset<MAX_EVENT_TYPE_COUNT> events(inputEventTypes);
DaqEventType eventType;
int eventIndex;
for(unsigned int i = 0; i < events.size(); i++)
{
if(events[i])
{
eventType = (DaqEventType) (1 << i);
eventIndex = getEventIndex(eventType);
mDaqEvents[eventIndex].eventOccured = false;
}
}
}
void DaqEventHandler::resetOutputEvents(DaqEventType eventTypes)
{
DaqEventType inputEventTypes = (DaqEventType) (eventTypes & (DE_ON_OUTPUT_SCAN_ERROR | DE_ON_END_OF_OUTPUT_SCAN ));
std::bitset<MAX_EVENT_TYPE_COUNT> events(inputEventTypes);
DaqEventType eventType;
int eventIndex;
for(unsigned int i = 0; i < events.size(); i++)
{
if(events[i])
{
eventType = (DaqEventType) (1 << i);
eventIndex = getEventIndex(eventType);
mDaqEvents[eventIndex].eventOccured = false;
}
}
}
unsigned long long DaqEventHandler::getEventParameter(DaqEventType eventType)
{
int eventIndex = getEventIndex(eventType);
return mDaqEvents[eventIndex].eventParameter;
}
void DaqEventHandler::setCurrentEventAndData(DaqEventType eventType, unsigned long long eventData)
{
UlLock lock(mEventMutex);
if(mEnabledEventsTypes & eventType) // check if this event type is disabled after scan started
{
int eventIndex = getEventIndex(eventType);
mDaqEvents[eventIndex].eventData = eventData;
mDaqEvents[eventIndex].eventOccured = true;
mDaqEventOccured = true;
mNotifier.signal();
}
}
void DaqEventHandler::getCurrentEventsAndData(DaqEvent* daqEvents, int& eventCount)
{
//std::vector<DaqEvent> currentEvents;
UlLock lock(mEventMutex);
eventCount = 0;
for(int eventIndex = 0; eventIndex < MAX_EVENT_TYPE_COUNT; eventIndex++ )
{
if(mDaqEvents[eventIndex].eventOccured)
{
daqEvents[eventCount] = mDaqEvents[eventIndex];
mDaqEvents[eventIndex].eventOccured = false;
eventCount++;
}
}
mDaqEventOccured = false;
}
void DaqEventHandler::startEventThread()
{
pthread_attr_t attr;
int status = pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if(!status)
{
mTerminateEventThread = false;
mEventThreadInitEvent.reset();
status = pthread_create(&mEventThreadHandle, &attr, &eventThread, this);
#ifndef __APPLE__
pthread_setname_np(mEventThreadHandle, "xfer_state_td");
#endif
if(status)
UL_LOG("#### Unable to start the daq event handler thread");
else
{
mEventThreadInitEvent.wait_for_signal(100);
}
status = pthread_attr_destroy(&attr);
}
else
UL_LOG("#### Unable to initialize attributes for the daq event handler thread");
}
void DaqEventHandler::terminateEventThread()
{
mTerminateEventThread = true;
mNotifier.signal();
if(mEventThreadHandle)
pthread_join(mEventThreadHandle, NULL);
mEventThreadHandle = 0;
}
void* DaqEventHandler::eventThread(void *arg)
{
DaqEventHandler* This = (DaqEventHandler*) arg;
int niceVal = 0; // make sure this thread does not get a high priority if the parent thread is running with high priority
setpriority(PRIO_PROCESS, 0, niceVal);
This->mEventThreadInitEvent.signal();
DaqEvent currentEvents[MAX_EVENT_TYPE_COUNT];
int eventCount = 0;
while (!This->mTerminateEventThread)
{
This->waitForEvent();
if(This->mDaqEventOccured)
{
This->getCurrentEventsAndData(currentEvents, eventCount);
for(int i = 0; i < eventCount; i++)
{
currentEvents[i].callbackFunction(This->mDaqDevice.getDeviceNumber(), currentEvents[i].type, currentEvents[i].eventData, currentEvents[i].userData);
}
}
}
return NULL;
}
void DaqEventHandler::waitForEvent()
{
if(!mDaqEventOccured && !mTerminateEventThread)
{
mNotifier.wait_for_signal();
}
}
void DaqEventHandler::check_EnableEvent_Args(DaqEventType eventTypes, unsigned long long eventParameter, DaqEventCallback eventCalbackFunc)
{
if((eventTypes == 0) || (eventTypes & ~mDaqDevice.getDevInfo().getEventTypes()))
throw UlException(ERR_BAD_EVENT_TYPE);
if(eventTypes & mEnabledEventsTypes)
throw UlException(ERR_EVENT_ALREADY_ENABLED);
if((eventTypes & DE_ON_DATA_AVAILABLE) && (eventParameter == 0))
throw UlException(ERR_BAD_EVENT_PARAMETER);
if(mDaqDevice.isScanRunning())
throw UlException(ERR_ALREADY_ACTIVE);
if(eventCalbackFunc == NULL)
throw UlException(ERR_BAD_CALLBACK_FUCNTION);
}
void DaqEventHandler::check_DisableEvent_Args(DaqEventType eventTypes)
{
//if(eventTypes & ~mDaqDevice.getDevInfo().getEventTypes())
// throw UlException(ERR_BAD_EVENT_TYPE);
}
int DaqEventHandler::getEventIndex(DaqEventType eventType)
{
int index = -1;
switch(eventType)
{
case DE_ON_DATA_AVAILABLE:
index = 0;
break;
case DE_ON_INPUT_SCAN_ERROR:
index = 1;
break;
case DE_ON_END_OF_INPUT_SCAN:
index = 2;
break;
case DE_ON_OUTPUT_SCAN_ERROR:
index = 3;
break;
case DE_ON_END_OF_OUTPUT_SCAN:
index = 4;
break;
default:
break;
}
return index;
}
} /* namespace ul */

75
src/DaqEventHandler.h Normal file
View File

@ -0,0 +1,75 @@
/*
* DaqEventHandler.h
*
* Author: Measurement Computing Corporation
*/
#ifndef DAQEVENTHANDLER_H_
#define DAQEVENTHANDLER_H_
#include <bitset>
#include "ul_internal.h"
#include "DaqDevice.h"
#include "DaqEvent.h"
#include "./utility/ThreadEvent.h"
#include "UlException.h"
namespace ul
{
class UL_LOCAL DaqEventHandler
{
public:
DaqEventHandler(const DaqDevice& daqDevice);
virtual ~DaqEventHandler();
DaqEventType getEnabledEventTypes() const { return mEnabledEventsTypes; }
void enableEvent(DaqEventType eventTypes, unsigned long long eventParameter, DaqEventCallback eventCallbackFunc, void* userData);
void disableEvent(DaqEventType eventTypes);
void resetInputEvents(DaqEventType eventTypes);
void resetOutputEvents(DaqEventType eventTypes);
unsigned long long getEventParameter(DaqEventType eventType);
void setCurrentEventAndData(DaqEventType eventType, unsigned long long eventData);
void start();
void stop();
private:
void startEventThread();
void terminateEventThread();
static void* eventThread(void* arg);
void waitForEvent();
int getEventIndex(DaqEventType eventType);
void addEnabledEvents(DaqEventType eventTypes, unsigned long long eventParameter, DaqEventCallback eventCalbackFunc, void* userData);
void getCurrentEventsAndData(DaqEvent* daqEvents, int& eventCount);
void check_EnableEvent_Args(DaqEventType eventTypes, unsigned long long eventParameter, DaqEventCallback eventCalbackFunc);
void check_DisableEvent_Args(DaqEventType eventTypes);
private:
enum {MAX_EVENT_TYPE_COUNT = 5};
const DaqDevice& mDaqDevice;
DaqEventType mEnabledEventsTypes;
DaqEvent mDaqEvents[MAX_EVENT_TYPE_COUNT];
pthread_mutex_t mEventHandlerMutex;
pthread_mutex_t mEventMutex;
pthread_t mEventThreadHandle;
bool mTerminateEventThread;
ThreadEvent mEventThreadInitEvent;
ThreadEvent mNotifier;
bool mDaqEventOccured;
int mLastEventIndex;
};
} /* namespace ul */
#endif /* DAQEVENTHANDLER_H_ */

330
src/DaqIDevice.cpp Normal file
View File

@ -0,0 +1,330 @@
/*
* DaqIDevice.cpp
*
* Created on: Nov 14, 2017
* Author: Measurement Computing Corporation
*/
#include "DaqIDevice.h"
#include "AiInfo.h"
#include "DioInfo.h"
#include "CtrInfo.h"
#include "DioDevice.h"
#include <math.h>
#include <algorithm>
#include "UlException.h"
namespace ul
{
DaqIDevice::DaqIDevice(const DaqDevice& daqDevice) : IoDevice(daqDevice), UlDaqIDevice()
{
for(int i = 0; i < 4; i++)
{
mLastStatus[i].error = ERR_NO_ERROR;
mLastStatus[i].scanCount = 0;
mLastStatus[i].totalCount = 0;
mLastStatus[i].index = -1;
}
}
DaqIDevice::~DaqIDevice()
{
}
double DaqIDevice::daqInScan(DaqInChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqInScanFlag flags, double data[])
{
return daqInScan(FT_DAQI, chanDescriptors, numChans, samplesPerChan, rate, options, flags, data);
}
double DaqIDevice::daqInScan(FunctionType functionType, DaqInChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqInScanFlag flags, void* data)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
UlError DaqIDevice::getStatus(ScanStatus* status, TransferStatus* xferStatus)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void DaqIDevice::stopBackground()
{
throw UlException(ERR_BAD_DEV_TYPE);
}
UlError DaqIDevice::getStatus(FunctionType functionType, ScanStatus* status, TransferStatus* xferStatus)
{
if(mScanInfo.functionType == functionType)
{
return getStatus(status, xferStatus);
}
else
{
*status = SS_IDLE;
return getLastStatus(functionType, xferStatus);
}
}
UlError DaqIDevice::waitUntilDone(FunctionType functionType, double timeout)
{
UlError err = ERR_NO_ERROR;
if(mScanInfo.functionType == functionType)
{
err = IoDevice::waitUntilDone(timeout);
}
return err;
}
void DaqIDevice::stopBackground(FunctionType functionType)
{
if(mScanInfo.functionType == functionType)
{
stopBackground();
}
}
void DaqIDevice::setTrigger(TriggerType type, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount)
{
if(mDaqIInfo.supportsTrigger())
{
check_DaqInSetTrigger_Args(type, trigChanDesc, level, variance, retriggerCount);
mTrigCfg.type = type;
mTrigCfg.trigChan = trigChanDesc.channel;
mTrigCfg.level = level;
mTrigCfg.variance = variance;
mTrigCfg.retrigCount = retriggerCount;
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
void DaqIDevice::storeLastStatus()
{
int index = -1;
ScanStatus status;
TransferStatus xferStatus;
UlError error = getStatus(&status, &xferStatus);
switch(mScanInfo.functionType)
{
case FT_DAQI:
index = 0;
break;
case FT_AI:
index = 1;
break;
case FT_DI:
index = 2;
break;
case FT_CTR:
index = 3;
break;
default:
break;
}
if(index != -1)
{
mLastStatus[index].error = error;
mLastStatus[index].scanCount = xferStatus.currentScanCount;
mLastStatus[index].totalCount = xferStatus.currentTotalCount;
mLastStatus[index].index = xferStatus.currentIndex;
}
}
UlError DaqIDevice::getLastStatus(FunctionType functionType, TransferStatus* xferStatus)
{
UlError error = ERR_NO_ERROR;
int index = -1;
switch(functionType)
{
case FT_DAQI:
index = 0;
break;
case FT_AI:
index = 1;
break;
case FT_DI:
index = 2;
break;
case FT_CTR:
index = 3;
break;
default:
break;
}
if(index != -1)
{
error = mLastStatus[index].error;
xferStatus->currentScanCount = mLastStatus[index].scanCount;
xferStatus->currentTotalCount = mLastStatus[index].totalCount;
xferStatus->currentIndex = mLastStatus[index].index;
}
return error;
}
void DaqIDevice::check_DaqInScan_Args(DaqInChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqInScanFlag flags, void* data) const
{
if(getScanState() == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(chanDescriptors != NULL)
{
bool invalidRate = false;
if(numChans > mDaqIInfo.getMaxQueueLength())
throw UlException(ERR_BAD_NUM_CHANS);
for(unsigned int i = 0; i < (unsigned int) numChans; i++)
{
if(mDaqIInfo.getChannelTypes() & chanDescriptors[i].type)
{
std::bitset<32> typeBitSet(chanDescriptors[i].type);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
if(chanDescriptors[i].type == DAQI_ANALOG_DIFF || chanDescriptors[i].type == DAQI_ANALOG_SE)
{
const AiInfo& aiInfo = (const AiInfo&) mDaqDevice.getAiDevice().getAiInfo();
AiInputMode inputMode = chanDescriptors[i].type == DAQI_ANALOG_DIFF ? AI_DIFFERENTIAL : AI_SINGLE_ENDED;
if(chanDescriptors[i].channel >= aiInfo.getNumChansByMode(inputMode))
throw UlException(ERR_BAD_AI_CHAN);
if(!aiInfo.isInputModeSupported(inputMode))
throw UlException(ERR_BAD_INPUT_MODE);
if(!aiInfo.isRangeSupported(inputMode, chanDescriptors[i].range))
throw UlException(ERR_BAD_RANGE);
if(rate > aiInfo.getMaxScanRate())
invalidRate = true;
}
else if(chanDescriptors[i].type == DAQI_DIGITAL)
{
const DioInfo& dioInfo = (const DioInfo&) mDaqDevice.getDioDevice().getDioInfo();
if(dioInfo.isPortSupported((DigitalPortType) chanDescriptors[i].channel) == false)
throw UlException(ERR_BAD_PORT_TYPE);
if(rate > dioInfo.getMaxScanRate(DD_INPUT))
invalidRate = true;
}
else if(chanDescriptors[i].type == DAQI_CTR16 || chanDescriptors[i].type == DAQI_CTR32 || chanDescriptors[i].type == DAQI_CTR48)
{
const CtrInfo& ctrInfo = (const CtrInfo&) mDaqDevice.getCtrDevice().getCtrInfo();
if(chanDescriptors[i].channel >= ctrInfo.getNumCtrs())
throw UlException(ERR_BAD_CTR);
if(rate > ctrInfo.getMaxScanRate())
invalidRate = true;
}
}
else
{
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
}
}
if(data == NULL)
throw UlException(ERR_BAD_BUFFER);
if(~mDaqIInfo.getScanOptions() & options)
throw UlException(ERR_BAD_OPTION);
//if(~mDaqIInfo.getDaqInScanFlags() & flags)
// throw UlException(ERR_BAD_FLAG);
if((!(options & SO_EXTCLOCK) && invalidRate) || (rate <= 0.0))
throw UlException(ERR_BAD_RATE);
if(samplesPerChan < mMinScanSampleCount)
throw UlException(ERR_BAD_SAMPLE_COUNT);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
}
void DaqIDevice::check_DaqInSetTrigger_Args(TriggerType trigType, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount) const
{
if(mDaqIInfo.supportsTrigger())
{
if(!(mDaqIInfo.getTriggerTypes() & trigType))
throw UlException(ERR_BAD_TRIG_TYPE);
std::bitset<32> typeBitSet(trigType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_TRIG_TYPE);
if(retriggerCount > 0 && !(mDaqIInfo.getScanOptions() & SO_RETRIGGER))
throw UlException(ERR_BAD_RETRIG_COUNT);
if(!(trigType & (TRIG_POS_EDGE | TRIG_NEG_EDGE | TRIG_HIGH | TRIG_LOW)))
{
if(trigChanDesc.type == DAQI_CTR16 || trigChanDesc.type == DAQI_CTR32 || trigChanDesc.type == DAQI_CTR48)
{
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
}
else if(trigChanDesc.type == DAQI_ANALOG_DIFF || trigChanDesc.type == DAQI_ANALOG_SE)
{
if(!(trigType & (TRIG_RISING | TRIG_FALLING | TRIG_ABOVE |TRIG_BELOW)))
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
}
else if(trigChanDesc.type == DAQI_DIGITAL)
{
DioDevice* dioDev = mDaqDevice.dioDevice();
if(dioDev)
{
if(!(trigType & (TRIG_PATTERN_EQ | TRIG_PATTERN_NE | TRIG_PATTERN_ABOVE |TRIG_PATTERN_BELOW)))
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
bool validPort = false;
const UlDioInfo& dioInfo = dioDev->getDioInfo();
unsigned int portNum;
for(portNum = 0; portNum < dioInfo.getNumPorts(); portNum++)
{
if(trigChanDesc.channel == dioInfo.getPortType(portNum))
{
validPort = true;
break;
}
}
if(!validPort)
throw UlException(ERR_BAD_PORT_TYPE);
unsigned long long pattern = ((unsigned long long) level) & ((unsigned long long) variance);
unsigned long long maxPortVal = (1ULL << dioInfo.getNumBits(portNum)) - 1;
if(pattern > maxPortVal)
throw UlException(ERR_BAD_PORT_VAL);
}
else
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
}
}
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
} /* namespace ul */

59
src/DaqIDevice.h Normal file
View File

@ -0,0 +1,59 @@
/*
* DaqIDevice.h
*
* Created on: Nov 14, 2017
* Author: Measurement Computing Corporation
*/
#ifndef DAQIDEVICE_H_
#define DAQIDEVICE_H_
#include "IoDevice.h"
#include "DaqIInfo.h"
#include "interfaces/UlDaqIDevice.h"
namespace ul
{
class UL_LOCAL DaqIDevice: public IoDevice, public UlDaqIDevice
{
public:
virtual ~DaqIDevice();
DaqIDevice(const DaqDevice& daqDevice);
virtual const UlDaqIInfo& getDaqIInfo() { return mDaqIInfo;}
virtual double daqInScan(DaqInChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqInScanFlag flags, double data[]);
virtual void setTrigger(TriggerType type, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount);
virtual UlError getStatus(ScanStatus* status, TransferStatus* xferStatus);
virtual UlError getStatus(FunctionType functionType, ScanStatus* status, TransferStatus* xferStatus);
virtual void stopBackground();
virtual void stopBackground(FunctionType functionType);
UlError waitUntilDone(FunctionType functionType, double timeout);
virtual double daqInScan(FunctionType functionType, DaqInChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqInScanFlag flags, void* data);
protected:
void check_DaqInScan_Args(DaqInChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqInScanFlag flags, void* data) const;
void check_DaqInSetTrigger_Args(TriggerType type, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount) const;
void storeLastStatus();
UlError getLastStatus(FunctionType functionType, TransferStatus* xferStatus);
protected:
DaqIInfo mDaqIInfo;
private:
struct
{
UlError error;
unsigned long long scanCount;
unsigned long long totalCount;
long long index;
}mLastStatus[4];
};
} /* namespace ul */
#endif /* DAQIDEVICE_H_ */

160
src/DaqIInfo.cpp Normal file
View File

@ -0,0 +1,160 @@
/*
* DaqIInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DaqIInfo.h"
#include <algorithm>
namespace ul
{
DaqIInfo::DaqIInfo()
{
mChanTypes = (DaqInChanType) 0;
mMinScanRate = 0;
mMaxScanRate = 0;
mMaxThroughput = 0;
mMaxBurstRate = 0;
mMaxBurstThroughput = 0;
mScanOptions = SO_DEFAULTIO;
mFifoSize = 0;
mMaxQueueLength = 0;
mDaqInScanFlags = 0;
mTriggerTypes = TRIG_NONE;
}
DaqIInfo::~DaqIInfo()
{
}
void DaqIInfo::setChannelTypes(long long chanTypes)
{
mChanTypes = (DaqInChanType) chanTypes;
}
DaqInChanType DaqIInfo::getChannelTypes() const
{
return mChanTypes;
}
void DaqIInfo::setMinScanRate(double minRate)
{
mMinScanRate = minRate;
}
double DaqIInfo::getMinScanRate() const
{
return mMinScanRate;
}
void DaqIInfo::setMaxScanRate(double maxRate)
{
mMaxScanRate = maxRate;
}
double DaqIInfo::getMaxScanRate() const
{
return mMaxScanRate;
}
void DaqIInfo::setMaxThroughput(double maxThroughput)
{
mMaxThroughput = maxThroughput;
}
double DaqIInfo::getMaxThroughput() const
{
return mMaxThroughput;
}
void DaqIInfo::setMaxBurstThroughput(double maxThroughput)
{
mMaxBurstThroughput = maxThroughput;
}
double DaqIInfo::getMaxBurstThroughput() const
{
return mMaxBurstThroughput;
}
void DaqIInfo::setMaxBurstRate(double maxRate)
{
mMaxBurstRate = maxRate;
}
double DaqIInfo::getMaxBurstRate() const
{
return mMaxBurstRate;
}
void DaqIInfo::setFifoSize(int size)
{
mFifoSize = size;
}
int DaqIInfo::getFifoSize() const
{
return mFifoSize;
}
void DaqIInfo::setScanOptions(long long options)
{
mScanOptions = (ScanOption) options;
}
ScanOption DaqIInfo::getScanOptions() const
{
return mScanOptions;
}
void DaqIInfo::setDaqInScanFlags(long long flags)
{
mDaqInScanFlags = flags;
}
long long DaqIInfo::getDaqInScanFlags() const
{
return mDaqInScanFlags;
}
void DaqIInfo::setTriggerTypes(long long triggerTypes)
{
mTriggerTypes = (TriggerType) triggerTypes;
}
TriggerType DaqIInfo::getTriggerTypes() const
{
return mTriggerTypes;
}
bool DaqIInfo::supportsTrigger() const
{
bool supportsTrig = false;
if(mTriggerTypes)
supportsTrig = true;
return supportsTrig;
}
void DaqIInfo::setMaxQueueLength(int length)
{
mMaxQueueLength = length;
}
int DaqIInfo::getMaxQueueLength() const
{
return mMaxQueueLength;
}
} /* namespace ul */

68
src/DaqIInfo.h Normal file
View File

@ -0,0 +1,68 @@
/*
* DaqIInfo.h
*
* Created on: Nov 14, 2017
* Author: Measurement Computing Corporation
*/
#ifndef DAQIINFO_H_
#define DAQIINFO_H_
#include <vector>
#include "interfaces/UlDaqIInfo.h"
#include "ul_internal.h"
namespace ul
{
class UL_LOCAL DaqIInfo: public UlDaqIInfo
{
public:
DaqIInfo();
virtual ~DaqIInfo();
void setChannelTypes(long long chanTypes);
DaqInChanType getChannelTypes() const;
void setMinScanRate(double minRate);
double getMinScanRate() const;
void setMaxScanRate(double maxRate);
double getMaxScanRate() const;
void setMaxThroughput(double maxThroughput);
double getMaxThroughput() const;
void setMaxBurstThroughput(double maxThroughput);
double getMaxBurstThroughput() const;
void setMaxBurstRate(double maxRate);
double getMaxBurstRate() const;
void setFifoSize(int size);
int getFifoSize() const;
void setScanOptions(long long options);
ScanOption getScanOptions() const;
void setDaqInScanFlags(long long flags);
long long getDaqInScanFlags() const;
void setMaxQueueLength(int length);
int getMaxQueueLength() const;
void setTriggerTypes(long long triggerTypes);
TriggerType getTriggerTypes() const;
bool supportsTrigger() const;
private:
DaqInChanType mChanTypes;
TriggerType mTriggerTypes;
double mMinScanRate;
double mMaxScanRate;
double mMaxThroughput;
double mMaxBurstRate;
double mMaxBurstThroughput;
ScanOption mScanOptions;
int mFifoSize;
int mMaxQueueLength;
long long mDaqInScanFlags;
};
} /* namespace ul */
#endif /* DAQIINFO_H_ */

304
src/DaqODevice.cpp Normal file
View File

@ -0,0 +1,304 @@
/*
* DaqODevice.cpp
*
* Created on: Dec 18, 2017
* Author: Measurement Computing Corporation
*/
#include "DaqODevice.h"
#include "AoInfo.h"
#include "DioInfo.h"
#include "DioDevice.h"
#include <math.h>
#include <algorithm>
#include <bitset>
#include "UlException.h"
namespace ul
{
DaqODevice::DaqODevice(const DaqDevice& daqDevice) : IoDevice(daqDevice), UlDaqODevice()
{
for(int i = 0; i < 3; i++)
{
mLastStatus[i].error = ERR_NO_ERROR;
mLastStatus[i].scanCount = 0;
mLastStatus[i].totalCount = 0;
mLastStatus[i].index = -1;
}
}
DaqODevice::~DaqODevice()
{
}
double DaqODevice::daqOutScan(DaqOutChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqOutScanFlag flags, double data[])
{
return daqOutScan(FT_DAQO, chanDescriptors, numChans, samplesPerChan, rate, options, flags, data);
}
double DaqODevice::daqOutScan(FunctionType functionType, DaqOutChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqOutScanFlag flags, void* data)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
UlError DaqODevice::getStatus(ScanStatus* status, TransferStatus* xferStatus)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void DaqODevice::stopBackground()
{
throw UlException(ERR_BAD_DEV_TYPE);
}
UlError DaqODevice::getStatus(FunctionType functionType, ScanStatus* status, TransferStatus* xferStatus)
{
if(mScanInfo.functionType == functionType)
{
return getStatus(status, xferStatus);
}
else
{
*status = SS_IDLE;
return getLastStatus(functionType, xferStatus);
}
}
UlError DaqODevice::waitUntilDone(FunctionType functionType, double timeout)
{
UlError err = ERR_NO_ERROR;
if(mScanInfo.functionType == functionType)
{
err = IoDevice::waitUntilDone(timeout);
}
return err;
}
void DaqODevice::stopBackground(FunctionType functionType)
{
if(mScanInfo.functionType == functionType)
{
stopBackground();
}
}
void DaqODevice::setTrigger(TriggerType type, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount)
{
if(mDaqOInfo.supportsTrigger())
{
check_DaqOutSetTrigger_Args(type, trigChanDesc, level, variance, retriggerCount);
mTrigCfg.type = type;
mTrigCfg.trigChan = trigChanDesc.channel;
mTrigCfg.level = level;
mTrigCfg.variance = variance;
mTrigCfg.retrigCount = retriggerCount;
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
void DaqODevice::storeLastStatus()
{
int index = -1;
ScanStatus status;
TransferStatus xferStatus;
UlError error = getStatus(&status, &xferStatus);
switch(mScanInfo.functionType)
{
case FT_DAQO:
index = 0;
break;
case FT_AO:
index = 1;
break;
case FT_DO:
index = 2;
break;
default:
break;
}
if(index != -1)
{
mLastStatus[index].error = error;
mLastStatus[index].scanCount = xferStatus.currentScanCount;
mLastStatus[index].totalCount = xferStatus.currentTotalCount;
mLastStatus[index].index = xferStatus.currentIndex;
}
}
UlError DaqODevice::getLastStatus(FunctionType functionType, TransferStatus* xferStatus)
{
UlError error = ERR_NO_ERROR;
int index = -1;
switch(functionType)
{
case FT_DAQO:
index = 0;
break;
case FT_AO:
index = 1;
break;
case FT_DO:
index = 2;
break;
default:
break;
}
if(index != -1)
{
error = mLastStatus[index].error;
xferStatus->currentScanCount = mLastStatus[index].scanCount;
xferStatus->currentTotalCount = mLastStatus[index].totalCount;
xferStatus->currentIndex = mLastStatus[index].index;
}
return error;
}
void DaqODevice::check_DaqOutScan_Args(DaqOutChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqOutScanFlag flags, void* data) const
{
if(getScanState() == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(chanDescriptors != NULL)
{
bool invalidRate = false;
if(numChans > mDaqOInfo.getMaxQueueLength())
throw UlException(ERR_BAD_NUM_CHANS);
for(unsigned int i = 0; i < (unsigned int) numChans; i++)
{
if(mDaqOInfo.getChannelTypes() & chanDescriptors[i].type)
{
std::bitset<32> typeBitSet(chanDescriptors[i].type);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_DAQO_CHAN_TYPE);
if(chanDescriptors[i].type == DAQO_ANALOG)
{
const AoInfo& aoInfo = (const AoInfo&) mDaqDevice.getAoDevice().getAoInfo();
if(!aoInfo.isRangeSupported(chanDescriptors[i].range))
throw UlException(ERR_BAD_RANGE);
if(rate > aoInfo.getMaxScanRate())
invalidRate = true;
}
else if(chanDescriptors[i].type == DAQO_DIGITAL)
{
const DioInfo& dioInfo = (const DioInfo&) mDaqDevice.getDioDevice().getDioInfo();
if(dioInfo.isPortSupported((DigitalPortType) chanDescriptors[i].channel) == false)
throw UlException(ERR_BAD_PORT_TYPE);
if(rate > dioInfo.getMaxScanRate(DD_OUTPUT))
invalidRate = true;
}
}
else
{
throw UlException(ERR_BAD_DAQO_CHAN_TYPE);
}
}
if(data == NULL)
throw UlException(ERR_BAD_BUFFER);
if(~mDaqOInfo.getScanOptions() & options)
throw UlException(ERR_BAD_OPTION);
if((!(options & SO_EXTCLOCK) && invalidRate) || (rate <= 0.0))
throw UlException(ERR_BAD_RATE);
if(samplesPerChan < mMinScanSampleCount)
throw UlException(ERR_BAD_SAMPLE_COUNT);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
}
void DaqODevice::check_DaqOutSetTrigger_Args(TriggerType trigType, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount) const
{
if(mDaqOInfo.supportsTrigger())
{
if(!(mDaqOInfo.getTriggerTypes() & trigType))
throw UlException(ERR_BAD_TRIG_TYPE);
std::bitset<32> typeBitSet(trigType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_TRIG_TYPE);
if(retriggerCount > 0 && !(mDaqOInfo.getScanOptions() & SO_RETRIGGER))
throw UlException(ERR_BAD_RETRIG_COUNT);
if(!(trigType & (TRIG_POS_EDGE | TRIG_NEG_EDGE | TRIG_HIGH | TRIG_LOW)))
{
if(trigChanDesc.type == DAQI_CTR16 || trigChanDesc.type == DAQI_CTR32 || trigChanDesc.type == DAQI_CTR48)
{
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
}
else if(trigChanDesc.type == DAQI_ANALOG_DIFF || trigChanDesc.type == DAQI_ANALOG_SE)
{
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
}
else if(trigChanDesc.type == DAQI_DIGITAL)
{
DioDevice* dioDev = mDaqDevice.dioDevice();
if(dioDev)
{
if(!(trigType & (TRIG_PATTERN_EQ | TRIG_PATTERN_NE | TRIG_PATTERN_ABOVE | TRIG_PATTERN_BELOW)))
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
bool validPort = false;
const UlDioInfo& dioInfo = dioDev->getDioInfo();
unsigned int portNum;
for(portNum = 0; portNum < dioInfo.getNumPorts(); portNum++)
{
if(trigChanDesc.channel == dioInfo.getPortType(portNum))
{
validPort = true;
break;
}
}
if(!validPort)
throw UlException(ERR_BAD_PORT_TYPE);
unsigned long long pattern = ((unsigned long long) level) & ((unsigned long long) variance);
unsigned long long maxPortVal = (1ULL << dioInfo.getNumBits(portNum)) - 1;
if(pattern > maxPortVal)
throw UlException(ERR_BAD_PORT_VAL);
}
else
throw UlException(ERR_BAD_DAQI_CHAN_TYPE);
}
}
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
} /* namespace ul */

59
src/DaqODevice.h Normal file
View File

@ -0,0 +1,59 @@
/*
* DaqODevice.h
*
* Created on: Dec 18, 2017
* Author: Measurement Computing Corporation
*/
#ifndef DAQODEVICE_H_
#define DAQODEVICE_H_
#include "IoDevice.h"
#include "DaqOInfo.h"
#include "interfaces/UlDaqODevice.h"
namespace ul
{
class UL_LOCAL DaqODevice: public IoDevice, public UlDaqODevice
{
public:
virtual ~DaqODevice();
DaqODevice(const DaqDevice& daqDevice);
virtual const UlDaqOInfo& getDaqOInfo() { return mDaqOInfo;}
virtual double daqOutScan(DaqOutChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqOutScanFlag flags, double data[]);
virtual void setTrigger(TriggerType type, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount);
virtual UlError getStatus(ScanStatus* status, TransferStatus* xferStatus);
virtual UlError getStatus(FunctionType functionType, ScanStatus* status, TransferStatus* xferStatus);
virtual void stopBackground();
virtual void stopBackground(FunctionType functionType);
UlError waitUntilDone(FunctionType functionType, double timeout);
virtual double daqOutScan(FunctionType functionType, DaqOutChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqOutScanFlag flags, void* data);
protected:
void check_DaqOutScan_Args(DaqOutChanDescriptor chanDescriptors[], int numChans, int samplesPerChan, double rate, ScanOption options, DaqOutScanFlag flags, void* data) const;
void check_DaqOutSetTrigger_Args(TriggerType type, DaqInChanDescriptor trigChanDesc, double level, double variance, unsigned int retriggerCount) const;
void storeLastStatus();
UlError getLastStatus(FunctionType functionType, TransferStatus* xferStatus);
protected:
DaqOInfo mDaqOInfo;
private:
struct
{
UlError error;
unsigned long long scanCount;
unsigned long long totalCount;
long long index;
}mLastStatus[3];
};
} /* namespace ul */
#endif /* DAQODEVICE_H_ */

156
src/DaqOInfo.cpp Normal file
View File

@ -0,0 +1,156 @@
/*
* DaqOInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DaqOInfo.h"
namespace ul
{
DaqOInfo::DaqOInfo()
{
mChanTypes = (DaqOutChanType) 0;
mMinScanRate = 0;
mMaxScanRate = 0;
mMaxThroughput = 0;
mMaxBurstRate = 0;
mMaxBurstThroughput = 0;
mScanOptions = SO_DEFAULTIO;
mFifoSize = 0;
mMaxQueueLength = 0;
mDaqOutScanFlags = 0;
mTriggerTypes = TRIG_NONE;
}
DaqOInfo::~DaqOInfo()
{
}
void DaqOInfo::setChannelTypes(long long chanTypes)
{
mChanTypes = (DaqOutChanType) chanTypes;
}
DaqOutChanType DaqOInfo::getChannelTypes() const
{
return mChanTypes;
}
void DaqOInfo::setMinScanRate(double minRate)
{
mMinScanRate = minRate;
}
double DaqOInfo::getMinScanRate() const
{
return mMinScanRate;
}
void DaqOInfo::setMaxScanRate(double maxRate)
{
mMaxScanRate = maxRate;
}
double DaqOInfo::getMaxScanRate() const
{
return mMaxScanRate;
}
void DaqOInfo::setMaxThroughput(double maxThroughput)
{
mMaxThroughput = maxThroughput;
}
double DaqOInfo::getMaxThroughput() const
{
return mMaxThroughput;
}
void DaqOInfo::setMaxBurstThroughput(double maxThroughput)
{
mMaxBurstThroughput = maxThroughput;
}
double DaqOInfo::getMaxBurstThroughput() const
{
return mMaxBurstThroughput;
}
void DaqOInfo::setMaxBurstRate(double maxRate)
{
mMaxBurstRate = maxRate;
}
double DaqOInfo::getMaxBurstRate() const
{
return mMaxBurstRate;
}
void DaqOInfo::setFifoSize(int size)
{
mFifoSize = size;
}
int DaqOInfo::getFifoSize() const
{
return mFifoSize;
}
void DaqOInfo::setScanOptions(long long options)
{
mScanOptions = (ScanOption) options;
}
ScanOption DaqOInfo::getScanOptions() const
{
return mScanOptions;
}
void DaqOInfo::setDaqOutScanFlags(long long flags)
{
mDaqOutScanFlags = flags;
}
long long DaqOInfo::getDaqOutScanFlags() const
{
return mDaqOutScanFlags;
}
void DaqOInfo::setTriggerTypes(long long triggerTypes)
{
mTriggerTypes = (TriggerType) triggerTypes;
}
TriggerType DaqOInfo::getTriggerTypes() const
{
return mTriggerTypes;
}
bool DaqOInfo::supportsTrigger() const
{
bool supportsTrig = false;
if(mTriggerTypes)
supportsTrig = true;
return supportsTrig;
}
void DaqOInfo::setMaxQueueLength(int length)
{
mMaxQueueLength = length;
}
int DaqOInfo::getMaxQueueLength() const
{
return mMaxQueueLength;
}
} /* namespace ul */

67
src/DaqOInfo.h Normal file
View File

@ -0,0 +1,67 @@
/*
* DaqOInfo.h
*
* Author: Measurement Computing Corporation
*/
#ifndef DAQOINFO_H_
#define DAQOINFO_H_
#include <vector>
#include "interfaces/UlDaqOInfo.h"
#include "ul_internal.h"
namespace ul
{
class UL_LOCAL DaqOInfo: public UlDaqOInfo
{
public:
DaqOInfo();
virtual ~DaqOInfo();
void setChannelTypes(long long chanTypes);
DaqOutChanType getChannelTypes() const;
void setMinScanRate(double minRate);
double getMinScanRate() const;
void setMaxScanRate(double maxRate);
double getMaxScanRate() const;
void setMaxThroughput(double maxThroughput);
double getMaxThroughput() const;
void setMaxBurstThroughput(double maxThroughput);
double getMaxBurstThroughput() const;
void setMaxBurstRate(double maxRate);
double getMaxBurstRate() const;
void setFifoSize(int size);
int getFifoSize() const;
void setScanOptions(long long options);
ScanOption getScanOptions() const;
void setDaqOutScanFlags(long long flags);
long long getDaqOutScanFlags() const;
void setMaxQueueLength(int length);
int getMaxQueueLength() const;
void setTriggerTypes(long long triggerTypes);
TriggerType getTriggerTypes() const;
bool supportsTrigger() const;
private:
DaqOutChanType mChanTypes;
TriggerType mTriggerTypes;
double mMinScanRate;
double mMaxScanRate;
double mMaxThroughput;
double mMaxBurstRate;
double mMaxBurstThroughput;
ScanOption mScanOptions;
int mFifoSize;
int mMaxQueueLength;
long long mDaqOutScanFlags;
};
} /* namespace ul */
#endif /* DAQOINFO_H_ */

52
src/DevMemInfo.cpp Normal file
View File

@ -0,0 +1,52 @@
/*
* DevMemInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DevMemInfo.h"
#include "UlException.h"
namespace ul
{
DevMemInfo::DevMemInfo()
{
}
DevMemInfo::~DevMemInfo()
{
}
void DevMemInfo::addMemRegion(MemRegion memRegionType, unsigned long long address, unsigned long long size, MemAccessType accessTypes)
{
mMemRegionMap.insert(std::pair<MemRegion, MemRegionInfo>(memRegionType, MemRegionInfo(memRegionType, address, size, accessTypes)));
}
MemRegion DevMemInfo::getMemRegionTypes() const
{
MemRegion regionTypes = (MemRegion) 0;
for(std::map<MemRegion, MemRegionInfo>::iterator itr = mMemRegionMap.begin(); itr != mMemRegionMap.end(); itr++)
{
regionTypes = (MemRegion) (regionTypes | itr->first);
}
return regionTypes;
}
UlMemRegionInfo& DevMemInfo::getMemRegionInfo(MemRegion memRegionType) const
{
MemRegionInfo* info = NULL;
std::map<MemRegion, MemRegionInfo>::iterator itr = mMemRegionMap.find(memRegionType);
if(itr != mMemRegionMap.end())
info = &itr->second;
else
throw UlException(ERR_BAD_MEM_REGION);
return *info;
}
} /* namespace ul */

37
src/DevMemInfo.h Normal file
View File

@ -0,0 +1,37 @@
/*
* DevMemInfo.h
*
* Created on: Jan 18, 2018
* Author: Measurement Computing Corporation
*/
#ifndef DEVMEMINFO_H_
#define DEVMEMINFO_H_
#include <map>
#include "interfaces/UlDevMemInfo.h"
#include "ul_internal.h"
#include "MemRegionInfo.h"
namespace ul
{
class UL_LOCAL DevMemInfo: public UlDevMemInfo
{
public:
DevMemInfo();
virtual ~DevMemInfo();
void addMemRegion(MemRegion memRegionType, unsigned long long address, unsigned long long size, MemAccessType accessTypes);
virtual MemRegion getMemRegionTypes() const;
virtual UlMemRegionInfo& getMemRegionInfo(MemRegion memRegionType) const;
private:
mutable std::map<MemRegion, MemRegionInfo> mMemRegionMap;
};
} /* namespace ul */
#endif /* DEVMEMINFO_H_ */

29
src/DioConfig.cpp Normal file
View File

@ -0,0 +1,29 @@
/*
* DioConfig.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DioDevice.h"
#include "DioConfig.h"
#include "uldaq.h"
namespace ul
{
DioConfig::DioConfig(DioDevice& dioDevice) : mDioDevice(dioDevice)
{
}
DioConfig::~DioConfig()
{
}
unsigned long long DioConfig::getPortDirectionMask(int portNum)
{
return mDioDevice.getCfg_PortDirectionMask(portNum);
}
} /* namespace ul */

30
src/DioConfig.h Normal file
View File

@ -0,0 +1,30 @@
/*
* DioConfig.h
*
* Author: Measurement Computing Corporation
*/
#ifndef DIOCONFIG_H_
#define DIOCONFIG_H_
#include "interfaces/UlDioConfig.h"
#include "ul_internal.h"
namespace ul
{
class DioDevice;
class UL_LOCAL DioConfig: public UlDioConfig
{
public:
DioConfig(DioDevice& dioDevice);
virtual ~DioConfig();
virtual unsigned long long getPortDirectionMask(int portNum);
private:
DioDevice& mDioDevice;
};
} /* namespace ul */
#endif /* DIOCONFIG_H_ */

525
src/DioDevice.cpp Normal file
View File

@ -0,0 +1,525 @@
/*
* DioDevice.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DioDevice.h"
#include "UlException.h"
namespace ul
{
DioDevice::DioDevice(const DaqDevice& daqDevice) : IoDevice(daqDevice), UlDioDevice()
{
mDioConfig = new DioConfig(*this);
mScanInState = SS_IDLE;
mScanOutState = SS_IDLE;
mDisableCheckDirection = false;
memset(&mDiTrigCfg, 0, sizeof(mDiTrigCfg));
mDiTrigCfg.type = TRIG_POS_EDGE;
memset(&mDoTrigCfg, 0, sizeof(mDoTrigCfg));
mDoTrigCfg.type = TRIG_POS_EDGE;
}
DioDevice::~DioDevice()
{
if(mDioConfig != NULL)
{
delete mDioConfig;
mDioConfig = NULL;
}
}
void DioDevice::dConfigPort(DigitalPortType portType, DigitalDirection direction)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void DioDevice::dConfigBit(DigitalPortType portType, int bitNum, DigitalDirection direction)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
unsigned long long DioDevice::dIn(DigitalPortType portType)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void DioDevice::dOut(DigitalPortType portType, unsigned long long data)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
bool DioDevice::dBitIn(DigitalPortType portType, int bitNum)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void DioDevice::dBitOut(DigitalPortType portType, int bitNum, bool bitValue)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
double DioDevice::dInScan(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DInScanFlag flags, unsigned long long data[])
{
throw UlException(ERR_BAD_DEV_TYPE);
}
double DioDevice::dOutScan(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DOutScanFlag flags, unsigned long long data[])
{
throw UlException(ERR_BAD_DEV_TYPE);
}
UlError DioDevice::getStatus(ScanDirection direction, ScanStatus* status, TransferStatus* xferStatus)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void DioDevice::stopBackground(ScanDirection direction)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void DioDevice::setTrigger(ScanDirection direction, TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount)
{
check_SetTrigger_Args(direction, type, trigChan, level, variance, retriggerCount);
if(direction == SD_INPUT)
{
mDiTrigCfg.type = type;
mDiTrigCfg.trigChan = trigChan;
mDiTrigCfg.level = level;
mDiTrigCfg.variance = variance;
mDiTrigCfg.retrigCount = retriggerCount;
}
else
{
mDoTrigCfg.type = type;
mDoTrigCfg.trigChan = trigChan;
mDoTrigCfg.level = level;
mDoTrigCfg.variance = variance;
mDoTrigCfg.retrigCount = retriggerCount;
}
}
void DioDevice::dInSetTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount)
{
setTrigger(SD_INPUT, type, trigChan, level, variance, retriggerCount);
}
void DioDevice::dOutSetTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount)
{
setTrigger(SD_OUTPUT, type, trigChan, level, variance, retriggerCount);
}
UlError DioDevice::dInGetStatus(ScanStatus* status, TransferStatus* xferStatus)
{
return getStatus(SD_INPUT, status, xferStatus);
}
UlError DioDevice::dOutGetStatus(ScanStatus* status, TransferStatus* xferStatus)
{
return getStatus(SD_OUTPUT, status, xferStatus);
}
void DioDevice::dInStopBackground()
{
stopBackground(SD_INPUT);
}
void DioDevice::dOutStopBackground()
{
stopBackground(SD_OUTPUT);
}
void DioDevice::initPortsDirectionMask()
{
std::bitset<32> portDirectionMask;
portDirectionMask.reset();
unsigned int portDirMask = 0;
mPortDirectionMask.clear();
for(unsigned int portNum = 0; portNum < mDioInfo.getNumPorts(); portNum++)
{
portDirMask = readPortDirMask(portNum);
std::bitset<32> portDirectionMask(portDirMask);
mPortDirectionMask.push_back(portDirectionMask);
}
}
TriggerConfig DioDevice::getTrigConfig(ScanDirection direction) const
{
if(direction == SD_INPUT)
return mDiTrigCfg;
else
return mDoTrigCfg;
}
void DioDevice::check_DConfigPort_Args(DigitalPortType portType, DigitalDirection direction)
{
if(mDioInfo.isPortSupported(portType) == false)
throw UlException(ERR_BAD_PORT_TYPE);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_DConfigBit_Args(DigitalPortType portType, int bitNum, DigitalDirection direction)
{
if(mDioInfo.isPortSupported(portType) == false)
throw UlException(ERR_BAD_PORT_TYPE);
int portNum = mDioInfo.getPortNum(portType);
int bitCount = mDioInfo.getNumBits(portNum);
if(bitCount <= bitNum)
throw UlException(ERR_BAD_BIT_NUM);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_DIn_Args(DigitalPortType portType)
{
if(mDioInfo.isPortSupported(portType) == false)
throw UlException(ERR_BAD_PORT_TYPE);
int portNum = mDioInfo.getPortNum(portType);
DigitalPortIoType ioType = mDioInfo.getPortIoType(portNum);
if(ioType == DPIOT_OUT)
throw UlException(ERR_WRONG_DIG_CONFIG);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_DOut_Args(DigitalPortType portType, unsigned long long data)
{
if(mDioInfo.isPortSupported(portType) == false)
throw UlException(ERR_BAD_PORT_TYPE);
int portNum = mDioInfo.getPortNum(portType);
int bitCount = mDioInfo.getNumBits(portNum);
DigitalPortIoType ioType = mDioInfo.getPortIoType(portNum);
if(ioType == DPIOT_IN)
throw UlException(ERR_WRONG_DIG_CONFIG);
else if((ioType == DPIOT_IO || ioType == DPIOT_BITIO) && !mDisableCheckDirection)
{
if(mPortDirectionMask[portNum].any())
throw UlException(ERR_WRONG_DIG_CONFIG);
}
unsigned long maxVal = (1 << bitCount) - 1;
if(data > maxVal)
throw UlException(ERR_BAD_PORT_VAL);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_DBitIn_Args(DigitalPortType portType, int bitNum)
{
if(mDioInfo.isPortSupported(portType) == false)
throw UlException(ERR_BAD_PORT_TYPE);
int portNum = mDioInfo.getPortNum(portType);
int bitCount = mDioInfo.getNumBits(portNum);
if(bitNum < 0 || bitNum >= bitCount)
throw UlException(ERR_BAD_BIT_NUM);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_DBitOut_Args(DigitalPortType portType, int bitNum)
{
if(mDioInfo.isPortSupported(portType) == false)
throw UlException(ERR_BAD_PORT_TYPE);
int portNum = mDioInfo.getPortNum(portType);
int bitCount = mDioInfo.getNumBits(portNum);
if(bitNum < 0 || bitNum >= bitCount)
throw UlException(ERR_BAD_BIT_NUM);
DigitalPortIoType ioType = mDioInfo.getPortIoType(portNum);
if(ioType == DPIOT_IN)
throw UlException(ERR_WRONG_DIG_CONFIG);
else if((ioType == DPIOT_IO || ioType == DPIOT_BITIO) && !mDisableCheckDirection)
{
if(mPortDirectionMask[portNum][bitNum])
throw UlException(ERR_WRONG_DIG_CONFIG);
}
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_DInScan_Args(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DInScanFlag flags, unsigned long long data[]) const
{
if(!mDioInfo.isPortSupported(lowPort) || !mDioInfo.isPortSupported(highPort))
throw UlException(ERR_BAD_PORT_TYPE);
int lowPortNum = mDioInfo.getPortNum(lowPort);
int highPortNum = mDioInfo.getPortNum(highPort);
int numOfScanPorts = highPortNum - lowPortNum + 1;
if(!mDioInfo.hasPacer(DD_INPUT))
throw UlException(ERR_BAD_DEV_TYPE);
if(getScanState(SD_INPUT) == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(((options & SO_SINGLEIO) && (options & SO_BLOCKIO)) || ((options & SO_SINGLEIO) && (options & SO_BURSTIO)) || ((options & SO_BLOCKIO) && (options & SO_BURSTIO)))
throw UlException(ERR_BAD_OPTION);
if(lowPortNum > highPortNum )
throw UlException(ERR_BAD_PORT_TYPE);
for(int portNum = lowPortNum; portNum <=highPortNum; portNum++)
{
if(mDioInfo.getPortIoType(portNum) == DPIOT_OUT)
throw UlException(ERR_WRONG_DIG_CONFIG);
}
if(data == NULL)
throw UlException(ERR_BAD_BUFFER);
if(~mDioInfo.getScanOptions(DD_INPUT) & options)
throw UlException(ERR_BAD_OPTION);
if(~mDioInfo.getScanFlags(DD_INPUT) & flags)
throw UlException(ERR_BAD_FLAG);
double throughput = rate * numOfScanPorts;
if(!(options & SO_EXTCLOCK))
{
if(((options & SO_BURSTIO) && (rate > mDioInfo.getDiMaxBurstRate() || throughput > mDioInfo.getDiMaxBurstThroughput())) || (!(options & SO_BURSTIO) && (rate > mDioInfo.getMaxScanRate(DD_INPUT) || throughput > mDioInfo.getMaxThroughput(DD_INPUT))) )
throw UlException(ERR_BAD_RATE);
}
if(rate <= 0.0)
throw UlException(ERR_BAD_RATE);
if(samplesPerPort < mMinScanSampleCount)
throw UlException(ERR_BAD_SAMPLE_COUNT);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_DOutScan_Args(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DOutScanFlag flags, unsigned long long data[]) const
{
if(!mDioInfo.isPortSupported(lowPort) || !mDioInfo.isPortSupported(highPort))
throw UlException(ERR_BAD_PORT_TYPE);
int lowPortNum = mDioInfo.getPortNum(lowPort);
int highPortNum = mDioInfo.getPortNum(highPort);
int numOfScanPorts = highPortNum - lowPortNum + 1;
if(!mDioInfo.hasPacer(DD_OUTPUT))
throw UlException(ERR_BAD_DEV_TYPE);
if(getScanState(SD_OUTPUT) == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
if(((options & SO_SINGLEIO) && (options & SO_BLOCKIO)) || ((options & SO_SINGLEIO) && (options & SO_BURSTIO)) || ((options & SO_BLOCKIO) && (options & SO_BURSTIO)))
throw UlException(ERR_BAD_OPTION);
if(lowPortNum > highPortNum )
throw UlException(ERR_BAD_PORT_TYPE);
DigitalPortIoType ioType;
for(int portNum = lowPortNum; portNum <=highPortNum; portNum++)
{
ioType = mDioInfo.getPortIoType(portNum);
if(ioType == DPIOT_IN)
throw UlException(ERR_WRONG_DIG_CONFIG);
else if((ioType == DPIOT_IO || ioType == DPIOT_BITIO) && !mDisableCheckDirection)
{
if(mPortDirectionMask[portNum].any())
throw UlException(ERR_WRONG_DIG_CONFIG);
}
}
if(data == NULL)
throw UlException(ERR_BAD_BUFFER);
if(~mDioInfo.getScanOptions(DD_OUTPUT) & options)
throw UlException(ERR_BAD_OPTION);
if(~mDioInfo.getScanFlags(DD_OUTPUT) & flags)
throw UlException(ERR_BAD_FLAG);
double throughput = rate * numOfScanPorts;
if(!(options & SO_EXTCLOCK))
{
if(rate > mDioInfo.getMaxScanRate(DD_OUTPUT) || throughput > mDioInfo.getMaxThroughput(DD_OUTPUT))
throw UlException(ERR_BAD_RATE);
}
if(rate <= 0.0)
throw UlException(ERR_BAD_RATE);
if(samplesPerPort < mMinScanSampleCount)
throw UlException(ERR_BAD_SAMPLE_COUNT);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void DioDevice::check_SetTrigger_Args(ScanDirection direction, TriggerType trigType, int trigChan, double level, double variance, unsigned int retriggerCount) const
{
DigitalDirection digitalDirection = DD_INPUT;
if(direction == SD_OUTPUT)
digitalDirection = DD_OUTPUT;
if(mDioInfo.supportsTrigger(digitalDirection))
{
if(!(mDioInfo.getTriggerTypes(digitalDirection) & trigType))
throw UlException(ERR_BAD_TRIG_TYPE);
std::bitset<32> typeBitSet(trigType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_TRIG_TYPE);
if(retriggerCount > 0 && !(mDioInfo.getScanOptions(digitalDirection) & SO_RETRIGGER))
throw UlException(ERR_BAD_RETRIG_COUNT);
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
std::bitset<32> DioDevice::getPortDirection(DigitalPortType portType) const
{
int portNum = mDioInfo.getPortNum(portType);
return mPortDirectionMask[portNum];
}
void DioDevice::setPortDirection(DigitalPortType portType, DigitalDirection direction)
{
int portNum = mDioInfo.getPortNum(portType);
unsigned int bitCount = mDioInfo.getNumBits(portNum);
if(direction == DD_OUTPUT)
mPortDirectionMask[portNum].reset();
else
{
for(unsigned int bit = 0; bit < bitCount; bit++)
mPortDirectionMask[portNum].set(bit, true);
}
}
void DioDevice::setBitDirection(DigitalPortType portType, int bitNum, DigitalDirection direction)
{
int portNum = mDioInfo.getPortNum(portType);
if(direction == DD_OUTPUT)
mPortDirectionMask[portNum].reset(bitNum);
else
mPortDirectionMask[portNum].set(bitNum);
}
void DioDevice::setScanState(ScanDirection direction, ScanStatus state)
{
if(direction == SD_INPUT)
mScanInState = state;
else
mScanOutState = state;
}
ScanStatus DioDevice::getScanState(ScanDirection direction) const
{
if(direction == SD_INPUT)
return mScanInState;
else
return mScanOutState;
}
void DioDevice::stopBackground()
{
if(getScanState(SD_INPUT) == SS_RUNNING)
stopBackground(SD_INPUT);
if(getScanState(SD_OUTPUT) == SS_RUNNING)
stopBackground(SD_OUTPUT);
}
ScanStatus DioDevice::getScanState() const
{
ScanStatus scanState = SS_IDLE;
if(getScanState(SD_INPUT) == SS_RUNNING || getScanState(SD_OUTPUT) == SS_RUNNING)
scanState = SS_RUNNING;
return scanState;
}
UlError DioDevice::wait(ScanDirection direction, WaitType waitType, long long waitParam, double timeout)
{
UlError err = ERR_NO_ERROR;
if(waitType == WAIT_UNTIL_DONE)
{
err = waitUntilDone(direction, timeout);
}
return err;
}
UlError DioDevice::waitUntilDone(ScanDirection direction, double timeout)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
////////////////////// Configuration functions /////////////////////////////////
unsigned long long DioDevice::getCfg_PortDirectionMask(unsigned int portNum) const
{
mDaqDevice.checkConnection();
unsigned long long dirMask = 0;
if(portNum < mDioInfo.getNumPorts())
{
DigitalPortType portType = mDioInfo.getPortType(portNum);
std::bitset<32> bitsetMask = getPortDirection(portType);
int portNum = mDioInfo.getPortNum(portType);
int bitCount = mDioInfo.getNumBits(portNum);
unsigned long long bits = (1ULL << bitCount) - 1;
dirMask = bitsetMask.flip().to_ulong() & bits;
}
return dirMask;
}
} /* namespace ul */

100
src/DioDevice.h Normal file
View File

@ -0,0 +1,100 @@
/*
* DioDevice.h
*
* Created on: Oct 19, 2017
* Author: Measurement Computing Corporation
*/
#ifndef DIODEVICE_H_
#define DIODEVICE_H_
#include <vector>
#include <bitset>
#include "IoDevice.h"
#include "DioInfo.h"
#include "DioConfig.h"
#include "interfaces/UlDioDevice.h"
namespace ul
{
class UL_LOCAL DioDevice: public IoDevice, public UlDioDevice
{
public:
DioDevice(const DaqDevice& daqDevice);
virtual ~DioDevice();
virtual const UlDioInfo& getDioInfo() { return mDioInfo;}
virtual UlDioConfig& getDioConfig() { return *mDioConfig;}
virtual void dConfigPort(DigitalPortType portType, DigitalDirection direction);
virtual void dConfigBit(DigitalPortType portType, int bitNum, DigitalDirection direction);
virtual unsigned long long dIn(DigitalPortType portType);
virtual void dOut(DigitalPortType portType, unsigned long long data);
virtual bool dBitIn(DigitalPortType portType, int bitNum);
virtual void dBitOut(DigitalPortType portType, int bitNum, bool bitValue);
virtual double dInScan(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DInScanFlag flags, unsigned long long data[]);
virtual double dOutScan(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DOutScanFlag flags, unsigned long long data[]);
void setScanState(ScanDirection direction, ScanStatus state);
virtual ScanStatus getScanState(ScanDirection direction) const;
ScanStatus getScanState() const;
virtual UlError getStatus(ScanDirection direction, ScanStatus* status, TransferStatus* xferStatus);
virtual void stopBackground(ScanDirection direction);
virtual void stopBackground();
virtual UlError wait(ScanDirection direction, WaitType waitType, long long waitParam, double timeout);
virtual UlError waitUntilDone(ScanDirection direction, double timeout);
void setTrigger(ScanDirection direction, TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount);
TriggerConfig getTrigConfig(ScanDirection direction) const;
virtual void dInSetTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount);
virtual void dOutSetTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount);
virtual UlError dInGetStatus(ScanStatus* status, TransferStatus* xferStatus);
virtual UlError dOutGetStatus(ScanStatus* status, TransferStatus* xferStatus);
virtual void dInStopBackground();
virtual void dOutStopBackground();
////////////////////// Configuration functions /////////////////////////////////
virtual unsigned long long getCfg_PortDirectionMask(unsigned int portNum) const;
protected:
void initPortsDirectionMask();
virtual unsigned long readPortDirMask(unsigned int portNum) const { return 0; }
void check_DConfigPort_Args(DigitalPortType portType, DigitalDirection direction);
void check_DConfigBit_Args(DigitalPortType portType, int bitNum, DigitalDirection direction);
void check_DIn_Args(DigitalPortType portType);
void check_DOut_Args(DigitalPortType portType, unsigned long long data);
void check_DBitIn_Args(DigitalPortType portType, int bitNum);
void check_DBitOut_Args(DigitalPortType portType, int bitNum);
void check_DInScan_Args(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DInScanFlag flags, unsigned long long data[]) const;
void check_DOutScan_Args(DigitalPortType lowPort, DigitalPortType highPort, int samplesPerPort, double rate, ScanOption options, DOutScanFlag flags, unsigned long long data[]) const;
virtual void check_SetTrigger_Args(ScanDirection direction, TriggerType trigType, int trigChan, double level, double variance, unsigned int retriggerCount) const;
std::bitset<32> getPortDirection(DigitalPortType portType) const;
void setPortDirection(DigitalPortType portType, DigitalDirection direction);
void setBitDirection(DigitalPortType portType, int bitNum, DigitalDirection direction);
protected:
DioInfo mDioInfo;
DioConfig* mDioConfig;
private:
std::vector<std::bitset<32> > mPortDirectionMask;
ScanStatus mScanInState;
ScanStatus mScanOutState;
TriggerConfig mDiTrigCfg;
TriggerConfig mDoTrigCfg;
bool mDisableCheckDirection;
};
} /* namespace ul */
#endif /* DIODEVICE_H_ */

329
src/DioInfo.cpp Normal file
View File

@ -0,0 +1,329 @@
/*
* DioInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DioInfo.h"
namespace ul
{
DioInfo::DioInfo()
{
mDiHasPacer = false;
mDoHasPacer = false;
mDiMinScanRate = 0;
mDiMaxScanRate = 0;
mDiMaxThroughput = 0.0;
mDiMaxBurstRate = 0;
mDiMaxBurstThroughput = 0.0;
mDiScanOptions = SO_DEFAULTIO;
mDiScanFlags = 0;
mDiTriggerTypes = (TriggerType) 0;
mDiFifoSize = 0;
mDoMinScanRate = 0;
mDoMaxScanRate = 0;
mDoMaxThroughput = 0;
mDoScanOptions = SO_DEFAULTIO;
mDoScanFlags = 0;
mDoTriggerTypes = (TriggerType) 0;
mDoFifoSize = 0;
}
DioInfo::~DioInfo()
{
}
void DioInfo::addPort(unsigned int portNum, DigitalPortType type, unsigned int numBits, DigitalPortIoType ioType)
{
mPortInfo.push_back(DioPortInfo(portNum, type, numBits, ioType));
}
unsigned int DioInfo::getNumPorts() const
{
return mPortInfo.size();
}
DioPortInfo DioInfo::getPortInfo(unsigned int portNum) const
{
DioPortInfo portInfo(-1, (DigitalPortType)-1, -1, (DigitalPortIoType)-1);
if(portNum < getNumPorts())
{
portInfo = mPortInfo[portNum];
}
return portInfo;
}
DigitalPortType DioInfo::getPortType(unsigned int portNum) const
{
DigitalPortType type = (DigitalPortType) 0;
if(portNum < getNumPorts())
{
type = mPortInfo[portNum].getType();
}
return type;
}
unsigned int DioInfo::getNumBits(unsigned int portNum) const
{
unsigned int bitCount = 0;
if(portNum < getNumPorts())
{
bitCount = mPortInfo[portNum].getNumBits();
}
return bitCount;
}
DigitalPortIoType DioInfo::getPortIoType(unsigned int portNum) const
{
DigitalPortIoType ioType = (DigitalPortIoType) 0;
if(portNum < getNumPorts())
{
ioType = mPortInfo[portNum].getPortIOType();
}
return ioType;
}
bool DioInfo::hasPacer(DigitalDirection direction) const
{
bool hasPaser = false;
if(direction == DD_INPUT)
hasPaser = mDiHasPacer;
else if(direction == DD_OUTPUT)
hasPaser = mDoHasPacer;
return hasPaser;
}
void DioInfo::hasPacer(DigitalDirection direction, bool hasPacer)
{
if(direction == DD_INPUT)
mDiHasPacer = hasPacer;
else
mDoHasPacer = hasPacer;
}
void DioInfo::setMinScanRate(DigitalDirection direction, double minRate)
{
if(direction == DD_INPUT)
mDiMinScanRate = minRate;
else
mDoMinScanRate = minRate;
}
double DioInfo::getMinScanRate(DigitalDirection direction) const
{
double minRate = 0;
if(direction == DD_INPUT)
minRate = mDiMinScanRate;
else if(direction == DD_OUTPUT)
minRate = mDoMinScanRate;
return minRate;
}
void DioInfo::setMaxScanRate(DigitalDirection direction, double maxRate)
{
if(direction == DD_INPUT)
mDiMaxScanRate = maxRate;
else
mDoMaxScanRate = maxRate;
}
double DioInfo::getMaxScanRate(DigitalDirection direction) const
{
double maxRate = 0;
if(direction == DD_INPUT)
maxRate = mDiMaxScanRate;
else if(direction == DD_OUTPUT)
maxRate = mDoMaxScanRate;
return maxRate;
}
void DioInfo::setMaxThroughput(DigitalDirection direction, double maxThroughput)
{
if(direction == DD_INPUT)
mDiMaxThroughput = maxThroughput;
else
mDoMaxThroughput = maxThroughput;
}
double DioInfo::getMaxThroughput(DigitalDirection direction) const
{
double maxThroughput = 0;
if(direction == DD_INPUT)
maxThroughput = mDiMaxThroughput;
else if(direction == DD_OUTPUT)
maxThroughput = mDoMaxThroughput;
return maxThroughput;
}
void DioInfo::setDiMaxBurstThroughput(double maxThroughput)
{
mDiMaxBurstThroughput = maxThroughput;
}
double DioInfo::getDiMaxBurstThroughput() const
{
return mDiMaxBurstThroughput;
}
void DioInfo::setDiMaxBurstRate(double maxRate)
{
mDiMaxBurstRate = maxRate;
}
double DioInfo::getDiMaxBurstRate() const
{
return mDiMaxBurstRate;
}
void DioInfo::setFifoSize(DigitalDirection direction, int size)
{
if(direction == DD_INPUT)
mDiFifoSize = size;
else
mDoFifoSize = size;
}
int DioInfo::getFifoSize(DigitalDirection direction) const
{
int fifoSize = 0;
if(direction == DD_INPUT)
fifoSize = mDiFifoSize;
else if(direction == DD_OUTPUT)
fifoSize = mDoFifoSize;
return fifoSize;
}
void DioInfo::setScanOptions(DigitalDirection direction, long long options)
{
if(direction == DD_INPUT)
mDiScanOptions = (ScanOption) options;
else
mDoScanOptions = (ScanOption) options;
}
ScanOption DioInfo::getScanOptions(DigitalDirection direction) const
{
ScanOption scanOptions = SO_DEFAULTIO;
if(direction == DD_INPUT)
scanOptions = mDiScanOptions;
else if(direction == DD_OUTPUT)
scanOptions = mDoScanOptions;
return scanOptions;
}
void DioInfo::setScanFlags(DigitalDirection direction, long long flags)
{
if(direction == DD_INPUT)
mDiScanFlags = flags;
else
mDoScanFlags = flags;
}
long long DioInfo::getScanFlags(DigitalDirection direction) const
{
long long flags = 0;
if(direction == DD_INPUT)
flags = mDiScanFlags;
else if(direction == DD_OUTPUT)
flags = mDoScanFlags;
return flags;
}
void DioInfo::setTriggerTypes(DigitalDirection direction, long long triggerTypes)
{
if(direction == DD_INPUT)
mDiTriggerTypes = (TriggerType) triggerTypes;
else
mDoTriggerTypes = (TriggerType) triggerTypes;
}
TriggerType DioInfo::getTriggerTypes(DigitalDirection direction) const
{
TriggerType types = TRIG_NONE;
if(direction == DD_INPUT)
types = mDiTriggerTypes;
else if(direction == DD_OUTPUT)
types = mDoTriggerTypes;
return types;
}
bool DioInfo::supportsTrigger(DigitalDirection direction) const
{
bool supportsTrig = false;
TriggerType types;
if(direction == DD_INPUT)
types = mDiTriggerTypes;
else
types = mDoTriggerTypes;
if(types)
supportsTrig = true;
return supportsTrig;
}
bool DioInfo::isPortSupported(DigitalPortType portType) const
{
bool supported = false;
if(getPortNum(portType) != -1)
supported = true;
return supported;
}
int DioInfo::getPortNum(DigitalPortType portType) const
{
int portIndex = -1;
DigitalPortType type;
for(unsigned int i = 0; i < getNumPorts(); i++)
{
type = getPortType(i);
if(type == portType)
{
portIndex = i;
break;
}
}
return portIndex;
}
} /* namespace ul */

88
src/DioInfo.h Normal file
View File

@ -0,0 +1,88 @@
/*
* DioInfo.h
*
* Author: Measurement Computing Corporation
*/
#ifndef DIOINFO_H_
#define DIOINFO_H_
#include <vector>
#include "ul_internal.h"
#include "DioPortInfo.h"
#include "interfaces/UlDioInfo.h"
namespace ul
{
class UL_LOCAL DioInfo: public UlDioInfo
{
public:
DioInfo();
virtual ~DioInfo();
void addPort(unsigned int portNum, DigitalPortType type, unsigned int numBits, DigitalPortIoType ioType);
unsigned int getNumPorts() const;
DioPortInfo getPortInfo(unsigned int portNum) const;
DigitalPortType getPortType(unsigned int portNum) const;
unsigned int getNumBits(unsigned int portNum) const;
DigitalPortIoType getPortIoType(unsigned int portNum) const;
void setMinScanRate(DigitalDirection direction, double minRate);
double getMinScanRate(DigitalDirection direction) const;
void setMaxScanRate(DigitalDirection direction, double maxRate);
double getMaxScanRate(DigitalDirection direction) const;
void setMaxThroughput(DigitalDirection direction, double maxThroughput);
double getMaxThroughput(DigitalDirection direction) const;
void setDiMaxBurstThroughput(double maxThroughput);
double getDiMaxBurstThroughput() const;
void setDiMaxBurstRate(double maxRate);
double getDiMaxBurstRate() const;
void setFifoSize(DigitalDirection direction, int size);
int getFifoSize(DigitalDirection direction) const;
void setScanOptions(DigitalDirection direction, long long options);
ScanOption getScanOptions(DigitalDirection direction) const;
void setScanFlags(DigitalDirection direction, long long flags);
long long getScanFlags(DigitalDirection direction) const;
bool hasPacer(DigitalDirection direction) const;
void hasPacer(DigitalDirection direction, bool hasPacer);
void setTriggerTypes(DigitalDirection direction, long long triggerTypes);
TriggerType getTriggerTypes(DigitalDirection direction) const;
bool supportsTrigger(DigitalDirection direction) const;
bool isPortSupported(DigitalPortType portType) const;
int getPortNum(DigitalPortType portType) const;
private:
std::vector<DioPortInfo> mPortInfo;
TriggerType mDiTriggerTypes;
TriggerType mDoTriggerTypes;
long long mDiScanFlags;
long long mDoScanFlags;
bool mDiHasPacer;
bool mDoHasPacer;
double mDiMinScanRate;
double mDiMaxScanRate;
double mDiMaxThroughput;
ScanOption mDiScanOptions;
double mDiMaxBurstRate;
double mDiMaxBurstThroughput;
unsigned int mDiFifoSize;
double mDoMinScanRate;
double mDoMaxScanRate;
double mDoMaxThroughput;
ScanOption mDoScanOptions;
unsigned int mDoFifoSize;
};
} /* namespace ul */
#endif /* DIOINFO_H_ */

46
src/DioPortInfo.cpp Normal file
View File

@ -0,0 +1,46 @@
/*
* DioPortInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "DioPortInfo.h"
namespace ul
{
DioPortInfo::DioPortInfo(int portNum, DigitalPortType type, unsigned int numBits, DigitalPortIoType ioType)
{
mNum = portNum;
mType = type;
mNumBits = numBits;
mIoType = ioType;
}
DioPortInfo::~DioPortInfo()
{
}
unsigned int DioPortInfo::getPortNum() const
{
return mNum;
}
DigitalPortType DioPortInfo::getType() const
{
return mType;
}
unsigned int DioPortInfo::getNumBits() const
{
return mNumBits;
}
DigitalPortIoType DioPortInfo::getPortIOType() const
{
return mIoType;
}
} /* namespace ul */

37
src/DioPortInfo.h Normal file
View File

@ -0,0 +1,37 @@
/*
* DioPortInfo.h
*
* Author: Measurement Computing Corporation
*/
#ifndef DIOPORTINFO_H_
#define DIOPORTINFO_H_
#include "interfaces/UlDioPortInfo.h"
#include "uldaq.h"
#include "ul_internal.h"
namespace ul
{
class UL_LOCAL DioPortInfo: public UlDioPortInfo
{
public:
DioPortInfo(int portNum, DigitalPortType type, unsigned int numBits, DigitalPortIoType ioType);
virtual ~DioPortInfo();
unsigned int getPortNum() const;
DigitalPortType getType() const;
unsigned int getNumBits() const;
DigitalPortIoType getPortIOType() const;
private:
unsigned int mNum;
DigitalPortType mType;
unsigned int mNumBits;
DigitalPortIoType mIoType;
};
} /* namespace ul */
#endif /* DIOPORTINFO_H_ */

241
src/IoDevice.cpp Normal file
View File

@ -0,0 +1,241 @@
/*
* IoDevice.cpp
*
* Author: Measurement Computing Corporation
*/
#include <limits.h>
#include "IoDevice.h"
#include "UlException.h"
namespace ul
{
IoDevice::IoDevice(const DaqDevice& daqDevice): mDaqDevice(daqDevice), mMinScanSampleCount(1), mEndian(Endian::Instance()), mScanState(SS_IDLE), mActualScanRate(0.0)
{
memset(&mScanInfo, 0, sizeof(mScanInfo));
memset(&mTrigCfg, 0, sizeof(mTrigCfg));
mTrigCfg.type = TRIG_POS_EDGE;
UlLock::initMutex(mIoDeviceMutex, PTHREAD_MUTEX_RECURSIVE);
UlLock::initMutex(mProcessScanDataMutex, PTHREAD_MUTEX_RECURSIVE);
}
IoDevice::~IoDevice()
{
UlLock::destroyMutex(mIoDeviceMutex);
UlLock::destroyMutex(mProcessScanDataMutex);
}
void IoDevice::disconnect()
{
try
{
if(getScanState() == SS_RUNNING)
stopBackground();
}
catch(UlException& e)
{
//UL_LOG("Ul exception occurred: " << e.what());
}
}
void IoDevice::setScanState(ScanStatus state)
{
mScanState = state;
}
ScanStatus IoDevice::getScanState() const
{
return mScanState;
}
void IoDevice::setActualScanRate(double rate)
{
mActualScanRate = rate;
}
double IoDevice::actualScanRate() const
{
return mActualScanRate;
}
void IoDevice::setScanInfo(FunctionType functionType, int chanCount, int samplesPerChanCount, int sampleSize, unsigned int analogResolution, ScanOption options, long long flags, std::vector<CalCoef> calCoefs, std::vector<CustomScale> customScales, void* dataBuffer)
{
if(mScanState == SS_RUNNING)
throw UlException(ERR_ALREADY_ACTIVE);
ScanDataBufferType dataBufferType = DATA_DBL;
if(functionType == FT_DI || functionType == FT_DO || functionType == FT_CTR)
dataBufferType = DATA_UINT64;
mScanInfo.functionType = functionType;
mScanInfo.chanCount = chanCount;
mScanInfo.samplesPerChanCount = samplesPerChanCount;
mScanInfo.sampleSize = sampleSize;
//mScanInfo.sampleBitness = sampleBitness;
mScanInfo.flags = flags;
std::copy(calCoefs.begin(), calCoefs.end(), mScanInfo.calCoefs);
std::copy(customScales.begin(), customScales.end(), mScanInfo.customScales);
mScanInfo.recycle = options & SO_CONTINUOUS ? true : false;
mScanInfo.dataBuffer = dataBuffer;
mScanInfo.dataBufferType = dataBufferType;
mScanInfo.fullScale = (1ULL << analogResolution) - 1;
mScanInfo.currentCalCoefIdx = 0;
mScanInfo.currentDataBufferIdx = 0;
mScanInfo.totalSampleTransferred = 0;
mScanInfo.allSamplesTransferred = false;
mScanInfo.dataBufferSize = mScanInfo.chanCount * mScanInfo.samplesPerChanCount;
mScanInfo.stoppingScan = false;
mScanDoneWaitEvent.reset();
}
void IoDevice::setScanInfo(FunctionType functionType, int chanCount, int samplesPerChanCount, int sampleSize, unsigned int analogResolution, ScanOption options, long long flags, std::vector<CalCoef> calCoefs, void* dataBuffer)
{
std::vector<CustomScale> customScales;
setScanInfo(functionType, chanCount, samplesPerChanCount, sampleSize, analogResolution, options, flags, calCoefs, customScales, dataBuffer);
}
void IoDevice::getXferStatus(TransferStatus* xferStatus) const
{
UlLock lock(mProcessScanDataMutex); // added the lock since mScanInfo.totalSampleTransfered is not updated atomically
if(mScanInfo.totalSampleTransferred == 0) // if scan never ran since ul is loaded
{
xferStatus->currentIndex = -1;
xferStatus->currentTotalCount = 0;
xferStatus->currentScanCount = 0;
}
else
{
unsigned long long count = mScanInfo.totalSampleTransferred; // return current sample count
unsigned long long idx = -1;
if(mScanInfo.chanCount > 0 && count >= mScanInfo.chanCount)
{
idx = count;
idx -= (idx % mScanInfo.chanCount);
idx -= mScanInfo.chanCount;
idx = idx % mScanInfo.dataBufferSize;
}
xferStatus->currentIndex = idx;
xferStatus->currentTotalCount = count;
xferStatus->currentScanCount = count / mScanInfo.chanCount;
}
}
/*
void IoDevice::getXferStatus(unsigned long long* currentScanCount, unsigned long long* currentTotalCount, long long* currentIndex) const
{
UlLock lock(mProcessScanDataMutex); // added the lock since mScanInfo.totalSampleTransfered is not updated atomically
if(mScanInfo.totalSampleTransferred == 0) // if scan never ran since ul is loaded
{
*currentIndex = -1;
*currentTotalCount = 0;
*currentScanCount = 0;
}
else
{
unsigned long long count = mScanInfo.totalSampleTransferred; // return current sample count
unsigned long long idx = -1;
if(mScanInfo.chanCount > 0 && count >= mScanInfo.chanCount)
{
idx = count;
idx -= (idx % mScanInfo.chanCount);
idx -= mScanInfo.chanCount;
idx = idx % mScanInfo.dataBufferSize;
}
*currentIndex = idx;
*currentTotalCount = count;
*currentScanCount = count / mScanInfo.chanCount;
}
}*/
unsigned int IoDevice::calcPacerPeriod(double rate, ScanOption options)
{
unsigned int period = 0;
if(!(options & SO_EXTCLOCK))
{
double clockFreq = mDaqDevice.getClockFreq();
double periodDbl = clockFreq / rate;
if (periodDbl > 0)
--periodDbl;
if(periodDbl > UINT_MAX)
periodDbl = UINT_MAX;
period = periodDbl;
double actualrate = clockFreq / (1ULL + period);
setActualScanRate(actualrate);
}
else
{
period = 0;
setActualScanRate(rate);
}
return period;
}
UlError IoDevice::wait(WaitType waitType, long long waitParam, double timeout)
{
UlError err = ERR_NO_ERROR;
if(waitType == WAIT_UNTIL_DONE)
{
err = waitUntilDone( timeout);
}
return err;
}
UlError IoDevice::waitUntilDone(double timeout)
{
UlError err = ERR_NO_ERROR;
if(mScanState == SS_RUNNING)
{
unsigned long long timeout_us = timeout * 1000000;
int ret = 0;
if(timeout > 0)
{
ret = mScanDoneWaitEvent.wait_for_signal(timeout_us);
}
else if(timeout == -1)
{
mScanDoneWaitEvent.wait_for_signal();
}
if(ret == ETIMEDOUT)
err = ERR_TIMEDOUT;
}
return err;
}
/*unsigned int IoDevice::readScanDataDbl(double* readArray, unsigned int samplesPerChanCount, int fillMode, double timeout)
{
unsigned int samplesPerChanRead = 0;
return samplesPerChanRead;
}*/
} /* namespace ul */

105
src/IoDevice.h Normal file
View File

@ -0,0 +1,105 @@
/*
* IoDevice.h
*
* Author: Measurement Computing Corporation
*/
#ifndef IODEVICE_H_
#define IODEVICE_H_
#include <vector>
#include "DaqDevice.h"
#include "./utility/Endian.h"
#include "./utility/UlLock.h"
#include "./utility/ThreadEvent.h"
namespace ul
{
class UL_LOCAL IoDevice
{
public:
IoDevice(const DaqDevice& daqDevice);
virtual ~IoDevice();
virtual void initialize() {};
virtual void reconfigure() {};
virtual void disconnect();
virtual void setScanState(ScanStatus state);
virtual ScanStatus getScanState() const;
void setActualScanRate(double rate);
double actualScanRate() const;
virtual void stopBackground() {};
virtual UlError terminateScan() {return ERR_BAD_DEV_TYPE;}
virtual UlError checkScanState(bool* scanDone = NULL) const { return ERR_BAD_DEV_TYPE;}
virtual void updateScanParam(int param) {};
virtual void processScanData(void* transfer) {};
virtual unsigned int processScanData(void* transfer, unsigned int stageSize) { return 0;}
//void getXferStatus(unsigned long long* currentScanCount, unsigned long long* currentTotalCount, long long* currentIndex) const;
void getXferStatus(TransferStatus* xferStatus) const;
inline bool allScanSamplesTransferred() const { return mScanInfo.allSamplesTransferred; }
inline bool recycleMode() const { return mScanInfo.recycle; }
inline unsigned int scanChanCount() const { return mScanInfo.chanCount; }
inline unsigned long long totalScanSamplesTransferred() const { return mScanInfo.totalSampleTransferred; }
TriggerConfig getTrigConfig() const { return mTrigCfg;}
virtual UlError wait(WaitType waitType, long long waitParam, double timeout);
virtual UlError waitUntilDone(double timeout);
void signalScanDoneWaitEvent() { mScanDoneWaitEvent.signal();}
protected:
void setScanInfo(FunctionType functionType, int chanCount, int samplesPerChanCount, int sampleSize, unsigned int analogResolution, ScanOption options, long long flags, std::vector<CalCoef> calCoefs, std::vector<CustomScale> customScales, void* dataBuffer);
void setScanInfo(FunctionType functionType, int chanCount, int samplesPerChanCount, int sampleSize, unsigned int analogResolution, ScanOption options, long long flags, std::vector<CalCoef> calCoefs, void* dataBuffer);
virtual unsigned int calcPacerPeriod(double rate, ScanOption options);
protected:
const DaqDevice& mDaqDevice;
pthread_mutex_t mIoDeviceMutex;
int mMinScanSampleCount;
mutable pthread_mutex_t mProcessScanDataMutex;
enum {MAX_CHAN_COUNT = 128};
struct
{
FunctionType functionType;
unsigned int chanCount;
unsigned int samplesPerChanCount;
unsigned int sampleSize;
long long flags;
bool recycle;
unsigned long long fullScale; // analog channels only
CalCoef calCoefs[MAX_CHAN_COUNT];
CustomScale customScales[MAX_CHAN_COUNT];
unsigned long long dataBufferSize;
void* dataBuffer;
ScanDataBufferType dataBufferType;
unsigned int currentCalCoefIdx;
unsigned long long currentDataBufferIdx;
unsigned long long totalSampleTransferred;
bool allSamplesTransferred;
bool stoppingScan;
} mScanInfo;
TriggerConfig mTrigCfg;
public:
Endian& mEndian;
private:
ScanStatus mScanState;
double mActualScanRate;
ThreadEvent mScanDoneWaitEvent;
};
} /* namespace ul */
#endif /* IODEVICE_H_ */

13
src/Makefile.am Normal file
View File

@ -0,0 +1,13 @@
AUTOMAKE_OPTIONS = subdir-objects
if DEBUG
AM_CPPFLAGS = -DDEBUG
endif
lib_LTLIBRARIES = libuldaq.la
libuldaq_la_SOURCES = CtrInfo.cpp DaqODevice.h TmrDevice.h DioPortInfo.cpp UlDaqDeviceManager.cpp AoInfo.h ulc.cpp DaqEventHandler.h UlException.cpp CtrDevice.cpp DaqDevice.h main.cpp DaqDevice.cpp TmrInfo.cpp DaqDeviceManager.h TmrInfo.h AiConfig.cpp AoInfo.cpp UlException.h DaqODevice.cpp AoConfig.cpp DaqEvent.h AiDevice.h AiInfo.cpp DaqIInfo.cpp DaqEventHandler.cpp DaqDeviceConfig.cpp CtrDevice.h DaqDeviceConfig.h DaqIDevice.cpp AiChanInfo.cpp DaqDeviceManager.cpp AiInfo.h AoDevice.h DioPortInfo.h DioInfo.h UlDaqDeviceManager.h AoConfig.h AiChanInfo.h DioDevice.h DaqDeviceInfo.cpp CtrInfo.h DaqOInfo.cpp DaqOInfo.h DioInfo.cpp MemRegionInfo.h DaqIInfo.h AiDevice.cpp DevMemInfo.h DaqDeviceInfo.h DioConfig.cpp DaqDeviceId.h IoDevice.cpp interfaces/UlAiConfig.h interfaces/UlDioPortInfo.h interfaces/UlAiInfo.h interfaces/UlDioConfig.h interfaces/UlDaqDevice.h interfaces/UlTmrDevice.h interfaces/UlDaqODevice.h interfaces/UlDaqDeviceInfo.h interfaces/UlDaqDeviceConfig.h interfaces/UlCtrDevice.h interfaces/UlDevMemInfo.h interfaces/UlDioDevice.h interfaces/UlDaqOInfo.h interfaces/UlTmrInfo.h interfaces/UlDaqIDevice.h interfaces/UlAiDevice.h interfaces/UlAoDevice.h interfaces/UlMemRegionInfo.h interfaces/UlDaqIInfo.h interfaces/UlAoInfo.h interfaces/UlAoConfig.h interfaces/UlDioInfo.h interfaces/UlCtrInfo.h interfaces/UlAiChanInfo.h DevMemInfo.cpp AoDevice.cpp ul_internal.h DioConfig.h DioDevice.cpp usb/Usb1608g.cpp usb/UsbFpgaDevice.h usb/ctr/CtrUsbCtrx.cpp usb/ctr/CtrUsb1208hs.h usb/ctr/CtrUsbCtrx.h usb/ctr/CtrUsb1208hs.cpp usb/ctr/CtrUsbBase.cpp usb/ctr/CtrUsb1808.cpp usb/ctr/CtrUsb1808.h usb/ctr/CtrUsbBase.h usb/Usb1608fsPlus.cpp usb/tmr/TmrUsb1208hs.cpp usb/tmr/TmrUsb1208hs.h usb/tmr/TmrUsbBase.cpp usb/tmr/TmrUsbBase.h usb/tmr/TmrUsb1808.h usb/tmr/TmrUsb1808.cpp usb/UsbDio32hs.h usb/UsbDio32hs.cpp usb/Usb20x.h usb/UsbDaqDevice.h usb/dio/DioUsb1608g.cpp usb/dio/DioUsb1208fsPlus.cpp usb/dio/DioUsb1608g.h usb/dio/DioUsbDio32hs.h usb/dio/UsbDOutScan.h usb/dio/DioUsbBase.cpp usb/dio/DioUsbDio32hs.cpp usb/dio/DioUsb26xx.cpp usb/dio/DioUsbBase.h usb/dio/DioUsb1208hs.cpp usb/dio/UsbDOutScan.cpp usb/dio/UsbDInScan.h usb/dio/DioUsbCtrx.cpp usb/dio/DioUsb1208fsPlus.h usb/dio/DioUsb1208hs.h usb/dio/UsbDInScan.cpp usb/dio/DioUsbCtrx.h usb/dio/DioUsb1808.h usb/dio/DioUsb1808.cpp usb/dio/DioUsb26xx.h usb/Usb1608fsPlus.h usb/Usb1208fsPlus.cpp usb/daqi/DaqIUsb1808.cpp usb/daqi/DaqIUsbBase.h usb/daqi/DaqIUsb1808.h usb/daqi/DaqIUsbCtrx.cpp usb/daqi/DaqIUsbBase.cpp usb/daqi/DaqIUsbCtrx.h usb/Usb1808.h usb/Usb26xx.h usb/ai/AiUsb1208hs.h usb/ai/AiUsb1608g.cpp usb/ai/AiUsb1808.h usb/ai/AiUsb1608fsPlus.h usb/ai/AiUsb1808.cpp usb/ai/AiUsbBase.cpp usb/ai/AiUsb26xx.cpp usb/ai/AiUsb1208hs.cpp usb/ai/AiUsb1608g.h usb/ai/AiUsb1608fsPlus.cpp usb/ai/AiUsbBase.h usb/ai/AiUsb1208fsPlus.h usb/ai/AiUsb1208fsPlus.cpp usb/ai/AiUsb20x.cpp usb/ai/AiUsb20x.h usb/ai/AiUsb26xx.h usb/UsbEndpoint.h usb/ao/AoUsb26xx.h usb/ao/AoUsb20x.cpp usb/ao/AoUsb1608g.cpp usb/ao/AoUsb1208hs.h usb/ao/AoUsb1808.h usb/ao/AoUsb26xx.cpp usb/ao/AoUsbBase.h usb/ao/AoUsb1208fsPlus.h usb/ao/AoUsbBase.cpp usb/ao/AoUsb1808.cpp usb/ao/AoUsb20x.h usb/ao/AoUsb1208fsPlus.cpp usb/ao/AoUsb1208hs.cpp usb/ao/AoUsb1608g.h usb/daqo/DaqOUsbBase.h usb/daqo/DaqOUsb1808.h usb/daqo/DaqOUsb1808.cpp usb/daqo/DaqOUsbBase.cpp usb/Usb1608g.h usb/Usb1208hs.h usb/Usb20x.cpp usb/UsbEndpoint.cpp usb/UsbScanTransferOut.cpp usb/UsbScanTransferIn.h usb/Usb1208fsPlus.h usb/Usb1208hs.cpp usb/Usb1808.cpp usb/UsbDaqDevice.cpp usb/UsbScanTransferIn.cpp usb/UsbCtrx.cpp usb/UsbCtrx.h usb/Usb26xx.cpp usb/UsbScanTransferOut.h usb/UsbFpgaDevice.cpp utility/ErrorMap.cpp utility/ThreadEvent.cpp utility/UlLock.cpp utility/Endian.cpp utility/EuScale.h utility/FnLog.h utility/Nist.cpp utility/Endian.h utility/EuScale.cpp utility/ErrorMap.h utility/Nist.h utility/SuspendMonitor.cpp utility/FnLog.cpp utility/ThreadEvent.h utility/SuspendMonitor.h utility/UlLock.h IoDevice.h uldaq.h TmrDevice.cpp AiConfig.h DaqIDevice.h
libuldaq_la_LDFLAGS = $(LTLDFLAGS)
include_HEADERS = uldaq.h

45
src/MemRegionInfo.h Normal file
View File

@ -0,0 +1,45 @@
/*
* MemRegionInfo.h
*
* Author: Measurement Computing Corporation
*/
#ifndef MEMREGIONINFO_H_
#define MEMREGIONINFO_H_
#include "interfaces/UlMemRegionInfo.h"
#include "ul_internal.h"
namespace ul
{
class UL_LOCAL MemRegionInfo: public UlMemRegionInfo
{
public:
MemRegionInfo(MemRegion regionType, unsigned long long address, unsigned long long size, MemAccessType accessTypes)
{
mRegionType = regionType;
mAddress = address;
mSize = size;
mAccessTypes = accessTypes;
};
virtual MemRegion getRegionType () const { return mRegionType; }
virtual unsigned long long getAddress() const { return mAddress; }
virtual unsigned long long getSize() const { return mSize; }
virtual MemAccessType getAccessTypes() const { return mAccessTypes;}
private:
MemRegion mRegionType;
unsigned long long mAddress;
unsigned long long mSize;
MemAccessType mAccessTypes;
};
} /* namespace ul */
#endif /* MEMREGIONINFO_H_ */

122
src/TmrDevice.cpp Normal file
View File

@ -0,0 +1,122 @@
/*
* TmrDevice.cpp
*
* Author: Measurement Computing Corporation
*/
#include <limits.h>
#include <math.h>
#include <algorithm>
#include <bitset>
#include "TmrDevice.h"
#include "UlException.h"
namespace ul
{
TmrDevice::TmrDevice(const DaqDevice& daqDevice) : IoDevice(daqDevice), UlTmrDevice()
{
}
TmrDevice::~TmrDevice()
{
}
void TmrDevice::tmrPulseOutStart(int timerNum, double* frequency, double* dutyCycle, unsigned long long pulseCount, double* initialDelay, TmrIdleState idleState, PulseOutOption options)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void TmrDevice::tmrPulseOutStop(int timerNum)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void TmrDevice::tmrPulseOutStatus(int timerNum, TmrStatus* status)
{
throw UlException(ERR_BAD_DEV_TYPE);
}
void TmrDevice::setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount)
{
check_TmrSetTrigger_Args(type, trigChan, level, variance, retriggerCount);
mTrigCfg.type = type;
mTrigCfg.trigChan = trigChan;
mTrigCfg.level = round(level);
mTrigCfg.variance = round(variance);
mTrigCfg.retrigCount = retriggerCount;
}
void TmrDevice::check_TmrPulseOutStart_Args(int timerNum, double* frequency, double* dutyCycle, unsigned long long pulseCount, double* initialDelay, TmrIdleState idleState, PulseOutOption options)
{
if(timerNum < 0 || timerNum >= mTmrInfo.getNumTimers())
throw UlException(ERR_BAD_TMR);
if (frequency == NULL || (*frequency > mTmrInfo.getMaxFrequency()) || (*frequency < mTmrInfo.getMinFrequency()))
throw UlException(ERR_BAD_FREQUENCY);
if(dutyCycle == NULL || (*dutyCycle >= 1 || *dutyCycle <= 0))
throw UlException(ERR_BAD_DUTY_CYCLE);
if(initialDelay == NULL)
throw UlException(ERR_BAD_INITIAL_DELAY);
double clockFreq = mDaqDevice.getClockFreq();
unsigned long long delayPulseCount = *initialDelay * clockFreq;
if(delayPulseCount > UINT_MAX)
throw UlException(ERR_BAD_INITIAL_DELAY);
if(~mTmrInfo.getScanOptions() & options)
throw UlException(ERR_BAD_OPTION);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void TmrDevice::check_TmrPulseOutStop_Args(int timerNum)
{
if(timerNum < 0 || timerNum >= mTmrInfo.getNumTimers())
throw UlException(ERR_BAD_TMR);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void TmrDevice::check_TmrOutStatus_Args(int timerNum)
{
if(timerNum < 0 || timerNum >= mTmrInfo.getNumTimers())
throw UlException(ERR_BAD_TMR);
if(!mDaqDevice.isConnected())
throw UlException(ERR_NO_CONNECTION_ESTABLISHED);
}
void TmrDevice::check_TmrSetTrigger_Args(TriggerType trigType, int trigChan, double level, double variance, unsigned int retriggerCount)
{
if(mTmrInfo.supportsTrigger())
{
if(!(mTmrInfo.getTriggerTypes() & trigType))
throw UlException(ERR_BAD_TRIG_TYPE);
std::bitset<32> typeBitSet(trigType);
if(typeBitSet.count() > 1)
throw UlException(ERR_BAD_TRIG_TYPE);
if(retriggerCount > 0 && !(mTmrInfo.getScanOptions() & SO_RETRIGGER))
throw UlException(ERR_BAD_RETRIG_COUNT);
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
} /* namespace ul */

43
src/TmrDevice.h Normal file
View File

@ -0,0 +1,43 @@
/*
* TmrDevice.h
*
* Author: Measurement Computing Corporation
*/
#ifndef TMRDEVICE_H_
#define TMRDEVICE_H_
#include "interfaces/UlTmrDevice.h"
#include "ul_internal.h"
#include "IoDevice.h"
#include "TmrInfo.h"
namespace ul
{
class UL_LOCAL TmrDevice: public IoDevice, public UlTmrDevice
{
public:
TmrDevice(const DaqDevice& daqDevice);
virtual ~TmrDevice();
virtual const UlTmrInfo& getTmrInfo() { return mTmrInfo;}
virtual void tmrPulseOutStart(int timerNum, double* frequency, double* dutyCycle, unsigned long long pulseCount, double* initialDelay, TmrIdleState idleState, PulseOutOption options);
virtual void tmrPulseOutStop(int timerNum);
virtual void tmrPulseOutStatus(int timerNum, TmrStatus* status);
virtual void setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount);
protected:
virtual void check_TmrPulseOutStart_Args(int timerNum, double* frequency, double* dutyCycle, unsigned long long pulseCount, double* initialDelay, TmrIdleState idleState, PulseOutOption options);
virtual void check_TmrPulseOutStop_Args(int timerNum);
virtual void check_TmrOutStatus_Args(int timerNum);
virtual void check_TmrSetTrigger_Args(TriggerType trigtype, int trigChan, double level, double variance, unsigned int retriggerCount);
protected:
TmrInfo mTmrInfo;
};
} /* namespace ul */
#endif /* TMRDEVICE_H_ */

103
src/TmrInfo.cpp Normal file
View File

@ -0,0 +1,103 @@
/*
* TmrInfo.cpp
*
* Author: Measurement Computing Corporation
*/
#include "TmrInfo.h"
namespace ul
{
TmrInfo::TmrInfo()
{
mNumTimers = 0;
mMinFreq = 0;
mMaxFreq = 0;
mType = (TimerType) 0;
mScanOptions = SO_DEFAULTIO;
mTriggerTypes = TRIG_NONE;
}
TmrInfo::~TmrInfo()
{
}
void TmrInfo::setNumTimers(int numTimers)
{
mNumTimers = numTimers;
}
int TmrInfo::getNumTimers() const
{
return mNumTimers;
}
void TmrInfo::setTimerType(TimerType type)
{
mType = type;
}
TimerType TmrInfo::getTimerType(int tmrNum) const
{
TimerType type = (TimerType) 0;
if(tmrNum < mNumTimers)
type = mType;
return type;
}
void TmrInfo::setMinFrequency(double minFreq)
{
mMinFreq = minFreq;
}
double TmrInfo::getMinFrequency() const
{
return mMinFreq;
}
void TmrInfo::setMaxFrequency(double maxFreq)
{
mMaxFreq = maxFreq;
}
double TmrInfo::getMaxFrequency() const
{
return mMaxFreq;
}
void TmrInfo::setScanOptions(long long options)
{
mScanOptions = (ScanOption) options;
}
ScanOption TmrInfo::getScanOptions() const
{
return mScanOptions;
}
void TmrInfo::setTriggerTypes(long long triggerTypes)
{
mTriggerTypes = (TriggerType) triggerTypes;
}
TriggerType TmrInfo::getTriggerTypes() const
{
return mTriggerTypes;
}
bool TmrInfo::supportsTrigger() const
{
bool supportsTrig = false;
if(mTriggerTypes)
supportsTrig = true;
return supportsTrig;
}
} /* namespace ul */

49
src/TmrInfo.h Normal file
View File

@ -0,0 +1,49 @@
/*
* TmrInfo.h
*
* Author: Measurement Computing Corporation
*/
#ifndef TMRINFO_H_
#define TMRINFO_H_
#include "ul_internal.h"
#include <vector>
#include "interfaces/UlTmrInfo.h"
namespace ul
{
class UL_LOCAL TmrInfo: public UlTmrInfo
{
public:
TmrInfo();
virtual ~TmrInfo();
virtual void setNumTimers(int numChans);
virtual int getNumTimers() const;
virtual void setTimerType(TimerType type);
virtual TimerType getTimerType(int tmrNum) const;
virtual void setMinFrequency(double minFreq);
virtual double getMinFrequency() const;
virtual void setMaxFrequency(double maxFreq);
virtual double getMaxFrequency() const;
void setScanOptions(long long options);
ScanOption getScanOptions() const;
bool supportsTrigger() const;
void setTriggerTypes(long long triggerTypes);
TriggerType getTriggerTypes() const;
private:
int mNumTimers;
double mMinFreq;
double mMaxFreq;
TimerType mType;
ScanOption mScanOptions;
TriggerType mTriggerTypes;
};
} /* namespace ul */
#endif /* TMRINFO_H_ */

148
src/UlDaqDeviceManager.cpp Normal file
View File

@ -0,0 +1,148 @@
/*
* UlDaqDeviceManager.cpp
*
* Author: Measurement Computing Corporation
*/
#include "./UlDaqDeviceManager.h"
#include "DaqDeviceId.h"
#include "DaqDeviceManager.h"
#include "./usb/UsbDaqDevice.h"
//#include "./hid/HidDaqDevice.h"
#include "./usb/Usb1208fsPlus.h"
#include "./usb/Usb1608fsPlus.h"
#include "./usb/Usb20x.h"
#include "./usb/Usb1208hs.h"
#include "./usb/Usb1608g.h"
#include "./usb/Usb1808.h"
#include "./usb/Usb26xx.h"
#include "./usb/UsbDio32hs.h"
#include "./usb/UsbCtrx.h"
//#include "./hid/UsbTc.h"
#include <iostream>
#include <cstring>
#include <vector>
namespace ul
{
UlDaqDeviceManager::UlDaqDeviceManager()
{
}
UlDaqDeviceManager::~UlDaqDeviceManager()
{
}
std::vector<DaqDeviceDescriptor> UlDaqDeviceManager::getDaqDeviceInventory(DaqDeviceInterface InterfaceType)
{
FnLog log("UlDaqDeviceManager::getDaqDeviceInventory");
std::vector<DaqDeviceDescriptor> daqDeviceList;
std::vector<DaqDeviceDescriptor> usbDaqDeviceList = UsbDaqDevice::findDaqDevices();
//std::vector<DaqDeviceDescriptor> hidDaqDeviceList = HidDaqDevice::findDaqDevices();
for(unsigned int i = 0; i < usbDaqDeviceList.size(); i++)
daqDeviceList.push_back(usbDaqDeviceList[i]);
/*for(unsigned int i = 0; i < hidDaqDeviceList.size(); i++)
daqDeviceList.push_back(hidDaqDeviceList[i]);*/
return daqDeviceList;
}
UlDaqDevice& UlDaqDeviceManager::createDaqDevice(DaqDeviceDescriptor daqDevDescriptor)
{
DaqDevice* daqDev = DaqDeviceManager::getDaqDevice(daqDevDescriptor); // Don't recreate a new DaqDevice object if it already exists for the specified descriptor
if(daqDev == NULL)
{
switch(daqDevDescriptor.productId)
{
case DaqDeviceId::USB_1208FS_PLUS:
case DaqDeviceId::USB_1408FS_PLUS:
daqDev = new Usb1208fs_Plus(daqDevDescriptor);
break;
case DaqDeviceId::USB_1608FS_PLUS:
daqDev = new Usb1608fs_Plus(daqDevDescriptor);
break;
case DaqDeviceId::USB_201:
case DaqDeviceId::USB_202:
case DaqDeviceId::USB_204:
case DaqDeviceId::USB_205:
daqDev = new Usb20x(daqDevDescriptor);
break;
case DaqDeviceId::USB_1208HS:
case DaqDeviceId::USB_1208HS_2AO:
case DaqDeviceId::USB_1208HS_4AO:
daqDev = new Usb1208hs(daqDevDescriptor, "USB_1208HS.rbf");
break;
case DaqDeviceId::USB_1608G:
case DaqDeviceId::USB_1608GX:
case DaqDeviceId::USB_1608GX_2AO:
daqDev = new Usb1608g(daqDevDescriptor, "USB_1608G.rbf");
break;
case DaqDeviceId::USB_1608G_2:
case DaqDeviceId::USB_1608GX_2:
case DaqDeviceId::USB_1608GX_2AO_2:
daqDev = new Usb1608g(daqDevDescriptor, "USB_1608G_2.rbf");
break;
case DaqDeviceId::USB_1808:
case DaqDeviceId::USB_1808X:
daqDev = new Usb1808(daqDevDescriptor, "USB_1808.bin");
break;
case DaqDeviceId::USB_2623:
case DaqDeviceId::USB_2627:
case DaqDeviceId::USB_2633:
case DaqDeviceId::USB_2637:
daqDev = new Usb26xx(daqDevDescriptor, "USB_26xx.rbf");
break;
case DaqDeviceId::USB_DIO32HS:
daqDev = new UsbDio32hs(daqDevDescriptor, "USB_DIO32HS.bin");
break;
case DaqDeviceId::USB_CTR04:
case DaqDeviceId::USB_CTR08:
daqDev = new UsbCtrx(daqDevDescriptor, "USB_CTR.bin");
break;
/*case DaqDeviceId::USB_TC:
daqDev = new UsbTc(daqDevDescriptor);
break;*/
}
if(daqDev)
{
DaqDeviceManager::addToCreatedList(daqDev);
}
else
throw UlException(ERR_BAD_DEV_TYPE);
}
return *daqDev;
}
void UlDaqDeviceManager::releaseDaqDevice(UlDaqDevice& daqDevice)
{
DaqDeviceManager::releaseDevice(((DaqDevice&)daqDevice).getDeviceNumber());
}
} /* namespace ul */

32
src/UlDaqDeviceManager.h Normal file
View File

@ -0,0 +1,32 @@
/*
* UlDaqDeviceManager.h
*
* Author: Measurement Computing Corporation
*/
#ifndef ULDAQDEVICEMANAGER_H_
#define ULDAQDEVICEMANAGER_H_
#include <vector>
#include "./interfaces/UlDaqDevice.h"
#include "uldaq.h"
namespace ul
{
class UlDaqDeviceManager
{
public:
UlDaqDeviceManager();
virtual ~UlDaqDeviceManager();
static std::vector<DaqDeviceDescriptor> getDaqDeviceInventory(DaqDeviceInterface InterfaceType);
static UlDaqDevice& createDaqDevice(DaqDeviceDescriptor daqDevDescriptor);
static void releaseDaqDevice(UlDaqDevice& daqDevice);
};
} /* namespace ul */
#endif /* UlDaqDeviceManager_H_ */

27
src/UlException.cpp Normal file
View File

@ -0,0 +1,27 @@
/*
* UlException.cpp
*
* Author: Measurement Computing Corporation
*/
#include "./UlException.h"
#include "./utility/ErrorMap.h"
namespace ul
{
UlException::UlException(UlError err)
{
mError = err;
mStr = ErrorMap::instance().getErrorMsg(err);
}
const char* UlException::what() const throw()
{
return mStr.c_str();
}
} /* namespace ul */

35
src/UlException.h Normal file
View File

@ -0,0 +1,35 @@
/*
* UlException.h
*
* Author: Measurement Computing Corporation
*/
#ifndef UlException_H_
#define UlException_H_
#include <exception>
#include <string>
#include "uldaq.h"
namespace ul
{
class UlException: public std::exception
{
public:
UlException(UlError err);
virtual ~UlException () throw() {};
UlError getError() {return mError;}
virtual const char* what() const throw();
private:
std::string mStr;
UlError mError;
};
} /* namespace ul */
#endif /* UlException_H_ */

View File

@ -0,0 +1,23 @@
/*
* UlAiChanInfo.h
*
* Author: Measurement Computing Corporation
*/
#ifndef INTERFACES_ULAICHANINFO_H_
#define INTERFACES_ULAICHANINFO_H_
#include "../uldaq.h"
namespace ul
{
class UlAiChanInfo
{
public:
virtual ~UlAiChanInfo(){};
};
} /* namespace ul */
#endif /* INTERFACES_ULAICHANINFO_H_ */

View File

@ -0,0 +1,57 @@
/*
* UlAiConfig.h
*
* Author: Measurement Computing Corporation
*/
#ifndef INTERFACES_ULAICONFIG_H_
#define INTERFACES_ULAICONFIG_H_
#include "../uldaq.h"
namespace ul
{
class UlAiConfig
{
public:
virtual ~UlAiConfig() {};
virtual void setChanType(int channel, AiChanType chanType) = 0;
virtual AiChanType getChanType(int channel) = 0;
virtual void setChanTcType(int channel, TcType tcType) = 0;
virtual TcType getChanTcType(int channel) = 0;
virtual void setChanTempUnit(int channel, TempUnit unit) = 0;
virtual TempUnit getChanTempUnit(int channel) = 0;
virtual void setTempUnit(TempUnit unit) = 0;
virtual void setAutoZeroMode(AutoZeroMode mode) = 0;
virtual AutoZeroMode getAutoZeroMode() = 0;
virtual void setAdcTimingMode(AdcTimingMode mode) = 0;
virtual AdcTimingMode getAdcTimingMode() = 0;
virtual void setChanIepeMode(int channel, IepeMode mode) = 0;
virtual IepeMode getChanIepeMode(int channel) = 0;
virtual void setChanCouplingMode(int channel, CouplingMode mode) = 0;
virtual CouplingMode getChanCouplingMode(int channel) = 0;
virtual void setChanSensorSensitivity(int channel, double sensitivity) = 0;
virtual double getChanSensorSensitivity(int channel) = 0;
virtual void setChanSlope(int channel, double slope) = 0;
virtual double getChanSlope(int channel) = 0;
virtual void setChanOffset(int channel, double offset) = 0;
virtual double getChanOffset(int channel) = 0;
virtual unsigned long long getCalDate() = 0; // returns number of seconds since unix epoch
virtual void getCalDateStr(char* calDate, unsigned int* maxStrLen) = 0;
};
} /* namespace ul */
#endif /* INTERFACES_ULAICONFIG_H_ */

View File

@ -0,0 +1,36 @@
/*
* UlAiDevice.h
*
* Author: Measurement Computing Corporation
*/
#ifndef INTERFACES_ULAIDEVICE_H_
#define INTERFACES_ULAIDEVICE_H_
#include "../uldaq.h"
#include "UlAiConfig.h"
#include "UlAiInfo.h"
namespace ul
{
class UlAiDevice
{
public:
virtual ~UlAiDevice() {};
virtual const UlAiInfo& getAiInfo() = 0;
virtual UlAiConfig& getAiConfig() = 0;
virtual double aIn(int channel, AiInputMode mode, Range range, AInFlag flags) = 0;
virtual double aInScan(int lowChan, int highChan, AiInputMode mode, Range range, int samplesPerChan, double rate, ScanOption options, AInScanFlag flags, double data[]) = 0;
virtual void aInLoadQueue(AiQueueElement queue[], unsigned int numElements) = 0;
virtual void setTrigger(TriggerType type, int trigChan, double level, double variance, unsigned int retriggerCount) = 0;
virtual UlError getStatus(ScanStatus* status, TransferStatus* xferStatus) = 0;
virtual void stopBackground() = 0;
};
} /* namespace ul */
#endif /* INTERFACES_ULAIDEVICE_H_ */

Some files were not shown because too many files have changed in this diff Show More