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 */