diff options
author | Tom Rondeau | 2011-10-19 16:40:14 -0700 |
---|---|---|
committer | Tom Rondeau | 2011-10-19 16:40:14 -0700 |
commit | eb95f431badf197b249131a3119a92bd5317621b (patch) | |
tree | 645854a7e1e6cf57fcae56f196a5d828b913555e /usrp2/host | |
parent | e30b824e9165bff69f09121631c3d5a706cbbd39 (diff) | |
download | gnuradio-eb95f431badf197b249131a3119a92bd5317621b.tar.gz gnuradio-eb95f431badf197b249131a3119a92bd5317621b.tar.bz2 gnuradio-eb95f431badf197b249131a3119a92bd5317621b.zip |
Removed usrp(2) directories.
Diffstat (limited to 'usrp2/host')
60 files changed, 0 insertions, 8312 deletions
diff --git a/usrp2/host/.gitignore b/usrp2/host/.gitignore deleted file mode 100644 index 605b6fe86..000000000 --- a/usrp2/host/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -/configure -/Makefile.in -/config.log -/config.status -/config.guess -/stamp-h1 -/config.h -/ltmain.sh -/config.sub -/config.h.in -/libtool -/autom4te.cache -/missing -/aclocal.m4 -/Makefile -/install-sh -/depcomp -/usrp2*.tar.gz -/py-compile -/usrp2.pc diff --git a/usrp2/host/Makefile.am b/usrp2/host/Makefile.am deleted file mode 100644 index 13f7cb86a..000000000 --- a/usrp2/host/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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, or (at your option) -# any later version. -# -# GNU Radio 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, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -include $(top_srcdir)/Makefile.common - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = usrp2.pc - -EXTRA_DIST += \ - usrp2.pc.in - -SUBDIRS = include lib apps diff --git a/usrp2/host/apps/.gitignore b/usrp2/host/apps/.gitignore deleted file mode 100644 index 4b66ac0f9..000000000 --- a/usrp2/host/apps/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -/Makefile -/Makefile.in -/.libs -/.deps -/test_eth -/test_usrp2 -/gen_const -/find_usrps -/cerr -/*.sh -/tx_samples -/rx_streaming_samples -/u2_burn_mac_addr -/usrp2_burn_mac_addr -/test_mimo_tx -/gpio diff --git a/usrp2/host/apps/Makefile.am b/usrp2/host/apps/Makefile.am deleted file mode 100644 index 087ab9e31..000000000 --- a/usrp2/host/apps/Makefile.am +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright 2007,2008,2010 Free Software Foundation, Inc. -# -# 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 $(top_srcdir)/Makefile.common - -AM_CPPFLAGS = \ - $(USRP2_INCLUDES) \ - $(GRUEL_INCLUDES) \ - $(STD_DEFINES_AND_INCLUDES) \ - $(CPPUNIT_INCLUDES) - -LDADD = \ - $(USRP2_LA) \ - $(GRUEL_LA) - -bin_PROGRAMS = \ - find_usrps \ - usrp2_burn_mac_addr - -noinst_PROGRAMS = \ - gen_const \ - rx_streaming_samples \ - tx_samples \ - test_mimo_tx \ - gpio - -find_usrps_SOURCES = find_usrps.cc -usrp2_burn_mac_addr_SOURCES = usrp2_burn_mac_addr.cc -rx_streaming_samples_SOURCES = rx_streaming_samples.cc -gen_const_SOURCES = gen_const.cc -tx_samples_SOURCES = tx_samples.cc -test_mimo_tx_SOURCES = test_mimo_tx.cc -gpio_SOURCES = gpio.cc diff --git a/usrp2/host/apps/bitrot/rx_samples.cc b/usrp2/host/apps/bitrot/rx_samples.cc deleted file mode 100644 index c1c3b5917..000000000 --- a/usrp2/host/apps/bitrot/rx_samples.cc +++ /dev/null @@ -1,382 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "usrp2_basic.h" -#include <iostream> -#include <complex> -#include <getopt.h> -#include <string.h> -#include "strtod_si.h" -#include <signal.h> -#include <stdexcept> -#include "gri_if_stats.h" -#include <gr_realtime.h> - - -typedef std::complex<float> fcomplex; - -static volatile bool signaled = false; - -static void -sig_handler(int sig) -{ - signaled = true; -} - -static void -install_sig_handler(int signum, - void (*new_handler)(int)) -{ - struct sigaction new_action; - memset (&new_action, 0, sizeof (new_action)); - - new_action.sa_handler = new_handler; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; - - if (sigaction (signum, &new_action, 0) < 0){ - perror ("sigaction (install new)"); - throw std::runtime_error ("sigaction"); - } -} - - -/* - * Vectorize me! - */ -void -convert_samples_to_complex(size_t nsamples, - uint32_t *i_samples, - fcomplex *c_samples) -{ - uint32_t *p = i_samples; - for (size_t i = 0; i < nsamples; i++){ - int16_t si = ((int16_t) (p[i] >> 16)); - int16_t sq = ((int16_t) (p[i] & 0xffff)); - c_samples[i] = fcomplex((float) si, (float) sq); - } -} - - -static void -usage(const char *progname) -{ - const char *p = strrchr(progname, '/'); // drop leading directory path - if (p) - p++; - - if (strncmp(p, "lt-", 3) == 0) // drop lt- libtool prefix - p += 3; - - fprintf(stderr, "Usage: %s [options]\n\n", p); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -h show this message and exit\n"); - fprintf(stderr, " -e ETH_INTERFACE specify ethernet interface [default=eth0]\n"); - fprintf(stderr, " -m MAC_ADDR mac address of USRP2 HH:HH [default=first one found]\n"); - fprintf(stderr, " -o OUTPUT_FILE set output filename [default=NONE]\n"); - fprintf(stderr, " -f FREQ set frequency to FREQ [default=0]\n"); - fprintf(stderr, " -d DECIM set decimation rate to DECIM [default=32]\n"); - fprintf(stderr, " -N NSAMPLES total number of samples to receive [default=2.5e6]\n"); - fprintf(stderr, " -F SAMPLES_PER_FRAME number of samples in each frame [default=371]\n"); - fprintf(stderr, " -S SCALE fpga scaling factor for I & Q [default=1024]\n"); - fprintf(stderr, " -M DONT_LOCK|LOCK_TO_SMA|LOCK_TO_MIMO specify MIMO clock source\n"); - fprintf(stderr, " -P provide clock to MIMO connector\n"); -} - -struct pkt_info { - int d_nsamples; - int d_timestamp; - unsigned int d_seqno; - - pkt_info(int nsamples, int timestamp, int seqno) - : d_nsamples(nsamples), - d_timestamp(timestamp), - d_seqno(seqno) {} -}; - -int -main(int argc, char **argv) -{ - - // options and their defaults - const char *interface = "eth0"; - const char *mac_addr_str = 0; - const char *output_filename = 0; - double freq = 0; - int32_t decim = 32; - int32_t nsamples = static_cast<int32_t>(2.5e6); - int32_t samples_per_frame = 371; - int32_t scale = 1024; - int mimo_config = MC_WE_DONT_LOCK; - bool provide_clock = false; - - int ch; - double tmp; - u2_mac_addr_t mac_addr; - - setvbuf(stdout, 0, _IOFBF, 64 * 1024); // make stdout fully buffered - - while ((ch = getopt(argc, argv, "he:m:o:f:d:N:F:S:M:P")) != EOF){ - switch (ch){ - - case 'e': - interface = optarg; - break; - - case 'm': - mac_addr_str = optarg; - if (!usrp2_basic::parse_mac_addr(optarg, &mac_addr)){ - std::cerr << "invalid mac addr: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - break; - - case 'o': - output_filename = optarg; - break; - - case 'f': - if (!strtod_si(optarg, &freq)){ - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - break; - - case 'N': - if (!strtod_si(optarg, &tmp)){ - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - nsamples = static_cast<int32_t>(tmp); - break; - - case 'F': - samples_per_frame = strtol(optarg, 0, 0); - break; - - case 'd': - decim = strtol(optarg, 0, 0); - break; - - case 'S': - if (!strtod_si(optarg, &tmp)){ - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - scale = static_cast<int32_t>(tmp); - break; - - case 'M': - if (strcmp(optarg, "DONT_LOCK") == 0) - mimo_config = MC_WE_DONT_LOCK; - else if (strcmp(optarg, "LOCK_TO_SMA") == 0) - mimo_config = MC_WE_LOCK_TO_SMA; - else if (strcmp(optarg, "LOCK_TO_MIMO") == 0) - mimo_config = MC_WE_LOCK_TO_MIMO; - else { - usage(argv[0]); - exit(1); - } - break; - - case 'P': - provide_clock = true; - break; - - case 'h': - default: - usage(argv[0]); - exit(1); - } - } - - if (argc - optind != 0){ - usage(argv[0]); - exit(1); - } - - FILE *of = 0; - if (output_filename) - of = fopen(output_filename, "wb"); - - usrp2_basic *u2 = new usrp2_basic(); - - if (!u2->open(interface)){ - std::cerr << "couldn't open " << interface << std::endl; - return 0; - } - - - install_sig_handler(SIGINT, sig_handler); - if (1){ - install_sig_handler(SIGALRM, sig_handler); - alarm(5); - } - - - std::vector<op_id_reply_t> r = u2->find_usrps(); - - for (size_t i = 0; i < r.size(); i++){ - std::cout << r[i] << std::endl; - } - - if (r.size() == 0){ - std::cerr << "No USRP2 found.\n"; - return 1; - } - - u2_mac_addr_t which = r[0].addr; // pick the first one - - - gr_rt_status_t rt = gr_enable_realtime_scheduling(); - if (rt != RT_OK) - std::cerr << "failed to enable realtime scheduling\n"; - - if (provide_clock) - mimo_config |= MC_PROVIDE_CLK_TO_MIMO; - - u2->config_mimo(which, mimo_confg); - - - gri_if_stats start, stop; - gri_get_if_stats(interface, &start); - - if (!u2->start_rx(which, freq, decim, nsamples, samples_per_frame, scale, scale)){ - std::cerr << "start_rx failed\n"; - return 1; - } - - - std::vector<pkt_info> history; - history.reserve(64*1024); // preallocate 64K entries - - - long total_samples_recvd = 0; - - while (!signaled && total_samples_recvd < nsamples){ - u2_eth_samples_t pkt; - // fcomplex c_samples[U2_MAX_SAMPLES]; - - // read samples - int n = u2->read_samples(which, &pkt); - if (n <= 0) - break; - - total_samples_recvd += n; - - history.push_back(pkt_info(n, u2p_timestamp(&pkt.hdrs.fixed), pkt.hdrs.thdr.seqno)); - - // convert_samples_to_complex(n, pkt.samples, c_samples); - // size_t r = fwrite(c_samples, sizeof(fcomplex), n, of); - - if (of){ - fwrite(pkt.samples, sizeof(uint32_t), n, of); - fflush(of); - } - } - - - gri_get_if_stats(interface, &stop); - - if (!u2->stop_rx(which)){ - std::cerr << "stop_rx failed\n"; - return 1; - } - - - long expected_rx_packets = - (nsamples + samples_per_frame - 1)/samples_per_frame; - - long expected_rx_bytes = - expected_rx_packets * sizeof(u2_eth_packet_t) + nsamples * 4; - - - long total_pkts_recvd = 0; - total_samples_recvd = 0; - - int nbad_seqno = 0; - - for (unsigned i = 0; i < history.size(); i++){ - total_pkts_recvd++; - total_samples_recvd += history[i].d_nsamples; - - bool bad_seqno = history[i].d_seqno != (i & 0xff); - if (bad_seqno) - nbad_seqno++; - - printf("%3d %8d %8ld %8ld %3d %s\n", - history[i].d_nsamples, - history[i].d_timestamp, - total_pkts_recvd, total_samples_recvd, - history[i].d_seqno, - bad_seqno ? "BAD SEQNO" : "" - ); - } - - if (nbad_seqno == 0) - printf("\nAll sequence numbers are correct\n"); - else - printf("\n%d sequence numbers were INCORRECT\n", nbad_seqno); - - - printf("\nUser space statistics:\n"); - printf(" rx_samples: %8ld", total_samples_recvd); - printf(" expected %8d %s\n", - nsamples, - nsamples - total_samples_recvd == 0 ? "OK" : "NOT OK"); - - printf(" rx_packets: %8ld", total_pkts_recvd); - printf(" expected %8ld %s\n", - expected_rx_packets, - expected_rx_packets - total_pkts_recvd == 0 ? "OK" : "NOT OK"); - - - fflush(stdout); - - printf("\nKernel interface statistics:\n"); - - long long delta; - delta = stop.rx_bytes - start.rx_bytes; - printf(" rx_bytes: %8Ld", delta); - printf(" expected %8ld %s\n", - expected_rx_bytes, - expected_rx_bytes - delta == 0 ? "OK" : "NOT OK"); - - delta = stop.rx_packets - start.rx_packets; - printf(" rx_packets: %8Ld", delta); - printf(" expected %8ld %s\n", - expected_rx_packets, - expected_rx_packets - delta == 0 ? "OK" : "NOT OK"); - - printf(" rx_errs: %8Ld\n", stop.rx_errs - start.rx_errs); - printf(" rx_drop: %8Ld\n", stop.rx_drop - start.rx_drop); - printf(" tx_bytes: %8Ld\n", stop.tx_bytes - start.tx_bytes); - printf(" tx_packets: %8Ld\n", stop.tx_packets - start.tx_packets); - printf(" tx_errs: %8Ld\n", stop.tx_errs - start.tx_errs); - printf(" tx_drop: %8Ld\n", stop.tx_drop - start.tx_drop); - - - return 0; -} diff --git a/usrp2/host/apps/find_usrps.cc b/usrp2/host/apps/find_usrps.cc deleted file mode 100644 index ff6b4ab79..000000000 --- a/usrp2/host/apps/find_usrps.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2/usrp2.h> -#include <iostream> -#include <cstdio> -#include <getopt.h> - -static void -usage(const char *progname) -{ - fprintf(stderr, "usage: %s [-e ethN]\n", - progname); -} - -int -main(int argc, char **argv) -{ - int ch; - const char *interface = "eth0"; - - while ((ch = getopt(argc, argv, "he:")) != EOF){ - switch (ch){ - case 'e': - interface = optarg; - break; - - case 'h': - default: - usage(argv[0]); - exit(1); - } - } - - if (argc - optind != 0){ - usage(argv[0]); - exit(1); - } - - usrp2::props_vector_t r = usrp2::find(interface); - - for (size_t i = 0; i < r.size(); i++){ - std::cout << r[i] << std::endl; - } - - if (r.size() == 0){ - std::cerr << "No USRP2 found.\n"; - return 1; - } - - return 0; -} diff --git a/usrp2/host/apps/gen_2tone.py b/usrp2/host/apps/gen_2tone.py deleted file mode 100755 index ec681d3e0..000000000 --- a/usrp2/host/apps/gen_2tone.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 Free Software Foundation, Inc. -# -# 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/>. -# - -from gnuradio import gr, eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import sys - -master_clock = 100e6 - -class my_top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self) - - parser = OptionParser(option_class=eng_option) - parser.add_option("-f", "--freq1", type="eng_float", default=1e6, - help="set waveform frequency to FREQ [default=%default]") - parser.add_option("-g", "--freq2", type="eng_float", default=1e6, - help="set waveform frequency to FREQ [default=%default]") - parser.add_option ("-a", "--amplitude1", type="eng_float", default=16e3, - help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL") - parser.add_option ("-b", "--amplitude2", type="eng_float", default=16e3, - help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL") - - parser.add_option("-i", "--interp", type="int", default=32, - help="assume fgpa interpolation rate is INTERP [default=%default]") - - (options, args) = parser.parse_args () - if len(args) != 0: - parser.print_help() - raise SystemExit, 1 - - - src0 = gr.sig_source_c(master_clock/options.interp, - gr.GR_SIN_WAVE, - options.freq1, - options.amplitude1) - src1 = gr.sig_source_c(master_clock/options.interp, - gr.GR_SIN_WAVE, - options.freq2, - options.amplitude2) - - adder = gr.add_cc() - - - c2s = gr.complex_to_interleaved_short() - - stdout_sink = gr.file_descriptor_sink(gr.sizeof_short, 1) - - self.connect(src0, (adder,0)) - self.connect(src1, (adder,1)) - self.connect(adder, c2s, stdout_sink) - - -if __name__ == '__main__': - try: - my_top_block().run() - except KeyboardInterrupt: - pass diff --git a/usrp2/host/apps/gen_const.cc b/usrp2/host/apps/gen_const.cc deleted file mode 100644 index d2c36ebba..000000000 --- a/usrp2/host/apps/gen_const.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> - -int -main(int argc, char **argv) -{ - if (argc != 3){ - fprintf(stderr, "usage: %s i-val q-val\n", argv[0]); - return 1; - } - - int i_val = strtol(argv[1], 0, 0); - int q_val = strtol(argv[2], 0, 0); - - static const int NSAMPLES = 16384; - - uint32_t sample[NSAMPLES]; - sample[0] = ((i_val & 0xffff) << 16) | (q_val & 0xffff); - for (int i = 1; i < NSAMPLES; i++) - sample[i] = sample[0]; - - while(1){ - write(1, sample, sizeof(sample)); - } -} diff --git a/usrp2/host/apps/gen_sine.py b/usrp2/host/apps/gen_sine.py deleted file mode 100755 index 6a44dd110..000000000 --- a/usrp2/host/apps/gen_sine.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 Free Software Foundation, Inc. -# -# 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/>. -# - -from gnuradio import gr, eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import sys - -master_clock = 100e6 - -class my_top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self) - - parser = OptionParser(option_class=eng_option) - parser.add_option("-f", "--freq", type="eng_float", default=1e6, - help="set waveform frequency to FREQ [default=%default]") - parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3, - help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL") - - parser.add_option("-i", "--interp", type="int", default=32, - help="assume fgpa interpolation rate is INTERP [default=%default]") - - (options, args) = parser.parse_args () - if len(args) != 0: - parser.print_help() - raise SystemExit, 1 - - - src0 = gr.sig_source_c(master_clock/options.interp, - gr.GR_SIN_WAVE, - options.freq, - options.amplitude) - - - c2s = gr.complex_to_interleaved_short() - - stdout_sink = gr.file_descriptor_sink(gr.sizeof_short, 1) - - self.connect(src0, c2s, stdout_sink) - - -if __name__ == '__main__': - try: - my_top_block().run() - except KeyboardInterrupt: - pass diff --git a/usrp2/host/apps/gpio.cc b/usrp2/host/apps/gpio.cc deleted file mode 100644 index 2fee7e761..000000000 --- a/usrp2/host/apps/gpio.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2/usrp2.h> -#include <iostream> -#include <cstdio> - -int -main(int argc, char **argv) -{ - usrp2::usrp2::sptr u2 = usrp2::usrp2::make("eth0"); - - // Set io_tx[15] as FPGA output - u2->set_gpio_ddr(usrp2::GPIO_TX_BANK, 0x8000, 0x8000); - - // Set io_tx[15] under host sofware control - u2->set_gpio_sels(usrp2::GPIO_TX_BANK, "s..............."); - - // Write pins - uint16_t v = 0x8765; - u2->write_gpio(usrp2::GPIO_TX_BANK, v, 0x8000); - - // Read back - v = 0; - u2->read_gpio(usrp2::GPIO_TX_BANK, &v); - printf("TX GPIO read: %04X\n", v); - return 0; -} diff --git a/usrp2/host/apps/rx_streaming_samples.cc b/usrp2/host/apps/rx_streaming_samples.cc deleted file mode 100644 index 8479ae1b2..000000000 --- a/usrp2/host/apps/rx_streaming_samples.cc +++ /dev/null @@ -1,373 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2/usrp2.h> -#include <usrp2/strtod_si.h> -#include <usrp2/copiers.h> -#include <usrp2/rx_nop_handler.h> -#include <gruel/realtime.h> -#include <sys/time.h> -#include <iostream> -#include <cstdio> -#include <string.h> -#include <boost/scoped_ptr.hpp> -#include <boost/shared_ptr.hpp> -#include <stdexcept> -#include <signal.h> - -static volatile bool signaled = false; - -static void -sig_handler(int sig) -{ - signaled = true; -} - -static void -install_sig_handler(int signum, - void (*new_handler)(int)) -{ - struct sigaction new_action; - memset (&new_action, 0, sizeof (new_action)); - - new_action.sa_handler = new_handler; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; - - if (sigaction (signum, &new_action, 0) < 0){ - perror ("sigaction (install new)"); - throw std::runtime_error ("sigaction"); - } -} - -// ------------------------------------------------------------------------ - -// FIXME make this a template - -class file_writer_16sc : public usrp2::rx_nop_handler -{ - FILE *d_fp; - std::string d_filename; - -public: - - file_writer_16sc(const std::string &filename, uint64_t max_samples) - : usrp2::rx_nop_handler(max_samples), d_filename(filename) - { - d_fp = fopen(filename.c_str(), "wb"); - if (d_fp == 0){ - perror(filename.c_str()); - throw std::invalid_argument(filename); - } - } - - ~file_writer_16sc(); - - bool - operator()(const uint32_t *items, size_t nitems, const usrp2::rx_metadata *metadata) - { - bool ok = rx_nop_handler::operator()(items, nitems, metadata); - - size_t host_nitems = nitems; - std::complex<int16_t> host_items[host_nitems]; - - usrp2::copy_u2_16sc_to_host_16sc(nitems, items, host_items); - - size_t n = 0; - while (n < host_nitems){ - size_t r = fwrite(&host_items[n], sizeof(host_items[0]), host_nitems - n, d_fp); - n += r; - if (r == 0){ // out of space? - d_err = true; - perror(d_filename.c_str()); - ok = false; - break; - } - } - - return ok; - } -}; - -file_writer_16sc::~file_writer_16sc() -{ - fclose(d_fp); -} - -// ------------------------------------------------------------------------ - -class file_writer_32fc : public usrp2::rx_nop_handler -{ - FILE *d_fp; - std::string d_filename; - -public: - - file_writer_32fc(const std::string &filename, uint64_t max_samples) - : usrp2::rx_nop_handler(max_samples), d_filename(filename) - { - d_fp = fopen(filename.c_str(), "wb"); - if (d_fp == 0){ - perror(filename.c_str()); - throw std::invalid_argument(filename); - } - } - - ~file_writer_32fc(); - - bool - operator()(const uint32_t *items, size_t nitems, const usrp2::rx_metadata *metadata) - { - bool ok = rx_nop_handler::operator()(items, nitems, metadata); - - size_t host_nitems = nitems; - std::complex<float> host_items[host_nitems]; - - usrp2::copy_u2_16sc_to_host_32fc(nitems, items, host_items); - - size_t n = 0; - while (n < host_nitems){ - size_t r = fwrite(&host_items[n], sizeof(host_items[0]), host_nitems - n, d_fp); - n += r; - if (r == 0){ // out of space? - d_err = true; - perror(d_filename.c_str()); - ok = false; - break; - } - } - - return ok; - } -}; - -file_writer_32fc::~file_writer_32fc() -{ - fclose(d_fp); -} - -// ------------------------------------------------------------------------ - -static void -usage(const char *progname) -{ - const char *p = strrchr(progname, '/'); // drop leading directory path - if (p) - p++; - - if (strncmp(p, "lt-", 3) == 0) // drop lt- libtool prefix - p += 3; - - fprintf(stderr, "Usage: %s [options]\n\n", p); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -h show this message and exit\n"); - fprintf(stderr, " -e ETH_INTERFACE specify ethernet interface [default=eth0]\n"); - fprintf(stderr, " -m MAC_ADDR mac address of USRP2 HH:HH [default=first one found]\n"); - fprintf(stderr, " -f FREQUENCY specify receive center frequency in Hz [default=0.0]\n"); - fprintf(stderr, " -d DECIM specify receive decimation rate [default=5]\n"); - fprintf(stderr, " -g GAIN specify receive daughterboard gain [default=0]\n"); - fprintf(stderr, " -N NSAMPLES specify number of samples to receive [default=infinite]\n"); - fprintf(stderr, " -o OUTPUT_FILENAME specify file to receive samples [default=none]\n"); - fprintf(stderr, " -s write complex<short> [default=complex<float>]\n"); - fprintf(stderr, " -v verbose output\n"); -} - -int -main(int argc, char **argv) -{ - // options and their defaults - const char *interface = "eth0"; - const char *mac_addr_str = ""; - double rx_freq = 0.0; - int rx_decim = 5; - double rx_gain = 0.0; - uint64_t nsamples = 0; - bool output_shorts = false; - char *output_filename = 0; - bool verbose = false; - - int ch; - - while ((ch = getopt(argc, argv, "he:m:f:d:g:N:o:sv")) != EOF){ - double tmp; - switch (ch){ - - case 'e': - interface = optarg; - break; - - case 'm': - mac_addr_str = optarg; - break; - - case 'f': - if (!strtod_si(optarg, &rx_freq)) { - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - break; - - case 'g': - if (!strtod_si(optarg, &rx_gain)) { - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - break; - - case 'd': - rx_decim = strtol(optarg, 0, 0); - if (rx_decim < 4 or rx_decim > 512) { - std::cerr << "invalid decimation rate: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - break; - - case 'N': - if (!strtod_si(optarg, &tmp)) { - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - exit(1); - } - nsamples = static_cast<uint64_t>(tmp); - break; - - case 's': - output_shorts = true; - break; - - case 'o': - output_filename = optarg; - break; - - case 'v': - verbose = true; - break; - - case 'h': - default: - usage(argv[0]); - exit(1); - } - } - - - install_sig_handler(SIGINT, sig_handler); - - usrp2::rx_nop_handler::sptr handler; - - if (output_filename){ - if (output_shorts) - handler = usrp2::rx_nop_handler::sptr(new file_writer_16sc(output_filename, nsamples)); - else - handler = usrp2::rx_nop_handler::sptr(new file_writer_32fc(output_filename, nsamples)); - } - else - handler = usrp2::rx_nop_handler::sptr(new usrp2::rx_nop_handler(nsamples)); - - gruel::rt_status_t rt = gruel::enable_realtime_scheduling(); - if (rt != gruel::RT_OK) - std::cerr << "Failed to enable realtime scheduling" << std::endl; - - usrp2::usrp2::sptr u2 = usrp2::usrp2::make(interface, mac_addr_str); - - // FIXME in case it was left running... - if (!u2->stop_rx_streaming()){ - fprintf(stderr, "stop_rx_streaming failed\n"); - } - - if (!u2->set_rx_gain(rx_gain)){ - fprintf(stderr, "set_rx_gain(%f) failed\n", rx_gain); - exit(1); - } - - usrp2::tune_result tr; - if (!u2->set_rx_center_freq(rx_freq, &tr)){ - fprintf(stderr, "set_rx_center_freq(%g) failed\n", rx_freq); - exit(1); - } - - if (verbose){ - printf("USRP2 MAC address: %s\n\n", u2->mac_addr().c_str()); - printf("Daughterboard configuration:\n"); - printf(" baseband_freq=%f\n", tr.baseband_freq); - printf(" ddc_freq=%f\n", tr.dxc_freq); - printf(" residual_freq=%f\n", tr.residual_freq); - printf(" inverted=%s\n\n", tr.spectrum_inverted ? "yes" : "no"); - } - - if (!u2->set_rx_decim(rx_decim)) { - fprintf(stderr, "set_rx_decim(%d) failed\n", rx_decim); - exit(1); - } - - if (verbose) - printf("USRP2 using decimation rate of %d\n", rx_decim); - - if (!u2->start_rx_streaming(0)){ - fprintf(stderr, "start_rx_streaming failed\n"); - exit(1); - } - - if (verbose) { - if (nsamples > 0) - printf("Receiving %zd samples\n\n", nsamples); - else - printf("Receiving infinite samples\n\n"); - } - - struct timeval start, end; - gettimeofday(&start, 0); - - while (!signaled && - !handler->has_errored_p() && - !handler->has_finished_p()) { - bool ok = u2->rx_samples(0, handler.get()); - if (!ok){ - fprintf(stderr, "u2->rx_samples failed\n"); - return 1; - } - } - - gettimeofday(&end, 0); - long n_usecs = end.tv_usec-start.tv_usec; - long n_secs = end.tv_sec-start.tv_sec; - double elapsed = (double)n_secs + (double)n_usecs*1e-6; - double mbs = handler->nsamples()*sizeof(uint32_t)/elapsed/1e6; - double pps = handler->nframes()/elapsed; - - u2->stop_rx_streaming(); - - if (verbose){ - printf("\nCopy handler called %li times.\n", handler->nframes()); - printf("Copy handler called with %li bytes.\n\n", handler->nsamples()*sizeof(uint32_t)); - printf("Elapsed time was %5.3f seconds.\n", elapsed); - printf("Packet rate was %1.0f pkts/sec.\n", pps); - printf("Approximate throughput was %5.2f MB/sec.\n", mbs); - printf("Total instances of overruns was %d.\n", u2->rx_overruns()); - printf("Total missing frames was %d.\n", u2->rx_missing()); - } - - return 0; -} diff --git a/usrp2/host/apps/stdin_int32_fft.py b/usrp2/host/apps/stdin_int32_fft.py deleted file mode 100755 index 1596fa00d..000000000 --- a/usrp2/host/apps/stdin_int32_fft.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2007,2008,2010 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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, or (at your option) -# any later version. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -from gnuradio import gr, gru -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider -from optparse import OptionParser -import wx -import sys -import numpy - - -class app_top_block(stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser(option_class=eng_option) - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-W", "--waterfall", action="store_true", default=False, - help="Enable waterfall display") - parser.add_option("-S", "--oscilloscope", action="store_true", default=False, - help="Enable oscilloscope display") - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - self.options = options - self.options.gain = 1.0 - self.show_debug_info = True - - - input_rate = 100e6 / options.decim - - self.src = gr.file_descriptor_source(gr.sizeof_short, 0, False); - self.s2c = gr.interleaved_short_to_complex() - - if options.waterfall: - self.scope = \ - waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate) - elif options.oscilloscope: - self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) - else: - self.scope = fftsink2.fft_sink_c (panel, fft_size=1024, y_divs=12, sample_rate=input_rate,ref_level=110,fft_rate=20) - - self.connect(self.src, self.s2c, self.scope) - - self._build_gui(vbox) - self._setup_events() - - # set initial values - - if options.freq is None: - # if no freq was specified, use the mid-point - options.freq = 0.0 - - if self.show_debug_info: - self.myform['decim'].set_value(self.options.decim) - - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - def _form_set_decim(kv): - return self.set_decim(kv['decim']) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - - if True: - self.myform['freq'].set_value(target_freq) # update displayed value - if not self.options.waterfall and not self.options.oscilloscope: - self.scope.set_baseband_freq(target_freq) - return True - - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - - def set_decim(self, decim): - input_rate = 100e6 / self.options.decim - self.scope.set_sample_rate(input_rate) - if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim_rate()) - return ok - - def _setup_events(self): - if not self.options.waterfall and not self.options.oscilloscope: - self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick) - - def evt_left_dclick(self, event): - (ux, uy) = self.scope.win.GetXY(event) - if event.CmdDown(): - # Re-center on maximum power - points = self.scope.win._points - if self.scope.win.peak_hold: - if self.scope.win.peak_vals is not None: - ind = numpy.argmax(self.scope.win.peak_vals) - else: - ind = int(points.shape()[0]/2) - else: - ind = numpy.argmax(points[:,1]) - (freq, pwr) = points[ind] - target_freq = freq/self.scope.win._scale_factor - print ind, freq, pwr - self.set_freq(target_freq) - else: - # Re-center on clicked frequency - target_freq = ux/self.scope.win._scale_factor - self.set_freq(target_freq) - - -def main (): - app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/usrp2/host/apps/streaming_fft.py b/usrp2/host/apps/streaming_fft.py deleted file mode 100755 index 4d341497a..000000000 --- a/usrp2/host/apps/streaming_fft.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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, or (at your option) -# any later version. -# -# GNU Radio 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, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -import os -import os.path -import sys -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -def main(): - parser = OptionParser(option_class=eng_option) - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=0.0, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="string", default=None, - help="set gain to GAIN [default=%default]") - parser.add_option("-W", "--waterfall", action="store_true", default=False, - help="Enable waterfall display") - parser.add_option("-S", "--oscilloscope", action="store_true", default=False, - help="Enable oscilloscope display") - parser.add_option("-F", "--samples-per-frame", type="int", default=250, - help="[default=%default]") - parser.add_option("-e", "--eth", default="eth0", - help="specify ethernet interface [default=%default]") - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - - path = os.path.dirname(sys.argv[0]) - if path == '': - path = '.' - - - display_type = '' - if options.waterfall: - display_type = '-W' - if options.oscilloscope: - display_type = '-S' - - gain_clause = '' - if options.gain: - gain_clause = '-g ' + options.gain - - # FIXME: restore -F - cmd = "%s/rx_streaming_samples -s -e %s -f %g -d %d %s -o /proc/self/fd/1 | %s/stdin_int32_fft.py %s -f %g -d %d" % ( - path, options.eth, options.freq, options.decim, gain_clause, - path, display_type, options.freq, options.decim) - - print cmd - os.system(cmd) - - -if __name__ == '__main__': - main() diff --git a/usrp2/host/apps/test.sh b/usrp2/host/apps/test.sh deleted file mode 100755 index c533c3339..000000000 --- a/usrp2/host/apps/test.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -sudo ./rx_streaming_samples -d 4 -v -N 100M - diff --git a/usrp2/host/apps/test_mimo_tx.cc b/usrp2/host/apps/test_mimo_tx.cc deleted file mode 100644 index f52bfd582..000000000 --- a/usrp2/host/apps/test_mimo_tx.cc +++ /dev/null @@ -1,311 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008,2009 Free Software Foundation, Inc. - * - * 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/>. - */ - -/* - * This is a down and dirty test program that confirms that the we can - * coherently transmit different signals to two USRP2s connected via a - * mimo cable. It ignores most of its command line arguments, and - * requires that special purpose firmware be installed in the two - * USRP2s. The one connected to the ethernet must be running - * mimo_tx.bin The other must be running mimo_tx_slave.bin. - * - * Don't use this as a model for how s/w should be written :-) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include <usrp2/usrp2.h> -#include <usrp2/strtod_si.h> -#include <iostream> -#include <cstdio> -#include <complex> -#include <getopt.h> -#include <gruel/realtime.h> -#include <signal.h> -#include <string.h> -#include <stdexcept> -#include <math.h> - - -typedef std::complex<float> fcomplex; - -static volatile bool signaled = false; - -void -gen_and_send(usrp2::usrp2::sptr u2, int chan, - double *ph, double ph_incr, int nsamples); - - -static void -sig_handler(int sig) -{ - signaled = true; -} - -static void -install_sig_handler(int signum, - void (*new_handler)(int)) -{ - struct sigaction new_action; - memset (&new_action, 0, sizeof (new_action)); - - new_action.sa_handler = new_handler; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; - - if (sigaction (signum, &new_action, 0) < 0){ - perror ("sigaction (install new)"); - throw std::runtime_error ("sigaction"); - } -} - - -static const char * -prettify_progname(const char *progname) // that's probably almost a word ;) -{ - const char *p = strrchr(progname, '/'); // drop leading directory path - if (p) - p++; - - if (strncmp(p, "lt-", 3) == 0) // drop lt- libtool prefix - p += 3; - - return p; -} - -static void -usage(const char *progname) -{ - fprintf(stderr, "Usage: %s [options]\n\n", prettify_progname(progname)); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -h show this message and exit\n"); - fprintf(stderr, " -e ETH_INTERFACE specify ethernet interface [default=eth0]\n"); - fprintf(stderr, " -m MAC_ADDR mac address of USRP2 HH:HH [default=first one found]\n"); - fprintf(stderr, " -I INPUT_FILE set input filename [default=stdin]\n"); - fprintf(stderr, " -r repeat. When EOF of input file is reached, seek to beginning\n"); - fprintf(stderr, " -f FREQ set frequency to FREQ [default=0]\n"); - fprintf(stderr, " -i INTERP set interpolation rate to INTERP [default=32]\n"); - fprintf(stderr, " -g gain set tx gain\n"); - fprintf(stderr, " -S SCALE fpga scaling factor for I & Q [default=256]\n"); -} - -#define GAIN_NOT_SET (-1000) -#define MAX_SAMPLES (371) - -int -main(int argc, char **argv) -{ - const char *interface = "eth0"; - const char *input_filename = 0; - bool repeat = false; - const char *mac_addr_str = ""; - double freq = 0; - int32_t interp = 32; - int32_t samples_per_frame = MAX_SAMPLES; - int32_t scale = -1; - double gain = GAIN_NOT_SET; - - int ch; - double tmp; - - - while ((ch = getopt(argc, argv, "he:m:I:rf:i:S:F:g:")) != EOF){ - switch (ch){ - - case 'e': - interface = optarg; - break; - - case 'm': - mac_addr_str = optarg; -#if 0 - if (!usrp2_basic::parse_mac_addr(optarg, &mac_addr)){ - std::cerr << "invalid mac addr: " << optarg << std::endl; - usage(argv[0]); - return 1; - } -#endif - break; - - case 'I': - input_filename = optarg; - break; - - case 'r': - repeat = true; - break; - - case 'f': - if (!strtod_si(optarg, &freq)){ - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - return 1; - } - break; - - case 'F': - samples_per_frame = strtol(optarg, 0, 0); - break; - - case 'i': - interp = strtol(optarg, 0, 0); - break; - - case 'S': - if (!strtod_si(optarg, &tmp)){ - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - return 1; - } - scale = static_cast<int32_t>(tmp); - break; - - case 'h': - default: - usage(argv[0]); - return 1; - } - } - - - if (argc - optind != 0){ - usage(argv[0]); - return 1; - } - - if (samples_per_frame < 9 || samples_per_frame > MAX_SAMPLES){ - std::cerr << prettify_progname(argv[0]) - << ": samples_per_frame is out of range. " - << "Must be in [9, " << MAX_SAMPLES << "].\n"; - usage(argv[0]); - return 1; - } - - - FILE *fp = 0; - if (input_filename == 0) - fp = stdin; - else { - fp = fopen(input_filename, "rb"); - if (fp == 0){ - perror(input_filename); - return 1; - } - } - - install_sig_handler(SIGINT, sig_handler); - - - gruel::rt_status_t rt = gruel::enable_realtime_scheduling(); - if (rt != gruel::RT_OK) - std::cerr << "Failed to enable realtime scheduling" << std::endl; - - - usrp2::usrp2::sptr u2 = usrp2::usrp2::make(interface, mac_addr_str); - -#if 0 - if (gain != GAIN_NOT_SET){ - if (!u2->set_tx_gain(gain)){ - std::cerr << "set_tx_gain failed\n"; - return 1; - } - } - - usrp2::tune_result tr; - if (!u2->set_tx_center_freq(freq, &tr)){ - fprintf(stderr, "set_tx_center_freq(%g) failed\n", freq); - return 1; - } - - printf("Daughterboard configuration:\n"); - printf(" baseband_freq=%f\n", tr.baseband_freq); - printf(" duc_freq=%f\n", tr.dxc_freq); - printf(" residual_freq=%f\n", tr.residual_freq); - printf(" inverted=%s\n\n", tr.spectrum_inverted ? "yes" : "no"); - - if (!u2->set_tx_interp(interp)){ - fprintf(stderr, "set_tx_interp(%d) failed\n", interp); - return 1; - } - - if (scale != -1){ - if (!u2->set_tx_scale_iq(scale, scale)){ - std::cerr << "set_tx_scale_iq failed\n"; - return 1; - } - } -#endif - - double baseband_rate = 100e6 / 32; - - double ph0 = 0; - double ph1 = 0; - - double ph0_incr = 7.5e3/baseband_rate * 2 * M_PI; - double ph1_incr = 7.5e3/baseband_rate * 2 * M_PI; - - while (!signaled){ - - gen_and_send(u2, 0, &ph0, ph0_incr, samples_per_frame); - gen_and_send(u2, 1, &ph1, ph1_incr, samples_per_frame); - - } - - return 0; -} - -void -gen_and_send(usrp2::usrp2::sptr u2, int chan, - double *ph_ptr, double ph_incr, int nsamples) -{ - double ph = *ph_ptr; - - std::complex<float> buf[MAX_SAMPLES]; - - usrp2::tx_metadata md; - md.timestamp = -1; - md.start_of_burst = 1; - md.send_now = 1; - - float ampl; - - if (chan == 0) - ampl = 0.5; - else - ampl = 0.75; - - - for (int i = 0; i < nsamples; i++){ -#if 0 - float s, c; - sincosf((float) ph, &s, &c); - buf[i] = std::complex<float>(s * ampl, c * ampl); - ph += ph_incr; -#else - buf[i] = std::complex<float>(ampl, 0); -#endif - } - - if (!u2->tx_32fc(chan, buf, nsamples, &md)){ - fprintf(stderr, "tx_32fc failed\n"); - } - - ph = fmod(ph, 2*M_PI); - *ph_ptr = ph; -} diff --git a/usrp2/host/apps/tx_samples.cc b/usrp2/host/apps/tx_samples.cc deleted file mode 100644 index 3e41bbf8d..000000000 --- a/usrp2/host/apps/tx_samples.cc +++ /dev/null @@ -1,269 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include <usrp2/usrp2.h> -#include <usrp2/strtod_si.h> -#include <iostream> -#include <cstdio> -#include <complex> -#include <getopt.h> -#include <gruel/realtime.h> -#include <signal.h> -#include <string.h> -#include <stdexcept> - - -typedef std::complex<float> fcomplex; - -static volatile bool signaled = false; - -static void -sig_handler(int sig) -{ - signaled = true; -} - -static void -install_sig_handler(int signum, - void (*new_handler)(int)) -{ - struct sigaction new_action; - memset (&new_action, 0, sizeof (new_action)); - - new_action.sa_handler = new_handler; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; - - if (sigaction (signum, &new_action, 0) < 0){ - perror ("sigaction (install new)"); - throw std::runtime_error ("sigaction"); - } -} - - -static const char * -prettify_progname(const char *progname) // that's probably almost a word ;) -{ - const char *p = strrchr(progname, '/'); // drop leading directory path - if (p) - p++; - - if (strncmp(p, "lt-", 3) == 0) // drop lt- libtool prefix - p += 3; - - return p; -} - -static void -usage(const char *progname) -{ - fprintf(stderr, "Usage: %s [options]\n\n", prettify_progname(progname)); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -h show this message and exit\n"); - fprintf(stderr, " -e ETH_INTERFACE specify ethernet interface [default=eth0]\n"); - fprintf(stderr, " -m MAC_ADDR mac address of USRP2 HH:HH [default=first one found]\n"); - fprintf(stderr, " -I INPUT_FILE set input filename [default=stdin]\n"); - fprintf(stderr, " -r repeat. When EOF of input file is reached, seek to beginning\n"); - fprintf(stderr, " -f FREQ set frequency to FREQ [default=0]\n"); - fprintf(stderr, " -i INTERP set interpolation rate to INTERP [default=32]\n"); - fprintf(stderr, " -g gain set tx gain\n"); - fprintf(stderr, " -S SCALE fpga scaling factor for I & Q [default=256]\n"); -} - -#define GAIN_NOT_SET (-1000) -#define MAX_SAMPLES (371) - -int -main(int argc, char **argv) -{ - const char *interface = "eth0"; - const char *input_filename = 0; - bool repeat = false; - const char *mac_addr_str = ""; - double freq = 0; - int32_t interp = 32; - int32_t samples_per_frame = MAX_SAMPLES; - int32_t scale = -1; - double gain = GAIN_NOT_SET; - - int ch; - double tmp; - - - while ((ch = getopt(argc, argv, "he:m:I:rf:i:S:F:g:")) != EOF){ - switch (ch){ - - case 'e': - interface = optarg; - break; - - case 'm': - mac_addr_str = optarg; -#if 0 - if (!usrp2_basic::parse_mac_addr(optarg, &mac_addr)){ - std::cerr << "invalid mac addr: " << optarg << std::endl; - usage(argv[0]); - return 1; - } -#endif - break; - - case 'I': - input_filename = optarg; - break; - - case 'r': - repeat = true; - break; - - case 'f': - if (!strtod_si(optarg, &freq)){ - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - return 1; - } - break; - - case 'F': - samples_per_frame = strtol(optarg, 0, 0); - break; - - case 'i': - interp = strtol(optarg, 0, 0); - break; - - case 'g': - gain = strtod(optarg, 0); - break; - - case 'S': - if (!strtod_si(optarg, &tmp)){ - std::cerr << "invalid number: " << optarg << std::endl; - usage(argv[0]); - return 1; - } - scale = static_cast<int32_t>(tmp); - break; - - case 'h': - default: - usage(argv[0]); - return 1; - } - } - - - if (argc - optind != 0){ - usage(argv[0]); - return 1; - } - - if (samples_per_frame < 9 || samples_per_frame > MAX_SAMPLES){ - std::cerr << prettify_progname(argv[0]) - << ": samples_per_frame is out of range. " - << "Must be in [9, " << MAX_SAMPLES << "].\n"; - usage(argv[0]); - return 1; - } - - - FILE *fp = 0; - if (input_filename == 0) - fp = stdin; - else { - fp = fopen(input_filename, "rb"); - if (fp == 0){ - perror(input_filename); - return 1; - } - } - - install_sig_handler(SIGINT, sig_handler); - - - gruel::rt_status_t rt = gruel::enable_realtime_scheduling(); - if (rt != gruel::RT_OK) - std::cerr << "Failed to enable realtime scheduling" << std::endl; - - - usrp2::usrp2::sptr u2 = usrp2::usrp2::make(interface, mac_addr_str); - - if (gain != GAIN_NOT_SET){ - if (!u2->set_tx_gain(gain)){ - std::cerr << "set_tx_gain failed\n"; - return 1; - } - } - - usrp2::tune_result tr; - if (!u2->set_tx_center_freq(freq, &tr)){ - fprintf(stderr, "set_tx_center_freq(%g) failed\n", freq); - return 1; - } - - printf("Daughterboard configuration:\n"); - printf(" baseband_freq=%f\n", tr.baseband_freq); - printf(" duc_freq=%f\n", tr.dxc_freq); - printf(" residual_freq=%f\n", tr.residual_freq); - printf(" inverted=%s\n\n", tr.spectrum_inverted ? "yes" : "no"); - - if (!u2->set_tx_interp(interp)){ - fprintf(stderr, "set_tx_interp(%d) failed\n", interp); - return 1; - } - - if (scale != -1){ - if (!u2->set_tx_scale_iq(scale, scale)){ - std::cerr << "set_tx_scale_iq failed\n"; - return 1; - } - } - - usrp2::tx_metadata md; - md.timestamp = -1; - md.start_of_burst = 1; - md.send_now = 1; - - while (!signaled){ - - std::complex<int16_t> samples[MAX_SAMPLES]; - - int r = fread(samples, sizeof(uint32_t), samples_per_frame, fp); - - // fprintf(stderr, "fread -> %d\n", r); - - if (r == 0){ - if (!repeat) - break; - if (fseek(fp, 0, SEEK_SET) == -1) - break; - } - - // FIXME if r < 9, pad to 9 for minimum packet size constraint - - if (!u2->tx_16sc(0, samples, r, &md)){ - fprintf(stderr, "tx_complex_int16 failed\n"); - break; - } - } - - return 0; -} diff --git a/usrp2/host/apps/usrp2_burn_mac_addr.cc b/usrp2/host/apps/usrp2_burn_mac_addr.cc deleted file mode 100644 index 6ee76c130..000000000 --- a/usrp2/host/apps/usrp2_burn_mac_addr.cc +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <usrp2/usrp2.h> -#include <iostream> -#include <getopt.h> -#include <string.h> -#include <time.h> -#include <stdio.h> -#include <signal.h> -#include <stdexcept> - - -static volatile bool signaled = false; - -static void -sig_handler(int sig) -{ - signaled = true; -} - -static void -install_sig_handler(int signum, - void (*new_handler)(int)) -{ - struct sigaction new_action; - memset (&new_action, 0, sizeof (new_action)); - - new_action.sa_handler = new_handler; - sigemptyset (&new_action.sa_mask); - new_action.sa_flags = 0; - - if (sigaction (signum, &new_action, 0) < 0){ - perror ("sigaction (install new)"); - throw std::runtime_error ("sigaction"); - } -} - - -static void -usage(const char *progname) -{ - fprintf(stderr, "usage: %s [-e ethN] [-m old_mac_addr] new_mac_addr\n", - progname); - fprintf(stderr, " old_mac_addr defaults to 00:50:c2:85:3f:ff\n"); - fprintf(stderr, " new_mac_address must be HH:HH or HH:HH:HH:HH:HH:HH\n"); -} - -static bool -check_mac_addr_syntax(const std::string &s) -{ - unsigned char addr[6]; - - addr[0] = 0x00; // Matt's IAB - addr[1] = 0x50; - addr[2] = 0xC2; - addr[3] = 0x85; - addr[4] = 0x30; - addr[5] = 0x00; - - int len = s.size(); - - switch (len){ - - case 5: - return sscanf(s.c_str(), "%hhx:%hhx", &addr[4], &addr[5]) == 2; - - case 17: - return sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &addr[0], &addr[1], &addr[2], - &addr[3], &addr[4], &addr[5]) == 6; - default: - return false; - } - - return true; -} - - -int -main(int argc, char **argv) -{ - int ch; - const char *interface = "eth0"; - const char *old_mac_addr = "00:50:c2:85:3f:ff"; - const char *new_mac_addr = 0; - - while ((ch = getopt(argc, argv, "he:m:")) != EOF){ - switch (ch){ - case 'e': - interface = optarg; - break; - - case 'm': - old_mac_addr = optarg; - break; - - case 'h': - default: - usage(argv[0]); - exit(1); - } - } - - if (argc - optind != 1){ - usage(argv[0]); - exit(1); - } - - new_mac_addr = argv[optind]; - - if (!check_mac_addr_syntax(old_mac_addr)){ - fprintf(stderr, "invalid mac address: %s\n", old_mac_addr); - exit(1); - } - if (!check_mac_addr_syntax(new_mac_addr)){ - fprintf(stderr, "invalid mac address: %s\n", new_mac_addr); - exit(1); - } - - install_sig_handler(SIGINT, sig_handler); - - usrp2::usrp2::sptr u2; - - try { - u2 = usrp2::usrp2::make(interface, old_mac_addr); - } - catch (std::exception const &e){ - std::cerr << e.what() << std::endl; - return 1; - } - - if (!u2->burn_mac_addr(new_mac_addr)){ - std::cerr << "Failed to burn mac address: " - << new_mac_addr << std::endl; - return 1; - } - - u2.reset(); // close - - // wait 250 ms - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 250000000; - nanosleep(&ts, 0); - - try { - u2 = usrp2::usrp2::make(interface, new_mac_addr); - } - catch (std::exception const &e){ - std::cerr << "Failed to connect to USRP2 using new addr: " - << new_mac_addr << std::endl; - std::cerr << e.what() << std::endl; - return 1; - } - - return 0; -} diff --git a/usrp2/host/include/.gitignore b/usrp2/host/include/.gitignore deleted file mode 100644 index b336cc7ce..000000000 --- a/usrp2/host/include/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Makefile -/Makefile.in diff --git a/usrp2/host/include/Makefile.am b/usrp2/host/include/Makefile.am deleted file mode 100644 index e2f7282b1..000000000 --- a/usrp2/host/include/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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, or (at your option) -# any later version. -# -# GNU Radio 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, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -include $(top_srcdir)/Makefile.common - -SUBDIRS = usrp2 diff --git a/usrp2/host/include/usrp2/.gitignore b/usrp2/host/include/usrp2/.gitignore deleted file mode 100644 index b336cc7ce..000000000 --- a/usrp2/host/include/usrp2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Makefile -/Makefile.in diff --git a/usrp2/host/include/usrp2/Makefile.am b/usrp2/host/include/usrp2/Makefile.am deleted file mode 100644 index 08fdcde33..000000000 --- a/usrp2/host/include/usrp2/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright 2008 Free Software Foundation, Inc. -# -# 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 $(top_srcdir)/Makefile.common - -INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) - -usrp2includedir = $(includedir)/usrp2 - -usrp2include_HEADERS = \ - copiers.h \ - copy_handler.h \ - data_handler.h \ - metadata.h \ - mimo_config.h \ - rx_nop_handler.h \ - rx_sample_handler.h \ - strtod_si.h \ - tune_result.h \ - usrp2.h \ - usrp2_cdefs.h diff --git a/usrp2/host/include/usrp2/copiers.h b/usrp2/host/include/usrp2/copiers.h deleted file mode 100644 index e98126f65..000000000 --- a/usrp2/host/include/usrp2/copiers.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_USRP2_COPIERS_H -#define INCLUDED_USRP2_COPIERS_H - -#include <complex> -#include <stdint.h> - -namespace usrp2 { - - // FIXME we may want to rework this, but this will get us on the air - - /* - * ---------------------------------------------------------------- - * Copy and convert from USRP2 wire format to host format - * ---------------------------------------------------------------- - */ - - void - copy_u2_16sc_to_host_16sc(size_t nitems, - const uint32_t *items, - std::complex<int16_t> *host_items); - - void - copy_u2_16sc_to_host_32fc(size_t nitems, - const uint32_t *items, - std::complex<float> *host_items); - - /* - * ---------------------------------------------------------------- - * Copy and convert from host format to USRP2 wire format - * ---------------------------------------------------------------- - */ - - void - copy_host_16sc_to_u2_16sc(size_t nitems, - const std::complex<int16_t> *host_items, - uint32_t *items); - - void - copy_host_32fc_to_u2_16sc(size_t nitems, - const std::complex<float> *host_items, - uint32_t *items); -} - - -#endif /* INCLUDED_USRP2_COPIERS_H */ diff --git a/usrp2/host/include/usrp2/copy_handler.h b/usrp2/host/include/usrp2/copy_handler.h deleted file mode 100644 index aef14cac8..000000000 --- a/usrp2/host/include/usrp2/copy_handler.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_COPY_HANDLER_H -#define INCLUDED_COPY_HANDLER_H - -#include <usrp2/data_handler.h> -#include <boost/utility.hpp> - -namespace usrp2 { - - class copy_handler : public data_handler, boost::noncopyable - { - uint8_t *d_dest; // next write pointer - size_t d_space; // space left in destination buffer - size_t d_bytes; // total bytes copied - size_t d_times; // number of times invoked - - public: - copy_handler(void *dest, size_t len); - ~copy_handler(); - - virtual data_handler::result operator()(const void *base, size_t len); - - size_t bytes() const { return d_bytes; } - size_t times() const { return d_times; } - - static const size_t MIN_COPY_LEN = 1484; // FIXME: calculate eth packet - thdr - bool full() const { return d_space < MIN_COPY_LEN; } - }; - -} // namespace usrp2 - -#endif /* INCLUDED_COPY_HANDLER_H */ diff --git a/usrp2/host/include/usrp2/data_handler.h b/usrp2/host/include/usrp2/data_handler.h deleted file mode 100644 index 7317b38af..000000000 --- a/usrp2/host/include/usrp2/data_handler.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_DATA_HANDLER_H -#define INCLUDED_DATA_HANDLER_H - -#include <stdint.h> -#include <stddef.h> - -namespace usrp2 { - - /*! - * \brief Abstract function object called to handle received data blocks. - */ - class data_handler - { - public: - - enum result_bits { - RELEASE = 0x0000, //< OK to release data (opposite of KEEP) - KEEP = 0x0001, //< do not discard data - DONE = 0x0002, //< do not call this object again - }; - - typedef int result; //< bitmask of result_bits - - /*! - * \param base points to the beginning of the data - * \param len is the length in bytes of the data - * \returns bitmask composed of DONE, KEEP - */ - virtual result operator()(const void *base, size_t len) = 0; - virtual ~data_handler(); - }; - -} // namespace usrp2 - -#endif /* INCLUDED_DATA_HANDLER_H */ diff --git a/usrp2/host/include/usrp2/metadata.h b/usrp2/host/include/usrp2/metadata.h deleted file mode 100644 index 8a95c3859..000000000 --- a/usrp2/host/include/usrp2/metadata.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ -#ifndef INCLUDED_USRP2_METADATA_H -#define INCLUDED_USRP2_METADATA_H - -#include <stdint.h> - -namespace usrp2 { - - //! type of the timestamp returned from the USRP2 FPGA - typedef uint32_t fpga_timestamp; - - /*! - * \brief metadata associated with received frames - * \ingroup usrp2 - */ - struct rx_metadata { - uint32_t word0; //< debugging, extensions - fpga_timestamp timestamp; //< time that first sample of frame was received - unsigned int start_of_burst : 1; //< this frame is the start of a burst - unsigned int end_of_burst : 1; //< this frame is the end of a burst - unsigned int rx_overrun : 1; //< An Rx overrun occurred in the FPGA - // rssi - // agc_mode - - rx_metadata() : - word0(0), timestamp(0), start_of_burst(0), end_of_burst(0), rx_overrun(0) {} - }; - - /*! - * \brief metadata associated with transmitted frames - * \ingroup usrp2 - */ - struct tx_metadata { - fpga_timestamp timestamp; //< time to transmit first sample of frame - unsigned int send_now : 1; //< ignore timestamp, send now - unsigned int start_of_burst : 1; //< this frame is the start of a burst - unsigned int end_of_burst : 1; //< this frame is the end of a burst - // ... - - tx_metadata() : - timestamp(0), send_now(0), start_of_burst(0), end_of_burst(0) {} - }; - -}; // usrp2 - -#endif /* INCLUDED_USRP2_METADATA_H */ diff --git a/usrp2/host/include/usrp2/mimo_config.h b/usrp2/host/include/usrp2/mimo_config.h deleted file mode 100644 index a1e038f74..000000000 --- a/usrp2/host/include/usrp2/mimo_config.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- c -*- */ -/* - * Copyright 2008,2009 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP2_MIMO_CONFIG_H -#define INCLUDED_USRP2_MIMO_CONFIG_H - -// FIXME: This duplicates the firmware usrp2_mimo_config.h file - -namespace usrp2 { - - static const int _MC_WE_LOCK = 0x0001; - static const int _MC_MIMO_CLK_INPUT = 0x0002; // else SMA input - - /* - * Derived masks (use these): - * - * We get our input from 1 of three places: - * Our free running oscilator, our SMA connector, or from the MIMO connector - */ - static const int MC_WE_DONT_LOCK = 0x0000; - static const int MC_WE_LOCK_TO_SMA = (_MC_WE_LOCK | 0); - static const int MC_WE_LOCK_TO_MIMO = (_MC_WE_LOCK | _MC_MIMO_CLK_INPUT); - - /* - * Independent of the source of the clock, we may or may not drive our - * clock onto the mimo connector. Note that there are dedicated clock - * signals in each direction, so disaster doesn't occurs if we're - * unnecessarily providing clock. - */ - static const int MC_PROVIDE_CLK_TO_MIMO = 0x0004; -} - -#endif /* INCLUDED_USRP2_MIMO_CONFIG_H */ diff --git a/usrp2/host/include/usrp2/rx_nop_handler.h b/usrp2/host/include/usrp2/rx_nop_handler.h deleted file mode 100644 index 68a254f31..000000000 --- a/usrp2/host/include/usrp2/rx_nop_handler.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_RX_NOP_HANDLER_H -#define INCLUDED_RX_NOP_HANDLER_H - -#include <usrp2/rx_sample_handler.h> -#include <boost/shared_ptr.hpp> - -/*! - * \ingroup usrp2 - * - * Base class for receive handlers that must copy into potentially limited - * range destination buffers. - * - * Maintains counters for number of items copied, times invoked, and test - * for whether maximum has been reached. - * - * Derived classes should override the () operator, but call this - * parent class method at some point at the start of their own operations. - */ - -namespace usrp2 { - - class rx_nop_handler : public rx_sample_handler - { - uint64_t d_max_samples; - uint64_t d_max_quantum; - uint64_t d_nsamples; - uint64_t d_nframes; - - protected: - bool d_err; - - public: - - // Shared pointer to an instance of this class - typedef boost::shared_ptr<rx_nop_handler> sptr; - - /*! - * Constructor - * - * \param max_samples Maximum number of samples to copy. Use zero for no maximum. - * \param max_quantum Maximum number of samples required to accept in one call. - * Use 0 to indicate no maximum. - */ - rx_nop_handler(uint64_t max_samples, uint64_t max_quantum=0) - : d_max_samples(max_samples), d_max_quantum(max_quantum), - d_nsamples(0), d_nframes(0), d_err(false) {} - - /*! - * Destructor. Derived classes must implement their own, non-inline destructor. - */ - virtual ~rx_nop_handler(); - - /*! - * \brief Returns number of frames this copier was called with - */ - uint64_t nframes() const { return d_nframes; } - - /*! - * \brief Returns actual number of samples copied - */ - uint64_t nsamples() const { return d_nsamples; } - - /*! - * \brief Returns maximum number of samples that will be copied - */ - uint64_t max_samples() const { return d_max_samples; } - - /*! - * Returns true if an error has occurred. Derived classes must set d_err to true - * when an error occurs in the () operator - */ - bool has_errored_p() const { return d_err; } - - /*! - * \brief Returns true if this instance has reached the maximum number of samples - */ - bool has_finished_p() const - { return d_max_samples == 0 ? false : d_nsamples >= d_max_samples-d_max_quantum; } - - - /*! - * Function operator invoked by USRP2 RX API. Derived classes must override this method - * but then invoke it at the start of their processing. This operator will always be - * called at least once. - * - * \param items points to the first 32-bit word of uninterpreted sample data in the frame. - * \param nitems is the number of entries in the frame in units of uint32_t's. - * \param metadata is the additional per frame data provided by the USRP2 FPGA. - * - * \p items points to the raw sample data received off of the ethernet. The data is - * packed into big-endian 32-bit unsigned ints for transport, but the actual format - * of the data is dependent on the current configuration of the USRP2. The most common - * format is 16-bit I & Q, with I in the top of the 32-bit word. - * - * \returns true if the object wants to be called again with new data; - * false if no additional data is wanted. - */ - virtual bool operator()(const uint32_t *items, size_t nitems, const rx_metadata *metadata) - { - // printf("W0: %08x TS: %08x\n", metadata->word0, metadata->timestamp); - // printf("I0: %08x\n", items[0]); - - d_nsamples += nitems; - d_nframes++; - - return !has_finished_p(); - } - }; - -} /* namespace usrp2 */ - -#endif /* INCLUDED_RX_NOP_HANDLER */ diff --git a/usrp2/host/include/usrp2/rx_sample_handler.h b/usrp2/host/include/usrp2/rx_sample_handler.h deleted file mode 100644 index a7fb7b641..000000000 --- a/usrp2/host/include/usrp2/rx_sample_handler.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ -#ifndef INCLUDED_USRP2_RX_SAMPLE_HANDLER_H -#define INCLUDED_USRP2_RX_SAMPLE_HANDLER_H - -#include <usrp2/metadata.h> -#include <stddef.h> - - -namespace usrp2 { - - /*! - * \brief Abstract function object called to handle received data blocks. - * \ingroup usrp2 - * - * An object derived from this class is passed to usrp2::rx_samples - * to process the received frames of samples. - */ - class rx_sample_handler { - public: - virtual ~rx_sample_handler(); - - /*! - * \param items points to the first 32-bit word of uninterpreted sample data in the frame. - * \param nitems is the number of entries in the frame in units of uint32_t's. - * \param metadata is the additional per frame data provided by the USRP2 FPGA. - * - * \p items points to the raw sample data received off of the ethernet. The data is - * packed into big-endian 32-bit unsigned ints for transport, but the actual format - * of the data is dependent on the current configuration of the USRP2. The most common - * format is 16-bit I & Q, with I in the top of the 32-bit word. - * - * This is the general purpose, low level interface and relies on other functions - * to handle all required endian-swapping and format conversion. \sa FIXME. - * - * \returns true if the object wants to be called again with new data; - * false if no additional data is wanted. - */ - virtual bool operator()(const uint32_t *items, size_t nitems, const rx_metadata *metadata) = 0; - }; - -}; - -#endif /* INCLUDED_RX_SAMPLE_HANDLER_H */ diff --git a/usrp2/host/include/usrp2/strtod_si.h b/usrp2/host/include/usrp2/strtod_si.h deleted file mode 100644 index 0a0f5a62c..000000000 --- a/usrp2/host/include/usrp2/strtod_si.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_STRTOD_SI_H -#define INCLUDED_STRTOD_SI_H - -#include "usrp2_cdefs.h" -__U2_BEGIN_DECLS - - -/*! - * \brief convert string at s to double honoring any trailing SI suffixes - * - * \param[in] s is the string to convert - * \param[out] result is the converted value - * \returns non-zero iff conversion was successful. - */ -int strtod_si(const char *s, double *result); - -__U2_END_DECLS - - -#endif /* INCLUDED_STRTOD_SI_H */ - diff --git a/usrp2/host/include/usrp2/tune_result.h b/usrp2/host/include/usrp2/tune_result.h deleted file mode 100644 index 9fe6539da..000000000 --- a/usrp2/host/include/usrp2/tune_result.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_USRP2_TUNE_RESULT_H -#define INCLUDED_USRP2_TUNE_RESULT_H - -namespace usrp2 { - - /* - * \ingroup usrp2 - */ - class tune_result - { - public: - // RF frequency that corresponds to DC in the IF - double baseband_freq; - - // frequency programmed into the DDC/DUC - double dxc_freq; - - // residual frequency (typically < 0.01 Hz) - double residual_freq; - - // is the spectrum inverted? - bool spectrum_inverted; - - tune_result(double baseband=0, double dxc=0, double residual=0, bool inverted=false) - : baseband_freq(baseband), dxc_freq(dxc), - residual_freq(residual), spectrum_inverted(inverted) {} - }; - -} // namespace usrp2 - -#endif /* INCLUDED_USRP2_TUNE_RESULT_H */ diff --git a/usrp2/host/include/usrp2/usrp2.h b/usrp2/host/include/usrp2/usrp2.h deleted file mode 100644 index e29caa33d..000000000 --- a/usrp2/host/include/usrp2/usrp2.h +++ /dev/null @@ -1,632 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2009 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_USRP2_H -#define INCLUDED_USRP2_H - -#include <boost/shared_ptr.hpp> -#include <boost/utility.hpp> -#include <boost/bind.hpp> -#include <vector> -#include <complex> -#include <usrp2/rx_sample_handler.h> -#include <usrp2/tune_result.h> -#include <usrp2/mimo_config.h> - -/* - * N.B., The interfaces described here are still in flux. - * - * We will keep all the code in the tree up-to-date with regard to changes - * here, but reserve the right to change this on a whim. - */ - -namespace usrp2 { - - /*! - * Structure to hold properties of USRP2 hardware devices. - * - */ - struct props - { - std::string addr; - uint16_t hw_rev; - uint8_t fpga_md5sum[16]; - uint8_t sw_md5sum[16]; - }; - - typedef std::vector<props> props_vector_t; - - /*! - * \brief Search the ethernet for all USRP2s or for a specific USRP2. - * - * \param ifc is the name of the OS ethernet interface (e.g., "eth0") - * \param mac_addr is the MAC address of the desired USRP2, or "" to search for all. - * mac_addr must be either a zero length string, "", or must be of the form - * "01:02:03:04:05:06" or "05:06". - * - * \returns a vector of properties, 1 entry for each matching USRP2 found. - */ - props_vector_t find(const std::string &ifc, const std::string &mac_addr=""); - - class tune_result; - - // FIXME: get from firmware include - static const int GPIO_TX_BANK = 0; - static const int GPIO_RX_BANK = 1; - - /*! - * \brief standard C++ interface to USRP2 - * \ingroup usrp2 - */ - class usrp2 : boost::noncopyable - { - public: - static const unsigned int MAX_CHAN = 30; - - /*! - * Shared pointer to this class - */ - typedef boost::shared_ptr<usrp2> sptr; - - /*! - * Static function to return an instance of usrp2 as a shared pointer - * - * \param ifc Network interface name, e.g., "eth0" - * \param addr Network mac address, e.g., "01:23:45:67:89:ab", "89:ab" or "". - * If \p addr is HH:HH, it's treated as if it were 00:50:c2:85:HH:HH - * "" will autoselect a USRP2 if there is only a single one on the local ethernet. - * \param rx_bufsize is the length in bytes of the kernel networking buffer to allocate. - */ - static sptr make(const std::string &ifc, const std::string &addr="", size_t rx_bufsize=0); - - /*! - * Class destructor - */ - ~usrp2(); - - /*! - * Returns the MAC address associated with this USRP - */ - std::string mac_addr(); - - /*! - * Returns the GbE interface name associated with this USRP - */ - std::string interface_name(); - - /* - * ---------------------------------------------------------------- - * Rx configuration and control - * ---------------------------------------------------------------- - */ - - /*! - * Set the rx antenna - */ - bool set_rx_antenna(int ant); - - /*! - * Set receiver gain - * \param gain in dB (more or less) - */ - bool set_rx_gain(double gain); - - //! return minimum Rx gain - double rx_gain_min(); - - //! return maximum Rx gain - double rx_gain_max(); - - //! return Rx gain db_per_step - double rx_gain_db_per_step(); - - /*! - * \brief Set receive daughterboard LO offset frequency - */ - bool set_rx_lo_offset(double frequency); - - /*! - * Set receiver center frequency - */ - bool set_rx_center_freq(double frequency, tune_result *result); - - //! return minimum Rx center frequency - double rx_freq_min(); - - //! return maximum Rx center frequency - double rx_freq_max(); - - /*! - * Set receiver sample rate decimation - */ - bool set_rx_decim(int decimation_factor); - - //! Return current decimation factor - int rx_decim(); - - /*! - * Set receiver IQ magnitude scaling - */ - bool set_rx_scale_iq(int scale_i, int scale_q); - - /*! - * Set received sample format - * - * domain: complex or real - * type: floating, fixed point, or raw - * depth: bits per sample - * - * Sets format over the wire for samples from USRP2. - */ - // bool set_rx_format(...); - - /*! - * Start streaming receive mode. USRP2 will send a continuous stream of - * DSP pipeline samples to host. Call rx_samples(...) to access. - * - * \param channel Stream channel number (0-30) - * \param items_per_frame Number of 32-bit items per frame. - */ - bool start_rx_streaming(unsigned int channel=0, unsigned int items_per_frame=0); - - /*! - * Start streaming receive mode at specified timestamp. USRP2 will send a - * continuous stream of DSP pipeline samples to host. Call rx_samples(...) - * to access. - * - * \param channel Stream channel number (0-30) - * \param items_per_frame Number of 32-bit items per frame. - * \param time Timestamp to start streaming at - */ - bool start_rx_streaming_at(unsigned int channel=0, unsigned int items_per_frame=0, unsigned int time=0); - - /*! - * Sync to PPS and start streaming receive mode at specified timestamp. - * Just like calling sync_to_pps() and start_rx_streaming_at(). - * - * \param channel Stream channel number (0-30) - * \param items_per_frame Number of 32-bit items per frame. - * \param time Timestamp to start streaming at - */ - bool sync_and_start_rx_streaming_at(unsigned int channel=0, unsigned int items_per_frame=0, uint32_t time=0); - - /*! - * Stop streaming receive mode. - */ - bool stop_rx_streaming(unsigned int channel=0); - - /*! - * \brief Receive data from the specified channel - * This method is used to receive all data: streaming or discrete. - */ - bool rx_samples(unsigned int channel, rx_sample_handler *handler); - - /*! - * Returns number of times receive overruns have occurred - */ - unsigned int rx_overruns(); - - /*! - * Returns total number of missing frames from overruns. - */ - unsigned int rx_missing(); - - /* - * ---------------------------------------------------------------- - * Tx configuration and control - * ---------------------------------------------------------------- - */ - - /*! - * Set the tx antenna - */ - bool set_tx_antenna(int ant); - - /*! - * Set transmitter gain - */ - bool set_tx_gain(double gain); - - //! return minimum Tx gain - double tx_gain_min(); - - //! return maximum Tx gain - double tx_gain_max(); - - //! return Tx gain db_per_step - double tx_gain_db_per_step(); - - /* - * \brief Set transmit daughterboard LO offset frequency - */ - bool set_tx_lo_offset(double frequency); - - /*! - * Set transmitter center frequency - */ - bool set_tx_center_freq(double frequency, tune_result *result); - - //! return minimum Tx center frequency - double tx_freq_min(); - - //! return maximum Tx center frequency - double tx_freq_max(); - - /*! - * Set transmitter sample rate interpolation - */ - bool set_tx_interp(int interpolation_factor); - - //! Return current interpolation factor - int tx_interp(); - - /* - * \brief Calculate default scale_iq for given interpolation rate - */ - void default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q); - - /*! - * Set transmit IQ magnitude scaling - */ - bool set_tx_scale_iq(int scale_i, int scale_q); - - /*! - * Set transmit sample format - * - * domain: complex or real - * type: floating, fixed point, or raw - * depth: bits per sample - * - * Sets format over the wire for samples to USRP2. - */ - // bool set_tx_format(...); - - /*! - * \brief transmit complex<float> samples to USRP2 - * - * \param channel specifies the channel to send them to - * \param samples are the samples to transmit. They should be in the range [-1.0, +1.0] - * \param nsamples is the number of samples to transmit - * \param metadata provides the timestamp and flags - * - * The complex<float> samples are converted to the appropriate - * "on the wire" representation, depending on the current USRP2 - * configuration. Typically, this is big-endian 16-bit I & Q. - */ - bool tx_32fc(unsigned int channel, - const std::complex<float> *samples, - size_t nsamples, - const tx_metadata *metadata); - - /*! - * \brief transmit complex<int16_t> samples to USRP2 - * - * \param channel specifies the channel to send them to - * \param samples are the samples to transmit - * \param nsamples is the number of samples to transmit - * \param metadata provides the timestamp and flags - * - * The complex<int16_t> samples are converted to the appropriate - * "on the wire" representation, depending on the current USRP2 - * configuration. Typically, this is big-endian 16-bit I & Q. - */ - bool tx_16sc(unsigned int channel, - const std::complex<int16_t> *samples, - size_t nsamples, - const tx_metadata *metadata); - - /*! - * \brief transmit raw uint32_t data items to USRP2 - * - * The caller is responsible for ensuring that the items are - * formatted appropriately for the USRP2 and its configuration. - * This method is used primarily by the system itself. Users - * should call tx_32fc or tx_16sc instead. - * - * \param channel specifies the channel to send them to - * \param items are the data items to transmit - * \param nitems is the number of items to transmit - * \param metadata provides the timestamp and flags - */ - bool tx_raw(unsigned int channel, - const uint32_t *items, - size_t nitems, - const tx_metadata *metadata); - - /* - * ---------------------------------------------------------------- - * miscellaneous methods - * ---------------------------------------------------------------- - */ - - /*! - * \brief MIMO configuration - * - * \param flags from usrp2_mimo_config.h - * - * <pre> - * one of these: - * - * MC_WE_DONT_LOCK - * MC_WE_LOCK_TO_SMA - * MC_WE_LOCK_TO_MIMO - * - * and optionally this: - * - * MC_PROVIDE_CLK_TO_MIMO - * </pre> - */ - bool config_mimo(int flags); - - - //! Get frequency of master oscillator in Hz - bool fpga_master_clock_freq(long *freq); - - // Get Sampling rate of A/D converter in Hz - bool adc_rate(long *rate); - - // Get Sampling rate of D/A converter in Hz - bool dac_rate(long *rate); - - /*! - * \brief Get Tx daughterboard ID - * - * \param[out] dbid returns the daughterboard id. - * - * daughterboard id >= 0 if successful, -1 if no daugherboard installed, - * -2 if invalid EEPROM on daughterboard. - */ - bool tx_daughterboard_id(int *dbid); - - /*! - * \brief Get Rx daughterboard ID - * - * \param[out] dbid returns the daughterboard id. - * - * daughterboard id >= 0 if successful, -1 if no daugherboard installed, - * -2 if invalid EEPROM on daughterboard. - */ - bool rx_daughterboard_id(int *dbid); - - /* - * ---------------------------------------------------------------- - * Low level methods - * ---------------------------------------------------------------- - */ - - /*! - * Burn new mac address into EEPROM on USRP2 - * - * \param new_addr Network mac address, e.g., "01:23:45:67:89:ab" or "89:ab". - * If \p addr is HH:HH, it's treated as if it were 00:50:c2:85:HH:HH - */ - bool burn_mac_addr(const std::string &new_addr); - - /*! - * Reset master time to 0 at next PPS edge - */ - bool sync_to_pps(); - - /*! - * Reset master time to 0 at every PPS edge - */ - bool sync_every_pps(bool enable); - - /*! - * Read memory from Wishbone bus as 32-bit words. Handles endian swapping if needed. - * - * \param addr 32-bit aligned address. Only the lower 16-bits are significant. - * \param words Number of 32-bit words - * - * \returns Vector of 32-bit read values - * - * WARNING: Attempts to read memory from addresses that do not correspond to RAM or - * memory-mapped peripherals may cause the USRP2 to hang, requiring a power cycle. - * - */ - std::vector<uint32_t> peek32(uint32_t addr, uint32_t words); - - /*! - * Write memory to Wishbone bus as 32-bit words. Handles endian swapping if needed. - * - * \param addr 32-bit aligned address. Only the lower 16-bits are significant - * \param data Vector of 32-bit values to write. - * - * \returns true iff successful - * - * WARNING: Attempts to read memory from addresses that do not correspond to RAM or - * memory-mapped peripherals may cause the USRP2 to hang, requiring a power cycle. - * - */ - bool poke32(uint32_t addr, const std::vector<uint32_t> &data); - - /*! - * Set daughterboard GPIO data direction register. - * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \param value 16-bits, 0=FPGA input, 1=FPGA output - * \param mask 16-bits, 0=ignore, 1=set - * - * \returns true iff successful - * - * WARNING: Improper usage of this function may result in damage to the USRP2 - * - */ - bool set_gpio_ddr(int bank, uint16_t value, uint16_t mask); - - /*! - * Set daughterboard GPIO output selection register. For those GPIO pins that - * are configured as outputs in the DDR, this settings configures the source - * of the pin value. - * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \param sels Exactly 16 character MSB->LSB string. For each position: - * '.' = ignore this bit, i.e., leave current value - * 'a' = Output ATR value - * 's' = Output host software controlled value - * '0' = Output FPGA debug bus 0 value - * '1' = Output FPGA debug bus 1 value - * - * \returns true iff successful - * - * WARNING: Improper usage of this function may result in damage to the USRP2 - * - */ - bool set_gpio_sels(int bank, std::string sels); - - /*! - * Set daughterboard GPIO pin values. - * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \param value 16 bits, 0=low, 1=high - * \param mask 16 bits, 0=ignore, 1=set - * - * \returns true iff successful - * - * WARNING: Improper usage of this function may result in damage to the USRP2 - * - */ - bool write_gpio(int bank, uint16_t value, uint16_t mask); - - /*! - * Read daughterboard GPIO pin values - * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \param value pointer to uint16_t to hold read results - * - * \returns true iff successful - * - */ - bool read_gpio(int bank, uint16_t *value); - - /*! - * Set GPIO streaming mode - * - * Individually enables streaming GPIO pins through LSBs of DSP - * samples. - * - * On receive, io_rx[15] replaces I[0], io_rx[14] replaces Q[0] - * On transmit, I[0] maps to io_tx[15], Q[0] maps to io_tx[14] - * (Transmit streaming is not yet implemented.) - * - * The selected GPIO pins must have been set as inputs or outputs - * and, for transmit, set to software control. - * - * When enabled, the replaced DSP sample LSBs become 0. - * - * \param bank GPIO_TX_BANK or GPIO_RX_BANK - * \param enable enable[0] controls I channel LSB - * enable[1] controls Q channel LSB - * - * \returns true iff successful - * - * WARNING: Improper usage of this function may result in damage to the USRP2 - * - */ - bool enable_gpio_streaming(int bank, int enable); - -#if 0 // not yet implemented - /*! - * \brief Write EEPROM on motherboard or any daughterboard. - * \param i2c_addr I2C bus address of EEPROM - * \param eeprom_offset byte offset in EEPROM to begin writing - * \param buf the data to write - * \returns true iff sucessful - */ - bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string &buf); - - /*! - * \brief Read EEPROM on motherboard or any daughterboard. - * \param i2c_addr I2C bus address of EEPROM - * \param eeprom_offset byte offset in EEPROM to begin reading - * \param len number of bytes to read - * \returns the data read if successful, else a zero length string. - */ - std::string read_eeprom (int i2c_addr, int eeprom_offset, int len); - - /*! - * \brief Write to I2C peripheral - * \param i2c_addr I2C bus address (7-bits) - * \param buf the data to write - * \returns true iff successful - * Writes are limited to a maximum of of 64 bytes. - */ - bool write_i2c (int i2c_addr, const std::string &buf); - - /*! - * \brief Read from I2C peripheral - * \param i2c_addr I2C bus address (7-bits) - * \param len number of bytes to read - * \returns the data read if successful, else a zero length string. - * Reads are limited to a maximum of 64 bytes. - */ - std::string read_i2c (int i2c_addr, int len); - - /*! - * \brief Write data to SPI bus peripheral. - * - * \param optional_header 0,1 or 2 bytes to write before buf. - * \param enables bitmask of peripherals to write. See usrp_spi_defs.h - * \param format transaction format. See usrp_spi_defs.h SPI_FMT_* - * \param buf the data to write - * \returns true iff successful - * Writes are limited to a maximum of 64 bytes. - * - * If \p format specifies that optional_header bytes are present, they are - * written to the peripheral immediately prior to writing \p buf. - */ - bool write_spi (int optional_header, int enables, int format, const std::string &buf); - - /* - * \brief Read data from SPI bus peripheral. - * - * \param optional_header 0,1 or 2 bytes to write before buf. - * \param enables bitmask of peripheral to read. See usrp_spi_defs.h - * \param format transaction format. See usrp_spi_defs.h SPI_FMT_* - * \param len number of bytes to read. Must be in [0,64]. - * \returns the data read if sucessful, else a zero length string. - * - * Reads are limited to a maximum of 64 bytes. - * - * If \p format specifies that optional_header bytes are present, they - * are written to the peripheral first. Then \p len bytes are read from - * the peripheral and returned. - */ - std::string read_spi (int optional_header, int enables, int format, int len); -#endif - - - class impl; // implementation details - - private: - // Static function to retrieve or create usrp2 instance - static sptr find_existing_or_make_new(const std::string &ifc, props *p, size_t rx_bufsize); - - // Only class members can instantiate this class - usrp2(const std::string &ifc, props *p, size_t rx_bufsize); - - // All private state is held in opaque pointer - std::auto_ptr<impl> d_impl; - }; - -}; - -std::ostream& operator<<(std::ostream &os, const usrp2::props &x); - - -#endif /* INCLUDED_USRP2_H */ diff --git a/usrp2/host/include/usrp2/usrp2_cdefs.h b/usrp2/host/include/usrp2/usrp2_cdefs.h deleted file mode 100644 index 71395cda8..000000000 --- a/usrp2/host/include/usrp2/usrp2_cdefs.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef INCLUDED_USRP2_CDEFS_H -#define INCLUDED_USRP2_CDEFS_H - -/* C++ needs to know that types and declarations are C, not C++. */ -#ifdef __cplusplus -# define __U2_BEGIN_DECLS extern "C" { -# define __U2_END_DECLS } -#else -# define __U2_BEGIN_DECLS -# define __U2_END_DECLS -#endif - -#endif /* INCLUDED_USRP2_CDEFS_H */ diff --git a/usrp2/host/lib/.gitignore b/usrp2/host/lib/.gitignore deleted file mode 100644 index 8f5500b33..000000000 --- a/usrp2/host/lib/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/.libs -/.deps -/Makefile -/Makefile.in -/usrp2_socket_opener diff --git a/usrp2/host/lib/Makefile.am b/usrp2/host/lib/Makefile.am deleted file mode 100644 index 85bec4673..000000000 --- a/usrp2/host/lib/Makefile.am +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright 2007,2008,2010 Free Software Foundation, Inc. -# -# 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 $(top_srcdir)/Makefile.common - -AM_CPPFLAGS = \ - $(USRP2_INCLUDES) \ - $(GRUEL_INCLUDES) \ - $(STD_DEFINES_AND_INCLUDES) \ - $(BOOST_CPPFLAGS) \ - $(CPPUNIT_INCLUDES) - -bin_PROGRAMS = usrp2_socket_opener -usrp2_socket_opener_SOURCES = usrp2_socket_opener.cc - -lib_LTLIBRARIES = \ - libusrp2.la - -libusrp2_la_LDFLAGS = $(LTVERSIONFLAGS) - -libusrp2_la_SOURCES = \ - control.cc \ - copiers.cc \ - copy_handler.cc \ - data_handler.cc \ - eth_buffer.cc \ - ethernet.cc \ - find.cc \ - open_usrp2_socket.cc \ - pktfilter.cc \ - ring.cc \ - rx_nop_handler.cc \ - rx_sample_handler.cc \ - strtod_si.c \ - usrp2.cc \ - usrp2_impl.cc - -libusrp2_la_LIBADD = \ - $(GRUEL_LA) \ - $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) - -# Private headers not needed for above the API development -noinst_HEADERS = \ - control.h \ - eth_buffer.h \ - eth_common.h \ - ethernet.h \ - open_usrp2_socket.h \ - pktfilter.h \ - ring.h \ - usrp2_bytesex.h \ - usrp2_impl.h
\ No newline at end of file diff --git a/usrp2/host/lib/control.cc b/usrp2/host/lib/control.cc deleted file mode 100644 index 3b5533eb8..000000000 --- a/usrp2/host/lib/control.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2009,2010 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "control.h" -#include <iostream> -#include <gruel/thread.h> - -#include <boost/date_time/posix_time/posix_time.hpp> -namespace pt = boost::posix_time; - -namespace usrp2 { - - pending_reply::pending_reply(unsigned int rid, void *buffer, size_t len) - : d_rid(rid), d_buffer(buffer), d_len(len), d_mutex(), d_cond(), - d_complete(false) - { - } - - pending_reply::~pending_reply() - { - notify_completion(); // Needed? - } - - int - pending_reply::wait_for_completion(double secs) - { - gruel::scoped_lock l(d_mutex); - - while (!d_complete) { - if (!d_cond.timed_wait(l, pt::milliseconds(long(secs*1e3)))) - return 0; // timed out - } - - return 1; - } - - void - pending_reply::notify_completion() - { - gruel::scoped_lock l(d_mutex); - d_complete = true; - d_cond.notify_one(); - } - -} // namespace usrp2 - diff --git a/usrp2/host/lib/control.h b/usrp2/host/lib/control.h deleted file mode 100644 index 3515ba10f..000000000 --- a/usrp2/host/lib/control.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2009,2010 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_CONTROL_H -#define INCLUDED_CONTROL_H - -#include <gruel/thread.h> -#include <usrp2_eth_packet.h> - -namespace usrp2 { - - struct op_generic_cmd { - u2_eth_packet_t h; - op_generic_t op; - op_generic_t eop; - }; - - /*! - * OP_CONFIG_RX_V2 command packet - */ - struct op_config_rx_v2_cmd - { - u2_eth_packet_t h; - op_config_rx_v2_t op; - op_generic_t eop; - }; - - struct op_start_rx_streaming_cmd - { - u2_eth_packet_t h; - op_start_rx_streaming_t op; - op_generic_t eop; - }; - - struct op_sync_and_start_rx_streaming_cmd - { - u2_eth_packet_t h; - op_generic_t sync_op; - op_start_rx_streaming_t rx_op; - op_generic_t eop; - }; - - struct op_stop_rx_cmd { - u2_eth_packet_t h; - op_generic_t op; - op_generic_t eop; - }; - - struct op_config_tx_v2_cmd - { - u2_eth_packet_t h; - op_config_tx_v2_t op; - op_generic_t eop; - }; - - struct op_config_mimo_cmd - { - u2_eth_packet_t h; - op_config_mimo_t op; - op_generic_t eop; - }; - - struct op_burn_mac_addr_cmd - { - u2_eth_packet_t h; - op_burn_mac_addr_t op; - op_generic_t eop; - }; - - struct op_dboard_info_cmd { - u2_eth_packet_t h; - op_generic_t op; - op_generic_t eop; - }; - - struct op_peek_cmd { - u2_eth_packet_t h; - op_peek_t op; - op_generic_t eop; - }; - - struct op_poke_cmd { - u2_eth_packet_t h; - op_poke_t op; - // words to write go here - // eop must be dynamically written here - }; - - struct op_freq_cmd { - u2_eth_packet_t h; - op_freq_t op; - op_generic_t eop; - }; - - struct op_gpio_cmd { - u2_eth_packet_t h; - op_gpio_t op; - op_generic_t eop; - }; - - struct op_gpio_set_sels_cmd { - u2_eth_packet_t h; - op_gpio_set_sels_t op; - op_generic_t eop; - }; - - /*! - * Control mechanism to allow API calls to block waiting for reply packets - */ - class pending_reply - { - private: - unsigned int d_rid; - void *d_buffer; - size_t d_len; - - // d_mutex is used with d_cond and also protects d_complete - gruel::mutex d_mutex; - gruel::condition_variable d_cond; - bool d_complete; - - public: - /*! - * Construct a pending reply from the reply ID, response packet - * buffer, and buffer length. - */ - pending_reply(unsigned int rid, void *buffer, size_t len); - - /*! - * Destructor. Signals creating thread. - */ - ~pending_reply(); - - /*! - * Block, waiting for reply packet. - * Returns: 1 = ok, reply packet in buffer - * 0 = timeout - */ - int wait_for_completion(double secs); - - /*! - * Allows creating thread to resume after copying reply into buffer - */ - void notify_completion(); - - /*! - * Retrieve pending reply ID - */ - unsigned int rid() const { return d_rid; } - - /*! - * Retrieve destination buffer address - */ - void *buffer() const { return d_buffer; } - - /*! - * Retrieve destination buffer length - */ - size_t len() const { return d_len; } - }; - -} // namespace usrp2 - -#endif /* INCLUDED_CONTROL_H */ diff --git a/usrp2/host/lib/copiers.cc b/usrp2/host/lib/copiers.cc deleted file mode 100644 index 52c66f616..000000000 --- a/usrp2/host/lib/copiers.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <usrp2/copiers.h> -#include <gruel/inet.h> -#include <gr_math.h> -#include <math.h> -#include <stdexcept> -#include <assert.h> -#include <string.h> - -// FIXME need gruel::not_implemented - -namespace usrp2 { - - /* - * N.B., in all of these, uint32_t *items is NOT 32-bit aligned! - * FIXME Needs fix for non-x86 machines. - */ - - /* - * ---------------------------------------------------------------- - * Copy and convert from USRP2 wire format to host format - * ---------------------------------------------------------------- - */ - void - copy_u2_16sc_to_host_16sc(size_t nitems, - const uint32_t *items, - std::complex<int16_t> *host_items) - { -#ifdef WORDS_BIGENDIAN - - assert(sizeof(items[0]) == sizeof(host_items[0])); - memcpy(host_items, items, nitems * sizeof(items[0])); - -#else - - // FIXME SIMD welcome here - - for (size_t i = 0; i < nitems; i++){ - uint32_t t = ntohx(items[i]); - //printf("%9d\n", items[i]); - host_items[i] = std::complex<int16_t>((t >> 16), t & 0xffff); - } - -#endif - } - - - /* - * endian swap if required and map [-32768, 32767] -> [1.0, +1.0) - */ - void - copy_u2_16sc_to_host_32fc(size_t nitems, - const uint32_t *items, - std::complex<float> *host_items) - { - for (size_t i = 0; i < nitems; i++){ - uint32_t t = ntohx(items[i]); - int16_t re = (t >> 16) & 0xffff; - int16_t im = (t & 0xffff); - host_items[i] = std::complex<float>(re * 1.0/32768, im * 1.0/32768); - } - } - - /* - * ---------------------------------------------------------------- - * Copy and convert from host format to USRP2 wire format - * ---------------------------------------------------------------- - */ - void - copy_host_16sc_to_u2_16sc(size_t nitems, - const std::complex<int16_t> *host_items, - uint32_t *items) - { -#ifdef WORDS_BIGENDIAN - - assert(sizeof(items[0]) == sizeof(host_items[0])); - memcpy(items, host_items, nitems * sizeof(items[0])); - -#else - - // FIXME SIMD welcome here - - for (size_t i = 0; i < nitems; i++){ - items[i] = htonl((host_items[i].real() << 16) | (host_items[i].imag() & 0xffff)); - } - -#endif - } - - - static inline int16_t - clip_and_scale(float x) - { - return static_cast<int16_t>(rintf(gr_branchless_clip(x, 1.0) * 32767.0)); - } - - void - copy_host_32fc_to_u2_16sc(size_t nitems, - const std::complex<float> *host_items, - uint32_t *items) - { - for (size_t i = 0; i < nitems; i++){ - int16_t re = clip_and_scale(host_items[i].real()); - int16_t im = clip_and_scale(host_items[i].imag()); - - items[i] = htonl((re << 16) | (im & 0xffff)); - } - } - -} diff --git a/usrp2/host/lib/copy_handler.cc b/usrp2/host/lib/copy_handler.cc deleted file mode 100644 index 92759084b..000000000 --- a/usrp2/host/lib/copy_handler.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2/copy_handler.h> -#include <iostream> -#include <string.h> - -namespace usrp2 { - - copy_handler::copy_handler(void *dest, size_t len) - : d_dest((uint8_t *)dest), d_space(len), d_bytes(0), d_times(0) - { - } - - copy_handler::~copy_handler() - { - // NOP - } - - data_handler::result - copy_handler::operator()(const void *base, size_t len) - { - if (len > d_space) - return KEEP|DONE; // can't do anything, retry later - - memcpy(&d_dest[d_bytes], base, len); - d_space -= len; - d_bytes += len; - d_times++; - - if (d_space < MIN_COPY_LEN) - return DONE; // don't call me anymore - - return 0; - } - -} // namespace usrp2 - diff --git a/usrp2/host/lib/data_handler.cc b/usrp2/host/lib/data_handler.cc deleted file mode 100644 index ba9123681..000000000 --- a/usrp2/host/lib/data_handler.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <usrp2/data_handler.h> - -namespace usrp2 { - - data_handler::~data_handler() - { - // default nop destructor - } - -} - diff --git a/usrp2/host/lib/eth_buffer.cc b/usrp2/host/lib/eth_buffer.cc deleted file mode 100644 index e8ca05283..000000000 --- a/usrp2/host/lib/eth_buffer.cc +++ /dev/null @@ -1,279 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2009 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "eth_buffer.h" -#include "ethernet.h" -#include <usrp2/data_handler.h> -#include <linux/if_packet.h> -#include <sys/socket.h> -#include <sys/mman.h> -#include <sys/poll.h> -#include <iostream> -#include <cmath> -#include <errno.h> -#include <stdexcept> -#include <string.h> -#include <cstdio> - - -#define ETH_BUFFER_DEBUG 0 // define to 0 or 1 -#if ETH_BUFFER_DEBUG -#define DEBUG_LOG(x) ::write(2, (x), 1) -#else -#define DEBUG_LOG(X) -#endif - -#define DEFAULT_MEM_SIZE 25e6 // ~0.25s @ 100 MB/s -#define MAX_MEM_SIZE 1000e6 // ~10.00s @ 100 MB/s. -#define MAX_SLAB_SIZE 131072 // 128 KB (FIXME fish out of /proc/slabinfo) -#define MAX_PKT_SIZE 1512 // we don't do jumbo frames - -namespace usrp2 { - - eth_buffer::eth_buffer(size_t rx_bufsize) - : d_fd(0), d_using_tpring(false), d_buflen(0), d_buf(0), d_frame_nr(0), - d_frame_size(0), d_head(0), d_ring(0), d_ethernet(new ethernet()) - { - if (rx_bufsize == 0) - d_buflen = (size_t)DEFAULT_MEM_SIZE; - else - d_buflen = std::min((size_t)MAX_MEM_SIZE, rx_bufsize); - - memset(d_mac, 0, sizeof(d_mac)); - } - - eth_buffer::~eth_buffer() - { - close(); - } - - bool - eth_buffer::open(const std::string &ifname, int protocol) - { - if (!d_ethernet->open(ifname, protocol)) { - std::cerr << "eth_buffer: unable to open interface " - << ifname << std::endl; - return false; - } - - d_fd = d_ethernet->fd(); - memcpy(d_mac, d_ethernet->mac(), sizeof(d_mac)); - - struct tpacket_req req; - size_t page_size = getpagesize(); - - // Calculate minimum power-of-two aligned size for frames - req.tp_frame_size = - (unsigned int)rint(pow(2, ceil(log2(TPACKET_ALIGN(TPACKET_HDRLEN)+TPACKET_ALIGN(MAX_PKT_SIZE))))); - d_frame_size = req.tp_frame_size; - - // Calculate minimum contiguous pages needed to enclose a frame - int npages = (page_size > req.tp_frame_size) ? 1 : ((req.tp_frame_size+page_size-1)/page_size); - req.tp_block_size = page_size << (int)ceil(log2(npages)); - - // Calculate number of blocks - req.tp_block_nr = (int)(d_buflen/req.tp_block_size); - - - // Recalculate buffer length - d_buflen = req.tp_block_nr*req.tp_block_size; - - // Finally, calculate total number of frames. Since frames, blocks, - // and pages are all power-of-two aligned, frames are contiguous - req.tp_frame_nr = d_buflen/req.tp_frame_size; - d_frame_nr = req.tp_frame_nr; - -#if 0 - if (ETH_BUFFER_DEBUG) - std::cerr << "eth_buffer:" - << " frame_size=" << req.tp_frame_size - << " block_size=" << req.tp_block_size - << " block_nr=" << req.tp_block_nr - << " frame_nr=" << req.tp_frame_nr - << " buflen=" << d_buflen - << std::endl; -#endif - - // Try to get kernel shared memory buffer - if (setsockopt(d_fd, SOL_PACKET, PACKET_RX_RING, (void *)&req, sizeof(req))) { - perror("eth_buffer: setsockopt"); - d_using_tpring = false; - if (!(d_buf = (uint8_t *)malloc(d_buflen))) { - std::cerr << "eth_buffer: failed to allocate packet memory" << std::endl; - return false; - } - - std::cerr << "eth_buffer: using malloc'd memory for buffer" << std::endl; - } - else { - d_using_tpring = true; - void *p = mmap(0, d_buflen, PROT_READ|PROT_WRITE, MAP_SHARED, d_fd, 0); - if (p == MAP_FAILED){ - perror("eth_buffer: mmap"); - return false; - } - d_buf = (uint8_t *) p; - - if (ETH_BUFFER_DEBUG) - std::cerr << "eth_buffer: using kernel shared mem for buffer" << std::endl; - } - - // Initialize our pointers into the packet ring - d_ring = std::vector<uint8_t *>(req.tp_frame_nr); - for (unsigned int i=0; i < req.tp_frame_nr; i++) { - d_ring[i] = (uint8_t *)(d_buf+i*req.tp_frame_size); - } - - // If not using kernel ring, instantiate select/read thread here - - return true; - } - - bool - eth_buffer::close() - { - // if we have background thread, stop it here - - if(d_buf) { - if (!d_using_tpring) - free(d_buf); - else - munmap(d_buf, d_buflen); - } - - return d_ethernet->close(); - } - - bool - eth_buffer::attach_pktfilter(pktfilter *pf) - { - return d_ethernet->attach_pktfilter(pf); - } - - inline bool - eth_buffer::frame_available() - { - return (((tpacket_hdr *)d_ring[d_head])->tp_status != TP_STATUS_KERNEL); - } - - eth_buffer::result - eth_buffer::rx_frames(data_handler *f, int timeout_in_ms) - { - DEBUG_LOG("\n"); - - while (!frame_available()) { - if (timeout_in_ms == 0) { - DEBUG_LOG("w"); - return EB_WOULD_BLOCK; - } - - struct pollfd pfd; - pfd.fd = d_fd; - pfd.revents = 0; - pfd.events = POLLIN; - - DEBUG_LOG("P"); - - int pres = poll(&pfd, 1, timeout_in_ms); - if (pres == -1) { - perror("poll"); - return EB_ERROR; - } - - if (pres == 0) { - DEBUG_LOG("t"); - return EB_TIMED_OUT; - } - } - - // Iterate through available packets - while (frame_available()) { - // Get start of ethernet frame and length - tpacket_hdr *hdr = (tpacket_hdr *)d_ring[d_head]; - void *base = (uint8_t *)hdr+hdr->tp_mac; - size_t len = hdr->tp_len; - - // FYI, (base % 4 == 2) Not what we want given the current FPGA - // code. This means that our uint32_t samples are not 4-byte - // aligned. We'll have to deal with it downstream. - - if (0) - fprintf(stderr, "eth_buffer: base = %p tp_mac = %3d tp_net = %3d\n", - base, hdr->tp_mac, hdr->tp_net); - - // Invoke data handler - data_handler::result r = (*f)(base, len); - if (!(r & data_handler::KEEP)) - hdr->tp_status = TP_STATUS_KERNEL; // mark it free - - inc_head(); - - if (r & data_handler::DONE) - break; - } - - DEBUG_LOG("|"); - return EB_OK; - } - - eth_buffer::result - eth_buffer::tx_frame(const void *base, size_t len, int flags) - { - DEBUG_LOG("T"); - - if (flags & EF_DONTWAIT) // FIXME: implement flags - throw std::runtime_error("tx_frame: EF_DONTWAIT not implemented"); - - int res = d_ethernet->write_packet(base, len); - if (res < 0 || (unsigned int)res != len) - return EB_ERROR; - - return EB_OK; - } - - eth_buffer::result - eth_buffer::tx_framev(const eth_iovec *iov, int iovcnt, int flags) - { - DEBUG_LOG("T"); - - if (flags & EF_DONTWAIT) // FIXME: implement flags - throw std::runtime_error("tx_frame: EF_DONTWAIT not implemented"); - - int res = d_ethernet->write_packetv(iov, iovcnt); - if (res < 0) - return EB_ERROR; - - return EB_OK; - } - - void - eth_buffer::release_frame(void *base) - { - // Get d_frame_size aligned header - tpacket_hdr *hdr = (tpacket_hdr *)((intptr_t)base & ~(d_frame_size-1)); - hdr->tp_status = TP_STATUS_KERNEL; // mark it free - } - -} // namespace usrp2 diff --git a/usrp2/host/lib/eth_buffer.h b/usrp2/host/lib/eth_buffer.h deleted file mode 100644 index 8dee9a4a2..000000000 --- a/usrp2/host/lib/eth_buffer.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP2_ETH_BUFFER_H -#define INCLUDED_USRP2_ETH_BUFFER_H - -#include "pktfilter.h" -#include <eth_common.h> -#include <boost/utility.hpp> -#include <vector> -#include <memory> -#include <stdint.h> - -namespace usrp2 { - - class ethernet; - class data_handler; - - /*! - * \brief high-performance interface to send and receive raw - * ethernet frames with out-of-order retirement of received frames. - * - * On many systems it should be possible to implement this on top of libpcap - * - * \internal - */ - class eth_buffer : boost::noncopyable - { - - int d_fd; // socket file descriptor - uint8_t d_mac[6]; // our mac address - bool d_using_tpring; // using kernel mapped packet ring - size_t d_buflen; // length of our buffer - uint8_t *d_buf; // packet ring - unsigned int d_frame_nr; // max frames on ring - size_t d_frame_size; // frame storage size - unsigned int d_head; // pointer to next frame - - std::vector<uint8_t *> d_ring; // pointers into buffer - std::auto_ptr<ethernet> d_ethernet; // our underlying interface - - bool frame_available(); - - void inc_head() - { - if (d_head + 1 >= d_frame_nr) - d_head = 0; - else - d_head = d_head + 1; - } - - - public: - - enum result { - EB_OK, //< everything's fine - EB_ERROR, //< A non-recoverable error occurred - EB_WOULD_BLOCK, //< A timeout of 0 was specified and nothing was ready - EB_TIMED_OUT, //< The timeout expired before anything was ready - }; - - static const unsigned int MAX_PKTLEN = 1512; - static const unsigned int MIN_PKTLEN = 64; - - /*! - * \param rx_bufsize is a hint as to the number of bytes of memory - * to allocate for received ethernet frames (0 -> reasonable default) - */ - eth_buffer(size_t rx_bufsize = 0); - ~eth_buffer(); - - /*! - * \brief open the specified interface - * - * \param ifname ethernet interface name, e.g., "eth0" - * \param protocol is the ethertype protocol number in network order. - * Use 0 to receive all protocols. - */ - bool open(const std::string &ifname, int protocol); - - /*! - * \brief close the interface - */ - bool close(); - - /*! - * \brief attach packet filter to socket to restrict which packets read sees. - * \param pf the packet filter - */ - bool attach_pktfilter(pktfilter *pf); - - /*! - * \brief return 6 byte string containing our MAC address - */ - const uint8_t *mac() const { return d_mac; } - - /*! - * \brief Call \p f for each frame in the receive buffer. - * \param f is the frame data handler - * \param timeout (in ms) controls behavior when there are no frames to read - * - * If \p timeout is 0, rx_frames will not wait for frames if none are - * available, and f will not be invoked. If \p timeout is -1 (the - * default), rx_frames will block indefinitely until frames are - * available. If \p timeout is positive, it indicates the number of - * milliseconds to wait for a frame to become available. Once the - * timeout has expired, rx_frames will return, f never having been - * invoked. - * - * \p f will be called on each ethernet frame that is available. - * \p f returns a bit mask with one of the following set or cleared: - * - * data_handler::KEEP - hold onto the frame and present it again during - * the next call to rx_frames, otherwise discard it - * - * data_handler::DONE - return from rx_frames now even though more frames - * might be available; otherwise continue if more - * frames are ready. - * - * The idea of holding onto a frame for the next iteration allows - * the caller to scan the received packet stream for particular - * classes of frames (such as command replies) leaving the rest - * intact. On the next call all kept frames, followed by any new - * frames received, will be presented in order to \p f. - * See usrp2.cc for an example of the pattern. - * - * \returns EB_OK if at least one frame was received - * \returns EB_WOULD_BLOCK if \p timeout is 0 and the call would have blocked - * \returns EB_TIMED_OUT if timeout occurred - * \returns EB_ERROR if there was an unrecoverable error. - */ - result rx_frames(data_handler *f, int timeout=-1); - - /* - * \brief Release frame from buffer - * - * Call to release a frame previously held by a data_handler::KEEP. - * The pointer may be offset from the base of the frame up to its length. - */ - void release_frame(void *p); - - /* - * \brief Write an ethernet frame to the interface. - * - * \param base points to the beginning of the frame (the 14-byte ethernet header). - * \param len is the length of the frame in bytes. - * \param flags is 0 or the bitwise-or of values from eth_flags - * - * The frame must begin with a 14-byte ethernet header. - * - * \returns EB_OK if the frame was successfully enqueued. - * \returns EB_WOULD_BLOCK if flags contains EF_DONT_WAIT and the call would have blocked. - * \returns EB_ERROR if there was an unrecoverable error. - */ - result tx_frame(const void *base, size_t len, int flags=0); - - /* - * \brief Write an ethernet frame to the interface using scatter/gather. - * - * \param iov points to an array of iovec structs - * \param iovcnt is the number of entries - * \param flags is 0 or the bitwise-or of values from eth_flags - * - * The frame must begin with a 14-byte ethernet header. - * - * \returns EB_OK if the frame was successfully enqueued. - * \returns EB_WOULD_BLOCK if flags contains EF_DONT_WAIT and the call would have blocked. - * \returns EB_ERROR if there was an unrecoverable error. - */ - result tx_framev(const eth_iovec *iov, int iovcnt, int flags=0); - - /* - * \brief Returns maximum possible number of frames in buffer - */ - unsigned int max_frames() const { return d_frame_nr; } - - }; - -}; // namespace usrp2 - -#endif /* INCLUDED_USRP2_ETH_BUFFER_H */ diff --git a/usrp2/host/lib/eth_common.h b/usrp2/host/lib/eth_common.h deleted file mode 100644 index 7c9feaa25..000000000 --- a/usrp2/host/lib/eth_common.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef INCLUDED_USRP2_ETH_COMMON_H -#define INCLUDED_USRP2_ETH_COMMON_H - -#include <sys/uio.h> // FIXME autoconf this - -namespace usrp2 { - - enum eth_flags { - EF_DONTWAIT = 0x0001, - }; - - typedef struct iovec eth_iovec; // FIXME autoconf this - -} // namespace usrp2 - - -#endif /* INCLUDED_USRP2_ETH_COMMON_H */ diff --git a/usrp2/host/lib/ethernet.cc b/usrp2/host/lib/ethernet.cc deleted file mode 100644 index e51680b2e..000000000 --- a/usrp2/host/lib/ethernet.cc +++ /dev/null @@ -1,230 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "eth_buffer.h" -#include "ethernet.h" -#include "pktfilter.h" -#include <open_usrp2_socket.h> - -#include <cstdio> -#include <iostream> -#include <unistd.h> -#include <fcntl.h> -//#include <features.h> -#include <errno.h> -#include <string.h> -#include <net/if.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <net/ethernet.h> -#include <netinet/in.h> - -#include <linux/types.h> -#include <netpacket/packet.h> -#include <linux/filter.h> // packet filter - -namespace usrp2 { - - static int - open_packet_socket (std::string ifname, int protocol) - { -#if 0 - if (protocol == 0) - protocol = htons(ETH_P_ALL); - - int fd = socket (PF_PACKET, SOCK_RAW, protocol); -#else - int fd = usrp2::open_usrp2_socket(); -#endif - - if (fd == -1){ - fprintf (stderr, "%s: socket: %s\n", ifname.c_str(), strerror (errno)); - return -1; - } - - // get interface index - struct ifreq ifr; - memset (&ifr, 0, sizeof(ifr)); - strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name)); - int res = ioctl (fd, SIOCGIFINDEX, &ifr); - if (res != 0){ - ::close (fd); - fprintf (stderr, "%s: SIOCGIFINDEX: %s\n", ifname.c_str(), strerror(errno)); - return -1; - } - int ifindex = ifr.ifr_ifindex; - - // bind to the specified interface - sockaddr_ll sa; - memset (&sa, 0, sizeof (sa)); - sa.sll_family = AF_PACKET; - sa.sll_protocol = protocol; - sa.sll_ifindex = ifindex; - res = bind (fd, (struct sockaddr *)&sa, sizeof (sa)); - if (res != 0){ - ::close (fd); - fprintf (stderr, "%s: bind: %s\n", ifname.c_str(), strerror(errno)); - return -1; - } - return fd; - } - - static void - extract_mac_addr (unsigned char *mac, const unsigned char *hwaddr) - { - int i; - for (i = 0; i < 6; i++) - mac[i] = 0xff; - - i = 0; - for (int j = 0; j < 14; j++){ - if (hwaddr[j] != 0xff){ - mac[i++] = hwaddr[j]; - if (i == 6) - return; - } - } - } - - static bool - get_mac_addr (std::string ifname, int fd, unsigned char *mac) - { - struct ifreq ifr; - memset (&ifr, 0, sizeof(ifr)); - strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name)); - int res = ioctl (fd, SIOCGIFHWADDR, &ifr); - if (res != 0){ - fprintf (stderr, "%s: SIOCGIFHWADDR: %s\n", ifname.c_str(), strerror(errno)); - return false; - } - else { - if (0){ - for (unsigned i = 0; i < sizeof (ifr.ifr_hwaddr.sa_data); i++) - fprintf (stderr, "%02x", ifr.ifr_hwaddr.sa_data[i]); - fprintf (stderr, "\n"); - } - } - extract_mac_addr (mac, (unsigned char *)ifr.ifr_hwaddr.sa_data); - return true; - } - - ethernet::ethernet () - { - d_fd = -1; - memset (d_mac, 0, sizeof (d_mac)); - } - - ethernet::~ethernet () - { - close (); - } - - bool - ethernet::open (std::string ifname, int protocol) - { - if (d_fd != -1){ - fprintf (stderr, "ethernet: already open\n"); - return false; - } - if ((d_fd = open_packet_socket (ifname, protocol)) == -1){ - return false; - } - get_mac_addr (ifname, d_fd, d_mac); - return true; - } - - bool - ethernet::close () - { - if (d_fd >= 0){ - ::close (d_fd); - d_fd = -1; - } - return true; - } - - int - ethernet::read_packet (void *buf, int buflen) - { - int len = recvfrom (d_fd, buf, buflen, 0, (sockaddr *) 0, 0); - return len; - } - - int - ethernet::read_packet_dont_block (void *buf, int buflen) - { - int len = recvfrom (d_fd, buf, buflen, MSG_DONTWAIT, 0, 0); - if (len == -1 && errno == EAGAIN) - return 0; - - return len; - } - - int - ethernet::write_packet (const void *buf, int buflen) - { - int retval = send (d_fd, buf, buflen, 0); - if (retval < 0){ - if (errno == EINTR) - return write_packet (buf, buflen); - - perror ("ethernet:write_packet: send"); - return -1; - } - return retval; - } - - int - ethernet::write_packetv(const eth_iovec *iov, size_t iovlen) - { - struct msghdr mh; - memset(&mh, 0, sizeof(mh)); - mh.msg_iov = const_cast<eth_iovec*>(iov); - mh.msg_iovlen = iovlen; - - int retval = sendmsg(d_fd, &mh, 0); - if (retval < 0){ - if (errno == EINTR) - return write_packetv(iov, iovlen); - - perror("ethernet:write_packetv: send"); - return -1; - } - return retval; - } - - bool - ethernet::attach_pktfilter (pktfilter *pf) - { - struct sock_fprog filter; - filter.len = pf->d_len; - filter.filter = pf->d_inst; - - int r = setsockopt (d_fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof (filter)); - if (r < 0){ - perror ("ethernet:attach: SO_ATTACH_FILTER"); - return false; - } - return true; - } - -} // namespace usrp2 diff --git a/usrp2/host/lib/ethernet.h b/usrp2/host/lib/ethernet.h deleted file mode 100644 index 24624f441..000000000 --- a/usrp2/host/lib/ethernet.h +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_USRP2_ETHERNET_H -#define INCLUDED_USRP2_ETHERNET_H - -#include <string> -#include <vector> -#include <eth_common.h> - -namespace usrp2 { - - class pktfilter; - - /*! - * \brief Read and write ethernet frames. - * - * This provides a low level interface to hardware that communicates - * via raw (non-IP) ethernet frames. - */ - class ethernet { - int d_fd; - uint8_t d_mac[6]; - - public: - ethernet (); - ~ethernet (); - - static const int MAX_PKTLEN = 1512; - static const int MIN_PKTLEN = 64; - - /*! - * \param ifname ethernet interface name, e.g., "eth0" - * \param protocol is the ethertype protocol number in network order. - * Use 0 to receive all protocols. - */ - bool open (std::string ifname, int protocol); - - bool close (); - - /*! - * \brief attach packet filter to socket to restrict which packets read sees. - * \param pf the packet filter - */ - bool attach_pktfilter (pktfilter *pf); - - /*! - * \brief return 6 byte string containing our MAC address - */ - const uint8_t *mac () const { return d_mac; } - - /*! - * \brief Return file descriptor associated with socket. - */ - int fd () const { return d_fd; } - - /*! - * \brief Read packet from interface. - * - * \param buf where to put the packet - * \param buflen maximum length of packet in bytes (should be >= 1528) - * - * \returns number of bytes read or -1 if trouble. - * - * Returned packet includes 14-byte ethhdr - */ - int read_packet (void *buf, int buflen); - - /*! - * \brief Read packet from interface, but don't block waiting - * - * \param buf where to put the packet - * \param buflen maximum length of packet in bytes (should be >= 1528) - * - * \returns number of bytes read, -1 if trouble or 0 if nothing available. - * - * Returned packet includes 14-byte ethhdr - */ - int read_packet_dont_block (void *buf, int buflen); - - /* - * \brief Write ethernet packet to interface. - * - * \param buf the packet to write - * \param buflen length of packet in bytes - * - * \returns number of bytes written or -1 if trouble. - * - * Packet must begin with 14-byte ethhdr, but does not include the FCS. - */ - int write_packet (const void *buf, int buflen); - - /* - * \brief Write ethernet packet to interface. - * - * \param iov scatter/gather array - * \param iovlen number of elements in iov - * - * \returns number of bytes written or -1 if trouble. - * - * Packet must begin with 14-byte ethhdr, but does not include the FCS. - */ - int write_packetv (const eth_iovec *iov, size_t iovlen); - - }; - -} // namespace usrp2 - -#endif /* INCLUDED_USRP2_ETHERNET_H */ diff --git a/usrp2/host/lib/find.cc b/usrp2/host/lib/find.cc deleted file mode 100644 index d1df47fc5..000000000 --- a/usrp2/host/lib/find.cc +++ /dev/null @@ -1,182 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2_eth_packet.h> -#include <usrp2/usrp2.h> -#include <boost/scoped_ptr.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include "ethernet.h" -#include "pktfilter.h" -#include <string.h> -#include <iostream> -#include <stdexcept> -#include <cstdio> - -#define FIND_DEBUG 0 - - -// FIXME move to gruel - -static struct timeval -time_duration_to_timeval(boost::posix_time::time_duration delta) -{ - long total_us = delta.total_microseconds(); - if (total_us < 0) - throw std::invalid_argument("duration_to_time: delta is negative"); - - struct timeval tv; - tv.tv_sec = total_us / 1000000; - tv.tv_usec = total_us % 1000000; - return tv; -} - - -namespace usrp2 { - - static props - reply_to_props(const op_id_reply_t *r) - { - const uint8_t *mac = (const uint8_t *)&r->addr; - char addr_buf[128]; - snprintf(addr_buf, sizeof(addr_buf), "%02x:%02x:%02x:%02x:%02x:%02x", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - props p; - p.addr = std::string(addr_buf); - p.hw_rev = ntohs(r->hw_rev); - memcpy(p.fpga_md5sum, r->fpga_md5sum, sizeof(p.fpga_md5sum)); - memcpy(p.sw_md5sum, r->sw_md5sum, sizeof(p.sw_md5sum)); - return p; - } - - static void - read_replies(ethernet *enet, struct timeval timeout, - const std::string &target_addr, props_vector_t &result) - { - struct reply { - u2_eth_packet_t h; - op_id_reply_t op_id_reply; - }; - - uint8_t pktbuf[ethernet::MAX_PKTLEN]; - memset(pktbuf, 0, sizeof(pktbuf)); - - fd_set read_fds; - FD_ZERO(&read_fds); - FD_SET(enet->fd(), &read_fds); - - select(enet->fd()+1, &read_fds, 0, 0, &timeout); - while(1) { - memset(pktbuf, 0, sizeof(pktbuf)); - int len = enet->read_packet_dont_block(pktbuf, sizeof(pktbuf)); - if (len < 0){ - perror("usrp2_basic: read_packet_dont_block"); - return; - } - if (len == 0) - break; - - reply *rp = (reply *)pktbuf; - if (u2p_chan(&rp->h.fixed) != CONTROL_CHAN) // ignore - continue; - if (rp->op_id_reply.opcode != OP_ID_REPLY) // ignore - continue; - - props p = reply_to_props(&rp->op_id_reply); - if (FIND_DEBUG) - std::cerr << "usrp2::find: response from " << p.addr << std::endl; - - if ((target_addr == "") || (target_addr == p.addr)) - result.push_back(p); - } - } - - props_vector_t - find(const std::string &ifc, const std::string &addr) - { - if (FIND_DEBUG) { - std::cerr << "usrp2::find: Searching interface " << ifc << " for " - << (addr == "" ? "all USRP2s" : addr) - << std::endl; - } - - props_vector_t result; - struct command { - u2_eth_packet_t h; - op_generic_t op_id; - }; - - std::auto_ptr<ethernet> enet(new ethernet()); - - if (!enet->open(ifc, htons(U2_ETHERTYPE))) - return result; - - std::auto_ptr<pktfilter> pf(pktfilter::make_ethertype_inbound(U2_ETHERTYPE, enet->mac())); - if (!enet->attach_pktfilter(pf.get())) - return result; - - static u2_mac_addr_t broadcast_mac_addr = - {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}; - - uint8_t pktbuf[ethernet::MAX_PKTLEN]; - memset(pktbuf, 0, sizeof(pktbuf)); - - command *c = (command *)pktbuf; - c->h.ehdr.ethertype = htons(U2_ETHERTYPE); - c->h.ehdr.dst = broadcast_mac_addr; - memcpy(&c->h.ehdr.src, enet->mac(), 6); - c->h.thdr.flags = 0; - c->h.thdr.seqno = 0; - c->h.thdr.ack = 0; - u2p_set_word0(&c->h.fixed, 0, CONTROL_CHAN); - u2p_set_timestamp(&c->h.fixed, -1); - c->op_id.opcode = OP_ID; - c->op_id.len = sizeof(c->op_id); - int len = std::max((size_t) ethernet::MIN_PKTLEN, sizeof(command)); - if (enet->write_packet(c, len) != len) - return result; - - if (FIND_DEBUG) - std::cerr << "usrp2::find: broadcast ID command" << std::endl; - - /* - * Gather all responses that occur within 50ms - */ - boost::posix_time::ptime start(boost::posix_time::microsec_clock::universal_time()); - boost::posix_time::ptime limit(start + boost::posix_time::milliseconds(50)); - boost::posix_time::ptime now; - - while (1){ - now = boost::posix_time::microsec_clock::universal_time(); - if (now >= limit) - break; - - boost::posix_time::time_duration delta(limit - now); - struct timeval timeout = time_duration_to_timeval(delta); - - read_replies(enet.get(), timeout, addr, result); - } - return result; - } - -} // namespace usrp2 - diff --git a/usrp2/host/lib/open_usrp2_socket.cc b/usrp2/host/lib/open_usrp2_socket.cc deleted file mode 100644 index cd729205d..000000000 --- a/usrp2/host/lib/open_usrp2_socket.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <open_usrp2_socket.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/wait.h> -#include <stdio.h> -#include <errno.h> -#include <string> - -static const char *helper = "usrp2_socket_opener"; - -static ssize_t -read_fd(int fd, void *ptr, size_t nbytes, int *recvfd) -{ - struct msghdr msg; - struct iovec iov[1]; - ssize_t n; - -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof (int))]; - } control_un; - struct cmsghdr *cmptr; - - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); -#else - int newfd; - - msg.msg_accrights = (char *) &newfd; - msg.msg_accrightslen = sizeof(int); -#endif - - msg.msg_name = NULL; - msg.msg_namelen = 0; - - iov[0].iov_base = ptr; - iov[0].iov_len = nbytes; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - - if ((n = recvmsg(fd, &msg, 0)) <= 0) - return n; - -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL - if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL - && cmptr->cmsg_len == CMSG_LEN(sizeof(int))){ - if (cmptr->cmsg_level != SOL_SOCKET){ - fprintf(stderr, "read_fd: control level != SOL_SOCKET\n"); - return -1; - } - if (cmptr->cmsg_type != SCM_RIGHTS){ - fprintf(stderr, "read_fd: control type != SCM_RIGHTS\n"); - return -1; - } - *recvfd = *((int *) CMSG_DATA(cmptr)); - } else - *recvfd = -1; /* descriptor was not passed */ -#else - if (msg.msg_accrightslen == sizeof(int)) - *recvfd = newfd; - else - *recvfd = -1; /* descriptor was not passed */ -#endif - - return n; -} - -int -usrp2::open_usrp2_socket() -{ - int fd = -1, sockfd[2], status; - pid_t childpid; - char c, argsockfd[10]; - - if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd) != 0){ - perror("socketpair"); - return -1; - } - - if ((childpid = fork()) == 0) { /* child process */ - close(sockfd[0]); - snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]); - execlp(helper, helper, argsockfd, (char *) NULL); - std::string msg("execlp: couldn't exec " + std::string(helper)); - perror(msg.c_str()); - close(sockfd[0]); - close(sockfd[1]); - return -1; - } - - /* parent process - wait for the child to terminate */ - close(sockfd[1]); /* close the end we don't use */ - - waitpid(childpid, &status, 0); - if (!WIFEXITED(status)){ - fprintf(stderr, "child did not terminate\n"); - return -1; - } - if ((status = WEXITSTATUS(status)) == 0) - read_fd(sockfd[0], &c, 1, &fd); - else { - errno = status; /* bogus: set errno value from child's status */ - fd = -1; - } - - close(sockfd[0]); - return (fd); -} diff --git a/usrp2/host/lib/open_usrp2_socket.h b/usrp2/host/lib/open_usrp2_socket.h deleted file mode 100644 index d42440ea0..000000000 --- a/usrp2/host/lib/open_usrp2_socket.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ -#ifndef INCLUDED_OPEN_USRP2_SOCKET_H -#define INCLUDED_OPEN_USRP2_SOCKET_H - -namespace usrp2 { - - /*! - * Return the result of executing: - * - * int fd = socket(PF_PACKET, SOCK_RAW, htons(0xBEEF)); - * - * Doing it in a way that we don't need to be running as root. - */ - int open_usrp2_socket(); -}; - - -#endif /* INCLUDED_OPEN_USRP2_SOCKET_H */ diff --git a/usrp2/host/lib/pktfilter.cc b/usrp2/host/lib/pktfilter.cc deleted file mode 100644 index 1ccf90446..000000000 --- a/usrp2/host/lib/pktfilter.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pktfilter.h" -#include <iostream> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <net/if.h> -#include <features.h> -#include <netpacket/packet.h> -#include <net/ethernet.h> -#include <netinet/in.h> -#include <assert.h> -#include <linux/types.h> -#include <linux/filter.h> // packet filter - -namespace usrp2 { - - /* - * This is all based on the Berkeley Packet Filter (BPF) as implemented on Linux. - * - * The BPF allows you to run an interpreted program (a filter) in the - * kernel that sorts through the packets looking for ones you are - * interested in. This eliminates the overhead of passing all of the - * networking packets up into user space for filtering there. - * - * For documentation on this see - * /usr/src/linux/Documentation/networking/filter.txt, The BSD - * Berkeley Packet Filter manual page, and "The BSD Packet Filter: A - * New Architecture for User-level Packet Capture", by Steven McCanne - * and Van Jacobson. - */ - - pktfilter::pktfilter () - : d_len (0), d_inst (0) - { - // NOP - } - - pktfilter::~pktfilter () - { - delete [] d_inst; - } - - inline static sock_filter - make_stmt (__u16 code, __u32 k) - { - sock_filter f; - f.code = code; - f.jt = 0; - f.jf = 0; - f.k = k; - return f; - } - - inline static sock_filter - make_jump (__u16 code, __u32 k, __u8 jt, __u8 jf) - { - sock_filter f; - f.code = code; - f.jt = jt; - f.jf = jf; - f.k = k; - return f; - } - - /* - * Return a filter that harvests packets with the specified ethertype. - */ - pktfilter * - pktfilter::make_ethertype (unsigned short ethertype) - { - static const int MAX_LEN = 20; - sock_filter *inst = new sock_filter [MAX_LEN]; - pktfilter *pf = new pktfilter (); - - // nothing quite like coding in assembly without the benefit of an assembler ;-) - - // ignore packets that don't have the right ethertype - - int i = 0; - inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12); // load ethertype - inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 1, 0); - inst[i++] = make_stmt (BPF_RET|BPF_K, 0); // return 0 (ignore packet) - inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1); // return whole packet - - assert (i <= MAX_LEN); - - pf->d_inst = inst; - pf->d_len = i; - - return pf; - } - - /* - * Return a filter that harvests inbound packets with the specified ethertype. - * \param ethertype the ethertype we're looking for - * \param our_mac our ethernet MAC address so we can avoid pkts we sent - */ - pktfilter * - pktfilter::make_ethertype_inbound (unsigned short ethertype, const unsigned char *our_mac) - { - static const int MAX_LEN = 20; - sock_filter *inst = new sock_filter [MAX_LEN]; - pktfilter *pf = new pktfilter (); - - __u16 smac_hi = (our_mac[0] << 8) | our_mac[1]; - __u32 smac_lo = (our_mac[2] << 24) | (our_mac[3] << 16) | (our_mac[4] << 8) | our_mac[5]; - - // nothing quite like coding in assembly without the benefit of an assembler ;-) - - // ignore packets that have a different ethertype - // and packets that have a source mac address == our_mac (packets we sent) - - int i = 0; - inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12); // load ethertype - inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 0, 5); - inst[i++] = make_stmt (BPF_LD|BPF_W|BPF_ABS, 8); // load low 32-bit of src mac - inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_lo, 0, 2); - inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 6); // load high 16-bits of src mac - inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_hi, 1, 0); - inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1); // return whole packet - inst[i++] = make_stmt (BPF_RET|BPF_K, 0); // return 0 (ignore packet) - - assert (i <= MAX_LEN); - - pf->d_inst = inst; - pf->d_len = i; - - return pf; - } - /* - * Return a filter that harvests inbound packets with the specified ethertype and target USRP2 MAC address. - * \param ethertype the ethertype we're looking for - * \param usrp_mac our target USRP2 MAC address - */ - pktfilter * - pktfilter::make_ethertype_inbound_target (unsigned short ethertype, const unsigned char *usrp_mac) - { - static const int MAX_LEN = 20; - sock_filter *inst = new sock_filter [MAX_LEN]; - pktfilter *pf = new pktfilter (); - - __u16 tmac_hi = (usrp_mac[0] << 8) | usrp_mac[1]; - __u32 tmac_lo = (usrp_mac[2] << 24) | (usrp_mac[3] << 16) | (usrp_mac[4] << 8) | usrp_mac[5]; - - // ignore packets that have a different ethertype - // and only return packets that have a source mac address == usrp_mac - - int i = 0; - inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12); // load ethertype - inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 0, 5); - inst[i++] = make_stmt (BPF_LD|BPF_W|BPF_ABS, 8); // load low 32-bit of src mac - inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, tmac_lo, 0, 3); - inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 6); // load high 16-bits of src mac - inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, tmac_hi, 0, 1); - inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1); // return whole packet - inst[i++] = make_stmt (BPF_RET|BPF_K, 0); // return 0 (ignore packet) - - assert (i <= MAX_LEN); - - pf->d_inst = inst; - pf->d_len = i; - - return pf; - } - -} // namespace usrp2 diff --git a/usrp2/host/lib/pktfilter.h b/usrp2/host/lib/pktfilter.h deleted file mode 100644 index 09937ae34..000000000 --- a/usrp2/host/lib/pktfilter.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2007,2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_USRP2_PKTFILTER_H -#define INCLUDED_USRP2_PKTFILTER_H - -struct sock_filter; - -namespace usrp2 { - - /* - * \brief Compile programs for the Berkeley Packet Filter - */ - class pktfilter { - public: - - unsigned d_len; // # of instructions - struct sock_filter *d_inst; // the instructions - - pktfilter (); - ~pktfilter (); - - /*! - * \brief Return a filter that harvests packets with the specified ethertype. - * \param ethertype the ethertype we're looking for. - */ - static pktfilter *make_ethertype (unsigned short ethertype); - - /*! - * \brief Return a filter that harvests inbound packets with the specified ethertype. - * \param ethertype the ethertype we're looking for - * \param our_mac our MAC address so we can avoid pkts we sent - */ - static pktfilter *make_ethertype_inbound (unsigned short ethertype, - const unsigned char *our_mac); - - /*! - * \brief Return a filter that harvests inbound packets with the specified ethertype - * and source MAC address - * \param ethertype the ethertype we're looking for - * \param usrp_mac the source MAC address - */ - static pktfilter *make_ethertype_inbound_target (unsigned short ethertype, - const unsigned char *usrp_mac); - }; - -} // namespace usrp2 - -#endif /* INCLUDED_USRP2_PKTFILTER_H */ diff --git a/usrp2/host/lib/ring.cc b/usrp2/host/lib/ring.cc deleted file mode 100644 index d0048418c..000000000 --- a/usrp2/host/lib/ring.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2010 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "ring.h" - -namespace usrp2 { - - ring::ring(unsigned int entries) - : d_max(entries), d_read_ind(0), d_write_ind(0), d_ring(entries), - d_mutex(), d_not_empty() - { - for (unsigned int i = 0; i < entries; i++) { - d_ring[i].d_base = 0; - d_ring[i].d_len = 0; - } - } - - void - ring::wait_for_not_empty() - { - gruel::scoped_lock l(d_mutex); - while (empty()) - d_not_empty.wait(l); - } - - bool - ring::enqueue(void *p, size_t len) - { - gruel::scoped_lock l(d_mutex); - if (full()) - return false; - - d_ring[d_write_ind].d_len = len; - d_ring[d_write_ind].d_base = p; - - inc_write_ind(); - d_not_empty.notify_one(); - return true; - } - - bool - ring::dequeue(void **p, size_t *len) - { - gruel::scoped_lock l(d_mutex); - if (empty()) - return false; - - *p = d_ring[d_read_ind].d_base; - *len = d_ring[d_read_ind].d_len; - - inc_read_ind(); - return true; - } - -} // namespace usrp2 - diff --git a/usrp2/host/lib/ring.h b/usrp2/host/lib/ring.h deleted file mode 100644 index fd0ad0a9f..000000000 --- a/usrp2/host/lib/ring.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2010 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_RING_H -#define INCLUDED_RING_H - -#include <stddef.h> -#include <vector> -#include <boost/shared_ptr.hpp> -#include <gruel/thread.h> - -namespace usrp2 { - - class ring; - typedef boost::shared_ptr<ring> ring_sptr; - - class ring - { - private: - - size_t d_max; - size_t d_read_ind; - size_t d_write_ind; - - struct ring_desc - { - void *d_base; - size_t d_len; - }; - std::vector<ring_desc> d_ring; - - gruel::mutex d_mutex; - gruel::condition_variable d_not_empty; - - void inc_read_ind() - { - if (d_read_ind + 1 >= d_max) - d_read_ind = 0; - else - d_read_ind = d_read_ind + 1; - } - - void inc_write_ind() - { - if (d_write_ind + 1 >= d_max) - d_write_ind = 0; - else - d_write_ind = d_write_ind + 1; - } - - bool empty() const { return d_read_ind == d_write_ind; } - bool full() const { return (d_write_ind+1)%d_max == d_read_ind; } - - public: - - ring(unsigned int entries); - - void wait_for_not_empty(); - - bool enqueue(void *p, size_t len); - bool dequeue(void **p, size_t *len); - }; - -} // namespace usrp2 - -#endif /* INCLUDED_RING_H */ diff --git a/usrp2/host/lib/rx_nop_handler.cc b/usrp2/host/lib/rx_nop_handler.cc deleted file mode 100644 index 96c9164a5..000000000 --- a/usrp2/host/lib/rx_nop_handler.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2/rx_nop_handler.h> - -namespace usrp2 { - - rx_nop_handler::~rx_nop_handler() - { - } - -} // namespace usrp2 - diff --git a/usrp2/host/lib/rx_sample_handler.cc b/usrp2/host/lib/rx_sample_handler.cc deleted file mode 100644 index 4521025cb..000000000 --- a/usrp2/host/lib/rx_sample_handler.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <usrp2/rx_sample_handler.h> - -usrp2::rx_sample_handler::~rx_sample_handler() -{ - // nop -} diff --git a/usrp2/host/lib/strtod_si.c b/usrp2/host/lib/strtod_si.c deleted file mode 100644 index 5e5deb2b6..000000000 --- a/usrp2/host/lib/strtod_si.c +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * 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 <usrp2/strtod_si.h> -#include <stdlib.h> - -#define true 1 -#define false 0 - -int -strtod_si(const char *s, double *result) -{ - *result = 0; - - char *endptr; - double r = strtod(s, &endptr); - if (s == endptr) - return false; - - switch (*endptr){ - case 'p': r *= 1e-12; break; - case 'n': r *= 1e-9; break; - case 'u': r *= 1e-6; break; - case 'm': r *= 1e-3; break; - case 'k': r *= 1e3; break; - case 'M': r *= 1e6; break; - case 'G': r *= 1e9; break; - case 'T': r *= 1e12; break; - default: - // ignore. FIXME could be more robust - break; - } - - *result = r; - return true; -} - - diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc deleted file mode 100644 index 0842482e4..000000000 --- a/usrp2/host/lib/usrp2.cc +++ /dev/null @@ -1,504 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2009 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2/usrp2.h> -#include "usrp2_impl.h" -#include <vector> -#include <boost/thread.hpp> -#include <boost/weak_ptr.hpp> -#include <string> -#include <stdexcept> -#include <cstdio> - -namespace usrp2 { - - // --- Table of weak pointers to usrps we know about --- - - // (Could be cleaned up and turned into a template) - - struct usrp_table_entry { - // inteface + normalized mac addr ("eth0:01:23:45:67:89:ab") - std::string key; - boost::weak_ptr<usrp2> value; - - usrp_table_entry(const std::string &_key, boost::weak_ptr<usrp2> _value) - : key(_key), value(_value) {} - }; - - typedef std::vector<usrp_table_entry> usrp_table; - - static boost::mutex s_table_mutex; - static usrp_table s_table; - - usrp2::sptr - usrp2::find_existing_or_make_new(const std::string &ifc, props *pr, size_t rx_bufsize) - { - std::string key = ifc + ":" + pr->addr; - - boost::mutex::scoped_lock guard(s_table_mutex); - - for (usrp_table::iterator p = s_table.begin(); p != s_table.end();){ - if (p->value.expired()) // weak pointer is now dead - p = s_table.erase(p); // erase it - else { - if (key == p->key) // found it - return usrp2::sptr(p->value); - else - ++p; // keep looking - } - } - - // We don't have the USRP2 we're looking for - - // create a new one and stick it in the table. - usrp2::sptr r(new usrp2(ifc, pr, rx_bufsize)); - usrp_table_entry t(key, r); - s_table.push_back(t); - - return r; - } - - // --- end of table code --- - - static bool - parse_mac_addr(const std::string &s, std::string &ns) - { - u2_mac_addr_t p; - - p.addr[0] = 0x00; // Matt's IAB - p.addr[1] = 0x50; - p.addr[2] = 0xC2; - p.addr[3] = 0x85; - p.addr[4] = 0x30; - p.addr[5] = 0x00; - - int len = s.size(); - switch (len) { - - case 5: - if (sscanf(s.c_str(), "%hhx:%hhx", &p.addr[4], &p.addr[5]) != 2) - return false; - break; - - case 17: - if (sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &p.addr[0], &p.addr[1], &p.addr[2], - &p.addr[3], &p.addr[4], &p.addr[5]) != 6) - return false; - break; - - default: - return false; - } - - char buf[128]; - snprintf(buf, sizeof(buf), - "%02x:%02x:%02x:%02x:%02x:%02x", - p.addr[0],p.addr[1],p.addr[2], - p.addr[3],p.addr[4],p.addr[5]); - ns = std::string(buf); - return true; - } - - usrp2::sptr - usrp2::make(const std::string &ifc, const std::string &addr, size_t rx_bufsize) - { - std::string naddr = ""; - if (addr != "" && !parse_mac_addr(addr, naddr)) - throw std::runtime_error("Invalid MAC address"); - - props_vector_t u2s = find(ifc, naddr); - int n = u2s.size(); - - if (n == 0) { - if (addr == "") - throw std::runtime_error("No USRPs found on interface " + ifc); - else - throw std::runtime_error("No USRP found with addr " + addr + " on interface " + ifc); - } - - if (n > 1) - throw std::runtime_error("Multiple USRPs found on interface; must select by MAC address."); - - return find_existing_or_make_new(ifc, &u2s[0], rx_bufsize); - } - - // Private constructor. Sole function is to create an impl. - usrp2::usrp2(const std::string &ifc, props *p, size_t rx_bufsize) - : d_impl(new usrp2::impl(ifc, p, rx_bufsize)) - { - // NOP - } - - // Public class destructor. d_impl will auto-delete. - usrp2::~usrp2() - { - // NOP - } - - std::string - usrp2::mac_addr() - { - return d_impl->mac_addr(); - } - - std::string - usrp2::interface_name() - { - return d_impl->interface_name(); - } - - // Receive - - bool - usrp2::set_rx_antenna(int ant){ - return d_impl->set_rx_antenna(ant); - } - - bool - usrp2::set_rx_gain(double gain) - { - return d_impl->set_rx_gain(gain); - } - - double - usrp2::rx_gain_min() - { - return d_impl->rx_gain_min(); - } - - double - usrp2::rx_gain_max() - { - return d_impl->rx_gain_max(); - } - - double - usrp2::rx_gain_db_per_step() - { - return d_impl->rx_gain_db_per_step(); - } - - bool - usrp2::set_rx_lo_offset(double frequency) - { - return d_impl->set_rx_lo_offset(frequency); - } - - bool - usrp2::set_rx_center_freq(double frequency, tune_result *result) - { - return d_impl->set_rx_center_freq(frequency, result); - } - - double - usrp2::rx_freq_min() - { - return d_impl->rx_freq_min(); - } - - double - usrp2::rx_freq_max() - { - return d_impl->rx_freq_max(); - } - - bool - usrp2::set_rx_decim(int decimation_factor) - { - return d_impl->set_rx_decim(decimation_factor); - } - - int - usrp2::rx_decim() - { - return d_impl->rx_decim(); - } - - bool - usrp2::set_rx_scale_iq(int scale_i, int scale_q) - { - return d_impl->set_rx_scale_iq(scale_i, scale_q); - } - - bool - usrp2::start_rx_streaming(unsigned int channel, unsigned int items_per_frame) - { - return d_impl->start_rx_streaming(channel, items_per_frame); - } - - bool - usrp2::start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time) - { - return d_impl->start_rx_streaming_at(channel, items_per_frame,time); - } - - bool - usrp2::sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time) - { - return d_impl->sync_and_start_rx_streaming_at(channel, items_per_frame, time); - } - - bool - usrp2::rx_samples(unsigned int channel, rx_sample_handler *handler) - { - return d_impl->rx_samples(channel, handler); - } - - bool - usrp2::stop_rx_streaming(unsigned int channel) - { - return d_impl->stop_rx_streaming(channel); - } - - unsigned int - usrp2::rx_overruns() - { - return d_impl->rx_overruns(); - } - - unsigned int - usrp2::rx_missing() - { - return d_impl->rx_missing(); - } - - // Transmit - - bool - usrp2::set_tx_antenna(int ant){ - return d_impl->set_tx_antenna(ant); - } - - bool - usrp2::set_tx_gain(double gain) - { - return d_impl->set_tx_gain(gain); - } - - double - usrp2::tx_gain_min() - { - return d_impl->tx_gain_min(); - } - - double - usrp2::tx_gain_max() - { - return d_impl->tx_gain_max(); - } - - double - usrp2::tx_gain_db_per_step() - { - return d_impl->tx_gain_db_per_step(); - } - - bool - usrp2::set_tx_lo_offset(double frequency) - { - return d_impl->set_tx_lo_offset(frequency); - } - - bool - usrp2::set_tx_center_freq(double frequency, tune_result *result) - { - return d_impl->set_tx_center_freq(frequency, result); - } - - double - usrp2::tx_freq_min() - { - return d_impl->tx_freq_min(); - } - - double - usrp2::tx_freq_max() - { - return d_impl->tx_freq_max(); - } - - - bool - usrp2::set_tx_interp(int interpolation_factor) - { - return d_impl->set_tx_interp(interpolation_factor); - } - - int - usrp2::tx_interp() - { - return d_impl->tx_interp(); - } - - void - usrp2::default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q) - { - d_impl->default_tx_scale_iq(interpolation_factor, scale_i, scale_q); - } - - bool - usrp2::set_tx_scale_iq(int scale_i, int scale_q) - { - return d_impl->set_tx_scale_iq(scale_i, scale_q); - } - - bool - usrp2::tx_32fc(unsigned int channel, - const std::complex<float> *samples, - size_t nsamples, - const tx_metadata *metadata) - { - return d_impl->tx_32fc(channel, samples, nsamples, metadata); - } - - bool - usrp2::tx_16sc(unsigned int channel, - const std::complex<int16_t> *samples, - size_t nsamples, - const tx_metadata *metadata) - { - return d_impl->tx_16sc(channel, samples, nsamples, metadata); - } - - bool - usrp2::tx_raw(unsigned int channel, - const uint32_t *items, - size_t nitems, - const tx_metadata *metadata) - { - return d_impl->tx_raw(channel, items, nitems, metadata); - } - - // miscellaneous methods - - bool - usrp2::config_mimo(int flags) - { - return d_impl->config_mimo(flags); - } - - bool - usrp2::fpga_master_clock_freq(long *freq) - { - return d_impl->fpga_master_clock_freq(freq); - } - - bool - usrp2::adc_rate(long *rate) - { - return d_impl->adc_rate(rate); - } - - bool - usrp2::dac_rate(long *rate) - { - return d_impl->dac_rate(rate); - } - - bool - usrp2::tx_daughterboard_id(int *dbid) - { - return d_impl->tx_daughterboard_id(dbid); - } - - bool - usrp2::rx_daughterboard_id(int *dbid) - { - return d_impl->rx_daughterboard_id(dbid); - } - - - // low level methods - - bool - usrp2::burn_mac_addr(const std::string &new_addr) - { - return d_impl->burn_mac_addr(new_addr); - } - - bool - usrp2::sync_to_pps() - { - return d_impl->sync_to_pps(); - } - - bool - usrp2::sync_every_pps(bool enable) - { - return d_impl->sync_every_pps(enable); - } - - std::vector<uint32_t> - usrp2::peek32(uint32_t addr, uint32_t words) - { - return d_impl->peek32(addr, words); - } - - bool - usrp2::poke32(uint32_t addr, const std::vector<uint32_t> &data) - { - return d_impl->poke32(addr, data); - } - - bool - usrp2::set_gpio_ddr(int bank, uint16_t value, uint16_t mask) - { - return d_impl->set_gpio_ddr(bank, value, mask); - } - - bool - usrp2::set_gpio_sels(int bank, std::string src) - { - return d_impl->set_gpio_sels(bank, src); - } - - bool - usrp2::write_gpio(int bank, uint16_t value, uint16_t mask) - { - return d_impl->write_gpio(bank, value, mask); - } - - bool - usrp2::read_gpio(int bank, uint16_t *value) - { - return d_impl->read_gpio(bank, value); - } - - bool - usrp2::enable_gpio_streaming(int bank, int enable) - { - return d_impl->enable_gpio_streaming(bank, enable); - } - -} // namespace usrp2 - -std::ostream& operator<<(std::ostream &os, const usrp2::props &x) -{ - os << x.addr; - - char buf[128]; - snprintf(buf, sizeof(buf)," hw_rev = 0x%04x", x.hw_rev); - - os << buf; - return os; -} diff --git a/usrp2/host/lib/usrp2_bytesex.h b/usrp2/host/lib/usrp2_bytesex.h deleted file mode 100644 index 4f63d0793..000000000 --- a/usrp2/host/lib/usrp2_bytesex.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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 <gruel/inet.h> diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc deleted file mode 100644 index 333e2d1e7..000000000 --- a/usrp2/host/lib/usrp2_impl.cc +++ /dev/null @@ -1,1667 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2009,2010 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp2/usrp2.h> -#include <usrp2/tune_result.h> -#include <usrp2/copiers.h> -#include <gruel/inet.h> -#include <gruel/realtime.h> -#include <boost/bind.hpp> -#include <usrp2_types.h> -#include "usrp2_impl.h" -#include "eth_buffer.h" -#include "pktfilter.h" -#include "control.h" -#include "ring.h" -#include <stdexcept> -#include <iostream> -#include <stdio.h> -#include <stddef.h> -#include <assert.h> -#include <string.h> - -#define USRP2_IMPL_DEBUG 0 -#if USRP2_IMPL_DEBUG -#define DEBUG_LOG(x) ::write(2, x, 1) -#else -#define DEBUG_LOG(x) -#endif - -static const int DEFAULT_RX_SCALE = 1024; - -namespace usrp2 { - - static const double DEF_CMD_TIMEOUT = 0.1; - - std::string - opcode_to_string(int opcode) - { - switch(opcode){ - case OP_EOP: return "OP_EOP"; - case OP_ID: return "OP_ID"; - case OP_ID_REPLY: return "OP_ID_REPLY"; - case OP_BURN_MAC_ADDR: return "OP_BURN_MAC_ADDR"; - case OP_READ_TIME: return "OP_READ_TIME"; - case OP_READ_TIME_REPLY: return "OP_READ_TIME_REPLY"; - case OP_CONFIG_RX_V2: return "OP_CONFIG_RX_V2"; - case OP_CONFIG_RX_REPLY_V2: return "OP_CONFIG_RX_REPLY_V2"; - case OP_CONFIG_TX_V2: return "OP_CONFIG_TX_V2"; - case OP_CONFIG_TX_REPLY_V2: return "OP_CONFIG_TX_REPLY_V2"; - case OP_START_RX_STREAMING: return "OP_START_RX_STREAMING"; - case OP_STOP_RX: return "OP_STOP_RX"; - case OP_CONFIG_MIMO: return "OP_CONFIG_MIMO"; - case OP_DBOARD_INFO: return "OP_DBOARD_INFO"; - case OP_DBOARD_INFO_REPLY: return "OP_DBOARD_INFO_REPLY"; - case OP_SYNC_TO_PPS: return "OP_SYNC_TO_PPS"; - case OP_PEEK: return "OP_PEEK"; - case OP_PEEK_REPLY: return "OP_PEEK_REPLY"; - case OP_SET_TX_LO_OFFSET: return "OP_SET_TX_LO_OFFSET"; - case OP_SET_TX_LO_OFFSET_REPLY: return "OP_SET_TX_LO_OFFSET_REPLY"; - case OP_SET_RX_LO_OFFSET: return "OP_SET_RX_LO_OFFSET"; - case OP_SET_RX_LO_OFFSET_REPLY: return "OP_SET_RX_LO_OFFSET_REPLY"; - case OP_SYNC_EVERY_PPS: return "OP_SYNC_EVERY_PPS"; - case OP_SYNC_EVERY_PPS_REPLY: return "OP_SYNC_EVERY_PPS_REPLY"; - - default: - char buf[64]; - snprintf(buf, sizeof(buf), "<unknown opcode: %d>", opcode); - return buf; - } - } - - - /*! - * \param p points to fixed header - * \param payload_len_in_bytes is length of the fixed hdr and the payload - * \param[out] items is set to point to the first uint32 item in the payload - * \param[out] nitems is set to the number of uint32 items in the payload - * \param[out] md is filled in with the parsed metadata from the frame. - */ - static bool - parse_rx_metadata(void *p, size_t payload_len_in_bytes, - uint32_t **items, size_t *nitems_in_uint32s, rx_metadata *md) - { - if (payload_len_in_bytes < sizeof(u2_fixed_hdr_t)) // invalid format - return false; - - // FIXME deal with the fact that (p % 4) == 2 - //assert((((uintptr_t) p) % 4) == 0); // must be 4-byte aligned - - u2_fixed_hdr_t *fh = static_cast<u2_fixed_hdr_t *>(p); - - // FIXME unaligned loads! - md->word0 = u2p_word0(fh); - md->timestamp = u2p_timestamp(fh); - - // FIXME when we've got more info - // md->start_of_burst = (md->word0 & XXX) != 0; - // md->end_of_burst = (md->word0 & XXX) != 0; - // md->rx_overrun = (md->word0 & XXX) != 0; - md->start_of_burst = 0; - md->end_of_burst = 0; - md->rx_overrun = 0; - - *items = (uint32_t *)(&fh[1]); - size_t nbytes = payload_len_in_bytes - sizeof(u2_fixed_hdr_t); - assert((nbytes % sizeof(uint32_t)) == 0); - *nitems_in_uint32s = nbytes / sizeof(uint32_t); - - return true; - } - - - usrp2::impl::impl(const std::string &ifc, props *p, size_t rx_bufsize) - : d_eth_buf(new eth_buffer(rx_bufsize)), d_interface_name(ifc), d_pf(0), - d_bg_running(false), d_rx_seqno(-1), d_tx_seqno(0), d_next_rid(0), - d_num_rx_frames(0), d_num_rx_missing(0), d_num_rx_overruns(0), d_num_rx_bytes(0), - d_num_enqueued(0), d_enqueued_mutex(), d_bg_pending_cond(), - d_channel_rings(NCHANS), d_tx_interp(0), d_rx_decim(0), d_dont_enqueue(true) - { - if (!d_eth_buf->open(ifc, htons(U2_ETHERTYPE))) - throw std::runtime_error("Unable to register USRP2 protocol"); - - d_addr = p->addr; - - // Create a packet filter for U2_ETHERTYPE packets sourced from target USRP2 - u2_mac_addr_t usrp_mac; - parse_mac_addr(d_addr, &usrp_mac); - d_pf = pktfilter::make_ethertype_inbound_target(U2_ETHERTYPE, (const unsigned char*)&(usrp_mac.addr)); - if (!d_pf || !d_eth_buf->attach_pktfilter(d_pf)) - throw std::runtime_error("Unable to attach packet filter."); - - if (USRP2_IMPL_DEBUG) - std::cerr << "usrp2 constructor: using USRP2 at " << d_addr << std::endl; - - memset(d_pending_replies, 0, sizeof(d_pending_replies)); - - // Kick off receive thread - start_bg(); - - // In case the USRP2 was left streaming RX - // FIXME: only one channel right now - stop_rx_streaming(0); - - if (!dboard_info()) // we're hosed - throw std::runtime_error("Unable to retrieve daughterboard info"); - - if (0){ - int dbid; - - tx_daughterboard_id(&dbid); - fprintf(stderr, "Tx dboard 0x%x\n", dbid); - fprintf(stderr, " freq_min = %g\n", tx_freq_min()); - fprintf(stderr, " freq_max = %g\n", tx_freq_max()); - fprintf(stderr, " gain_min = %g\n", tx_gain_min()); - fprintf(stderr, " gain_max = %g\n", tx_gain_max()); - fprintf(stderr, " gain_db_per_step = %g\n", tx_gain_db_per_step()); - - rx_daughterboard_id(&dbid); - fprintf(stderr, "Rx dboard 0x%x\n", dbid); - fprintf(stderr, " freq_min = %g\n", rx_freq_min()); - fprintf(stderr, " freq_max = %g\n", rx_freq_max()); - fprintf(stderr, " gain_min = %g\n", rx_gain_min()); - fprintf(stderr, " gain_max = %g\n", rx_gain_max()); - fprintf(stderr, " gain_db_per_step = %g\n", rx_gain_db_per_step()); - } - - // Ensure any custom values in hardware are cleared - if (!reset_db()) - std::cerr << "usrp2::ctor reset_db failed\n"; - - // default gains to mid point - if (!set_tx_gain((tx_gain_min() + tx_gain_max()) / 2)) - std::cerr << "usrp2::ctor set_tx_gain failed\n"; - - if (!set_rx_gain((rx_gain_min() + rx_gain_max()) / 2)) - std::cerr << "usrp2::ctor set_rx_gain failed\n"; - - // default interp and decim - if (!set_tx_interp(12)) - std::cerr << "usrp2::ctor set_tx_interp failed\n"; - - if (!set_rx_decim(12)) - std::cerr << "usrp2::ctor set_rx_decim failed\n"; - - // set workable defaults for scaling - if (!set_rx_scale_iq(DEFAULT_RX_SCALE, DEFAULT_RX_SCALE)) - std::cerr << "usrp2::ctor set_rx_scale_iq failed\n"; - } - - usrp2::impl::~impl() - { - stop_bg(); - delete d_pf; - d_eth_buf->close(); - delete d_eth_buf; - - if (USRP2_IMPL_DEBUG) { - std::cerr << std::endl - << "usrp2 destructor: received " << d_num_rx_frames - << " frames, with " << d_num_rx_missing << " lost (" - << (d_num_rx_frames == 0 ? 0 : (int)(100.0*d_num_rx_missing/d_num_rx_frames)) - << "%), totaling " << d_num_rx_bytes - << " bytes" << std::endl; - } - } - - bool - usrp2::impl::parse_mac_addr(const std::string &s, u2_mac_addr_t *p) - { - p->addr[0] = 0x00; // Matt's IAB - p->addr[1] = 0x50; - p->addr[2] = 0xC2; - p->addr[3] = 0x85; - p->addr[4] = 0x30; - p->addr[5] = 0x00; - - int len = s.size(); - - switch (len){ - - case 5: - return sscanf(s.c_str(), "%hhx:%hhx", &p->addr[4], &p->addr[5]) == 2; - - case 17: - return sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &p->addr[0], &p->addr[1], &p->addr[2], - &p->addr[3], &p->addr[4], &p->addr[5]) == 6; - default: - return false; - } - } - - void - usrp2::impl::init_et_hdrs(u2_eth_packet_t *p, const std::string &dst) - { - p->ehdr.ethertype = htons(U2_ETHERTYPE); - parse_mac_addr(dst, &p->ehdr.dst); - memcpy(&p->ehdr.src, d_eth_buf->mac(), 6); - p->thdr.flags = 0; // FIXME transport header values? - p->thdr.seqno = d_tx_seqno++; - p->thdr.ack = 0; - } - - void - usrp2::impl::init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst, - int word0_flags, int chan, uint32_t timestamp) - { - init_et_hdrs(p, dst); - u2p_set_word0(&p->fixed, word0_flags, chan); - u2p_set_timestamp(&p->fixed, timestamp); - - if (chan == CONTROL_CHAN) { // no sequence numbers, back it out - p->thdr.seqno = 0; - d_tx_seqno--; - } - } - - void - usrp2::impl::init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd) - { - memset(cmd, 0, sizeof(*cmd)); - init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1); - cmd->op.opcode = OP_CONFIG_RX_V2; - cmd->op.len = sizeof(cmd->op); - cmd->op.rid = d_next_rid++; - cmd->eop.opcode = OP_EOP; - cmd->eop.len = sizeof(cmd->eop); - } - - void - usrp2::impl::init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd) - { - memset(cmd, 0, sizeof(*cmd)); - init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1); - cmd->op.opcode = OP_CONFIG_TX_V2; - cmd->op.len = sizeof(cmd->op); - cmd->op.rid = d_next_rid++; - cmd->eop.opcode = OP_EOP; - cmd->eop.len = sizeof(cmd->eop); - } - - - bool - usrp2::impl::transmit_cmd(void *cmd_, size_t len_) - { - const void *cmd = cmd_; - int len = len_; - unsigned char tmp[64]; - - if (len_ < 64){ // pad to minimum ethernet frame size - memset(tmp, 0, sizeof(tmp)); - memcpy(tmp, cmd_, len_); - cmd = tmp; - len = sizeof(tmp); - } - - return d_eth_buf->tx_frame(cmd, len) == eth_buffer::EB_OK; - } - - bool - usrp2::impl::transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs) - { - d_pending_replies[p->rid()] = p; - - if (!transmit_cmd(cmd, len)){ - d_pending_replies[p->rid()] = 0; - return false; - } - - int res = p->wait_for_completion(secs); - d_pending_replies[p->rid()] = 0; - return res == 1; - } - - // ---------------------------------------------------------------- - // Background loop: received packet demuxing - // ---------------------------------------------------------------- - - void - usrp2::impl::start_bg() - { - d_rx_tg.create_thread(boost::bind(&usrp2::impl::bg_loop, this)); - } - - void - usrp2::impl::stop_bg() - { - d_bg_running = false; - d_bg_pending_cond.notify_one(); // FIXME: check if needed - d_rx_tg.join_all(); - } - - void - usrp2::impl::bg_loop() - { - gruel::enable_realtime_scheduling(); - - d_bg_running = true; - while(d_bg_running) { - DEBUG_LOG(":"); - // Receive available frames from ethernet buffer. Handler will - // process control frames, enqueue data packets in channel - // rings, and signal blocked API threads - int res = d_eth_buf->rx_frames(this, 100); // FIXME magic timeout - if (res == eth_buffer::EB_ERROR) - break; - - // Wait for user API thread(s) to process all enqueued packets. - // The channel ring thread that decrements d_num_enqueued to zero - // will signal this thread to continue. - { - gruel::scoped_lock l(d_enqueued_mutex); - while(d_num_enqueued > 0 && d_bg_running) - d_bg_pending_cond.wait(l); - } - } - d_bg_running = false; - } - - // - // passed to eth_buffer::rx_frames - // - data_handler::result - usrp2::impl::operator()(const void *base, size_t len) - { - u2_eth_samples_t *pkt = (u2_eth_samples_t *)base; - - // FIXME unaligned load! - int chan = u2p_chan(&pkt->hdrs.fixed); - - if (chan == CONTROL_CHAN) { // control packets - DEBUG_LOG("c"); - return handle_control_packet(base, len); - } - else { // data packets - - if (d_dont_enqueue) // toss packet - return data_handler::RELEASE; - - return handle_data_packet(base, len); - } - - // not reached - } - - data_handler::result - usrp2::impl::handle_control_packet(const void *base, size_t len) - { - // point to beginning of payload (subpackets) - unsigned char *p = (unsigned char *)base + sizeof(u2_eth_packet_t); - - // FIXME (p % 4) == 2. Not good. Must watch for unaligned loads. - - // FIXME iterate over payload, handling more than a single subpacket. - - int opcode = p[0]; - unsigned int oplen = p[1]; - unsigned int rid = p[2]; - - pending_reply *rp = d_pending_replies[rid]; - if (rp) { - unsigned int buflen = rp->len(); - if (oplen != buflen) { - std::cerr << "usrp2: mismatched command reply length (expected: " - << buflen << " got: " << oplen << "). " - << "op = " << opcode_to_string(opcode) << std::endl; - } - - // Copy reply into caller's buffer - memcpy(rp->buffer(), p, std::min(oplen, buflen)); - rp->notify_completion(); - d_pending_replies[rid] = 0; - return data_handler::RELEASE; - } - - // TODO: handle unsolicited, USRP2 initiated, or late replies - DEBUG_LOG("l"); - return data_handler::RELEASE; - } - - data_handler::result - usrp2::impl::handle_data_packet(const void *base, size_t len) - { - u2_eth_samples_t *pkt = (u2_eth_samples_t *)base; - d_num_rx_frames++; - d_num_rx_bytes += len; - - /* --- FIXME start of fake transport layer handler --- */ - - if (d_rx_seqno != -1) { - int expected_seqno = (d_rx_seqno + 1) & 0xFF; - int seqno = pkt->hdrs.thdr.seqno; - - if (seqno != expected_seqno) { - ::write(2, "S", 1); // missing sequence number - int missing = seqno - expected_seqno; - if (missing < 0) - missing += 256; - - d_num_rx_overruns++; - d_num_rx_missing += missing; - } - } - - d_rx_seqno = pkt->hdrs.thdr.seqno; - - /* --- end of fake transport layer handler --- */ - - // FIXME unaligned load! - unsigned int chan = u2p_chan(&pkt->hdrs.fixed); - - { - gruel::scoped_lock l(d_channel_rings_mutex); - - if (!d_channel_rings[chan]) { - DEBUG_LOG("!"); - return data_handler::RELEASE; // discard packet, no channel handler - } - - // Strip off ethernet header and transport header and enqueue the rest - - size_t offset = offsetof(u2_eth_samples_t, hdrs.fixed); - if (d_channel_rings[chan]->enqueue(&pkt->hdrs.fixed, len-offset)) { - inc_enqueued(); - DEBUG_LOG("+"); - return data_handler::KEEP; // channel ring runner will mark frame done - } - else { - DEBUG_LOG("!"); - return data_handler::RELEASE; // discard, no room in channel ring - } - return data_handler::RELEASE; - } - } - - - // ---------------------------------------------------------------- - // Receive - // ---------------------------------------------------------------- - - bool - usrp2::impl::set_rx_antenna(int ant){ - op_config_mimo_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_RX_ANTENNA; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.flags = ant; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - return ntohx(reply.ok) == 1; - } - - bool - usrp2::impl::set_rx_gain(double gain) - { - op_config_rx_v2_cmd cmd; - op_config_rx_reply_v2_t reply; - - init_config_rx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_GAIN); - cmd.op.gain = htons(u2_double_to_fxpt_gain(gain)); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool - usrp2::impl::set_rx_lo_offset(double frequency) - { - op_freq_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_SET_RX_LO_OFFSET; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - - u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency); - cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt)); - cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt)); - - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool - usrp2::impl::set_rx_center_freq(double frequency, tune_result *result) - { - op_config_rx_v2_cmd cmd; - op_config_rx_reply_v2_t reply; - - init_config_rx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_FREQ); - u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency); - cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt)); - cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt)); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - if (result && success) { - result->baseband_freq = - u2_fxpt_freq_to_double( - u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi), - ntohl(reply.baseband_freq_lo))); - - result->dxc_freq = - u2_fxpt_freq_to_double( - u2_fxpt_freq_from_hilo(ntohl(reply.ddc_freq_hi), - ntohl(reply.ddc_freq_lo))); - - result->residual_freq = - u2_fxpt_freq_to_double( - u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi), - ntohl(reply.residual_freq_lo))); - - result->spectrum_inverted = (bool)(ntohx(reply.inverted) == 1); - } - - return success; - } - - bool - usrp2::impl::set_rx_decim(int decimation_factor) - { - op_config_rx_v2_cmd cmd; - op_config_rx_reply_v2_t reply; - - init_config_rx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_INTERP_DECIM); - cmd.op.decim = htonl(decimation_factor); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - if (success) - d_rx_decim = decimation_factor; - return success; - } - - bool - usrp2::impl::set_rx_scale_iq(int scale_i, int scale_q) - { - op_config_rx_v2_cmd cmd; - op_config_rx_reply_v2_t reply; - - init_config_rx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_SCALE_IQ); - cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff)); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool - usrp2::impl::start_rx_streaming(unsigned int channel, unsigned int items_per_frame) - { - if (channel > MAX_CHAN) { - std::cerr << "usrp2: invalid channel number (" << channel - << ")" << std::endl; - return false; - } - - if (channel > 0) { // until firmware supports multiple streams - std::cerr << "usrp2: channel " << channel - << " not implemented" << std::endl; - return false; - } - - { - gruel::scoped_lock l(d_channel_rings_mutex); - if (d_channel_rings[channel]) { - std::cerr << "usrp2: channel " << channel - << " already streaming" << std::endl; - return false; - } - - if (items_per_frame == 0) - items_per_frame = U2_MAX_SAMPLES; // minimize overhead - - op_start_rx_streaming_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_START_RX_STREAMING; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.items_per_frame = htonl(items_per_frame); - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - d_dont_enqueue = false; - bool success = false; - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT); - success = success && (ntohx(reply.ok) == 1); - - if (success) - d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames())); - else - d_dont_enqueue = true; - - //fprintf(stderr, "usrp2::start_rx_streaming: success = %d\n", success); - return success; - } - } - - bool - usrp2::impl::start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time) - { - if (channel > MAX_CHAN) { - std::cerr << "usrp2: invalid channel number (" << channel - << ")" << std::endl; - return false; - } - - if (channel > 0) { // until firmware supports multiple streams - std::cerr << "usrp2: channel " << channel - << " not implemented" << std::endl; - return false; - } - - { - gruel::scoped_lock guard(d_channel_rings_mutex); - if (d_channel_rings[channel]) { - std::cerr << "usrp2: channel " << channel - << " already streaming" << std::endl; - return false; - } - - if (items_per_frame == 0) - items_per_frame = U2_MAX_SAMPLES; // minimize overhead - - op_start_rx_streaming_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, time); - cmd.op.opcode = OP_START_RX_STREAMING; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.items_per_frame = htonl(items_per_frame); - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - d_dont_enqueue = false; - bool success = false; - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT); - success = success && (ntohx(reply.ok) == 1); - - if (success) - d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames())); - else - d_dont_enqueue = true; - - return success; - } - } - - bool - usrp2::impl::sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time) - { - - if (channel > MAX_CHAN) { - std::cerr << "usrp2: invalid channel number (" << channel - << ")" << std::endl; - return false; - } - - if (channel > 0) { // until firmware supports multiple streams - std::cerr << "usrp2: channel " << channel - << " not implemented" << std::endl; - return false; - } - - { - gruel::scoped_lock guard(d_channel_rings_mutex); - if (d_channel_rings[channel]) { - std::cerr << "usrp2: channel " << channel - << " already streaming" << std::endl; - return false; - } - - if (items_per_frame == 0) - items_per_frame = U2_MAX_SAMPLES; // minimize overhead - - op_sync_and_start_rx_streaming_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, time); - cmd.sync_op.opcode = OP_SYNC_TO_PPS; - cmd.sync_op.len = sizeof(cmd.sync_op); - cmd.sync_op.rid = d_next_rid++; - cmd.rx_op.opcode = OP_START_RX_STREAMING; - cmd.rx_op.len = sizeof(cmd.rx_op); - cmd.rx_op.rid = d_next_rid++; - cmd.rx_op.items_per_frame = htonl(items_per_frame); - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - d_dont_enqueue = false; - bool success = false; - pending_reply p(cmd.sync_op.rid, &reply, sizeof(reply)); - success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT); - success = success && (ntohx(reply.ok) == 1); - - if (success) - d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames())); - else - d_dont_enqueue = true; - - return success; - } - } - - bool - usrp2::impl::stop_rx_streaming(unsigned int channel) - { - if (channel > MAX_CHAN) { - std::cerr << "usrp2: invalid channel number (" << channel - << ")" << std::endl; - return false; - } - - if (channel > 0) { // until firmware supports multiple streams - std::cerr << "usrp2: channel " << channel - << " not implemented" << std::endl; - return false; - } - - d_dont_enqueue = true; // no new samples - flush_rx_samples(channel); // dump any we may already have - - op_stop_rx_cmd cmd; - op_generic_t reply; - - { - gruel::scoped_lock l(d_channel_rings_mutex); - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_STOP_RX; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - bool success = false; - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT); - success = success && (ntohx(reply.ok) == 1); - d_channel_rings[channel].reset(); - d_rx_seqno = -1; - //fprintf(stderr, "usrp2::stop_rx_streaming: success = %d\n", success); - return success; - } - } - - bool - usrp2::impl::rx_samples(unsigned int channel, rx_sample_handler *handler) - { - if (channel > MAX_CHAN) { - std::cerr << "usrp2: invalid channel (" << channel - << " )" << std::endl; - return false; - } - - if (channel > 0) { - std::cerr << "usrp2: channel " << channel - << " not implemented" << std::endl; - return false; - } - - ring_sptr rp = d_channel_rings[channel]; - if (!rp){ - std::cerr << "usrp2: channel " << channel - << " not receiving" << std::endl; - return false; - } - - // Wait for frames available in channel ring - DEBUG_LOG("W"); - rp->wait_for_not_empty(); - DEBUG_LOG("s"); - - // Iterate through frames and present to user - void *p; - size_t frame_len_in_bytes; - while (rp->dequeue(&p, &frame_len_in_bytes)) { - uint32_t *items; // points to beginning of data items - size_t nitems_in_uint32s; - rx_metadata md; - if (!parse_rx_metadata(p, frame_len_in_bytes, &items, &nitems_in_uint32s, &md)) - return false; - - bool want_more = (*handler)(items, nitems_in_uint32s, &md); - d_eth_buf->release_frame(p); - DEBUG_LOG("-"); - dec_enqueued(); - - if (!want_more) - break; - } - return true; - } - - bool - usrp2::impl::flush_rx_samples(unsigned int channel) - { - if (channel > MAX_CHAN) { - std::cerr << "usrp2: invalid channel (" << channel - << " )" << std::endl; - return false; - } - - if (channel > 0) { - std::cerr << "usrp2: channel " << channel - << " not implemented" << std::endl; - return false; - } - - ring_sptr rp = d_channel_rings[channel]; - if (!rp){ - return false; - } - - // Iterate through frames and drop them - void *p; - size_t frame_len_in_bytes; - while (rp->dequeue(&p, &frame_len_in_bytes)) { - d_eth_buf->release_frame(p); - dec_enqueued(); - } - return true; - } - - // ---------------------------------------------------------------- - // Transmit - // ---------------------------------------------------------------- - - bool - usrp2::impl::set_tx_antenna(int ant){ - op_config_mimo_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_TX_ANTENNA; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.flags = ant; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - return ntohx(reply.ok) == 1; - } - - bool - usrp2::impl::set_tx_gain(double gain) - { - op_config_tx_v2_cmd cmd; - op_config_tx_reply_v2_t reply; - - init_config_tx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_GAIN); - cmd.op.gain = htons(u2_double_to_fxpt_gain(gain)); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool - usrp2::impl::set_tx_lo_offset(double frequency) - { - op_freq_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_SET_TX_LO_OFFSET; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - - u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency); - cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt)); - cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt)); - - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool - usrp2::impl::set_tx_center_freq(double frequency, tune_result *result) - { - op_config_tx_v2_cmd cmd; - op_config_tx_reply_v2_t reply; - - init_config_tx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_FREQ); - u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency); - cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt)); - cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt)); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - if (result && success) { - result->baseband_freq = - u2_fxpt_freq_to_double( - u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi), - ntohl(reply.baseband_freq_lo))); - - result->dxc_freq = - u2_fxpt_freq_to_double( - u2_fxpt_freq_from_hilo(ntohl(reply.duc_freq_hi), - ntohl(reply.duc_freq_lo))); - - result->residual_freq = - u2_fxpt_freq_to_double( - u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi), - ntohl(reply.residual_freq_lo))); - - result->spectrum_inverted = (bool)(ntohx(reply.inverted) == 1); - } - - return success; - } - - bool - usrp2::impl::set_tx_interp(int interpolation_factor) - { - op_config_tx_v2_cmd cmd; - op_config_tx_reply_v2_t reply; - - init_config_tx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_INTERP_DECIM); - cmd.op.interp = htonl(interpolation_factor); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - if (success) { - d_tx_interp = interpolation_factor; - - // Auto-set TX scaling based on interpolation rate - int scale_i, scale_q; - default_tx_scale_iq(d_tx_interp, &scale_i, &scale_q); - return set_tx_scale_iq(scale_i, scale_q); - } - - return success; - } - - void - usrp2::impl::default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q) - { - // Calculate CIC interpolation (i.e., without halfband interpolators) - int i = interpolation_factor; - if (i > 128) - i = i >> 1; - if (i > 128) - i = i >> 1; - - // Calculate dsp_core_tx gain absent scale multipliers - float gain = (1.65*i*i*i)/(4096*pow(2, ceil(log2(i*i*i)))); - - // Calculate closest multiplier constant to reverse gain - int scale = (int)rint(1.0/gain); - // fprintf(stderr, "if=%i i=%i gain=%f scale=%i\n", interpolation_factor, i, gain, scale); - - // Both I and Q are identical in this case - if (scale_i) - *scale_i = scale; - if (scale_q) - *scale_q = scale; - } - - bool - usrp2::impl::set_tx_scale_iq(int scale_i, int scale_q) - { - op_config_tx_v2_cmd cmd; - op_config_tx_reply_v2_t reply; - - init_config_tx_v2_cmd(&cmd); - cmd.op.valid = htons(CFGV_SCALE_IQ); - cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff)); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool - usrp2::impl::tx_32fc(unsigned int channel, - const std::complex<float> *samples, - size_t nsamples, - const tx_metadata *metadata) - { - uint32_t items[nsamples]; - copy_host_32fc_to_u2_16sc(nsamples, samples, items); - return tx_raw(channel, items, nsamples, metadata); - } - - bool - usrp2::impl::tx_16sc(unsigned int channel, - const std::complex<int16_t> *samples, - size_t nsamples, - const tx_metadata *metadata) - { -#ifdef WORDS_BIGENDIAN - - // Already binary equivalent to 16-bit I/Q on the wire. - // No conversion required. - - assert(sizeof(samples[0]) == sizeof(uint32_t)); - return tx_raw(channel, (const uint32_t *) samples, nsamples, metadata); - -#else - - uint32_t items[nsamples]; - copy_host_16sc_to_u2_16sc(nsamples, samples, items); - return tx_raw(channel, items, nsamples, metadata); - -#endif - } - - bool - usrp2::impl::tx_raw(unsigned int channel, - const uint32_t *items, - size_t nitems, - const tx_metadata *metadata) - { - if (nitems == 0) - return true; - - // FIXME can't deal with nitems < U2_MIN_SAMPLES (will be fixed in VRT) - // FIXME need to check the MTU instead of assuming 1500 bytes - - // fragment as necessary then fire away - - size_t nframes = (nitems + U2_MAX_SAMPLES - 1) / U2_MAX_SAMPLES; - size_t last_frame = nframes - 1; - u2_eth_packet_t hdrs; - - size_t n = 0; - for (size_t fn = 0; fn < nframes; fn++){ - uint32_t timestamp = 0; - uint32_t flags = 0; - - if (fn == 0){ - timestamp = metadata->timestamp; - if (metadata->send_now) - flags |= U2P_TX_IMMEDIATE; - if (metadata->start_of_burst) - flags |= U2P_TX_START_OF_BURST; - } - if (fn > 0){ - flags |= U2P_TX_IMMEDIATE; - } - if (fn == last_frame){ - if (metadata->end_of_burst) - flags |= U2P_TX_END_OF_BURST; - } - - init_etf_hdrs(&hdrs, d_addr, flags, channel, timestamp); - - // Avoid short packet by splitting last two packets if reqd - size_t i; - if ((nitems - n) > U2_MAX_SAMPLES && (nitems - n) < (U2_MAX_SAMPLES + U2_MIN_SAMPLES)) - i = (nitems - n) / 2; - else - i = std::min((size_t) U2_MAX_SAMPLES, nitems - n); - - eth_iovec iov[2]; - iov[0].iov_base = &hdrs; - iov[0].iov_len = sizeof(hdrs); - iov[1].iov_base = const_cast<uint32_t *>(&items[n]); - iov[1].iov_len = i * sizeof(uint32_t); - - size_t total = iov[0].iov_len + iov[1].iov_len; - if (total < 64) - fprintf(stderr, "usrp2::tx_raw: FIXME: short packet: %zd items (%zd bytes)\n", i, total); - - if (d_eth_buf->tx_framev(iov, 2) != eth_buffer::EB_OK){ - return false; - } - - n += i; - } - - return true; - } - - // ---------------------------------------------------------------- - // misc commands - // ---------------------------------------------------------------- - - bool - usrp2::impl::config_mimo(int flags) - { - op_config_mimo_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_CONFIG_MIMO; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.flags = flags; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - return ntohx(reply.ok) == 1; - } - - bool - usrp2::impl::fpga_master_clock_freq(long *freq) - { - *freq = 100000000L; // 100 MHz - return true; - } - - bool - usrp2::impl::adc_rate(long *rate) - { - return fpga_master_clock_freq(rate); - } - - bool - usrp2::impl::dac_rate(long *rate) - { - return fpga_master_clock_freq(rate); - } - - bool - usrp2::impl::tx_daughterboard_id(int *dbid) - { - *dbid = d_tx_db_info.dbid; - return true; - } - - bool - usrp2::impl::rx_daughterboard_id(int *dbid) - { - *dbid = d_rx_db_info.dbid; - return true; - } - - - // ---------------------------------------------------------------- - // low-level commands - // ---------------------------------------------------------------- - - bool - usrp2::impl::burn_mac_addr(const std::string &new_addr) - { - op_burn_mac_addr_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_BURN_MAC_ADDR; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - if (!parse_mac_addr(new_addr, &cmd.op.addr)) - return false; - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, 4*DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - static void - fill_dboard_info(db_info *dst, const u2_db_info_t *src) - { - dst->dbid = ntohl(src->dbid); - - dst->freq_min = - u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_min_hi), - ntohl(src->freq_min_lo))); - dst->freq_max = - u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_max_hi), - ntohl(src->freq_max_lo))); - - dst->gain_min = u2_fxpt_gain_to_double(ntohs(src->gain_min)); - dst->gain_max = u2_fxpt_gain_to_double(ntohs(src->gain_max)); - dst->gain_step_size = u2_fxpt_gain_to_double(ntohs(src->gain_step_size)); - } - - bool - usrp2::impl::dboard_info() - { - op_dboard_info_cmd cmd; - op_dboard_info_reply_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_DBOARD_INFO; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - if (success){ - fill_dboard_info(&d_tx_db_info, &reply.tx_db_info); - fill_dboard_info(&d_rx_db_info, &reply.rx_db_info); - } - return success; - } - - - bool - usrp2::impl::sync_to_pps() - { - op_generic_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_SYNC_TO_PPS; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - return ntohx(reply.ok) == 1; - } - - bool - usrp2::impl::sync_every_pps(bool enable) - { - op_generic_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_SYNC_EVERY_PPS; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.ok = enable ? 1 : 0; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - return ntohx(reply.ok) == 1; - } - - std::vector<uint32_t> - usrp2::impl::peek32(uint32_t addr, uint32_t words) - { - std::vector<uint32_t> result; // zero sized on error return - // fprintf(stderr, "usrp2::peek: addr=%08X words=%u\n", addr, words); - - if (addr % 4 != 0) { - fprintf(stderr, "usrp2::peek: addr (=%08X) must be 32-bit word aligned\n", addr); - return result; - } - - if (words == 0) - return result; - - op_peek_cmd cmd; - op_generic_t *reply; - - int wlen = sizeof(uint32_t); - int rlen = sizeof(op_generic_t); - size_t bytes = words*wlen; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_PEEK; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - cmd.op.addr = htonl(addr); - cmd.op.bytes = htonl(bytes); - - reply = (op_generic_t *)malloc(rlen+bytes); - pending_reply p(cmd.op.rid, reply, rlen+bytes); - if (transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) { - uint32_t nwords = (reply->len-rlen)/sizeof(uint32_t); - uint32_t *data = (uint32_t *)(reply+rlen/wlen); - for (unsigned int i = 0; i < nwords; i++) - result.push_back(ntohl(data[i])); - } - - free(reply); - return result; - } - - bool - usrp2::impl::poke32(uint32_t addr, const std::vector<uint32_t> &data) - { - if (addr % 4 != 0) { - fprintf(stderr, "usrp2::poke32: addr (=%08X) must be 32-bit word aligned\n", addr); - return false; - } - - int plen = sizeof(op_poke_cmd); - int wlen = sizeof(uint32_t); - int max_words = (MAX_SUBPKT_LEN-plen)/wlen; - int words = data.size(); - - if (words > max_words) { - fprintf(stderr, "usrp2::poke32: write size (=%u) exceeds maximum of %u words\n", - words, max_words); - return false; - } - - //fprintf(stderr, "usrp2::poke32: addr=%08X words=%u\n", addr, words); - - if (words == 0) - return true; // NOP - - op_poke_cmd *cmd; - op_generic_t *eop; - - // Allocate, clear, and initialize command packet - int bytes = words*wlen; - int l = plen+bytes+sizeof(*eop); // op_poke_cmd+data+eop - cmd = (op_poke_cmd *)malloc(l); - //fprintf(stderr, "cmd=%p l=%i\n", cmd, l); - memset(cmd, 0, l); - init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1); - cmd->op.opcode = OP_POKE; - cmd->op.len = sizeof(cmd->op)+bytes; - cmd->op.rid = d_next_rid++; - cmd->op.addr = htonl(addr); - - // Copy data from vector into packet space - uint32_t *dest = (uint32_t *)((uint8_t *)cmd+plen); - for (int i = 0; i < words; i++) { - //fprintf(stderr, "%03i@%p\n", i, dest); - *dest++ = htonl(data[i]); - } - - // Write end-of-packet subpacket - eop = (op_generic_t *)dest; - eop->opcode = OP_EOP; - eop->len = sizeof(*eop); - //fprintf(stderr, "eop=%p len=%i\n", eop, eop->len); - - // Send command to device and retrieve reply - bool ok = false; - op_generic_t reply; - pending_reply p(cmd->op.rid, &reply, sizeof(reply)); - if (transmit_cmd_and_wait(cmd, l, &p, DEF_CMD_TIMEOUT)) - ok = (ntohx(reply.ok) == 1); - - free(cmd); - return ok; - } - - bool - usrp2::impl::reset_db() - { - op_generic_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_RESET_DB; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool usrp2::impl::set_gpio_ddr(int bank, uint16_t value, uint16_t mask) - { - if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) { - fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n"); - return false; - } - - op_gpio_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_GPIO_SET_DDR; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.bank = static_cast<uint8_t>(bank); - cmd.op.value = htons(value); - cmd.op.mask = htons(mask); - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool usrp2::impl::set_gpio_sels(int bank, std::string sels) - { - if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) { - fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n"); - return false; - } - - if (sels.size() != 16) { - fprintf(stderr, "set_gpio_sels: sels must be exactly 16 bytes\n"); - return false; - } - - op_gpio_set_sels_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_GPIO_SET_SELS; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.bank = static_cast<uint8_t>(bank); - memcpy(&cmd.op.sels, sels.c_str(), 16); - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool usrp2::impl::write_gpio(int bank, uint16_t value, uint16_t mask) - { - if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) { - fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n"); - return false; - } - - op_gpio_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_GPIO_WRITE; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.bank = static_cast<uint8_t>(bank); - cmd.op.value = htons(value); - cmd.op.mask = htons(mask); - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - - bool usrp2::impl::read_gpio(int bank, uint16_t *value) - { - if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) { - fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n"); - return false; - } - - op_gpio_cmd cmd; - op_gpio_read_reply_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_GPIO_READ; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.bank = static_cast<uint8_t>(bank); - cmd.op.value = 0; // not used - cmd.op.mask = 0; // not used - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - if (success && (value != NULL)) - *value = ntohs(reply.value); - - return success; - } - - bool usrp2::impl::enable_gpio_streaming(int bank, int enable) - { - if (bank != GPIO_RX_BANK) { - fprintf(stderr, "enable_gpio_streaming: only RX streaming is currently implemented\n"); - return false; - } - - if ((enable & ~0x03) != 0) { - fprintf(stderr, "enable_gpio_streaming: invalid enable format\n"); - return false; - } - - op_gpio_cmd cmd; - op_generic_t reply; - - memset(&cmd, 0, sizeof(cmd)); - init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1); - cmd.op.opcode = OP_GPIO_STREAM; - cmd.op.len = sizeof(cmd.op); - cmd.op.rid = d_next_rid++; - cmd.op.bank = static_cast<uint8_t>(bank); - cmd.op.value = htons((uint16_t)enable); - cmd.op.mask = 0; // not used - cmd.eop.opcode = OP_EOP; - cmd.eop.len = sizeof(cmd.eop); - - pending_reply p(cmd.op.rid, &reply, sizeof(reply)); - if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) - return false; - - bool success = (ntohx(reply.ok) == 1); - return success; - } - -} // namespace usrp2 diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h deleted file mode 100644 index eee26358e..000000000 --- a/usrp2/host/lib/usrp2_impl.h +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2009,2010 Free Software Foundation, Inc. - * - * 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/>. - */ - -#ifndef INCLUDED_USRP2_IMPL_H -#define INCLUDED_USRP2_IMPL_H - -#include <usrp2/usrp2.h> -#include <usrp2/data_handler.h> -#include <usrp2_eth_packet.h> -#include <gruel/thread.h> -#include <boost/scoped_ptr.hpp> -#include "control.h" -#include "ring.h" -#include <string> - -#define MAX_SUBPKT_LEN 252 - -namespace usrp2 { - - class eth_buffer; - class pktfilter; - class usrp2_thread; - class usrp2_tune_result; - class pending_reply; - class ring; - - //! High-level d'board info - struct db_info { - int dbid; - double freq_min; // Hz - double freq_max; // Hz - double gain_min; // dB - double gain_max; // dB - double gain_step_size; // dB - - db_info() : dbid(-1), freq_min(0), freq_max(0), - gain_min(0), gain_max(0), gain_step_size(0) {} - }; - - class usrp2::impl : private data_handler - { - static const size_t NRIDS = 256; - static const size_t NCHANS = 32; - - eth_buffer *d_eth_buf; - std::string d_interface_name; - pktfilter *d_pf; - std::string d_addr; // FIXME: use u2_mac_addr_t instead - - boost::thread_group d_rx_tg; - volatile bool d_bg_running; // TODO: multistate if needed - - int d_rx_seqno; - int d_tx_seqno; - int d_next_rid; - unsigned int d_num_rx_frames; - unsigned int d_num_rx_missing; - unsigned int d_num_rx_overruns; - unsigned int d_num_rx_bytes; - - unsigned int d_num_enqueued; - gruel::mutex d_enqueued_mutex; - gruel::condition_variable d_bg_pending_cond; - - // all pending_replies are stack allocated, thus no possibility of leaking these - pending_reply *d_pending_replies[NRIDS]; // indexed by 8-bit reply id - - std::vector<ring_sptr> d_channel_rings; // indexed by 5-bit channel number - gruel::mutex d_channel_rings_mutex; - - db_info d_tx_db_info; - db_info d_rx_db_info; - - int d_tx_interp; // shadow tx interp - int d_rx_decim; // shadow rx decim - - bool d_dont_enqueue; - - void inc_enqueued() { - gruel::scoped_lock l(d_enqueued_mutex); - d_num_enqueued++; - } - - void dec_enqueued() { - gruel::scoped_lock l(d_enqueued_mutex); - if (--d_num_enqueued == 0) - d_bg_pending_cond.notify_one(); - } - - static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p); - void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst); - void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst, - int word0_flags, int chan, uint32_t timestamp); - void start_bg(); - void stop_bg(); - void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd); - void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd); - bool transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs=0.0); - bool transmit_cmd(void *cmd, size_t len); - virtual data_handler::result operator()(const void *base, size_t len); - data_handler::result handle_control_packet(const void *base, size_t len); - data_handler::result handle_data_packet(const void *base, size_t len); - bool dboard_info(); - bool reset_db(); - - public: - impl(const std::string &ifc, props *p, size_t rx_bufsize); - ~impl(); - - std::string mac_addr() const { return d_addr; } // FIXME: convert from u2_mac_addr_t - std::string interface_name() const { return d_interface_name; } - - // Rx - - bool set_rx_antenna(int ant); - bool set_rx_gain(double gain); - double rx_gain_min() { return d_rx_db_info.gain_min; } - double rx_gain_max() { return d_rx_db_info.gain_max; } - double rx_gain_db_per_step() { return d_rx_db_info.gain_step_size; } - bool set_rx_lo_offset(double frequency); - bool set_rx_center_freq(double frequency, tune_result *result); - double rx_freq_min() { return d_rx_db_info.freq_min; } - double rx_freq_max() { return d_rx_db_info.freq_max; } - bool set_rx_decim(int decimation_factor); - int rx_decim() { return d_rx_decim; } - bool set_rx_scale_iq(int scale_i, int scale_q); - bool set_gpio_ddr(int bank, uint16_t value, uint16_t mask); - bool set_gpio_sels(int bank, std::string src); - bool enable_gpio_streaming(int bank, int enable); - bool write_gpio(int bank, uint16_t value, uint16_t mask); - bool read_gpio(int bank, uint16_t *value); - bool start_rx_streaming(unsigned int channel, unsigned int items_per_frame); - bool start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time); - bool sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time); - bool rx_samples(unsigned int channel, rx_sample_handler *handler); - bool flush_rx_samples(unsigned int channel); - bool stop_rx_streaming(unsigned int channel); - unsigned int rx_overruns() const { return d_num_rx_overruns; } - unsigned int rx_missing() const { return d_num_rx_missing; } - - // Tx - - bool set_tx_antenna(int ant); - bool set_tx_gain(double gain); - double tx_gain_min() { return d_tx_db_info.gain_min; } - double tx_gain_max() { return d_tx_db_info.gain_max; } - double tx_gain_db_per_step() { return d_tx_db_info.gain_step_size; } - bool set_tx_lo_offset(double frequency); - bool set_tx_center_freq(double frequency, tune_result *result); - double tx_freq_min() { return d_tx_db_info.freq_min; } - double tx_freq_max() { return d_tx_db_info.freq_max; } - bool set_tx_interp(int interpolation_factor); - int tx_interp() { return d_tx_interp; } - void default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q); - bool set_tx_scale_iq(int scale_i, int scale_q); - - bool tx_32fc(unsigned int channel, - const std::complex<float> *samples, - size_t nsamples, - const tx_metadata *metadata); - - bool tx_16sc(unsigned int channel, - const std::complex<int16_t> *samples, - size_t nsamples, - const tx_metadata *metadata); - - bool tx_raw(unsigned int channel, - const uint32_t *items, - size_t nitems, - const tx_metadata *metadata); - - // misc - - bool config_mimo(int flags); - bool fpga_master_clock_freq(long *freq); - bool adc_rate(long *rate); - bool dac_rate(long *rate); - bool tx_daughterboard_id(int *dbid); - bool rx_daughterboard_id(int *dbid); - - // low level - - bool burn_mac_addr(const std::string &new_addr); - bool sync_to_pps(); - bool sync_every_pps(bool enable); - std::vector<uint32_t> peek32(uint32_t addr, uint32_t words); - bool poke32(uint32_t addr, const std::vector<uint32_t> &data); - - // Receive thread, need to be public for boost::bind - void bg_loop(); - }; - -} // namespace usrp2 - -#endif /* INCLUDED_USRP2_IMPL_H */ diff --git a/usrp2/host/lib/usrp2_socket_opener.cc b/usrp2/host/lib/usrp2_socket_opener.cc deleted file mode 100644 index 27d3935e4..000000000 --- a/usrp2/host/lib/usrp2_socket_opener.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * 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/>. - */ - -/*! - * setuid root program that opens a socket using (PF_PACKET, SOCK_RAW, - * htons(0xBEEF)), and sends the resulting file descriptor by way of - * of the file descriptor specified as the first command line argument. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <sys/types.h> -#include <sys/socket.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#elif defined(HAVE_NETINET_IN_H) -#include <netinet/in.h> -#endif - - -ssize_t -write_fd(int fd, const void *ptr, size_t nbytes, int sendfd) -{ - struct msghdr msg; - struct iovec iov[1]; - -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(int))]; - } control_un; - struct cmsghdr *cmptr; - - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - cmptr = CMSG_FIRSTHDR(&msg); - cmptr->cmsg_len = CMSG_LEN(sizeof(int)); - cmptr->cmsg_level = SOL_SOCKET; - cmptr->cmsg_type = SCM_RIGHTS; - *((int *) CMSG_DATA(cmptr)) = sendfd; -#else - msg.msg_accrights = (char *) &sendfd; - msg.msg_accrightslen = sizeof(int); -#endif - - msg.msg_name = NULL; - msg.msg_namelen = 0; - - iov[0].iov_base = const_cast<void *>(ptr); - iov[0].iov_len = nbytes; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - - return sendmsg(fd, &msg, 0); -} - -bool -reset_eids() -{ - if (setgid(getgid()) < 0){ - perror("setguid"); - return false; - } - - if (setuid(getuid()) < 0){ - perror("setuid"); - return false; - } - - return true; -} - - -static void -usage() -{ - fprintf(stderr, "usage: usrp2_socket_opener file-descriptor\n"); - exit(1); -} - -int -main(int argc, char **argv) -{ - if (argc != 2) - usage(); - - char *endptr; - int unix_domain_fd = strtol(argv[1], &endptr, 0); - if (*endptr != 0) - usage(); - - // FIXME get client credentials from unix_domain_fd using SCM_CREDENTIALS - - // open the raw socket - int socket_fd = socket(PF_PACKET, SOCK_RAW, htons(0xBEEF)); - if (socket_fd == -1){ - perror("socket(PF_PACKET, SOCK_RAW, htons(0xBEEF))"); - // printf("errno = %d\n", errno); - if (errno == EACCES || errno == ESPIPE){ - fprintf(stderr, "usrp2_socket_opener must be setuid root to open the socket using SOCK_RAW.\n"); - fprintf(stderr, "Running as root, please execute: \n"); - fprintf(stderr, " # chown root:usrp usrp2_socket_opener\n"); - fprintf(stderr, " # chmod 04750 usrp2_socket_opener\n"); - } - exit(2); - } - - // drop privs - if (!reset_eids()){ - fprintf(stderr, "Can't drop root permissions\n"); - exit(3); - } - - if (write_fd(unix_domain_fd, "", 1, socket_fd) != 1){ - perror("write_fd"); - exit(4); - } - - return 0; -} diff --git a/usrp2/host/usrp2.pc.in b/usrp2/host/usrp2.pc.in deleted file mode 100644 index 0c862a877..000000000 --- a/usrp2/host/usrp2.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: usrp2 -Description: Universal Software Radio Peripheral 2 -Requires: gruel -Version: @LIBVER@ -Libs: -L${libdir} -lusrp2 -Cflags: -I${includedir} @DEFINES@ |