read_adcs.c

00001 /*=========================================================================
00002 | (c) 2005-2007  Total Phase, Inc.
00003 |--------------------------------------------------------------------------
00004 | Project : Cheetah Sample Code
00005 | File    : async.c
00006 |--------------------------------------------------------------------------
00007 | Use the asynchronous interface of the Cheetah host adapter
00008 |--------------------------------------------------------------------------
00009 | Redistribution and use of this file in source and binary forms, with
00010 | or without modification, are permitted.
00011 |
00012 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00013 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00014 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00015 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
00016 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00017 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00018 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00019 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00020 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00021 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00022 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00023 | POSSIBILITY OF SUCH DAMAGE.
00024  ========================================================================*/
00025 
00026 //=========================================================================
00027 // INCLUDES
00028 //=========================================================================
00029 #include <math.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include "cheetah.h"
00034 #include <fftw3.h>
00035 
00036 #ifdef _WIN32
00037 #include <time.h>
00038 #else
00039 #include <sys/time.h>
00040 #endif
00041 
00042 
00043 //=========================================================================
00044 // CONSTANTS
00045 //=========================================================================
00046 // Uncomment to show the data returned by the shifting device
00047 #define SHOW_DATA
00048 
00049 // Add a delay between bytes by changing this constant (in nanoseconds)
00050 #define BYTE_DELAY 0
00051 
00052 
00053 #define MAX_TX_LENGTH 3072
00054 
00055 const int N_FFT = 1024;
00056 
00057 
00058 
00059 //=========================================================================
00060 // UTILITY FUNCTIONS
00061 //=========================================================================
00062 static s64 _timeMillis () {
00063 #ifdef _WIN32
00064     return ((s64)clock()) * 1000 / CLOCKS_PER_SEC;
00065 #else
00066     struct timeval tv;
00067     gettimeofday(&tv, 0);
00068     return ((s64)tv.tv_sec * 1000L) + (s64)(tv.tv_usec / 1000L);
00069 #endif
00070 }
00071 
00072 
00073 #ifndef max
00074         #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
00075 #endif
00076 
00077 #ifndef min
00078         #define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
00079 #endif
00080 
00081 //=========================================================================
00082 // FUNCTIONS
00083 //=========================================================================
00084 static void _blast_async (Cheetah handle, u32 txnlen, u32 iter) {
00085     double elapsed, cycle_duration;
00086     u32    i,j,k;
00087     int    count = 0;
00088     u08    data_out[2];
00089 //    u08    data_out[4];
00090 //    u08    *data_in;
00091     u08    data_in[MAX_TX_LENGTH];
00092     int    input;
00093     int    ready_bit;
00094     int    valid_data_point;
00095     s64    start, itteration_start;
00096     int    ret;
00097     fftw_complex    *data, *fft_result;
00098     //fftw_plan       plan_forward;
00099 
00100 
00101     data        = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * N_FFT );
00102     fft_result  = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * N_FFT );
00103 
00104 
00105     // Opens file to write out data as column vector
00106     FILE *data1_output, *data2_output, *data3_output;
00107     data1_output = fopen("data.1.dat", "w");
00108     data2_output = fopen("data.2.dat", "w");
00109     data3_output = fopen("data.3.dat", "w");
00110     if (data1_output == NULL || data2_output == NULL || data3_output == NULL) {
00111         fprintf(stderr, "Could not open files!!!");
00112         exit(1);
00113     }
00114 
00115     // Make a simple queue to just assert OE.
00116     ch_spi_queue_clear(handle);
00117     ch_spi_queue_oe(handle, 1);
00118     ch_spi_batch_shift(handle, 0, 0);
00119 
00120     fprintf(stderr, "Beginning to queue SPI packets...");
00121     // Queue the batch which is a sequence of SPI packets
00122     // (back-to-back) each of length 2.
00123     data_out[0] = 0xff;
00124     data_out[1] = 0xff;
00125     ch_spi_queue_clear(handle);
00126 //    for (i = 0; i < N_FFT * txnlen; ++i) {
00127     for (i = 0; i < N_FFT * 3; ++i) {
00128         //ch_spi_queue_ss(handle, 0x1);
00129     
00130         
00131         //data_out[2] = (count >>  8) & 0xff;
00132         //data_out[3] = (count >>  0) & 0xff;
00133     
00134         ++count;
00135         
00136         //ch_spi_queue_array(handle, 2, data_out);
00137         //ch_spi_queue_ss(handle, 0x0);
00138         // Convert Slave 1
00139         ch_spi_queue_ss(handle, 0xF);
00140         ch_spi_queue_array(handle, 2, data_out);
00141         ch_spi_queue_ss(handle, 0xE);
00142         
00143         // Convert Slave 2
00144         ch_spi_queue_ss(handle, 0xF);
00145         ch_spi_queue_array(handle, 2, data_out);
00146         ch_spi_queue_ss(handle, 0xD);
00147 
00148         // Convert Slave 3
00149         ch_spi_queue_ss(handle, 0xF);
00150         ch_spi_queue_array(handle, 2, data_out);
00151         ch_spi_queue_ss(handle, 0xB);
00152 
00153     }
00154     fprintf(stderr, " Done\n");
00155     
00156     fprintf(stderr, "Beginning asynchronous SPI packet transmission...\n");
00157     start = _timeMillis();
00158     itteration_start = _timeMillis();
00159 
00160     // First, submit first batch 
00161     ch_spi_async_submit(handle);
00162 
00163     for (i = 0; i < iter; ++i) {
00164         cycle_duration = ((double)(_timeMillis() - itteration_start)) / 1000;
00165         itteration_start = _timeMillis();
00166         fprintf(stderr, "Packet %d...\n", i);
00167         // Submit another batch, while the previous one is in
00168         // progress.  The application may even clear the current
00169         // batch queue and queue a different set of SPI
00170         // transactions before submitting this batch
00171         // asynchronously.
00172         ch_spi_async_submit(handle);
00173         
00174         // The application can now perform some other functions
00175         // while the Cheetah is both finishing the previous batch
00176         // and shifting the current batch as well.  In order to
00177         // keep the Cheetah's pipe full, this entire loop must
00178         // complete AND another batch must be submitted
00179         // before the current batch completes.
00180         ch_sleep_ms(1);
00181         
00182         // Collect the previous batch
00183         //ret = ch_spi_async_collect(handle, txnlen, data_in);
00184         ret = ch_spi_async_collect(handle, N_FFT * 3, data_in);        
00185         //elapsed = ((double)(_timeMillis() - start)) / 1000;
00186 
00187 
00188         //data_in = (u08 *)malloc(3); 
00189         for (j = 0; j < N_FFT * 3; j += 6) {
00190 //        for (j = 0; j < N_FFT; j +=2 ) {
00191             // SS2 Data
00192             input = (data_in[j] << 8) + data_in[j+1];
00193             ready_bit = input & 0x4000;
00194             valid_data_point = (input & 0x3ffc) >> 2;
00195 //            valid_data[j/2] = valid_data_point;
00196             fprintf(data2_output, "%d\n", valid_data_point);
00197 
00198             // SS3 Data
00199             input = (data_in[j+2] << 8) + data_in[j+3];
00200             ready_bit = input & 0x4000;
00201             valid_data_point = (input & 0x3ffc) >> 2;
00202 //            valid_data[j/2 + 1] = valid_data_point;
00203             fprintf(data3_output, "%d\n", valid_data_point);
00204 //            fprintf(data1_output, "%d ", valid_data_point);
00205 //            data[j][0] = (double)valid_data_point;
00206 //            data[j][1] = 0.0;
00207 
00208             // SS1 Data
00209             input = (data_in[j+4] << 8) + data_in[j+5];
00210             ready_bit = input & 0x4000;
00211             valid_data_point = (input & 0x3ffc) >> 2;
00212 //            valid_data[j/2 + 2] = valid_data_point;
00213             fprintf(data1_output, "%d\n", valid_data_point);
00214         }
00215 
00216         // Ensures communication is successful
00217         if (ret < 0)  printf("status error: %s\n", ch_status_string(ret));
00218         fflush(stdout);
00219 
00220         //plan_forward  = fftw_plan_dft_1d( N_FFT, data, fft_result, FFTW_FORWARD, FFTW_ESTIMATE );
00221         //fftw_execute ( plan_forward );
00222 
00223         // Print FFT result
00224         //printf("Sampling frequency: %.6lf Hz\n", N_FFT / cycle_duration);
00225         //printf("Expected Index: %1.0f\n", 21000 * cycle_duration); 
00226 
00227         //fprintf(stderr, "Output FFT Result\n");
00228         //for( k = max(21000 * cycle_duration - 20, 0) ; k < min(21000 * cycle_duration + 20, N_FFT); k++ ) {
00229             //fprintf(data1_output, "%2.2f ", sqrt(pow(fft_result[k][0],2) + pow(fft_result[k][1],2)));
00230             //fprintf(stderr, "|fft_result[%d]| = %2.2f\n",
00231             //    k, sqrt(pow(fft_result[k][0],2) + pow(fft_result[k][1],2)) );
00232         //}
00233 
00234         //for( k = 0 ; k < N_FFT; k++ ) {
00235         //    fprintf(data1_output, "%2.2f ", data[k][0]);
00236         //}
00237         k=0;
00238         //fprintf(data1_output, "\n");
00239         //fprintf(stderr, "End of FFT Results\n");
00240 
00241 
00242         // The current batch is now shifting out on the SPI
00243         // interface. The application can again do some more tasks
00244         // here but this entire loop must finish so that a new
00245         // batch is armed before the current batch completes.
00246         ch_sleep_ms(1);
00247     }
00248     elapsed = ((double)(_timeMillis() - start)) / 1000;
00249     fprintf(stderr, "Transmission complete.  Data Collected.\n");
00250 
00251     fclose(data1_output); data1_output = NULL;
00252     fclose(data2_output); data2_output = NULL;
00253     fclose(data3_output); data3_output = NULL;
00254     
00255     printf("Took %.2lf seconds to get the data.\n", elapsed);
00256     fflush(stdout);
00257     printf("Sampling frequency: %.6lf Hz\n", 3 * 3 * N_FFT * iter / elapsed);
00258     fflush(stdout);
00259 
00260     // Collect batch the last batch
00261     //ret = ch_spi_async_collect(handle, 0, 0);
00262     //elapsed = ((double)(_timeMillis() - start)) / 1000;
00263     //printf("collected batch #%03d in %.5lf seconds\n", i+1, elapsed);
00264     //if (ret < 0)  printf("status error: %s\n", ch_status_string(ret));
00265     //fflush(stdout);
00266 }
00267 
00268 
00269 //=========================================================================
00270 // MAIN PROGRAM
00271 //=========================================================================
00272 int main (int argc, char *argv[]) {
00273     Cheetah handle;
00274     int port     = 0;
00275     int bitrate  = 0;
00276     u08 mode     = 0;
00277     u32 txnlen;
00278     u32 iter;
00279 
00280     if (argc < 5) {
00281         printf("usage: async PORT BITRATE TXN_LENGTH ITER\n");
00282         printf("\n");
00283         printf("TXN_LENGTH is the number of SPI packets, each of length\n");
00284         printf("4 to queue in a single batch.\n");
00285         printf("\n");
00286         printf("ITER is the number of batches to process asynchronously.\n");
00287         return 1;
00288     }
00289 
00290     port     = atoi(argv[1]);
00291     bitrate  = atoi(argv[2]);
00292     txnlen   = atoi(argv[3]);
00293     iter     = atoi(argv[4]);
00294     
00295     // Open the device
00296     handle = ch_open(port);
00297     if (handle <= 0) {
00298         printf("Unable to open Cheetah device on port %d\n", port);
00299         printf("Error code = %d (%s)\n", handle, ch_status_string(handle));
00300         return 1;
00301     }
00302     printf("Opened Cheetah device on port %d\n", port);
00303 
00304     printf("Host interface is %s\n",
00305            (ch_host_ifce_speed(handle)) ? "high speed" : "full speed");
00306 
00307     // Ensure that the SPI subsystem is configured.
00308     ch_spi_configure(handle, (mode >> 1), mode & 1, CH_SPI_BITORDER_MSB, 0x0);
00309     printf("SPI configuration set to mode %d, %s shift, SS[2:0] active low\n",
00310            mode, "MSB");
00311     fflush(stdout);
00312 
00313     // Power the target using the Cheetah adapter's power supply.
00314     ch_target_power(handle, CH_TARGET_POWER_ON);
00315     ch_sleep_ms(100);
00316 
00317     // Set the bitrate.
00318     bitrate = ch_spi_bitrate(handle, bitrate);
00319     printf("Bitrate set to %d kHz\n", bitrate);
00320     fflush(stdout);
00321 
00322     _blast_async(handle, txnlen, iter);
00323     
00324     // Close and exit.
00325     ch_close(handle);
00326     return 0;
00327 }
Generated on Sun May 8 08:42:06 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3