[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r5612 - gnuradio/branches/features/inband-usb/usrp/hos
From: |
gnychis |
Subject: |
[Commit-gnuradio] r5612 - gnuradio/branches/features/inband-usb/usrp/host/lib/inband |
Date: |
Sat, 2 Jun 2007 17:41:17 -0600 (MDT) |
Author: gnychis
Date: 2007-06-02 17:41:17 -0600 (Sat, 02 Jun 2007)
New Revision: 5612
Added:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.h
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.mbh
Log:
Merging from -r5227:5611 branches/developers/gnychis/inband
Modified: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
2007-06-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
2007-06-02 23:41:17 UTC (rev 5612)
@@ -27,41 +27,52 @@
TESTS = test_inband
EXTRA_DIST = \
- usrp_server.mbh
+ usrp_server.mbh \
+ usrp_interface.mbh
+
lib_LTLIBRARIES = \
- libusrp_inband.la \
- libusrp_inband-qa.la
+ libusrp_inband.la \
+ libusrp_inband-qa.la
# ------------------------------------------------------------------------
# Build the inband library
BUILT_SOURCES = \
- usrp_server_mbh.cc
+ usrp_server_mbh.cc \
+ usrp_interface_mbh.cc
usrp_server_mbh.cc : usrp_server.mbh
$(COMPILE_MBH) usrp_server.mbh usrp_server_mbh.cc
+usrp_interface_mbh.cc : usrp_interface.mbh
+ $(COMPILE_MBH) usrp_interface.mbh usrp_interface_mbh.cc
+
libusrp_inband_la_SOURCES = \
$(BUILT_SOURCES) \
- usrp_server.cc
+ usrp_server.cc \
+ usrp_usb_interface.cc \
+ usrp_usb_interface_stub.cc
libusrp_inband_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
libusrp_inband_la_LIBADD = \
$(MBLOCK_LA) \
+ $(USRP_LA) \
-lstdc++
-
include_HEADERS = \
- usrp_server.h
+ usrp_server.h \
+ usrp_usb_interface.h \
+ usrp_inband_usb_packet.h \
+ usrp_usb_interface_stub.h
noinst_HEADERS = \
qa_inband.h \
qa_inband_packet_prims.h \
qa_inband_usrp_server.h \
- usrp_inband_usb_packet.h
+ fake_usrp.h
# ------------------------------------------------------------------------
@@ -70,7 +81,8 @@
libusrp_inband_qa_la_SOURCES = \
qa_inband.cc \
qa_inband_packet_prims.cc \
- qa_inband_usrp_server.cc
+ qa_inband_usrp_server.cc \
+ fake_usrp.cc
# magic flags
libusrp_inband_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version
@@ -79,17 +91,21 @@
libusrp_inband_qa_la_LIBADD = \
libusrp_inband.la \
$(CPPUNIT_LIBS) \
+ $(USRP_LA) \
-lstdc++
# ------------------------------------------------------------------------
noinst_PROGRAMS = \
- test_inband
+ test_inband \
+ test_usrp_inband
test_inband_SOURCES = test_inband.cc
test_inband_LDADD = libusrp_inband-qa.la
+test_usrp_inband_SOURCES = test_usrp_inband.cc
+test_usrp_inband_LDADD = libusrp_inband-qa.la
+
MOSTLYCLEANFILES = \
$(BUILT_SOURCES) *~ *.pyc
-
Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/fake_usrp.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc
(rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,135 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <fake_usrp.h>
+#include <iostream>
+#include <usrp_inband_usb_packet.h>
+#include <mb_class_registry.h>
+#include <vector>
+
+typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit
easy
+
+fake_usrp::fake_usrp()
+{
+ std::cout << "[fake_usrp] Initializing...\n";
+}
+
+fake_usrp::~fake_usrp() {}
+
+long
+fake_usrp::write_bus(transport_pkt *pkts, long n_bytes)
+{
+ std::cout << "[fake_usrp] Bytes over bus: " << n_bytes << "\n";
+
+ // I'm assuming that a control packet cannot exist in a burst of data
packets,
+ // therefore i read only the first packet's channel in the current burst
+ if(pkts[0].chan() == 0x1f) {
+ return control_block(pkts, n_bytes);
+ } else {
+ return data_block(pkts, n_bytes);
+ }
+
+}
+
+long
+fake_usrp::data_block(transport_pkt *pkts, long n_bytes)
+{
+ std::cout << "[fake_usrp] Entering data block\n";
+
+ // Infer the number of packets from the byte count to do logical tests
+ long n_pkts = static_cast<long>(std::ceil(n_bytes /
(double)transport_pkt::max_pkt_size()));
+
+ std::cout << "[fake_usrp] Number of packets: " << n_pkts << "\n";
+
+ // The first packet should have the start of burst, and the last packet
should have end of burst
+ if(pkts[0].start_of_burst() && pkts[n_pkts-1].end_of_burst()) {
+ std::cout << "[fake_usrp] Correct burst flags set\n";
+ } else {
+ std::cout << "[fake_usrp] Incorrect burst flags set!\n";
+ return 0;
+ }
+
+ // All other flags should be set to 0 (e.g., overrun should not be set yet)
on ALL packets
+ for(int i=0; i < n_pkts; i++) {
+ if(pkts[i].overrun()) {
+ std::cout << "[fake_usrp] Incorrect set of overrun flag on transmit\n";
+ return 0;
+ } else if(pkts[i].underrun()) {
+ std::cout << "[fake_usrp] Incorrect set of underrun flag on transmit\n";
+ return 0;
+ } else if(pkts[i].dropped()) {
+ std::cout << "[fake_usrp] Incorrect set of drop flag on transmit\n";
+ return 0;
+ }
+ }
+ std::cout << "[fake_usrp] Correct overrun, underrun, and drop flags on
transmit (initialized to 0)\n";
+
+ // The first packet should have a timestamp, other packets should have "NOW"
+ if(pkts[0].timestamp() != 0xffffffff) {
+ std::cout << "[fake_usrp] Correct timestamp on first packet\n";
+ } else {
+ std::cout << "[fake_usrp] Initial packet should not have the 0xffffffff
timestamp\n";
+ return 0;
+ }
+
+ // Check that all of the other packets include the NOW timestamp
+ int check_stamps=1;
+ for(int i=1; i < n_pkts; i++) // start at 1 to skip the first
packet
+ if(pkts[i].timestamp() != 0xffffffff)
+ check_stamps=0;
+
+ if(check_stamps) {
+ std::cout << "[fake_usrp] Correct NOW timestamps (0xffffffff) on
intermediate burst packets\n";
+ } else {
+ std::cout << "[fake_usrp] Incorrect timestamps on intermediate burst
packets\n";
+ return 0;
+ }
+
+ // Since we are being transparent about samples, we do not ensure the
payload is correct, however
+ // it should be the case that if there are >1 packets, all packets except
the last packet should
+ // have a full payload size
+ if(n_pkts > 1) {
+ int check_size=1;
+ for(int i=0; i < n_pkts-1; i++)
+ if(pkts[i].payload_len() != transport_pkt::max_payload())
+ check_size=0;
+
+ if(check_size) {
+ std::cout << "[fake_usrp] Correct payload size sanity check on
packets\n";
+ } else {
+ std::cout << "[fake_usrp] Failed payload size sanity check\n";
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+long
+fake_usrp::control_block(transport_pkt *pkts, long n_bytes)
+{
+ std::cout << "[fake_usrp] Entering control block\n";
+
+ return 1;
+}
Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/fake_usrp.h)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h
(rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,43 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_FAKE_USRP_H
+#define INCLUDED_FAKE_USRP_H
+
+#include <usrp_inband_usb_packet.h>
+typedef usrp_inband_usb_packet transport_pkt;
+
+/*!
+ * \brief Implements a fake USRP for testing without hardware
+ */
+class fake_usrp
+{
+ public:
+ fake_usrp();
+ ~fake_usrp();
+ long write_bus(transport_pkt *pkts, long n_bytes);
+
+ protected:
+ long data_block(transport_pkt *pkts, long n_bytes);
+ long control_block(transport_pkt *pkts, long n_bytes);
+};
+
+#endif /* INCLUDED_FAKE_USRP_H */
+
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
2007-06-02 22:43:26 UTC (rev 5611)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
2007-06-02 23:41:17 UTC (rev 5612)
@@ -23,6 +23,7 @@
#include <config.h>
#endif
+#include <usrp_inband_usb_packet.h>
#include <qa_inband_usrp_server.h>
#include <cppunit/TestAssert.h>
#include <stdio.h>
@@ -33,7 +34,14 @@
#include <mb_class_registry.h>
#include <vector>
#include <iostream>
+#include <pmt.h>
+typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit
easy
+
+static pmt_t s_cmd_open = pmt_intern("cmd-open");
+static pmt_t s_response_open = pmt_intern("response-open");
+static pmt_t s_cmd_close = pmt_intern("cmd-close");
+static pmt_t s_response_close = pmt_intern("response-close");
static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
static pmt_t s_response_allocate_channel =
pmt_intern("response-allocate-channel");
static pmt_t s_send_allocate_channel = pmt_intern("send-allocate-channel");
@@ -48,8 +56,9 @@
static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
static pmt_t s_cmd_current_capacity_allocation =
pmt_intern("cmd-current-capacity-allocation");
static pmt_t s_response_current_capacity_allocation =
pmt_intern("response-current-capacity-allocation");
+static pmt_t s_cmd_xmit_raw_frame = pmt_intern("cmd-xmit-raw-frame");
+static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
-
//
----------------------------------------------------------------------------------------------
class qa_alloc_top : public mb_mblock
@@ -82,16 +91,20 @@
: mb_mblock(runtime, instance_name, user_arg)
{
d_nrecvd=0;
- d_nmsgs_to_recv = 7;
+ d_nmsgs_to_recv = 6;
d_nstatus=0;
- d_nstatus_to_recv = 3;
+ 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("usrp-interface"),
pmt_intern("usrp_usb_interface_stub"));
// Test the TX side
- define_component("server", "usrp_server", PMT_F);
+ define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
connect("self", "tx0", "server", "tx0");
connect("self", "rx0", "server", "rx0");
connect("self", "cs", "server", "cs");
@@ -103,10 +116,15 @@
void
qa_alloc_top::initial_transition()
{
+ // Allocations should fail before open
+ d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_F, pmt_from_long(1)));
+ d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_F, pmt_from_long(1)));
+
// Retrieve information about the USRP, then run tests
- d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_F));
- d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_F));
- d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_F));
+ d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
+ d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_T));
+ d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_T));
+ d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_T));
}
void
@@ -154,15 +172,15 @@
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(1, data));
+ d_max_capacity = pmt_to_long(pmt_nth(2, data));
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(1, data));
+ d_ntx_chan = pmt_to_long(pmt_nth(2, data));
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(1, data));
+ d_nrx_chan = pmt_to_long(pmt_nth(2, data));
std::cout << "[qa_alloc_top] USRP rx channels: " << d_nrx_chan << "\n";
}
else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
@@ -171,6 +189,8 @@
d_nstatus++;
+ check_message(msg);
+
if(d_nstatus==d_nstatus_to_recv)
run_tests();
}
@@ -244,14 +264,18 @@
d_nalloc_recvd=0;
d_nalloc_to_recv = 0;
d_nstatus=0;
- d_nstatus_to_recv = 3;
+ 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("usrp-interface"),
pmt_intern("usrp_usb_interface_stub"));
+
// Test the TX side
- define_component("server", "usrp_server", PMT_F);
+ define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
connect("self", "tx0", "server", "tx0");
connect("self", "rx0", "server", "rx0");
connect("self", "cs", "server", "cs");
@@ -263,9 +287,10 @@
qa_dealloc_top::initial_transition()
{
// Retrieve information about the USRP, then run tests
- d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_F));
- d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_F));
- d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_F));
+ d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
+ d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_T));
+ d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_T));
+ d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_T));
}
void
@@ -316,7 +341,7 @@
// 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_from_long(0)));
+ d_cs->send(s_cmd_current_capacity_allocation, pmt_list1(PMT_T));
}
void
@@ -338,15 +363,15 @@
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(1, data));
+ d_max_capacity = pmt_to_long(pmt_nth(2, data));
std::cout << "[qa_dealloc_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(1, data));
+ d_ntx_chan = pmt_to_long(pmt_nth(2, data));
std::cout << "[qa_dealloc_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(1, data));
+ d_nrx_chan = pmt_to_long(pmt_nth(2, data));
std::cout << "[qa_dealloc_top] USRP rx channels: " << d_nrx_chan << "\n";
}
else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
@@ -426,12 +451,335 @@
//
----------------------------------------------------------------------------------------------
+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("usrp-interface"),
pmt_intern("usrp_usb_interface_stub"));
+
+ // Test the TX side
+ define_component("server", "usrp_server", pmt_list1(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_F));
+
+ // Perform an open, and a second open which should fail
+ d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
+ d_cs->send(s_cmd_open, pmt_list2(PMT_F, pmt_from_long(0)));
+
+ // A close should now be successful since the interface is open
+ d_cs->send(s_cmd_close, pmt_list1(PMT_T));
+
+ // But, a second close should fail
+ d_cs->send(s_cmd_close, pmt_list1(PMT_F));
+
+ // Just to be thorough, try an open and close again
+ d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
+ d_cs->send(s_cmd_close, pmt_list1(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 expected_result = pmt_nth(0, data);
+ pmt_t result = pmt_nth(1, data);
+
+ if(!pmt_eqv(expected_result, result)) {
+ std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << result << "
Expected: " << expected_result << " for event " << msg->signal() << "\n";
+ shutdown_all(PMT_F);
+ } else {
+ std::cout << "[qa_open_close_top] Received expected CS response for
message (" << msg->signal() << ")\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=12;
+ 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("usrp-interface"),
pmt_intern("usrp_usb_interface_stub"));
+
+ // Test the TX side
+ define_component("server", "usrp_server", pmt_list1(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()
+{
+ 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_F, pmt_from_long(0),
pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
+
+ // Open, and now try an xmit again which should be successful
+ d_cs->send(s_cmd_open, pmt_list2(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_from_long(usrp_server::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_T, pmt_from_long(1)));
+ d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(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_T));
+
+ // After closing, a new transmit raw frame should fail again
+ d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(PMT_F, 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_T, pmt_from_long(0)));
+ d_tx->send(s_cmd_xmit_raw_frame,
pmt_list4(pmt_from_long(usrp_server::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_T, pmt_from_long(1)));
+ d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(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_T));
+
+}
+
+
+void
+qa_tx_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())) {
+
+ if(pmt_eq(msg->signal(), s_response_allocate_channel))
+ check_allocation(msg);
+
+ if(pmt_eq(msg->signal(), s_response_xmit_raw_frame))
+ check_xmit(msg);
+ }
+
+ 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_tx_top::check_deallocation(mb_message_sptr msg)
+{
+ pmt_t data = msg->data();
+
+ pmt_t expected_result = pmt_nth(0, data);
+ pmt_t result = pmt_nth(1, data);
+
+ if(!pmt_eqv(expected_result, result)) {
+ std::cout << "[qa_tx_top] FAILED check_deallocation... Got: " << result <<
" Expected: " << expected_result << "\n";
+ shutdown_all(PMT_F);
+ } else {
+ std::cout << "[qa_tx_top] Received expected deallocation response for
message\n";
+ }
+}
+
+void
+qa_tx_top::check_allocation(mb_message_sptr msg)
+{
+ pmt_t data = msg->data();
+
+ pmt_t expected_result = pmt_nth(0, data);
+ pmt_t result = pmt_nth(1, data);
+ pmt_t channel = pmt_nth(2, data);
+
+ if(!pmt_eqv(expected_result, result)) {
+ std::cout << "[qa_tx_top] FAILED check_allocation... Got: " << result << "
Expected: " << expected_result << " for event " << msg->signal() << ")\n";
+ shutdown_all(PMT_F);
+ } else {
+ std::cout << "[qa_tx_top] Received expected allocation response for
message\n";
+ }
+
+ if(pmt_eqv(result, 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);
+ }
+}
+
+void
+qa_tx_top::check_xmit(mb_message_sptr msg)
+{
+ pmt_t data = msg->data();
+
+ pmt_t expected_result = pmt_nth(0, data);
+ pmt_t result = pmt_nth(1, data);
+
+ if(!pmt_eqv(expected_result, result)) {
+ std::cout << "[qa_tx_top] FAILED check_xmit... Got: " << result << "
Expected: " << expected_result << " for event " << msg->signal() << ")\n";
+ shutdown_all(PMT_F);
+ } else {
+ std::cout << "[qa_tx_top] Received expected xmit response for message\n";
+ }
+}
+
+void
+qa_tx_top::check_cs(mb_message_sptr msg)
+{
+ pmt_t data = msg->data();
+
+ pmt_t expected_result = pmt_nth(0, data);
+ pmt_t result = pmt_nth(1, data);
+
+ if(!pmt_eqv(expected_result, result)) {
+ std::cout << "[qa_tx_top] FAILED check_cs... Got: " << result << "
Expected: " << expected_result << " for event " << msg->signal() << "\n";
+ shutdown_all(PMT_F);
+ } else {
+ std::cout << "[qa_tx_top] Received expected CS response for message (" <<
msg->signal() << ")\n";
+ }
+
+}
+
+REGISTER_MBLOCK_CLASS(qa_tx_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("top", "qa_alloc_top", PMT_F, &result);
CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
@@ -443,13 +791,24 @@
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("top", "qa_dealloc_top", PMT_F, &result);
CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
}
void
-qa_inband_usrp_server::test_fragmentation()
+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));
}
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
2007-06-02 22:43:26 UTC (rev 5611)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
2007-06-02 23:41:17 UTC (rev 5612)
@@ -28,15 +28,17 @@
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_fragmentation);
+ CPPUNIT_TEST(test_tx);
CPPUNIT_TEST_SUITE_END();
private:
void test_chan_allocation();
void test_chan_deallocation();
- void test_fragmentation();
+ void test_open_close();
+ void test_tx();
};
#endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */
Copied:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/test_usrp_inband.cc)
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc
(rev 0)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,297 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <iostream>
+#include <usrp_inband_usb_packet.h>
+#include <mb_mblock.h>
+#include <mb_runtime.h>
+#include <mb_protocol_class.h>
+#include <mb_class_registry.h>
+#include <pmt.h>
+#include "usrp_standard.h"
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+// Signal set for the USRP server
+static pmt_t s_cmd_open = pmt_intern("cmd-open");
+static pmt_t s_response_open = pmt_intern("response-open");
+static pmt_t s_cmd_close = pmt_intern("cmd-close");
+static pmt_t s_response_close = pmt_intern("response-close");
+static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
+static pmt_t s_response_allocate_channel =
pmt_intern("response-allocate-channel");
+static pmt_t s_send_allocate_channel = pmt_intern("send-allocate-channel");
+static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
+static pmt_t s_response_deallocate_channel =
pmt_intern("response-deallocate-channel");
+static pmt_t s_send_deallocate_channel = pmt_intern("send-deallocate-channel");
+static pmt_t s_cmd_max_capacity = pmt_intern("cmd-max-capacity");
+static pmt_t s_response_max_capacity = pmt_intern("response-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_response_ntx_chan = pmt_intern("response-ntx-chan");
+static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
+static pmt_t s_cmd_current_capacity_allocation =
pmt_intern("cmd-current-capacity-allocation");
+static pmt_t s_response_current_capacity_allocation =
pmt_intern("response-current-capacity-allocation");
+static pmt_t s_cmd_xmit_raw_frame = pmt_intern("cmd-xmit-raw-frame");
+static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
+
+bool loopback_p = false;
+bool counting_p = false;
+bool fake_usrp_p = false;
+char *prog_name;
+
+static void
+set_progname (char *path)
+{
+ char *p = strrchr (path, '/');
+ if (p != 0)
+ prog_name = p+1;
+ else
+ prog_name = path;
+}
+
+static void
+usage()
+{
+ fprintf (stderr, "usage: %s [-l]\n", prog_name);
+ fprintf (stderr, " [-l] digital loopback in FPGA\n");
+ fprintf (stderr, " [-c] counting in FPGA\n");
+ fprintf (stderr, " [-f] fake usrp\n");
+
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+
+ set_progname(argv[0]);
+
+ mb_runtime_sptr rt = mb_make_runtime();
+ pmt_t result = PMT_T;
+
+ while ((ch = getopt(argc, argv, "flc")) != EOF) {
+ switch(ch) {
+
+ case 'l':
+ loopback_p = true;
+ break;
+
+ case 'c':
+ counting_p = true;
+ break;
+
+ case 'f':
+ fake_usrp_p = true;
+ break;
+
+ default:
+ usage();
+ }
+ }
+
+
+ std::cout << "[test_usrp_inband] Starting...\n";
+
+ rt->run("top", "test_usrp_inband_top", PMT_F, &result);
+}
+
+class test_usrp_inband_top : public mb_mblock
+{
+ mb_port_sptr d_tx;
+ mb_port_sptr d_cs;
+
+ long d_tx_chan;
+
+ public:
+ test_usrp_inband_top(mb_runtime *runtime, const std::string &instance_name,
pmt_t user_arg);
+ ~test_usrp_inband_top();
+ void initial_transition();
+ void handle_message(mb_message_sptr msg);
+
+ protected:
+ void open_usrp();
+ void close_usrp();
+ void check_message(mb_message_sptr msg);
+ void allocate_channel();
+ void send_packets();
+};
+
+test_usrp_inband_top::test_usrp_inband_top(mb_runtime *runtime, const
std::string &instance_name, pmt_t user_arg)
+ : mb_mblock(runtime, instance_name, user_arg)
+{
+ std::cout << "[TEST_USRP_INBAND_TOP] Initializing...\n";
+
+ d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+ d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+ // Test the TX side
+
+ // Pass a dictionary to usrp_server which specifies which interface to use,
the stub or USRP
+ pmt_t usrp_server_dict = pmt_make_dict();
+
+ if(fake_usrp_p)
+ pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"),
pmt_intern("usrp_usb_interface_stub"));
+
+ define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
+ connect("self", "tx0", "server", "tx0");
+ connect("self", "cs", "server", "cs");
+}
+
+test_usrp_inband_top::~test_usrp_inband_top()
+{
+}
+
+void
+test_usrp_inband_top::initial_transition()
+{
+ open_usrp();
+}
+
+void
+test_usrp_inband_top::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 metadata = msg->metadata();
+ pmt_t status;
+
+ if (pmt_eq(port_id, d_cs->port_symbol())) { // message came in on our
control/status port
+
+ //---------- OPEN RESPONSE ----------//
+ if (pmt_eq(event, s_response_open)) {
+ status = pmt_nth(1, data);
+
+ if(pmt_eq(status, PMT_T)) {
+ std::cout << "[TEST_USRP_INBAND_TOP] Success opening USRP\n";
+ }
+ else {
+ std::cout << "[TEST_USRP_INBAND_TOP] Received error message opening
USRP\n";
+ shutdown_all(PMT_F);
+ }
+
+ allocate_channel();
+
+ return;
+ }
+ //--------- CLOSE RESPONSE -----------//
+ else if (pmt_eq(event, s_response_close)) {
+ status = pmt_nth(1, data);
+
+ if(pmt_eq(status, PMT_T)) {
+ std::cout << "[TEST_USRP_INBAND_TOP] Successfully closed USRP\n";
+ }
+ else {
+ std::cout << "[TEST_USRP_INBAND_TOP] Received error message closing
USRP\n";
+ shutdown_all(PMT_F);
+ }
+
+ shutdown_all(PMT_T);
+
+ return;
+ }
+ }
+
+ if (pmt_eq(port_id, d_tx->port_symbol())) {
+
+ //---------- ALLOCATE RESPONSE ---------//
+ if(pmt_eq(event, s_response_allocate_channel)) {
+ status = pmt_nth(1, data);
+ pmt_t channel = pmt_nth(2, data);
+
+ if(pmt_eq(status, PMT_T)) {
+ d_tx_chan = pmt_to_long(channel);
+ std::cout << "[TEST_USRP_INBAND_TOP] Received allocation on channel "
<< d_tx_chan << "\n";
+ }
+ else {
+ std::cout << "[TEST_USRP_INBAND_TOP] Error allocating channel\n";
+ shutdown_all(PMT_F);
+ }
+
+ send_packets();
+
+ return;
+ }
+ //----------- XMIT RESPONSE ------------//
+ else if(pmt_eq(event, s_response_xmit_raw_frame)) {
+ status = pmt_nth(1, data);
+
+ if(pmt_eq(status, PMT_T)) {
+ std::cout << "[TEST_USRP_INBAND_TOP] Transmission successful\n";
+ }
+ else {
+ std::cout << "[TEST_USRP_INBAND_TOP] Failed transmission\n";
+ shutdown_all(PMT_F);
+ }
+
+ close_usrp();
+
+ return;
+ }
+ }
+
+ std::cout << "[TEST_USRP_INBAND_TOP] Received unhandled message: " << event
<< "\n";
+}
+
+void
+test_usrp_inband_top::allocate_channel()
+{
+ std::cout << "[TEST_USRP_INBAND_TOP] Requesting channel allocation...\n";
+
+ d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+}
+
+void
+test_usrp_inband_top::send_packets()
+{
+ std::cout << "[TEST_USRP_INBAND_TOP] Sending single packet..\n";
+ d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(pmt_from_long(1),
pmt_from_long(d_tx_chan), pmt_make_u32vector(transport_pkt::max_payload()/4,
0), pmt_from_long(0)));
+
+}
+
+void
+test_usrp_inband_top::open_usrp()
+{
+ pmt_t usrp = pmt_from_long(0);
+
+ long rx_mode = 0;
+
+ if(loopback_p)
+ rx_mode |= usrp_standard_rx::FPGA_MODE_LOOPBACK;
+ if(counting_p)
+ rx_mode |= usrp_standard_rx::FPGA_MODE_COUNTING;
+
+ d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, usrp));
+}
+
+void
+test_usrp_inband_top::close_usrp()
+{
+ d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_inband_top);
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.h
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.h
2007-06-02 22:43:26 UTC (rev 5611)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.h
2007-06-02 23:41:17 UTC (rev 5612)
@@ -144,6 +144,10 @@
return MAX_PAYLOAD;
}
+ static int max_pkt_size() {
+ return USB_PKT_SIZE;
+ }
+
};
#endif
Copied:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_interface.mbh)
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh
(rev 0)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,51 @@
+;; -*- 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++.
+;; ----------------------------------------------------------------
+
+;; ----------------------------------------------------------------
+;; tx-channels
+;;
+;; Handles a query for the number of tx-channels
+
+(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 n-bytes)
+ )
+
+ (: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 channel status)
+ )
+ )
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
2007-06-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
2007-06-02 23:41:17 UTC (rev 5612)
@@ -27,6 +27,8 @@
#include <usrp_inband_usb_packet.h>
#include <mb_class_registry.h>
#include <vector>
+#include <usrp_usb_interface.h>
+#include <usrp_usb_interface_stub.h>
typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit
easy
@@ -61,6 +63,18 @@
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");
+// USRP signal set
+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_write = pmt_intern("cmd-usrp-write");
+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_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_open = pmt_intern("response-usrp-open");
+static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close");
+static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write");
+
static std::string
str(long x)
{
@@ -72,10 +86,25 @@
usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name,
pmt_t user_arg)
: mb_mblock(rt, instance_name, user_arg)
{
- // define our ports
+ // Default USRP interface
+ std::string usrp_interface = "usrp_usb_interface";
+
+ // a dictionary is given for usrp server parameters, such as the interface
to use
+ pmt_t usrp_dict = pmt_nth(0, user_arg);
+
+ if(!pmt_eqv(usrp_dict, PMT_NIL)) {
+
+ if(pmt_dict_has_key(usrp_dict, pmt_intern("usrp-interface")))
+ usrp_interface = pmt_write_string(pmt_dict_ref(usrp_dict,
pmt_intern("usrp-interface"), PMT_NIL));
+
+ }
+
+ std::cout << "[USRP_SERVER] Using interface: " << usrp_interface << "\n";
+
// 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
//
@@ -86,12 +115,25 @@
d_rx.push_back(define_port("rx"+str(port), "usrp-rx", true,
mb_port::EXTERNAL));
}
- // FIXME ... initializing to 2 channels on each for now, eventually we should
- // query the FPGA to get these values
+ define_component("usrp", usrp_interface, PMT_F);
+ 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;
- d_nrx_chan = 2;
// Initialize capacity on each channel to 0 and to no owner
+ // Also initialize the USRP standard tx/rx pointers to NULL
+ reset_channels();
+
+}
+
+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;
@@ -131,64 +173,184 @@
// 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.
+ if (pmt_eq(port_id, d_cs_usrp->port_symbol())) {
- if (pmt_eq(port_id, d_cs->port_symbol())){ // message came in on our
control/status port
+ if(pmt_eq(event, s_response_usrp_open)) {
+ // pass the response back over the regular CS port
+ invocation_handle = pmt_nth(0, data);
+ pmt_t status = pmt_nth(1, data);
+ d_cs->send(s_response_open, pmt_list2(invocation_handle, status));
- if (pmt_eq(event, s_cmd_open)){
- // extract args from data
+ if(pmt_eqv(status,PMT_T)) {
+ d_opened = true;
+ d_defer = false;
+ recall_defer_queue();
+ }
+
+ return;
+ }
+ else if (pmt_eq(event, s_response_usrp_close)) {
invocation_handle = pmt_nth(0, data);
- long which_usrp = pmt_to_long(pmt_nth(1, data)); // integer usrp id,
usually 0
+ pmt_t status = pmt_nth(1, data);
+ d_cs->send(s_response_close, pmt_list2(invocation_handle, status));
- // Do the right thing....
- // build a reply
+ if(pmt_eqv(status,PMT_T)) {
+ d_opened = false;
+ d_defer = false;
+ reset_channels();
+ recall_defer_queue();
+ }
+
+ return;
+ }
+ else if (pmt_eq(event, s_response_usrp_write)) {
+
+ invocation_handle = pmt_nth(0, data);
+ long channel = pmt_to_long(pmt_nth(1, data));
+ pmt_t status = pmt_nth(2, data);
- // if everything OK
- status = PMT_T;
- reply_data = pmt_list2(invocation_handle, status);
+ // Find the port through the owner of the channel
+ long port = tx_port_index(d_chaninfo_tx[channel].owner);
+ d_tx[port]->send(s_response_xmit_raw_frame, pmt_list2(invocation_handle,
status));
+ return;
+ }
- // ...and send it
- d_cs->send(s_response_open, reply_data);
+ goto unhandled;
+ }
+
+ // Checking for defer on all other messages
+ if(d_defer) {
+ std::cout << "[USRP_SERVER] Received msg while deferring (" <<
msg->signal() << ")\n";
+ d_defer_queue.push(msg);
+ return;
+ }
+
+ if (pmt_eq(port_id, d_cs->port_symbol())){ // message came in on our
control/status port
+
+ if (pmt_eq(event, s_cmd_open)){
+
+ // Reject if already open
+ if(d_opened) {
+ invocation_handle = pmt_nth(0, data);
+ d_cs->send(s_response_open, pmt_list2(invocation_handle, PMT_F));
+ 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;
}
else if (pmt_eq(event, s_cmd_close)){
- // ...
+ invocation_handle = pmt_nth(0, data);
+ if(!d_opened) {
+ d_cs->send(s_response_close, pmt_list2(invocation_handle, PMT_F));
+ return;
+ }
+
+ d_defer = true;
+ d_cs_usrp->send(s_cmd_usrp_close, pmt_list1(invocation_handle));
+
+ return;
}
else if (pmt_eq(event, s_cmd_max_capacity)) {
invocation_handle = pmt_nth(0, data);
- reply_data = pmt_list2(invocation_handle, pmt_from_long(max_capacity()));
+ if(!d_opened) {
+ d_cs->send(s_response_max_capacity, pmt_list3(invocation_handle,
PMT_F, pmt_from_long(0)));
+ return;
+ }
+ reply_data = pmt_list3(invocation_handle, PMT_T,
pmt_from_long(max_capacity()));
d_cs->send(s_response_max_capacity, reply_data);
return;
}
else if (pmt_eq(event, s_cmd_ntx_chan)) {
invocation_handle = pmt_nth(0, data);
- reply_data = pmt_list2(invocation_handle, pmt_from_long(d_ntx_chan));
+ if(!d_opened) {
+ d_cs->send(s_response_ntx_chan, pmt_list3(invocation_handle, PMT_F,
pmt_from_long(0)));
+ return;
+ }
+ reply_data = pmt_list3(invocation_handle, PMT_T,
pmt_from_long(d_ntx_chan));
d_cs->send(s_response_ntx_chan, reply_data);
+ return;
}
else if (pmt_eq(event, s_cmd_nrx_chan)) {
invocation_handle = pmt_nth(0, data);
- reply_data = pmt_list2(invocation_handle, pmt_from_long(d_nrx_chan));
+ if(!d_opened) {
+ d_cs->send(s_response_nrx_chan, pmt_list3(invocation_handle, PMT_F,
pmt_from_long(0)));
+ return;
+ }
+ reply_data = pmt_list3(invocation_handle, PMT_T,
pmt_from_long(d_nrx_chan));
d_cs->send(s_response_nrx_chan, reply_data);
+ return;
}
else if (pmt_eq(event, s_cmd_current_capacity_allocation)) {
invocation_handle = pmt_nth(0, data);
- reply_data = pmt_list2(invocation_handle,
pmt_from_long(current_capacity_allocation()));
+ if(!d_opened) {
+ d_cs->send(s_response_current_capacity_allocation,
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+ return;
+ }
+ reply_data = pmt_list3(invocation_handle, PMT_T,
pmt_from_long(current_capacity_allocation()));
d_cs->send(s_response_current_capacity_allocation, reply_data);
+ return;
}
goto unhandled;
}
+
if (pmt_eq(event, s_cmd_allocate_channel)){
+ if(!d_opened) { // check the USRP was opened
+ pmt_t invocation_handle = pmt_nth(0, data);
+
+ long port;
+ if((port = tx_port_index(port_id)) != -1) {
+ d_tx[port]->send(s_response_allocate_channel,
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+ } else {
+ port = rx_port_index(port_id);
+ d_rx[port]->send(s_response_allocate_channel,
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+ }
+ return;
+ }
+
handle_cmd_allocate_channel(port_id, data);
return;
}
if (pmt_eq(event, s_cmd_deallocate_channel)) {
+ if(!d_opened) { // check the USRP was opened
+ pmt_t invocation_handle = pmt_nth(0, data);
+
+ long port;
+ if((port = tx_port_index(port_id)) != -1) {
+ d_tx[port]->send(s_response_allocate_channel,
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+ } else {
+ port = rx_port_index(port_id);
+ d_rx[port]->send(s_response_allocate_channel,
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+ }
+ return;
+ }
+
handle_cmd_deallocate_channel(port_id, data);
return;
}
if (pmt_eq(event, s_cmd_xmit_raw_frame)){
- handle_cmd_xmit_raw_frame(data);
+ if(!d_opened) { // check the USRP was opened
+ pmt_t invocation_handle = pmt_nth(0, data);
+ long port = tx_port_index(port_id);
+ d_tx[port]->send(s_response_xmit_raw_frame, pmt_list2(invocation_handle,
PMT_F));
+ return;
+ }
+ handle_cmd_xmit_raw_frame(port_id, data);
return;
}
@@ -351,44 +513,84 @@
}
-void usrp_server::handle_cmd_xmit_raw_frame(pmt_t data) {
+void usrp_server::handle_cmd_xmit_raw_frame(pmt_t port_id, pmt_t data) {
size_t n_bytes, psize;
long max_payload_len = transport_pkt::max_payload();
+ pmt_t reply_data;
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));
+
+ long port;
- // 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);
+ // Check that the channel number is valid, and that the caller is the owner
+ // of the channel to send the frame
+ if((port = tx_port_index(port_id)) != -1) {
+
+ if(channel >= d_ntx_chan) {
+ reply_data = pmt_list2(invocation_handle,
pmt_from_long(CHANNEL_INVALID)); // not a legit channel number
+ d_tx[port]->send(s_response_xmit_raw_frame, reply_data);
+ return;
+ }
- transport_pkt *pkts =
- (transport_pkt *) pmt_u8vector_writeable_elements(v_packets, psize);
+ if(d_chaninfo_tx[channel].owner != port_id) {
+ reply_data = pmt_list2(invocation_handle,
pmt_from_long(PERMISSION_DENIED)); // not the owner of the port
+ d_tx[port]->send(s_response_xmit_raw_frame, reply_data);
+ return;
+ }
- for(int n=0; n < n_packets; n++) {
+ // 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);
- 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
- 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);
+ transport_pkt *pkts =
+ (transport_pkt *) pmt_u8vector_writeable_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
+ 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);
}
- 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
+
+ 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
+ d_cs_usrp->send(s_cmd_usrp_write, pmt_list4(invocation_handle,
pmt_from_long(channel), v_packets,
pmt_from_long(n_packets*transport_pkt::max_pkt_size())));
+
}
+}
- pkts[n_packets-1].set_end_of_burst(); // set the last packet's end of burst
+void
+usrp_server::recall_defer_queue()
+{
- // interface with the USRP to send the USB packet, since the memory is
- // contiguous, this should be a serious of memory copies to the bus, each
being
- // USB_PKT_SIZE * MAX_PACKET_BURST bytes worth of data (given a full burst)
+ 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;
}
REGISTER_MBLOCK_CLASS(usrp_server);
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h
2007-06-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h
2007-06-02 23:41:17 UTC (rev 5612)
@@ -23,14 +23,14 @@
#include <mb_mblock.h>
#include <vector>
+#include <queue>
/*!
- * \brief Implements the lowest-level mblock interface to the USRP
+ * \brief Implements the lowest-level mblock usb_interface to the USRP
*/
class usrp_server : public mb_mblock
{
public:
-
enum error_codes {
RQSTD_CAPACITY_UNAVAIL = 0,
CHANNEL_UNAVAIL = 1,
@@ -46,6 +46,7 @@
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;
@@ -60,6 +61,11 @@
struct channel_info d_chaninfo_tx[D_MAX_CHANNELS];
struct channel_info d_chaninfo_rx[D_MAX_CHANNELS];
+ std::queue<mb_message_sptr> d_defer_queue;
+
+ bool d_defer;
+ bool d_opened;
+
public:
usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t
user_arg);
~usrp_server();
@@ -73,10 +79,12 @@
private:
void handle_cmd_allocate_channel(pmt_t port_id, pmt_t data);
void handle_cmd_deallocate_channel(pmt_t port_id, pmt_t data);
- void handle_cmd_xmit_raw_frame(pmt_t data);
+ void handle_cmd_xmit_raw_frame(pmt_t port_id, 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();
};
#endif /* INCLUDED_USRP_SERVER_H */
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.mbh
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.mbh
2007-06-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.mbh
2007-06-02 23:41:17 UTC (rev 5612)
@@ -248,9 +248,9 @@
(:incoming
(response-open invocation-handle status)
(response-close invocation-handle status)
- (response-max-capacity invocation-handle capacity)
- (response-ntx-chan invocation-handle ntx-chan)
- (response-nrx-chan invocation-handle nrx-chan)
- (response-current-capacity-allocation invocation-handle capacity)
+ (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)
)
)
Copied:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface.cc)
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
(rev 0)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,224 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <iostream>
+#include <vector>
+#include <usb.h>
+#include <mb_class_registry.h>
+#include <usrp_usb_interface.h>
+#include <usrp_inband_usb_packet.h>
+#include "usrp_standard.h"
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+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_write = pmt_intern("cmd-usrp-write");
+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_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_open = pmt_intern("response-usrp-open");
+static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close");
+static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write");
+
+// need to take number of TX and RX channels as parameter
+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_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL);
+
+ // FIX ME: the code should query the FPGA to retrieve the number of channels
and such
+ d_ntx_chan = 2;
+ d_nrx_chan = 2;
+
+ d_utx = NULL;
+ d_urx = NULL;
+}
+
+usrp_usb_interface::~usrp_usb_interface()
+{
+
+}
+
+void
+usrp_usb_interface::initial_transition()
+{
+
+}
+
+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;
+
+ // message came in on our control/status port
+ if (pmt_eq(port_id, d_cs->port_symbol())) {
+
+ if (pmt_eq(event, s_cmd_usrp_open)){
+ handle_cmd_open(data);
+ return;
+ }
+ else if (pmt_eq(event, s_cmd_usrp_close)) {
+ handle_cmd_close(data);
+ return;
+ }
+ 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;
+ }
+ 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;
+ }
+ else if(pmt_eq(event, s_cmd_usrp_write)) {
+ handle_cmd_write(data);
+ return;
+ }
+ goto unhandled;
+ }
+
+ unhandled:
+ std::cout << "[usrp_usb_interface] unhandled msg: " << msg << std::endl;
+}
+
+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;
+
+ 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,
+ 16, // interp = 32.0MB/s
+ d_ntx_chan,
+ -1, // mux
+ 4096, // USB block size
+ 16); // number of blocks for async transfers
+
+ if(d_utx==0) {
+ 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;
+ }
+
+ if(!d_utx->set_tx_freq (0,0)) { // try setting center freq to 0
+ std::cout << "[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();
+
+ std::cout << "[USRP_USB_INTERFACE] Setup TX channel\n";
+
+ d_urx = usrp_standard_rx::make (which_usrp,
+ 16, // interp = 32.0MB/s
+ d_nrx_chan,
+ -1, // mux
+ 0, // set blank mode to start
+ 4096, // USB block size
+ 16); // number of blocks for async transfers
+
+ if(!d_urx) {
+ 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;
+ }
+
+ if(!d_urx->set_rx_freq (0,0)) { // try setting center freq to 0
+ std::cout << "[usrp_server] 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;
+ }
+
+ d_urx->start(); // FIXME: currently causing a hang
+
+ std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
+
+ d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
+}
+
+void
+usrp_usb_interface::handle_cmd_write(pmt_t data)
+{
+ pmt_t invocation_handle = pmt_nth(0, data);
+ long channel = pmt_to_long(pmt_nth(1, data));
+ pmt_t v_packets = pmt_nth(2, data);
+ long n_bytes = pmt_to_long(pmt_nth(3, data));
+
+ size_t psize;
+ bool underrun; // this will need to go, as it is taken care of in the
packet headers
+
+ transport_pkt *pkts = (transport_pkt *)
pmt_u8vector_writeable_elements(v_packets, psize);
+
+ int ret = d_utx->write (pkts, n_bytes, &underrun);
+
+ if (ret == n_bytes) {
+ 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_write, pmt_list3(invocation_handle,
pmt_from_long(channel), PMT_T));
+ }
+ else {
+ std::cout << "[usrp_server] Error writing " << n_bytes << " bytes to USB
bus\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_write, pmt_list3(invocation_handle,
pmt_from_long(channel), PMT_F));
+ }
+
+ return;
+}
+
+void
+usrp_usb_interface::handle_cmd_close(pmt_t data)
+{
+ pmt_t invocation_handle = pmt_nth(0, data);
+
+ std::cout << "[usrp_usb_interface] Handling close request for USRP\n";
+
+ delete d_utx;
+
+ delete d_urx;
+
+ d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
+
+ shutdown_all(PMT_T);
+}
+
+
+REGISTER_MBLOCK_CLASS(usrp_usb_interface);
Copied:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface.h)
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h
(rev 0)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_USRP_USB_INTERFACE_H
+#define INCLUDED_USRP_USB_INTERFACE_H
+
+#include <mb_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* d_utx;
+ usrp_standard_rx* d_urx;
+
+ mb_port_sptr d_cs;
+
+ long d_ntx_chan;
+ long d_nrx_chan;
+
+ 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);
+
+ private:
+ void handle_cmd_open(pmt_t data);
+ void handle_cmd_close(pmt_t data);
+ void handle_cmd_write(pmt_t data);
+
+};
+
+
+#endif /* INCLUDED_USRP_USB_INTERFACE_H */
Copied:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface_stub.cc)
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
(rev 0)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,152 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <iostream>
+#include <vector>
+#include <usb.h>
+#include <mb_class_registry.h>
+#include <usrp_usb_interface_stub.h>
+#include <usrp_inband_usb_packet.h>
+#include "usrp_standard.h"
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+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_write = pmt_intern("cmd-usrp-write");
+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_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_open = pmt_intern("response-usrp-open");
+static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close");
+static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write");
+
+// need to take number of TX and RX channels as parameter
+usrp_usb_interface_stub::usrp_usb_interface_stub(mb_runtime *rt, const
std::string &instance_name, pmt_t user_arg)
+ : mb_mblock(rt, instance_name, user_arg)
+{
+ d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL);
+
+ // FIX ME: the code should query the FPGA to retrieve the number of channels
and such
+ d_ntx_chan = 2;
+ d_nrx_chan = 2;
+
+ d_utx = NULL;
+ d_urx = NULL;
+}
+
+usrp_usb_interface_stub::~usrp_usb_interface_stub()
+{
+
+}
+
+void
+usrp_usb_interface_stub::initial_transition()
+{
+
+}
+
+void
+usrp_usb_interface_stub::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;
+
+ // message came in on our control/status port
+ if (pmt_eq(port_id, d_cs->port_symbol())) {
+
+ if (pmt_eq(event, s_cmd_usrp_open)){
+ handle_cmd_open(data);
+ return;
+ }
+ else if (pmt_eq(event, s_cmd_usrp_close)) {
+ handle_cmd_close(data);
+ return;
+ }
+ 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;
+ }
+ 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;
+ }
+ else if(pmt_eq(event, s_cmd_usrp_write)) {
+ handle_cmd_write(data);
+ return;
+ }
+ goto unhandled;
+ }
+
+ unhandled:
+ std::cout << "[USRP_USB_INTERFACE_STUB] unhandled msg: " << msg << std::endl;
+}
+
+void
+usrp_usb_interface_stub::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 rx_mode = pmt_nth(2, data);
+ pmt_t reply_data;
+
+ std::cout << "[USRP_USB_INTERFACE_STUB] Handling open request for USRP " <<
which_usrp << "\n";
+
+ usleep(2 * 1000000); // artificial time to open the interface
+
+ d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
+}
+
+void
+usrp_usb_interface_stub::handle_cmd_write(pmt_t data)
+{
+ pmt_t invocation_handle = pmt_nth(0, data);
+ pmt_t channel = pmt_nth(1, data);
+
+ d_cs->send(s_response_usrp_write, pmt_list3(invocation_handle, channel,
PMT_T));
+
+ std::cout << "[USRP_USB_INTERFACE_STUB] Successful write\n";
+
+ return;
+}
+
+void
+usrp_usb_interface_stub::handle_cmd_close(pmt_t data)
+{
+ pmt_t invocation_handle = pmt_nth(0, data);
+
+ std::cout << "[USRP_USB_INTERFACE_STUB] Handling close request for USRP\n";
+
+ d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
+
+ return;
+}
+
+
+REGISTER_MBLOCK_CLASS(usrp_usb_interface_stub);
Copied:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
(from rev 5611,
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface_stub.h)
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
(rev 0)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_USRP_USB_INTERFACE_STUB_H
+#define INCLUDED_USRP_USB_INTERFACE_STUB_H
+
+#include <mb_mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_usb_interface_stub : public mb_mblock
+{
+ public:
+
+ usrp_standard_tx* d_utx;
+ usrp_standard_rx* d_urx;
+
+ mb_port_sptr d_cs;
+
+ long d_ntx_chan;
+ long d_nrx_chan;
+
+ public:
+ usrp_usb_interface_stub(mb_runtime *rt, const std::string &instance_name,
pmt_t user_arg);
+ ~usrp_usb_interface_stub();
+ void initial_transition();
+ void handle_message(mb_message_sptr msg);
+
+ private:
+ void handle_cmd_open(pmt_t data);
+ void handle_cmd_close(pmt_t data);
+ void handle_cmd_write(pmt_t data);
+
+};
+
+
+#endif /* INCLUDED_USRP_USB_INTERFACE_STUB_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r5612 - gnuradio/branches/features/inband-usb/usrp/host/lib/inband,
gnychis <=