1 /*
2 * $RCSfile: receiver.cpp,v $
3 * $Revision: 1.3 $
4 * $Date: 2009/10/23 20:54:05 $
5 * :tabSize=4:collapseFolds=1:
6 *
7 * AIOUSB library sample program
8 */
9
10
11 // {{{ notes and build instructions
12 /*
13 * This source code looks best with a tab width of 4.
14 *
15 * All the API functions that DO NOT begin "AIOUSB_" are standard API functions, largely
16 * documented in http://accesio.com/MANUALS/USB%20Software%20Reference.pdf. The functions
17 * that DO begin with "AIOUSB_" are "extended" API functions added to the Linux
18 * implementation. Source code lines in this sample program that are prefixed with the
19 * comment "/ * API * /" highlight calls to the AIOUSB API.
20 *
21 * LIBUSB (http://www.libusb.org/) must be installed on the Linux box (the AIOUSB code
22 * was developed using libusb version 1.0.3). After installing libusb, it may also be
23 * necessary to set an environment variable so that the libusb and aiousb header files can
24 * be located:
25 *
26 * export CPATH=/usr/local/include/libusb-1.0/:/usr/local/include/aiousb/
27 *
28 * Once libusb is installed properly, it should be possible to compile the sample program
29 * using the simple command:
30 *
31 * make
32 *
33 * Alternatively, one can "manually" compile the sample program using the command:
34 *
35 * g++ receiver.cpp -laiousb -lusb-1.0 -o receiver
36 */
37 // }}}
38
39 // {{{ includes
40 #include <aiousb.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45 using namespace AIOUSB;
46 // }}}
47
48 int main( int argc, char **argv ) {
49 unsigned long result = AIOUSB_SUCCESS;
50
51 if( argc != 3 ) {
52 printf(
53 "USB-DIO-16A sample program $Revision: 1.3 $ $Date: 2009/10/23 20:54:05 $\n"
54 " (AIOUSB library %s)\n"
55 " This program demonstrates high speed streaming between 2 USB-DIO-16A\n"
56 " devices on the same USB bus. For simplicity, it uses the first 2 such\n"
57 " devices found on the bus.\n"
58 "\n"
59 " This program is not intended to be executed by itself, but as a child\n"
60 " process of ./sample. Please run ./sample instead.\n"
61 "\n"
62 " Usage: receiver <hex serial number> <num. points>\n"
63 /*API*/ , AIOUSB_GetVersion()
64 );
65 } else {
66 /*
67 * parse command line
68 */
69 const __uint64_t targetSerialNumber = strtoll( *( argv + 1 ), 0, 16 );
70 const unsigned long framePoints = strtol( *( argv + 2 ), 0, 0 );
71
72 /*
73 * initialize AIOUSB library; MUST do before any meaningful AIOUSB functions
74 */
75 /*API*/ unsigned long result = AIOUSB_Init();
76 if( result == AIOUSB_SUCCESS ) {
77 /*
78 * find the device with the specified serial number
79 */
80 /*API*/ unsigned long deviceIndex = GetDeviceBySerialNumber( &targetSerialNumber );
81 if( deviceIndex != diNone ) {
82 /*
83 * found it; allocate buffer in which to receive streaming DIO data
84 */
85 unsigned short *const frameData = ( unsigned short * ) malloc( framePoints * sizeof( unsigned short ) );
86 if( frameData != 0 ) {
87 unsigned char outputMask = 0x08; // receiver: port D is output; C, B and A are input
88 unsigned long initialData = 0xffffffff;
89 unsigned char tristateMask = 0x00;
90 double ReadClockHz
91 , WriteClockHz;
92 unsigned long transferred;
93
94 /*
95 * set up communication parameters
96 */
97 /*API*/ AIOUSB_SetCommTimeout( deviceIndex, 1000 );
98 /*API*/ AIOUSB_SetStreamingBlockSize( deviceIndex, 256 );
99
100 /*
101 * turn off the clocks; the sender will control the clock
102 */
103 ReadClockHz = WriteClockHz = 0;
104 /*API*/ result = DIO_StreamSetClocks( deviceIndex, &ReadClockHz, &WriteClockHz );
105 if( result != AIOUSB_SUCCESS ) {
106 printf( "Error '%s' setting stream clock for device at index %lu\n"
107 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
108 goto abort;
109 } // if( result ...
110
111 /*
112 * open stream for reading
113 */
114 /*API*/ result = DIO_StreamOpen( deviceIndex, TRUE /* open for reading */ );
115 if( result != AIOUSB_SUCCESS ) {
116 printf( "Error '%s' opening read stream for device at index %lu\n"
117 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
118 goto abort;
119 } // if( result ...
120
121 /*
122 * configure I/O ports
123 */
124 /*API*/ result = DIO_ConfigureEx( deviceIndex, &outputMask, &initialData, &tristateMask );
125 if( result != AIOUSB_SUCCESS ) {
126 printf( "Error '%s' configuring device at index %lu\n"
127 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
128 /*API*/ DIO_StreamClose( deviceIndex );
129 goto abort;
130 } // if( result ...
131
132 /*
133 * fill buffer with a known pattern so we can verify data received
134 */
135 memset( frameData, 0x55, framePoints * sizeof( unsigned short ) );
136
137 /*
138 * receive frame
139 */
140 /*API*/ result = DIO_StreamFrame( deviceIndex, framePoints, frameData, &transferred );
141 if( result == AIOUSB_SUCCESS ) {
142 if( transferred == framePoints * sizeof( unsigned short ) ) {
143 /*
144 * it looks like we read the correct amount of data, but
145 * verify the data received
146 */
147 BOOL correct = TRUE;
148 unsigned long point;
149 for( point = 0; point < framePoints; point++ ) {
150 if( frameData[ point ] != ( point & 0xfffful ) ) {
151 printf( "Error: frame word %lu = %u; expected %u\n"
152 , point, frameData[ point ]
153 , ( unsigned short ) ( point & 0xfffful ) );
154 correct = FALSE;
155 break;
156 } // if( frameData[ ...
157 } // for( point ...
158 if( correct )
159 printf( "%lu point frame successfully read from device at index %lu\n"
160 , framePoints, deviceIndex );
161 else
162 printf( "Error: frame read from device at index %lu contained data errors\n", deviceIndex );
163 } else {
164 printf(
165 "Error: incorrect amount of frame data read from device at index %lu\n"
166 " attempted to read %lu bytes, but actually read %lu bytes\n"
167 , deviceIndex
168 , framePoints * sizeof( unsigned short )
169 , transferred );
170 } // if( transferred ...
171 } else {
172 printf( "Error '%s' reading frame from device at index %lu\n"
173 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
174 } // if( result ...
175 /*API*/ DIO_StreamClose( deviceIndex );
176
177 abort:
178 free( frameData );
179 } else {
180 printf( "Unable to allocate buffer for frame data\n" );
181 } // if( frameData ...
182 } else {
183 printf( "Unable to find device with serial number %llx\n", targetSerialNumber );
184 } // if( deviceIndex ...
185
186 /*
187 * MUST be called before program exits, but only if AIOUSB_Init() succeeded
188 */
189 /*API*/ AIOUSB_Exit();
190 } // if( result ...
191 } // if( argc ...
192
193 return ( int ) result;
194 } // main()
195
196
197 /* end of file */