Source code in the attachment 15.03.2018, 15:44, Андрей 1 <andrew4...@rambler.ru>Hello I duplicated the attachment with the source code.Derek can you see what's wrong.I can understand what the maximum speed of perestroika I can get with TwinRX.
Thank you
/* * Copyright 2015 Ettus Research LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <uhd.h> #include "getopt.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define EXECUTE_OR_GOTO(label, ...) \ if(__VA_ARGS__){ \ return_code = EXIT_FAILURE; \ goto label; \ } #define MIN(x,y) (((x) < (y)) ? (x):(y)) void print_help(void){ fprintf(stderr, "rx_samples_c - A simple RX example using UHD's C API\n\n" "Options:\n" " -a (device args)\n" " -f (frequency in Hz)\n" " -r (sample rate in Hz)\n" " -g (gain)\n" " -n (number of samples to receive)\n" " -o (output filename, default = \"out.dat\")\n" " -v (enable verbose prints)\n" " -h (print this help message)\n"); }; #define spb 1024 #define fcount 11 size_t ACTIVE_CHAN = 0; size_t UNUSED_CHAN = 1; uhd_usrp_handle usrp; uhd_rx_streamer_handle streamer; uhd_rx_metadata_handle metadata; double f1 = 100e+6; double f2 = 110e+6; double fs = 1e+6; double receive_interval = 50e-3; size_t recv_spb; double rf_freqs[fcount]; float data[fcount*spb*2]; // 100..110 freq range uhd_error set_device_subspec(uhd_usrp_handle h, const char* markup) { uhd_error e; uhd_subdev_spec_handle spec; e = uhd_subdev_spec_make(&spec,markup); if (e == UHD_ERROR_NONE) e = uhd_usrp_set_rx_subdev_spec(h,spec,0); uhd_subdev_spec_free(&spec); return e; } uhd_error init_device_stream(uhd_usrp_handle h, uhd_rx_streamer_handle sh) { uhd_stream_args_t stream_args = { .cpu_format = "fc32", .otw_format = "sc16", .args = "", .channel_list = &ACTIVE_CHAN, .n_channels = 1 }; return uhd_usrp_get_rx_stream(h,&stream_args,sh); } uhd_error set_device_freq(uhd_usrp_handle h, double freq, size_t chan) { uhd_tune_request_t tune_request = { .target_freq = freq, .rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO, .dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO, }; uhd_tune_result_t tune_result; return uhd_usrp_set_rx_freq(h,&tune_request,chan,&tune_result); } uhd_error init_commands(uhd_usrp_handle h, uhd_rx_streamer_handle sh, int n) { uhd_error e; e = uhd_usrp_set_time_now(h,0,0,0); if (e != UHD_ERROR_NONE) return e; uhd_stream_cmd_t stream_cmd = { .stream_mode = UHD_STREAM_MODE_NUM_SAMPS_AND_DONE, .num_samps = spb, .stream_now = false }; double command_time = 0; for(int i=0; i<n; i++) { command_time += receive_interval; stream_cmd.time_spec_full_secs = (int)command_time; stream_cmd.time_spec_frac_secs = command_time - (int)command_time; e = uhd_rx_streamer_issue_stream_cmd(sh,&stream_cmd); if (e != UHD_ERROR_NONE) break; } return e; } uhd_error twinrx_recv(uhd_rx_streamer_handle sh, uhd_rx_metadata_handle mh, float *buffer) { uhd_error e; size_t num_acc_samps = 0; size_t num_recvd; float *p = buffer; // Repeatedly retrieve samples until the entire acquisition is received while (num_acc_samps < spb) { size_t num_to_recv = MIN(recv_spb, (spb - num_acc_samps)); // recv call will block until samples are ready or the call times out e = uhd_rx_streamer_recv(sh,(void **) &p,num_to_recv,&mh,receive_interval,false,&num_recvd); if (e != UHD_ERROR_NONE) break; num_acc_samps += num_recvd; p += num_recvd; } return e; } uhd_error test() { uhd_error e; clock_t t1,t2; e = uhd_usrp_set_rx_lo_source(usrp,"disabled","all",UNUSED_CHAN); e = uhd_usrp_set_rx_antenna(usrp,"RX1",ACTIVE_CHAN); e = uhd_usrp_set_rx_rate(usrp,fs,ACTIVE_CHAN); e = uhd_usrp_set_rx_rate(usrp,fs,UNUSED_CHAN); e = uhd_usrp_set_rx_gain(usrp,80,ACTIVE_CHAN,""); e = uhd_usrp_set_rx_gain(usrp,80,UNUSED_CHAN,""); uhd_rx_streamer_max_num_samps(streamer,&recv_spb); for (int i=0; i<fcount; i++) rf_freqs[i] = f1 + i*fs; e = set_device_freq(usrp,rf_freqs[0],ACTIVE_CHAN); if (e != UHD_ERROR_NONE) return e; e = init_commands(usrp,streamer,fcount); if (e != UHD_ERROR_NONE) return e; for (int i=0; i<fcount; i++) { char* lo_src = (i % 2) ? "companion" : "internal"; t1 = clock(); e = uhd_usrp_set_rx_lo_source(usrp,lo_src,"all",ACTIVE_CHAN); if (e != UHD_ERROR_NONE) break; t2 = clock(); printf("lo_source time %f\n",(double)(t2-t1)/CLOCKS_PER_SEC); e = set_device_freq(usrp,rf_freqs[(i+1) % fcount],UNUSED_CHAN); if (e != UHD_ERROR_NONE) break; e = set_device_freq(usrp,rf_freqs[i], ACTIVE_CHAN); if (e != UHD_ERROR_NONE) break; e = twinrx_recv(streamer,metadata,&data[i*spb*2]); if (e != UHD_ERROR_NONE) break; } return e; } void sleep(double sec) { time_t start = clock(); while ((clock()-start) < sec*CLOCKS_PER_SEC) {}; } void do_test() { clock_t t1 = clock(); uhd_error e = test(); clock_t t2 = clock(); double delta = (double)(t2-t1)/CLOCKS_PER_SEC; printf("error: %d\n",e); printf("exec time %f\n",delta); } int main(void) { if(uhd_set_thread_priority(uhd_default_thread_priority, true)){ fprintf(stderr, "Unable to set thread priority. Continuing anyway.\n"); } uhd_error e; // Create //**************************************************** uhd_usrp_make(&usrp, ""); uhd_rx_streamer_make(&streamer); uhd_rx_metadata_make(&metadata); //**************************************************** // Init //**************************************************** e = set_device_subspec(usrp,"A:0 A:1"); if (e != UHD_ERROR_NONE) goto free_device; e = init_device_stream(usrp,streamer); if (e != UHD_ERROR_NONE) goto free_device; //**************************************************** do_test(); free_device: // Delete //**************************************************** uhd_rx_metadata_free(&metadata); uhd_rx_streamer_free(&streamer); uhd_usrp_free(&usrp); //**************************************************** return EXIT_SUCCESS; /* int option = 0; double freq = 500e6; double rate = 1e6; double gain = 5.0; char* device_args = ""; size_t channel = 0; char* filename = "out.dat"; size_t n_samples = 1000000; bool verbose = false; int return_code = EXIT_SUCCESS; bool custom_filename = false; char error_string[512]; // Process options while((option = getopt(argc, argv, "a:f:r:g:n:o:vh")) != -1){ switch(option){ case 'a': device_args = strdup(optarg); break; case 'f': freq = atof(optarg); break; case 'r': rate = atof(optarg); break; case 'g': gain = atof(optarg); break; case 'n': n_samples = atoi(optarg); break; case 'o': filename = strdup(optarg); custom_filename = true; break; case 'v': verbose = true; break; case 'h': print_help(); goto free_option_strings; default: print_help(); return_code = EXIT_FAILURE; goto free_option_strings; } } // Create USRP uhd_usrp_handle usrp; fprintf(stderr, "Creating USRP with args \"%s\"...\n", device_args); EXECUTE_OR_GOTO(free_option_strings, uhd_usrp_make(&usrp, device_args) ) // Create RX streamer uhd_rx_streamer_handle rx_streamer; EXECUTE_OR_GOTO(free_usrp, uhd_rx_streamer_make(&rx_streamer) ) // Create RX metadata uhd_rx_metadata_handle md; EXECUTE_OR_GOTO(free_rx_streamer, uhd_rx_metadata_make(&md) ) // Create other necessary structs uhd_tune_request_t tune_request = { .target_freq = freq, .rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO, .dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO, }; uhd_tune_result_t tune_result; uhd_stream_args_t stream_args = { .cpu_format = "fc32", .otw_format = "sc16", .args = "", .channel_list = &channel, .n_channels = 1 }; uhd_stream_cmd_t stream_cmd = { .stream_mode = UHD_STREAM_MODE_NUM_SAMPS_AND_DONE, .num_samps = n_samples, .stream_now = true }; size_t samps_per_buff; float *buff = NULL; void **buffs_ptr = NULL; FILE *fp = NULL; size_t num_acc_samps = 0; // Set rate fprintf(stderr, "Setting RX Rate: %f...\n", rate); EXECUTE_OR_GOTO(free_rx_metadata, uhd_usrp_set_rx_rate(usrp, rate, channel) ) // See what rate actually is EXECUTE_OR_GOTO(free_rx_metadata, uhd_usrp_get_rx_rate(usrp, channel, &rate) ) fprintf(stderr, "Actual RX Rate: %f...\n", rate); // Set gain fprintf(stderr, "Setting RX Gain: %f dB...\n", gain); EXECUTE_OR_GOTO(free_rx_metadata, uhd_usrp_set_rx_gain(usrp, gain, channel, "") ) // See what gain actually is EXECUTE_OR_GOTO(free_rx_metadata, uhd_usrp_get_rx_gain(usrp, channel, "", &gain) ) fprintf(stderr, "Actual RX Gain: %f...\n", gain); // Set frequency fprintf(stderr, "Setting RX frequency: %f MHz...\n", freq/1e6); EXECUTE_OR_GOTO(free_rx_metadata, uhd_usrp_set_rx_freq(usrp, &tune_request, channel, &tune_result) ) // See what frequency actually is EXECUTE_OR_GOTO(free_rx_metadata, uhd_usrp_get_rx_freq(usrp, channel, &freq) ) fprintf(stderr, "Actual RX frequency: %f MHz...\n", freq / 1e6); // Set up streamer stream_args.channel_list = &channel; EXECUTE_OR_GOTO(free_rx_streamer, uhd_usrp_get_rx_stream(usrp, &stream_args, rx_streamer) ) // Set up buffer EXECUTE_OR_GOTO(free_rx_streamer, uhd_rx_streamer_max_num_samps(rx_streamer, &samps_per_buff) ) fprintf(stderr, "Buffer size in samples: %zu\n", samps_per_buff); buff = malloc(samps_per_buff * 2 * sizeof(float)); buffs_ptr = (void**)&buff; // Issue stream command fprintf(stderr, "Issuing stream command.\n"); EXECUTE_OR_GOTO(free_buffer, uhd_rx_streamer_issue_stream_cmd(rx_streamer, &stream_cmd) ) // Set up file output fp = fopen(filename, "wb"); // Actual streaming while (num_acc_samps < n_samples) { size_t num_rx_samps = 0; EXECUTE_OR_GOTO(close_file, uhd_rx_streamer_recv(rx_streamer, buffs_ptr, samps_per_buff, &md, 3.0, false, &num_rx_samps) ) uhd_rx_metadata_error_code_t error_code; EXECUTE_OR_GOTO(close_file, uhd_rx_metadata_error_code(md, &error_code) ) if(error_code != UHD_RX_METADATA_ERROR_CODE_NONE){ fprintf(stderr, "Error code 0x%x was returned during streaming. Aborting.\n", return_code); goto close_file; } // Handle data fwrite(buff, sizeof(float) * 2, num_rx_samps, fp); if (verbose) { time_t full_secs; double frac_secs; uhd_rx_metadata_time_spec(md, &full_secs, &frac_secs); fprintf(stderr, "Received packet: %zu samples, %.f full secs, %f frac secs\n", num_rx_samps, difftime(full_secs, (time_t) 0), frac_secs); } num_acc_samps += num_rx_samps; } // Cleanup close_file: fclose(fp); free_buffer: if(buff){ if(verbose){ fprintf(stderr, "Freeing buffer.\n"); } free(buff); } buff = NULL; buffs_ptr = NULL; free_rx_streamer: if(verbose){ fprintf(stderr, "Cleaning up RX streamer.\n"); } uhd_rx_streamer_free(&rx_streamer); free_rx_metadata: if(verbose){ fprintf(stderr, "Cleaning up RX metadata.\n"); } uhd_rx_metadata_free(&md); free_usrp: if(verbose){ fprintf(stderr, "Cleaning up USRP.\n"); } if(return_code != EXIT_SUCCESS && usrp != NULL){ uhd_usrp_last_error(usrp, error_string, 512); fprintf(stderr, "USRP reported the following error: %s\n", error_string); } uhd_usrp_free(&usrp); free_option_strings: if(strcmp(device_args,"")){ free(device_args); } if(custom_filename){ free(filename); } fprintf(stderr, (return_code ? "Failure\n" : "Success\n")); return return_code; */ }
_______________________________________________ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com