[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r6728 - gnuradio/branches/features/inband-usb/usrp/hos
From: |
gnychis |
Subject: |
[Commit-gnuradio] r6728 - gnuradio/branches/features/inband-usb/usrp/host/lib/inband |
Date: |
Sun, 28 Oct 2007 19:19:40 -0600 (MDT) |
Author: gnychis
Date: 2007-10-28 19:19:39 -0600 (Sun, 28 Oct 2007)
New Revision: 6728
Removed:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.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/usrp_inband_usb_packet.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
Log:
Merging -r6706:6727 from 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-10-29 00:44:18 UTC (rev 6727)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
2007-10-29 01:19:39 UTC (rev 6728)
@@ -78,7 +78,6 @@
usrp_usb_interface.h
noinst_HEADERS = \
- fake_usrp.h \
qa_inband.h \
qa_inband_packet_prims.h \
qa_inband_usrp_server.h \
Deleted: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc
Deleted: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/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-10-29 00:44:18 UTC (rev 6727)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
2007-10-29 01:19:39 UTC (rev 6728)
@@ -46,6 +46,8 @@
static bool verbose = false;
+static pmt_t s_timeout = pmt_intern("%timeout");
+
//
----------------------------------------------------------------------------------------------
class qa_alloc_top : public mb_mblock
@@ -903,10 +905,10 @@
long d_rx_chan;
- long d_got_response_recv;
+ bool d_got_response_recv;
- long d_nmsg_to_recv;
- long d_nmsg_recvd;
+ mb_time d_t0;
+ double d_delta_t;
public:
qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t
user_arg);
@@ -927,18 +929,19 @@
d_got_response_recv(false)
{
- d_nmsg_to_recv=12;
- d_nmsg_recvd=0;
-
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_server_dict = pmt_make_dict();
- pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"), PMT_T);
+ 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_server_dict);
+ define_component("server", "usrp_server", usrp_dict);
connect("self", "rx0", "server", "rx0");
connect("self", "cs", "server", "cs");
}
@@ -967,17 +970,10 @@
pmt_list2(PMT_NIL,
pmt_from_long(0)));
- // A small sleep is used to ensure, if working properly, a recv
- // response comes through successfully before the close gets
- // through
- usleep(1000);
-
- 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)));
-
+ // 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);
}
@@ -992,26 +988,37 @@
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(pmt_eqv(status, PMT_T)) {
+
if(verbose)
- std::cout << "Got: " << status << " Expected: " << PMT_T << "\n";
- shutdown_all(PMT_F);
- return;
- }
- else {
- if(verbose)
std::cout << "[qa_rx_top] Received expected response for message "
- << d_nmsg_recvd
<< " (" << 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;
}
@@ -1026,8 +1033,7 @@
} else {
if(verbose)
std::cout << "[qa_rx_top] Received expected response for message "
- << d_nmsg_recvd
- << " (" << event << ")\n";
+ << " (" << event << ")\n";
}
if (pmt_eq(msg->port_id(), d_rx->port_symbol())) {
@@ -1051,12 +1057,7 @@
std::cout << "[qa_rx_top] No response message before close\n";
return;
}
-
}
-
-
- d_nmsg_recvd++;
-
}
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.cc
===================================================================
---
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.cc
2007-10-29 00:44:18 UTC (rev 6727)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.cc
2007-10-29 01:19:39 UTC (rev 6728)
@@ -29,6 +29,14 @@
#include <iostream>
#include <stdio.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();
@@ -43,18 +51,20 @@
if((MAX_PAYLOAD - p_len) < bytes_needed)
return false;
- p_len += bytes_needed;
+ incr_header_len(bytes_needed);
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = p_len;
-
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
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())
@@ -82,7 +92,15 @@
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())
@@ -110,6 +128,15 @@
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())
@@ -143,6 +170,14 @@
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())
@@ -179,6 +214,14 @@
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())
@@ -206,6 +249,17 @@
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())
@@ -237,6 +291,14 @@
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())
@@ -263,6 +325,11 @@
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())
@@ -297,6 +364,15 @@
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())
@@ -331,6 +407,15 @@
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())
@@ -365,6 +450,11 @@
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())
@@ -408,6 +498,11 @@
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())
@@ -457,6 +552,12 @@
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())
@@ -490,20 +591,27 @@
return true;
}
-// Takes an offset to the beginning of a subpacket and extracts the
-// length of the subpacket
+/*!
+ * \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;
}
-// The following method takes an offset within the packet payload to extract
-// a control/status subpacket and construct 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.
+/*!
+ * \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)));
Modified: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc
2007-10-29 00:44:18 UTC (rev 6727)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc
2007-10-29 01:19:39 UTC (rev 6728)
@@ -73,6 +73,12 @@
}
+/*!
+ * \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)
{
@@ -89,6 +95,17 @@
}
}
+/*!
+ * \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)
{
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc
2007-10-29 00:44:18 UTC (rev 6727)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc
2007-10-29 01:19:39 UTC (rev 6728)
@@ -40,7 +40,7 @@
typedef usrp_inband_usb_packet transport_pkt;
-static const bool verbose = true;
+static const bool verbose = false;
bool usrp_rx_stop_stub;
@@ -96,7 +96,6 @@
void
usrp_rx_stub::initial_transition()
{
-
}
void
@@ -106,96 +105,122 @@
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())) {
+ 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;
- if(pmt_eqv(event, s_cmd_usrp_rx_start_reading))
- read_and_respond(data);
+ start_packet_timer();
}
}
+// Setup a periodic timer which will drive packet generation
void
-usrp_rx_stub::read_and_respond(pmt_t data)
+usrp_rx_stub::start_packet_timer()
{
+ d_t0 = mb_time::time(); // current time
- while(!usrp_rx_stop_stub) {
+ // 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;
- long nsamples_this_frame = d_samples_per_frame;
+ 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;
+ }
- 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_writeable_elements(uvec, ignore);
+ schedule_periodic_timeout(d_t0 + frame_rate, mb_time(frame_rate), PMT_T);
+}
- // fill in the complex sinusoid
+void
+usrp_rx_stub::read_and_respond()
+{
- for (int i = 0; i < nsamples_this_frame; i++){
+ long nsamples_this_frame = d_samples_per_frame;
- 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);
+ 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_writeable_elements(uvec, ignore);
- // write 16-bit i & q
- samples[2*i] = (int16_t) s.real();
- samples[2*i+1] = (int16_t) s.imag();
- }
+ // 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();
}
-
- if(d_disk_write)
- d_ofile.write((const char *)samples, n_bytes);
+ 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();
+ }
+ }
- pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
- transport_pkt *pkt =
- (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
+ if(d_disk_write)
+ d_ofile.write((const char *)samples, n_bytes);
- 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));
+ pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
+ transport_pkt *pkt =
+ (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
- // 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();
+ 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));
- pmt_t invocation_handle = pmt_nth(0, cs_pkt);
- pmt_t v_pkt = pmt_nth(1, cs_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();
- d_cs->send(s_response_usrp_rx_read,
- pmt_list3(invocation_handle,
- PMT_T,
- v_pkt)); // Take the front CS pkt
+ pmt_t invocation_handle = pmt_nth(0, cs_pkt);
+ pmt_t v_pkt = pmt_nth(1, cs_pkt);
-
- if(verbose)
- std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n";
- }
+ 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";
}
-
- usrp_rx_stop_stub = false;
- if(verbose)
- std::cout << "[USRP_RX_STUB] Got fake RX stop\n";
-
}
REGISTER_MBLOCK_CLASS(usrp_rx_stub);
Modified:
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h
2007-10-29 00:44:18 UTC (rev 6727)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h
2007-10-29 01:19:39 UTC (rev 6728)
@@ -34,6 +34,9 @@
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
*/
@@ -46,6 +49,9 @@
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;
@@ -62,8 +68,9 @@
void handle_message(mb_message_sptr msg);
private:
- void read_and_respond(pmt_t data);
+ void read_and_respond();
void read_data();
+ void start_packet_timer();
};
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-10-29 00:44:18 UTC (rev 6727)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
2007-10-29 01:19:39 UTC (rev 6728)
@@ -41,7 +41,7 @@
typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit
easy
-const static bool verbose = true;
+const static bool verbose = false;
static std::string
str(long x)
@@ -137,6 +137,10 @@
//d_fake_rx=true;
}
+/*!
+ * \brief resets the assigned capacity and owners of each RX and TX channel
from
+ * allocations.
+ */
void
usrp_server::reset_channels()
{
@@ -165,6 +169,11 @@
// 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)
{
@@ -502,7 +511,14 @@
std::cout << "[USRP_SERVER] unhandled msg: " << msg << std::endl;
}
-// Return -1 if it is not an RX port, or an index
+/*!
+ * \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++)
@@ -512,7 +528,14 @@
return -1;
}
-// Return -1 if it is not an RX port, or an index
+/*!
+ * \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++)
@@ -522,8 +545,12 @@
return -1;
}
-// Go through all TX and RX channels, sum up the assigned capacity
-// and return it
+/*!
+ * \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;
@@ -536,6 +563,14 @@
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,
@@ -596,9 +631,13 @@
return;
}
-// Check the port type and deallocate assigned capacity based on this, ensuring
-// that the owner of the method invocation is the owner of the port and that
the
-// channel number is valid.
+/*!
+ * \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,
@@ -623,8 +662,26 @@
return;
}
-void usrp_server::handle_cmd_xmit_raw_frame(mb_port_sptr port,
std::vector<struct channel_info> &chan_info, pmt_t data) {
-
+/*!
+ * \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();
@@ -699,7 +756,8 @@
<< invocation_handle << std::endl;
// The actual response to the write will be generated by a
- // s_response_usrp_write
+ // 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),
@@ -708,7 +766,29 @@
return;
}
-void usrp_server::handle_cmd_to_control_channel(mb_port_sptr port,
std::vector<struct channel_info> &chan_info, pmt_t data)
+/*!
+ * \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);
@@ -1022,8 +1102,22 @@
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)
+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));
@@ -1064,6 +1158,18 @@
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,
@@ -1099,7 +1205,22 @@
return;
}
-// Read the packet header, determine the port by the channel owner
+/*!
+ * \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)
{
@@ -1177,6 +1298,19 @@
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)
{
@@ -1222,6 +1356,9 @@
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)
@@ -1257,6 +1394,9 @@
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)
@@ -1293,6 +1433,9 @@
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,
@@ -1326,6 +1469,9 @@
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,
@@ -1349,6 +1495,10 @@
}
}
+/*!
+ * \brief Used to recall all incoming signals that were deferred when USRP
+ * server was in the initialization state.
+ */
void
usrp_server::recall_defer_queue()
{
@@ -1367,6 +1517,25 @@
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,
@@ -1409,8 +1578,12 @@
return true;
}
-// Goes through the vector of RIDs and retreieves an
-// available one for use
+/*!
+ * \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()
{
@@ -1418,14 +1591,16 @@
if(pmt_eqv(d_rids[i].owner, PMT_NIL))
return i;
+ if(verbose)
+ std::cout << "[USRP_SERVER] No RIDs left\n";
return -1;
}
-// Need to initialize several registers according to the specified settings of
-// the user
-//
-// FIXME: I believe this is specific to the basic daughterboards, this would
-// need to change when daughterboard support is added
+/*!
+ * \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()
{
@@ -1513,6 +1688,13 @@
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();
}
@@ -1601,6 +1783,10 @@
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()
{
@@ -1608,15 +1794,13 @@
set_register(i, 0);
}
-// THIS IS ONLY FOR INTERNAL USRP_SERVER USAGE
-//
-// This function needs to create its own USB packet and not use
-// handle_cmd_to_control_channel because in many cases such as initialization,
-// the number of register writes needed are more than the number of RID's. If
-// there are no RID's left for use then handle_cmd_to_control_channel() will
-// throw away the request. This allows usrp_server to generate its own
register
-// writes without eating up RID's, since usrp_server does not really care about
-// the response.
+/*!
+ * \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)
{
@@ -1637,16 +1821,34 @@
v_packet));
}
-// Only for internal usrp_server usage. Structed the same way as
-// set_register().
+/*!
+ * \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)
{
- handle_cmd_to_control_channel(d_tx[0], d_chaninfo_tx,
- pmt_list2(PMT_NIL, // empty invoc handle
- pmt_list1(pmt_list2(s_op_read_reg,
- pmt_list2(pmt_from_long(0),
- pmt_from_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_writeable_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);
Modified: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc
2007-10-29 00:44:18 UTC (rev 6727)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc
2007-10-29 01:19:39 UTC (rev 6728)
@@ -66,6 +66,10 @@
}
+/*!
+ * \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)
{
@@ -82,6 +86,14 @@
}
}
+/*!
+ * \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)
{
Modified:
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.cc
2007-10-29 00:44:18 UTC (rev 6727)
+++
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
2007-10-29 01:19:39 UTC (rev 6728)
@@ -47,8 +47,12 @@
static const bool verbose = false;
-
-// need to take number of TX and RX channels as parameter
+/*!
+ * \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),
@@ -159,6 +163,10 @@
}
+/*!
+ * \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)
{
@@ -254,6 +262,13 @@
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)
{
@@ -339,6 +354,14 @@
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)
{
@@ -357,6 +380,13 @@
return;
}
+/*!
+ * \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)
{
@@ -377,6 +407,13 @@
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)
{
@@ -386,6 +423,10 @@
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();
}
@@ -400,6 +441,13 @@
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)
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r6728 - gnuradio/branches/features/inband-usb/usrp/host/lib/inband,
gnychis <=