HelloEarlier I already wrote about big times for the example of
twinrx_freq_hopping
http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/2018-February/027782.htmlCan
anyone analyze the source code(rx_samples_c in the attachment) and say why it
turns out such a strange result (TestTwinRX) when called set_rx_lo_source.

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;
}
_______________________________________________
USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to