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