1 /*
2 * $RCSfile: receiver.cpp,v $
3 * $Revision: 1.9 $
4 * $Date: 2010/01/29 18:32:46 $
5 * jEdit:tabSize=4:indentSize=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 * or, to enable debug features
38 *
39 * g++ -ggdb sample.cpp -laiousbdbg -lusb-1.0 -o sample
40 */
41 // }}}
42
43 // {{{ includes
44 #include <aiousb.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49 using namespace AIOUSB;
50 // }}}
51
52 int main( int argc, char **argv ) {
53 unsigned long result = AIOUSB_SUCCESS;
54
55 if( argc != 3 ) {
56 printf(
57 "USB-DIO-16A sample program version 1.9, 29 January 2010\n"
58 " AIOUSB library version %s, %s\n"
59 " This program demonstrates high speed streaming between 2 USB-DIO-16A\n"
60 " devices on the same USB bus. For simplicity, it uses the first 2 such\n"
61 " devices found on the bus.\n"
62 "\n"
63 " This program is not intended to be executed by itself, but as a child\n"
64 " process of ./sample. Please run ./sample instead.\n"
65 "\n"
66 " Usage: receiver <hex serial number> <num. points>\n"
67 /*API*/ , AIOUSB_GetVersion(), AIOUSB_GetVersionDate()
68 );
69 } else {
70 /*
71 * parse command line
72 */
73 const __uint64_t targetSerialNumber = strtoll( *( argv + 1 ), 0, 16 );
74 const unsigned long framePoints = strtol( *( argv + 2 ), 0, 0 );
75
76 /*
77 * initialize AIOUSB library; MUST do before any meaningful AIOUSB functions
78 */
79 /*API*/ unsigned long result = AIOUSB_Init();
80 if( result == AIOUSB_SUCCESS ) {
81 /*
82 * find the device with the specified serial number
83 */
84 /*API*/ unsigned long deviceIndex = GetDeviceBySerialNumber( &targetSerialNumber );
85 if( deviceIndex != diNone ) {
86 /*
87 * found it; allocate buffer in which to receive streaming DIO data
88 */
89 unsigned short *const frameData = ( unsigned short * ) malloc( framePoints * sizeof( unsigned short ) );
90 if( frameData != 0 ) {
91 unsigned char outputMask = 0x08; // receiver: port D is output; C, B and A are input
92 unsigned long initialData = 0xffffffff;
93 unsigned char tristateMask = 0x00;
94 double ReadClockHz
95 , WriteClockHz;
96 unsigned long transferred;
97
98 /*
99 * set up communication parameters
100 */
101 /*API*/ AIOUSB_SetCommTimeout( deviceIndex, 1000 );
102 /*API*/ AIOUSB_SetStreamingBlockSize( deviceIndex, 256 );
103
104 /*
105 * turn off the clocks; the sender will control the clock
106 */
107 ReadClockHz = WriteClockHz = 0;
108 /*API*/ result = DIO_StreamSetClocks( deviceIndex, &ReadClockHz, &WriteClockHz );
109 if( result != AIOUSB_SUCCESS ) {
110 printf( "Error '%s' setting stream clock for device at index %lu\n"
111 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
112 goto abort;
113 } // if( result ...
114
115 /*
116 * open stream for reading
117 */
118 /*API*/ result = DIO_StreamOpen( deviceIndex, AIOUSB_TRUE /* open for reading */ );
119 if( result != AIOUSB_SUCCESS ) {
120 printf( "Error '%s' opening read stream for device at index %lu\n"
121 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
122 goto abort;
123 } // if( result ...
124
125 /*
126 * configure I/O ports
127 */
128 /*API*/ result = DIO_ConfigureEx( deviceIndex, &outputMask, &initialData, &tristateMask );
129 if( result != AIOUSB_SUCCESS ) {
130 printf( "Error '%s' configuring device at index %lu\n"
131 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
132 /*API*/ DIO_StreamClose( deviceIndex );
133 goto abort;
134 } // if( result ...
135
136 /*
137 * fill buffer with a known pattern so we can verify data received
138 */
139 memset( frameData, 0x55, framePoints * sizeof( unsigned short ) );
140
141 /*
142 * receive frame
143 */
144 /*API*/ result = DIO_StreamFrame( deviceIndex, framePoints, frameData, &transferred );
145 if( result == AIOUSB_SUCCESS ) {
146 if( transferred == framePoints * sizeof( unsigned short ) ) {
147 /*
148 * it looks like we read the correct amount of data, but
149 * verify the data received
150 */
151 AIOUSB_BOOL correct = AIOUSB_TRUE;
152 unsigned long point;
153 for( point = 0; point < framePoints; point++ ) {
154 if( frameData[ point ] != ( point & 0xfffful ) ) {
155 printf( "Error: frame word %lu = %u; expected %u\n"
156 , point, frameData[ point ]
157 , ( unsigned short ) ( point & 0xfffful ) );
158 correct = AIOUSB_FALSE;
159 break;
160 } // if( frameData[ ...
161 } // for( point ...
162 if( correct )
163 printf( "%lu point frame successfully read from device at index %lu\n"
164 , framePoints, deviceIndex );
165 else
166 printf( "Error: frame read from device at index %lu contained data errors\n", deviceIndex );
167 } else {
168 printf(
169 "Error: incorrect amount of frame data read from device at index %lu\n"
170 " attempted to read %lu bytes, but actually read %lu bytes\n"
171 , deviceIndex
172 , framePoints * sizeof( unsigned short )
173 , transferred );
174 AIOUSB_ClearFIFO( deviceIndex, CLEAR_FIFO_METHOD_IMMEDIATE_AND_ABORT );
175 } // if( transferred ...
176 } else {
177 printf( "Error '%s' reading frame from device at index %lu\n"
178 /*API*/ , AIOUSB_GetResultCodeAsString( result ), deviceIndex );
179 AIOUSB_ClearFIFO( deviceIndex, CLEAR_FIFO_METHOD_IMMEDIATE_AND_ABORT );
180 } // if( result ...
181 /*API*/ DIO_StreamClose( deviceIndex );
182
183 abort:
184 free( frameData );
185 } else {
186 printf( "Unable to allocate buffer for frame data\n" );
187 } // if( frameData ...
188 } else {
189 printf( "Unable to find device with serial number %llx\n", ( long long ) targetSerialNumber );
190 } // if( deviceIndex ...
191
192 /*
193 * MUST be called before program exits, but only if AIOUSB_Init() succeeded
194 */
195 /*API*/ AIOUSB_Exit();
196 } // if( result ...
197 } // if( argc ...
198
199 return ( int ) result;
200 } // main()
201
202
203 /* end of file */