diff options
Diffstat (limited to 'usrp/host/lib/inband')
35 files changed, 0 insertions, 7826 deletions
diff --git a/usrp/host/lib/inband/Makefile.am b/usrp/host/lib/inband/Makefile.am deleted file mode 100644 index 650a25ff9..000000000 --- a/usrp/host/lib/inband/Makefile.am +++ /dev/null @@ -1,114 +0,0 @@ -# -# Copyright 2007,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 - -AM_CPPFLAGS = \ - $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \ - $(USRP_INCLUDES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \ - -I$(srcdir)/../../apps-inband $(WITH_INCLUDES) - -TESTS = test_inband - -EXTRA_DIST = \ - usrp_server.mbh \ - usrp_interface.mbh - -lib_LTLIBRARIES = \ - libusrp-inband.la \ - libusrp-inband-qa.la - -# ------------------------------------------------------------------------ -# Build the inband library - -BUILT_SOURCES = \ - usrp_server_mbh.cc \ - usrp_interface_mbh.cc - -usrp_server_mbh.cc : usrp_server.mbh - $(COMPILE_MBH) $(srcdir)/usrp_server.mbh usrp_server_mbh.cc - -usrp_interface_mbh.cc : usrp_interface.mbh - $(COMPILE_MBH) $(srcdir)/usrp_interface.mbh usrp_interface_mbh.cc - -libusrp_inband_la_SOURCES = \ - $(BUILT_SOURCES) \ - $(srcdir)/../../apps-inband/ui_sincos.c \ - usrp_inband_usb_packet.cc \ - usrp_rx.cc \ - usrp_rx_stub.cc \ - usrp_server.cc \ - usrp_tx.cc \ - usrp_tx_stub.cc \ - usrp_usb_interface.cc - -libusrp_inband_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 - -libusrp_inband_la_LIBADD = \ - $(MBLOCK_LA) \ - $(USRP_LA) \ - -lstdc++ - -include_HEADERS = \ - usrp_inband_usb_packet.h \ - usrp_rx.h \ - usrp_rx_stub.h \ - usrp_server.h \ - usrp_tx.h \ - usrp_tx_stub.h \ - usrp_usb_interface.h - -noinst_HEADERS = \ - qa_inband.h \ - qa_inband_packet_prims.h \ - qa_inband_usrp_server.h \ - symbols_usrp_channel.h \ - symbols_usrp_interface_cs.h \ - symbols_usrp_low_level_cs.h \ - symbols_usrp_rx.h \ - symbols_usrp_rx_cs.h \ - symbols_usrp_server_cs.h \ - symbols_usrp_tx.h \ - symbols_usrp_tx_cs.h - -# ------------------------------------------------------------------------ -# Build the qa code in its own library - -libusrp_inband_qa_la_SOURCES = \ - qa_inband.cc \ - qa_inband_packet_prims.cc \ - qa_inband_usrp_server.cc - -# magic flags -libusrp_inband_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version - -libusrp_inband_qa_la_LIBADD = \ - libusrp-inband.la \ - $(PMT_LA) \ - $(CPPUNIT_LIBS) \ - -lstdc++ - -# ------------------------------------------------------------------------ - -noinst_PROGRAMS = \ - test_inband - -test_inband_SOURCES = test_inband.cc -test_inband_LDADD = libusrp-inband-qa.la diff --git a/usrp/host/lib/inband/dump_packets.py b/usrp/host/lib/inband/dump_packets.py deleted file mode 100755 index 237362406..000000000 --- a/usrp/host/lib/inband/dump_packets.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -# 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. -# - -import sys -import struct -from optparse import OptionParser - -from usb_packet import * - -def dump_packet(raw_pkt, outfile, dump_payload): - pkt = usb_packet(raw_pkt) - outfile.write(pkt.decoded_flags()) - outfile.write(' chan= %2d len= %3d timestamp= 0x%08x rssi= % 2d tag= %2d\n' % ( - pkt.chan(), pkt.payload_len(), pkt.timestamp(), pkt.rssi(), pkt.tag())) - if dump_payload: - assert pkt.payload_len() % 4 == 0 - shorts = struct.unpack('<%dh' % (pkt.payload_len() // 2), pkt.payload()) - for i in range(0, len(shorts), 2): - outfile.write(' %6d, %6d\n' % (shorts[i], shorts[i+1])) - - -def dump_packets(infile, outfile, dump_payload): - raw_pkt = infile.read(512) - while raw_pkt: - if len(raw_pkt) != 512: - sys.stderr.write("File length is not a multiple of 512 bytes") - raise SystemExit, 1 - - dump_packet(raw_pkt, outfile, dump_payload) - raw_pkt = infile.read(512) - - -def main(): - parser = OptionParser() - parser.add_option('-p', '--dump-payload', action='store_true', default=False, - help='dump payload in decimal and hex') - - (options, files) = parser.parse_args() - if len(files) == 0: - dump_packets(sys.stdin, sys.stdout, options.dump_payload) - else: - for f in files: - dump_packets(open(f, "r"), sys.stdout, options.dump_payload) - - -if __name__ == '__main__': - main() diff --git a/usrp/host/lib/inband/gen_test_packets.py b/usrp/host/lib/inband/gen_test_packets.py deleted file mode 100755 index 2ee646384..000000000 --- a/usrp/host/lib/inband/gen_test_packets.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python - -import random -import struct -from pprint import pprint -from usb_packet import * - -MAX_PAYLOAD = 504 -TIME_NOW = 0xffffffff - - -class sequence_generator(object): - def __init__(self): - self.i = 0 - - def __call__(self): - t = self.i - self.i += 1 - return t - -def gen_shuffled_lengths(): - valid_lengths = range(0, MAX_PAYLOAD+1, 4) # [0, 4, 8, ... 504] - random.shuffle(valid_lengths) - return valid_lengths - - -class packet_sequence_generator(object): - def __init__(self, channel, lengths): - self.next = sequence_generator() - self.channel = channel - self.lengths = lengths - - def __call__(self, output_file): - gen_packet(output_file, self.channel, self.next, self.lengths[0]) - del self.lengths[0] - - -def gen_packet(output_file, channel, content_generator, payload_len): - assert (payload_len % 4) == 0 - payload = [] - n_iq = payload_len // 4 - for n in range(n_iq): - payload.append(content_generator()) # I - payload.append(content_generator()) # Q - for n in range(MAX_PAYLOAD // 4 - n_iq): - payload.append(0x0000) - payload.append(0xffff) - - assert (len(payload) == MAX_PAYLOAD // 2) - - #print "\npayload_len =", payload_len - #pprint(payload) - - output_file.write(make_header(FL_START_OF_BURST|FL_END_OF_BURST, - channel, payload_len, TIME_NOW)) - output_file.write(struct.pack('<252h', *payload)) - - -def gen_all_valid_packet_lengths_1_channel(output_file): - lengths = gen_shuffled_lengths() - npkts = len(lengths) # number of packets we'll generator on each stream - pkt_gen_0 = packet_sequence_generator(0, lengths) - for i in range(npkts): - pkt_gen_0(output_file) - - assert pkt_gen_0.next() == 16002 # 2*sum(1, 2, ..., 126) == 126 * 127 - - -def gen_all_valid_packet_lengths_2_channels(output_file): - lengths = gen_shuffled_lengths() - npkts = len(lengths) # number of packets we'll generator on each stream - pkt_gen_0 = packet_sequence_generator(0, lengths) - pkt_gen_1 = packet_sequence_generator(0x1f, gen_shuffled_lengths()) - pkt_gen = (pkt_gen_0, pkt_gen_1) - - which_gen = (npkts * [0]) + (npkts * [1]) - random.shuffle(which_gen) - - for i in which_gen: - pkt_gen[i](output_file) - - assert pkt_gen_0.next() == 16002 # 2*sum(1, 2, ..., 126) == 126 * 127 - assert pkt_gen_1.next() == 16002 # 2*sum(1, 2, ..., 126) == 126 * 127 - -if __name__ == '__main__': - random.seed(0) - gen_all_valid_packet_lengths_1_channel(open("all_valid_packet_lengths_1_channel.dat", "w")) - gen_all_valid_packet_lengths_2_channels(open("all_valid_packet_lengths_2_channels.dat", "w")) diff --git a/usrp/host/lib/inband/qa_inband.cc b/usrp/host/lib/inband/qa_inband.cc deleted file mode 100644 index 6f33a6ead..000000000 --- a/usrp/host/lib/inband/qa_inband.cc +++ /dev/null @@ -1,35 +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. - */ - -#include <qa_inband.h> -#include <qa_inband_packet_prims.h> -#include <qa_inband_usrp_server.h> - -CppUnit::TestSuite * -qa_inband::suite() -{ - CppUnit::TestSuite *s = new CppUnit::TestSuite("inband"); - - s->addTest (qa_inband_packet_prims::suite()); - s->addTest (qa_inband_usrp_server::suite()); - - return s; -} diff --git a/usrp/host/lib/inband/qa_inband.h b/usrp/host/lib/inband/qa_inband.h deleted file mode 100644 index ab8f7f250..000000000 --- a/usrp/host/lib/inband/qa_inband.h +++ /dev/null @@ -1,35 +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_QA_INBAND_H -#define INCLUDED_QA_INBAND_H - -#include <cppunit/TestSuite.h> - -//! collect all the tests for the user server - -class qa_inband { - public: - //! return suite of tests for all of usrp server - static CppUnit::TestSuite *suite(); -}; - -#endif /* INCLUDED_QA_INBAND_H */ diff --git a/usrp/host/lib/inband/qa_inband_packet_prims.cc b/usrp/host/lib/inband/qa_inband_packet_prims.cc deleted file mode 100644 index d9bbbec22..000000000 --- a/usrp/host/lib/inband/qa_inband_packet_prims.cc +++ /dev/null @@ -1,162 +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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <qa_inband_packet_prims.h> -#include <cppunit/TestAssert.h> -#include <stdio.h> -#include <string.h> -#include <usrp_inband_usb_packet.h> // will change on gigabit crossover - -typedef usrp_inband_usb_packet transport_pkt; - -void -qa_inband_packet_prims::test_flags() -{ - transport_pkt pkt; - - // Test each one of the flags while ensuring no other fields become set in the process - pkt.set_header(pkt.FL_START_OF_BURST,0,0,0); - CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_END_OF_BURST,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_OVERRUN,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_UNDERRUN,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_DROPPED,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - // test of all fields set - pkt.set_header( - pkt.FL_START_OF_BURST | - pkt.FL_END_OF_BURST | - pkt.FL_UNDERRUN | - pkt.FL_OVERRUN | - pkt.FL_DROPPED - ,0,0,0); - CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - -} -////////////////////////////////////////////////////////////////////// - -void -qa_inband_packet_prims::test_fields() -{ - transport_pkt pkt; - void * payload; - - // test word0 field exclusiveness - // - // I want to test max values of each field to ensure field boundaries - // but these max values could change based on technology? The - // max payload is returned by a private method so the code is not - // technology dependent - pkt.set_header(0,16,0,0); - CPPUNIT_ASSERT_EQUAL(16, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(0,0,8,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(8, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0,pkt.payload_len()); - - pkt.set_header(0,0,0,pkt.max_payload()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(pkt.max_payload(), pkt.payload_len()); - - // test timestamp, shouldn't have to test other fields since - // setting the timestamp only has the ability to affect one word - pkt.set_timestamp(54); - CPPUNIT_ASSERT_EQUAL(uint32_t(54), pkt.timestamp()); - - // test the payload, ensure no other fields overwritten - // - // is there a better test for this? - pkt.set_header(0,0,0,0); - payload = malloc(pkt.payload_len()); - memset(payload, 'f', pkt.payload_len()); - memcpy(pkt.payload(), payload, pkt.payload_len()); - CPPUNIT_ASSERT_EQUAL(0, memcmp(pkt.payload(), payload, pkt.payload_len())); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - free(payload); - -} -////////////////////////////////////////////////////////////////////// diff --git a/usrp/host/lib/inband/qa_inband_packet_prims.h b/usrp/host/lib/inband/qa_inband_packet_prims.h deleted file mode 100644 index 71c0d737d..000000000 --- a/usrp/host/lib/inband/qa_inband_packet_prims.h +++ /dev/null @@ -1,41 +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 QA_INBAND_PACKET_PRIMS_H -#define QA_INBAND_PACKET_PRIMS_H - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCase.h> - -class qa_inband_packet_prims : public CppUnit::TestCase { - - CPPUNIT_TEST_SUITE(qa_inband_packet_prims); - CPPUNIT_TEST(test_flags); - CPPUNIT_TEST(test_fields); - CPPUNIT_TEST_SUITE_END(); - - private: - void test_flags(); - void test_fields(); - -}; - -#endif /* INCLUDED_QA_INBAND_PACKET_PRIMS_H */ diff --git a/usrp/host/lib/inband/qa_inband_usrp_server.cc b/usrp/host/lib/inband/qa_inband_usrp_server.cc deleted file mode 100644 index 6049a8a87..000000000 --- a/usrp/host/lib/inband/qa_inband_usrp_server.cc +++ /dev/null @@ -1,1575 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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 <usrp_inband_usb_packet.h> -#include <qa_inband_usrp_server.h> -#include <cppunit/TestAssert.h> -#include <stdio.h> -#include <usrp_server.h> -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/class_registry.h> -#include <vector> -#include <iostream> -#include <pmt.h> - -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy - -static bool verbose = false; - -static pmt_t s_timeout = pmt_intern("%timeout"); - -// ---------------------------------------------------------------------------------------------- - -class qa_alloc_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_nmsgs_to_recv; - long d_nrecvd; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_nstatus; - long d_nstatus_to_recv; - - public: - qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_alloc_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_message(mb_message_sptr msg); - void run_tests(); -}; - -qa_alloc_top::qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_nrecvd=0; - d_nmsgs_to_recv = 6; - d_nstatus=0; - d_nstatus_to_recv = 50; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -qa_alloc_top::~qa_alloc_top(){} - -void -qa_alloc_top::initial_transition() -{ - // Allocations should fail before open - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, - s_err_usrp_not_opened), - pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, - s_err_usrp_not_opened), - pmt_from_long(1))); - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_max_capacity, - pmt_list1(pmt_list2(s_response_max_capacity, PMT_T))); - - d_cs->send(s_cmd_ntx_chan, - pmt_list1(pmt_list2(s_response_ntx_chan, PMT_T))); - - d_cs->send(s_cmd_nrx_chan, - pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T))); -} - -void -qa_alloc_top::run_tests() -{ - if(verbose) - std::cout << "[qa_alloc_top] Starting tests...\n"; - - // should be able to allocate 1 byte - d_tx->send(s_cmd_allocate_channel, - pmt_list2(PMT_T, pmt_from_long(1))); - - // should not be able to allocate max capacity after 100 bytes were allocated - d_tx->send(s_cmd_allocate_channel, - pmt_list2(s_err_requested_capacity_unavailable, - pmt_from_long(d_max_capacity))); - - // keep allocating a little more until all of the channels are used and test - // the error response we start at 1 since we've already allocated 1 channel - for(int i=1; i < d_ntx_chan; i++) { - - if(verbose) - std::cout << "[qa_alloc_top] Sent allocation request...\n"; - - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1))); - - d_nmsgs_to_recv++; - } - - // No more channels after allocating all of them is expected - d_tx->send(s_cmd_allocate_channel, - pmt_list2(s_err_channel_unavailable, - pmt_from_long(1))); - - // test out the same on the RX side - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(s_err_requested_capacity_unavailable, - pmt_from_long(d_max_capacity))); - - for(int i=1; i < d_nrx_chan; i++) { - - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1))); - - d_nmsgs_to_recv++; - } - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(s_err_channel_unavailable, - pmt_from_long(1))); - - // when all is said and done, there should be d_ntx_chan+d_ntx_chan bytes - // allocated - d_cs->send(s_cmd_current_capacity_allocation, - pmt_list1(pmt_from_long(d_ntx_chan+d_nrx_chan))); -} - -void -qa_alloc_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - - if ((pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) - && pmt_eq(msg->signal(), s_response_allocate_channel)) - check_message(msg); - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_max_capacity)) { - d_max_capacity = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_alloc_top] USRP has max capacity of " - << d_max_capacity << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_ntx_chan)) { - d_ntx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_alloc_top] USRP tx channels: " - << d_ntx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_nrx_chan)) { - d_nrx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_alloc_top] USRP rx channels: " - << d_nrx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) { - check_message(msg); - } - - d_nstatus++; - - check_message(msg); - - if(d_nstatus==d_nstatus_to_recv) - run_tests(); - } -} - -void -qa_alloc_top::check_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - d_nrecvd++; - - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_alloc_top] Received expected response for message " - << d_nrecvd << " (" << event << ")\n"; - } - - if(d_nrecvd == d_nmsgs_to_recv) - shutdown_all(PMT_T); -} - -REGISTER_MBLOCK_CLASS(qa_alloc_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_dealloc_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_nstatus; - long d_nstatus_to_recv; - - long d_nalloc_to_recv; - long d_nalloc_recvd; - - long d_ndealloc_to_recv; - long d_ndealloc_recvd; - - std::vector<long> d_tx_chans; - std::vector<long> d_rx_chans; - - public: - qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_dealloc_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_allocation(mb_message_sptr msg); - void check_deallocation(mb_message_sptr msg); - void allocate_max(); - void deallocate_all(); -}; - -qa_dealloc_top::qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_ndealloc_recvd=0; - d_ndealloc_to_recv = 0; - d_nalloc_recvd=0; - d_nalloc_to_recv = 0; // auto-set - d_nstatus=0; - d_nstatus_to_recv = 4; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); -} - -qa_dealloc_top::~qa_dealloc_top(){} - -void -qa_dealloc_top::initial_transition() -{ - - if(verbose) - std::cout << "[qa_dealloc_top] Initializing...\n"; - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_max_capacity, - pmt_list1(pmt_list2(s_response_max_capacity,PMT_T))); - - d_cs->send(s_cmd_ntx_chan, - pmt_list1(pmt_list2(s_response_ntx_chan,PMT_T))); - - d_cs->send(s_cmd_nrx_chan, - pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T))); -} - -void -qa_dealloc_top::allocate_max() -{ - - // Keep allocating until we hit the maximum number of channels - for(int i=0; i < d_ntx_chan; i++) { - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), - pmt_from_long(1))); // 1 byte is good enough - - d_nalloc_to_recv++; - } - - for(int i=0; i < d_nrx_chan; i++) { - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), - pmt_from_long(1))); - - d_nalloc_to_recv++; - } - -} - -void -qa_dealloc_top::deallocate_all() { - - // Deallocate all of the channels that were allocated from allocate_max() - for(int i=0; i < (int)d_tx_chans.size(); i++) { - - if(verbose) - std::cout << "[qa_dealloc_top] Trying to dealloc TX " - << d_tx_chans[i] << std::endl; - - d_tx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), - pmt_from_long(d_tx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Deallocate the RX side now - for(int i=0; i < (int)d_rx_chans.size(); i++) { - - if(verbose) - std::cout << "[qa_dealloc_top] Trying to dealloc RX " - << d_tx_chans[i] << std::endl; - - d_rx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), - pmt_from_long(d_rx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Should get permission denied errors trying to re-dealloc the channels, as - // we no longer have permission to them after deallocating - for(int i=0; i < (int)d_tx_chans.size(); i++) { - - d_tx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_permission_denied), - pmt_from_long(d_tx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Same for RX - for(int i=0; i < (int)d_rx_chans.size(); i++) { - - d_rx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_permission_denied), - pmt_from_long(d_rx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Try to deallocate a channel that doesn't exist on both sides, the last - // element in the vectors is the highest channel number, so we take that plus - // 1 - d_ndealloc_to_recv+=2; - d_tx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_invalid), - pmt_from_long(d_rx_chans.back()+1))); - - d_rx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_invalid), - pmt_from_long(d_rx_chans.back()+1))); - - - // The used capacity should be back to 0 now that we've deallocated everything - d_cs->send(s_cmd_current_capacity_allocation, - pmt_list1(pmt_list2(s_response_current_capacity_allocation, - PMT_T))); -} - -void -qa_dealloc_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - if(pmt_eq(event, pmt_intern("%shutdown"))) - return; - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_alloc_top] Received expected response for message " - << d_ndealloc_recvd - << " (" << event << ")\n"; - } - - if (pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_allocate_channel)) { - check_allocation(msg); - } - - } - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_max_capacity)) { - d_max_capacity = pmt_to_long(pmt_nth(2, data)); - } - else if(pmt_eq(msg->signal(), s_response_ntx_chan)) { - d_ntx_chan = pmt_to_long(pmt_nth(2, data)); - } - else if(pmt_eq(msg->signal(), s_response_nrx_chan)) { - d_nrx_chan = pmt_to_long(pmt_nth(2, data)); - } - else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) { - // the final command is a capacity check which should be 0, then we - // shutdown - pmt_t expected_result = pmt_from_long(0); - pmt_t result = pmt_nth(2, data); - - if(pmt_eqv(expected_result, result)) { - shutdown_all(PMT_T); - return; - } else { - shutdown_all(PMT_F); - return; - } - } - - d_nstatus++; - - if(d_nstatus==d_nstatus_to_recv) - allocate_max(); - } -} - - -void -qa_dealloc_top::check_allocation(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - d_nalloc_recvd++; - - if(!pmt_eqv(status, PMT_T)) { - shutdown_all(PMT_F); - return; - } else { - // store all of the allocate channel numbers - if(pmt_eq(msg->port_id(), d_tx->port_symbol())) - d_tx_chans.push_back(pmt_to_long(channel)); - if(pmt_eq(msg->port_id(), d_rx->port_symbol())) - d_rx_chans.push_back(pmt_to_long(channel)); - } - - if(d_nalloc_recvd == d_nalloc_to_recv) { - - if(verbose) { - std::cout << "[qa_dealloc_top] Allocated TX channels: "; - for(int i=0; i < (int)d_tx_chans.size(); i++) - std::cout << d_tx_chans[i] << " "; - - std::cout << "\n[qa_dealloc_top] Allocated RX channels: "; - for(int i=0; i < (int)d_rx_chans.size(); i++) - std::cout << d_rx_chans[i] << " "; - std::cout << "\n"; - } - - deallocate_all(); // once we've allocated all of our channels, try to - // dealloc them - } -} - -REGISTER_MBLOCK_CLASS(qa_dealloc_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_open_close_top : public mb_mblock -{ - mb_port_sptr d_cs; - - long d_max_capacity; - - long d_nmsg_to_recv; - long d_nmsg_recvd; - - public: - qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_open_close_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_cs(mb_message_sptr msg); - void run_tests(); -}; - -qa_open_close_top::qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - - d_nmsg_to_recv=7; - d_nmsg_recvd=0; - - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "cs", "server", "cs"); -} - -qa_open_close_top::~qa_open_close_top(){} - -void -qa_open_close_top::initial_transition() -{ - run_tests(); -} - -void -qa_open_close_top::run_tests() -{ - // std::cout << "[qa_open_close_top] Starting tests\n"; - - // A close before an open should fail - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close, - s_err_usrp_already_closed))); - - // Perform an open, and a second open which should fail - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, - s_err_usrp_already_opened), - pmt_from_long(0))); - - // A close should now be successful since the interface is open - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - - // But, a second close should fail - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close, - s_err_usrp_already_closed))); - - // Just to be thorough, try an open and close again - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - -} - - -void -qa_open_close_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - check_cs(msg); - } - - d_nmsg_recvd++; - - if(d_nmsg_to_recv == d_nmsg_recvd) - shutdown_all(PMT_T); -} - -void -qa_open_close_top::check_cs(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - - if(verbose) - std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << status - << " Expected: " << e_status - << " for event " << event << "\n"; - - shutdown_all(PMT_F); - } else { - if(verbose) - std::cout << "[qa_open_close_top] Received expected CS response (" - << event << ")\n"; - } - -} - -REGISTER_MBLOCK_CLASS(qa_open_close_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_tx_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_tx_chan; - long d_rx_chan; - - long d_nmsg_to_recv; - long d_nmsg_recvd; - - public: - qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_tx_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_allocation(mb_message_sptr msg); - void check_deallocation(mb_message_sptr msg); - void check_xmit(mb_message_sptr msg); - void check_cs(mb_message_sptr msg); - void run_tests(); -}; - -qa_tx_top::qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - - d_nmsg_to_recv=10; - d_nmsg_recvd=0; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); -} - -qa_tx_top::~qa_tx_top(){} - -void -qa_tx_top::initial_transition() -{ - run_tests(); -} - -void -qa_tx_top::run_tests() -{ - if(verbose) - std::cout << "[qa_tx_top] Starting tests\n"; - - // A transmit before an open should fail - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_usrp_not_opened), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Now open - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - // Try to transmit on a channel that we have no allocation for - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_channel_permission_denied), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Get a channel allocation and send on it, we assume 0 (FIXME) until 'defer' - // is implemented for simplicity - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_T), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Close should be successful - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - - // After closing, a new transmit raw frame should fail again - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_usrp_not_opened), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Reopen and retry before getting an allocation, the first xmit should fail, - // after we allocate it should work again - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_channel_permission_denied), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame,PMT_T), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // A final close which should be successful - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - -} - - -void -qa_tx_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - if(pmt_eq(event, pmt_intern("%shutdown"))) - return; - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "[qa_xmit_top] Got: " << status - << " Expected: " << e_status - << "For signal: " << event << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_xmit_top] Received expected response for message " - << d_nmsg_recvd - << " (" << event << ")\n"; - } - - if (pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_allocate_channel)) - check_allocation(msg); - - } - - d_nmsg_recvd++; - - if(d_nmsg_to_recv == d_nmsg_recvd){ - shutdown_all(PMT_T); - return; - } -} - -void -qa_tx_top::check_allocation(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - if(pmt_eqv(status, PMT_T)) { - // store all of the allocate channel numbers - if(pmt_eq(msg->port_id(), d_tx->port_symbol())) - d_tx_chan = pmt_to_long(channel); - if(pmt_eq(msg->port_id(), d_rx->port_symbol())) - d_rx_chan = pmt_to_long(channel); - } -} - -REGISTER_MBLOCK_CLASS(qa_tx_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_rx_top : public mb_mblock -{ - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_rx_chan; - - bool d_got_response_recv; - - mb_time d_t0; - double d_delta_t; - - public: - qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_rx_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_allocation(mb_message_sptr msg); - void check_deallocation(mb_message_sptr msg); - void check_xmit(mb_message_sptr msg); - void check_cs(mb_message_sptr msg); - void run_tests(); -}; - -qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_got_response_recv(false) -{ - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_dict = pmt_make_dict(); - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(128)); - pmt_dict_set(usrp_dict, pmt_intern("fake-usrp"), PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_dict); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); -} - -qa_rx_top::~qa_rx_top(){} - -void -qa_rx_top::initial_transition() -{ - run_tests(); -} - -void -qa_rx_top::run_tests() -{ - if(verbose) - std::cout << "[qa_rx_top] Starting tests\n"; - - d_cs->send(s_cmd_open, pmt_list2(pmt_list2(s_response_open,PMT_T), pmt_from_long(0))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), - pmt_from_long(1))); - - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - // Schedule a small timeout in which we expect to have received at least one - // packet worth of samples from the stub - d_t0 = mb_time::time(); - schedule_one_shot_timeout(d_t0 + 0.01, PMT_NIL); -} - - -void -qa_rx_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - if(pmt_eq(event, pmt_intern("%shutdown"))) - return; - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - // If we get a timeout we shutdown - if(pmt_eq(event, s_timeout)) { - if(verbose) - std::cout << "[qa_rx_top] Got timeout\n"; - d_rx->send(s_cmd_stop_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - return; - } - - // For testing RX, an invocation handle is not generated by the stub, - // therefore the same approach for testing is not used. We simply - // expect all responses to be true. - if(pmt_eq(event, s_response_recv_raw_samples)) { - if(pmt_eqv(status, PMT_T)) { - - if(verbose) - std::cout << "[qa_rx_top] Received expected response for message " - << " (" << event << ")\n"; - - // All we want is 1 response receive! Can't guarantee exact numbers - d_got_response_recv = true; - } - else { - if(verbose) - std::cout << "Got: " << status << " Expected: " << PMT_T << "\n"; - shutdown_all(PMT_F); - } - return; - } - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_rx_top] Received expected response for message " - << " (" << event << ")\n"; - } - - if (pmt_eq(msg->port_id(), d_rx->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_allocate_channel)) - check_allocation(msg); - - } - - // We stop when we get a close, we are successful if we - // got a response from recv, fail if we never got a recv response - if(pmt_eq(msg->signal(), s_response_close)) { - - if(d_got_response_recv) { - shutdown_all(PMT_T); - return; - } - else { - shutdown_all(PMT_F); - if(verbose) - std::cout << "[qa_rx_top] No response message before close\n"; - return; - } - } -} - - -void -qa_rx_top::check_allocation(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - if(pmt_eqv(status, PMT_T)) { - // store all of the allocate channel numbers - if(pmt_eq(msg->port_id(), d_rx->port_symbol())) - d_rx_chan = pmt_to_long(channel); - } -} - -REGISTER_MBLOCK_CLASS(qa_rx_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_rid_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_npongs; - long d_tcycles; - long d_cycles; - long d_max_rid; - - mb_time d_t0; - double d_delta_t; - - public: - qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_rid_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void run_tests(); - void send_max_pings(); -}; - -qa_rid_top::qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_npongs = 0; - d_tcycles = 3; - d_cycles = d_tcycles; - d_max_rid = usrp_server::D_MAX_RID; - d_delta_t = 0.1; - - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -qa_rid_top::~qa_rid_top(){} - -void -qa_rid_top::initial_transition() -{ - run_tests(); -} - -void -qa_rid_top::run_tests() -{ - if(verbose) - std::cout << "[qa_rid_top] Starting tests...\n"; - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - // should be able to allocate 1 byte - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - // Need to start receiving to read from the USRP to get C/S responses - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - // Build a subpacket of MAX_RID pings and wait a small amount for all of the - // responses and fire off another MAX_RID. If MAX_RID*2 responses are - // received, the RID recycling is working correctly. - // Schedule a timer in which we expect to have received all of the responses, - // which will send off another MAX_RID worth. - send_max_pings(); - d_t0 = mb_time::time(); - schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL); -} - -void -qa_rid_top::send_max_pings() -{ - pmt_t ping = pmt_list2(s_op_ping_fixed, - pmt_list2(pmt_from_long(0), - pmt_from_long(0))); - - pmt_t sub_packets = PMT_NIL; - - for(int i=0; i<d_max_rid; i++) - sub_packets = pmt_list_add(sub_packets, ping); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - sub_packets)); -} - -void -qa_rid_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - // If we get a timeout we ensure we got a maximum RID number of responses. - if(pmt_eq(event, s_timeout)) { - if(verbose) - std::cout << "[qa_rid_top] Got timeout, received so far: " - << d_npongs << "\n"; - - d_cycles--; - - if(d_cycles==0 && d_npongs == d_max_rid*d_tcycles) { - shutdown_all(PMT_T); - } - else if(d_cycles==0) { - - std::cout << "[qa_rid_top] d_npongs: " << d_npongs - << " expected: " << d_max_rid*d_tcycles - << std::endl; - - shutdown_all(PMT_F); - } - else { - send_max_pings(); - d_t0 = mb_time::time(); - schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL); - } - - } - else if(pmt_eq(event, s_response_from_control_channel)) - { - d_npongs++; - } - -} - -REGISTER_MBLOCK_CLASS(qa_rid_top); - - -// ---------------------------------------------------------------------------------------------- - -class qa_cs_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_nmsgs_to_recv; - long d_nrecvd; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_nstatus; - long d_nstatus_to_recv; - - public: - qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_cs_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_message(mb_message_sptr msg); - void run_tests(); -}; - -qa_cs_top::qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_nrecvd=0; - d_nmsgs_to_recv = 8; - d_nstatus=0; - d_nstatus_to_recv = 50; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -qa_cs_top::~qa_cs_top(){} - -void -qa_cs_top::initial_transition() -{ - run_tests(); -} - -void -qa_cs_top::run_tests() -{ - if(verbose) - std::cout << "[qa_cs_top] Starting tests...\n"; - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - // should be able to allocate 1 byte - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - // Need to start receiving to read from the USRP to get C/S responses - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_ping_fixed, - pmt_list2(pmt_from_long(3), - pmt_from_long(0)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_write_reg, - pmt_list2( - pmt_from_long(0x3), - pmt_from_long(0x4)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_write_reg_masked, - pmt_list3( - pmt_from_long(0x3), - pmt_from_long(0x4), - pmt_from_long(0x5)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_read_reg, - pmt_list2(pmt_from_long(0), - pmt_from_long(0x6)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_delay, - pmt_list1(pmt_from_long(0x7)))))); - - pmt_t subpackets = pmt_list5( - pmt_list2(s_op_ping_fixed, pmt_list2(pmt_from_long(0), pmt_from_long(0))), - pmt_list2(s_op_delay, pmt_list1(pmt_from_long(0x7))), - pmt_list2(s_op_write_reg_masked, pmt_list3(pmt_from_long(3), - pmt_from_long(4), - pmt_from_long(5))), - pmt_list2(s_op_write_reg, pmt_list2(pmt_from_long(3), - pmt_from_long(4))), - pmt_list2(s_op_read_reg, pmt_list2(pmt_from_long(0), - pmt_from_long(6))) - ); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - subpackets)); - - pmt_t i2c_data = pmt_make_u8vector(8, 0xff); - - subpackets = pmt_list2( - pmt_list2(s_op_i2c_write, - pmt_list2(pmt_from_long(8), i2c_data)), - pmt_list2(s_op_i2c_read, - pmt_list3(pmt_from_long(0), pmt_from_long(9), pmt_from_long(1))) - - ); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - subpackets)); - -} - -void -qa_cs_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - - if ((pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) - && pmt_eq(msg->signal(), s_response_allocate_channel)) - check_message(msg); - - if (pmt_eq(msg->port_id(), d_tx->port_symbol()) - && pmt_eq(msg->signal(), s_response_from_control_channel)) - check_message(msg); - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_max_capacity)) { - d_max_capacity = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_cs_top] USRP has max capacity of " - << d_max_capacity << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_ntx_chan)) { - d_ntx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_cs_top] USRP tx channels: " - << d_ntx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_nrx_chan)) { - d_nrx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_cs_top] USRP rx channels: " - << d_nrx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) { - check_message(msg); - } - - d_nstatus++; - - check_message(msg); - - if(d_nstatus==d_nstatus_to_recv) - run_tests(); - } -} - -void -qa_cs_top::check_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - d_nrecvd++; - - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "[qa_cs_top] Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_cs_top] Received expected response for message " - << d_nrecvd << " (" << event << ")\n"; - } - - if(d_nrecvd == d_nmsgs_to_recv) - shutdown_all(PMT_T); -} - -REGISTER_MBLOCK_CLASS(qa_cs_top); - -// ---------------------------------------------------------------------------------------------- - -void -qa_inband_usrp_server::test_open_close() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n----------------------------\n"; - // std::cout << " RUNNING OPEN/CLOSE TESTS \n"; - - rt->run("top", "qa_open_close_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_chan_allocation() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n----------------------------\n"; - // std::cout << " RUNNING ALLOCATION TESTS \n"; - - rt->run("qa_alloc_top", "qa_alloc_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_chan_deallocation() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n----------------------------\n"; - // std::cout << " RUNNING DEALLOCATION TESTS \n"; - - rt->run("qa_dealloc_top", "qa_dealloc_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_tx() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING TX TESTS \n"; - - rt->run("top", "qa_tx_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_rx() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING RX TESTS \n"; - - rt->run("top", "qa_rx_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_cs() -{ - // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's - return; - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING CS TESTS \n"; - - rt->run("top", "qa_cs_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_rid() -{ - // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's - return; - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING RID TESTS \n"; - - rt->run("top", "qa_rid_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} diff --git a/usrp/host/lib/inband/qa_inband_usrp_server.h b/usrp/host/lib/inband/qa_inband_usrp_server.h deleted file mode 100644 index 52a4a0b06..000000000 --- a/usrp/host/lib/inband/qa_inband_usrp_server.h +++ /dev/null @@ -1,50 +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 QA_INBAND_USRP_SERVER_H -#define QA_INBAND_USRP_SERVER_H - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCase.h> - -class qa_inband_usrp_server : public CppUnit::TestCase { - - CPPUNIT_TEST_SUITE(qa_inband_usrp_server); - CPPUNIT_TEST(test_open_close); - CPPUNIT_TEST(test_chan_allocation); - CPPUNIT_TEST(test_chan_deallocation); - CPPUNIT_TEST(test_tx); - CPPUNIT_TEST(test_rx); - CPPUNIT_TEST(test_cs); - CPPUNIT_TEST(test_rid); - CPPUNIT_TEST_SUITE_END(); - - private: - void test_chan_allocation(); - void test_chan_deallocation(); - void test_open_close(); - void test_tx(); - void test_rx(); - void test_cs(); - void test_rid(); -}; - -#endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_channel.h b/usrp/host/lib/inband/symbols_usrp_channel.h deleted file mode 100644 index a0114cf3c..000000000 --- a/usrp/host/lib/inband/symbols_usrp_channel.h +++ /dev/null @@ -1,40 +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_SYMBOLS_USRP_CHANNEL_H -#define INCLUDED_SYMBOLS_USRP_CHANNEL_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel"); -static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel"); - -// Incoming -static pmt_t s_response_allocate_channel = pmt_intern("response-allocate-channel"); -static pmt_t s_response_deallocate_channel = pmt_intern("response-deallocate-channel"); - -// Errors -static pmt_t s_err_requested_capacity_unavailable = pmt_intern("err-requested-capacity-unavailable"); -static pmt_t s_err_channel_unavailable = pmt_intern("err-channel-unavailable"); -static pmt_t s_err_channel_invalid = pmt_intern("err-channel-invalid"); -static pmt_t s_err_channel_permission_denied = pmt_intern("err-channel-permission-denied"); - -#endif /* INCLUDED_SYMBOLS_USRP_CHANNEL_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_interface_cs.h b/usrp/host/lib/inband/symbols_usrp_interface_cs.h deleted file mode 100644 index 72c8fcc91..000000000 --- a/usrp/host/lib/inband/symbols_usrp_interface_cs.h +++ /dev/null @@ -1,43 +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_SYMBOLS_USRP_INTERFACE_CS_H -#define INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_usrp_open = pmt_intern("cmd-usrp-open"); -static pmt_t s_cmd_usrp_close = pmt_intern("cmd-usrp-close"); -static pmt_t s_cmd_usrp_ntx_chan = pmt_intern("cmd-usrp-ntx-chan"); -static pmt_t s_cmd_usrp_nrx_chan = pmt_intern("cmd-usrp-nrx-chan"); -static pmt_t s_cmd_usrp_write = pmt_intern("cmd-usrp-write"); -static pmt_t s_cmd_usrp_start_reading = pmt_intern("cmd-usrp-start-reading"); -static pmt_t s_cmd_usrp_stop_reading = pmt_intern("cmd-usrp-stop-reading"); - -// Incoming -static pmt_t s_response_usrp_open = pmt_intern("response-usrp-open"); -static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close"); -static pmt_t s_response_usrp_ntx_chan = pmt_intern("response-usrp-ntx-chan"); -static pmt_t s_response_usrp_nrx_chan = pmt_intern("response-usrp-nrx-chan"); -static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write"); -static pmt_t s_response_usrp_read = pmt_intern("response-usrp-read"); - -#endif /* INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_low_level_cs.h b/usrp/host/lib/inband/symbols_usrp_low_level_cs.h deleted file mode 100644 index a7260603a..000000000 --- a/usrp/host/lib/inband/symbols_usrp_low_level_cs.h +++ /dev/null @@ -1,47 +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_SYMBOLS_USRP_LOW_LEVEL_CS_H -#define INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_to_control_channel = pmt_intern("cmd-to-control-channel"); - -// Incoming -static pmt_t s_response_from_control_channel = pmt_intern("response-from-control-channel"); - -// Subpackets -static pmt_t s_op_ping_fixed = pmt_intern("op-ping-fixed"); -static pmt_t s_op_ping_fixed_reply = pmt_intern("op-ping-fixed-reply"); -static pmt_t s_op_write_reg = pmt_intern("op-write-reg"); -static pmt_t s_op_write_reg_masked = pmt_intern("op-write-reg-masked"); -static pmt_t s_op_read_reg = pmt_intern("op-read-reg"); -static pmt_t s_op_read_reg_reply = pmt_intern("op-read-reg-reply"); -static pmt_t s_op_i2c_write = pmt_intern("op-i2c-write"); -static pmt_t s_op_i2c_read = pmt_intern("op-i2c-read"); -static pmt_t s_op_i2c_read_reply = pmt_intern("op-i2c-read-reply"); -static pmt_t s_op_spi_write = pmt_intern("op-spi-write"); -static pmt_t s_op_spi_read = pmt_intern("op-spi-read"); -static pmt_t s_op_spi_read_reply = pmt_intern("op-spi-read-reply"); -static pmt_t s_op_delay = pmt_intern("op-delay"); - -#endif /* INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_rx.h b/usrp/host/lib/inband/symbols_usrp_rx.h deleted file mode 100644 index 07d58a3f5..000000000 --- a/usrp/host/lib/inband/symbols_usrp_rx.h +++ /dev/null @@ -1,36 +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_SYMBOLS_USRP_RX_H -#define INCLUDED_SYMBOLS_USRP_RX_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_start_recv_raw_samples = pmt_intern("cmd-start-recv-raw-samples"); -static pmt_t s_cmd_stop_recv_raw_samples = pmt_intern("cmd-stop-recv-raw-samples"); - -// Incoming -static pmt_t s_response_recv_raw_samples = pmt_intern("response-recv-raw-samples"); - -// Errors -static pmt_t s_err_already_receiving = pmt_intern("err-already-receiving"); - -#endif /* INCLUDED_SYMBOLS_USRP_RX_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_rx_cs.h b/usrp/host/lib/inband/symbols_usrp_rx_cs.h deleted file mode 100644 index bf4f0338b..000000000 --- a/usrp/host/lib/inband/symbols_usrp_rx_cs.h +++ /dev/null @@ -1,32 +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_SYMBOLS_USRP_RX_CS_H -#define INCLUDED_SYMBOLS_USRP_RX_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_usrp_rx_start_reading = pmt_intern("cmd-usrp-rx-start-reading"); - -// Incoming -static pmt_t s_response_usrp_rx_read = pmt_intern("response-usrp-rx-read"); - -#endif /* INCLUDED_SYMBOLS_USRP_RX_CS_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_server_cs.h b/usrp/host/lib/inband/symbols_usrp_server_cs.h deleted file mode 100644 index e612e24ea..000000000 --- a/usrp/host/lib/inband/symbols_usrp_server_cs.h +++ /dev/null @@ -1,47 +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_SYMBOLS_USRP_SERVER_CS_H -#define INCLUDED_SYMBOLS_USRP_SERVER_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_open = pmt_intern("cmd-open"); -static pmt_t s_cmd_close = pmt_intern("cmd-close"); -static pmt_t s_cmd_max_capacity = pmt_intern("cmd-max-capacity"); -static pmt_t s_cmd_ntx_chan = pmt_intern("cmd-ntx-chan"); -static pmt_t s_cmd_nrx_chan = pmt_intern("cmd-nrx-chan"); -static pmt_t s_cmd_current_capacity_allocation = pmt_intern("cmd-current-capacity-allocation"); - -// Incoming -static pmt_t s_response_open = pmt_intern("response-open"); -static pmt_t s_response_close = pmt_intern("response-close"); -static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity"); -static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan"); -static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan"); -static pmt_t s_response_current_capacity_allocation = pmt_intern("response-current-capacity-allocation"); - -// Errors -static pmt_t s_err_usrp_not_opened = pmt_intern("err-usrp-not-opened"); -static pmt_t s_err_usrp_already_opened = pmt_intern("err-usrp-already-opened"); -static pmt_t s_err_usrp_already_closed = pmt_intern("err-usrp-already-closed"); - -#endif /* INCLUDED_SYMBOLS_USRP_SERVER_CS_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_tx.h b/usrp/host/lib/inband/symbols_usrp_tx.h deleted file mode 100644 index 4e58e2cf9..000000000 --- a/usrp/host/lib/inband/symbols_usrp_tx.h +++ /dev/null @@ -1,32 +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_SYMBOLS_USRP_TX_H -#define INCLUDED_SYMBOLS_USRP_TX_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_xmit_raw_frame = pmt_intern("cmd-xmit-raw-frame"); - -// Incoming -static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame"); - -#endif /* INCLUDED_SYMBOLS_USRP_TX_H */ diff --git a/usrp/host/lib/inband/symbols_usrp_tx_cs.h b/usrp/host/lib/inband/symbols_usrp_tx_cs.h deleted file mode 100644 index d02ef1d26..000000000 --- a/usrp/host/lib/inband/symbols_usrp_tx_cs.h +++ /dev/null @@ -1,32 +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_SYMBOLS_USRP_TX_CS_H -#define INCLUDED_SYMBOLS_USRP_TX_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_usrp_tx_write = pmt_intern("cmd-usrp-tx-write"); - -// Incoming -static pmt_t s_response_usrp_tx_write = pmt_intern("response-usrp-tx-write"); - -#endif /* INCLUDED_SYMBOLS_USRP_TX_CS_H */ diff --git a/usrp/host/lib/inband/test_inband.cc b/usrp/host/lib/inband/test_inband.cc deleted file mode 100644 index 77cdca556..000000000 --- a/usrp/host/lib/inband/test_inband.cc +++ /dev/null @@ -1,36 +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. - */ - -#include <cppunit/TextTestRunner.h> -#include <qa_inband.h> - -int -main(int argc, char **argv) -{ - - CppUnit::TextTestRunner runner; - - runner.addTest(qa_inband::suite ()); - - bool was_successful = runner.run("", false); - - return was_successful ? 0 : 1; -} diff --git a/usrp/host/lib/inband/usb_packet.py b/usrp/host/lib/inband/usb_packet.py deleted file mode 100644 index 6dfcf8638..000000000 --- a/usrp/host/lib/inband/usb_packet.py +++ /dev/null @@ -1,115 +0,0 @@ -# -# 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. -# - -import struct - - -FL_OVERRUN = 0x80000000 -FL_UNDERRUN = 0x40000000 -FL_DROPPED = 0x20000000 -FL_END_OF_BURST = 0x10000000 -FL_START_OF_BURST = 0x08000000 - -FL_ALL_FLAGS = 0xf8000000 - -FL_OVERRUN_SHIFT = 31 -FL_UNDERRUN_SHIFT = 30 -FL_DROPPED_SHIFT = 29 -FL_END_OF_BURST_SHIFT = 28 -FL_START_OF_BURST_SHIFT = 27 - -RSSI_MASK = 0x3f -RSSI_SHIFT = 21 - -CHAN_MASK = 0x1f -CHAN_SHIFT = 16 - -TAG_MASK = 0xf -TAG_SHIFT = 9 - -PAYLOAD_LEN_MASK = 0x1ff -PAYLOAD_LEN_SHIFT = 0 - -def make_header(flags, chan, payload_len, timestamp, rssi=0, tag=0): - word0 = ((flags & FL_ALL_FLAGS) - | ((rssi & RSSI_MASK) << RSSI_SHIFT) - | ((chan & CHAN_MASK) << CHAN_SHIFT) - | ((tag & TAG_MASK) << TAG_SHIFT) - | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT)) - word1 = timestamp - return struct.pack('<2I', word0, word1) - - -def _decode(pred, indicator): - if pred: - return indicator - else: - return '-' - - -class usb_packet(object): - def __init__(self, raw_pkt): - assert isinstance(raw_pkt, str) and len(raw_pkt) == 512 - self._raw_pkt = raw_pkt; - (self._word0, self._word1) = struct.unpack('<2I', self._raw_pkt[0:8]) - - def timestamp(self): - return self._word1 - - def rssi(self): - return (self._word0 >> RSSI_SHIFT) & RSSI_MASK - - def chan(self): - return (self._word0 >> CHAN_SHIFT) & CHAN_MASK - - def tag(self): - return (self._word0 >> TAG_SHIFT) & TAG_MASK - - def payload_len(self): - return (self._word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK - - def flags(self): - return self._word0 & FL_ALL_FLAGS - - def overrun(self): - return (self._word0 >> FL_OVERRUN_SHIFT) & 0x1 - - def underrun(self): - return (self._word0 >> FL_UNDERRUN_SHIFT) & 0x1 - - def start_of_burst(self): - return (self._word0 >> FL_START_OF_BURST_SHIFT) & 0x1 - - def end_of_burst(self): - return (self._word0 >> FL_END_OF_BURST_SHIFT) & 0x1 - - def dropped(self): - return (self._word0 >> FL_DROPPED_SHIFT) & 0x1 - - def payload(self): - return self._raw_pkt[8:8+self.payload_len()] - - def decoded_flags(self): - s = (_decode(self.overrun(), 'O') - + _decode(self.underrun(), 'U') - + _decode(self.dropped(), 'D') - + _decode(self.end_of_burst(), 'E') - + _decode(self.start_of_burst(), 'S')) - return s diff --git a/usrp/host/lib/inband/usrp_inband_usb_packet.cc b/usrp/host/lib/inband/usrp_inband_usb_packet.cc deleted file mode 100644 index 72bc45ccb..000000000 --- a/usrp/host/lib/inband/usrp_inband_usb_packet.cc +++ /dev/null @@ -1,793 +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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_inband_usb_packet.h> - -#include <usrp_bytesex.h> -#include <iostream> -#include <stdio.h> -#include <string.h> - -/*! - * \brief Aligns the packet payload on a 32 bit boundary. This is essential to - * all control/status packets so that the inband FPGA code can parse them - * easily. - * - * \returns true if successful or if the packet was already aligned; false if it - * cannot be aligned. - */ -bool usrp_inband_usb_packet::align32() -{ - int p_len = payload_len(); - - int bytes_needed = 4 - (p_len % 4); - - if(bytes_needed == 4) - return true; - - // If the room left in the packet is less than the number of bytes - // needed, return false to indicate no room to align - if((MAX_PAYLOAD - p_len) < bytes_needed) - return false; - - incr_header_len(bytes_needed); - - return true; -} - -/*! - * \brief Adds a ping command to the current control packet. - * - * The \p rid is the rid to be associated with the ping response and \p ping_val - * is currently unused. - * - * \returns true if adding the ping command was successful, false otherwise - * (i.e. no space in the current packet). - */ -bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN)) - return false; - - uint32_t ping = ( - ((OP_PING_FIXED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | (ping_val & CS_PINGVAL_MASK) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(ping); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_PING_LEN); - - return true; -} - -/*! - * \brief Adds a ping response to the packet. This is used by the fake USRP - * code to generate fake responses for pings. - * - * The \p rid is the RID to be associated with the response and \p ping_val is - * currently unused. - * - * \returns true if the ping reply was added successfully, false otherwise. - */ -bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN)) - return false; - - uint32_t ping = ( - ((OP_PING_FIXED_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((ping_val & CS_PINGVAL_MASK) << CS_PINGVAL_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(ping); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_PING_LEN); - - return true; -} - -/*! - * \brief Adds a write register command to the packet. - * - * The \p reg_num is the register number for which the value \p val will be - * written to. - * - * \returns true if the command was added to the packet successfully, false - * otherwise. - */ -bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_WRITEREG_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - // Build the first word which includes the register number - word0 = ( - ((OP_WRITE_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_WRITEREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // The second word is solely the register value to be written - // FIXME: should this be unsigned? - payload += 1; - *payload = host_to_usrp_u32((uint32_t) val); - - // Rebuild the header to update the payload length - incr_header_len(CS_FIXED_LEN + CS_WRITEREG_LEN); - - return true; -} - -/*! - * \brief Adds a write register masked command to the packet. - * - * The \p reg_num is the register number for which the value \p val will be - * written, masked by \p mask - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long mask) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_WRITEREGMASKED_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - // Build the first word which includes the register number - word0 = ( - ((OP_WRITE_REG_MASKED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_WRITEREGMASKED_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Skip over the first word and write the register value - payload += 1; - *payload = host_to_usrp_u32((uint32_t) val); - - // Skip over the register value and write the mask - payload += 1; - *payload = host_to_usrp_u32((uint32_t) mask); - - // Rebuild the header to update the payload length - incr_header_len(CS_FIXED_LEN + CS_WRITEREGMASKED_LEN); - - return true; -} - -/*! - * \brief Adds a read register message to the packet. - * - * The \p rid will be the associated RID returned with the response, and \p - * reg_num is the register to be read. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_READREG_LEN + CS_FIXED_LEN)) - return false; - - uint32_t read_reg = ( - ((OP_READ_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_READREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(read_reg); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_READREG_LEN); - - return true; -} - -/*! - * \brief Adds a read register reply response to the current packet. This is - * used by the fake USRP code to generate fake register read responses for - * testing. - * - * The \p rid is the associated RID to be included in the response, \p reg_num - * is the register the read is coming from, and \p reg_val is the value of the - * read. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_READREGREPLY_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = ( - ((OP_READ_REG_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_READREGREPLY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Hop to the next word and write the reg value - payload += 1; - *payload = host_to_usrp_u32((uint32_t) reg_val); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_READREGREPLY_LEN); - - return true; -} - -/*! - * \brief Adds a delay command to the current packet. - * - * The \p ticks parameter is the number of clock ticks the FPGA should delay - * parsing for, which is added to the packet. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_delay(long ticks) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_DELAY_LEN + CS_FIXED_LEN)) - return false; - - uint32_t delay = ( - ((OP_DELAY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_DELAY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((ticks & CS_DELAY_MASK) << CS_DELAY_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(delay); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_DELAY_LEN); - - return true; -} - -/*! - * \brief - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int i2c_len = data_len + 2; // 2 bytes between mbz and addr - - if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - word0 = ( - ((OP_I2C_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Jump over the first word and write the data - // FIXME: Should the data be changed to usrp byte order? - payload += 1; - memcpy(payload, i2c_data, data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + i2c_len); - - return true; -} - -/*! - * \brief Adds an I2C read command to the current packet. - * - * The \p rid is the associated RID to return with the read response, \p - * i2c_addr is the address to read from on the I2C bus, and \p n_bytes is the - * number of bytes to be read from the bus. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_I2CREAD_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - word0 = ( - ((OP_I2C_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_I2CREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Jump a word and write the number of bytes to read - payload += 1; - uint32_t word1 = - (n_bytes & CS_I2CREADBYTES_MASK) << CS_I2CREADBYTES_SHIFT; - *payload = host_to_usrp_u32(word1); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_I2CREAD_LEN); - - return true; -} - -/*! - * \brief Adds an I2C read reply response to the current packet. This is used - * by the fake USRP code to generate fake I2C responses. - * - * The \p rid is the RID to be associated with the response, \p i2c_addr is the - * address on the I2C bus that the \p i2c_data of \p i2c_data_len was read from. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int i2c_len = i2c_data_len + 2; - - if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - word0 = ( - ((OP_I2C_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Jump a word and write the actual data - payload += 1; - memcpy(payload, i2c_data, i2c_data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + i2c_len); - - return true; -} - -/*! - * \brief Adds a SPI write command to the current packet. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int spi_len = spi_data_len + 6; - - if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN)) - return false; - - uint32_t word = 0; - - // First word contains the opcode and length, then mbz - word = ( - ((OP_SPI_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT) - ); - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - - // Second word contains the enables, format, and optional tx bytes - word = 0; - word = ( - ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT) - | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT) - | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT) - ); - payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - memcpy(payload, spi_data, spi_data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + spi_len); - - return true; -} - -/*! - * \brief Adds a SPI bus read command to the packet. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_SPIREAD_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word = 0; - - // First word contains the opcode, length, and RID - word = ( - ((OP_SPI_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_SPIREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - ); - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - - // Second word contains the enables, format, and optional tx bytes - word = 0; - word = ( - ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT) - | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT) - | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT) - ); - payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - - // The third word contains the number of bytes - word = 0; - word = ( - ((n_bytes & CS_SPINBYTES_MASK) << CS_SPINBYTES_SHIFT) - ); - payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_SPIREAD_LEN); - - return true; -} - -/*! - * \brief Adds an SPI read reply to the current packet. This is used by the - * fake USRP code to generate fake responses for SPI reads. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int spi_len = spi_data_len + 2; - - if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN)) - return false; - - uint32_t word = 0; - - // First word contains the opcode, length, and RID - word = ( - ((OP_SPI_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - ); - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - // Jump a word and write the actual data - payload += 1; - memcpy(payload, spi_data, spi_data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + spi_len); - - return true; -} - -/*! - * \brief Since all control packets contain subpackets which have the length of - * the subpacket at a uniform location in the subpacket, this will return the - * subpacket length given a byte offset of the start of the subpacket from the beginning of the packet. - * - * \returns the length of the subpacket - */ -int usrp_inband_usb_packet::cs_len(int payload_offset) { - uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset))); - return (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK; -} - -/*! - * \brief The following method takes an offset within the packet payload to - * extract a control/status subpacket and constructs a pmt response which - * includes the proper signal and arguments specified by usrp-low-level-cs. The - * USRP server could therefore use this to read subpackets and pass them - * responses back up to the application. It's arguable that only reply packets - * should be parsed here, however we parse others for use in debugging or - * failure reporting on the transmit side of packets. - */ -pmt_t usrp_inband_usb_packet::read_subpacket(int payload_offset) { - - uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset))); - uint32_t opcode = (subpkt >> CS_OPCODE_SHIFT) & CS_OPCODE_MASK; - uint32_t len = (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK; - - switch(opcode) { - - case OP_PING_FIXED_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK); - return pmt_list3(s_op_ping_fixed_reply, rid, pingval); - } - - case OP_READ_REG_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - // To get the register value we just read the next 32 bits - uint32_t val = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t reg_val = pmt_from_long(val); - - return pmt_list4(s_op_read_reg_reply, rid, reg_num, reg_val); - } - - case OP_I2C_READ_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t i2c_addr = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK); - - // Make a u8 vector to dump the data from the packet into - size_t i2c_data_len; - pmt_t i2c_data = pmt_make_u8vector(len - 2, 0); // skip rid+mbz+addr = 2 bytes - uint8_t *w_data = - (uint8_t *) pmt_u8vector_writable_elements(i2c_data, i2c_data_len); - - memcpy(w_data, d_payload + payload_offset + 4, i2c_data_len); // skip first word - - return pmt_list4(s_op_i2c_read_reply, rid, i2c_addr, i2c_data); - } - - case OP_SPI_READ_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - - // Make a u8 vector to dump the data from the packet into - size_t spi_data_len; - pmt_t spi_data = pmt_make_u8vector(len - 2, 0); // skip rid+mbz+addr = 2 bytes - uint8_t *w_data = - (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len); - - memcpy(w_data, d_payload + payload_offset + 4, spi_data_len); // skip first word - - return pmt_list3(s_op_spi_read_reply, rid, spi_data); - } - - case OP_PING_FIXED: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK); - return pmt_list3(s_op_ping_fixed, rid, pingval); - } - - case OP_WRITE_REG: - { - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - // To get the register value we just read the next 32 bits - uint32_t val = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t reg_val = pmt_from_long(val); - - return pmt_list3(s_op_write_reg, reg_num, reg_val); - } - - case OP_WRITE_REG_MASKED: - { - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - // To get the register value we just read the next 32 bits - uint32_t val = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t reg_val = pmt_from_long(val); - - // The mask is the next 32 bits - uint32_t mask = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8))); - pmt_t reg_mask = pmt_from_long(mask); - - return pmt_list4(s_op_write_reg_masked, reg_num, reg_val, reg_mask); - } - - case OP_READ_REG: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - return pmt_list3(s_op_read_reg, rid, reg_num); - } - - case OP_I2C_WRITE: - { - pmt_t i2c_addr = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK); - - // The length includes an extra 2 bytes for storing the mbz and addr - pmt_t i2c_data = pmt_make_u8vector(len-2, 0); - - // Get a writable address to copy the data from the packet - size_t ignore; - uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore); - memcpy(w_data, d_payload + payload_offset + 4, len-2); - - - return pmt_list3(s_op_i2c_write, i2c_addr, i2c_data); - } - - case OP_I2C_READ: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t i2c_addr = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK); - - // The number of bytes is in the next word - uint32_t bytes = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - bytes = (bytes >> CS_I2CREADBYTES_SHIFT) & CS_I2CREADBYTES_MASK; - pmt_t i2c_bytes = pmt_from_long(bytes); - - return pmt_list4(s_op_i2c_read, rid, i2c_addr, i2c_bytes); - } - - case OP_SPI_WRITE: - { - // Nothing interesting in the first word, skip to the next - uint32_t word = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t enables = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK); - pmt_t format = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK); - pmt_t opt = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK); - - // From the next word and on is data - size_t spi_data_len; - pmt_t spi_data = pmt_make_u8vector(len - 6, 0); // skip rid+mbz+addr = 2 bytes - uint8_t *w_data = - (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len); - - memcpy(w_data, d_payload + payload_offset + 8, spi_data_len); // skip first 2 words - - return pmt_list5(s_op_spi_write, enables, format, opt, spi_data); - } - - case OP_SPI_READ: - { - // Read the RID from the first word, the rest is mbz - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - - // Continue at the next word... - uint32_t word = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t enables = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK); - pmt_t format = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK); - pmt_t opt = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK); - - // The number of bytes is the only thing to read in the next word - word = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8))); - pmt_t n_bytes = pmt_from_long((word >> CS_SPINBYTES_SHIFT) & CS_SPINBYTES_MASK); - - return pmt_list6(s_op_spi_read, rid, enables, format, opt, n_bytes); - } - - case OP_DELAY: - { - pmt_t ticks = pmt_from_long((subpkt >> CS_DELAY_SHIFT) & CS_DELAY_MASK); - - return pmt_list2(s_op_delay, ticks); - } - - default: - return PMT_NIL; - - } -} - diff --git a/usrp/host/lib/inband/usrp_inband_usb_packet.h b/usrp/host/lib/inband/usrp_inband_usb_packet.h deleted file mode 100644 index 6f1a3feb3..000000000 --- a/usrp/host/lib/inband/usrp_inband_usb_packet.h +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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_USRP_INBAND_USB_PACKET_H_ -#define INCLUDED_USRP_INBAND_USB_PACKET_H_ - -#include <usrp_bytesex.h> -#include <mblock/mblock.h> -#include <pmt.h> -#include <iostream> - -#include <symbols_usrp_low_level_cs.h> - -static const int USB_PKT_SIZE = 512; // bytes -static const int MAX_PAYLOAD = USB_PKT_SIZE-2*sizeof(uint32_t); -static const int CONTROL_CHAN = 0x1f; - -class usrp_inband_usb_packet { - // - // keep raw packet in USRP-endian order - // - uint32_t d_word0; - uint32_t d_timestamp; - unsigned char d_payload[MAX_PAYLOAD]; - -public: - - enum opcodes { - OP_PING_FIXED = 0x00, - OP_PING_FIXED_REPLY = 0x01, - OP_WRITE_REG = 0x02, - OP_WRITE_REG_MASKED = 0x03, - OP_READ_REG = 0x04, - OP_READ_REG_REPLY = 0x05, - OP_I2C_WRITE = 0x06, - OP_I2C_READ = 0x07, - OP_I2C_READ_REPLY = 0x08, - OP_SPI_WRITE = 0x09, - OP_SPI_READ = 0x0a, - OP_SPI_READ_REPLY = 0x0b, - OP_DELAY = 0x0c - }; - - enum flags { - FL_OVERRUN = 0x80000000, - FL_UNDERRUN = 0x40000000, - FL_DROPPED = 0x20000000, - FL_START_OF_BURST = 0x10000000, - FL_END_OF_BURST = 0x08000000, - FL_CARRIER_SENSE = 0x04000000, - - FL_ALL_FLAGS = 0xfc000000 - }; - - static const int FL_OVERRUN_SHIFT = 31; - static const int FL_UNDERRUN_SHIFT = 30; - static const int FL_DROPPED_SHIFT = 29; - static const int FL_END_OF_BURST_SHIFT = 27; - static const int FL_START_OF_BURST_SHIFT = 28; - - static const int RSSI_MASK = 0x3f; - static const int RSSI_SHIFT = 21; - - static const int CHAN_MASK = 0x1f; - static const int CHAN_SHIFT = 16; - - static const int TAG_MASK = 0xf; - static const int TAG_SHIFT = 9; - - static const int PAYLOAD_LEN_MASK = 0x1ff; - static const int PAYLOAD_LEN_SHIFT = 0; - - // Fixed size for opcode and length fields - static const int CS_FIXED_LEN = 2; - - static const int CS_OPCODE_MASK = 0xff; - static const int CS_OPCODE_SHIFT = 24; - - static const int CS_LEN_MASK = 0xff; - static const int CS_LEN_SHIFT = 16; - - static const int CS_RID_MASK = 0x3f; - static const int CS_RID_SHIFT = 10; - - static const int CS_PING_LEN = 2; - static const int CS_PINGVAL_MASK = 0x3ff; - static const int CS_PINGVAL_SHIFT = 0; - - static const int CS_WRITEREG_LEN = 6; - static const int CS_WRITEREGMASKED_LEN = 10; - static const int CS_READREG_LEN = 2; - static const int CS_READREGREPLY_LEN = 6; - static const int CS_REGNUM_MASK = 0x3ff; - static const int CS_REGNUM_SHIFT = 0; - - static const int CS_DELAY_LEN = 2; - static const int CS_DELAY_MASK = 0xffff; - static const int CS_DELAY_SHIFT = 0; - - static const int CS_I2CADDR_MASK = 0x7f; - static const int CS_I2CADDR_SHIFT = 0; - - static const int CS_I2CREAD_LEN = 3; - static const int CS_I2CREADBYTES_MASK = 0x7f; - static const int CS_I2CREADBYTES_SHIFT = 24; - - static const int CS_SPIOPT_MASK = 0xffff; - static const int CS_SPIOPT_SHIFT = 0; - static const int CS_SPIFORMAT_MASK = 0xff; - static const int CS_SPIFORMAT_SHIFT = 16; - static const int CS_SPIENABLES_MASK = 0xff; - static const int CS_SPIENABLES_SHIFT = 24; - static const int CS_SPIREAD_LEN = 7; - static const int CS_SPINBYTES_MASK = 0xff; - static const int CS_SPINBYTES_SHIFT = 24; - -public: - - void set_timestamp(uint32_t timestamp){ - d_timestamp = host_to_usrp_u32(timestamp); - } - - void set_end_of_burst() { - uint32_t word0 = usrp_to_host_u32(d_word0); - word0 |= 1<<FL_END_OF_BURST_SHIFT; - d_word0 = host_to_usrp_u32(word0); - } - - void set_header(int flags, int chan, int tag, int payload_len){ - uint32_t word0 = ((flags & FL_ALL_FLAGS) - | ((chan & CHAN_MASK) << CHAN_SHIFT) - | ((tag & TAG_MASK) << TAG_SHIFT) - | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT)); - d_word0 = host_to_usrp_u32(word0); - } - - void incr_header_len(int val) { - set_header(flags(), chan(), tag(), payload_len() + val); - } - - uint32_t timestamp() const { - return usrp_to_host_u32(d_timestamp); - } - - int rssi() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> RSSI_SHIFT) & RSSI_MASK; - } - - int chan() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> CHAN_SHIFT) & CHAN_MASK; - } - - int tag() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> TAG_SHIFT) & TAG_MASK; - } - - int payload_len() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK; - } - - int flags() const { - return usrp_to_host_u32(d_word0) & FL_ALL_FLAGS; - } - - int overrun() const { - return (usrp_to_host_u32(d_word0) & FL_OVERRUN) >> FL_OVERRUN_SHIFT; - } - - - int underrun() const { - return (usrp_to_host_u32(d_word0) & FL_UNDERRUN) >> FL_UNDERRUN_SHIFT; - } - - - int start_of_burst() const { - return (usrp_to_host_u32(d_word0) & FL_START_OF_BURST) >> FL_START_OF_BURST_SHIFT; - } - - int end_of_burst() const { - return (usrp_to_host_u32(d_word0) & FL_END_OF_BURST) >> FL_END_OF_BURST_SHIFT; - } - - int dropped() const { - return (usrp_to_host_u32(d_word0) & FL_DROPPED) >> FL_DROPPED_SHIFT; - } - - unsigned char *payload() { - return d_payload; - } - - static int max_payload() { - return MAX_PAYLOAD; - } - - static int max_pkt_size() { - return USB_PKT_SIZE; - } - - // C/S methods - bool align32(); - bool cs_ping(long rid, long ping_val); - bool cs_ping_reply(long rid, long ping_val); - bool cs_write_reg(long reg_num, long val); - bool cs_write_reg_masked(long reg_num, long val, long mask); - bool cs_read_reg(long rid, long reg_num); - bool cs_read_reg_reply(long rid, long reg_num, long reg_val); - bool cs_delay(long ticks); - bool cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len); - bool cs_i2c_read(long rid, long i2c_addr, long n_bytes); - bool cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len); - bool cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len); - bool cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes); - bool cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len); - int cs_len(int payload_offset); - pmt_t read_subpacket(int payload_offset); -}; - -#endif diff --git a/usrp/host/lib/inband/usrp_interface.mbh b/usrp/host/lib/inband/usrp_interface.mbh deleted file mode 100644 index ad0f78b4e..000000000 --- a/usrp/host/lib/inband/usrp_interface.mbh +++ /dev/null @@ -1,88 +0,0 @@ -;; -*- scheme -*- ; not really, but tells emacs how to format this -;; -;; 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 2, 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. -;; - -;; ---------------------------------------------------------------- -;; This is an mblock header file -;; -;; The format is very much a work-in-progress. -;; It'll be compiled to C++. -;; ---------------------------------------------------------------- - -;; ---------------------------------------------------------------- -;; usrp-interface-cs -;; -;; Handles interaction between the usrp_sever and the USB interface - -(define-protocol-class usrp-interface-cs - - (:outgoing - (cmd-usrp-open invocation-handle which-usrp) - (cmd-usrp-close invocation-handle) - (cmd-usrp-ntx-chan invocation-handle) - (cmd-usrp-nrx-chan invocation-handle) - (cmd-usrp-write invocation-handle channel data) - (cmd-usrp-start-reading invocation-handle channel) - ) - - (:incoming - (response-usrp-open invocation-handle status) - (response-usrp-close invocation-handle status) - (response-usrp-ntx-chan invocation-handle ntx-chan) - (response-usrp-nrx-chan invocation-handle nrx-chan) - (response-usrp-write invocation-handle status channel) - (response-usrp-read invocation-handle status data) - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-tx-cs -;; -;; Handles interaction between the USB interface and TX interface - -(define-protocol-class usrp-tx-cs - - (:outgoing - (cmd-usrp-tx-write invocation-handle channel data tx-handle) - ) - - (:incoming - (response-usrp-tx-write invocation-handle status channel) - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-rx-cs -;; -;; Handles interaction between the USB interface and RX interface - -(define-protocol-class usrp-rx-cs - - (:outgoing - (cmd-usrp-rx-start-reading invocation-handle rx-handle) - (cmd-usrp-rx-stop-reading invocation-handle) - ) - - (:incoming - (response-usrp-rx-read invocation-handle status data) - - ;; There is currently no response to a stop reading - ) - ) diff --git a/usrp/host/lib/inband/usrp_rx.cc b/usrp/host/lib/inband/usrp_rx.cc deleted file mode 100644 index fe9486cf6..000000000 --- a/usrp/host/lib/inband/usrp_rx.cc +++ /dev/null @@ -1,184 +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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_rx.h> - -#include <usrp_standard.h> -#include <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include <stdio.h> - -#include <symbols_usrp_rx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -bool usrp_rx_stop; - -usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_disk_write(false), - d_disk_write_pkt(false) // if true, writes full packet, else just the payload -{ - d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL); - - if(d_disk_write) { - d_ofile0.open("rx_data_chan0.dat",std::ios::binary|std::ios::out); - d_ofile1.open("rx_data_chan1.dat",std::ios::binary|std::ios::out); - d_cs_ofile.open("rx_cs.dat",std::ios::binary|std::ios::out); - } - - usrp_rx_stop = false; - -} - -usrp_rx::~usrp_rx() -{ - if(d_disk_write) { - d_ofile0.close(); - d_ofile1.close(); - d_cs_ofile.close(); - } -} - -void -usrp_rx::initial_transition() -{ - -} - -/*! - * \brief Handles incoming signals to to the m-block, wihch should only ever be - * a single message: cmd-usrrp-rx-start-reading. There is no signal to stop - * reading as the m-block goes in to a forever loop to read inband packets from - * the bus. - */ -void -usrp_rx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol())) { - - if(pmt_eqv(event, s_cmd_usrp_rx_start_reading)) - read_and_respond(data); - } -} - -/*! - * \brief Performs the actual reading of data from the USB bus, called by - * handle_message() when a cmd-usrp-rx-start-reading signal is received. - * - * The method enters a forever loop where it continues to read data from the bus - * and generate read responses to the higher layer. Currently, shared memory is - * used to exit this loop. - * - * The \p data parameter is a PMT list which contains only a single element, an - * invocation handle which will be returned with all read respones. - */ -void -usrp_rx::read_and_respond(pmt_t data) -{ - size_t ignore; - bool underrun; - unsigned int n_read; - unsigned int pkt_size = sizeof(transport_pkt); - - pmt_t invocation_handle = pmt_nth(0, data); - - // Need the handle to the RX port to send responses, this is passed - // by the USRP interface m-block - pmt_t handle = pmt_nth(1, data); - d_urx = - boost::any_cast<usrp_standard_rx_sptr>(pmt_any_ref(handle)); - - if(verbose) - std::cout << "[usrp_rx] Waiting for packets..\n"; - - // Read by 512 which is packet size and send them back up - while(!usrp_rx_stop) { - - pmt_t v_pkt = pmt_make_u8vector(pkt_size, 0); - transport_pkt *pkt = - (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore); - - n_read = d_urx->read(pkt, pkt_size, &underrun); - - if(n_read != pkt_size) { - std::cerr << "[usrp_rx] Error reading packet, shutting down\n"; - d_cs->send(s_response_usrp_rx_read, - pmt_list3(PMT_NIL, PMT_F, PMT_NIL)); - return; - } - - if(underrun && verbose && 0) - std::cout << "[usrp_rx] Underrun\n"; - - d_cs->send(s_response_usrp_rx_read, - pmt_list3(PMT_NIL, PMT_T, v_pkt)); - if(verbose && 0) - std::cout << "[usrp_rx] Read 1 packet\n"; - - if(d_disk_write) { - if(pkt->chan() == CONTROL_CHAN) - d_cs_ofile.write((const char *)pkt, transport_pkt::max_pkt_size()); - else { - if(d_disk_write_pkt) { - if(pkt->chan() == 0) - d_ofile0.write((const char *)pkt, transport_pkt::max_pkt_size()); - else if(pkt->chan() == 1) - d_ofile1.write((const char *)pkt, transport_pkt::max_pkt_size()); - } else { - if(pkt->chan() == 0) - d_ofile0.write((const char *)pkt->payload(), transport_pkt::max_payload()); - else if(pkt->chan() == 1) - d_ofile1.write((const char *)pkt->payload(), transport_pkt::max_payload()); - } - } - - d_cs_ofile.flush(); - d_ofile0.flush(); - d_ofile1.flush(); - } - } - - usrp_rx_stop = false; - - if(verbose) { - std::cout << "[USRP_RX] Stopping...\n"; - fflush(stdout); - } -} - -REGISTER_MBLOCK_CLASS(usrp_rx); diff --git a/usrp/host/lib/inband/usrp_rx.h b/usrp/host/lib/inband/usrp_rx.h deleted file mode 100644 index 1006235bf..000000000 --- a/usrp/host/lib/inband/usrp_rx.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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_USRP_RX_H -#define INCLUDED_USRP_RX_H - -#include <mblock/mblock.h> -#include <fstream> -#include "usrp_standard.h" - -extern bool usrp_rx_stop; // used to communicate a 'stop' to the RX stub - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_rx : public mb_mblock -{ - mb_port_sptr d_cs; - usrp_standard_rx_sptr d_urx; - - bool d_disk_write; - bool d_disk_write_pkt; - std::ofstream d_ofile0; - std::ofstream d_ofile1; - std::ofstream d_cs_ofile; - - public: - usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_rx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void read_and_respond(pmt_t data); - void read_data(); - -}; - - -#endif /* INCLUDED_USRP_RX_H */ - diff --git a/usrp/host/lib/inband/usrp_rx_stub.cc b/usrp/host/lib/inband/usrp_rx_stub.cc deleted file mode 100644 index e5c454d24..000000000 --- a/usrp/host/lib/inband/usrp_rx_stub.cc +++ /dev/null @@ -1,227 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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 <usrp_rx_stub.h> - -#include <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include "usrp_standard.h" -#include <stdio.h> -#include <string.h> -#include <ui_nco.h> -#include <fstream> - -#include <symbols_usrp_rx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -bool usrp_rx_stop_stub; - -// Used for the fake control packet response code to send the responses back up -// the RX. The TX stub dumps responses in to this queue. -std::queue<pmt_t> d_cs_queue; - -usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_samples_per_frame((long)(126)), - d_decim_rx(128), - d_amplitude(16384), - d_disk_write(false) -{ - - // Information about the rates are passed all the way from the app in the form - // of a dictionary. We use this to read the RX decimation rate and compute - // the approximate number of MS/s as a form of flow control for the stub. - pmt_t usrp_dict = user_arg; - - if (pmt_is_dict(usrp_dict)) { - // Read the RX decimation rate - if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, - pmt_intern("decim-rx"), - PMT_NIL)) { - if(!pmt_eqv(decim_rx, PMT_NIL)) - d_decim_rx = pmt_to_long(decim_rx); - } - } - - d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL); - - // initialize NCO - double freq = 100e3; - int interp = 32; // 32 -> 4MS/s - double sample_rate = 64e6 / interp; - d_nco.set_freq(2*M_PI * freq/sample_rate); - - //d_disk_write = true; - - if(d_disk_write) - d_ofile.open("raw_rx.dat",std::ios::binary|std::ios::out); - - usrp_rx_stop_stub = false; -} - -usrp_rx_stub::~usrp_rx_stub() -{ - if(d_disk_write) - d_ofile.close(); -} - -void -usrp_rx_stub::initial_transition() -{ -} - -void -usrp_rx_stub::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - if (pmt_eq(msg->signal(), s_timeout) - && !pmt_eq(msg->data(), s_done)) { - - if(!usrp_rx_stop_stub) - read_and_respond(); - else { // requested to stop - cancel_timeout(msg->metadata()); - usrp_rx_stop_stub=false; - if(verbose) - std::cout << "[USRP_RX_STUB] Stopping RX stub\n"; - } - - } - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol()) - && pmt_eqv(event, s_cmd_usrp_rx_start_reading)) { - - if(verbose) - std::cout << "[USRP_RX_STUB] Starting with decim @ " - << d_decim_rx << std::endl; - - start_packet_timer(); - } -} - -// Setup a periodic timer which will drive packet generation -void -usrp_rx_stub::start_packet_timer() -{ - d_t0 = mb_time::time(); // current time - - // Calculate the inter-packet arrival time. - double samples_per_sec = (64.0/(double)d_decim_rx)*1000000.0; - double frames_per_sec = samples_per_sec / (double)d_samples_per_frame; - double frame_rate = 1.0 / frames_per_sec; - - if(verbose) { - std::cout << "[USRP_RX_STUB] Scheduling periodic packet generator\n"; - std::cout << "\tsamples_per_sec: " << samples_per_sec << std::endl; - std::cout << "\tframes_per_sec: " << frames_per_sec << std::endl; - std::cout << "\tframe_rate: " << frame_rate << std::endl; - } - - schedule_periodic_timeout(d_t0 + frame_rate, mb_time(frame_rate), PMT_T); -} - -void -usrp_rx_stub::read_and_respond() -{ - - long nsamples_this_frame = d_samples_per_frame; - - size_t nshorts = 2 * nsamples_this_frame; // 16-bit I & Q - long channel = 0; - long n_bytes = nshorts*2; - pmt_t uvec = pmt_make_s16vector(nshorts, 0); - size_t ignore; - int16_t *samples = pmt_s16vector_writable_elements(uvec, ignore); - - // fill in the complex sinusoid - - for (int i = 0; i < nsamples_this_frame; i++){ - - if (1){ - gr_complex s; - d_nco.sincos(&s, 1, d_amplitude); - // write 16-bit i & q - samples[2*i] = (int16_t) s.real(); - samples[2*i+1] = (int16_t) s.imag(); - } - else { - gr_complex s(d_amplitude, d_amplitude); - - // write 16-bit i & q - samples[2*i] = (int16_t) s.real(); - samples[2*i+1] = (int16_t) s.imag(); - } - } - - if(d_disk_write) - d_ofile.write((const char *)samples, n_bytes); - - pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = - (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore); - - pkt->set_header(0, channel, 0, n_bytes); - pkt->set_timestamp(0xffffffff); - memcpy(pkt->payload(), samples, n_bytes); - - d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt)); - - // Now lets check the shared CS queue between the TX and RX stub. Each - // element in a queue is a list where the first element is an invocation - // handle and the second element is a PMT u8 vect representation of the - // CS packet response which can just be passed transparently. - while(!d_cs_queue.empty()) { - - pmt_t cs_pkt = d_cs_queue.front(); - d_cs_queue.pop(); - - pmt_t invocation_handle = pmt_nth(0, cs_pkt); - pmt_t v_pkt = pmt_nth(1, cs_pkt); - - d_cs->send(s_response_usrp_rx_read, - pmt_list3(invocation_handle, - PMT_T, - v_pkt)); // Take the front CS pkt - - - if(verbose) - std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n"; - } - -} - -REGISTER_MBLOCK_CLASS(usrp_rx_stub); diff --git a/usrp/host/lib/inband/usrp_rx_stub.h b/usrp/host/lib/inband/usrp_rx_stub.h deleted file mode 100644 index 238b4568f..000000000 --- a/usrp/host/lib/inband/usrp_rx_stub.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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_USRP_RX_STUB_H -#define INCLUDED_USRP_RX_STUB_H - -#include <mblock/mblock.h> -#include <vector> -#include "usrp_standard.h" -#include <ui_nco.h> -#include <fstream> -#include <queue> -#include <usrp_inband_usb_packet.h> - -typedef usrp_inband_usb_packet transport_pkt; - -extern bool usrp_rx_stop_stub; // used to communicate a 'stop' to the RX stub -extern std::queue<pmt_t> d_cs_queue; - -static pmt_t s_timeout = pmt_intern("%timeout"); -static pmt_t s_done = pmt_intern("done"); - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_rx_stub : public mb_mblock -{ - public: - - mb_port_sptr d_cs; - usrp_standard_rx* d_urx; - - long d_samples_per_frame; - long d_decim_rx; - - mb_time d_t0; - double d_delta_t; - - // for generating sine wave output - ui_nco<float,float> d_nco; - double d_amplitude; - - bool d_disk_write; - - std::ofstream d_ofile; - - public: - usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_rx_stub(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void read_and_respond(); - void read_data(); - void start_packet_timer(); - -}; - - -#endif /* INCLUDED_USRP_RX_H */ - diff --git a/usrp/host/lib/inband/usrp_server.cc b/usrp/host/lib/inband/usrp_server.cc deleted file mode 100644 index ac2636308..000000000 --- a/usrp/host/lib/inband/usrp_server.cc +++ /dev/null @@ -1,1860 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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 <usrp_server.h> -#include <iostream> -#include <usrp_inband_usb_packet.h> -#include <mblock/class_registry.h> -#include <vector> -#include <usrp_usb_interface.h> -#include <string.h> -#include <fpga_regs_common.h> -#include <fpga_regs_standard.h> - -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_interface_cs.h> - -static pmt_t s_shutdown = pmt_intern("%shutdown"); - -typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy - -const static bool verbose = false; - -static std::string -str(long x) -{ - std::ostringstream s; - s << x; - return s.str(); -} - -usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_fpga_debug(false), - d_interp_tx(128), // these should match the lower level defaults (rx also) - d_decim_rx(128), - d_fake_rx(false) -{ - if(verbose) - std::cout << "[USRP_SERVER] Initializing...\n"; - - // Dictionary for arguments to all of the components - d_usrp_dict = user_arg; - - if (pmt_is_dict(d_usrp_dict)) { - - if(pmt_t fpga_debug = pmt_dict_ref(d_usrp_dict, - pmt_intern("fpga-debug"), - PMT_NIL)) { - if(pmt_eqv(fpga_debug, PMT_T)) - d_fpga_debug=true; - } - - // Read the TX interpolations - if(pmt_t interp_tx = pmt_dict_ref(d_usrp_dict, - pmt_intern("interp-tx"), - PMT_NIL)) { - if(!pmt_eqv(interp_tx, PMT_NIL)) - d_interp_tx = pmt_to_long(interp_tx); - } - - // Read the RX decimation rate - if(pmt_t decim_rx = pmt_dict_ref(d_usrp_dict, - pmt_intern("decim-rx"), - PMT_NIL)) { - if(!pmt_eqv(decim_rx, PMT_NIL)) - d_decim_rx = pmt_to_long(decim_rx); - } - } - - // control & status port - d_cs = define_port("cs", "usrp-server-cs", true, mb_port::EXTERNAL); - d_cs_usrp = define_port("cs_usrp", "usrp-interface-cs", false, mb_port::INTERNAL); - - // ports - // - // (if/when we do replicated ports, these will be replaced by a - // single replicated port) - for(int port=0; port < N_PORTS; port++) { - - d_tx.push_back(define_port("tx"+str(port), - "usrp-tx", - true, - mb_port::EXTERNAL)); - - d_rx.push_back(define_port("rx"+str(port), - "usrp-rx", - true, - mb_port::EXTERNAL)); - } - - define_component("usrp", "usrp_usb_interface", d_usrp_dict); - connect("self", "cs_usrp", "usrp", "cs"); - - d_defer=false; - d_opened=false; - - // FIXME: needs to be returned from open, if we want to use this - d_nrx_chan = 2; - d_ntx_chan = 2; - - // Initialize capacity on each channel to 0 and to no owner - // Also initialize the USRP standard tx/rx pointers to NULL - for(int chan=0; chan < d_ntx_chan; chan++) - d_chaninfo_tx.push_back(channel_info()); - - for(int chan=0; chan < d_nrx_chan; chan++) - d_chaninfo_rx.push_back(channel_info()); - - d_rx_chan_mask = 0; - - for(int i=0; i < D_MAX_RID; i++) - d_rids.push_back(rid_info()); - - //d_fake_rx=true; -} - -/*! - * \brief resets the assigned capacity and owners of each RX and TX channel from - * allocations. - */ -void -usrp_server::reset_channels() -{ - - for(int chan=0; chan < d_ntx_chan; chan++) { - d_chaninfo_tx[chan].assigned_capacity = 0; - d_chaninfo_tx[chan].owner = PMT_NIL; - } - - for(int chan=0; chan < d_nrx_chan; chan++) { - d_chaninfo_rx[chan].assigned_capacity = 0; - d_chaninfo_rx[chan].owner = PMT_NIL; - } - - d_rx_chan_mask = 0; -} - -usrp_server::~usrp_server() -{ -} - - -void -usrp_server::initial_transition() -{ - // the initial transition -} - -/*! - * \brief Reads all incoming messages to USRP server from the TX, RX, and the CS - * ports. This drives the state of USRP server and dispatches based on the - * message. - */ -void -usrp_server::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); // the "name" of the message - pmt_t port_id = msg->port_id(); // which port it came in on - pmt_t data = msg->data(); - pmt_t invocation_handle; - pmt_t metadata = msg->metadata(); - pmt_t status; - - long port; - - if (pmt_eq(event, s_shutdown)) // ignore (for now) - return; - - invocation_handle = pmt_nth(0, data); - - if (0){ - std::cout << "[USRP_SERVER] event: " << event << std::endl; - std::cout << "[USRP_SERVER] port_id: " << port_id << std::endl; - } - - // It would be nice if this were all table driven, and we could compute our - // state transition as f(current_state, port_id, signal) - - // A message from the USRP CS, which should *only* be responses - // - // It is important that this set come before checking messages of any other - // components. This is since we always want to listen to the low level USRP - // server, even if we aren't initialized we are waiting for responses to - // become initialized. Likewise, after the usrp_server is "closed", we still - // want to pass responses back from the low level. - - //---------------- USRP RESPONSE ---------------// - if (pmt_eq(port_id, d_cs_usrp->port_symbol())) { - - //-------------- USRP OPEN ------------------// - if(pmt_eq(event, s_response_usrp_open)) { - // pass the response back over the regular CS port - pmt_t status = pmt_nth(1, data); - d_cs->send(s_response_open, pmt_list2(invocation_handle, status)); - - //reset_all_registers(); - //initialize_registers(); - - if(pmt_eqv(status,PMT_T)) { - d_opened = true; - d_defer = false; - recall_defer_queue(); - } - - return; - } - //------------- USRP CLOSE -------------------// - else if (pmt_eq(event, s_response_usrp_close)) { - pmt_t status = pmt_nth(1, data); - d_cs->send(s_response_close, pmt_list2(invocation_handle, status)); - - if(pmt_eqv(status,PMT_T)) { - d_opened = false; - d_defer = false; - reset_channels(); - recall_defer_queue(); - } - - return; - } - //--------------- USRP WRITE --------------// - else if (pmt_eq(event, s_response_usrp_write)) { - - pmt_t status = pmt_nth(1, data); - long channel = pmt_to_long(pmt_nth(2, data)); - long port; - - // Do not report back responses if they were generated from a - // command packet - if(channel == CONTROL_CHAN) - return; - - // Find the port through the owner of the channel - if((port = tx_port_index(d_chaninfo_tx[channel].owner)) !=-1 ) - d_tx[port]->send(s_response_xmit_raw_frame, - pmt_list2(invocation_handle, status)); - return; - } - //--------------- USRP READ ---------------// - else if (pmt_eq(event, s_response_usrp_read)) { - - pmt_t status = pmt_nth(1, data); - - if(!pmt_eqv(status, PMT_T)) { - std::cerr << "[USRP_SERVER] Error receiving packet\n"; - return; - } - else { - handle_response_usrp_read(data); - return; - } - } - - goto unhandled; - } - - // Checking for defer on all other messages - if(d_defer) { - if (verbose) - std::cout << "[USRP_SERVER] Received msg while deferring (" - << msg->signal() << ")\n"; - d_defer_queue.push(msg); - return; - } - - //--------- CONTROL / STATUS ------------// - if (pmt_eq(port_id, d_cs->port_symbol())){ - - //----------- OPEN -----------// - if (pmt_eq(event, s_cmd_open)){ - - // Reject if already open - if(d_opened) { - d_cs->send(s_response_open, pmt_list2(invocation_handle, s_err_usrp_already_opened)); - return; - } - - // the parameters are the same to the low level interface, so we just pass 'data' along - d_cs_usrp->send(s_cmd_usrp_open, data); - - d_defer = true; - - return; - } - //---------- CLOSE -----------// - else if (pmt_eq(event, s_cmd_close)){ - - if(!d_opened) { - d_cs->send(s_response_close, pmt_list2(invocation_handle, s_err_usrp_already_closed)); - return; - } - - d_defer = true; - d_cs_usrp->send(s_cmd_usrp_close, pmt_list1(invocation_handle)); - - return; - } - //---------- MAX CAPACITY ----------// - else if (pmt_eq(event, s_cmd_max_capacity)) { - - if(!d_opened) { - d_cs->send(s_response_max_capacity, - pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0))); - return; - } - - d_cs->send(s_response_max_capacity, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(max_capacity()))); - return; - } - //---------- NTX CHAN --------------// - else if (pmt_eq(event, s_cmd_ntx_chan)) { - - if(!d_opened) { - d_cs->send(s_response_ntx_chan, - pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0))); - return; - } - - d_cs->send(s_response_ntx_chan, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(d_ntx_chan))); - return; - } - //---------- NRX CHAN -----------// - else if (pmt_eq(event, s_cmd_nrx_chan)) { - - if(!d_opened) { - d_cs->send(s_response_nrx_chan, - pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0))); - return; - } - - d_cs->send(s_response_nrx_chan, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(d_nrx_chan))); - return; - } - //--------- ALLOCATION? -----------// - else if (pmt_eq(event, s_cmd_current_capacity_allocation)) { - - if(!d_opened) { - d_cs->send(s_response_current_capacity_allocation, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - d_cs->send(s_response_current_capacity_allocation, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(current_capacity_allocation()))); - return; - } - goto unhandled; - } - - //-------------- TX ---------------// - if ((port = tx_port_index(port_id)) != -1) { - - //------------ ALLOCATE (TX) ----------------// - if (pmt_eq(event, s_cmd_allocate_channel)){ - - if(!d_opened) { - d_tx[port]->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_allocate_channel(d_tx[port], d_chaninfo_tx, data); - return; - } - - //----------- DEALLOCATE (TX) ---------------// - if (pmt_eq(event, s_cmd_deallocate_channel)) { - - if(!d_opened) { - d_tx[port]->send(s_response_deallocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_deallocate_channel(d_tx[port], d_chaninfo_tx, data); - return; - } - - //-------------- XMIT RAW FRAME -----------------/ - if (pmt_eq(event, s_cmd_xmit_raw_frame)){ - - if(!d_opened) { - d_tx[port]->send(s_response_xmit_raw_frame, - pmt_list2(invocation_handle, s_err_usrp_not_opened)); - return; - } - - handle_cmd_xmit_raw_frame(d_tx[port], d_chaninfo_tx, data); - return; - } - - //-------------- CONTROL PACKET -----------------/ - if (pmt_eq(event, s_cmd_to_control_channel)) { - - if(!d_opened) { - d_tx[port]->send(s_response_xmit_raw_frame, - pmt_list2(invocation_handle, s_err_usrp_not_opened)); - return; - } - - handle_cmd_to_control_channel(d_tx[port], d_chaninfo_tx, data); - return; - - } - - goto unhandled; - } - - //-------------- RX ---------------// - if ((port = rx_port_index(port_id)) != -1) { - - //------------ ALLOCATE (RX) ----------------// - if (pmt_eq(event, s_cmd_allocate_channel)) { - - if(!d_opened) { - d_rx[port]->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_allocate_channel(d_rx[port], d_chaninfo_rx, data); - return; - } - - //----------- DEALLOCATE (RX) ---------------// - if (pmt_eq(event, s_cmd_deallocate_channel)) { - - if(!d_opened) { - d_rx[port]->send(s_response_deallocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_deallocate_channel(d_rx[port], d_chaninfo_rx, data); - return; - } - - //-------------- START RECV ----------------// - if (pmt_eq(event, s_cmd_start_recv_raw_samples)) { - - if(!d_opened) { - d_rx[port]->send(s_response_recv_raw_samples, - pmt_list2(invocation_handle, s_err_usrp_not_opened)); - return; - } - - handle_cmd_start_recv_raw_samples(d_rx[port], d_chaninfo_rx, data); - return; - } - - //-------------- STOP RECV ----------------// - if (pmt_eq(event, s_cmd_stop_recv_raw_samples)) { - - if(!d_opened) - return; - - // FIX ME : no response for stopping? even if error? (permissions) - handle_cmd_stop_recv_raw_samples(d_rx[port], d_chaninfo_rx, data); - - return; - } - - goto unhandled; - } - - unhandled: - std::cout << "[USRP_SERVER] unhandled msg: " << msg << std::endl; -} - -/*! - * \brief Takes a port_symbol() as parameter \p port_id and is used to determine - * if the port is a TX port, or to find an index in the d_tx vector which stores - * the port. - * - * \returns -1 if \p port_id is not in the d_tx vector (i.e., it's not a TX - * port), otherwise returns an index in the d_tx vector which stores the port. - */ -int usrp_server::tx_port_index(pmt_t port_id) { - - for(int i=0; i < (int) d_tx.size(); i++) - if(pmt_eq(d_tx[i]->port_symbol(), port_id)) - return i; - - return -1; -} - -/*! - * \brief Takes a port_symbol() as parameter \p port_id and is used to determine - * if the port is an RX port, or to find an index in the d_rx vector which - * stores the port. - * - * \returns -1 if \p port_id is not in the d_rx vector (i.e., it's not an RX - * port), otherwise returns an index in the d_rx vector which stores the port. - */ -int usrp_server::rx_port_index(pmt_t port_id) { - - for(int i=0; i < (int) d_rx.size(); i++) - if(pmt_eq(d_rx[i]->port_symbol(), port_id)) - return i; - - return -1; -} - -/*! - * \brief Determines the current total capacity allocated by all RX and TX - * channels. - * - * \returns the total allocated capacity - */ -long usrp_server::current_capacity_allocation() { - long capacity = 0; - - for(int chan=0; chan < d_ntx_chan; chan++) - capacity += d_chaninfo_tx[chan].assigned_capacity; - - for(int chan=0; chan < d_nrx_chan; chan++) - capacity += d_chaninfo_rx[chan].assigned_capacity; - - return capacity; -} - - -/*! - * \brief Called by the handle_message() method if the incoming message to - * usrp_server is to allocate a channel (cmd-allocate-channel). The method - * checks if the requested capacity exists and if so it will reserve it for the - * caller on the channel that is returned via a response-allocate-channel - * signal. - */ -void -usrp_server::handle_cmd_allocate_channel( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long rqstd_capacity = pmt_to_long(pmt_nth(1, data)); - long chan; - - // Check capacity exists - if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) { - - // no capacity available - port->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_requested_capacity_unavailable, - PMT_NIL)); - return; - } - - // Find a free channel, assign the capacity and respond - for(chan=0; chan < (long)chan_info.size(); chan++) { - - if(verbose) - std::cout << "[USRP_SERVER] Checking chan: " << chan - << " owner " << chan_info[chan].owner - << " size " << chan_info.size() - << std::endl; - - if(chan_info[chan].owner == PMT_NIL) { - - chan_info[chan].owner = port->port_symbol(); - chan_info[chan].assigned_capacity = rqstd_capacity; - - port->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(chan))); - - if(verbose) - std::cout << "[USRP_SERVER] Assigning channel: " << chan - << " to " << chan_info[chan].owner - << std::endl; - return; - } - - } - - if (verbose) - std::cout << "[USRP_SERVER] Couldnt find a TX chan\n"; - - // no free TX chan found - port->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_channel_unavailable, - PMT_NIL)); - return; -} - -/*! - * \brief Called by the handle_message() method if the incoming message to - * usrp_server is to deallocate a channel (cmd-deallocate-channel). The method - * ensures that the sender of the signal owns the channel and that the channel - * number is valid. A response-deallocate-channel signal is sent back with the - * result of the deallocation. - */ -void -usrp_server::handle_cmd_deallocate_channel( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - - pmt_t invocation_handle = pmt_nth(0, data); - long channel = pmt_to_long(pmt_nth(1, data)); - - // Ensure the channel is valid and the caller owns the port - if(!check_valid(port, channel, chan_info, - pmt_list2(s_response_deallocate_channel, invocation_handle))) - return; - - chan_info[channel].assigned_capacity = 0; - chan_info[channel].owner = PMT_NIL; - - port->send(s_response_deallocate_channel, - pmt_list2(invocation_handle, - PMT_T)); - return; -} - -/*! - * \brief Called by the handle_message() method if the incoming message to - * usrp_server is to transmit a frame (cmd-xmit-raw-frame). The method - * allocates enough memory to support a burst of packets which contain the frame - * over the bus of the frame, sets the packet headers, and sends a signal to the - * lower block for the data (packets) to be written to the bus. - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel the frame is to be transmitted on are passed to ensure that the - * caller owns the channel. - * - * The \p data parameter is in the format of a cmd-xmit-raw-frame signal. - * - * The properties - */ -void usrp_server::handle_cmd_xmit_raw_frame( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - size_t n_bytes, psize; - long max_payload_len = transport_pkt::max_payload(); - - pmt_t invocation_handle = pmt_nth(0, data); - long channel = pmt_to_long(pmt_nth(1, data)); - const void *samples = pmt_uniform_vector_elements(pmt_nth(2, data), n_bytes); - long timestamp = pmt_to_long(pmt_nth(3, data)); - pmt_t properties = pmt_nth(4, data); - - // Ensure the channel is valid and the caller owns the port - if(!check_valid(port, channel, chan_info, - pmt_list2(s_response_xmit_raw_frame, invocation_handle))) - return; - - // Read information from the properties of the packet - bool carrier_sense = false; - if(pmt_is_dict(properties)) { - - // Check if carrier sense is enabled for the frame - if(pmt_t p_carrier_sense = pmt_dict_ref(properties, - pmt_intern("carrier-sense"), - PMT_NIL)) { - if(pmt_eqv(p_carrier_sense, PMT_T)) - carrier_sense = true; - } - } - - - // Determine the number of packets to allocate contiguous memory for - // bursting over the USB and get a pointer to the memory to be used in - // building the packets - long n_packets = - static_cast<long>(std::ceil(n_bytes / (double)max_payload_len)); - - pmt_t v_packets = pmt_make_u8vector(sizeof(transport_pkt) * n_packets, 0); - - transport_pkt *pkts = - (transport_pkt *) pmt_u8vector_writable_elements(v_packets, psize); - - for(int n=0; n < n_packets; n++) { - - long payload_len = - std::min((long)(n_bytes-(n*max_payload_len)), (long)max_payload_len); - - if(n == 0) { // first packet gets start of burst flag and timestamp - - if(carrier_sense) - pkts[n].set_header(pkts[n].FL_START_OF_BURST - | pkts[n].FL_CARRIER_SENSE, - channel, 0, payload_len); - else - pkts[n].set_header(pkts[n].FL_START_OF_BURST, channel, 0, payload_len); - - pkts[n].set_timestamp(timestamp); - - } else { - pkts[n].set_header(0, channel, 0, payload_len); - pkts[n].set_timestamp(0xffffffff); - } - - memcpy(pkts[n].payload(), - (uint8_t *)samples+(max_payload_len * n), - payload_len); - - } - - - pkts[n_packets-1].set_end_of_burst(); // set the last packet's end of burst - - if (verbose && 0) - std::cout << "[USRP_SERVER] Received raw frame invocation: " - << invocation_handle << std::endl; - - // The actual response to the write will be generated by a - // s_response_usrp_write since we cannot determine whether to transmit was - // successful until we hear from the lower layers. - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packets)); - - return; -} - -/*! - * \brief Called by the handle_message() method to parse incoming control/status - * signals (cmd-to-control-channel). - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel are passed to ensure that the caller owns the channel. - * - * The \p data parameter is in the format of a PMT list, where each element - * follows the format of a control/status signal (i.e. op-ping-fixed). - * - * The method will parse all of the C/S commands included in \p data and place - * the commands in to a lower level packet sent to the control channel. The - * method will pack as many commands as possible in t oa single packet, and once - * it is fill generate as many lower level packets as needed. - * - * Anything that needs to be returned to the sender of the signal (i.e. the - * value of a register) will be generated by the parse_control_pkt() method as - * the responses to the commands are read back from the USRP. - */ -void usrp_server::handle_cmd_to_control_channel( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t subpackets = pmt_nth(1, data); - - long n_subpkts = pmt_length(subpackets); - long curr_subpkt = 0; - - size_t psize; - long payload_len = 0; - long channel = CONTROL_CHAN; - - if(verbose) - std::cout << "[USRP_SERVER] Handling " << n_subpkts << " commands\n"; - - // The design of the following code is optimized for simplicity, not - // performance. To performance optimize this code, the total size in bytes - // needed for all of the CS packets is needed to allocate contiguous memory - // which contains the USB packets for bursting over the bus. However to do - // this the packets subpackets would need to be parsed twice and their sizes - // would need to be determined. - // - // The approach taken is to keep parsing the subpackets and putting them in to - // USB packets. Once the USB packet is full, a write is sent for it and - // another packet is created. - // - // The subpacket creation methods will return false if the subpacket will not - // fit in to the current USB packet. In these cases a new USB packet is - // created and the old is sent. - - new_packet: - // This code needs to become "smart" and only make a new packet when full - pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize); - payload_len = 0; - - pkt->set_header(0, channel, 0, payload_len); - pkt->set_timestamp(0xffffffff); - - while(curr_subpkt < n_subpkts) { - - pmt_t subp = pmt_nth(curr_subpkt, subpackets); - pmt_t subp_cmd = pmt_nth(0, subp); - pmt_t subp_data = pmt_nth(1, subp); - - //--------- PING FIXED --------------// - if(pmt_eq(subp_cmd, s_op_ping_fixed)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long pingval = pmt_to_long(pmt_nth(1, subp_data)); - - // USRP server sets request ID's to keep track of which application gets - // what response back. To allow a full 6-bits for an RID to the user, we - // keep a mapping and replace the RID's as the packets go in and out. If - // there are no RID's available, the command is thrown away silently. - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - // We use a vector to store the owner of the ping request and will use it - // to send the request on any RX port they own. - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - // Adds a ping after the previous command in the pkt - if(!pkt->cs_ping(srid, pingval)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received ping command request" - << " assigning RID " << srid << std::endl; - - } - - //----------- WRITE REG ---------------// - if(pmt_eq(subp_cmd, s_op_write_reg)) { - - long reg_num = pmt_to_long(pmt_nth(0, subp_data)); - long val = pmt_to_long(pmt_nth(1, subp_data)); - - if(!pkt->cs_write_reg(reg_num, val)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received write register request " - << "(" - << "Reg: " << reg_num << ", " - << "Val: " << val - << ")\n"; - } - - //------- WRITE REG MASKED ----------// - if(pmt_eq(subp_cmd, s_op_write_reg_masked)) { - - long reg_num = pmt_to_long(pmt_nth(0, subp_data)); - long val = pmt_to_long(pmt_nth(1, subp_data)); - long mask = pmt_to_long(pmt_nth(2, subp_data)); - - if(!pkt->cs_write_reg_masked(reg_num, val, mask)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received write register masked request\n"; - } - - //------------ READ REG --------------// - if(pmt_eq(subp_cmd, s_op_read_reg)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long reg_num = pmt_to_long(pmt_nth(1, subp_data)); - - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - if(!pkt->cs_read_reg(srid, reg_num)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - // Return the rid - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received read register request" - << " assigning RID " << srid << std::endl; - } - - //------------ DELAY --------------// - if(pmt_eq(subp_cmd, s_op_delay)) { - - long ticks = pmt_to_long(pmt_nth(0, subp_data)); - - if(!pkt->cs_delay(ticks)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received delay request of " - << ticks << " ticks\n"; - } - - //--------- I2C WRITE -----------// - // FIXME: could check that byte count does not exceed 2^8 which - // is the max length in the subpacket for # of bytes to read. - if(pmt_eq(subp_cmd, s_op_i2c_write)) { - - long i2c_addr = pmt_to_long(pmt_nth(0, subp_data)); - pmt_t data = pmt_nth(1, subp_data); - - // Get a readable address to the data which also gives us the length - size_t data_len; - uint8_t *i2c_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len); - - // Make the USB packet - if(!pkt->cs_i2c_write(i2c_addr, i2c_data, data_len)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received I2C write\n"; - } - - //----------- I2C Read -------------// - if(pmt_eq(subp_cmd, s_op_i2c_read)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long i2c_addr = pmt_to_long(pmt_nth(1, subp_data)); - long i2c_bytes = pmt_to_long(pmt_nth(2, subp_data)); - - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - if(!pkt->cs_i2c_read(srid, i2c_addr, i2c_bytes)) - { - - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received I2C read\n"; - } - - //--------- SPI WRITE -----------// - if(pmt_eq(subp_cmd, s_op_spi_write)) { - - long enables = pmt_to_long(pmt_nth(0, subp_data)); - long format = pmt_to_long(pmt_nth(1, subp_data)); - long opt = pmt_to_long(pmt_nth(2, subp_data)); - pmt_t data = pmt_nth(3, subp_data); - - // Get a readable address to the data which also gives us the length - size_t data_len; - uint8_t *spi_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len); - - // Make the USB packet - if(!pkt->cs_spi_write(enables, format, opt, spi_data, data_len)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received SPI write\n"; - } - - //--------- SPI READ -----------// - if(pmt_eq(subp_cmd, s_op_spi_read)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long enables = pmt_to_long(pmt_nth(1, subp_data)); - long format = pmt_to_long(pmt_nth(2, subp_data)); - long opt = pmt_to_long(pmt_nth(3, subp_data)); - long n_bytes = pmt_to_long(pmt_nth(4, subp_data)); - - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - // Make the USB packet - if(!pkt->cs_spi_read(srid, enables, format, opt, n_bytes)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - // Return the rid - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received SPI read\n"; - } - - subpkt_bail: - curr_subpkt++; - - } - - - // If the current packets length is > 0, we know there are subpackets that - // need to be sent out still. - if(pkt->payload_len() > 0) - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is a - * command to start reading samples from the USRP (cmd-start-recv-raw-samples). - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel are passed to ensure that the caller owns the channel. - * - * The \p data parameter should be in the format of a cmd-start-recv-raw-samples - * command where the first element in the list is an invocation handle, and the - * second is the channel the signal generator wants to receive the samples on. - */ -void -usrp_server::handle_cmd_start_recv_raw_samples( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long channel = pmt_to_long(pmt_nth(1, data)); - - // Ensure the channel is valid and the caller owns the port - if(!check_valid(port, channel, chan_info, - pmt_list2(s_response_xmit_raw_frame, invocation_handle))) - return; - - // Already started receiving samples? (another start before a stop) - // Check the RX channel bitmask. - if(d_rx_chan_mask & (1 << channel)) { - port->send(s_response_recv_raw_samples, - pmt_list5(invocation_handle, - s_err_already_receiving, - PMT_NIL, - PMT_NIL, - PMT_NIL)); - return; - } - - // We only need to generate a 'start reading' command down to the - // low level interface if no other channel is already reading - // - // We carry this over the CS interface because the lower level - // interface does not care about the channel, we only demux it - // at the usrp_server on responses. - if(d_rx_chan_mask == 0) { - - if(verbose) - std::cout << "[USRP_SERVER] Sending read request down to start recv\n"; - - d_cs_usrp->send(s_cmd_usrp_start_reading, pmt_list1(invocation_handle)); - } - - d_rx_chan_mask |= 1<<channel; - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * stop receiving samples from the USRP (cmd-stop-recv-raw-samples). - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel are passed to ensure that the caller owns the channel. - * - * The \p data parameter should be in the format of a cmd-stop-recv-raw-samples - * command where the first element in the list is an invocation handle, and the - * second is the channel the signal generator wants to stop receiving the - * samples from. - */ -void -usrp_server::handle_cmd_stop_recv_raw_samples( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long channel = pmt_to_long(pmt_nth(1, data)); - - // FIX ME : we have no responses to send an error... - // Ensure the channel is valid and the caller owns the port - //if(!check_valid(port, channel, chan_info, - // pmt_list2(s_response_xmit_raw_frame, invocation_handle))) - // return; - - // Remove this hosts bit from the receiver mask - d_rx_chan_mask &= ~(1<<channel); - - // We only need to generate a 'start reading' command down to the - // low level interface if no other channel is already reading - // - // We carry this over the CS interface because the lower level - // interface does not care about the channel, we only demux it - // at the usrp_server on responses. - if(d_rx_chan_mask == 0) { - - if(verbose) - std::cout << "[USRP_SERVER] Sending stop reading request down\n"; - - d_cs_usrp->send(s_cmd_usrp_stop_reading, pmt_list1(invocation_handle)); - } - - return; -} - -/*! - * \brief Called by the handle_message() method when an incoming signal is - * generated to USRP server that contains raw samples from the USRP. This - * method generates the response-recv-raw-samples signals that are the result of - * a cmd-start-recv-raw-samples signal. - * - * The raw lower-level packet is extracted from \p data, where the format for \p - * data is a PMT list. The PMT \p data list should contain an invocation handle - * as the first element, the status of the lower-level read as the second - * element, and a uniform vector representation of the packets as the third - * element. - * - * The packet contains a channel field that the samples are destined to, and the - * method determines where to send the samples based on this channel since each - * channel has an associated port which allocated it. - */ -void -usrp_server::handle_response_usrp_read(pmt_t data) -{ - - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t v_pkt = pmt_nth(2, data); - - size_t n_bytes; - size_t ignore; - - if (d_fake_rx) { - - pmt_t pkt = pmt_nth(2, data); - - d_rx[0]->send(s_response_recv_raw_samples, - pmt_list5(PMT_F, - PMT_T, - pkt, - pmt_from_long(0xffff), - PMT_NIL)); - - return; - } - - // Extract the packet and return appropriately - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, n_bytes); - - // The channel is used to find the port to pass the samples on - long channel = pkt->chan(); - long payload_len = pkt->payload_len(); - long port; - - // Ignore packets which seem to have incorrect size or size 0 - if(payload_len > pkt->max_payload() || payload_len == 0) - return; - - // If the packet is a C/S packet, parse it separately - if(channel == CONTROL_CHAN) { - parse_control_pkt(invocation_handle, pkt); - return; - } - - if((port = rx_port_index(d_chaninfo_rx[channel].owner)) == -1) - return; // Don't know where to send the sample... possibility on abrupt close - - pmt_t v_samples = pmt_make_u8vector(payload_len, 0); - uint8_t *samples = pmt_u8vector_writable_elements(v_samples, ignore); - - memcpy(samples, pkt->payload(), payload_len); - - // Build a properties dictionary to store things such as the RSSI - pmt_t properties = pmt_make_dict(); - - pmt_dict_set(properties, - pmt_intern("rssi"), - pmt_from_long(pkt->rssi())); - - if(pkt->overrun()) - pmt_dict_set(properties, - pmt_intern("overrun"), - PMT_T); - - if(pkt->underrun()) - pmt_dict_set(properties, - pmt_intern("underrun"), - PMT_T); - - d_rx[port]->send(s_response_recv_raw_samples, - pmt_list6(invocation_handle, - status, - v_samples, - pmt_from_long(pkt->timestamp()), - pmt_from_long(channel), - properties)); - return; -} - -/*! - * \brief Called by handle_response_usrp_read() when the incoming packet has a - * channel of CONTROL_CHAN. This means that the incoming packet contains a - * response for a command sent to the control channel, which this method will - * parse. - * - * The \p pkt parameter is a pointer to the full packet (transport_pkt) in - * memory. - * - * Given that all commands sent to the control channel that require responses - * will carry an RID (request ID), the method will use the RID passed back with - * the response to determine which port the response should be sent on. - */ -void -usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt) -{ - - long payload_len = pkt->payload_len(); - long curr_payload = 0; - long port; - - // We dispatch based on the control packet type, however we can extract the - // opcode and the length immediately which is consistent in all responses. - // - // Since each control packet can have multiple responses, we keep reading the - // lengths of each subpacket until we reach the payload length. - while(curr_payload < payload_len) { - - pmt_t sub_packet = pkt->read_subpacket(curr_payload); - pmt_t op_symbol = pmt_nth(0, sub_packet); - - int len = pkt->cs_len(curr_payload); - - if(verbose) - std::cout << "[USRP_SERVER] Parsing subpacket " - << op_symbol << " ... length " << len << std::endl; - - //----------------- PING RESPONSE ------------------// - if(pmt_eq(op_symbol, s_op_ping_fixed_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t pingval = pmt_nth(2, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found ping response " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "VAL: " << pingval - << ")\n"; - - // Do some bounds checking incase of bogus/corrupt responses - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - // FIXME: should be 1 response for all subpackets here ? - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_ping_fixed_reply, // subp - pmt_list2(pmt_from_long(urid), - pingval)), - pmt_from_long(pkt->timestamp()))); - } - - //----------------- READ REG RESPONSE ------------------// - else if(pmt_eq(op_symbol, s_op_read_reg_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t reg_num = pmt_nth(2, sub_packet); - pmt_t reg_val = pmt_nth(3, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found read register response " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "REG: " << reg_num << ", " - << "VAL: " << reg_val - << ")\n"; - - // Do some bounds checking to avoid seg faults - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - // FIXME: should be 1 response for all subpackets here ? - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_read_reg_reply, // subp - pmt_list3(pmt_from_long(urid), - reg_num, - reg_val)), - pmt_from_long(pkt->timestamp()))); - } - - //------------------ I2C READ REPLY -------------------// - else if(pmt_eq(op_symbol, s_op_i2c_read_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t i2c_addr = pmt_nth(2, sub_packet); - pmt_t i2c_data = pmt_nth(3, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found i2c read reply " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "Addr: " << i2c_addr << ", " - << "Data: " << i2c_data - << ")\n"; - - // Do some bounds checking to avoid seg faults - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_i2c_read_reply, - pmt_list3(pmt_from_long(urid), - i2c_addr, - i2c_data)), - pmt_from_long(pkt->timestamp()))); - } - - //------------------ SPI READ REPLY -------------------// - else if(pmt_eq(op_symbol, s_op_spi_read_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t spi_data = pmt_nth(2, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found SPI read reply " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "Data: " << spi_data - << ")\n"; - - // Bounds check the RID - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_spi_read_reply, - pmt_list2(pmt_from_long(urid), - spi_data)), - pmt_from_long(pkt->timestamp()))); - } - - // Each subpacket has an unaccounted for 2 bytes which is the opcode - // and the length field - curr_payload += len + 2; - - // All subpackets are 32-bit aligned - int align_offset = 4 - (curr_payload % 4); - - if(align_offset != 4) - curr_payload += align_offset; - } -} - -/*! - * \brief Used to recall all incoming signals that were deferred when USRP - * server was in the initialization state. - */ -void -usrp_server::recall_defer_queue() -{ - - std::vector<mb_message_sptr> recall; - - while(!d_defer_queue.empty()) { - recall.push_back(d_defer_queue.front()); - d_defer_queue.pop(); - } - - // Parse the messages that were queued while waiting for an open response - for(int i=0; i < (int)recall.size(); i++) - handle_message(recall[i]); - - return; -} - -/*! - * \brief Commonly called by any method which handles outgoing frames or control - * packets to the USRP to check if the port on which the signal was sent owns - * the channel the outgoing packet will be associated with. This helps ensure - * that applications do not send data on other application's ports. - * - * The \p port parameter is the port symbol that the caller wishes to determine - * owns the channel specified by \p chan_info. - * - * The \p signal_info parameter is a PMT list containing two elements: the - * response signal to use if the permissions are invalid, and the invocation - * handle that was passed. This allows the method to generate detailed failure - * responses to signals without having to return some sort of structured - * information which the caller must then parse and interpret to determine the - * failure type. - * - * \returns true if \p port owns the channel specified by \p chan_info, false - * otherwise. - */ -bool -usrp_server::check_valid(mb_port_sptr port, - long channel, - std::vector<struct channel_info> &chan_info, - pmt_t signal_info) -{ - - pmt_t response_signal = pmt_nth(0, signal_info); - pmt_t invocation_handle = pmt_nth(1, signal_info); - - // not a valid channel number? - if(channel >= (long)chan_info.size() && channel != CONTROL_CHAN) { - port->send(response_signal, - pmt_list2(invocation_handle, - s_err_channel_invalid)); - - if(verbose) - std::cout << "[USRP_SERVER] Invalid channel number for event " - << response_signal << std::endl; - return false; - } - - // not the owner of the port? - if(chan_info[channel].owner != port->port_symbol()) { - port->send(response_signal, - pmt_list2(invocation_handle, - s_err_channel_permission_denied)); - - if(verbose) - std::cout << "[USRP_SERVER] Invalid permissions" - << " for " << response_signal - << " from " << port->port_symbol() - << " proper owner is " << chan_info[channel].owner - << " on channel " << channel - << " invocation " << invocation_handle - << std::endl; - return false; - } - - return true; -} - -/*! - * \brief Finds the next available RID for internal USRP server use with control - * and status packets. - * - * \returns the next valid RID or -1 if no more RIDs are available. - */ -long -usrp_server::next_rid() -{ - for(int i = 0; i < D_MAX_RID; i++) - if(pmt_eqv(d_rids[i].owner, PMT_NIL)) - return i; - - if(verbose) - std::cout << "[USRP_SERVER] No RIDs left\n"; - return -1; -} - -/*! - * \brief Called by handle_message() when USRP server gets a response that the - * USRP was opened successfully to initialize the registers using the new - * register read/write control packets. - */ -void -usrp_server::initialize_registers() -{ - // We use handle_cmd_to_control_channel() to create the register writes using - // PMT_NIL as the response port to tell usrp_server not to pass the response - // up to any application. - if(verbose) - std::cout << "[USRP_SERVER] Initializing registers...\n"; - - // RX mode to normal (0) - set_register(FR_MODE, 0); - - // FPGA debugging? - if(d_fpga_debug) { - set_register(FR_DEBUG_EN, 1); - // FIXME: need to figure out exact register writes to control daughterboard - // pins that need to be written to - } else { - set_register(FR_DEBUG_EN, 0); - } - - // Set the transmit sample rate divisor, which is 4-1 - set_register(FR_TX_SAMPLE_RATE_DIV, 3); - - // Dboard IO buffer and register settings - set_register(FR_OE_0, (0xffff << 16) | 0x0000); - set_register(FR_IO_0, (0xffff << 16) | 0x0000); - set_register(FR_OE_1, (0xffff << 16) | 0x0000); - set_register(FR_IO_1, (0xffff << 16) | 0x0000); - set_register(FR_OE_2, (0xffff << 16) | 0x0000); - set_register(FR_IO_2, (0xffff << 16) | 0x0000); - set_register(FR_OE_3, (0xffff << 16) | 0x0000); - set_register(FR_IO_3, (0xffff << 16) | 0x0000); - - // zero Tx side Auto Transmit/Receive regs - set_register(FR_ATR_MASK_0, 0); - set_register(FR_ATR_TXVAL_0, 0); - set_register(FR_ATR_RXVAL_0, 0); - set_register(FR_ATR_MASK_1, 0); - set_register(FR_ATR_TXVAL_1, 0); - set_register(FR_ATR_RXVAL_1, 0); - set_register(FR_ATR_MASK_2, 0); - set_register(FR_ATR_TXVAL_2, 0); - set_register(FR_ATR_RXVAL_2, 0); - set_register(FR_ATR_MASK_3, 0); - set_register(FR_ATR_TXVAL_3, 0); - set_register(FR_ATR_RXVAL_3, 0); - - // Configure TX mux, this is a hacked value - set_register(FR_TX_MUX, 0x00000081); - - // Set the interpolation rate, which is the rate divided by 4, minus 1 - set_register(FR_INTERP_RATE, (d_interp_tx/4)-1); - - // Apparently this register changes again - set_register(FR_TX_MUX, 0x00000981); - - // Set the receive sample rate divisor, which is 2-1 - set_register(FR_RX_SAMPLE_RATE_DIV, 1); - - // DC offset - set_register(FR_DC_OFFSET_CL_EN, 0x0000000f); - - // Reset the DC correction offsets - set_register(FR_ADC_OFFSET_0, 0); - set_register(FR_ADC_OFFSET_1, 0); - - // Some hard-coded RX configuration - set_register(FR_RX_FORMAT, 0x00000300); - set_register(FR_RX_MUX, 1); - - // RX decimation rate is divided by two, then subtract 1 - set_register(FR_DECIM_RATE, (d_decim_rx/2)-1); - - // More hard coding - set_register(FR_RX_MUX, 0x000e4e41); - - // Resetting RX registers - set_register(FR_RX_PHASE_0, 0); - set_register(FR_RX_PHASE_1, 0); - set_register(FR_RX_PHASE_2, 0); - set_register(FR_RX_PHASE_3, 0); - set_register(FR_RX_FREQ_0, 0x28000000); - set_register(FR_RX_FREQ_1, 0); - set_register(FR_RX_FREQ_2, 0); - set_register(FR_RX_FREQ_3, 0); - - // Enable debug bus - set_register(FR_DEBUG_EN, 0xf); - set_register(FR_OE_0, -1); - set_register(FR_OE_1, -1); - set_register(FR_OE_2, -1); - set_register(FR_OE_3, -1); - - // DEBUGGING - //check_register_initialization(); -} - -// FIXME: used for debugging to determine if all the registers are actually -// being set correctly -void -usrp_server::check_register_initialization() -{ - // RX mode to normal (0) - read_register(FR_MODE); - - // FPGA debugging? - if(d_fpga_debug) { - read_register(FR_DEBUG_EN); - // FIXME: need to figure out exact register writes to control daughterboard - // pins that need to be written to - } else { - read_register(FR_DEBUG_EN); - } - - // Set the transmit sample rate divisor, which is 4-1 - read_register(FR_TX_SAMPLE_RATE_DIV); - - // Dboard IO buffer and register settings - read_register(FR_OE_0); - read_register(FR_IO_0); - read_register(FR_OE_1); - read_register(FR_IO_1); - read_register(FR_OE_2); - read_register(FR_IO_2); - read_register(FR_OE_3); - read_register(FR_IO_3); - - // zero Tx side Auto Transmit/Receive regs - read_register(FR_ATR_MASK_0); - read_register(FR_ATR_TXVAL_0); - read_register(FR_ATR_RXVAL_0); - read_register(FR_ATR_MASK_1); - read_register(FR_ATR_TXVAL_1); - read_register(FR_ATR_RXVAL_1); - read_register(FR_ATR_MASK_2); - read_register(FR_ATR_TXVAL_2); - read_register(FR_ATR_RXVAL_2); - read_register(FR_ATR_MASK_3); - read_register(FR_ATR_TXVAL_3); - read_register(FR_ATR_RXVAL_3); - - // Configure TX mux, this is a hacked value - read_register(FR_TX_MUX); - - // Set the interpolation rate, which is the rate divided by 4, minus 1 - read_register(FR_INTERP_RATE); - - // Apparently this register changes again - read_register(FR_TX_MUX); - - // Set the receive sample rate divisor, which is 2-1 - read_register(FR_RX_SAMPLE_RATE_DIV); - - // DC offset - read_register(FR_DC_OFFSET_CL_EN); - - // Reset the DC correction offsets - read_register(FR_ADC_OFFSET_0); - read_register(FR_ADC_OFFSET_1); - - // Some hard-coded RX configuration - read_register(FR_RX_FORMAT); - read_register(FR_RX_MUX); - - // RX decimation rate is divided by two, then subtract 1 - read_register(FR_DECIM_RATE); - - // More hard coding - read_register(FR_RX_MUX); - - // Resetting RX registers - read_register(FR_RX_PHASE_0); - read_register(FR_RX_PHASE_1); - read_register(FR_RX_PHASE_2); - read_register(FR_RX_PHASE_3); - read_register(FR_RX_FREQ_0); - read_register(FR_RX_FREQ_1); - read_register(FR_RX_FREQ_2); - read_register(FR_RX_FREQ_3); -} - -/*! - * \brief Used to generate FPGA register write commands to reset all of the FPGA - * registers to a value of 0. - */ -void -usrp_server::reset_all_registers() -{ - for(int i=0; i<64; i++) - set_register(i, 0); -} - -/*! - * \brief Used internally by USRP server to generate a control/status packet - * which contains a register write. - * - * The \p reg parameter is the register number that the value \p val will be - * written to. - */ -void -usrp_server::set_register(long reg, long val) -{ - size_t psize; - long payload_len = 0; - - pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize); - - pkt->set_header(0, CONTROL_CHAN, 0, payload_len); - pkt->set_timestamp(0xffffffff); - - pkt->cs_write_reg(reg, val); - - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(PMT_NIL, - pmt_from_long(CONTROL_CHAN), - v_packet)); -} - -/*! - * \brief Used internally by USRP server to generate a control/status packet - * which contains a register read. This is important to use internally so that - * USRP server can bypass the use of RIDs with register reads, as they are not - * needed and it would use up the finite number of RIDs available for use for - * applications to receive responses. - * - * The \p reg parameter is the register number that the value should be read - * from. - */ -void -usrp_server::read_register(long reg) -{ - size_t psize; - long payload_len = 0; - - pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize); - - pkt->set_header(0, CONTROL_CHAN, 0, payload_len); - pkt->set_timestamp(0xffffffff); - - pkt->cs_read_reg(0, reg); - - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(PMT_NIL, - pmt_from_long(CONTROL_CHAN), - v_packet)); -} - -REGISTER_MBLOCK_CLASS(usrp_server); diff --git a/usrp/host/lib/inband/usrp_server.h b/usrp/host/lib/inband/usrp_server.h deleted file mode 100644 index dd1825d57..000000000 --- a/usrp/host/lib/inband/usrp_server.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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_USRP_SERVER_H -#define INCLUDED_USRP_SERVER_H - -#include <mblock/mblock.h> -#include <vector> -#include <queue> -#include <fstream> -#include <usrp_inband_usb_packet.h> - -typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy - -/*! - * \brief Implements the lowest-level mblock usb_interface to the USRP - */ -class usrp_server : public mb_mblock -{ -public: - - // our ports - enum port_types { - RX_PORT = 0, - TX_PORT = 1 - }; - static const int N_PORTS = 4; - std::vector<mb_port_sptr> d_tx, d_rx; - mb_port_sptr d_cs; - mb_port_sptr d_cs_usrp; - - static const int D_USB_CAPACITY = 32 * 1024 * 1024; - static const int D_MAX_CHANNELS = 16; - long d_ntx_chan; - long d_nrx_chan; - - pmt_t d_usrp_dict; - - bool d_fpga_debug; - - long d_interp_tx; - long d_decim_rx; - - // Keep track of the request IDs - struct rid_info { - pmt_t owner; - long user_rid; - - rid_info() { - owner = PMT_NIL; - user_rid = 0; - } - }; - - static const long D_MAX_RID = 64; - std::vector<rid_info> d_rids; - - struct channel_info { - long assigned_capacity; // the capacity currently assignedby the channel - pmt_t owner; // port ID of the owner of the channel - - channel_info() { - assigned_capacity = 0; - owner = PMT_NIL; - } - }; - - long d_rx_chan_mask; // A bitmask representing the channels in the - // receiving state - - std::vector<struct channel_info> d_chaninfo_tx; - std::vector<struct channel_info> d_chaninfo_rx; - - std::queue<mb_message_sptr> d_defer_queue; - - bool d_defer; - bool d_opened; - - bool d_fake_rx; - -public: - usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_server(); - - void initial_transition(); - void handle_message(mb_message_sptr msg); - -protected: - static int max_capacity() { return D_USB_CAPACITY; } - -private: - void handle_cmd_allocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_deallocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_to_control_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_stop_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - int rx_port_index(pmt_t port_id); - int tx_port_index(pmt_t port_id); - long current_capacity_allocation(); - void recall_defer_queue(); - void reset_channels(); - void handle_response_usrp_read(pmt_t data); - bool check_valid(mb_port_sptr port, long channel, std::vector<struct channel_info> &chan_info, pmt_t signal_info); - void parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt); - long next_rid(); - void initialize_registers(); - void set_register(long reg, long val); - void read_register(long reg); - void check_register_initialization(); - void reset_all_registers(); -}; - -#endif /* INCLUDED_USRP_SERVER_H */ diff --git a/usrp/host/lib/inband/usrp_server.mbh b/usrp/host/lib/inband/usrp_server.mbh deleted file mode 100644 index ed7943fc3..000000000 --- a/usrp/host/lib/inband/usrp_server.mbh +++ /dev/null @@ -1,255 +0,0 @@ -;; -*- scheme -*- ; not really, but tells emacs how to format this -;; -;; 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. -;; - -;; ---------------------------------------------------------------- -;; This is an mblock header file -;; -;; The format is very much a work-in-progress. -;; It'll be compiled to C++. -;; ---------------------------------------------------------------- - -;; In the outgoing messages described below, invocation-handle is an -;; identifier provided by the client to tag the method invocation. -;; The identifier will be returned with the response, to provide the -;; client with a mechanism to match asynchronous responses with the -;; commands that generate them. The value of the invocation-handle is -;; opaque the the server, and is not required by the server to be -;; unique. -;; -;; In the incoming messages described below, invocation-handle is the -;; identifier provided by the client in the prompting invocation. The -;; identifier is returned with the response, so that the client has a -;; mechanism to match asynchronous responses with the commands that -;; generated them. -;; -;; status is either #t, indicating success, or a symbol indicating an error. -;; All symbol's names shall begin with %error- - - -;; ---------------------------------------------------------------- -;; usrp-channel -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-channel - - (:outgoing - - (cmd-allocate-channel invocation-handle capacity-reservation) - - ;; The cmd-allocate-channel message requests that the server - ;; allocates a logical channel in the FPGA for use. - ;; capacity-reservation specifies the number of bytes/s of - ;; interconnect capacity (USB or ethernet) to reserve for this - ;; channel. (The reservation is just a sanity check, no OS - ;; specific mechanism is used.) - - (cmd-deallocate-channel invocation-handle channel) - - ;; The integer channel specifies the channel to deallocate. - - ) - - (:incoming - - - (response-allocate-channel invocation-handle status channel) - - ;; If successful, a channel the specified capacity was allocated. - ;; channel, an integer, indicates which channel was allocated. - - (response-deallocate-channel invocation-handle status) - - ;; If successful, the specified channel and associated interconnect - ;; capacity were deallocated. - - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-low-level-cs -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) -;; -;; This defines a low level control and status interface to the usrp. -;; This will probably be replaced (or at least augmented) with a -;; higher level interface. For now, this will allow us to get on -;; the air. -;; -;; The subpackets are lists containing the relevant parameters. The -;; server will marshall them appropriately. Below is a list of -;; subpackets. See inband-signaling-usb for details. The opcodes are -;; symbols; unless otherwise indicated the remaining parameters are -;; integers. rid values are limited to 3-bits. -;; -;; (op-ping-fixed rid ping-value) -;; (op-ping-fixed-reply rid ping-value) -;; (op-write-reg reg-number reg-value) -;; (op-write-reg-masked reg-number reg-value mask-value) -;; (op-read-reg rid reg-number) -;; (op-read-reg-reply rid reg-number reg-value) -;; (op-i2c-write i2c-addr u8-vec) -;; (op-i2c-read rid i2c-addr nbytes) -;; (op-i2c-read-reply rid i2c-addr u8-vec) -;; (op-spi-write enables format opt-header-bytes u8-vec) -;; (op-spi-read rid enables format opt-header-bytes nbytes) -;; (op-spi-read-reply rid u8-vec) -;; (op-delay ticks) - - -(define-protocol-class usrp-low-level-cs - - (:outgoing - - (cmd-to-control-channel invocation-handle list-of-subpackets) - - ) - - (:incoming - - (response-from-control-channel invocation-handle status list-of-subpackets timestamp) - - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-tx -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-tx - (:include usrp-channel) - (:include usrp-low-level-cs) - - (:outgoing - - (cmd-xmit-raw-frame invocation-handle channel samples timestamp properties) - - ;; The argument channel must be an integer. It specifies the - ;; channel on which the frame of samples will be be sent. - ;; - ;; samples must be a uniform numeric vector. The contents of the - ;; sample vector is treated as opaque and is passed on to the FPGA - ;; unmodified. It is the responsibility of the sender to ensure - ;; that the binary format is sensible for the current FPGA - ;; configuration. - ;; - ;; timestamp is a 32-bit integer that specifies the time at which - ;; the first sample in samples shall be sent to the D/A converter. - ;; The format and interpration of time is specified in the file - ;; inband-signaling-usb - ) - - (:incoming - - (response-xmit-raw-frame invocation-handle status) - - ;; If successful, the samples of the associated frame have been - ;; transmitted to the USRP. This message may be used to implement - ;; Tx flow control. The client could for example implement a - ;; policy of never having more than 4 unacknowledged - ;; cmd-xmit-raw-frame's outstanding. - - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-rx -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-rx - (:include usrp-channel) - (:include usrp-low-level-cs) - - (:outgoing - - (cmd-start-recv-raw-samples invocation-handle channel) - - ;; The argument channel must be an integer. It specifies the - ;; channel from which frames of samples will be be received. The - ;; server will return response-recv-raw-samples messages until a - ;; cmd-stop-recv-raw-samples message is received. - - (cmd-stop-recv-raw-samples invocation-handle channel) - - ;; The argument channel must be an integer. There is no reply to - ;; this message. - - ) - - (:incoming - - (response-recv-raw-samples invocation-handle status samples timestamp channel properties) - - ;; samples is a uniform numeric vector. The contents of the sample - ;; vector is treated as opaque and is passed from the FPGA - ;; unmodified. It is the responsibility of the receiver to decode - ;; the binary format as appropriate for the current FPGA - ;; configuration. - ;; - ;; timestamp is a 32-bit integer that specifies the time at which - ;; the first sample in samples was received from the A/D converter. - ;; The format and interpretation of time is as specified in the - ;; file inband-signaling-usb. - ;; - ;; properties is a dictionary containing additional (key, value) - ;; pairs associated with the reception of these samples. In - ;; particular, the map may contain the Received Signal Strength - ;; Indication (RSSI) reported by the front end at the time the - ;; first sample was received from the A/D. - - ) - ) - - -;; ---------------------------------------------------------------- -;; usrp-server-cs -;; -;; Control and status port for usrp-server -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-server-cs - - (:outgoing - (cmd-open invocation-handle which-usrp) - (cmd-close invocation-handle) - (cmd-max-capacity invocation-handle) - (cmd-ntx-chan invocation-handle) - (cmd-nrx-chan invocation-handle) - (cmd-current-capacity-allocation invocation-handle) - ) - - (:incoming - (response-open invocation-handle status) - (response-close invocation-handle status) - (response-max-capacity invocation-handle status capacity) - (response-ntx-chan invocation-handle status ntx-chan) - (response-nrx-chan invocation-handle status nrx-chan) - (response-current-capacity-allocation invocation-handle status capacity) - ) - ) diff --git a/usrp/host/lib/inband/usrp_tx.cc b/usrp/host/lib/inband/usrp_tx.cc deleted file mode 100644 index 0d4a84619..000000000 --- a/usrp/host/lib/inband/usrp_tx.cc +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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 <usrp_tx.h> -#include <iostream> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include <usrp_standard.h> -#include <stdio.h> - -#include <symbols_usrp_tx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -usrp_tx::usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_disk_write(false) -{ - d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL); - - //d_disk_write=true; - - if(d_disk_write) { - d_ofile.open("tx_data.dat",std::ios::binary|std::ios::out); - d_cs_ofile.open("tx_cs.dat",std::ios::binary|std::ios::out); - } -} - -usrp_tx::~usrp_tx() -{ - if(d_disk_write) { - d_ofile.close(); - d_cs_ofile.close(); - } -} - -void -usrp_tx::initial_transition() -{ - -} - -/*! - * \brief Handles incoming signals to to the m-block, wihch should only ever be - * a single message: cmd-usrp-tx-write. - */ -void -usrp_tx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol())) { - - if(pmt_eqv(event, s_cmd_usrp_tx_write)) - write(data); - } -} - -/*! - * \brief Performs the actual writing of data to the USB bus, called by - * handle_message() when a cmd-usrp-tx-write signal is received. - * - * The \p data parameter is a PMT list which contains three mandatory elements, - * in the following order: an invocation handle, a channel, and a uniform vector - * of memory which contains the packets to be written to the bus. - */ -void -usrp_tx::write(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t channel = pmt_nth(1, data); - pmt_t v_packets = pmt_nth(2, data); - d_utx = boost::any_cast<usrp_standard_tx_sptr>(pmt_any_ref(pmt_nth(3, data))); - - size_t n_bytes; - bool underrun; // this will need to go, as it is taken care of in the packet headers - - transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes); - - int ret = d_utx->write (pkts, n_bytes, &underrun); - - if (0 && underrun) - fprintf(stderr, "uU"); - - if (ret == (int) n_bytes) { - if (verbose) - std::cout << "[usrp_server] Write of " << n_bytes << " successful\n"; - // need to respond with the channel so the USRP server knows who to forward the result of - // the write to by looking up the owner of the channel - d_cs->send(s_response_usrp_tx_write, - pmt_list3(invocation_handle, PMT_T, channel)); - } - else { - if (verbose) - std::cout << "[usrp_server] Error writing " << n_bytes << " bytes to USB bus\n"; - d_cs->send(s_response_usrp_tx_write, - pmt_list3(invocation_handle, PMT_F, channel)); - } - - long n_packets = - static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size())); - - for(int i=0; i < n_packets; i++) { - - if(d_disk_write) { - if(pkts[i].chan() == CONTROL_CHAN) - d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - else - d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - - d_cs_ofile.flush(); - d_ofile.flush(); - } - } - - - return; -} - -REGISTER_MBLOCK_CLASS(usrp_tx); diff --git a/usrp/host/lib/inband/usrp_tx.h b/usrp/host/lib/inband/usrp_tx.h deleted file mode 100644 index d3a6f8b54..000000000 --- a/usrp/host/lib/inband/usrp_tx.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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_USRP_TX_H -#define INCLUDED_USRP_TX_H - -#include <mblock/mblock.h> -#include <fstream> -#include "usrp_standard.h" - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_tx : public mb_mblock -{ - mb_port_sptr d_cs; - usrp_standard_tx_sptr d_utx; - - bool d_disk_write; - std::ofstream d_ofile; - std::ofstream d_cs_ofile; - - public: - usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_tx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void write(pmt_t data); -}; - - -#endif /* INCLUDED_USRP_TX_H */ - diff --git a/usrp/host/lib/inband/usrp_tx_stub.cc b/usrp/host/lib/inband/usrp_tx_stub.cc deleted file mode 100644 index c78b1a7b8..000000000 --- a/usrp/host/lib/inband/usrp_tx_stub.cc +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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 <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_tx_stub.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include "usrp_standard.h" -#include <stdio.h> -#include <fstream> -#include <usrp_rx_stub.h> - -#include <symbols_usrp_tx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -usrp_tx_stub::usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_disk_write(false) -{ - d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL); - - //d_disk_write=true; - - if(d_disk_write) { - d_ofile.open("tx_stub_data.dat",std::ios::binary|std::ios::out); - d_cs_ofile.open("tx_stub_cs.dat",std::ios::binary|std::ios::out); - } -} - -usrp_tx_stub::~usrp_tx_stub() -{ - if(d_disk_write) { - d_ofile.close(); - d_cs_ofile.close(); - } -} - -void -usrp_tx_stub::initial_transition() -{ - -} - -void -usrp_tx_stub::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol())) { - - if(pmt_eqv(event, s_cmd_usrp_tx_write)) - write(data); - } -} - -void -usrp_tx_stub::write(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t channel = pmt_nth(1, data); - pmt_t v_packets = pmt_nth(2, data); - d_utx = boost::any_cast<usrp_standard_tx *>(pmt_any_ref(pmt_nth(3, data))); - - size_t n_bytes; - - transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes); - long n_packets = static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size())); - - // Parse the packets looking for C/S packets and dump them to a disk if - // necessary - for(long i=0; i<n_packets; i++) { - - if(d_disk_write) { - if(pkts[i].chan() == CONTROL_CHAN) - d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - else - d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - - d_cs_ofile.flush(); - d_ofile.flush(); - } - - if(pkts[i].chan() == CONTROL_CHAN) - parse_cs(invocation_handle, pkts[i]); - } - - d_cs->send(s_response_usrp_tx_write, - pmt_list3(invocation_handle, PMT_T, channel)); - - return; -} - -void -usrp_tx_stub::parse_cs(pmt_t invocation_handle, transport_pkt pkt) -{ - - long payload_len = pkt.payload_len(); - long curr_payload = 0; - - size_t ignore; - - // There is the possibility that the responses for a single USB packet full of - // CS packets will not fit back in a single USB packet, considering some - // responses are greater than their commands (read registers). - new_packet: - pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0); - - transport_pkt *q_pkt = - (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore); - - q_pkt->set_header(0, CONTROL_CHAN, 0, 0); - q_pkt->set_timestamp(0xffffffff); - - // We dispatch based on the control packet type, however we can extract the - // opcode and the length immediately which is consistent in all responses. - // - // Since each control packet can have multiple responses, we keep reading the - // lengths of each subpacket until we reach the payload length. - while(curr_payload < payload_len) { - - pmt_t sub_packet = pkt.read_subpacket(curr_payload); - pmt_t op_symbol = pmt_nth(0, sub_packet); - - int len = pkt.cs_len(curr_payload); - - if(verbose) - std::cout << "[USRP_TX_STUB] Parsing subpacket " - << op_symbol << " ... length " << len << std::endl; - - //----------------- PING FIXED ------------------// - if(pmt_eq(op_symbol, s_op_ping_fixed)) { - - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long pingval = pmt_to_long(pmt_nth(2, sub_packet)); - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_ping_reply(rid, pingval)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Generated ping response " - << "(" - << "RID: " << rid << ", " - << "VAL: " << pingval - << ")\n"; - } - - //----------------- READ REG ------------------// - if(pmt_eq(op_symbol, s_op_read_reg)) { - - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long reg_num = pmt_to_long(pmt_nth(2, sub_packet)); - long reg_val = 0xdeef; - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_read_reg_reply(rid, reg_num, reg_val)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Generated read register response " - << "(" - << "RID: " << rid << ", " - << "REG: " << reg_num << ", " - << "VAL: " << reg_val - << ")\n"; - } - - //----------------- DELAY ------------------// - if(pmt_eq(op_symbol, s_op_delay)) { - - long ticks = pmt_to_long(pmt_nth(1, sub_packet)); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received delay command " - << "(" - << "Ticks: " << ticks - << ")\n"; - } - - //----------------- WRITE REG ------------------// - if(pmt_eq(op_symbol, s_op_write_reg)) { - - pmt_t reg_num = pmt_nth(1, sub_packet); - pmt_t reg_val = pmt_nth(2, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received write register command " - << "(" - << "RegNum: " << reg_num << ", " - << "Val: " << reg_val - << ")\n"; - } - - //----------------- WRITE REG MASK ---------------// - if(pmt_eq(op_symbol, s_op_write_reg_masked)) { - - pmt_t reg_num = pmt_nth(1, sub_packet); - pmt_t reg_val = pmt_nth(2, sub_packet); - pmt_t mask = pmt_nth(3, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received write register command " - << "(" - << "RegNum: " << reg_num << ", " - << "Val: " << reg_val << ", " - << "Mask: " << mask - << ")\n"; - } - - //---------------- I2C WRITE ------------------// - if(pmt_eq(op_symbol, s_op_i2c_write)) { - pmt_t i2c_addr = pmt_nth(1, sub_packet); - pmt_t i2c_data = pmt_nth(2, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received i2c write command " - << "(" - << "Addr: " << i2c_addr << ", " - << "Data: " << i2c_data - << ")\n"; - } - - //---------------- I2C READ ------------------// - if(pmt_eq(op_symbol, s_op_i2c_read)) { - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long i2c_addr = pmt_to_long(pmt_nth(2, sub_packet)); - long i2c_bytes = pmt_to_long(pmt_nth(3, sub_packet)); - - // Create data to place as a response, filled with 0xff - size_t ignore; - pmt_t i2c_data = pmt_make_u8vector(i2c_bytes, 0xff); - uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore); - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_i2c_read_reply(rid, i2c_addr, w_data, i2c_bytes)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Received i2c read " - << "(" - << "RID: " << rid << ", " - << "Addr: " << i2c_addr << ", " - << "Bytes: " << i2c_bytes - << ")\n"; - } - - //---------------- SPI WRITE ------------------// - if(pmt_eq(op_symbol, s_op_spi_write)) { - long enables = pmt_to_long(pmt_nth(1, sub_packet)); - long format = pmt_to_long(pmt_nth(2, sub_packet)); - long opt = pmt_to_long(pmt_nth(3, sub_packet)); - pmt_t data = pmt_nth(4, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received spi write command " - << "(" - << "Enables: " << enables << ", " - << "Format: " << format << ", " - << "Options: " << opt << ", " - << "Data: " << data - << ")\n"; - } - - //---------------- SPI READ ------------------// - if(pmt_eq(op_symbol, s_op_spi_read)) { - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long enables = pmt_to_long(pmt_nth(2, sub_packet)); - long format = pmt_to_long(pmt_nth(3, sub_packet)); - long opt = pmt_to_long(pmt_nth(4, sub_packet)); - long n_bytes = pmt_to_long(pmt_nth(5, sub_packet)); - - // Create data to place as a fake response - size_t ignore; - pmt_t spi_data = pmt_make_u8vector(n_bytes, 0xff); - uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(spi_data, ignore); - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_spi_read_reply(rid, w_data, n_bytes)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Received spi read command " - << "(" - << "RID: " << rid << ", " - << "Enables: " << enables << ", " - << "Format: " << format << ", " - << "Options: " << opt << ", " - << "Bytes: " << n_bytes - << ")\n"; - - } - - // Each subpacket has an unaccounted for 2 bytes which is the opcode - // and the length field - curr_payload += len + 2; - - // All subpackets are 32-bit aligned - int align_offset = 4 - (curr_payload % 4); - - if(align_offset != 4) - curr_payload += align_offset; - - } - - // If the packet has data in the payload, it needs queued - if(q_pkt->payload_len() > 0) - d_cs_queue.push(pmt_list2(invocation_handle, v_pkt)); - - return; -} - -REGISTER_MBLOCK_CLASS(usrp_tx_stub); diff --git a/usrp/host/lib/inband/usrp_tx_stub.h b/usrp/host/lib/inband/usrp_tx_stub.h deleted file mode 100644 index b81037ad7..000000000 --- a/usrp/host/lib/inband/usrp_tx_stub.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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_USRP_TX_STUB_H -#define INCLUDED_USRP_TX_STUB_H - -#include <mblock/mblock.h> -#include <vector> -#include "usrp_standard.h" -#include <fstream> -#include <usrp_inband_usb_packet.h> - -typedef usrp_inband_usb_packet transport_pkt; - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_tx_stub : public mb_mblock -{ - public: - - mb_port_sptr d_cs; - usrp_standard_tx* d_utx; - - std::ofstream d_ofile; - std::ofstream d_cs_ofile; - - bool d_disk_write; - - public: - usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_tx_stub(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void write(pmt_t data); - void parse_cs(pmt_t invocation_handle, transport_pkt pkt); - -}; - - -#endif /* INCLUDED_USRP_TX_STUB_H */ - diff --git a/usrp/host/lib/inband/usrp_usb_interface.cc b/usrp/host/lib/inband/usrp_usb_interface.cc deleted file mode 100644 index fb7109a5a..000000000 --- a/usrp/host/lib/inband/usrp_usb_interface.cc +++ /dev/null @@ -1,601 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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 <usrp_usb_interface.h> - -#include <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include "usrp_rx.h" -#include <usrp_rx_stub.h> -#include "usrp_tx.h" -#include "usrp_standard.h" -#include <stdio.h> -#include <usrp_dbid.h> - -typedef usrp_inband_usb_packet transport_pkt; - -#include <symbols_usrp_interface_cs.h> -#include <symbols_usrp_tx_cs.h> -#include <symbols_usrp_rx_cs.h> -static pmt_t s_shutdown = pmt_intern("%shutdown"); - -static const bool verbose = false; - - -/*! - * \brief Initializes the USB interface m-block. - * - * The \p user_arg should be a PMT dictionary which can contain optional - * arguments for the block, such as the decimatoin and interpolation rate. - */ -usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_fake_usrp(false), - d_rx_reading(false), - d_interp_tx(128), - d_decim_rx(128), - d_rf_freq(-1), - d_rbf("inband_tx_rx.rbf") -{ - // Dictionary for arguments to all of the components - pmt_t usrp_dict = user_arg; - - // Default TX/RX interface - std::string tx_interface = "usrp_tx"; - std::string rx_interface = "usrp_rx"; - - if (pmt_is_dict(usrp_dict)) { - - // The 'fake-usrp' key enables the TX and RX stubs if PMT_T - if(pmt_t fake_usrp = pmt_dict_ref(usrp_dict, - pmt_intern("fake-usrp"), - PMT_NIL)) { - if(pmt_eqv(fake_usrp, PMT_T)) { - tx_interface = "usrp_tx_stub"; - rx_interface = "usrp_rx_stub"; - d_fake_usrp=true; - } - } - - // Read the TX interpolations - if(pmt_t interp_tx = pmt_dict_ref(usrp_dict, - pmt_intern("interp-tx"), - PMT_NIL)) { - if(!pmt_eqv(interp_tx, PMT_NIL)) - d_interp_tx = pmt_to_long(interp_tx); - } - - // Read the RX decimation rate - if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, - pmt_intern("decim-rx"), - PMT_NIL)) { - if(!pmt_eqv(decim_rx, PMT_NIL)) - d_decim_rx = pmt_to_long(decim_rx); - } - - // Read the RBF - if(pmt_t rbf = pmt_dict_ref(usrp_dict, - pmt_intern("rbf"), - PMT_NIL)) { - if(!pmt_eqv(rbf, PMT_NIL)) - d_rbf = pmt_symbol_to_string(rbf); - } - - // The RF center frequency - if(pmt_t rf_freq = pmt_dict_ref(usrp_dict, - pmt_intern("rf-freq"), - PMT_NIL)) { - if(!pmt_eqv(rf_freq, PMT_NIL)) - d_rf_freq = pmt_to_double(rf_freq); - } - } - - if (verbose) { - std::cout << "[USRP_USB_INTERFACE] Setting USRP RBF to " - << d_rbf << std::endl; - - std::cout << "[USRP_USB_INTERFACE] Setting TX interpolation to " - << d_interp_tx << std::endl; - - std::cout << "[USRP_USB_INTERFACE] Setting RX interpolation to " - << d_decim_rx << std::endl; - - std::cout << "[USRP_USB_INTERFACE] Using TX interface: " - << tx_interface << "\n"; - - std::cout << "[USRP_USB_INTERFACE] Using RX interface: " - << rx_interface << "\n"; - - } - - d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL); - d_rx_cs = define_port("rx_cs", "usrp-rx-cs", false, mb_port::INTERNAL); - d_tx_cs = define_port("tx_cs", "usrp-tx-cs", false, mb_port::INTERNAL); - - // Connect to TX and RX - define_component("tx", tx_interface, usrp_dict); - define_component("rx", rx_interface, usrp_dict); - connect("self", "rx_cs", "rx", "cs"); - connect("self", "tx_cs", "tx", "cs"); - - // FIXME: the code should query the FPGA to retrieve the number of channels and such - d_ntx_chan = 2; - d_nrx_chan = 2; -} - -usrp_usb_interface::~usrp_usb_interface() -{ - -} - -void -usrp_usb_interface::initial_transition() -{ - -} - -/*! - * \brief Handles all incoming signals to the block from the lowest m-blocks - * which read/write to the bus, or the higher m-block which is the USRP server. - */ -void -usrp_usb_interface::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); // the "name" of the message - pmt_t port_id = msg->port_id(); // which port it came in on - pmt_t data = msg->data(); - pmt_t invocation_handle; - - if (pmt_eq(event, s_shutdown)) // ignore (for now) - return; - - //------------- CONTROL / STATUS -------------// - if (pmt_eq(port_id, d_cs->port_symbol())) { - - //------------ OPEN --------------// - if (pmt_eq(event, s_cmd_usrp_open)){ - handle_cmd_open(data); - return; - } - //----------- CLOSE -------------// - else if (pmt_eq(event, s_cmd_usrp_close)) { - handle_cmd_close(data); - return; - } - //---------- NTX CHAN ----------// - else if (pmt_eq(event, s_cmd_usrp_ntx_chan)) { - invocation_handle = pmt_nth(0, data); - d_cs->send(s_response_usrp_ntx_chan, - pmt_list2(invocation_handle, - pmt_from_long(d_ntx_chan))); - return; - } - //---------- NRX CHAN ----------// - else if (pmt_eq(event, s_cmd_usrp_nrx_chan)) { - invocation_handle = pmt_nth(0, data); - d_cs->send(s_response_usrp_nrx_chan, - pmt_list2(invocation_handle, - pmt_from_long(d_nrx_chan))); - return; - } - //------------ WRITE -----------// - else if(pmt_eq(event, s_cmd_usrp_write)) { - handle_cmd_write(data); - return; - } - //-------- START READING --------// - else if(pmt_eq(event, s_cmd_usrp_start_reading)) { - handle_cmd_start_reading(data); - return; - } - //-------- STOP READING --------// - else if(pmt_eq(event, s_cmd_usrp_stop_reading)) { - handle_cmd_stop_reading(data); - return; - } - - goto unhandled; - } - - //---------------- RX ------------------// - if (pmt_eq(port_id, d_rx_cs->port_symbol())) { - - // Relay reads back up - if(pmt_eq(event, s_response_usrp_rx_read)) { - d_cs->send(s_response_usrp_read, data); - return; - } - - goto unhandled; - } - - //---------------- TX ------------------// - if (pmt_eq(port_id, d_tx_cs->port_symbol())) { - - if(pmt_eq(event, s_response_usrp_tx_write)) { - - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - d_cs->send(s_response_usrp_write, - pmt_list3(invocation_handle, - status, - channel)); - - return; - } - - goto unhandled; - } - - unhandled: - std::cout << "[USRP_USB_INTERFACE] unhandled msg: " << msg << std::endl; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * open a USB connection to the USRP (cmd-usrp-open). - * - * The \p data parameter is a PMT list, where the elements are an invocation - * handle and the USRP number. - */ -void -usrp_usb_interface::handle_cmd_open(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long which_usrp = pmt_to_long(pmt_nth(1, data)); - pmt_t reply_data; - - if(d_fake_usrp) { - d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T)); - return; - } - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Handling open request for USRP " << which_usrp << "\n"; - - // Open up a standard RX and TX for communication with the USRP - - d_utx = usrp_standard_tx::make(which_usrp, - d_interp_tx, - 1, // 1 channel - -1, // mux - 4096, // USB block size - 16, // nblocks for async transfers - d_rbf - ); - - if(d_utx==0) { - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Failed to open TX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - // Perform TX daughterboard tuning - double target_freq; - unsigned int mux; - int tgain, rgain; - float input_rate; - bool ok; - usrp_tune_result r; - - // Cast to usrp_basic and then detect daughterboards - d_ub_tx = d_utx; - usrp_subdev_spec tspec = pick_tx_subdevice(); - db_base_sptr tsubdev = d_ub_tx->selected_subdev(tspec); - - // Set the TX mux value - mux = d_utx->determine_tx_mux_value(tspec); - d_utx->set_mux(mux); - - // Set the TX gain and determine rate - tgain = tsubdev->gain_max(); - tsubdev->set_gain(tgain); - input_rate = d_ub_tx->converter_rate() / d_utx->interp_rate(); - - // Perform the actual tuning, if no frequency specified then pick - if(d_rf_freq==-1) - target_freq = tsubdev->freq_min()+((tsubdev->freq_max()-tsubdev->freq_min())/2.0); - else - target_freq = d_rf_freq; - ok = d_utx->tune(tsubdev->which(), tsubdev, target_freq, &r); - tsubdev->set_enable(true); - - if(verbose) { - printf("TX Subdevice name is %s\n", tsubdev->name().c_str()); - printf("TX Subdevice freq range: (%g, %g)\n", - tsubdev->freq_min(), tsubdev->freq_max()); - printf("mux: %#08x\n", mux); - printf("target_freq: %f\n", target_freq); - printf("ok: %s\n", ok ? "true" : "false"); - printf("gain: %d\n", tgain); - printf("r.baseband_freq: %f\n", r.baseband_freq); - printf("r.dxc_freq: %f\n", r.dxc_freq); - printf("r.residual_freq: %f\n", r.residual_freq); - printf("r.inverted: %d\n", r.inverted); - } - - if(!ok) { - std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on TX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - d_utx->start(); - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Setup TX channel\n"; - - d_urx = - usrp_standard_rx::make (which_usrp, - d_decim_rx, - 1, // nchan - -1, // mux - 0, // set blank mode to start - 4096, // USB block size - 16, // number of blocks for async transfers - d_rbf); - - if(!d_urx) { - if (verbose) - std::cout << "[usrp_server] Failed to open RX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - // Cast to usrp_basic and then detect daughterboards - d_ub_rx = d_urx; - usrp_subdev_spec rspec = pick_rx_subdevice(); - db_base_sptr rsubdev = d_ub_rx->selected_subdev(rspec); - - // Set the RX mux value - mux = d_urx->determine_rx_mux_value(rspec); - d_urx->set_mux(mux); - - // Set the RX gain and determine rate - rgain = rsubdev->gain_max()/2.0; - rsubdev->set_gain(rgain); - input_rate = d_ub_rx->converter_rate() / d_urx->decim_rate(); - - ok = d_urx->tune(rsubdev->which(), rsubdev, target_freq, &r); - rsubdev->set_enable(true); - - if(verbose) { - printf("RX Subdevice name is %s\n", rsubdev->name().c_str()); - printf("RX Subdevice freq range: (%g, %g)\n", - rsubdev->freq_min(), rsubdev->freq_max()); - printf("mux: %#08x\n", mux); - printf("target_freq: %f\n", target_freq); - printf("ok: %s\n", ok ? "true" : "false"); - printf("gain: %d\n", rgain); - printf("r.baseband_freq: %f\n", r.baseband_freq); - printf("r.dxc_freq: %f\n", r.dxc_freq); - printf("r.residual_freq: %f\n", r.residual_freq); - printf("r.inverted: %d\n", r.inverted); - } - - if(!ok) { - std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on RX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n"; - -// d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf); -// d_utx->_write_oe(0, 0xffff, 0xffff); -// d_urx->_write_oe(0, 0xffff, 0xffff); -// d_utx->_write_oe(1, 0xffff, 0xffff); -// d_urx->_write_oe(1, 0xffff, 0xffff); - - d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T)); -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * write data to the USB bus (cmd-usrp-write). - * - * The \p data parameter is a PMT list containing 3 mandatory elements in the - * following order: an invocation handle, channel, and a uniform vector - * representation of the packets. - */ -void -usrp_usb_interface::handle_cmd_write(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t channel = pmt_nth(1, data); - pmt_t pkts = pmt_nth(2, data); - - pmt_t tx_handle = pmt_make_any(d_utx); - - d_tx_cs->send(s_cmd_usrp_tx_write, - pmt_list4(invocation_handle, - channel, - pkts, - tx_handle)); -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * start reading data from the USB bus (cmd-usrp-start-reading). - * - * The \p data parameter is a PMT list with a single element: an invocation - * handle which can be returned with the response. - */ -void -usrp_usb_interface::handle_cmd_start_reading(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - - if(verbose) - std::cout << "[USRP_USB_INTERFACE] Starting RX...\n"; - - if(!d_fake_usrp) - d_urx->start(); - - pmt_t rx_handle = pmt_make_any(d_urx); - - d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle)); - - d_rx_reading = true; - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * stop reading data from the USB bus (cmd-usrp-stop-reading). - * - * The \p data parameter is a PMT list with a single element: an invocation - * handle which can be returned with the response. - */ -void -usrp_usb_interface::handle_cmd_stop_reading(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - - if(!d_fake_usrp) { - if(verbose) - std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n"; - usrp_rx_stop = true; - - // Used to allow a read() being called by a lower layer to complete before - // stopping, else there can be partial data left on the bus and can generate - // errors. - while(usrp_rx_stop) {usleep(1);} - d_urx->stop(); - } - else { - if(verbose) - std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n"; - usrp_rx_stop_stub = true; // extern to communicate with stub to wait - } - - d_rx_reading = false; - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * close the USB connection to the USRP. - * - * The \p data parameter is a PMT list with a single element: an invocation - * handle which can be returned with the response. - */ -void -usrp_usb_interface::handle_cmd_close(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - - if(d_rx_reading) - handle_cmd_stop_reading(PMT_NIL); - - if(d_fake_usrp) { - d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T)); - return; - } - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Handling close request for USRP\n"; - - d_utx.reset(); - d_urx.reset(); - - d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T)); - - // FIXME This seems like a _very_ strange place to be calling shutdown_all. - // That decision should be left to high-level code, not low-level code like this. - shutdown_all(PMT_T); -} - -usrp_subdev_spec -usrp_usb_interface::pick_rx_subdevice() -{ - int dbids[] = { - USRP_DBID_FLEX_400_RX, - USRP_DBID_FLEX_900_RX, - USRP_DBID_FLEX_1200_RX, - USRP_DBID_FLEX_2400_RX, - USRP_DBID_TV_RX, - USRP_DBID_TV_RX_REV_2, - USRP_DBID_DBS_RX, - USRP_DBID_BASIC_RX - }; - - std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int))); - return pick_subdev(d_ub_rx, candidates); -} - -usrp_subdev_spec -usrp_usb_interface::pick_tx_subdevice() -{ - int dbids[] = { - USRP_DBID_FLEX_400_TX, - USRP_DBID_FLEX_900_TX, - USRP_DBID_FLEX_1200_TX, - USRP_DBID_FLEX_2400_TX, - USRP_DBID_BASIC_TX - }; - - std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int))); - return pick_subdev(d_ub_tx, candidates); -} - -usrp_subdev_spec -usrp_usb_interface::pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates) -{ - int dbid0 = d_usrp_basic->selected_subdev(usrp_subdev_spec(0, 0))->dbid(); - int dbid1 = d_usrp_basic->selected_subdev(usrp_subdev_spec(1, 0))->dbid(); - - for (int i = 0; i < candidates.size(); i++) { - int dbid = candidates[i]; - if (dbid0 == dbid) - return usrp_subdev_spec(0, 0); - if (dbid1 == dbid) - return usrp_subdev_spec(1, 0); - } - - if (dbid0 >= 0) - return usrp_subdev_spec(0, 0); - if (dbid1 >= 0) - return usrp_subdev_spec(1, 0); - - throw std::runtime_error("No suitable daughterboard found!"); -} - - -REGISTER_MBLOCK_CLASS(usrp_usb_interface); diff --git a/usrp/host/lib/inband/usrp_usb_interface.h b/usrp/host/lib/inband/usrp_usb_interface.h deleted file mode 100644 index 4d7750a7d..000000000 --- a/usrp/host/lib/inband/usrp_usb_interface.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,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_USRP_USB_INTERFACE_H -#define INCLUDED_USRP_USB_INTERFACE_H - -#include <mblock/mblock.h> -#include <vector> -#include "usrp_standard.h" - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_usb_interface : public mb_mblock -{ - public: - - usrp_standard_tx_sptr d_utx; - usrp_standard_rx_sptr d_urx; - - boost::shared_ptr<usrp_basic> d_ub_tx; - boost::shared_ptr<usrp_basic> d_ub_rx; - - mb_port_sptr d_cs; - mb_port_sptr d_rx_cs; - mb_port_sptr d_tx_cs; - - long d_ntx_chan; - long d_nrx_chan; - - bool d_fake_usrp; - - bool d_rx_reading; - - long d_interp_tx; - long d_decim_rx; - - double d_rf_freq; - - std::string d_rbf; - - public: - usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_usb_interface(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - usrp_subdev_spec pick_rx_subdevice(); - usrp_subdev_spec pick_tx_subdevice(); - usrp_subdev_spec pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates); - - private: - void handle_cmd_open(pmt_t data); - void handle_cmd_close(pmt_t data); - void handle_cmd_write(pmt_t data); - void handle_cmd_start_reading(pmt_t data); - void handle_cmd_stop_reading(pmt_t data); - -}; - - -#endif /* INCLUDED_USRP_USB_INTERFACE_H */ |