00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <math.h> 00004 00005 #include "cheetah.h" 00006 #include <fftw3.h> 00007 #include "CImg.h" 00008 00009 using namespace cimg_library; 00010 00011 // Cheetah 00012 Cheetah handle; 00013 int port = 0; 00014 int bitrate = 0; 00015 uint8_t mode = 0; 00016 00017 // FFT 00018 const int N_FFT = 512; 00019 const size_t MAX_TX_LENGTH = (N_FFT) * 3 * 2; 00020 fftw_complex *data, *fft_result; 00021 fftw_plan plan_forward; 00022 00023 // Data 00024 uint8_t data_in[MAX_TX_LENGTH]; 00025 uint8_t data_out[2]; 00026 int ret; 00027 //int txnlen = atoi(argv[3]); 00028 int input; 00029 int ready_bit; 00030 int valid_data_point; 00031 00032 00033 00034 00035 int main (int argc, char const *argv[]) { 00036 if (argc < 3) { 00037 printf("usage: async PORT BITRATE\n"); 00038 return 1; 00039 } 00040 00041 port = atoi(argv[1]); 00042 bitrate = atoi(argv[2]); 00043 00044 // Open the device 00045 handle = ch_open(port); 00046 00047 if (handle <= 0) { 00048 printf("Unable to open Cheetah device on port %d\n", port); 00049 printf("Error code = %d (%s)\n", handle, ch_status_string(handle)); 00050 exit(1); 00051 } 00052 printf("Opened Cheetah device on port %d\n", port); 00053 00054 printf("Host interface is %s\n", 00055 (ch_host_ifce_speed(handle)) ? "high speed" : "full speed"); 00056 00057 // Ensure that the SPI subsystem is configured. 00058 ch_spi_configure(handle, CheetahSpiPolarity(mode >> 1), CheetahSpiPhase(mode & 1), CH_SPI_BITORDER_MSB, 0x0); 00059 printf("SPI configuration set to mode %d, %s shift, SS[2:0] active low\n", mode, "MSB"); 00060 00061 // Power the target using the Cheetah adapter's power supply. 00062 ch_target_power(handle, CH_TARGET_POWER_ON); 00063 ch_sleep_ms(100); 00064 00065 // Set the bitrate. 00066 bitrate = ch_spi_bitrate(handle, bitrate); 00067 printf("Bitrate set to %d kHz\n", bitrate); 00068 00069 // Make a simple queue to just assert OE. 00070 ch_spi_queue_clear(handle); 00071 ch_spi_queue_oe(handle, 1); 00072 ch_spi_batch_shift(handle, 0, 0); 00073 00074 fprintf(stderr, "Beginning to queue SPI packets..."); 00075 // Queue the batch, which is a sequence of SPI packets (back-to-back) each of length 2. 00076 data_out[0] = 0xff; 00077 data_out[1] = 0xff; 00078 ch_spi_queue_clear(handle); 00079 00080 for (int i = 0; i < N_FFT * 3; ++i) { 00081 // Convert Slave 1 00082 ch_spi_queue_ss(handle, 0xF); 00083 ch_spi_queue_array(handle, 2, data_out); 00084 ch_spi_queue_ss(handle, 0xE); 00085 00086 // Convert Slave 2 00087 ch_spi_queue_ss(handle, 0xF); 00088 ch_spi_queue_array(handle, 2, data_out); 00089 ch_spi_queue_ss(handle, 0xD); 00090 00091 // Convert Slave 3 00092 ch_spi_queue_ss(handle, 0xF); 00093 ch_spi_queue_array(handle, 2, data_out); 00094 ch_spi_queue_ss(handle, 0xB); 00095 } 00096 fprintf(stderr, " Done\n"); 00097 00098 // Define the Data Vectors 00099 CImg<int> data1(1, N_FFT, 1, 1, 0); 00100 CImg<int> data2(1, N_FFT, 1, 1, 0); 00101 CImg<int> data3(1, N_FFT, 1, 1, 0); 00102 CImg<float> result(1, N_FFT, 1, 1, 0); 00103 CImgList<float> fft_output; 00104 CImgList<float> display_set; 00105 CImgDisplay window(600,800); 00106 00107 00108 // Submit the first batch 00109 ch_spi_async_submit(handle); 00110 00111 while (1) { 00112 // Submit another batch, while the previous one is in 00113 // progress. The application may even clear the current 00114 // batch queue and queue a different set of SPI 00115 // transactions before submitting this batch 00116 // asynchronously. 00117 ch_spi_async_submit(handle); 00118 00119 // The application can now perform some other functions 00120 // while the Cheetah is both finishing the previous batch 00121 // and shifting the current batch as well. In order to 00122 // keep the Cheetah's pipe full, this entire loop must 00123 // complete AND another batch must be submitted 00124 // before the current batch completes. 00125 //ch_sleep_ms(1); 00126 00127 // Collect the previous batch 00128 ret = ch_spi_async_collect(handle, N_FFT * 6, data_in); 00129 00130 for (int j = 0; j < N_FFT * 6;j += 6) { 00131 00132 // SS3 Data 00133 input = (data_in[j] << 8) + data_in[j+1]; 00134 ready_bit = input & 0x4000; 00135 valid_data_point = (input & 0x3ffc) >> 2; 00136 data3(1,j/6) = valid_data_point; 00137 00138 // SS2 Data 00139 input = (data_in[j+2] << 8) + data_in[j+3]; 00140 ready_bit = input & 0x4000; 00141 valid_data_point = (input & 0x3ffc) >> 2; 00142 data2(1,j/6) = valid_data_point; 00143 00144 // SS1 Data 00145 input = (data_in[j+4] << 8) + data_in[j+5]; 00146 ready_bit = input & 0x4000; 00147 valid_data_point = (input & 0x3ffc) >> 2; 00148 data1(1,j/6) = valid_data_point; 00149 } 00150 //(data1,data2,data3).display(); 00151 fft_output = data2.get_FFT('y'); 00152 result = fft_output[0].sqr() + fft_output[1].sqr(); 00153 result = result.crop(0,10,0,200); 00154 display_set.push_back(result); 00155 if (display_set.size() > 100) 00156 display_set.pop_front(); 00157 window.resize(false).display(display_set); 00158 00159 // Ensures communication is successful 00160 if (ret < 0) printf("status error: %s\n", ch_status_string(ret)); 00161 fflush(stdout); 00162 00163 } 00164 00165 return 0; 00166 }