[USRP-users] Different streaming modes at the same time with same USRP hardware

Felipe Augusto Pereira de Figueiredo zz4fap at gmail.com
Sat Jul 22 12:18:12 EDT 2017


Dear Michael,

Do you have any update on my question/problem?
It's been quite a while since I sent you an email with my question/problem.

Thanks and Kind Regards,

Felipe Agusto

On Wed, Jul 12, 2017 at 5:16 PM, Felipe Augusto Pereira de Figueiredo
<zz4fap at gmail.com> wrote:
> Dear Michael,
>
> Do you have an update on my question?
>
> I'd also like to add that I have also modified the tx_samples_c.c
> example to open two different channels as I did for RX only that now I
> do it with TX streams. It also worked for both, x310 and b210.
>
> I really don't understand why I'm not able to open 2RX and 2TX streams
> with the code I sent you earlier.
>
> Thanks and Kind Regards,
>
> Felipe Augusto
>
> On Fri, Jul 7, 2017 at 11:58 PM, Felipe Augusto Pereira de Figueiredo
> <zz4fap at gmail.com> wrote:
>> Thanks Michael!
>>
>> Now I'm trying to create different streamers for TX and RX in channels
>> 0 and 1, but my application running on a b210 returns the following
>> error:
>>
>> Error opening RX stream for channel 1 with error code: 44
>> No compatible RF frontend found
>> Error opening rf
>>
>> I checked and code 44 means UHD_ERROR_RUNTIME.
>>
>> The most strange thing is that with a x310 the same code (see code
>> below) works. The code I sent previously to you runs with both b210
>> and x310 USRPs, however, it only creates/configures RX streamers.
>>
>> What could be the reason for this different behaviour? Is there a
>> sequence for creating and setting TX and RX streamers for channels 0
>> and 1?
>>
>> Thanks and Kind Regards,
>>
>> Felipe Augusto
>>
>>    /* Find available devices */
>>     uhd_string_vector_handle devices_str;
>>     uhd_string_vector_make(&devices_str);
>>     uhd_usrp_find("", &devices_str);
>>
>>     char args2[512];
>>
>>     handler->dynamic_rate = true;
>>
>>     // Allow NULL parameter
>>     if (args == NULL) {
>>       args = "";
>>     }
>>     handler->devname = NULL;
>>
>>     // Initialize handler
>>     handler->uhd_error_handler = NULL;
>>
>>     /* If device type or name not given in args, choose a B200 */
>>     if (args[0]=='\0') {
>>       if (find_string(devices_str, "type=b200") && !strstr(args,
>> "recv_frame_size")) {
>>         // If B200 is available, use it
>>         args = "type=b200";
>>         handler->devname = DEVNAME_B200;
>>       } else if (find_string(devices_str, "type=x300")) {
>>         // Else if X300 is available, set master clock rate now (with
>> x310 it can't be changed later)
>>         args = "type=x300,master_clock_rate=184.32e6";// If no
>> argument is passed we set master clock rate to 184.32 MHz in order to
>> use standard LTE rates, i.e., carrier sepration of 15 KHz.
>>         //args = "type=x300,master_clock_rate=200e6"; // In case we
>> need longer CP periods, we should set master clock rate to 200 MHz in
>> order to be able to set the sampling rate to 5 MHz and have bigger
>> CPs.
>>         handler->dynamic_rate = false;
>>         handler->devname = DEVNAME_X300;
>>       }
>>     } else {
>>       // If args is set and x300 type is specified, make sure
>> master_clock_rate is defined
>>       if (strstr(args, "type=x300") && !strstr(args, "master_clock_rate")) {
>>         sprintf(args2, "%s,master_clock_rate=184.32e6",args);
>>         args = args2;
>>         handler->dynamic_rate = false;
>>         handler->devname = DEVNAME_X300;
>>       } else if (strstr(args, "type=b200")) {
>>         handler->devname = DEVNAME_B200;
>>       }
>>     }
>>
>>     uhd_string_vector_free(&devices_str);
>>
>>     /* Create UHD handler */
>>     printf("Opening USRP with args: %s\n", args);
>>     uhd_error error = uhd_usrp_make(&handler->usrp, args);
>>     if (error) {
>>       fprintf(stderr, "Error opening UHD: code %d\n", error);
>>       return -1;
>>     }
>>
>>     if (!handler->devname) {
>>       char dev_str[1024];
>>       uhd_usrp_get_mboard_name(handler->usrp, 0, dev_str, 1024);
>>       if (strstr(dev_str, "B2") || strstr(dev_str, "B2")) {
>>         handler->devname = DEVNAME_B200;
>>       } else if (strstr(dev_str, "X3") || strstr(dev_str, "X3")) {
>>         handler->devname = DEVNAME_X300;
>>       }
>>     }
>>     if (!handler->devname) {
>>       handler->devname = "uhd_unknown";
>>     }
>>
>>     // Set external clock reference
>>     if (strstr(args, "clock=external")) {
>>       uhd_usrp_set_clock_source(handler->usrp, "external", 0);
>>     }
>>
>>     // ************* Initialize Channes 0 and 1. *************
>>     size_t channels[2] = {0,1};
>>     uhd_stream_args_t stream_args = {
>>       .cpu_format = "fc32",
>>       .otw_format = "sc16",
>>       .args = "",
>>       .channel_list = channels,
>>       .n_channels = 2
>>     };
>>
>>     // Stream args for channels 0 and 1
>>     for(size_t channel = 0; channel < 2; channel++) {
>>
>>       handler->channels[channel].has_rssi = get_has_rssi(handler, channel);
>>       if (handler->channels[channel].has_rssi) {
>>         uhd_sensor_value_make_from_realnum(&handler->channels[channel].rssi_value,
>> "rssi", 0, "dBm", "%f");
>>       }
>>
>>       /* Initialize RX and TX streamers */
>>       uhd_rx_streamer_make(&handler->channels[channel].rx_stream);
>>       stream_args.channel_list = &channels[channel];
>>       stream_args.n_channels = 1;
>>       error = uhd_usrp_get_rx_stream(handler->usrp, &stream_args,
>> handler->channels[channel].rx_stream);
>>       if (error) {
>>         fprintf(stderr, "Error opening RX stream for channel %d with
>> error code: %d\n",channel, error);
>>         return -1;
>>       }
>>       uhd_tx_streamer_make(&handler->channels[channel].tx_stream);
>>       error = uhd_usrp_get_tx_stream(handler->usrp, &stream_args,
>> handler->channels[channel].tx_stream);
>>       if (error) {
>>         fprintf(stderr, "Error opening TX stream: %d\n", error);
>>         return -1;
>>       }
>>
>>       uhd_rx_streamer_max_num_samps(handler->channels[channel].rx_stream,
>> &handler->channels[channel].rx_nof_samples);
>>       uhd_tx_streamer_max_num_samps(handler->channels[channel].tx_stream,
>> &handler->channels[channel].tx_nof_samples);
>>
>>       uhd_meta_range_make(&handler->channels[channel].rx_gain_range);
>>       uhd_usrp_get_rx_gain_range(handler->usrp, "", channel,
>> handler->channels[channel].rx_gain_range);
>>
>>       // Make metadata objects for RX/TX.
>>       uhd_rx_metadata_make(&handler->channels[channel].rx_md);
>>       uhd_rx_metadata_make(&handler->channels[channel].rx_md_first);
>>       uhd_tx_metadata_make(&handler->channels[channel].tx_md, false,
>> 0, 0, false, false);
>>     }
>>
>> On Fri, Jul 7, 2017 at 11:32 PM, Michael West <michael.west at ettus.com> wrote:
>>> Hi Felipe,
>>>
>>> If it works, it must be right!  The code looks fine to me.
>>>
>>> Regards,
>>> Michael
>>>
>>> On Mon, Jul 3, 2017 at 3:58 AM, Felipe Augusto Pereira de Figueiredo
>>> <zz4fap at gmail.com> wrote:
>>>>
>>>> Dear Michael,
>>>>
>>>> I've followed your suggestion and hacked the rx_samples_c.c example.
>>>> It seems to be working but I'm not sure if that is the right way of doing
>>>> that.
>>>> Could you please have a quick look and tell me if that is the correct way
>>>> of creating 2 different RX streams.
>>>>
>>>> Thanks and Kind Regards,
>>>>
>>>> Felipe Augusto
>>>>
>>>> /*
>>>>  * 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>
>>>>
>>>> #define EXECUTE_OR_GOTO(label, ...) \
>>>>     if(__VA_ARGS__){ \
>>>>         return_code = EXIT_FAILURE; \
>>>>         goto label; \
>>>>     }
>>>>
>>>> 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");
>>>> };
>>>>
>>>> int main(int argc, char* argv[])
>>>> {
>>>>     if(uhd_set_thread_priority(uhd_default_thread_priority, true)){
>>>>         fprintf(stderr, "Unable to set thread priority. Continuing
>>>> anyway.\n");
>>>>     }
>>>>
>>>>     int option = 0;
>>>>     double freq = 2.4e9;
>>>>     double rate = 10e6;
>>>>     double gain = 5.0;
>>>>     char* device_args = "";
>>>>     size_t channel[2] = {0,1};
>>>>     char *filename0 = "out0.dat", *filename1 = "out1.dat";
>>>>     size_t n_samples = 1000000;
>>>>     bool verbose = false;
>>>>     int return_code = EXIT_SUCCESS;
>>>>     bool custom_filename0 = false, custom_filename1 = false;
>>>>     char error_string[512];
>>>>
>>>>     // Process options
>>>>     while((option = getopt(argc, argv, "a:f:r:g:n:o: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':
>>>>                 filename0 = strdup(optarg);
>>>>                 custom_filename0 = true;
>>>>                 break;
>>>>
>>>>             case 'O':
>>>>                 filename1 = strdup(optarg);
>>>>                 custom_filename1 = 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 #0.
>>>>     uhd_rx_streamer_handle rx_streamer0;
>>>>     EXECUTE_OR_GOTO(free_usrp,
>>>>         uhd_rx_streamer_make(&rx_streamer0)
>>>>     )
>>>>
>>>>     // Create RX metadata #0.
>>>>     uhd_rx_metadata_handle md0;
>>>>     EXECUTE_OR_GOTO(free_rx_streamer0,
>>>>         uhd_rx_metadata_make(&md0)
>>>>     )
>>>>
>>>>     // Create RX streamer #1.
>>>>     uhd_rx_streamer_handle rx_streamer1;
>>>>     EXECUTE_OR_GOTO(free_usrp,
>>>>         uhd_rx_streamer_make(&rx_streamer1)
>>>>     )
>>>>
>>>>     // Create RX metadata #1.
>>>>     uhd_rx_metadata_handle md1;
>>>>     EXECUTE_OR_GOTO(free_rx_streamer1,
>>>>         uhd_rx_metadata_make(&md1)
>>>>     )
>>>>
>>>>     // 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 = 2
>>>>     };
>>>>
>>>>     size_t samps_per_buff0, samps_per_buff1;
>>>>     float *buff0 = NULL, *buff1 = NULL;
>>>>     void **buffs_ptr0 = NULL, **buffs_ptr1 = NULL;
>>>>     FILE *fp0 = NULL, *fp1 = NULL;
>>>>     size_t num_acc_samps0 = 0, num_acc_samps1 = 0;
>>>>
>>>>     // Set rate for stream #0
>>>>     fprintf(stderr, "Setting RX Rate 0: %f...\n", rate);
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_set_rx_rate(usrp, rate, channel[0])
>>>>     )
>>>>
>>>>     // Set rate for stream #1
>>>>     // Stream number 1 should have a different sampling rate.
>>>>     rate = 2*rate;
>>>>     fprintf(stderr, "Setting RX Rate 1: %f...\n", rate);
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_set_rx_rate(usrp, rate, channel[1])
>>>>     )
>>>>
>>>>     // See what rate is actually set for stream #0
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_get_rx_rate(usrp, channel[0], &rate)
>>>>     )
>>>>     fprintf(stderr, "Actual RX Rate 0: %f...\n", rate);
>>>>
>>>>     // See what rate is actually set for stream #1
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_get_rx_rate(usrp, channel[1], &rate)
>>>>     )
>>>>     fprintf(stderr, "Actual RX Rate 1: %f...\n", rate);
>>>>
>>>>     // Set gain for stream #0
>>>>     fprintf(stderr, "Setting RX Gain 0: %f dB...\n", gain);
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_set_rx_gain(usrp, gain, channel[0], "")
>>>>     )
>>>>
>>>>     // Set gain for stream #1
>>>>     fprintf(stderr, "Setting RX Gain 1: %f dB...\n", gain);
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_set_rx_gain(usrp, gain, channel[1], "")
>>>>     )
>>>>
>>>>     // See what gain is actually set for stream #0
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_get_rx_gain(usrp, channel[0], "", &gain)
>>>>     )
>>>>     fprintf(stderr, "Actual RX Gain 0: %f...\n", gain);
>>>>
>>>>     // See what gain is actually set for stream #1
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_get_rx_gain(usrp, channel[1], "", &gain)
>>>>     )
>>>>     fprintf(stderr, "Actual RX Gain 1: %f...\n", gain);
>>>>
>>>>     // Set frequency for stream #0
>>>>     fprintf(stderr, "Setting RX frequency 0: %f MHz...\n", freq/1e6);
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_set_rx_freq(usrp, &tune_request, channel[0],
>>>> &tune_result)
>>>>     )
>>>>
>>>>     // Set frequency for stream #1
>>>>     freq = 3e9;
>>>>     tune_request.target_freq = freq;
>>>>     fprintf(stderr, "Setting RX frequency 1: %f MHz...\n", freq/1e6);
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_set_rx_freq(usrp, &tune_request, channel[1],
>>>> &tune_result)
>>>>     )
>>>>
>>>>     // See what frequency is actually set fro stream #0
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_get_rx_freq(usrp, channel[0], &freq)
>>>>     )
>>>>     fprintf(stderr, "Actual RX frequency 0: %f MHz...\n", freq / 1e6);
>>>>
>>>>     // See what frequency is actually set fro stream #1
>>>>     EXECUTE_OR_GOTO(free_rx_metadata,
>>>>         uhd_usrp_get_rx_freq(usrp, channel[1], &freq)
>>>>     )
>>>>     fprintf(stderr, "Actual RX frequency 1: %f MHz...\n", freq / 1e6);
>>>>
>>>>     // Set up streamer #0.
>>>>     printf("Try to get RX Stream #0\n");
>>>>     stream_args.channel_list = &channel[0];
>>>>     stream_args.n_channels = 1;
>>>>     EXECUTE_OR_GOTO(free_rx_streamer0,
>>>>         uhd_usrp_get_rx_stream(usrp, &stream_args, rx_streamer0)
>>>>     )
>>>>     printf("Got RX Stream #0\n");
>>>>
>>>>     // Set up streamer #1.
>>>>     printf("Try to get RX Stream #1\n");
>>>>     stream_args.channel_list = &channel[1];
>>>>     stream_args.n_channels = 1;
>>>>     EXECUTE_OR_GOTO(free_rx_streamer1,
>>>>         uhd_usrp_get_rx_stream(usrp, &stream_args, rx_streamer1)
>>>>     )
>>>>     printf("Got RX Stream #1\n");
>>>>
>>>>     // Set up buffer for stream #0.
>>>>     EXECUTE_OR_GOTO(free_rx_streamer0,
>>>>        uhd_rx_streamer_max_num_samps(rx_streamer0, &samps_per_buff0)
>>>>     )
>>>>     printf("Buffer size in samples for stream #0: %zu\n",
>>>> samps_per_buff0);
>>>>     buff0 = malloc(samps_per_buff0 * 2 * sizeof(float));
>>>>     buffs_ptr0 = (void**)&buff0;
>>>>
>>>>     // Set up buffer for stream #1.
>>>>     EXECUTE_OR_GOTO(free_rx_streamer1,
>>>>        uhd_rx_streamer_max_num_samps(rx_streamer1, &samps_per_buff1)
>>>>     )
>>>>     printf("Buffer size in samples for stream #1: %zu\n",
>>>> samps_per_buff1);
>>>>     buff1 = malloc(samps_per_buff1 * 2 * sizeof(float));
>>>>     buffs_ptr1 = (void**)&buff1;
>>>>
>>>>     // Stream command for stream #0.
>>>>     uhd_stream_cmd_t stream_cmd0 = {
>>>>         .stream_mode = UHD_STREAM_MODE_NUM_SAMPS_AND_DONE,
>>>>         .num_samps = n_samples,
>>>>         .stream_now = false,
>>>> .time_spec_full_secs = 2,
>>>> .time_spec_frac_secs = 0
>>>>     };
>>>>
>>>>     // Issue stream command for stream #0.
>>>>     fprintf(stderr, "Issuing stream command for stream #0.\n");
>>>>     EXECUTE_OR_GOTO(free_buffer0,
>>>>         uhd_rx_streamer_issue_stream_cmd(rx_streamer0, &stream_cmd0)
>>>>     )
>>>>
>>>>     // Stream command for stream #1.
>>>>     uhd_stream_cmd_t stream_cmd1 = {
>>>>         .stream_mode = UHD_STREAM_MODE_NUM_SAMPS_AND_DONE,
>>>>         .num_samps = n_samples,
>>>>         .stream_now = false,
>>>> .time_spec_full_secs = 4,
>>>> .time_spec_frac_secs = 0
>>>>     };
>>>>
>>>>     // Issue stream command for stream #1.
>>>>     fprintf(stderr, "Issuing stream command for stream #1.\n");
>>>>     EXECUTE_OR_GOTO(free_buffer1,
>>>>         uhd_rx_streamer_issue_stream_cmd(rx_streamer1, &stream_cmd1)
>>>>     )
>>>>
>>>>     // Set up file output for stream #0.
>>>>     fp0 = fopen(filename0, "wb");
>>>>
>>>>     // Set up file output for stream #1.
>>>>     fp1 = fopen(filename1, "wb");
>>>>
>>>>     // Actual streaming
>>>>     while (num_acc_samps0 < n_samples) {
>>>>         size_t num_rx_samps0 = 0;
>>>>         EXECUTE_OR_GOTO(close_file0,
>>>>             uhd_rx_streamer_recv(rx_streamer0, buffs_ptr0,
>>>> samps_per_buff0, &md0, 3.0, false, &num_rx_samps0)
>>>>         )
>>>>
>>>>         size_t num_rx_samps1 = 0;
>>>>         EXECUTE_OR_GOTO(close_file1,
>>>>             uhd_rx_streamer_recv(rx_streamer1, buffs_ptr1,
>>>> samps_per_buff1, &md1, 3.0, false, &num_rx_samps1)
>>>>         )
>>>>
>>>>         uhd_rx_metadata_error_code_t error_code0;
>>>>         EXECUTE_OR_GOTO(close_file0,
>>>>             uhd_rx_metadata_error_code(md0, &error_code0)
>>>>         )
>>>>         if(error_code0 != UHD_RX_METADATA_ERROR_CODE_NONE){
>>>>             fprintf(stderr, "Error code 0x%x was returned during
>>>> streaming. Aborting: 0x%x.\n", return_code,error_code0);
>>>>             goto close_file0;
>>>>         }
>>>>
>>>>         uhd_rx_metadata_error_code_t error_code1;
>>>>         EXECUTE_OR_GOTO(close_file1,
>>>>             uhd_rx_metadata_error_code(md1, &error_code1)
>>>>         )
>>>>         if(error_code1 != UHD_RX_METADATA_ERROR_CODE_NONE){
>>>>             fprintf(stderr, "Error code 0x%x was returned during
>>>> streaming. Aborting: 0x%x.\n", return_code,error_code1);
>>>>             goto close_file1;
>>>>         }
>>>>
>>>>         // Handle data for stream #0.
>>>>         fwrite(buff0, sizeof(float) * 2, num_rx_samps0, fp0);
>>>>         if (verbose) {
>>>>             time_t full_secs;
>>>>             double frac_secs;
>>>>             uhd_rx_metadata_time_spec(md0, &full_secs, &frac_secs);
>>>>             fprintf(stderr, "Received packet: %zu samples, %.f full secs,
>>>> %f frac secs\n",
>>>>                     num_rx_samps0,
>>>>                     difftime(full_secs, (time_t) 0),
>>>>                     frac_secs);
>>>>         }
>>>>
>>>>         num_acc_samps0 += num_rx_samps0;
>>>>
>>>>         // Handle data for stream #1.
>>>>         fwrite(buff1, sizeof(float) * 2, num_rx_samps1, fp1);
>>>>         if (verbose) {
>>>>             time_t full_secs;
>>>>             double frac_secs;
>>>>             uhd_rx_metadata_time_spec(md1, &full_secs, &frac_secs);
>>>>             fprintf(stderr, "Received packet: %zu samples, %.f full secs,
>>>> %f frac secs\n",
>>>>                     num_rx_samps1,
>>>>                     difftime(full_secs, (time_t) 0),
>>>>                     frac_secs);
>>>>         }
>>>>
>>>>         num_acc_samps1 += num_rx_samps1;
>>>>     }
>>>>     printf("Finished.\n");
>>>>
>>>>     // Cleanup
>>>>     close_file0:
>>>>         fclose(fp0);
>>>>
>>>>     close_file1:
>>>>         fclose(fp1);
>>>>
>>>>     free_buffer0:
>>>>         if(buff0){
>>>>             if(verbose){
>>>>                 fprintf(stderr, "Freeing buffer #0.\n");
>>>>             }
>>>>             free(buff0);
>>>>         }
>>>>         buff0 = NULL;
>>>>         buffs_ptr0 = NULL;
>>>>
>>>>     free_buffer1:
>>>>         if(buff1){
>>>>             if(verbose){
>>>>                 fprintf(stderr, "Freeing buffer #1.\n");
>>>>             }
>>>>             free(buff1);
>>>>         }
>>>>         buff1 = NULL;
>>>>         buffs_ptr1 = NULL;
>>>>
>>>>     free_rx_streamer0:
>>>>         if(verbose){
>>>>             fprintf(stderr, "Cleaning up RX streamer #0.\n");
>>>>         }
>>>>         uhd_rx_streamer_free(&rx_streamer0);
>>>>
>>>>     free_rx_streamer1:
>>>>         if(verbose){
>>>>             fprintf(stderr, "Cleaning up RX streamer #1.\n");
>>>>         }
>>>>         uhd_rx_streamer_free(&rx_streamer1);
>>>>
>>>>     free_rx_metadata:
>>>>         if(verbose){
>>>>             fprintf(stderr, "Cleaning up RX metadata.\n");
>>>>         }
>>>>         uhd_rx_metadata_free(&md0);
>>>>
>>>>     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_filename0){
>>>>             free(filename0);
>>>>         }
>>>>         if(custom_filename1){
>>>>             free(filename1);
>>>>         }
>>>>
>>>>     fprintf(stderr, (return_code ? "Failure\n" : "Success\n"));
>>>>     return return_code;
>>>> }
>>>>
>>>> On Sat, Jul 1, 2017 at 6:36 PM, Michael West <michael.west at ettus.com>
>>>> wrote:
>>>>>
>>>>> Hi Felipe,
>>>>>
>>>>> Both the multi_usrp API and the RFNoC API support it.  And yes, you need
>>>>> to create two different stream objects.
>>>>>
>>>>> Regards,
>>>>> Michael
>>>>>
>>>>> On Sat, Jul 1, 2017 at 2:45 AM, Felipe Augusto Pereira de Figueiredo
>>>>> <zz4fap at gmail.com> wrote:
>>>>>>
>>>>>> Dear Michael,
>>>>>>
>>>>>> Some more questions follows inline.
>>>>>>
>>>>>> Thanks and Kind Regards,
>>>>>>
>>>>>> Felipe Augusto
>>>>>>
>>>>>> On Sat, Jul 1, 2017 at 2:16 AM, Michael West <michael.west at ettus.com>
>>>>>> wrote:
>>>>>>>
>>>>>>> Hi Felipe,
>>>>>>>
>>>>>>> 1)  Yes, that is supported.
>>>>>>
>>>>>>
>>>>>> When you say that is supported, do you mean with legacy UHD API or with
>>>>>> RFNoC one? Even though I have a x310 I'm still using the legacy API.
>>>>>>>
>>>>>>>
>>>>>>> 2)  There is no example, but it is pretty easy.  Just set the
>>>>>>> uhd::stream_args_t::channels value correctly for each streamer object.
>>>>>>
>>>>>>
>>>>>> Do I need to create two different stream objects?
>>>>>>>
>>>>>>>
>>>>>>> Regards,
>>>>>>> Michael
>>>>>>>
>>>>>>> On Fri, Jun 30, 2017 at 12:00 PM, Felipe Augusto Pereira de Figueiredo
>>>>>>> <zz4fap at gmail.com> wrote:
>>>>>>>>
>>>>>>>> Dear Michael,
>>>>>>>>
>>>>>>>> Thanks for the reply.
>>>>>>>>
>>>>>>>> Given your answer, I've got two additional questions:
>>>>>>>>
>>>>>>>> 1) Does it mean I can create a RX stream to read RXed samples from the
>>>>>>>> RF chain 0 (I think you call DSP0) and another RX stream to read samples
>>>>>>>> from RF chain 1 (DSP1)? I'd like to have a SISO physical layer running
>>>>>>>> (TX/RX) on the RF chain 0 at frequency X and sample rate Y and a spectrum
>>>>>>>> sensing module with different sampling rate Z at frequency W on the RF chain
>>>>>>>> 1.
>>>>>>>>
>>>>>>>> 2) Is there any example on how to create different streamers to
>>>>>>>> receive/transmit using different RF Chains?
>>>>>>>>
>>>>>>>> Many Thanks and Kind Regards,
>>>>>>>>
>>>>>>>> Felipe Augusto
>>>>>>>>
>>>>>>>> On Fri, Jun 30, 2017 at 8:32 PM, Michael West <michael.west at ettus.com>
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> Hi Felipe,
>>>>>>>>>
>>>>>>>>> Yes.  If you create different streamers, each with a different set of
>>>>>>>>> channels, each streamer can be configured independently.
>>>>>>>>>
>>>>>>>>> Regards,
>>>>>>>>> Michael
>>>>>>>>>
>>>>>>>>> On Tue, Jun 27, 2017 at 7:28 AM, Felipe Augusto Pereira de Figueiredo
>>>>>>>>> via USRP-users <usrp-users at lists.ettus.com> wrote:
>>>>>>>>>>
>>>>>>>>>> Dear folks,
>>>>>>>>>>
>>>>>>>>>> I've got a x310 and I'd like to know if it is possible to open two
>>>>>>>>>> streams with different streaming modes at the same time in the same USRP
>>>>>>>>>> hardware.
>>>>>>>>>>
>>>>>>>>>> For example, the first RF chain would be configures as
>>>>>>>>>>
>>>>>>>>>> UHD_STREAM_MODE_START_CONTINUOUS
>>>>>>>>>>
>>>>>>>>>> and the second one would be set to
>>>>>>>>>>
>>>>>>>>>> UHD_STREAM_MODE_NUM_SAMPS_AND_DONE
>>>>>>>>>>
>>>>>>>>>> Is is possible?
>>>>>>>>>>
>>>>>>>>>> Thanks and Kind regards,
>>>>>>>>>>
>>>>>>>>>> Felipe Augusto
>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> USRP-users mailing list
>>>>>>>>>> USRP-users at lists.ettus.com
>>>>>>>>>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>




More information about the USRP-users mailing list