[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r8295 - in gnuradio/trunk: mblock/src/lib pmt/src/lib
From: |
eb |
Subject: |
[Commit-gnuradio] r8295 - in gnuradio/trunk: mblock/src/lib pmt/src/lib usrp/fpga usrp/fpga/inband_lib usrp/fpga/megacells usrp/fpga/rbf usrp/fpga/rbf/rev2 usrp/fpga/rbf/rev4 usrp/fpga/toplevel/usrp_inband_usb usrp/host/apps-inband usrp/host/lib/inband usrp/host/lib/legacy |
Date: |
Tue, 29 Apr 2008 21:52:32 -0600 (MDT) |
Author: eb
Date: 2008-04-29 21:52:31 -0600 (Tue, 29 Apr 2008)
New Revision: 8295
Added:
gnuradio/trunk/usrp/fpga/rbf/rev2/inband_1rxhb_1tx.rbf
gnuradio/trunk/usrp/fpga/rbf/rev2/inband_2rxhb_2tx.rbf
gnuradio/trunk/usrp/fpga/rbf/rev4/inband_1rxhb_1tx.rbf
gnuradio/trunk/usrp/fpga/rbf/rev4/inband_2rxhb_2tx.rbf
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2rx.cc
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2tx.cc
Removed:
gnuradio/trunk/usrp/fpga/inband_lib/data_packet_fifo.v
gnuradio/trunk/usrp/fpga/inband_lib/usb_fifo_reader.v
gnuradio/trunk/usrp/fpga/inband_lib/usb_fifo_writer.v
gnuradio/trunk/usrp/host/apps-inband/gmac.cc
gnuradio/trunk/usrp/host/apps-inband/gmac.h
gnuradio/trunk/usrp/host/apps-inband/gmac.mbh
gnuradio/trunk/usrp/host/apps-inband/gmac_symbols.h
gnuradio/trunk/usrp/host/apps-inband/test_gmac_tx.cc
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_cs.cc
gnuradio/trunk/usrp/host/lib/inband/fake_usrp.cc
gnuradio/trunk/usrp/host/lib/inband/fake_usrp.h
gnuradio/trunk/usrp/host/lib/inband/test_usrp_inband.cc
Modified:
gnuradio/trunk/mblock/src/lib/mb_message.cc
gnuradio/trunk/pmt/src/lib/pmt.cc
gnuradio/trunk/pmt/src/lib/pmt.h
gnuradio/trunk/pmt/src/lib/pmt_pool.cc
gnuradio/trunk/pmt/src/lib/pmt_pool.h
gnuradio/trunk/pmt/src/lib/qa_pmt_prims.cc
gnuradio/trunk/pmt/src/lib/qa_pmt_prims.h
gnuradio/trunk/usrp/fpga/Makefile.extra
gnuradio/trunk/usrp/fpga/inband_lib/chan_fifo_reader.v
gnuradio/trunk/usrp/fpga/inband_lib/channel_demux.v
gnuradio/trunk/usrp/fpga/inband_lib/channel_ram.v
gnuradio/trunk/usrp/fpga/inband_lib/cmd_reader.v
gnuradio/trunk/usrp/fpga/inband_lib/packet_builder.v
gnuradio/trunk/usrp/fpga/inband_lib/register_io.v
gnuradio/trunk/usrp/fpga/inband_lib/rx_buffer_inband.v
gnuradio/trunk/usrp/fpga/inband_lib/tx_buffer_inband.v
gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.bsf
gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.v
gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16_bb.v
gnuradio/trunk/usrp/fpga/rbf/Makefile.am
gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/config.vh
gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.qsf
gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.v
gnuradio/trunk/usrp/host/apps-inband/
gnuradio/trunk/usrp/host/apps-inband/Makefile.am
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_overrun.cc
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_registers.cc
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_rx.cc
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_timestamps.cc
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_tx.cc
gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_underrun.cc
gnuradio/trunk/usrp/host/lib/inband/Makefile.am
gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.cc
gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.h
gnuradio/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.cc
gnuradio/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.h
gnuradio/trunk/usrp/host/lib/inband/usrp_rx.cc
gnuradio/trunk/usrp/host/lib/inband/usrp_rx.h
gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.cc
gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.h
gnuradio/trunk/usrp/host/lib/inband/usrp_server.cc
gnuradio/trunk/usrp/host/lib/inband/usrp_server.h
gnuradio/trunk/usrp/host/lib/inband/usrp_server.mbh
gnuradio/trunk/usrp/host/lib/inband/usrp_tx.cc
gnuradio/trunk/usrp/host/lib/inband/usrp_tx_stub.cc
gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.cc
gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.h
gnuradio/trunk/usrp/host/lib/legacy/fusb_linux.cc
Log:
Merged features/inband-usb -r6431:8293 into trunk.
Modified: gnuradio/trunk/mblock/src/lib/mb_message.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_message.cc 2008-04-30 03:50:36 UTC (rev
8294)
+++ gnuradio/trunk/mblock/src/lib/mb_message.cc 2008-04-30 03:52:31 UTC (rev
8295)
@@ -26,12 +26,13 @@
#include <stdio.h>
#include <pmt_pool.h>
-static const int CACHE_LINE_SIZE = 64; // good guess
-
-
+static const int CACHE_LINE_SIZE = 64; // good guess
+static const int MAX_MESSAGES = 1024; // KLUDGE max number of messages in sys
+ // 0 -> no limit
#if MB_MESSAGE_LOCAL_ALLOCATOR
-static pmt_pool global_msg_pool(sizeof(mb_message), CACHE_LINE_SIZE);
+static pmt_pool
+global_msg_pool(sizeof(mb_message), CACHE_LINE_SIZE, 16*1024, MAX_MESSAGES);
void *
mb_message::operator new(size_t size)
Modified: gnuradio/trunk/pmt/src/lib/pmt.cc
===================================================================
--- gnuradio/trunk/pmt/src/lib/pmt.cc 2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/pmt/src/lib/pmt.cc 2008-04-30 03:52:31 UTC (rev 8295)
@@ -963,6 +963,12 @@
}
pmt_t
+pmt_list_add(pmt_t list, pmt_t item)
+{
+ return pmt_reverse(pmt_cons(item, pmt_reverse(list)));
+}
+
+pmt_t
pmt_caar(pmt_t pair)
{
return (pmt_car(pmt_car(pair)));
Modified: gnuradio/trunk/pmt/src/lib/pmt.h
===================================================================
--- gnuradio/trunk/pmt/src/lib/pmt.h 2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/pmt/src/lib/pmt.h 2008-04-30 03:52:31 UTC (rev 8295)
@@ -609,7 +609,12 @@
*/
pmt_t pmt_list6(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4, pmt_t x5, pmt_t x6);
+/*!
+ * \brief Return \p list with \p item added to it.
+ */
+pmt_t pmt_list_add(pmt_t list, pmt_t item);
+
/*
* ------------------------------------------------------------------------
* read / write
Modified: gnuradio/trunk/pmt/src/lib/pmt_pool.cc
===================================================================
--- gnuradio/trunk/pmt/src/lib/pmt_pool.cc 2008-04-30 03:50:36 UTC (rev
8294)
+++ gnuradio/trunk/pmt/src/lib/pmt_pool.cc 2008-04-30 03:52:31 UTC (rev
8295)
@@ -32,10 +32,13 @@
return ((((x) + (stride) - 1)/(stride)) * (stride));
}
-pmt_pool::pmt_pool(size_t itemsize, size_t alignment, size_t allocation_size)
- : d_itemsize(ROUNDUP(itemsize, alignment)),
+pmt_pool::pmt_pool(size_t itemsize, size_t alignment,
+ size_t allocation_size, size_t max_items)
+ : d_cond(&d_mutex),
+ d_itemsize(ROUNDUP(itemsize, alignment)),
d_alignment(alignment),
d_allocation_size(std::max(allocation_size, 16 * itemsize)),
+ d_max_items(max_items), d_n_items(0),
d_freelist(0)
{
}
@@ -53,9 +56,15 @@
omni_mutex_lock l(d_mutex);
item *p;
+ if (d_max_items != 0){
+ while (d_n_items >= d_max_items)
+ d_cond.wait();
+ }
+
if (d_freelist){ // got something?
p = d_freelist;
d_freelist = p->d_next;
+ d_n_items++;
return p;
}
@@ -79,6 +88,7 @@
// now return the first one
p = d_freelist;
d_freelist = p->d_next;
+ d_n_items++;
return p;
}
@@ -93,4 +103,7 @@
item *p = (item *) foo;
p->d_next = d_freelist;
d_freelist = p;
+ d_n_items--;
+ if (d_max_items != 0)
+ d_cond.signal();
}
Modified: gnuradio/trunk/pmt/src/lib/pmt_pool.h
===================================================================
--- gnuradio/trunk/pmt/src/lib/pmt_pool.h 2008-04-30 03:50:36 UTC (rev
8294)
+++ gnuradio/trunk/pmt/src/lib/pmt_pool.h 2008-04-30 03:52:31 UTC (rev
8295)
@@ -38,10 +38,13 @@
};
omni_mutex d_mutex;
+ omni_condition d_cond;
size_t d_itemsize;
size_t d_alignment;
size_t d_allocation_size;
+ size_t d_max_items;
+ size_t d_n_items;
item *d_freelist;
std::vector<char *> d_allocations;
@@ -50,8 +53,11 @@
* \param itemsize size in bytes of the items to be allocated.
* \param alignment alignment in bytes of all objects to be allocated (must
be power-of-2).
* \param allocation_size number of bytes to allocate at a time from the
underlying allocator.
+ * \param max_items is the maximum number of items to allocate. If this
number is exceeded,
+ * the allocate blocks. 0 implies no limit.
*/
- pmt_pool(size_t itemsize, size_t alignment = 16, size_t allocation_size =
4096);
+ pmt_pool(size_t itemsize, size_t alignment = 16,
+ size_t allocation_size = 4096, size_t max_items = 0);
~pmt_pool();
void *malloc();
Modified: gnuradio/trunk/pmt/src/lib/qa_pmt_prims.cc
===================================================================
--- gnuradio/trunk/pmt/src/lib/qa_pmt_prims.cc 2008-04-30 03:50:36 UTC (rev
8294)
+++ gnuradio/trunk/pmt/src/lib/qa_pmt_prims.cc 2008-04-30 03:52:31 UTC (rev
8295)
@@ -301,6 +301,20 @@
CPPUNIT_ASSERT_EQUAL(std::string("k0"), pmt_write_string(k0));
}
+void
+qa_pmt_prims::test_lists()
+{
+ pmt_t s0 = pmt_intern("s0");
+ pmt_t s1 = pmt_intern("s1");
+ pmt_t s2 = pmt_intern("s2");
+ pmt_t s3 = pmt_intern("s3");
+
+ pmt_t l1 = pmt_list4(s0, s1, s2, s3);
+ pmt_t l2 = pmt_list3(s0, s1, s2);
+ pmt_t l3 = pmt_list_add(l2, s3);
+ CPPUNIT_ASSERT(pmt_equal(l1, l3));
+}
+
// ------------------------------------------------------------------------
// class foo is used in test_any below.
Modified: gnuradio/trunk/pmt/src/lib/qa_pmt_prims.h
===================================================================
--- gnuradio/trunk/pmt/src/lib/qa_pmt_prims.h 2008-04-30 03:50:36 UTC (rev
8294)
+++ gnuradio/trunk/pmt/src/lib/qa_pmt_prims.h 2008-04-30 03:52:31 UTC (rev
8295)
@@ -40,6 +40,7 @@
CPPUNIT_TEST(test_dict);
CPPUNIT_TEST(test_any);
CPPUNIT_TEST(test_io);
+ CPPUNIT_TEST(test_lists);
CPPUNIT_TEST(test_serialize);
CPPUNIT_TEST_SUITE_END();
@@ -56,6 +57,7 @@
void test_dict();
void test_any();
void test_io();
+ void test_lists();
void test_serialize();
};
Modified: gnuradio/trunk/usrp/fpga/Makefile.extra
===================================================================
--- gnuradio/trunk/usrp/fpga/Makefile.extra 2008-04-30 03:50:36 UTC (rev
8294)
+++ gnuradio/trunk/usrp/fpga/Makefile.extra 2008-04-30 03:52:31 UTC (rev
8295)
@@ -4,14 +4,11 @@
inband_lib/channel_demux.v \
inband_lib/channel_ram.v \
inband_lib/cmd_reader.v \
- inband_lib/data_packet_fifo.v \
inband_lib/packet_builder.v \
inband_lib/register_io.v \
inband_lib/rx_buffer_inband.v \
inband_lib/tx_buffer_inband.v \
inband_lib/tx_packer.v \
- inband_lib/usb_fifo_reader.v \
- inband_lib/usb_fifo_writer.v \
inband_lib/usb_packet_fifo.v \
megacells/accum32.bsf \
megacells/accum32.cmp \
Modified: gnuradio/trunk/usrp/fpga/inband_lib/chan_fifo_reader.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/chan_fifo_reader.v 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/chan_fifo_reader.v 2008-04-30
03:52:31 UTC (rev 8295)
@@ -1,106 +1,102 @@
module chan_fifo_reader
- ( reset, tx_clock, tx_strobe, adc_time, samples_format,
+ (reset, tx_clock, tx_strobe, timestamp_clock, samples_format,
fifodata, pkt_waiting, rdreq, skip, tx_q, tx_i,
underrun, tx_empty, debug, rssi, threshhold, rssi_wait) ;
- input wire reset ;
- input wire tx_clock ;
- input wire tx_strobe ; //signal to output tx_i and
tx_q
- input wire [31:0] adc_time ; //current time
- input wire [3:0] samples_format ;// not useful at this
point
- input wire [31:0] fifodata ; //the data input
- input wire pkt_waiting ; //signal the next packet is
ready
- output reg rdreq ; //actually an ack to the current
fifodata
- output reg skip ; //finish reading current packet
- output reg [15:0] tx_q ; //top 16 bit output of fifodata
- output reg [15:0] tx_i ; //bottom 16 bit output of fifodata
- output reg underrun ;
- output reg tx_empty ; //cause 0 to be the output
- input wire [31:0] rssi;
- input wire [31:0] threshhold;
- input wire [31:0] rssi_wait;
+ input wire reset ;
+ input wire tx_clock ;
+ input wire tx_strobe ; //signal to output tx_i and
tx_q
+ input wire [31:0] timestamp_clock ; //current time
+ input wire [3:0] samples_format ;// not useful at this point
+ input wire [31:0] fifodata ; //the data input
+ input wire pkt_waiting ; //signal the next packet is
ready
+ output reg rdreq ; //actually an ack to the current
fifodata
+ output reg skip ; //finish reading current packet
+ output reg [15:0] tx_q ; //top 16 bit output of fifodata
+ output reg [15:0] tx_i ; //bottom 16 bit output of fifodata
+ output reg underrun ;
+ output reg tx_empty ; //cause 0 to be the output
+ input wire [31:0] rssi;
+ input wire [31:0] threshhold;
+ input wire [31:0] rssi_wait;
- output wire [14:0] debug;
- assign debug = {reader_state, trash, skip, timestamp[4:0],
adc_time[4:0]};
- // Should not be needed if adc clock rate < tx clock rate
- // Used only to debug
- `define JITTER 5
+ output wire [14:0] debug;
+ assign debug = {7'd0, rdreq, skip, reader_state, pkt_waiting, tx_strobe,
tx_clock};
+
+ //Samples format
+ // 16 bits interleaved complex samples
+ `define QI16 4'b0
- //Samples format
- // 16 bits interleaved complex samples
- `define QI16 4'b0
-
- // States
- parameter IDLE = 3'd0;
- parameter HEADER = 3'd1;
- parameter TIMESTAMP = 3'd2;
- parameter WAIT = 3'd3;
- parameter WAITSTROBE = 3'd4;
- parameter SEND = 3'd5;
+ // States
+ parameter IDLE = 3'd0;
+ parameter HEADER = 3'd1;
+ parameter TIMESTAMP = 3'd2;
+ parameter WAIT = 3'd3;
+ parameter WAITSTROBE = 3'd4;
+ parameter SEND = 3'd5;
- // Header format
- `define PAYLOAD 8:2
- `define ENDOFBURST 27
- `define STARTOFBURST 28
- `define RSSI_FLAG 26
+ // Header format
+ `define PAYLOAD 8:2
+ `define ENDOFBURST 27
+ `define STARTOFBURST 28
+ `define RSSI_FLAG 26
- /* State registers */
- reg [2:0] reader_state;
- /* Local registers */
- reg [6:0] payload_len;
- reg [6:0] read_len;
- reg [31:0] timestamp;
- reg burst;
- reg trash;
- reg
rssi_flag;
- reg [31:0] time_wait;
+ /* State registers */
+ reg [2:0] reader_state;
+ /* Local registers */
+ reg [6:0] payload_len;
+ reg [6:0] read_len;
+ reg [31:0] timestamp;
+ reg burst;
+ reg trash;
+ reg rssi_flag;
+ reg [31:0] time_wait;
- always @(posedge tx_clock)
- begin
- if (reset)
- begin
- reader_state <= IDLE;
- rdreq <= 0;
- skip <= 0;
- underrun <= 0;
- burst <= 0;
- tx_empty <= 1;
- tx_q <= 0;
- tx_i <= 0;
- trash <= 0;
- rssi_flag <= 0;
- time_wait <= 0;
+ always @(posedge tx_clock)
+ begin
+ if (reset)
+ begin
+ reader_state <= IDLE;
+ rdreq <= 0;
+ skip <= 0;
+ underrun <= 0;
+ burst <= 0;
+ tx_empty <= 1;
+ tx_q <= 0;
+ tx_i <= 0;
+ trash <= 0;
+ rssi_flag <= 0;
+ time_wait <= 0;
end
else
- begin
+ begin
case (reader_state)
- IDLE:
+ IDLE:
begin
- /*
- * reset all the variables and wait for a
tx_strobe
- * it is assumed that the ram connected to this
fifo_reader
- * is a short hand fifo meaning that the header
to the next packet
- * is already available to this fifo_reader
when pkt_waiting is on
- */
- skip <=0;
- time_wait <= 0;
- if (pkt_waiting == 1)
- begin
- reader_state <= HEADER;
- rdreq <= 1;
- underrun <= 0;
- end
- if (burst == 1 && pkt_waiting == 0)
- underrun <= 1;
-
- if (tx_strobe == 1)
- tx_empty <= 1 ;
+ /*
+ * reset all the variables and wait for a tx_strobe
+ * it is assumed that the ram connected to this fifo_reader
+ * is a short hand fifo meaning that the header to the next
packet
+ * is already available to this fifo_reader when pkt_waiting is
on
+ */
+ skip <=0;
+ time_wait <= 0;
+ if (pkt_waiting == 1)
+ begin
+ reader_state <= HEADER;
+ rdreq <= 1;
+ underrun <= 0;
+ end
+ if (burst == 1 && pkt_waiting == 0)
+ underrun <= 1;
+ if (tx_strobe == 1)
+ tx_empty <= 1 ;
end
- /* Process header */
+ /* Process header */
HEADER:
- begin
+ begin
if (tx_strobe == 1)
tx_empty <= 1 ;
@@ -114,68 +110,64 @@
else if (fifodata[`ENDOFBURST] == 1)
burst <= 0;
- if (trash == 1 &&
fifodata[`STARTOFBURST] == 0)
- begin
- skip <= 1;
- reader_state <= IDLE;
- rdreq <= 0;
- end
- else
- begin
- payload_len <= fifodata[`PAYLOAD] ;
- read_len <= 0;
- rdreq <= 1;
- reader_state <= TIMESTAMP;
- end
- end
+ if (trash == 1 && fifodata[`STARTOFBURST] == 0)
+ begin
+ skip <= 1;
+ reader_state <= IDLE;
+ rdreq <= 0;
+ end
+ else
+ begin
+ payload_len <= fifodata[`PAYLOAD] ;
+ read_len <= 0;
+ rdreq <= 1;
+ reader_state <= TIMESTAMP;
+ end
+ end
TIMESTAMP:
- begin
+ begin
timestamp <= fifodata;
reader_state <= WAIT;
if (tx_strobe == 1)
tx_empty <= 1 ;
rdreq <= 0;
- end
+ end
- // Decide if we wait, send or discard samples
+ // Decide if we wait, send or discard samples
WAIT:
- begin
+ begin
if (tx_strobe == 1)
tx_empty <= 1 ;
time_wait <= time_wait + 32'd1;
- // Outdated
- if ((timestamp < adc_time) ||
- (time_wait >= rssi_wait
&& rssi_wait != 0 && rssi_flag))
+ // Outdated
+ if ((timestamp < timestamp_clock) ||
+ (time_wait >= rssi_wait && rssi_wait != 0 && rssi_flag))
begin
- trash <= 1;
- reader_state <= IDLE;
- skip <= 1;
+ trash <= 1;
+ reader_state <= IDLE;
+ skip <= 1;
end
// Let's send it
- else if ((timestamp <= adc_time + `JITTER
- && timestamp > adc_time)
+ else if (timestamp == timestamp_clock
|| timestamp == 32'hFFFFFFFF)
- begin
- if (rssi <= threshhold ||
rssi_flag == 0)
- begin
- trash <= 0;
- reader_state <= WAITSTROBE;
- end
- else
- reader_state <= WAIT;
- end
- else
- reader_state <= WAIT;
- // Wait a little bit more
- //else if (timestamp > adc_time + `JITTER)
- // reader_state <= WAIT;
- end
+ begin
+ if (rssi <= threshhold || rssi_flag == 0)
+ begin
+ trash <= 0;
+ reader_state <= WAITSTROBE;
+ end
+ else
+ reader_state <= WAIT;
+ end
+ else
+ reader_state <= WAIT;
+ end
// Wait for the transmit chain to be ready
WAITSTROBE:
- begin
+ begin
// If end of payload...
if (read_len == payload_len)
begin
@@ -189,11 +181,11 @@
reader_state <= SEND;
rdreq <= 1;
end
- end
+ end
- // Send the samples to the tx_chain
+ // Send the samples to the tx_chain
SEND:
- begin
+ begin
reader_state <= WAITSTROBE;
read_len <= read_len + 7'd1;
tx_empty <= 0;
@@ -213,13 +205,13 @@
tx_q <= fifodata[31:16];
end
endcase
- end
+ end
default:
- begin
- //error handling
+ begin
+ //error handling
reader_state <= IDLE;
- end
+ end
endcase
end
end
Modified: gnuradio/trunk/usrp/fpga/inband_lib/channel_demux.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/channel_demux.v 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/channel_demux.v 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -1,24 +1,24 @@
module channel_demux
- #(parameter NUM_CHAN = 2, parameter CHAN_WIDTH = 2) ( //usb Side
- input [31:0]usbdata_final,
- input WR_final,
-
- // TX Side
- input reset,
- input txclk,
- output reg [CHAN_WIDTH:0] WR_channel,
- output reg [31:0] ram_data,
- output reg [CHAN_WIDTH:0] WR_done_channel );
-/* Parse header and forward to ram */
- reg [2:0]reader_state;
- reg [4:0]channel ;
- reg [6:0]read_length ;
+ #(parameter NUM_CHAN = 2) ( //usb Side
+ input [31:0]usbdata_final,
+ input WR_final,
+ // TX Side
+ input reset,
+ input txclk,
+ output reg [NUM_CHAN:0] WR_channel,
+ output reg [31:0] ram_data,
+ output reg [NUM_CHAN:0] WR_done_channel );
+ /* Parse header and forward to ram */
+ reg [2:0]reader_state;
+ reg [4:0]channel ;
+ reg [6:0]read_length ;
+
// States
- parameter IDLE = 3'd0;
- parameter HEADER = 3'd1;
- parameter WAIT = 3'd2;
- parameter FORWARD = 3'd3;
+ parameter IDLE = 3'd0;
+ parameter HEADER = 3'd1;
+ parameter WAIT = 3'd2;
+ parameter FORWARD = 3'd3;
`define CHANNEL 20:16
`define PKT_SIZE 127
@@ -27,7 +27,7 @@
NUM_CHAN :
(usbdata_final[`CHANNEL]);
always @(posedge txclk)
- begin
+ begin
if (reset)
begin
reader_state <= IDLE;
Modified: gnuradio/trunk/usrp/fpga/inband_lib/channel_ram.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/channel_ram.v 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/channel_ram.v 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -1,114 +1,107 @@
module channel_ram
- ( // System
- input txclk,
- input reset,
+ ( // System
+ input txclk, input reset,
+ // USB side
+ input [31:0] datain, input WR, input WR_done, output have_space,
+ // Reader side
+ output [31:0] dataout, input RD, input RD_done, output packet_waiting);
- // USB side
- input [31:0] datain,
- input WR,
- input WR_done,
- output have_space,
-
- // Reader side
- output [31:0] dataout,
- input RD,
- input RD_done,
- output packet_waiting);
+ reg [6:0] wr_addr, rd_addr;
+ reg [1:0] which_ram_wr, which_ram_rd;
+ reg [2:0] nb_packets;
- reg [6:0] wr_addr, rd_addr;
- reg [1:0] which_ram_wr, which_ram_rd;
- reg [2:0] nb_packets;
+ reg [31:0] ram0 [0:127];
+ reg [31:0] ram1 [0:127];
+ reg [31:0] ram2 [0:127];
+ reg [31:0] ram3 [0:127];
- reg [31:0] ram0 [0:127];
- reg [31:0] ram1 [0:127];
- reg [31:0] ram2 [0:127];
- reg [31:0] ram3 [0:127];
+ reg [31:0] dataout0;
+ reg [31:0] dataout1;
+ reg [31:0] dataout2;
+ reg [31:0] dataout3;
- reg [31:0] dataout0;
- reg [31:0] dataout1;
- reg [31:0] dataout2;
- reg [31:0] dataout3;
+ wire wr_done_int;
+ wire rd_done_int;
+ wire [6:0] rd_addr_final;
+ wire [1:0] which_ram_rd_final;
- wire wr_done_int;
- wire rd_done_int;
- wire [6:0] rd_addr_final;
- wire [1:0] which_ram_rd_final;
-
- // USB side
- always @(posedge txclk)
- if(WR & (which_ram_wr == 2'd0)) ram0[wr_addr] <= datain;
+ // USB side
+ always @(posedge txclk)
+ if(WR & (which_ram_wr == 2'd0)) ram0[wr_addr] <= datain;
- always @(posedge txclk)
- if(WR & (which_ram_wr == 2'd1)) ram1[wr_addr] <= datain;
+ always @(posedge txclk)
+ if(WR & (which_ram_wr == 2'd1)) ram1[wr_addr] <= datain;
- always @(posedge txclk)
- if(WR & (which_ram_wr == 2'd2)) ram2[wr_addr] <= datain;
+ always @(posedge txclk)
+ if(WR & (which_ram_wr == 2'd2)) ram2[wr_addr] <= datain;
- always @(posedge txclk)
- if(WR & (which_ram_wr == 2'd3)) ram3[wr_addr] <= datain;
+ always @(posedge txclk)
+ if(WR & (which_ram_wr == 2'd3)) ram3[wr_addr] <= datain;
assign wr_done_int = ((WR && (wr_addr == 7'd127)) || WR_done);
- always @(posedge txclk)
- if(reset)
- wr_addr <= 0;
- else if (WR_done)
- wr_addr <= 0;
- else if (WR)
- wr_addr <= wr_addr + 7'd1;
+ always @(posedge txclk)
+ if(reset)
+ wr_addr <= 0;
+ else if (WR_done)
+ wr_addr <= 0;
+ else if (WR)
+ wr_addr <= wr_addr + 7'd1;
- always @(posedge txclk)
- if(reset)
- which_ram_wr <= 0;
- else if (wr_done_int)
- which_ram_wr <= which_ram_wr + 2'd1;
+ always @(posedge txclk)
+ if(reset)
+ which_ram_wr <= 0;
+ else if (wr_done_int)
+ which_ram_wr <= which_ram_wr + 2'd1;
- assign have_space = (nb_packets < 3'd3);
+ assign have_space = (nb_packets < 3'd3);
- // Reader side
- // short hand fifo
- // rd_addr_final is what rd_addr is going to be next clock cycle
- // which_ram_rd_final is what which_ram_rd is going to be next clock
cycle
- always @(posedge txclk) dataout0 <= ram0[rd_addr_final];
- always @(posedge txclk) dataout1 <= ram1[rd_addr_final];
- always @(posedge txclk) dataout2 <= ram2[rd_addr_final];
- always @(posedge txclk) dataout3 <= ram3[rd_addr_final];
+ // Reader side
+ // short hand fifo
+ // rd_addr_final is what rd_addr is going to be next clock cycle
+ // which_ram_rd_final is what which_ram_rd is going to be next clock cycle
+ always @(posedge txclk) dataout0 <= ram0[rd_addr_final];
+ always @(posedge txclk) dataout1 <= ram1[rd_addr_final];
+ always @(posedge txclk) dataout2 <= ram2[rd_addr_final];
+ always @(posedge txclk) dataout3 <= ram3[rd_addr_final];
- assign dataout = (which_ram_rd_final[1]) ?
- (which_ram_rd_final[0] ?
dataout3 : dataout2) :
- (which_ram_rd_final[0] ?
dataout1 : dataout0);
+ assign dataout = (which_ram_rd_final[1]) ?
+ (which_ram_rd_final[0] ? dataout3 : dataout2) :
+ (which_ram_rd_final[0] ? dataout1 : dataout0);
- //RD_done is the only way to signal the end of one packet
- assign rd_done_int = RD_done;
+ //RD_done is the only way to signal the end of one packet
+ assign rd_done_int = RD_done;
- always @(posedge txclk)
- if (reset)
- rd_addr <= 0;
- else if (RD_done)
- rd_addr <= 0;
- else if (RD) rd_addr <= rd_addr + 7'd1;
+ always @(posedge txclk)
+ if (reset)
+ rd_addr <= 0;
+ else if (RD_done)
+ rd_addr <= 0;
+ else if (RD)
+ rd_addr <= rd_addr + 7'd1;
- assign rd_addr_final = (reset|RD_done) ? (6'd0) :
- ((RD)?(rd_addr+7'd1):rd_addr);
- always @(posedge txclk)
- if (reset)
- which_ram_rd <= 0;
- else if (rd_done_int)
- which_ram_rd <= which_ram_rd + 2'd1;
+ assign rd_addr_final = (reset|RD_done) ? (6'd0) :
+ ((RD)?(rd_addr+7'd1):rd_addr);
+
+ always @(posedge txclk)
+ if (reset)
+ which_ram_rd <= 0;
+ else if (rd_done_int)
+ which_ram_rd <= which_ram_rd + 2'd1;
- assign which_ram_rd_final = (reset) ? (2'd0):
+ assign which_ram_rd_final = (reset) ? (2'd0):
((rd_done_int) ? (which_ram_rd + 2'd1) :
which_ram_rd);
- //packet_waiting is set to zero if rd_done_int is high
- //because there is no guarantee that nb_packets will be pos.
- //assign packet_waiting = (nb_packets != 0) & (~rd_done_int);
- assign packet_waiting = (nb_packets > 1) | ((nb_packets ==
1)&(~rd_done_int));
- always @(posedge txclk)
- if (reset)
- nb_packets <= 0;
- else if (wr_done_int & ~rd_done_int)
- nb_packets <= nb_packets + 3'd1;
- else if (rd_done_int & ~wr_done_int)
- nb_packets <= nb_packets - 3'd1;
+ //packet_waiting is set to zero if rd_done_int is high
+ //because there is no guarantee that nb_packets will be pos.
+
+ assign packet_waiting = (nb_packets > 1) | ((nb_packets ==
1)&(~rd_done_int));
+ always @(posedge txclk)
+ if (reset)
+ nb_packets <= 0;
+ else if (wr_done_int & ~rd_done_int)
+ nb_packets <= nb_packets + 3'd1;
+ else if (rd_done_int & ~wr_done_int)
+ nb_packets <= nb_packets - 3'd1;
-endmodule
\ No newline at end of file
+endmodule
Modified: gnuradio/trunk/usrp/fpga/inband_lib/cmd_reader.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/cmd_reader.v 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/cmd_reader.v 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -1,292 +1,305 @@
-module cmd_reader(
- //System
- input reset,
- input txclk,
- input [31:0] adc_time,
- //FX2 Side
- output reg skip,
- output reg rdreq,
- input [31:0] fifodata,
- input pkt_waiting,
- //Rx side
- input rx_WR_enabled,
- output reg [15:0] rx_databus,
- output reg rx_WR,
- output reg rx_WR_done,
- //register io
- input wire [31:0] reg_data_out,
- output reg [31:0] reg_data_in,
- output reg [6:0] reg_addr,
- output reg [1:0] reg_io_enable,
- output wire [14:0] debug
- );
+module cmd_reader
+ (//System
+ input reset, input txclk, input [31:0] timestamp_clock,
+ //FX2 Side
+ output reg skip, output reg rdreq,
+ input [31:0] fifodata, input pkt_waiting,
+ //Rx side
+ input rx_WR_enabled, output reg [15:0] rx_databus,
+ output reg rx_WR, output reg rx_WR_done,
+ //register io
+ input wire [31:0] reg_data_out, output reg [31:0] reg_data_in,
+ output reg [6:0] reg_addr, output reg [1:0] reg_io_enable,
+ output wire [14:0] debug, output reg stop, output reg [15:0] stop_time);
- // States
- parameter IDLE = 4'd0;
- parameter HEADER = 4'd1;
- parameter TIMESTAMP = 4'd2;
- parameter WAIT = 4'd3;
- parameter TEST = 4'd4;
- parameter SEND = 4'd5;
- parameter PING = 4'd6;
- parameter WRITE_REG = 4'd7;
- parameter WRITE_REG_MASKED = 4'd8;
- parameter READ_REG = 4'd9;
- parameter DELAY = 4'd14;
+ // States
+ parameter IDLE = 4'd0;
+ parameter HEADER = 4'd1;
+ parameter TIMESTAMP = 4'd2;
+ parameter WAIT = 4'd3;
+ parameter TEST = 4'd4;
+ parameter SEND = 4'd5;
+ parameter PING = 4'd6;
+ parameter WRITE_REG = 4'd7;
+ parameter WRITE_REG_MASKED = 4'd8;
+ parameter READ_REG = 4'd9;
+ parameter DELAY = 4'd14;
- `define OP_PING_FIXED 8'd0
- `define OP_PING_FIXED_REPLY 8'd1
- `define OP_WRITE_REG 8'd2
- `define OP_WRITE_REG_MASKED 8'd3
- `define OP_READ_REG 8'd4
- `define OP_READ_REG_REPLY 8'd5
- `define OP_DELAY 8'd12
+ `define OP_PING_FIXED 8'd0
+ `define OP_PING_FIXED_REPLY 8'd1
+ `define OP_WRITE_REG 8'd2
+ `define OP_WRITE_REG_MASKED 8'd3
+ `define OP_READ_REG 8'd4
+ `define OP_READ_REG_REPLY 8'd5
+ `define OP_DELAY 8'd12
- reg [6:0] payload;
- reg [6:0] payload_read;
- reg [3:0] state;
- reg [15:0] high;
- reg [15:0] low;
- reg pending;
- reg [31:0] value0;
- reg [31:0] value1;
- reg [31:0] value2;
- reg [1:0] lines_in;
- reg [1:0] lines_out;
- reg [1:0] lines_out_total;
+ reg [6:0] payload;
+ reg [6:0] payload_read;
+ reg [3:0] state;
+ reg [15:0] high;
+ reg [15:0] low;
+ reg pending;
+ reg [31:0] value0;
+ reg [31:0] value1;
+ reg [31:0] value2;
+ reg [1:0] lines_in;
+ reg [1:0] lines_out;
+ reg [1:0] lines_out_total;
- `define JITTER 5
- `define OP_CODE 31:24
- `define PAYLOAD 8:2
+ `define JITTER 5
+ `define OP_CODE 31:24
+ `define PAYLOAD 8:2
- wire [7:0] ops;
- assign ops = value0[`OP_CODE];
- assign debug = {state[3:0], lines_out[1:0], pending, rx_WR,
rx_WR_enabled, value0[2:0], ops[2:0]};
+ wire [7:0] ops;
+ assign ops = value0[`OP_CODE];
+ assign debug = {state[3:0], lines_out[1:0], pending, rx_WR, rx_WR_enabled,
value0[2:0], ops[2:0]};
- always @(posedge txclk)
- if (reset)
- begin
- pending <= 0;
- state <= IDLE;
- skip <= 0;
- rdreq <= 0;
- rx_WR <= 0;
- reg_io_enable <= 0;
- reg_data_in <= 0;
- reg_addr <= 0;
- end
- else case (state)
- IDLE : begin
- payload_read <= 0;
- skip <= 0;
- lines_in <= 0;
- if (pkt_waiting)
- begin
- state <= HEADER;
- rdreq <= 1;
- end
- end
+ always @(posedge txclk)
+ if (reset)
+ begin
+ pending <= 0;
+ state <= IDLE;
+ skip <= 0;
+ rdreq <= 0;
+ rx_WR <= 0;
+ reg_io_enable <= 0;
+ reg_data_in <= 0;
+ reg_addr <= 0;
+ stop <= 0;
+ end
+ else case (state)
+ IDLE :
+ begin
+ payload_read <= 0;
+ skip <= 0;
+ lines_in <= 0;
+ if(pkt_waiting)
+ begin
+ state <= HEADER;
+ rdreq <= 1;
+ end
+ end
+
+ HEADER :
+ begin
+ payload <= fifodata[`PAYLOAD];
+ state <= TIMESTAMP;
+ end
+
+ TIMESTAMP :
+ begin
+ value0 <= fifodata;
+ state <= WAIT;
+ rdreq <= 0;
+ end
- HEADER : begin
- payload <= fifodata[`PAYLOAD];
- state <= TIMESTAMP;
- end
+ WAIT :
+ begin
+ // Let's send it
+ if ((value0 <= timestamp_clock + `JITTER
+ && value0 > timestamp_clock)
+ || value0 == 32'hFFFFFFFF)
+ state <= TEST;
+ // Wait a little bit more
+ else if (value0 > timestamp_clock + `JITTER)
+ state <= WAIT;
+ // Outdated
+ else if (value0 < timestamp_clock)
+ begin
+ state <= IDLE;
+ skip <= 1;
+ end
+ end
- TIMESTAMP : begin
- value0 <= fifodata;
- state <= WAIT;
- rdreq <= 0;
- end
-
- WAIT : begin
- // Let's send it
- if ((value0 <= adc_time + `JITTER
- && value0 > adc_time)
- || value0 == 32'hFFFFFFFF)
- state <= TEST;
- // Wait a little bit more
- else if (value0 > adc_time + `JITTER)
- state <= WAIT;
- // Outdated
- else if (value0 < adc_time)
- begin
+ TEST :
+ begin
+ reg_io_enable <= 0;
+ rx_WR <= 0;
+ rx_WR_done <= 1;
+ stop <= 0;
+ if (payload_read == payload)
+ begin
+ skip <= 1;
+ state <= IDLE;
+ rdreq <= 0;
+ end
+ else
+ begin
+ value0 <= fifodata;
+ lines_in <= 2'd1;
+ rdreq <= 1;
+ payload_read <= payload_read + 7'd1;
+ lines_out <= 0;
+ case (fifodata[`OP_CODE])
+ `OP_PING_FIXED:
+ begin
+ state <= PING;
+ end
+ `OP_WRITE_REG:
+ begin
+ state <= WRITE_REG;
+ pending <= 1;
+ end
+ `OP_WRITE_REG_MASKED:
+ begin
+ state <= WRITE_REG_MASKED;
+ pending <= 1;
+ end
+ `OP_READ_REG:
+ begin
+ state <= READ_REG;
+ end
+ `OP_DELAY:
+ begin
+ state <= DELAY;
+ end
+ default:
+ begin
+ //error, skip this packet
+ skip <= 1;
state <= IDLE;
- skip <= 1;
- end
- end
+ end
+ endcase
+ end
+ end
- TEST : begin
- reg_io_enable <= 0;
- rx_WR <= 0;
- rx_WR_done <= 1;
- if (payload_read == payload)
- begin
- skip <= 1;
- state <= IDLE;
- rdreq <= 0;
- end
- else
- begin
- value0 <= fifodata;
- lines_in <= 2'd1;
- rdreq <= 1;
- payload_read <= payload_read +
7'd1;
- lines_out <= 0;
- case (fifodata[`OP_CODE])
- `OP_PING_FIXED: begin
- state <= PING;
- end
- `OP_WRITE_REG: begin
- state <=
WRITE_REG;
- pending <= 1;
- end
- `OP_WRITE_REG_MASKED:
begin
- state <=
WRITE_REG_MASKED;
- pending <= 1;
- end
- `OP_READ_REG: begin
- state <=
READ_REG;
- end
- `OP_DELAY: begin
- state <= DELAY;
- end
- default: begin
- //error, skip this
packet
- skip <= 1;
- state <= IDLE;
- end
- endcase
- end
- end
+ SEND:
+ begin
+ rdreq <= 0;
+ rx_WR_done <= 0;
+ if (pending)
+ begin
+ rx_WR <= 1;
+ rx_databus <= high;
+ pending <= 0;
+ if (lines_out == lines_out_total)
+ state <= TEST;
+ else case (ops)
+ `OP_READ_REG:
+ begin
+ state <= READ_REG;
+ end
+ default:
+ begin
+ state <= TEST;
+ end
+ endcase
+ end
+ else
+ begin
+ if (rx_WR_enabled)
+ begin
+ rx_WR <= 1;
+ rx_databus <= low;
+ pending <= 1;
+ lines_out <= lines_out + 2'd1;
+ end
+ else
+ rx_WR <= 0;
+ end
+ end
- SEND: begin
- rdreq <= 0;
- rx_WR_done <= 0;
- if (pending)
- begin
- rx_WR <= 1;
- rx_databus <= high;
- pending <= 0;
- if (lines_out ==
lines_out_total)
- state <= TEST;
- else case (ops)
- `OP_READ_REG: begin
- state <=
READ_REG;
- end
- default: begin
- state <= TEST;
- end
- endcase
- end
- else
- begin
- if (rx_WR_enabled)
- begin
- rx_WR <= 1;
- rx_databus <= low;
- pending <= 1;
- lines_out <= lines_out
+ 2'd1;
- end
- else
- rx_WR <= 0;
- end
- end
+ PING:
+ begin
+ rx_WR <= 0;
+ rdreq <= 0;
+ rx_WR_done <= 0;
+ lines_out_total <= 2'd1;
+ pending <= 0;
+ state <= SEND;
+ high <= {`OP_PING_FIXED_REPLY, 8'd2};
+ low <= value0[15:0];
+ end
- PING: begin
- rx_WR <= 0;
- rdreq <= 0;
- rx_WR_done <= 0;
- lines_out_total <= 2'd1;
- pending <= 0;
- state <= SEND;
- high <= {`OP_PING_FIXED_REPLY, 8'd2};
- low <= value0[15:0];
- end
+ READ_REG:
+ begin
+ rx_WR <= 0;
+ rx_WR_done <= 0;
+ rdreq <= 0;
+ lines_out_total <= 2'd2;
+ pending <= 0;
+ state <= SEND;
+ if (lines_out == 0)
+ begin
+ high <= {`OP_READ_REG_REPLY, 8'd6};
+ low <= value0[15:0];
+ reg_io_enable <= 2'd3;
+ reg_addr <= value0[6:0];
+ end
+ else
+ begin
+ high <= reg_data_out[31:16];
+ low <= reg_data_out[15:0];
+ end
+ end
- READ_REG: begin
- rx_WR <= 0;
- rx_WR_done <= 0;
- rdreq <= 0;
- lines_out_total <= 2'd2;
- pending <= 0;
- state <= SEND;
- if (lines_out == 0)
- begin
- high <= {`OP_READ_REG_REPLY,
8'd6};
- low <= value0[15:0];
- reg_io_enable <= 2'd3;
- reg_addr <= value0[6:0];
- end
- else
- begin
- high <= reg_data_out[31:16];
- low <= reg_data_out[15:0];
- end
- end
+ WRITE_REG:
+ begin
+ rx_WR <= 0;
+ if (pending)
+ pending <= 0;
+ else
+ begin
+ if (lines_in == 2'd1)
+ begin
+ payload_read <= payload_read + 7'd1;
+ lines_in <= lines_in + 2'd1;
+ value1 <= fifodata;
+ rdreq <= 0;
+ end
+ else
+ begin
+ reg_io_enable <= 2'd2;
+ reg_data_in <= value1;
+ reg_addr <= value0[6:0];
+ state <= TEST;
+ end
+ end
+ end
- WRITE_REG: begin
- rx_WR <= 0;
- if (pending)
- pending <= 0;
- else
- begin
- if (lines_in == 2'd1)
- begin
- payload_read <=
payload_read + 7'd1;
- lines_in <= lines_in +
2'd1;
- value1 <= fifodata;
- rdreq <= 0;
- end
- else
- begin
- reg_io_enable <= 2'd2;
- reg_data_in <= value1;
- reg_addr <= value0[6:0];
- state <= TEST;
- end
- end
- end
+ WRITE_REG_MASKED:
+ begin
+ rx_WR <= 0;
+ if (pending)
+ pending <= 0;
+ else
+ begin
+ if (lines_in == 2'd1)
+ begin
+ rdreq <= 1;
+ payload_read <= payload_read + 7'd1;
+ lines_in <= lines_in + 2'd1;
+ value1 <= fifodata;
+ end
+ else if (lines_in == 2'd2)
+ begin
+ rdreq <= 0;
+ payload_read <= payload_read + 7'd1;
+ lines_in <= lines_in + 2'd1;
+ value2 <= fifodata;
+ end
+ else
+ begin
+ reg_io_enable <= 2'd2;
+ reg_data_in <= (value1 & value2);
+ reg_addr <= value0[6:0];
+ state <= TEST;
+ end
+ end
+ end
- WRITE_REG_MASKED: begin
- rx_WR <= 0;
- if (pending)
- pending <= 0;
- else
- begin
- if (lines_in == 2'd1)
- begin
- rdreq <= 1;
- payload_read <=
payload_read + 7'd1;
- lines_in <= lines_in +
2'd1;
- value1 <= fifodata;
- end
- else if (lines_in == 2'd2)
- begin
- rdreq <= 0;
- payload_read <=
payload_read + 7'd1;
- lines_in <= lines_in +
2'd1;
- value2 <= fifodata;
- end
- else
- begin
- reg_io_enable <= 2'd2;
- reg_data_in <= (value1
& value2);
- reg_addr <= value0[6:0];
- state <= TEST;
- end
- end
- end
+ DELAY :
+ begin
+ rdreq <= 0;
+ stop <= 1;
+ stop_time <= value0[15:0];
+ state <= TEST;
+ end
- DELAY : begin
- rdreq <= 0;
- value1 <= value1 + 32'd1;
- if (value0[15:0] == value1[15:0])
- state <= TEST;
- end
-
- default : begin
- //error state handling
- state <= IDLE;
- end
- endcase
-endmodule
\ No newline at end of file
+ default :
+ begin
+ //error state handling
+ state <= IDLE;
+ end
+ endcase
+endmodule
Deleted: gnuradio/trunk/usrp/fpga/inband_lib/data_packet_fifo.v
Modified: gnuradio/trunk/usrp/fpga/inband_lib/packet_builder.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/packet_builder.v 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/packet_builder.v 2008-04-30
03:52:31 UTC (rev 8295)
@@ -1,8 +1,8 @@
-module packet_builder #(parameter NUM_CHAN = 1)(
+module packet_builder #(parameter NUM_CHAN = 2)(
// System
input rxclk,
input reset,
- input [31:0] adctime,
+ input [31:0] timestamp_clock,
input [3:0] channels,
// ADC side
input [15:0]chan_fifodata,
@@ -14,17 +14,17 @@
output reg WR,
output reg [15:0]fifodata,
input have_space,
- input wire [31:0]rssi_0, input wire [31:0]rssi_1, input wire
[31:0]rssi_2,
- input wire [31:0]rssi_3, output wire [7:0] debugbus,
- input [NUM_CHAN:0] overrun, input [NUM_CHAN:0] underrun);
+ input wire [31:0]rssi_0, input wire [31:0]rssi_1, input wire [31:0]rssi_2,
+ input wire [31:0]rssi_3, output wire [7:0] debugbus,
+ input [NUM_CHAN:0] underrun);
// States
`define IDLE 3'd0
`define HEADER1 3'd1
- `define HEADER2 3'd2
+ `define HEADER2 3'd2
`define TIMESTAMP 3'd3
- `define FORWARD 3'd4
+ `define FORWARD 3'd4
`define MAXPAYLOAD 504
@@ -39,51 +39,67 @@
`define UNDERRUN 14
`define OVERRUN 15
+ reg [NUM_CHAN:0] overrun;
reg [2:0] state;
reg [8:0] read_length;
reg [8:0] payload_len;
- reg tstamp_complete;
+ reg timestamp_complete;
reg [3:0] check_next;
- wire [8:0] chan_used;
+
wire [31:0] true_rssi;
- wire [4:0] true_channel;
+ wire [4:0] true_channel;
+ wire ready_to_send;
- assign debugbus = {state, chan_empty[0], underrun[0], check_next[0],
- have_space, rd_select[0]};
- assign chan_used = chan_usedw[8:0];
- assign true_rssi = (rd_select[1]) ? ((rd_select[0]) ? rssi_3:rssi_2) :
+ assign debugbus = {chan_empty[0], rd_select[0], have_space,
+ (chan_usedw >= 10'd504), (chan_usedw ==0),
+ ready_to_send, state[1:0]};
+
+ assign true_rssi = (rd_select[1]) ? ((rd_select[0]) ? rssi_3:rssi_2) :
((rd_select[0]) ?
rssi_1:rssi_0);
- assign true_channel = (check_next == 4'd0 ? 5'h1f : {1'd0, check_next -
4'd1});
+ assign true_channel = (check_next == 4'd0 ? 5'h1f : {1'd0, check_next -
4'd1});
+ assign ready_to_send = (chan_usedw >= 10'd504) || (chan_usedw == 0) ||
+ ((rd_select == NUM_CHAN)&&(chan_usedw > 0));
+
always @(posedge rxclk)
begin
if (reset)
begin
+ overrun <= 0;
WR <= 0;
rd_select <= 0;
chan_rdreq <= 0;
- tstamp_complete <= 0;
+ timestamp_complete <= 0;
check_next <= 0;
state <= `IDLE;
end
else case (state)
`IDLE: begin
- chan_rdreq <= #1 0;
- if (have_space)
- begin
- if(~chan_empty[check_next])
- begin
- state <= #1 `HEADER1;
- rd_select <= #1 check_next;
- end
- check_next <= #1 (check_next ==
channels ? 4'd0 : check_next + 4'd1);
- end
+ chan_rdreq <= #1 0;
+ //check if the channel is full
+ if(~chan_empty[check_next])
+ begin
+ if (have_space)
+ begin
+ //transmit if the usb buffer have space
+ //check if we should send
+ if (ready_to_send)
+ state <= #1 `HEADER1;
+
+ overrun[check_next] <= 0;
+ end
+ else
+ begin
+ state <= #1 `IDLE;
+ overrun[check_next] <= 1;
+ end
+ rd_select <= #1 check_next;
+ end
+ check_next <= #1 (check_next == channels ? 4'd0 : check_next +
4'd1);
end
`HEADER1: begin
- fifodata[`PAYLOAD_LEN] <= #1 (chan_used > 9'd252
- ? 9'd252 : chan_used << 1);
- payload_len <= #1 (chan_used > 9'd252
- ? 9'd252 : chan_used << 1);
+ fifodata[`PAYLOAD_LEN] <= #1 9'd504;
+ payload_len <= #1 9'd504;
fifodata[`TAG] <= #1 0;
fifodata[`MBZ] <= #1 0;
WR <= #1 1;
@@ -103,13 +119,13 @@
end
`TIMESTAMP: begin
- fifodata <= #1 (tstamp_complete ? adctime[31:16] :
adctime[15:0]);
- tstamp_complete <= #1 ~tstamp_complete;
+ fifodata <= #1 (timestamp_complete ? timestamp_clock[31:16] :
timestamp_clock[15:0]);
+ timestamp_complete <= #1 ~timestamp_complete;
- if (~tstamp_complete)
+ if (~timestamp_complete)
chan_rdreq <= #1 1;
- state <= #1 (tstamp_complete ? `FORWARD : `TIMESTAMP);
+ state <= #1 (timestamp_complete ? `FORWARD : `TIMESTAMP);
end
`FORWARD: begin
Modified: gnuradio/trunk/usrp/fpga/inband_lib/register_io.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/register_io.v 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/register_io.v 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -1,15 +1,38 @@
module register_io
- (input clk, input reset, input wire [1:0] enable, input wire [6:0]
addr,
- input wire [31:0] datain, output reg [31:0] dataout, output wire
[15:0] debugbus,
- input wire [31:0] rssi_0, input wire [31:0] rssi_1,
- input wire [31:0] rssi_2, input wire [31:0] rssi_3,
- output wire [31:0] threshhold, output wire [31:0] rssi_wait);
-
+ (clk, reset, enable, addr, datain, dataout, debugbus, addr_wr, data_wr,
strobe_wr,
+ rssi_0, rssi_1, rssi_2, rssi_3, threshhold, rssi_wait, reg_0, reg_1,
reg_2, reg_3,
+ debug_en, misc, txmux);
+
+ input clk;
+ input reset;
+ input wire [1:0] enable;
+ input wire [6:0] addr;
+ input wire [31:0] datain;
+ output reg [31:0] dataout;
+ output wire [15:0] debugbus;
+ output reg [6:0] addr_wr;
+ output reg [31:0] data_wr;
+ output wire strobe_wr;
+ input wire [31:0] rssi_0;
+ input wire [31:0] rssi_1;
+ input wire [31:0] rssi_2;
+ input wire [31:0] rssi_3;
+ output wire [31:0] threshhold;
+ output wire [31:0] rssi_wait;
+ input wire [15:0] reg_0;
+ input wire [15:0] reg_1;
+ input wire [15:0] reg_2;
+ input wire [15:0] reg_3;
+ input wire [3:0] debug_en;
+ input wire [7:0] misc;
+ input wire [31:0] txmux;
+
reg strobe;
- wire [31:0] out[7:0];
+ wire [31:0] out[2:1];
assign debugbus = {clk, enable, addr[2:0], datain[4:0], dataout[4:0]};
assign threshhold = out[1];
assign rssi_wait = out[2];
+ assign strobe_wr = strobe;
always @(*)
if (reset | ~enable[1])
@@ -22,41 +45,38 @@
if (enable[0])
begin
//read
- if (addr == 7'd9)
- dataout <= rssi_0;
- else if (addr == 7'd10)
- dataout <= rssi_1;
- else if (addr == 7'd11)
- dataout <= rssi_2;
- else if (addr == 7'd12)
- dataout <= rssi_3;
- else
- dataout <= out[addr[2:0]];
- strobe <= 0;
- end
+ if (addr <= 7'd52 && addr > 7'd50)
+ dataout <= out[addr-7'd50];
+ else
+ dataout <= 32'hFFFFFFFF;
+ strobe <= 0;
+ end
else
begin
//write
dataout <= dataout;
strobe <= 1;
+ data_wr <= datain;
+ addr_wr <= addr;
end
end
- //register declarations
- setting_reg #(0) setting_reg0(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[0]));
- setting_reg #(1) setting_reg1(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[1]));
- setting_reg #(2) setting_reg2(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[2]));
- setting_reg #(3) setting_reg3(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[3]));
- setting_reg #(4) setting_reg4(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[4]));
- setting_reg #(5) setting_reg5(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[5]));
- setting_reg #(6) setting_reg6(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[6]));
- setting_reg #(7) setting_reg7(.clock(clk),.reset(reset),
- .strobe(strobe),.addr(addr),.in(datain),.out(out[7]));
-endmodule
\ No newline at end of file
+//register declarations
+ /*setting_reg #(50) setting_reg0(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[0]));*/
+ setting_reg #(51) setting_reg1(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[1]));
+ setting_reg #(52) setting_reg2(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[2]));
+ /*setting_reg #(53) setting_reg3(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[3]));
+ setting_reg #(54) setting_reg4(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[4]));
+ setting_reg #(55) setting_reg5(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[5]));
+ setting_reg #(56) setting_reg6(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[6]));
+ setting_reg #(57) setting_reg7(.clock(clk),.reset(reset),
+ .strobe(strobe_wr),.addr(addr_wr),.in(data_wr),.out(out[7]));*/
+
+endmodule
Modified: gnuradio/trunk/usrp/fpga/inband_lib/rx_buffer_inband.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/rx_buffer_inband.v 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/rx_buffer_inband.v 2008-04-30
03:52:31 UTC (rev 8295)
@@ -1,179 +1,209 @@
-//`include "../../firmware/include/fpga_regs_common.v"
-//`include "../../firmware/include/fpga_regs_standard.v"
-module rx_buffer_inband
- ( input usbclk,
- input bus_reset,
- input reset, // DSP side reset (used here), do not reset registers
- input reset_regs, //Only reset registers
- output [15:0] usbdata,
- input RD,
- output wire have_pkt_rdy,
- output reg rx_overrun,
- input wire [3:0] channels,
- input wire [15:0] ch_0,
- input wire [15:0] ch_1,
- input wire [15:0] ch_2,
- input wire [15:0] ch_3,
- input wire [15:0] ch_4,
- input wire [15:0] ch_5,
- input wire [15:0] ch_6,
- input wire [15:0] ch_7,
- input rxclk,
- input rxstrobe,
- input clear_status,
- input [6:0] serial_addr,
- input [31:0] serial_data,
- input serial_strobe,
- output wire [15:0] debugbus,
-
- //Connection with tx_inband
- input rx_WR,
- input [15:0] rx_databus,
- input rx_WR_done,
- output reg rx_WR_enabled,
- //signal strength
- input wire [31:0] rssi_0, input wire [31:0] rssi_1,
- input wire [31:0] rssi_2, input wire [31:0] rssi_3,
- input wire [1:0] tx_overrun, input wire [1:0] tx_underrun
- );
-
- parameter NUM_CHAN = 1;
- genvar i ;
-
- // FX2 Bug Fix
- reg [8:0] read_count;
- always @(negedge usbclk)
- if(bus_reset)
- read_count <= #1 9'd0;
- else if(RD & ~read_count[8])
- read_count <= #1 read_count + 9'd1;
- else
- read_count <= #1 RD ? read_count : 9'b0;
-
- // Time counter
- reg [31:0] adctime;
- always @(posedge rxclk)
- if (reset)
- adctime <= 0;
- else if (rxstrobe)
- adctime <= adctime + 1;
-
- // USB side fifo
- wire [11:0] rdusedw;
- wire [11:0] wrusedw;
- wire [15:0] fifodata;
- wire WR;
- wire have_space;
-
- fifo_4kx16_dc rx_usb_fifo (
- .aclr ( reset ),
- .data ( fifodata ),
- .rdclk ( ~usbclk ),
- .rdreq ( RD & ~read_count[8] ),
- .wrclk ( rxclk ),
- .wrreq ( WR ),
- .q ( usbdata ),
- .rdempty ( ),
- .rdusedw ( rdusedw ),
- .wrfull ( ),
- .wrusedw ( wrusedw ) );
-
- assign have_pkt_rdy = (rdusedw >= 12'd256);
- assign have_space = (wrusedw < 12'd760);
-
- // Rx side fifos
- wire chan_rdreq;
- wire [15:0] chan_fifodata;
- wire [9:0] chan_usedw;
- wire [NUM_CHAN:0] chan_empty;
- wire [3:0] rd_select;
- wire [NUM_CHAN:0] rx_full;
-
- packet_builder #(NUM_CHAN) rx_pkt_builer (
- .rxclk ( rxclk ),
- .reset ( reset ),
- .adctime ( adctime ),
- .channels ( 4'd1 ),
- .chan_rdreq ( chan_rdreq ),
- .chan_fifodata ( chan_fifodata ),
- .chan_empty ( chan_empty ),
- .rd_select ( rd_select ),
- .chan_usedw ( chan_usedw ),
- .WR ( WR ),
- .fifodata ( fifodata ),
- .have_space ( have_space ),
- .rssi_0(rssi_0), .rssi_1(rssi_1),
- .rssi_2(rssi_2),.rssi_3(rssi_3), .debugbus(debug),
- .overrun(tx_overrun), .underrun(tx_underrun));
-
- // Detect overrun
- always @(posedge rxclk)
- if(reset)
- rx_overrun <= 1'b0;
- else if(rx_full[0])
- rx_overrun <= 1'b1;
- else if(clear_status)
- rx_overrun <= 1'b0;
-
- reg [6:0] test;
- always @(posedge rxclk)
- if (reset)
- test <= 0;
- else
- test <= test + 7'd1;
-
- // TODO write this genericly
- wire [15:0]ch[NUM_CHAN:0];
- assign ch[0] = ch_0;
-
- wire cmd_empty;
- always @(posedge rxclk)
- if(reset)
- rx_WR_enabled <= 1;
- else if(cmd_empty)
- rx_WR_enabled <= 1;
- else if(rx_WR_done)
- rx_WR_enabled <= 0;
-
- wire [15:0] dataout [0:NUM_CHAN];
- wire [9:0] usedw [0:NUM_CHAN];
- wire empty[0:NUM_CHAN];
-
- generate for (i = 0 ; i < NUM_CHAN; i = i + 1)
- begin : generate_channel_fifos
- wire rdreq;
-
- assign rdreq = (rd_select == i) & chan_rdreq;
- //assign chan_empty[i] = usedw[i] < 10'd126;
- fifo_1kx16 rx_chan_fifo (
- .aclr ( reset ),
- .clock ( rxclk ),
- .data ( ch[i] ),
- .rdreq ( rdreq ),
- .wrreq ( ~rx_full[i] & rxstrobe),
- .empty (empty[i]),
- .full (rx_full[i]),
- .q ( dataout[i]),
- .usedw ( usedw[i]),
- .almost_empty(chan_empty[i])
- );
- end
- endgenerate
- wire [7:0] debug;
- fifo_1kx16 rx_cmd_fifo (
- .aclr ( reset ),
- .clock ( rxclk ),
- .data ( rx_databus ),
- .rdreq ( (rd_select == NUM_CHAN) & chan_rdreq ),
- .wrreq ( rx_WR & rx_WR_enabled),
- .empty ( cmd_empty),
- .full ( rx_full[NUM_CHAN] ),
- .q ( dataout[NUM_CHAN]),
- .usedw ( usedw[NUM_CHAN] )
- );
- assign chan_empty[NUM_CHAN] = cmd_empty | rx_WR_enabled;
- assign chan_fifodata = dataout[rd_select];
- assign chan_usedw = usedw[rd_select];
- assign debugbus = {rxstrobe, chan_rdreq, debug,
- rx_full[0], chan_empty[0], empty[0],
have_space, RD, rxclk};
-endmodule
+//`include "../../firmware/include/fpga_regs_common.v"
+//`include "../../firmware/include/fpga_regs_standard.v"
+module rx_buffer_inband
+ ( input usbclk,
+ input bus_reset,
+ input reset, // DSP side reset (used here), do not reset registers
+ input reset_regs, //Only reset registers
+ output [15:0] usbdata,
+ input RD,
+ output wire have_pkt_rdy,
+ output reg rx_overrun,
+ input wire [3:0] channels,
+ input wire [15:0] ch_0,
+ input wire [15:0] ch_1,
+ input wire [15:0] ch_2,
+ input wire [15:0] ch_3,
+ input wire [15:0] ch_4,
+ input wire [15:0] ch_5,
+ input wire [15:0] ch_6,
+ input wire [15:0] ch_7,
+ input rxclk,
+ input rxstrobe,
+ input clear_status,
+ input [6:0] serial_addr,
+ input [31:0] serial_data,
+ input serial_strobe,
+ output wire [15:0] debugbus,
+
+ //Connection with tx_inband
+ input rx_WR,
+ input [15:0] rx_databus,
+ input rx_WR_done,
+ output reg rx_WR_enabled,
+ //signal strength
+ input wire [31:0] rssi_0, input wire [31:0] rssi_1,
+ input wire [31:0] rssi_2, input wire [31:0] rssi_3,
+ input wire [1:0] tx_underrun
+ );
+
+ parameter NUM_CHAN = 1;
+ genvar i ;
+
+ // FX2 Bug Fix
+ reg [8:0] read_count;
+ always @(negedge usbclk)
+ if(bus_reset)
+ read_count <= #1 9'd0;
+ else if(RD & ~read_count[8])
+ read_count <= #1 read_count + 9'd1;
+ else
+ read_count <= #1 RD ? read_count : 9'b0;
+
+ // Time counter
+ reg [31:0] timestamp_clock;
+ always @(posedge rxclk)
+ if (reset)
+ timestamp_clock <= 0;
+ else
+ timestamp_clock <= timestamp_clock + 1;
+
+ // USB side fifo
+ wire [11:0] rdusedw;
+ wire [11:0] wrusedw;
+ wire [15:0] fifodata;
+ wire [15:0] fifodata_il[0:NUM_CHAN];
+ wire WR;
+ wire have_space;
+ reg sel;
+ reg wr;
+
+ always@(posedge rxclk)
+ begin
+ if(reset)
+ begin
+ sel<=1;
+ wr<=0;
+ end
+ else if(rxstrobe)
+ begin
+ sel<=0;
+ wr<=1;
+ end
+ else if(wr&~sel)
+ sel<=1;
+ else if(wr&sel)
+ wr<=0;
+ else
+ wr<=0;
+ end
+
+ assign fifodata_il[0] = (sel)?ch_1:ch_0;
+ assign fifodata_il[1] = (sel)?ch_3:ch_2;
+
+ fifo_4kx16_dc rx_usb_fifo (
+ .aclr ( reset ),
+ .data ( fifodata ),
+ .rdclk ( ~usbclk ),
+ .rdreq ( RD & ~read_count[8] ),
+ .wrclk ( rxclk ),
+ .wrreq ( WR ),
+ .q ( usbdata ),
+ .rdempty ( ),
+ .rdusedw ( rdusedw ),
+ .wrfull ( ),
+ .wrusedw ( wrusedw ) );
+
+ assign have_pkt_rdy = (rdusedw >= 12'd256);
+ assign have_space = (wrusedw < 12'd760);
+
+ // Rx side fifos
+ // These are of size [NUM_CHAN:0] because the extra channel is used for the
+ // RX command channel. If there were no command channel, they would be
+ // NUM_CHAN-1.
+ wire chan_rdreq;
+ wire [15:0] chan_fifodata;
+ wire [9:0] chan_usedw;
+ wire [NUM_CHAN:0] chan_empty;
+ wire [3:0] rd_select;
+ wire [NUM_CHAN:0] rx_full;
+
+ packet_builder #(NUM_CHAN) rx_pkt_builer (
+ .rxclk ( rxclk ),
+ .reset ( reset ),
+ .timestamp_clock ( timestamp_clock ),
+ .channels ( NUM_CHAN ),
+ .chan_rdreq ( chan_rdreq ),
+ .chan_fifodata ( chan_fifodata ),
+ .chan_empty ( chan_empty ),
+ .rd_select ( rd_select ),
+ .chan_usedw ( chan_usedw ),
+ .WR ( WR ),
+ .fifodata ( fifodata ),
+ .have_space ( have_space ),
+ .rssi_0(rssi_0), .rssi_1(rssi_1),
+ .rssi_2(rssi_2),.rssi_3(rssi_3), .debugbus(debug),
+ .underrun(tx_underrun));
+
+ // Detect overrun
+ always @(posedge rxclk)
+ if(reset)
+ rx_overrun <= 1'b0;
+ else if(rx_full[0])
+ rx_overrun <= 1'b1;
+ else if(clear_status)
+ rx_overrun <= 1'b0;
+
+
+ // FIXME: what is the purpose of these two lines?
+ wire [15:0]ch[NUM_CHAN:0];
+ assign ch[0] = ch_0;
+
+ wire cmd_empty;
+
+ always @(posedge rxclk)
+ if(reset)
+ rx_WR_enabled <= 1;
+ else if(cmd_empty)
+ rx_WR_enabled <= 1;
+ else if(rx_WR_done)
+ rx_WR_enabled <= 0;
+
+
+ // Of Size 0:NUM_CHAN due to extra command channel.
+ wire [15:0] dataout [0:NUM_CHAN];
+ wire [9:0] usedw [0:NUM_CHAN];
+ wire empty[0:NUM_CHAN];
+
+ generate for (i = 0 ; i < NUM_CHAN; i = i + 1)
+ begin : generate_channel_fifos
+
+ wire rdreq;
+
+ assign rdreq = (rd_select == i) & chan_rdreq;
+
+ fifo_1kx16 rx_chan_fifo (
+ .aclr ( reset ),
+ .clock ( rxclk ),
+ .data ( fifodata_il[i] ),
+ .rdreq ( rdreq ),
+ .wrreq ( ~rx_full[i] & wr),
+ .empty (empty[i]),
+ .full (rx_full[i]),
+ .q ( dataout[i]),
+ .usedw ( usedw[i]),
+ .almost_empty(chan_empty[i])
+ );
+ end
+ endgenerate
+
+ wire [7:0] debug;
+
+ fifo_1kx16 rx_cmd_fifo (
+ .aclr ( reset ),
+ .clock ( rxclk ),
+ .data ( rx_databus ),
+ .rdreq ( (rd_select == NUM_CHAN) & chan_rdreq ),
+ .wrreq ( rx_WR & rx_WR_enabled),
+ .empty ( cmd_empty),
+ .full ( rx_full[NUM_CHAN] ),
+ .q ( dataout[NUM_CHAN]),
+ .usedw ( usedw[NUM_CHAN] )
+ );
+
+ assign chan_empty[NUM_CHAN] = cmd_empty | rx_WR_enabled;
+ assign chan_fifodata = dataout[rd_select];
+ assign chan_usedw = usedw[rd_select];
+ assign debugbus = {4'd0, rxclk, rxstrobe, rx_full[0], rx_full[1], sel, wr};
+
+endmodule
Modified: gnuradio/trunk/usrp/fpga/inband_lib/tx_buffer_inband.v
===================================================================
--- gnuradio/trunk/usrp/fpga/inband_lib/tx_buffer_inband.v 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/fpga/inband_lib/tx_buffer_inband.v 2008-04-30
03:52:31 UTC (rev 8295)
@@ -1,224 +1,143 @@
module tx_buffer_inband
- ( usbclk, bus_reset, reset, usbdata, WR, have_space,
- channels, tx_i_0, tx_q_0, tx_i_1, tx_q_1,
- tx_i_2, tx_q_2, tx_i_3, tx_q_3, txclk, txstrobe,
- clear_status, tx_empty, debugbus,
- rx_databus, rx_WR, rx_WR_done, rx_WR_enabled, reg_io_enable,
- reg_data_in, reg_data_out, reg_addr, rssi_0, rssi_1, rssi_2,
- rssi_3, rssi_wait, threshhold, tx_underrun
- );
+ ( //System
+ input wire usbclk, input wire bus_reset, input wire reset,
+ input wire [15:0] usbdata, output wire have_space, input wire [3:0]
channels,
+ //output transmit signals
+ output wire [15:0] tx_i_0, output wire [15:0] tx_q_0,
+ output wire [15:0] tx_i_1, output wire [15:0] tx_q_1,
+ output wire [15:0] tx_i_2, output wire [15:0] tx_q_2,
+ output wire [15:0] tx_i_3, output wire [15:0] tx_q_3,
+ input wire txclk, input wire txstrobe, input wire WR,
+ input wire clear_status, output wire tx_empty, output wire [15:0]
debugbus,
+ //command reader io
+ output wire [15:0] rx_databus, output wire rx_WR, output wire rx_WR_done,
+ input wire rx_WR_enabled,
+ //register io
+ output wire [1:0] reg_io_enable, output wire [31:0] reg_data_in, output
wire [6:0] reg_addr,
+ input wire [31:0] reg_data_out,
+ //input characteristic signals
+ input wire [31:0] rssi_0, input wire [31:0] rssi_1, input wire [31:0]
rssi_2,
+ input wire [31:0] rssi_3, input wire [31:0] rssi_wait, input wire [31:0]
threshhold,
+ output wire [1:0] tx_underrun,
+ //system stop
+ output wire stop, output wire [15:0] stop_time);
- parameter NUM_CHAN = 2 ;
- /* Debug paramters */
- parameter STROBE_RATE_0 = 8'd1 ;
- parameter STROBE_RATE_1 = 8'd2 ;
+ parameter NUM_CHAN = 1 ;
- input wire usbclk ;
- input wire bus_reset ; // Used here for the 257-Hack to
fix the FX2 bug
- input wire reset ; // standard DSP-side reset
- input wire [15:0] usbdata ;
- input wire WR ;
- input wire txclk ;
- input wire txstrobe ;
- input wire rx_WR_enabled;
- /* Not used yet */
- input wire [3:0] channels ;
- input wire clear_status ;
- /*register io*/
- input wire [31:0]reg_data_out;
- // rssi
- input wire [31:0]rssi_0;
- input wire [31:0]rssi_1;
- input wire [31:0]rssi_2;
- input wire [31:0]rssi_3;
- input wire [31:0]threshhold;
- input wire [31:0]rssi_wait;
-
- output wire have_space ;
- output wire tx_empty ;
- output wire [15:0] tx_i_0 ;
- output wire [15:0] tx_q_0 ;
- output wire [15:0] tx_i_1 ;
- output wire [15:0] tx_q_1 ;
- output wire [15:0] debugbus ;
- /* Not used yet */
- output wire [15:0] tx_i_2 ;
- output wire [15:0] tx_q_2 ;
- output wire [15:0] tx_i_3 ;
- output wire [15:0] tx_q_3 ;
-
- output wire [15:0] rx_databus ;
- output wire rx_WR;
- output wire rx_WR_done;
- /* reg_io */
- output wire [31:0] reg_data_in;
- output wire [6:0] reg_addr;
- output wire [1:0] reg_io_enable;
- output wire [NUM_CHAN-1:0] tx_underrun;
-
- /* To generate channel readers */
- genvar i ;
+ /* To generate channel readers */
+ genvar i ;
- /* These will eventually be external register */
- reg [31:0] adc_time ;
- wire [7:0] txstrobe_rate [NUM_CHAN-1:0] ;
- wire [31:0] rssi [3:0];
- assign rssi[0] = rssi_0;
- assign rssi[1] = rssi_1;
- assign rssi[2] = rssi_2;
- assign rssi[3] = rssi_3;
+ /* These will eventually be external register */
+ reg [31:0] timestamp_clock ;
+ wire [7:0] txstrobe_rate [NUM_CHAN-1:0] ;
+ wire [31:0] rssi [3:0];
+ assign rssi[0] = rssi_0;
+ assign rssi[1] = rssi_1;
+ assign rssi[2] = rssi_2;
+ assign rssi[3] = rssi_3;
- always @(posedge txclk)
- if (reset)
- adc_time <= 0;
- else if (txstrobe)
- adc_time <= adc_time + 1;
+ always @(posedge txclk)
+ if (reset)
+ timestamp_clock <= 0;
+ else
+ timestamp_clock <= timestamp_clock + 1;
/* Connections between tx_usb_fifo_reader and
cnannel/command processing blocks */
- wire [31:0] tx_data_bus ;
- wire [NUM_CHAN:0] chan_WR ;
- wire [NUM_CHAN:0] chan_done ;
+ wire [31:0] tx_data_bus ;
+ wire [NUM_CHAN:0] chan_WR ;
+ wire [NUM_CHAN:0] chan_done ;
/* Connections between data block and the
FX2/TX chains */
- wire [NUM_CHAN:0] chan_underrun ;
- wire [NUM_CHAN:0] chan_txempty ;
+ wire [NUM_CHAN:0] chan_underrun;
+ wire [NUM_CHAN:0] chan_txempty;
- /* Conections between tx_data_packet_fifo and
+ /* Conections between tx_data_packet_fifo and
its reader + strobe generator */
- wire [31:0] chan_fifodata [NUM_CHAN:0] ;
- wire chan_pkt_waiting [NUM_CHAN:0] ;
- wire chan_rdreq [NUM_CHAN:0] ;
- wire chan_skip [NUM_CHAN:0] ;
- wire [NUM_CHAN:0] chan_have_space ;
- wire chan_txstrobe [NUM_CHAN-1:0] ;
+ wire [31:0] chan_fifodata [NUM_CHAN:0] ;
+ wire chan_pkt_waiting [NUM_CHAN:0] ;
+ wire chan_rdreq [NUM_CHAN:0] ;
+ wire chan_skip [NUM_CHAN:0] ;
+ wire chan_have_space [NUM_CHAN:0] ;
- wire [14:0] debug;
+ wire [14:0] debug [NUM_CHAN:0];
- /* Outputs to transmit chains */
- wire [15:0] tx_i [NUM_CHAN-1:0] ;
- wire [15:0] tx_q [NUM_CHAN-1:0] ;
+ /* Outputs to transmit chains */
+ wire [15:0] tx_i [NUM_CHAN:0] ;
+ wire [15:0] tx_q [NUM_CHAN:0] ;
+
+ assign tx_i[NUM_CHAN] = 0;
+ assign tx_q[NUM_CHAN] = 0;
- /* TODO: Figure out how to write this genericly */
- assign have_space = chan_have_space[0] & chan_have_space[1];
- assign tx_empty = chan_txempty[0] & chan_txempty[1] ;
- assign tx_i_0 = chan_txempty[0] ? 16'b0 : tx_i[0] ;
- assign tx_q_0 = chan_txempty[0] ? 16'b0 : tx_q[0] ;
- assign tx_i_1 = chan_txempty[1] ? 16'b0 : tx_i[1] ;
- assign tx_q_1 = chan_txempty[1] ? 16'b0 : tx_q[1] ;
+ assign have_space = chan_have_space[0] & chan_have_space[1];
+ assign tx_empty = chan_txempty[0] & chan_txempty[1] ;
+
+ assign tx_i_0 = chan_txempty[0] ? 16'b0 : tx_i[0] ;
+ assign tx_q_0 = chan_txempty[0] ? 16'b0 : tx_q[0] ;
+ assign tx_i_1 = chan_txempty[1] ? 16'b0 : tx_i[1] ;
+ assign tx_q_1 = chan_txempty[1] ? 16'b0 : tx_q[1] ;
- /* Debug statement */
- assign txstrobe_rate[0] = STROBE_RATE_0 ;
- assign txstrobe_rate[1] = STROBE_RATE_1 ;
- assign tx_q_2 = 16'b0 ;
- assign tx_i_2 = 16'b0 ;
- assign tx_q_3 = 16'b0 ;
- assign tx_i_3 = 16'b0 ;
- assign tx_i_3 = 16'b0 ;
+ assign tx_q_2 = 16'b0 ;
+ assign tx_i_2 = 16'b0 ;
+ assign tx_q_3 = 16'b0 ;
+ assign tx_i_3 = 16'b0 ;
+ assign tx_i_3 = 16'b0 ;
- assign debugbus = {debug, txclk};
+ assign debugbus = {have_space, txclk, WR, WR_final, chan_WR, chan_done,
+ chan_pkt_waiting[0], chan_pkt_waiting[1],
+ chan_rdreq[0], chan_rdreq[1], chan_txempty[0],
chan_txempty[1]};
- wire [31:0] usbdata_final;
- wire WR_final;
+ wire [31:0] usbdata_final;
+ wire WR_final;
- tx_packer tx_usb_packer
- (
- .bus_reset (bus_reset),
- .usbclk (usbclk),
- .WR_fx2 (WR),
- .usbdata (usbdata),
- .reset (reset),
- .txclk (txclk),
- .usbdata_final (usbdata_final),
- .WR_final (WR_final)
- );
+ tx_packer tx_usb_packer
+ (.bus_reset(bus_reset), .usbclk(usbclk), .WR_fx2(WR),
+ .usbdata(usbdata), .reset(reset), .txclk(txclk),
+ .usbdata_final(usbdata_final), .WR_final(WR_final));
- channel_demux channel_demuxer
- (
- .usbdata_final (usbdata_final),
- .WR_final (WR_final),
- .reset (reset),
- .txclk (txclk),
- .WR_channel (chan_WR),
- .WR_done_channel (chan_done),
- .ram_data (tx_data_bus)
- );
+ channel_demux #(NUM_CHAN) channel_demuxer
+ (.usbdata_final(usbdata_final), .WR_final(WR_final),
+ .reset(reset), .txclk(txclk), .WR_channel(chan_WR),
+ .WR_done_channel(chan_done), .ram_data(tx_data_bus));
- generate for (i = 0 ; i < NUM_CHAN; i = i + 1)
- begin : generate_channel_readers
- assign tx_underrun[i] = chan_underrun[i];
- channel_ram tx_data_packet_fifo
- ( .reset (reset),
- .txclk (txclk),
- .datain (tx_data_bus),
- .WR (chan_WR[i]),
- .WR_done (chan_done[i]),
- .have_space (chan_have_space[i]),
- .dataout (chan_fifodata[i]),
- .packet_waiting (chan_pkt_waiting[i]),
- .RD (chan_rdreq[i]),
- .RD_done (chan_skip[i])
- );
+ generate for (i = 0 ; i < NUM_CHAN; i = i + 1)
+ begin : generate_channel_readers
+ assign tx_underrun[i] = chan_underrun[i];
- chan_fifo_reader tx_chan_reader
- ( .reset (reset),
- .tx_clock (txclk),
- .tx_strobe (txstrobe),
- .adc_time (adc_time),
- .samples_format (4'b0),
- .tx_q (tx_q[i]),
- .tx_i (tx_i[i]),
- .underrun (chan_underrun[i]),
- .skip (chan_skip[i]),
- .rdreq (chan_rdreq[i]),
- .fifodata (chan_fifodata[i]),
- .pkt_waiting (chan_pkt_waiting[i]),
- .tx_empty (chan_txempty[i]),
- .rssi (rssi[i]),
- .threshhold (threshhold),
- .rssi_wait (rssi_wait)
- );
-
+ channel_ram tx_data_packet_fifo
+ (.reset(reset), .txclk(txclk), .datain(tx_data_bus),
+ .WR(chan_WR[i]), .WR_done(chan_done[i]),
+ .have_space(chan_have_space[i]), .dataout(chan_fifodata[i]),
+ .packet_waiting(chan_pkt_waiting[i]), .RD(chan_rdreq[i]),
+ .RD_done(chan_skip[i]));
+
+ chan_fifo_reader tx_chan_reader
+ (.reset(reset), .tx_clock(txclk), .tx_strobe(txstrobe),
+ .timestamp_clock(timestamp_clock), .samples_format(4'b0),
+ .tx_q(tx_q[i]), .tx_i(tx_i[i]), .underrun(chan_underrun[i]),
+ .skip(chan_skip[i]), .rdreq(chan_rdreq[i]),
+ .fifodata(chan_fifodata[i]), .pkt_waiting(chan_pkt_waiting[i]),
+ .tx_empty(chan_txempty[i]), .rssi(rssi[i]), .debug(debug[i]),
+ .threshhold(threshhold), .rssi_wait(rssi_wait));
end
endgenerate
- channel_ram tx_cmd_packet_fifo
- ( .reset (reset),
- .txclk (txclk),
- .datain (tx_data_bus),
- .WR (chan_WR[NUM_CHAN]),
- .WR_done (chan_done[NUM_CHAN]),
- .have_space (chan_have_space[NUM_CHAN]),
- .dataout (chan_fifodata[NUM_CHAN]),
- .packet_waiting (chan_pkt_waiting[NUM_CHAN]),
- .RD (chan_rdreq[NUM_CHAN]),
- .RD_done (chan_skip[NUM_CHAN])
- );
+ channel_ram tx_cmd_packet_fifo
+ (.reset(reset), .txclk(txclk), .datain(tx_data_bus), .WR(chan_WR[NUM_CHAN]),
+ .WR_done(chan_done[NUM_CHAN]), .have_space(chan_have_space[NUM_CHAN]),
+ .dataout(chan_fifodata[NUM_CHAN]),
.packet_waiting(chan_pkt_waiting[NUM_CHAN]),
+ .RD(chan_rdreq[NUM_CHAN]), .RD_done(chan_skip[NUM_CHAN]));
-
- cmd_reader tx_cmd_reader
- ( .reset (reset),
- .txclk (txclk),
- .adc_time
(adc_time),
- .skip
(chan_skip[NUM_CHAN]),
- .rdreq
(chan_rdreq[NUM_CHAN]),
- .fifodata
(chan_fifodata[NUM_CHAN]),
- .pkt_waiting
(chan_pkt_waiting[NUM_CHAN]),
- .rx_databus
(rx_databus),
- .rx_WR (rx_WR),
- .rx_WR_done
(rx_WR_done),
- .rx_WR_enabled (rx_WR_enabled),
- .reg_data_in (reg_data_in),
- .reg_data_out (reg_data_out),
- .reg_addr
(reg_addr),
- .reg_io_enable (reg_io_enable),
- .debug (debug)
- );
-
-
-
+ cmd_reader tx_cmd_reader
+ (.reset(reset), .txclk(txclk), .timestamp_clock(timestamp_clock),
.skip(chan_skip[NUM_CHAN]),
+ .rdreq(chan_rdreq[NUM_CHAN]), .fifodata(chan_fifodata[NUM_CHAN]),
+ .pkt_waiting(chan_pkt_waiting[NUM_CHAN]), .rx_databus(rx_databus),
+ .rx_WR(rx_WR), .rx_WR_done(rx_WR_done), .rx_WR_enabled(rx_WR_enabled),
+ .reg_data_in(reg_data_in), .reg_data_out(reg_data_out),
.reg_addr(reg_addr),
+ .reg_io_enable(reg_io_enable), .debug(debug[NUM_CHAN]), .stop(stop),
.stop_time(stop_time));
+
endmodule // tx_buffer
Deleted: gnuradio/trunk/usrp/fpga/inband_lib/usb_fifo_reader.v
Deleted: gnuradio/trunk/usrp/fpga/inband_lib/usb_fifo_writer.v
Modified: gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.bsf
===================================================================
--- gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.bsf 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.bsf 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -95,7 +95,7 @@
)
(drawing
(text "16 bits x 1024 words" (rect 58 132 144 144)(font "Arial"
))
- (text "almost_empty < 126" (rect 58 122 144 134)(font "Arial" ))
+ (text "almost_empty < 504" (rect 58 122 144 134)(font "Arial" ))
(line (pt 16 16)(pt 144 16)(line_width 1))
(line (pt 144 16)(pt 144 144)(line_width 1))
(line (pt 144 144)(pt 16 144)(line_width 1))
Modified: gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.v
===================================================================
--- gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.v 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16.v 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -86,7 +86,7 @@
);
defparam
scfifo_component.add_ram_output_register = "OFF",
- scfifo_component.almost_empty_value = 126,
+ scfifo_component.almost_empty_value = 504,
scfifo_component.intended_device_family = "Cyclone",
scfifo_component.lpm_hint = "RAM_BLOCK_TYPE=M4K",
scfifo_component.lpm_numwords = 1024,
@@ -105,7 +105,7 @@
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "1"
-// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "126"
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "504"
// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
@@ -133,7 +133,7 @@
// Retrieval info: PRIVATE: wsFull NUMERIC "1"
// Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
-// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "126"
+// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "504"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: CONSTANT: LPM_HINT STRING "RAM_BLOCK_TYPE=M4K"
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"
Modified: gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16_bb.v
===================================================================
--- gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16_bb.v 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/fpga/megacells/fifo_1kx16_bb.v 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -57,7 +57,7 @@
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "1"
-// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "126"
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "504"
// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
@@ -85,7 +85,7 @@
// Retrieval info: PRIVATE: wsFull NUMERIC "1"
// Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
-// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "126"
+// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "504"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: CONSTANT: LPM_HINT STRING "RAM_BLOCK_TYPE=M4K"
// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"
Modified: gnuradio/trunk/usrp/fpga/rbf/Makefile.am
===================================================================
--- gnuradio/trunk/usrp/fpga/rbf/Makefile.am 2008-04-30 03:50:36 UTC (rev
8294)
+++ gnuradio/trunk/usrp/fpga/rbf/Makefile.am 2008-04-30 03:52:31 UTC (rev
8295)
@@ -26,8 +26,12 @@
rbfs = \
rev2/std_2rxhb_2tx.rbf \
rev2/std_4rx_0tx.rbf \
+ rev2/inband_1rxhb_1tx.rbf \
+ rev2/inband_2rxhb_2tx.rbf \
rev4/std_2rxhb_2tx.rbf \
rev4/std_4rx_0tx.rbf \
+ rev4/inband_1rxhb_1tx.rbf \
+ rev4/inband_2rxhb_2tx.rbf \
rev2/multi_2rxhb_2tx.rbf \
rev4/multi_2rxhb_2tx.rbf
Copied: gnuradio/trunk/usrp/fpga/rbf/rev2/inband_1rxhb_1tx.rbf (from rev 8293,
gnuradio/branches/features/inband-usb/usrp/fpga/rbf/rev2/inband_1rxhb_1tx.rbf)
===================================================================
(Binary files differ)
Copied: gnuradio/trunk/usrp/fpga/rbf/rev2/inband_2rxhb_2tx.rbf (from rev 8293,
gnuradio/branches/features/inband-usb/usrp/fpga/rbf/rev2/inband_2rxhb_2tx.rbf)
===================================================================
(Binary files differ)
Copied: gnuradio/trunk/usrp/fpga/rbf/rev4/inband_1rxhb_1tx.rbf (from rev 8293,
gnuradio/branches/features/inband-usb/usrp/fpga/rbf/rev4/inband_1rxhb_1tx.rbf)
===================================================================
(Binary files differ)
Copied: gnuradio/trunk/usrp/fpga/rbf/rev4/inband_2rxhb_2tx.rbf (from rev 8293,
gnuradio/branches/features/inband-usb/usrp/fpga/rbf/rev4/inband_2rxhb_2tx.rbf)
===================================================================
(Binary files differ)
Modified: gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/config.vh
===================================================================
--- gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/config.vh 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/config.vh 2008-04-30
03:52:31 UTC (rev 8295)
@@ -34,7 +34,7 @@
`include "../include/common_config_1rxhb_1tx.vh"
// Uncomment this for 2 rx channels (w/ halfband) & 2 transmit channels
-//`include "../include/common_config_2rxhb_2tx.vh"
+// `include "../include/common_config_2rxhb_2tx.vh"
// Uncomment this for 4 rx channels (w/o halfband) & 0 transmit channels
//`include "../include/common_config_4rx_0tx.vh"
Modified: gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.qsf
===================================================================
--- gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.qsf
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.qsf
2008-04-30 03:52:31 UTC (rev 8295)
@@ -27,7 +27,7 @@
# ========================
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 3.0
set_global_assignment -name PROJECT_CREATION_TIME_DATE "00:14:04 JULY 13,
2003"
-set_global_assignment -name LAST_QUARTUS_VERSION "5.1 SP1"
+set_global_assignment -name LAST_QUARTUS_VERSION "7.2 SP2"
# Pin & Location Assignments
# ==========================
@@ -392,7 +392,6 @@
set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_rom.v
set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/halfband_decim.v
set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/mac.v
-set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_ram.v
set_global_assignment -name VERILOG_FILE ../../sdr_lib/tx_chain.v
set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_dcoffset.v
set_global_assignment -name VERILOG_FILE ../../sdr_lib/adc_interface.v
@@ -419,4 +418,6 @@
set_global_assignment -name VERILOG_FILE ../../sdr_lib/strobe_gen.v
set_global_assignment -name VERILOG_FILE ../../sdr_lib/sign_extend.v
set_global_assignment -name VERILOG_FILE ../../inband_lib/channel_ram.v
-set_global_assignment -name VERILOG_FILE ../../inband_lib/register_io.v
\ No newline at end of file
+set_global_assignment -name VERILOG_FILE ../../inband_lib/register_io.v
+set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"
+set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"
\ No newline at end of file
Modified: gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.v
===================================================================
--- gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.v
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.v
2008-04-30 03:52:31 UTC (rev 8295)
@@ -97,8 +97,6 @@
// Tri-state bus macro
bustri bustri( .data(usbdata_out),.enabledt(OE),.tridata(usbdata) );
- assign clk64 = master_clk;
-
wire [15:0] ch0tx,ch1tx,ch2tx,ch3tx; //,ch4tx,ch5tx,ch6tx,ch7tx;
wire [15:0] ch0rx,ch1rx,ch2rx,ch3rx,ch4rx,ch5rx,ch6rx,ch7rx;
@@ -129,19 +127,7 @@
assign bb_tx_q0 = ch1tx;
assign bb_tx_i1 = ch2tx;
assign bb_tx_q1 = ch3tx;
-
-wire [6:0] reg_addr;
-wire [31:0] reg_data_out;
-wire [31:0] reg_data_in;
-wire [1:0] reg_io_enable;
-wire [31:0] rssi_threshhold;
-wire [31:0] rssi_wait;
-register_io register_control
-(.clk(clk64),.reset(1'b0),.enable(reg_io_enable),.addr(reg_addr),.datain(reg_data_in),
- .dataout(reg_data_out),.rssi_0(rssi_0), .rssi_1(rssi_1), .rssi_2(rssi_2),
- .rssi_3(rssi_3), .threshhold(rssi_threshhold), .rssi_wait(rssi_wait));
-wire [1:0] tx_overrun;
wire [1:0] tx_underrun;
`ifdef TX_IN_BAND
@@ -164,9 +150,15 @@
.reg_data_out(reg_data_out),
.reg_data_in(reg_data_in),
.reg_io_enable(reg_io_enable),
- .debugbus(),
+ .debugbus(rx_debugbus),
.rssi_0(rssi_0), .rssi_1(rssi_1), .rssi_2(rssi_2),
- .rssi_3(rssi_3), .threshhold(rssi_threshhold), .rssi_wait(rssi_wait));
+ .rssi_3(rssi_3), .threshhold(rssi_threshhold), .rssi_wait(rssi_wait),
+ .stop(stop), .stop_time(stop_time));
+
+ `ifdef TX_DUAL
+ defparam tx_buffer.NUM_CHAN=2;
+ `endif
+
`else
tx_buffer tx_buffer
( .usbclk(usbclk),.bus_reset(tx_bus_reset),.reset(tx_dsp_reset),
@@ -276,14 +268,18 @@
.ch_6(ch6rx),.ch_7(ch7rx),
.rxclk(clk64),.rxstrobe(hb_strobe),
.clear_status(clear_status),
-
.serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
.rx_WR(rx_WR),
.rx_databus(rx_databus),
.rx_WR_done(rx_WR_done),
.rx_WR_enabled(rx_WR_enabled),
.debugbus(tx_debugbus),
.rssi_0(rssi_0), .rssi_1(rssi_1), .rssi_2(rssi_2), .rssi_3(rssi_3),
- .tx_overrun(tx_overrun), .tx_underrun(tx_underrun));
+ .tx_underrun(tx_underrun));
+
+ `ifdef RX_DUAL
+ defparam rx_buffer.NUM_CHAN=2;
+ `endif
+
`else
rx_buffer rx_buffer
( .usbclk(usbclk),.bus_reset(rx_bus_reset),.reset(rx_dsp_reset),
@@ -357,11 +353,52 @@
serial_io serial_io
( .master_clk(clk64),.serial_clock(SCLK),.serial_data_in(SDI),
.enable(SEN_FPGA),.reset(1'b0),.serial_data_out(SDO),
-
.serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+ .serial_addr(addr_db),.serial_data(data_db),.serial_strobe(strobe_db),
.readback_0({io_rx_a,io_tx_a}),.readback_1({io_rx_b,io_tx_b}),.readback_2(capabilities),.readback_3(32'hf0f0931a),
.readback_4(rssi_0),.readback_5(rssi_1),.readback_6(rssi_2),.readback_7(rssi_3)
);
+ wire [6:0] reg_addr;
+ wire [31:0] reg_data_out;
+ wire [31:0] reg_data_in;
+ wire [1:0] reg_io_enable;
+ wire [31:0] rssi_threshhold;
+ wire [31:0] rssi_wait;
+ wire [6:0] addr_wr;
+ wire [31:0] data_wr;
+ wire strobe_wr;
+ wire [6:0] addr_db;
+ wire [31:0] data_db;
+ wire strobe_db;
+ assign serial_strobe = strobe_db | strobe_wr;
+ assign serial_addr = (strobe_db)? (addr_db) : (addr_wr);
+ assign serial_data = (strobe_db)? (data_db) : (data_wr);
+ //assign serial_strobe = strobe_wr;
+ //assign serial_data = data_wr;
+ //assign serial_addr = addr_wr;
+
+ register_io register_control
+
(.clk(clk64),.reset(1'b0),.enable(reg_io_enable),.addr(reg_addr),.datain(reg_data_in),
+ .dataout(reg_data_out), .addr_wr(addr_wr), .data_wr(data_wr),
.strobe_wr(strobe_wr),
+ .rssi_0(rssi_0), .rssi_1(rssi_1), .rssi_2(rssi_2),
+ .rssi_3(rssi_3), .threshhold(rssi_threshhold), .rssi_wait(rssi_wait),
+ .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3),
+ .debug_en(debug_en), .misc(settings),
+ .txmux({dac3mux,dac2mux,dac1mux,dac0mux,tx_realsignals,tx_numchan}));
+
+
+ //implementing freeze mode
+ reg [15:0] timestop;
+ wire stop;
+ wire [15:0] stop_time;
+ assign clk64 = (timestop == 0) ? master_clk : 0;
+ always @(posedge master_clk)
+ if (timestop[15:0] != 0)
+ timestop <= timestop - 16'd1;
+ else if (stop)
+ timestop <= stop_time;
+
+
wire [15:0] reg_0,reg_1,reg_2,reg_3;
master_control master_control
( .master_clk(clk64),.usbclk(usbclk),
@@ -374,8 +411,8 @@
.rx_sample_strobe(rx_sample_strobe),.strobe_decim(strobe_decim),
.tx_empty(tx_empty),
//.debug_0(rx_a_a),.debug_1(ddc0_in_i),
- .debug_0(tx_debugbus),.debug_1(tx_debugbus),
-
.debug_2({rx_sample_strobe,strobe_decim,serial_strobe,serial_addr}),.debug_3({rx_dsp_reset,tx_dsp_reset,rx_bus_reset,tx_bus_reset,enable_rx,(tx_underrun
== 0),rx_overrun,decim_rate}),
+ .debug_0(rx_debugbus),.debug_1(ddc0_in_i),
+
.debug_2({rx_sample_strobe,strobe_decim,serial_strobe,serial_addr}),.debug_3({rx_dsp_reset,tx_dsp_reset,rx_bus_reset,tx_bus_reset,enable_rx,tx_underrun,rx_overrun,decim_rate}),
.reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3) );
io_pins io_pins
Property changes on: gnuradio/trunk/usrp/host/apps-inband
___________________________________________________________________
Name: svn:ignore
- Makefile
Makefile.in
.la
.lo
.deps
.libs
*.la
*.lo
*.dat
.*.swp
usrper
usrper2
test_input
test_fusb
test_usrp
test_usrp0
test_usrp_standard_rx
test_usrp_standard_tx
test_usrp_inband_timestamps
test_usrp_inband_registers
test_usrp_inband_rx
test_usrp_inband_tx
test_usrp_basic_rx
check_order_quickly
usrp_cal_dc_offset
test_usrp_inband_cs
read_packets
test_usrp_inband_ping
test_usrp_inband_underrun
test_usrp_inband_overrun
gmac_mbh.cc
test_gmac_tx
+ Makefile
Makefile.in
.la
.lo
.deps
.libs
*.la
*.lo
*.dat
.*.swp
usrper
usrper2
test_input
test_fusb
test_usrp
test_usrp0
test_usrp_standard_rx
test_usrp_standard_tx
test_usrp_standard_2tx
test_usrp_inband_timestamps
test_usrp_inband_registers
test_usrp_inband_rx
test_usrp_inband_2rx
test_usrp_inband_tx
test_usrp_inband_2tx
test_usrp_basic_rx
check_order_quickly
usrp_cal_dc_offset
test_usrp_inband_cs
read_packets
test_usrp_inband_ping
test_usrp_inband_underrun
test_usrp_inband_overrun
gmac_mbh.cc
test_gmac_tx
Modified: gnuradio/trunk/usrp/host/apps-inband/Makefile.am
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/Makefile.am 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/apps-inband/Makefile.am 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -30,46 +30,31 @@
bin_PROGRAMS =
noinst_PROGRAMS = \
- test_usrp_inband_cs \
test_usrp_inband_ping \
test_usrp_inband_registers \
test_usrp_inband_rx \
+ test_usrp_inband_2rx \
test_usrp_inband_tx \
+ test_usrp_inband_2tx \
test_usrp_inband_timestamps \
test_usrp_inband_overrun \
test_usrp_inband_underrun \
- test_gmac_tx \
read_packets
noinst_HEADERS = \
ui_nco.h \
- ui_sincos.h \
- gmac.h \
- gmac_symbols.h
+ ui_sincos.h
-EXTRA_DIST = \
- gmac.mbh
-
-#------------------------------------------------------------------
-# Build gmac sources
-
-BUILT_SOURCES = \
- gmac_mbh.cc
-
-gmac_mbh.cc : gmac.mbh
- $(COMPILE_MBH) $(srcdir)/gmac.mbh gmac_mbh.cc
-
-
-test_usrp_inband_cs_SOURCES = test_usrp_inband_cs.cc ui_sincos.c
-test_usrp_inband_cs_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
-
test_usrp_inband_ping_SOURCES = test_usrp_inband_ping.cc
test_usrp_inband_ping_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
test_usrp_inband_tx_SOURCES = test_usrp_inband_tx.cc ui_sincos.c
test_usrp_inband_tx_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
+test_usrp_inband_2tx_SOURCES = test_usrp_inband_2tx.cc ui_sincos.c
+test_usrp_inband_2tx_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
+
test_usrp_inband_timestamps_SOURCES = test_usrp_inband_timestamps.cc
ui_sincos.c
test_usrp_inband_timestamps_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
@@ -85,8 +70,8 @@
test_usrp_inband_rx_SOURCES = test_usrp_inband_rx.cc ui_sincos.c
test_usrp_inband_rx_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
-test_gmac_tx_SOURCES = test_gmac_tx.cc gmac.cc gmac_mbh.cc ui_sincos.c
-test_gmac_tx_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
+test_usrp_inband_2rx_SOURCES = test_usrp_inband_2rx.cc ui_sincos.c
+test_usrp_inband_2rx_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
read_packets_SOURCES = read_packets.cc
read_packets_LDADD = $(USRP_LA) $(USRP_INBAND_LA)
Deleted: gnuradio/trunk/usrp/host/apps-inband/gmac.cc
Deleted: gnuradio/trunk/usrp/host/apps-inband/gmac.h
Deleted: gnuradio/trunk/usrp/host/apps-inband/gmac.mbh
Deleted: gnuradio/trunk/usrp/host/apps-inband/gmac_symbols.h
Deleted: gnuradio/trunk/usrp/host/apps-inband/test_gmac_tx.cc
Copied: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2rx.cc (from rev
8293,
gnuradio/branches/features/inband-usb/usrp/host/apps-inband/test_usrp_inband_2rx.cc)
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2rx.cc
(rev 0)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2rx.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -0,0 +1,371 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mb_mblock.h>
+#include <mb_runtime.h>
+#include <mb_runtime_nop.h> // QA only
+#include <mb_protocol_class.h>
+#include <mb_exception.h>
+#include <mb_msg_queue.h>
+#include <mb_message.h>
+#include <mb_mblock_impl.h>
+#include <mb_msg_accepter.h>
+#include <mb_class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+// Include the symbols needed for communication with USRP server
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_rx.h>
+
+static bool verbose = true;
+
+class test_usrp_rx : public mb_mblock
+{
+ mb_port_sptr d_rx;
+ mb_port_sptr d_cs;
+ pmt_t d_rx_chan0, d_rx_chan1;
+
+ enum state_t {
+ INIT,
+ OPENING_USRP,
+ ALLOCATING_CHANNEL,
+ RECEIVING,
+ CLOSING_CHANNEL,
+ CLOSING_USRP,
+ };
+
+ state_t d_state;
+
+ std::ofstream d_ofile;
+
+ long d_samples_recvd;
+ long d_samples_to_recv;
+
+ public:
+ test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t
user_arg);
+ ~test_usrp_rx();
+ void initial_transition();
+ void handle_message(mb_message_sptr msg);
+
+ protected:
+ void open_usrp();
+ void close_usrp();
+ void allocate_channel();
+ void send_packets();
+ void enter_receiving();
+ void build_and_send_next_frame();
+ void handle_response_recv_raw_samples(pmt_t invocation_handle);
+ void enter_closing_channel();
+};
+
+test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string
&instance_name, pmt_t user_arg)
+ : mb_mblock(runtime, instance_name, user_arg),
+ d_rx_chan0(PMT_NIL), d_rx_chan1(PMT_NIL),
+ d_samples_recvd(0),
+ d_samples_to_recv(20e6)
+{
+ d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+ d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+ // Pass a dictionary to usrp_server which specifies which interface to use,
the stub or USRP
+ pmt_t usrp_dict = pmt_make_dict();
+
+ // To test the application without a USRP
+ bool fake_usrp_p = false;
+ if(fake_usrp_p) {
+ pmt_dict_set(usrp_dict,
+ pmt_intern("fake-usrp"),
+ PMT_T);
+ }
+
+ // Specify the RBF to use
+ pmt_dict_set(usrp_dict,
+ pmt_intern("rbf"),
+ pmt_intern("inband_2rxhb_2tx.rbf"));
+
+ pmt_dict_set(usrp_dict,
+ pmt_intern("decim-rx"),
+ pmt_from_long(64));
+
+ define_component("server", "usrp_server", usrp_dict);
+
+ connect("self", "rx0", "server", "rx0");
+ connect("self", "cs", "server", "cs");
+
+}
+
+test_usrp_rx::~test_usrp_rx()
+{
+}
+
+void
+test_usrp_rx::initial_transition()
+{
+ open_usrp();
+}
+
+void
+test_usrp_rx::handle_message(mb_message_sptr msg)
+{
+ pmt_t event = msg->signal();
+ pmt_t data = msg->data();
+
+ pmt_t handle = PMT_F;
+ pmt_t status = PMT_F;
+ std::string error_msg;
+
+ switch(d_state){
+
+ //----------------------------- OPENING_USRP ----------------------------//
+ // We only expect a response from opening the USRP which should be
succesful
+ // or failed.
+ case OPENING_USRP:
+ if (pmt_eq(event, s_response_open)){
+ status = pmt_nth(1, data);
+ if (pmt_eq(status, PMT_T)){
+ allocate_channel();
+ return;
+ }
+ else {
+ error_msg = "failed to open usrp:";
+ goto bail;
+ }
+ }
+ goto unhandled;
+
+ //----------------------- ALLOCATING CHANNELS --------------------//
+ // Allocate an RX channel to perform the overrun test.
+ case ALLOCATING_CHANNEL:
+ if (pmt_eq(event, s_response_allocate_channel)){
+ status = pmt_nth(1, data);
+ if(pmt_eqv(d_rx_chan0, PMT_NIL))
+ d_rx_chan0 = pmt_nth(2, data);
+ else
+ d_rx_chan1 = pmt_nth(2, data);
+
+ if (pmt_eq(status, PMT_T) && !pmt_eqv(d_rx_chan1, PMT_NIL)){
+ enter_receiving();
+ return;
+ }
+ else if(pmt_eq(status, PMT_F)){
+ error_msg = "failed to allocate channel:";
+ goto bail;
+ }
+ return;
+ }
+ goto unhandled;
+
+ //--------------------------- RECEIVING ------------------------------//
+ // In the receiving state, we receive samples until the specified amount
+ // while counting the number of overruns.
+ case RECEIVING:
+ if (pmt_eq(event, s_response_recv_raw_samples)){
+ status = pmt_nth(1, data);
+
+ if (pmt_eq(status, PMT_T)){
+ handle_response_recv_raw_samples(data);
+ return;
+ }
+ else {
+ error_msg = "bad response-xmit-raw-frame:";
+ goto bail;
+ }
+ }
+ goto unhandled;
+
+ //------------------------- CLOSING CHANNEL ----------------------------//
+ // Check deallocation response for the RX channel
+ case CLOSING_CHANNEL:
+ if (pmt_eq(event, s_response_deallocate_channel)){
+ status = pmt_nth(1, data);
+
+ if (pmt_eq(status, PMT_T)){
+ close_usrp();
+ return;
+ }
+ else {
+ error_msg = "failed to deallocate channel:";
+ goto bail;
+ }
+ }
+
+ // Alternately, we ignore all response recv samples while waiting for the
+ // channel to actually close
+ if (pmt_eq(event, s_response_recv_raw_samples))
+ return;
+
+ goto unhandled;
+
+ //--------------------------- CLOSING USRP ------------------------------//
+ // Once we have received a successful USRP close response, we shutdown all
+ // mblocks and exit.
+ case CLOSING_USRP:
+ if (pmt_eq(event, s_response_close)){
+ status = pmt_nth(1, data);
+
+ if (pmt_eq(status, PMT_T)){
+ fflush(stdout);
+ shutdown_all(PMT_T);
+ return;
+ }
+ else {
+ error_msg = "failed to close USRP:";
+ goto bail;
+ }
+ }
+ goto unhandled;
+
+ default:
+ goto unhandled;
+ }
+ return;
+
+ // An error occured, print it, and shutdown all m-blocks
+ bail:
+ std::cerr << error_msg << data
+ << "status = " << status << std::endl;
+ shutdown_all(PMT_F);
+ return;
+
+ // Received an unhandled message for a specific state
+ unhandled:
+ if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
+ std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+ << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_rx::open_usrp()
+{
+ pmt_t which_usrp = pmt_from_long(0);
+
+ d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+ d_state = OPENING_USRP;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_RX] Opening the USRP\n";
+}
+
+void
+test_usrp_rx::close_usrp()
+{
+
+ d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+ d_state = CLOSING_USRP;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_RX] Closing the USRP\n";
+}
+
+void
+test_usrp_rx::allocate_channel()
+{
+ long capacity = (long) 16e6;
+ d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T,
pmt_from_long(capacity)));
+ d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T,
pmt_from_long(capacity)));
+ d_state = ALLOCATING_CHANNEL;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_RX] Requesting RX channel allocation\n";
+}
+
+void
+test_usrp_rx::enter_receiving()
+{
+ d_state = RECEIVING;
+
+ d_rx->send(s_cmd_start_recv_raw_samples,
+ pmt_list2(PMT_F,
+ d_rx_chan0));
+
+ d_rx->send(s_cmd_start_recv_raw_samples,
+ pmt_list2(PMT_F,
+ d_rx_chan1));
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_RX] Receiving...\n";
+}
+
+void
+test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
+{
+ pmt_t invocation_handle = pmt_nth(0, data);
+ pmt_t status = pmt_nth(1, data);
+ pmt_t v_samples = pmt_nth(2, data);
+ pmt_t timestamp = pmt_nth(3, data);
+ pmt_t channel = pmt_nth(4, data);
+ pmt_t properties = pmt_nth(5, data);
+
+ d_samples_recvd += pmt_length(v_samples) / 4;
+
+ // Check for overrun
+ if(!pmt_is_dict(properties)) {
+ std::cout << "[TEST_USRP_INBAND_RX] Recv samples dictionary is improper\n";
+ return;
+ }
+
+ // Check if the number samples we have received meets the test
+ if(d_samples_recvd >= d_samples_to_recv) {
+ d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan0));
+ d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan1));
+ enter_closing_channel();
+ return;
+ }
+
+}
+
+void
+test_usrp_rx::enter_closing_channel()
+{
+ d_state = CLOSING_CHANNEL;
+
+ d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan0));
+ d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan1));
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_RX] Deallocating RX channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_rx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+ mb_runtime_sptr rt = mb_make_runtime();
+ pmt_t result = PMT_NIL;
+
+ rt->run("top", "test_usrp_rx", PMT_F, &result);
+
+}
Copied: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2tx.cc (from rev
8293,
gnuradio/branches/features/inband-usb/usrp/host/apps-inband/test_usrp_inband_2tx.cc)
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2tx.cc
(rev 0)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_2tx.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -0,0 +1,430 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mb_mblock.h>
+#include <mb_runtime.h>
+#include <mb_runtime_nop.h> // QA only
+#include <mb_protocol_class.h>
+#include <mb_exception.h>
+#include <mb_msg_queue.h>
+#include <mb_message.h>
+#include <mb_mblock_impl.h>
+#include <mb_msg_accepter.h>
+#include <mb_class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+#include <ui_nco.h>
+#include <symbols_usrp_server_cs.h>
+#include <symbols_usrp_channel.h>
+#include <symbols_usrp_low_level_cs.h>
+#include <symbols_usrp_tx.h>
+
+static bool verbose = true;
+
+class test_usrp_tx : public mb_mblock
+{
+ mb_port_sptr d_tx;
+ mb_port_sptr d_cs;
+ pmt_t d_tx_chan0, d_tx_chan1;
+
+ enum state_t {
+ INIT,
+ OPENING_USRP,
+ ALLOCATING_CHANNEL,
+ TRANSMITTING,
+ CLOSING_CHANNEL,
+ CLOSING_USRP,
+ };
+
+ state_t d_state;
+ long d_nsamples_to_send;
+ long d_nsamples_xmitted;
+ long d_nframes_xmitted;
+ long d_samples_per_frame;
+ bool d_done_sending;
+
+ // for generating sine wave output
+ ui_nco<float,float> d_nco;
+ double d_amplitude;
+
+ public:
+ test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t
user_arg);
+ ~test_usrp_tx();
+ void initial_transition();
+ void handle_message(mb_message_sptr msg);
+
+ protected:
+ void open_usrp();
+ void close_usrp();
+ void allocate_channel();
+ void send_packets();
+ void enter_transmitting();
+ void build_and_send_next_frame();
+ void handle_xmit_response(pmt_t invocation_handle);
+ void enter_closing_channel();
+};
+
+test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string
&instance_name, pmt_t user_arg)
+ : mb_mblock(runtime, instance_name, user_arg),
+ d_tx_chan0(PMT_NIL), d_tx_chan1(PMT_NIL),
+ d_state(INIT), d_nsamples_to_send((long) 80e6),
+ d_nsamples_xmitted(0),
+ d_nframes_xmitted(0),
+ d_samples_per_frame((long)(126 * 4)), // full packet
+ d_done_sending(false),
+ d_amplitude(16384)
+{
+ // std::cout << "[TEST_USRP_TX] 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);
+
+ //bool fake_usrp_p = true;
+ bool fake_usrp_p = false;
+
+ // Test the TX side
+
+ pmt_t usrp_dict = pmt_make_dict();
+
+ if(fake_usrp_p) {
+ pmt_dict_set(usrp_dict,
+ pmt_intern("fake-usrp"),
+ PMT_T);
+ }
+
+ // Specify the RBF to use
+ pmt_dict_set(usrp_dict,
+ pmt_intern("rbf"),
+ pmt_intern("inband_2rxhb_2tx.rbf"));
+
+ // Set TX and RX interpolations
+ pmt_dict_set(usrp_dict,
+ pmt_intern("interp-tx"),
+ pmt_from_long(128));
+
+ pmt_dict_set(usrp_dict,
+ pmt_intern("rf-freq"),
+ pmt_from_long(10e6));
+
+ define_component("server", "usrp_server", usrp_dict);
+
+ connect("self", "tx0", "server", "tx0");
+ connect("self", "cs", "server", "cs");
+
+ // initialize NCO
+ double freq = 100e3;
+ int interp = 32; // 32 -> 4MS/s
+ double sample_rate = 128e6 / interp;
+ d_nco.set_freq(2*M_PI * freq/sample_rate);
+
+ // FIXME need to somehow set the interp rate in the USRP.
+ // for now, we'll have the low-level code hardwire it.
+}
+
+test_usrp_tx::~test_usrp_tx()
+{
+}
+
+void
+test_usrp_tx::initial_transition()
+{
+ open_usrp();
+}
+
+void
+test_usrp_tx::handle_message(mb_message_sptr msg)
+{
+ pmt_t event = msg->signal();
+ pmt_t data = msg->data();
+
+ pmt_t handle = PMT_F;
+ pmt_t status = PMT_F;
+ std::string error_msg;
+
+ //std::cout << msg << std::endl;
+
+ switch(d_state){
+ case OPENING_USRP:
+ if (pmt_eq(event, s_response_open)){
+ status = pmt_nth(1, data);
+ if (pmt_eq(status, PMT_T)){
+ allocate_channel();
+ return;
+ }
+ else {
+ error_msg = "failed to open usrp:";
+ goto bail;
+ }
+ }
+ goto unhandled;
+
+ case ALLOCATING_CHANNEL:
+ if (pmt_eq(event, s_response_allocate_channel)){
+ status = pmt_nth(1, data);
+ if(pmt_eqv(d_tx_chan0, PMT_NIL))
+ d_tx_chan0 = pmt_nth(2, data);
+ else
+ d_tx_chan1 = pmt_nth(2, data);
+
+ if (pmt_eq(status, PMT_T) && !pmt_eqv(d_tx_chan1, PMT_NIL)){
+ enter_transmitting();
+ return;
+ }
+ else if(pmt_eq(status, PMT_F)){
+ error_msg = "failed to allocate channel:";
+ goto bail;
+ }
+ return;
+ }
+ goto unhandled;
+
+ case TRANSMITTING:
+ if (pmt_eq(event, s_response_xmit_raw_frame)){
+ handle = pmt_nth(0, data);
+ status = pmt_nth(1, data);
+
+ if (pmt_eq(status, PMT_T)){
+ handle_xmit_response(handle);
+ return;
+ }
+ else {
+ error_msg = "bad response-xmit-raw-frame:";
+ goto bail;
+ }
+ }
+ goto unhandled;
+
+ case CLOSING_CHANNEL:
+ if (pmt_eq(event, s_response_deallocate_channel)){
+ status = pmt_nth(1, data);
+
+ if (pmt_eq(status, PMT_T)){
+ close_usrp();
+ return;
+ }
+ else {
+ error_msg = "failed to deallocate channel:";
+ goto bail;
+ }
+ }
+ goto unhandled;
+
+ case CLOSING_USRP:
+ if (pmt_eq(event, s_response_close)){
+ status = pmt_nth(1, data);
+
+ if (pmt_eq(status, PMT_T)){
+ shutdown_all(PMT_T);
+ return;
+ }
+ else {
+ error_msg = "failed to close USRP:";
+ goto bail;
+ }
+ }
+ goto unhandled;
+
+ default:
+ goto unhandled;
+ }
+ return;
+
+ bail:
+ std::cerr << error_msg << data
+ << "status = " << status << std::endl;
+ shutdown_all(PMT_F);
+ return;
+
+ unhandled:
+ std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
+ << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_tx::open_usrp()
+{
+ pmt_t which_usrp = pmt_from_long(0);
+
+ d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+ d_state = OPENING_USRP;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n";
+}
+
+void
+test_usrp_tx::close_usrp()
+{
+ d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+ d_state = CLOSING_USRP;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n";
+}
+
+void
+test_usrp_tx::allocate_channel()
+{
+ long capacity = (long) 16e6;
+
+ // Send two capacity requests, which will allocate us two channels
+ d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T,
pmt_from_long(capacity)));
+ d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T,
pmt_from_long(capacity)));
+ d_state = ALLOCATING_CHANNEL;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n";
+}
+
+void
+test_usrp_tx::enter_transmitting()
+{
+ d_state = TRANSMITTING;
+ d_nsamples_xmitted = 0;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\n";
+
+ build_and_send_next_frame(); // fire off 4 to start pipeline
+ build_and_send_next_frame();
+ build_and_send_next_frame();
+ build_and_send_next_frame();
+}
+
+void
+test_usrp_tx::build_and_send_next_frame()
+{
+ // allocate the uniform vector for the samples
+ // FIXME perhaps hold on to this between calls
+
+#if 1
+ long nsamples_this_frame =
+ std::min(d_nsamples_to_send - d_nsamples_xmitted,
+ d_samples_per_frame);
+#else
+ long nsamples_this_frame = d_samples_per_frame;
+#endif
+
+ if (nsamples_this_frame == 0){
+ d_done_sending = true;
+ return;
+ }
+
+
+ size_t nshorts = 2 * nsamples_this_frame; // 16-bit I & Q
+ pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+ size_t ignore;
+ int16_t *samples = pmt_s16vector_writeable_elements(uvec, ignore);
+
+ // fill in the complex sinusoid
+
+ for (int i = 0; i < nsamples_this_frame; i++){
+
+ if (1){
+ gr_complex s;
+ d_nco.sincos(&s, 1, d_amplitude);
+ // write 16-bit i & q
+ samples[2*i] = (int16_t) s.real();
+ samples[2*i+1] = (int16_t) s.imag();
+ }
+ else {
+ gr_complex s(d_amplitude, d_amplitude);
+
+ // write 16-bit i & q
+ samples[2*i] = (int16_t) s.real();
+ samples[2*i+1] = (int16_t) s.imag();
+ }
+ }
+
+ pmt_t tx_properties = pmt_make_dict();
+
+ pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
+ d_tx->send(s_cmd_xmit_raw_frame,
+ pmt_list5(pmt_from_long(d_nframes_xmitted), // invocation-handle
+ d_tx_chan0, // channel
+ uvec, // the samples
+ timestamp,
+ tx_properties));
+
+ // Resend on channel 1
+ d_tx->send(s_cmd_xmit_raw_frame,
+ pmt_list5(pmt_from_long(d_nframes_xmitted), // invocation-handle
+ d_tx_chan1, // channel
+ uvec, // the samples
+ timestamp,
+ tx_properties));
+
+ d_nsamples_xmitted += nsamples_this_frame;
+ d_nframes_xmitted++;
+
+ if(verbose && 0)
+ std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
+}
+
+
+void
+test_usrp_tx::handle_xmit_response(pmt_t handle)
+{
+ if (d_done_sending &&
+ pmt_to_long(handle) == (d_nframes_xmitted - 1)){
+ // We're done sending and have received all responses
+ enter_closing_channel();
+ }
+
+ build_and_send_next_frame();
+}
+
+void
+test_usrp_tx::enter_closing_channel()
+{
+ d_state = CLOSING_CHANNEL;
+
+ // Deallocate both channels
+ d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan0));
+ d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan1));
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n";
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_tx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+ // handle any command line args here
+
+ mb_runtime_sptr rt = mb_make_runtime();
+ pmt_t result = PMT_NIL;
+
+ rt->run("top", "test_usrp_tx", PMT_F, &result);
+}
Deleted: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_cs.cc
Modified: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_overrun.cc
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_overrun.cc
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_overrun.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -102,7 +102,7 @@
// Specify the RBF to use
pmt_dict_set(usrp_dict,
pmt_intern("rbf"),
- pmt_intern("nanocell9.rbf"));
+ pmt_intern("inband_1rxhb_1tx.rbf"));
pmt_dict_set(usrp_dict,
pmt_intern("decim-rx"),
@@ -306,7 +306,8 @@
pmt_t status = pmt_nth(1, data);
pmt_t v_samples = pmt_nth(2, data);
pmt_t timestamp = pmt_nth(3, data);
- pmt_t properties = pmt_nth(4, data);
+ pmt_t channel = pmt_nth(4, data);
+ pmt_t properties = pmt_nth(5, data);
d_samples_recvd += pmt_length(v_samples) / 4;
Modified: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_registers.cc
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_registers.cc
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_registers.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -118,7 +118,7 @@
// Specify the RBF to use
pmt_dict_set(usrp_dict,
pmt_intern("rbf"),
- pmt_intern("boe2.rbf"));
+ pmt_intern("inband_1rxhb_1tx.rbf"));
// Set TX and RX interpolations
pmt_dict_set(usrp_dict,
Modified: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_rx.cc
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_rx.cc 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_rx.cc 2008-04-30
03:52:31 UTC (rev 8295)
@@ -87,23 +87,30 @@
test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string
&instance_name, pmt_t user_arg)
: mb_mblock(runtime, instance_name, user_arg),
d_samples_recvd(0),
- d_samples_to_recv(5e6)
+ d_samples_to_recv(20e6)
{
-
d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
// Pass a dictionary to usrp_server which specifies which interface to use,
the stub or USRP
pmt_t usrp_dict = pmt_make_dict();
+
+ // To test the application without a USRP
+ bool fake_usrp_p = false;
+ if(fake_usrp_p) {
+ pmt_dict_set(usrp_dict,
+ pmt_intern("fake-usrp"),
+ PMT_T);
+ }
// Specify the RBF to use
pmt_dict_set(usrp_dict,
pmt_intern("rbf"),
- pmt_intern("nanocell9.rbf"));
+ pmt_intern("inband_1rxhb_1tx.rbf"));
pmt_dict_set(usrp_dict,
pmt_intern("decim-rx"),
- pmt_from_long(128));
+ pmt_from_long(64));
define_component("server", "usrp_server", usrp_dict);
@@ -264,6 +271,7 @@
void
test_usrp_rx::close_usrp()
{
+
d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
d_state = CLOSING_USRP;
@@ -302,7 +310,8 @@
pmt_t status = pmt_nth(1, data);
pmt_t v_samples = pmt_nth(2, data);
pmt_t timestamp = pmt_nth(3, data);
- pmt_t properties = pmt_nth(4, data);
+ pmt_t channel = pmt_nth(4, data);
+ pmt_t properties = pmt_nth(5, data);
d_samples_recvd += pmt_length(v_samples) / 4;
@@ -325,9 +334,7 @@
test_usrp_rx::enter_closing_channel()
{
d_state = CLOSING_CHANNEL;
-
- sleep(2);
-
+
d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
if(verbose)
@@ -342,10 +349,9 @@
int
main (int argc, char **argv)
{
- // handle any command line args here
-
mb_runtime_sptr rt = mb_make_runtime();
pmt_t result = PMT_NIL;
rt->run("top", "test_usrp_rx", PMT_F, &result);
+
}
Modified: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_timestamps.cc
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_timestamps.cc
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_timestamps.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -147,7 +147,7 @@
// Specify the RBF to use
pmt_dict_set(usrp_dict,
pmt_intern("rbf"),
- pmt_intern("tmac5.rbf"));
+ pmt_intern("inband_1rxhb_1tx.rbf"));
define_component("server", "usrp_server", usrp_dict);
Modified: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_tx.cc
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_tx.cc 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_tx.cc 2008-04-30
03:52:31 UTC (rev 8295)
@@ -42,7 +42,7 @@
#include <symbols_usrp_low_level_cs.h>
#include <symbols_usrp_tx.h>
-static bool verbose = false;
+static bool verbose = true;
class test_usrp_tx : public mb_mblock
{
@@ -89,11 +89,9 @@
test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string
&instance_name, pmt_t user_arg)
: mb_mblock(runtime, instance_name, user_arg),
- d_state(INIT), d_nsamples_to_send((long) 40e6),
+ d_state(INIT), d_nsamples_to_send((long) 80e6),
d_nsamples_xmitted(0),
d_nframes_xmitted(0),
- //d_samples_per_frame((long)(126)),
- //d_samples_per_frame((long)(126 * 3.5)), // non-full packet
d_samples_per_frame((long)(126 * 4)), // full packet
d_done_sending(false),
d_amplitude(16384)
@@ -119,18 +117,14 @@
// Specify the RBF to use
pmt_dict_set(usrp_dict,
pmt_intern("rbf"),
- pmt_intern("cs1.rbf"));
+ pmt_intern("inband_1rxhb_1tx.rbf"));
// Set TX and RX interpolations
pmt_dict_set(usrp_dict,
pmt_intern("interp-tx"),
- pmt_from_long(128));
+ pmt_from_long(64));
pmt_dict_set(usrp_dict,
- pmt_intern("decim-rx"),
- pmt_from_long(16));
-
- pmt_dict_set(usrp_dict,
pmt_intern("rf-freq"),
pmt_from_long(10e6));
@@ -176,12 +170,12 @@
if (pmt_eq(event, s_response_open)){
status = pmt_nth(1, data);
if (pmt_eq(status, PMT_T)){
- allocate_channel();
- return;
+ allocate_channel();
+ return;
}
else {
- error_msg = "failed to open usrp:";
- goto bail;
+ error_msg = "failed to open usrp:";
+ goto bail;
}
}
goto unhandled;
@@ -192,12 +186,12 @@
d_tx_chan = pmt_nth(2, data);
if (pmt_eq(status, PMT_T)){
- enter_transmitting();
- return;
+ enter_transmitting();
+ return;
}
else {
- error_msg = "failed to allocate channel:";
- goto bail;
+ error_msg = "failed to allocate channel:";
+ goto bail;
}
}
goto unhandled;
@@ -208,12 +202,12 @@
status = pmt_nth(1, data);
if (pmt_eq(status, PMT_T)){
- handle_xmit_response(handle);
- return;
+ handle_xmit_response(handle);
+ return;
}
else {
- error_msg = "bad response-xmit-raw-frame:";
- goto bail;
+ error_msg = "bad response-xmit-raw-frame:";
+ goto bail;
}
}
goto unhandled;
@@ -223,12 +217,12 @@
status = pmt_nth(1, data);
if (pmt_eq(status, PMT_T)){
- close_usrp();
- return;
+ close_usrp();
+ return;
}
else {
- error_msg = "failed to deallocate channel:";
- goto bail;
+ error_msg = "failed to deallocate channel:";
+ goto bail;
}
}
goto unhandled;
@@ -238,12 +232,12 @@
status = pmt_nth(1, data);
if (pmt_eq(status, PMT_T)){
- shutdown_all(PMT_T);
- return;
+ shutdown_all(PMT_T);
+ return;
}
else {
- error_msg = "failed to close USRP:";
- goto bail;
+ error_msg = "failed to close USRP:";
+ goto bail;
}
}
goto unhandled;
@@ -272,6 +266,9 @@
d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
d_state = OPENING_USRP;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n";
}
void
@@ -279,6 +276,9 @@
{
d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
d_state = CLOSING_USRP;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n";
}
void
@@ -287,6 +287,9 @@
long capacity = (long) 16e6;
d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T,
pmt_from_long(capacity)));
d_state = ALLOCATING_CHANNEL;
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n";
}
void
@@ -295,15 +298,9 @@
d_state = TRANSMITTING;
d_nsamples_xmitted = 0;
- // FIXME: carrier sense hack
- d_tx->send(s_cmd_to_control_channel, // C/S packet
- pmt_list2(PMT_NIL, // invoc handle
- pmt_list1(
- pmt_list2(s_op_write_reg,
- pmt_list2(
- pmt_from_long(1),
- pmt_from_long(21))))));
-
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\n";
+
build_and_send_next_frame(); // fire off 4 to start pipeline
build_and_send_next_frame();
build_and_send_next_frame();
@@ -356,9 +353,6 @@
}
pmt_t tx_properties = pmt_make_dict();
- pmt_dict_set(tx_properties,
- pmt_intern("carrier-sense"),
- PMT_T);
pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
d_tx->send(s_cmd_xmit_raw_frame,
@@ -371,7 +365,7 @@
d_nsamples_xmitted += nsamples_this_frame;
d_nframes_xmitted++;
- if(verbose)
+ if(verbose && 0)
std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
}
@@ -394,6 +388,9 @@
d_state = CLOSING_CHANNEL;
d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
+
+ if(verbose)
+ std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n";
}
REGISTER_MBLOCK_CLASS(test_usrp_tx);
Modified: gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_underrun.cc
===================================================================
--- gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_underrun.cc
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/apps-inband/test_usrp_inband_underrun.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -127,7 +127,7 @@
d_rx_chan(PMT_NIL),
d_which_usrp(pmt_from_long(0)),
d_state(INIT),
- d_nsamples_to_send((long) 20e6),
+ d_nsamples_to_send((long) 27e6),
d_nsamples_xmitted(0),
d_nframes_xmitted(0),
d_samples_per_frame(d_nsamples_to_send), // full packet
@@ -143,12 +143,12 @@
// Specify the RBF to use
pmt_dict_set(usrp_dict,
pmt_intern("rbf"),
- pmt_intern("nanocell9.rbf"));
+ pmt_intern("inband_1rxhb_1tx.rbf"));
// Set TX and RX interpolations
pmt_dict_set(usrp_dict,
pmt_intern("interp-tx"),
- pmt_from_long(8));
+ pmt_from_long(64));
pmt_dict_set(usrp_dict,
pmt_intern("decim-rx"),
@@ -668,8 +668,6 @@
{
d_state = CLOSING_USRP;
- sleep(2);
-
d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
}
Modified: gnuradio/trunk/usrp/host/lib/inband/Makefile.am
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/Makefile.am 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/Makefile.am 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -76,7 +76,6 @@
usrp_usb_interface.h
noinst_HEADERS = \
- fake_usrp.h \
qa_inband.h \
qa_inband_packet_prims.h \
qa_inband_usrp_server.h \
@@ -109,14 +108,10 @@
# ------------------------------------------------------------------------
noinst_PROGRAMS = \
- test_inband \
- test_usrp_inband
+ test_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
Deleted: gnuradio/trunk/usrp/host/lib/inband/fake_usrp.cc
Deleted: gnuradio/trunk/usrp/host/lib/inband/fake_usrp.h
Modified: gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.cc
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -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++;
-
}
@@ -1079,7 +1080,161 @@
REGISTER_MBLOCK_CLASS(qa_rx_top);
+//
----------------------------------------------------------------------------------------------
+class qa_rid_top : public mb_mblock
+{
+ mb_port_sptr d_tx;
+ mb_port_sptr d_rx;
+ mb_port_sptr d_cs;
+
+ long d_npongs;
+ long d_tcycles;
+ long d_cycles;
+ long d_max_rid;
+
+ mb_time d_t0;
+ double d_delta_t;
+
+ public:
+ qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t
user_arg);
+ ~qa_rid_top();
+ void initial_transition();
+ void handle_message(mb_message_sptr msg);
+
+ protected:
+ void run_tests();
+ void send_max_pings();
+};
+
+qa_rid_top::qa_rid_top(mb_runtime *runtime, const std::string &instance_name,
pmt_t user_arg)
+ : mb_mblock(runtime, instance_name, user_arg)
+{
+ d_npongs = 0;
+ d_tcycles = 3;
+ d_cycles = d_tcycles;
+ d_max_rid = usrp_server::D_MAX_RID;
+ d_delta_t = 0.1;
+
+
+ d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+ d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+ d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+ // Use the stub with the usrp_server
+ pmt_t usrp_server_dict = pmt_make_dict();
+ pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+ // Test the TX side
+ define_component("server", "usrp_server", usrp_server_dict);
+ connect("self", "tx0", "server", "tx0");
+ connect("self", "rx0", "server", "rx0");
+ connect("self", "cs", "server", "cs");
+
+}
+
+qa_rid_top::~qa_rid_top(){}
+
+void
+qa_rid_top::initial_transition()
+{
+ run_tests();
+}
+
+void
+qa_rid_top::run_tests()
+{
+ if(verbose)
+ std::cout << "[qa_rid_top] Starting tests...\n";
+
+ // Retrieve information about the USRP, then run tests
+ d_cs->send(s_cmd_open,
+ pmt_list2(pmt_list2(s_response_open, PMT_T),
+ pmt_from_long(0)));
+
+ // should be able to allocate 1 byte
+ d_tx->send(s_cmd_allocate_channel,
+ pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
+ pmt_from_long(1)));
+
+ d_rx->send(s_cmd_allocate_channel,
+ pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T),
+ pmt_from_long(1)));
+
+ // Need to start receiving to read from the USRP to get C/S responses
+ d_rx->send(s_cmd_start_recv_raw_samples,
+ pmt_list2(PMT_NIL,
+ pmt_from_long(0)));
+
+ // Build a subpacket of MAX_RID pings and wait a small amount for all of the
+ // responses and fire off another MAX_RID. If MAX_RID*2 responses are
+ // received, the RID recycling is working correctly.
+ // Schedule a timer in which we expect to have received all of the responses,
+ // which will send off another MAX_RID worth.
+ send_max_pings();
+ d_t0 = mb_time::time();
+ schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
+}
+
+void
+qa_rid_top::send_max_pings()
+{
+ pmt_t ping = pmt_list2(s_op_ping_fixed,
+ pmt_list2(pmt_from_long(0),
+ pmt_from_long(0)));
+
+ pmt_t sub_packets = PMT_NIL;
+
+ for(int i=0; i<d_max_rid; i++)
+ sub_packets = pmt_list_add(sub_packets, ping);
+
+ d_tx->send(s_cmd_to_control_channel,
+ pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+ sub_packets));
+}
+
+void
+qa_rid_top::handle_message(mb_message_sptr msg)
+{
+ pmt_t data = msg->data();
+ pmt_t event = msg->signal();
+
+ // If we get a timeout we ensure we got a maximum RID number of responses.
+ if(pmt_eq(event, s_timeout)) {
+ if(verbose)
+ std::cout << "[qa_rid_top] Got timeout, received so far: "
+ << d_npongs << "\n";
+
+ d_cycles--;
+
+ if(d_cycles==0 && d_npongs == d_max_rid*d_tcycles) {
+ shutdown_all(PMT_T);
+ }
+ else if(d_cycles==0) {
+
+ std::cout << "[qa_rid_top] d_npongs: " << d_npongs
+ << " expected: " << d_max_rid*d_tcycles
+ << std::endl;
+
+ shutdown_all(PMT_F);
+ }
+ else {
+ send_max_pings();
+ d_t0 = mb_time::time();
+ schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
+ }
+
+ }
+ else if(pmt_eq(event, s_response_from_control_channel))
+ {
+ d_npongs++;
+ }
+
+}
+
+REGISTER_MBLOCK_CLASS(qa_rid_top);
+
+
//
----------------------------------------------------------------------------------------------
class qa_cs_top : public mb_mblock
@@ -1398,3 +1553,17 @@
CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
}
+
+void
+qa_inband_usrp_server::test_rid()
+{
+ mb_runtime_sptr rt = mb_make_runtime();
+ pmt_t result = PMT_T;
+
+ // std::cout << "\n\n-----------------\n";
+ // std::cout << " RUNNING RID TESTS \n";
+
+ rt->run("top", "qa_rid_top", PMT_F, &result);
+
+ CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
Modified: gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.h
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.h 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/qa_inband_usrp_server.h 2008-04-30
03:52:31 UTC (rev 8295)
@@ -34,6 +34,7 @@
CPPUNIT_TEST(test_tx);
CPPUNIT_TEST(test_rx);
CPPUNIT_TEST(test_cs);
+ CPPUNIT_TEST(test_rid);
CPPUNIT_TEST_SUITE_END();
private:
@@ -43,6 +44,7 @@
void test_tx();
void test_rx();
void test_cs();
+ void test_rid();
};
#endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */
Deleted: gnuradio/trunk/usrp/host/lib/inband/test_usrp_inband.cc
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.cc
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.cc
2008-04-30 03:52:31 UTC (rev 8295)
@@ -30,6 +30,14 @@
#include <stdio.h>
#include <string.h>
+/*!
+ * \brief Aligns the packet payload on a 32 bit boundary. This is essential to
+ * all control/status packets so that the inband FPGA code can parse them
+ * easily.
+ *
+ * \returns true if successful or if the packet was already aligned; false if
it
+ * cannot be aligned.
+ */
bool usrp_inband_usb_packet::align32()
{
int p_len = payload_len();
@@ -44,18 +52,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())
@@ -78,17 +88,20 @@
*payload = host_to_usrp_u32(ping);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_PING_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
-
+/*!
+ * \brief Adds a ping response to the packet. This is used by the fake USRP
+ * code to generate fake responses for pings.
+ *
+ * The \p rid is the RID to be associated with the response and \p ping_val is
+ * currently unused.
+ *
+ * \returns true if the ping reply was added successfully, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val)
{
if(!align32())
@@ -111,16 +124,20 @@
*payload = host_to_usrp_u32(ping);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_PING_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds a write register command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written to.
+ *
+ * \returns true if the command was added to the packet successfully, false
+ * otherwise.
+ */
bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val)
{
if(!align32())
@@ -149,16 +166,19 @@
*payload = host_to_usrp_u32((uint32_t) val);
// Rebuild the header to update the payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_WRITEREG_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_WRITEREG_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds a write register masked command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written, masked by \p mask
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long
mask)
{
if(!align32())
@@ -190,16 +210,19 @@
*payload = host_to_usrp_u32((uint32_t) mask);
// Rebuild the header to update the payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_WRITEREGMASKED_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_WRITEREGMASKED_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds a read register message to the packet.
+ *
+ * The \p rid will be the associated RID returned with the response, and \p
+ * reg_num is the register to be read.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num)
{
if(!align32())
@@ -222,16 +245,22 @@
*payload = host_to_usrp_u32(read_reg);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_READREG_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_READREG_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds a read register reply response to the current packet. This is
+ * used by the fake USRP code to generate fake register read responses for
+ * testing.
+ *
+ * The \p rid is the associated RID to be included in the response, \p reg_num
+ * is the register the read is coming from, and \p reg_val is the value of the
+ * read.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long
reg_val)
{
if(!align32())
@@ -258,16 +287,19 @@
*payload = host_to_usrp_u32((uint32_t) reg_val);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_READREGREPLY_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_READREGREPLY_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds a delay command to the current packet.
+ *
+ * The \p ticks parameter is the number of clock ticks the FPGA should delay
+ * parsing for, which is added to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_delay(long ticks)
{
if(!align32())
@@ -289,16 +321,16 @@
*payload = host_to_usrp_u32(delay);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_DELAY_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_DELAY_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data,
size_t data_len)
{
if(!align32())
@@ -328,16 +360,20 @@
memcpy(payload, i2c_data, data_len);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + i2c_len;
+ incr_header_len(CS_FIXED_LEN + i2c_len);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds an I2C read command to the current packet.
+ *
+ * The \p rid is the associated RID to return with the read response, \p
+ * i2c_addr is the address to read from on the I2C bus, and \p n_bytes is the
+ * number of bytes to be read from the bus.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes)
{
if(!align32())
@@ -367,16 +403,20 @@
*payload = host_to_usrp_u32(word1);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_I2CREAD_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_I2CREAD_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds an I2C read reply response to the current packet. This is used
+ * by the fake USRP code to generate fake I2C responses.
+ *
+ * The \p rid is the RID to be associated with the response, \p i2c_addr is the
+ * address on the I2C bus that the \p i2c_data of \p i2c_data_len was read
from.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr,
uint8_t *i2c_data, long i2c_data_len)
{
if(!align32())
@@ -406,16 +446,16 @@
memcpy(payload, i2c_data, i2c_data_len);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + i2c_len;
+ incr_header_len(CS_FIXED_LEN + i2c_len);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds a SPI write command to the current packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long
opt_header_bytes, uint8_t *spi_data, long spi_data_len)
{
if(!align32())
@@ -454,16 +494,16 @@
memcpy(payload, spi_data, spi_data_len);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + spi_len;
+ incr_header_len(CS_FIXED_LEN + spi_len);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds a SPI bus read command to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format,
long opt_header_bytes, long n_bytes)
{
if(!align32())
@@ -508,16 +548,17 @@
*payload = host_to_usrp_u32(word);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + CS_SPIREAD_LEN;
+ incr_header_len(CS_FIXED_LEN + CS_SPIREAD_LEN);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
return true;
}
+/*!
+ * \brief Adds an SPI read reply to the current packet. This is used by the
+ * fake USRP code to generate fake responses for SPI reads.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data,
long spi_data_len)
{
if(!align32())
@@ -546,30 +587,32 @@
memcpy(payload, spi_data, spi_data_len);
// Update payload length
- int h_flags = flags();
- int h_chan = chan();
- int h_tag = tag();
- int h_payload_len = payload_len() + CS_FIXED_LEN + spi_len;
+ incr_header_len(CS_FIXED_LEN + spi_len);
- set_header(h_flags, h_chan, h_tag, h_payload_len);
-
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/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.h
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.h
2008-04-30 03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_inband_usb_packet.h
2008-04-30 03:52:31 UTC (rev 8295)
@@ -31,6 +31,7 @@
static const int USB_PKT_SIZE = 512; // bytes
static const int MAX_PAYLOAD = USB_PKT_SIZE-2*sizeof(uint32_t);
+static const int CONTROL_CHAN = 0x1f;
class usrp_inband_usb_packet {
//
@@ -150,6 +151,10 @@
| ((payload_len & PAYLOAD_LEN_MASK) <<
PAYLOAD_LEN_SHIFT));
d_word0 = host_to_usrp_u32(word0);
}
+
+ void incr_header_len(int val) {
+ set_header(flags(), chan(), tag(), payload_len() + val);
+ }
uint32_t timestamp() const {
return usrp_to_host_u32(d_timestamp);
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_rx.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_rx.cc 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_rx.cc 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -40,25 +40,30 @@
static const bool verbose = false;
+bool usrp_rx_stop;
+
usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t
user_arg)
: mb_mblock(rt, instance_name, user_arg),
- d_disk_write(false)
+ d_disk_write(false),
+ d_disk_write_pkt(false) // if true, writes full packet, else just the
payload
{
d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
- //d_disk_write=true;
-
if(d_disk_write) {
- d_ofile.open("rx_data.dat",std::ios::binary|std::ios::out);
+ d_ofile0.open("rx_data_chan0.dat",std::ios::binary|std::ios::out);
+ d_ofile1.open("rx_data_chan1.dat",std::ios::binary|std::ios::out);
d_cs_ofile.open("rx_cs.dat",std::ios::binary|std::ios::out);
}
+
+ usrp_rx_stop = false;
}
usrp_rx::~usrp_rx()
{
if(d_disk_write) {
- d_ofile.close();
+ d_ofile0.close();
+ d_ofile1.close();
d_cs_ofile.close();
}
}
@@ -69,6 +74,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)
{
@@ -85,6 +96,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)
{
@@ -104,7 +126,7 @@
std::cout << "[usrp_rx] Waiting for packets..\n";
// Read by 512 which is packet size and send them back up
- while(1) {
+ while(!usrp_rx_stop) {
pmt_t v_pkt = pmt_make_u8vector(pkt_size, 0);
transport_pkt *pkt =
@@ -124,19 +146,38 @@
d_cs->send(s_response_usrp_rx_read,
pmt_list3(PMT_NIL, PMT_T, v_pkt));
- if(verbose)
+ if(verbose && 0)
std::cout << "[usrp_rx] Read 1 packet\n";
if(d_disk_write) {
- if(pkt->chan() == 0x1f)
+ if(pkt->chan() == CONTROL_CHAN)
d_cs_ofile.write((const char *)pkt, transport_pkt::max_pkt_size());
- else
- d_ofile.write((const char *)pkt, transport_pkt::max_pkt_size());
+ else {
+ if(d_disk_write_pkt) {
+ if(pkt->chan() == 0)
+ d_ofile0.write((const char *)pkt, transport_pkt::max_pkt_size());
+ else if(pkt->chan() == 1)
+ d_ofile1.write((const char *)pkt, transport_pkt::max_pkt_size());
+ } else {
+ if(pkt->chan() == 0)
+ d_ofile0.write((const char *)pkt->payload(),
transport_pkt::max_payload());
+ else if(pkt->chan() == 1)
+ d_ofile1.write((const char *)pkt->payload(),
transport_pkt::max_payload());
+ }
+ }
d_cs_ofile.flush();
- d_ofile.flush();
+ d_ofile0.flush();
+ d_ofile1.flush();
}
}
+
+ usrp_rx_stop = false;
+
+ if(verbose) {
+ std::cout << "[USRP_RX] Stopping...\n";
+ fflush(stdout);
+ }
}
REGISTER_MBLOCK_CLASS(usrp_rx);
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_rx.h
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_rx.h 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_rx.h 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -26,6 +26,8 @@
class usrp_standard_rx;
+extern bool usrp_rx_stop; // used to communicate a 'stop' to the RX stub
+
/*!
* \brief Implements the low level usb interface to the USRP
*/
@@ -35,7 +37,9 @@
usrp_standard_rx *d_urx;
bool d_disk_write;
- std::ofstream d_ofile;
+ bool d_disk_write_pkt;
+ std::ofstream d_ofile0;
+ std::ofstream d_ofile1;
std::ofstream d_cs_ofile;
public:
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.cc 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.cc 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -43,7 +43,7 @@
static const bool verbose = false;
-bool usrp_rx_stop;
+bool usrp_rx_stop_stub;
// Used for the fake control packet response code to send the responses back up
// the RX. The TX stub dumps responses in to this queue.
@@ -52,15 +52,32 @@
usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name,
pmt_t user_arg)
: mb_mblock(rt, instance_name, user_arg),
d_samples_per_frame((long)(126)),
+ d_decim_rx(128),
d_amplitude(16384),
d_disk_write(false)
{
+
+ // Information about the rates are passed all the way from the app in the
form
+ // of a dictionary. We use this to read the RX decimation rate and compute
+ // the approximate number of MS/s as a form of flow control for the stub.
+ pmt_t usrp_dict = user_arg;
+
+ if (pmt_is_dict(usrp_dict)) {
+ // Read the RX decimation rate
+ if(pmt_t decim_rx = pmt_dict_ref(usrp_dict,
+ pmt_intern("decim-rx"),
+ PMT_NIL)) {
+ if(!pmt_eqv(decim_rx, PMT_NIL))
+ d_decim_rx = pmt_to_long(decim_rx);
+ }
+ }
+
d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
// initialize NCO
double freq = 100e3;
int interp = 32; // 32 -> 4MS/s
- double sample_rate = 128e6 / interp;
+ double sample_rate = 64e6 / interp;
d_nco.set_freq(2*M_PI * freq/sample_rate);
//d_disk_write = true;
@@ -68,7 +85,7 @@
if(d_disk_write)
d_ofile.open("raw_rx.dat",std::ios::binary|std::ios::out);
- usrp_rx_stop = false;
+ usrp_rx_stop_stub = false;
}
usrp_rx_stub::~usrp_rx_stub()
@@ -80,7 +97,6 @@
void
usrp_rx_stub::initial_transition()
{
-
}
void
@@ -90,95 +106,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...\n";
+ 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) {
+ // 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 = false;
- if(verbose)
- std::cout << "[USRP_RX_STUB] Got fake RX stop\n";
-
}
REGISTER_MBLOCK_CLASS(usrp_rx_stub);
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.h
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.h 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_rx_stub.h 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -31,9 +31,12 @@
typedef usrp_inband_usb_packet transport_pkt;
-extern bool usrp_rx_stop; // used to communicate a 'stop' to the RX stub
+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
*/
@@ -45,6 +48,10 @@
usrp_standard_rx* d_urx;
long d_samples_per_frame;
+ long d_decim_rx;
+
+ mb_time d_t0;
+ double d_delta_t;
// for generating sine wave output
ui_nco<float,float> d_nco;
@@ -61,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/trunk/usrp/host/lib/inband/usrp_server.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_server.cc 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_server.cc 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -29,6 +29,8 @@
#include <vector>
#include <usrp_usb_interface.h>
#include <string.h>
+#include <fpga_regs_common.h>
+#include <fpga_regs_standard.h>
#include <symbols_usrp_server_cs.h>
#include <symbols_usrp_channel.h>
@@ -53,14 +55,43 @@
usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name,
pmt_t user_arg)
: mb_mblock(rt, instance_name, user_arg),
+ d_fpga_debug(false),
+ d_interp_tx(128), // these should match the lower level defaults (rx
also)
+ d_decim_rx(128),
d_fake_rx(false)
{
if(verbose)
std::cout << "[USRP_SERVER] Initializing...\n";
// Dictionary for arguments to all of the components
- pmt_t usrp_dict = user_arg;
+ d_usrp_dict = user_arg;
+ if (pmt_is_dict(d_usrp_dict)) {
+
+ if(pmt_t fpga_debug = pmt_dict_ref(d_usrp_dict,
+ pmt_intern("fpga-debug"),
+ PMT_NIL)) {
+ if(pmt_eqv(fpga_debug, PMT_T))
+ d_fpga_debug=true;
+ }
+
+ // Read the TX interpolations
+ if(pmt_t interp_tx = pmt_dict_ref(d_usrp_dict,
+ pmt_intern("interp-tx"),
+ PMT_NIL)) {
+ if(!pmt_eqv(interp_tx, PMT_NIL))
+ d_interp_tx = pmt_to_long(interp_tx);
+ }
+
+ // Read the RX decimation rate
+ if(pmt_t decim_rx = pmt_dict_ref(d_usrp_dict,
+ pmt_intern("decim-rx"),
+ PMT_NIL)) {
+ if(!pmt_eqv(decim_rx, PMT_NIL))
+ d_decim_rx = pmt_to_long(decim_rx);
+ }
+ }
+
// control & status port
d_cs = define_port("cs", "usrp-server-cs", true, mb_port::EXTERNAL);
d_cs_usrp = define_port("cs_usrp", "usrp-interface-cs", false,
mb_port::INTERNAL);
@@ -82,7 +113,7 @@
mb_port::EXTERNAL));
}
- define_component("usrp", "usrp_usb_interface", usrp_dict);
+ define_component("usrp", "usrp_usb_interface", d_usrp_dict);
connect("self", "cs_usrp", "usrp", "cs");
d_defer=false;
@@ -108,6 +139,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()
{
@@ -136,6 +171,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)
{
@@ -178,6 +218,9 @@
pmt_t status = pmt_nth(1, data);
d_cs->send(s_response_open, pmt_list2(invocation_handle, status));
+ //reset_all_registers();
+ //initialize_registers();
+
if(pmt_eqv(status,PMT_T)) {
d_opened = true;
d_defer = false;
@@ -209,7 +252,7 @@
// Do not report back responses if they were generated from a
// command packet
- if(channel == 0x1f)
+ if(channel == CONTROL_CHAN)
return;
// Find the port through the owner of the channel
@@ -470,7 +513,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++)
@@ -480,7 +530,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++)
@@ -490,8 +547,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;
@@ -504,6 +565,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,
@@ -564,9 +633,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,
@@ -591,8 +664,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();
@@ -667,7 +758,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),
@@ -676,7 +768,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);
@@ -687,8 +801,11 @@
size_t psize;
long payload_len = 0;
- long channel = 0x1f;
+ long channel = CONTROL_CHAN;
+ if(verbose)
+ std::cout << "[USRP_SERVER] Handling " << n_subpkts << " commands\n";
+
// The design of the following code is optimized for simplicity, not
// performance. To performance optimize this code, the total size in bytes
// needed for all of the CS packets is needed to allocate contiguous memory
@@ -990,8 +1107,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));
@@ -1032,6 +1163,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,
@@ -1067,7 +1210,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)
{
@@ -1106,7 +1264,7 @@
return;
// If the packet is a C/S packet, parse it separately
- if(channel == 0x1f) {
+ if(channel == CONTROL_CHAN) {
parse_control_pkt(invocation_handle, pkt);
return;
}
@@ -1137,14 +1295,28 @@
PMT_T);
d_rx[port]->send(s_response_recv_raw_samples,
- pmt_list5(invocation_handle,
+ pmt_list6(invocation_handle,
status,
v_samples,
pmt_from_long(pkt->timestamp()),
+ pmt_from_long(channel),
properties));
return;
}
+/*!
+ * \brief Called by handle_response_usrp_read() when the incoming packet has a
+ * channel of CONTROL_CHAN. This means that the incoming packet contains a
+ * response for a command sent to the control channel, which this method will
+ * parse.
+ *
+ * The \p pkt parameter is a pointer to the full packet (transport_pkt) in
+ * memory.
+ *
+ * Given that all commands sent to the control channel that require responses
+ * will carry an RID (request ID), the method will use the RID passed back with
+ * the response to determine which port the response should be sent on.
+ */
void
usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
{
@@ -1190,6 +1362,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)
@@ -1225,6 +1400,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)
@@ -1261,6 +1439,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,
@@ -1294,6 +1475,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,
@@ -1317,6 +1501,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()
{
@@ -1335,6 +1523,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,
@@ -1346,7 +1553,7 @@
pmt_t invocation_handle = pmt_nth(1, signal_info);
// not a valid channel number?
- if(channel >= (long)chan_info.size() && channel != 0x1f) {
+ if(channel >= (long)chan_info.size() && channel != CONTROL_CHAN) {
port->send(response_signal,
pmt_list2(invocation_handle,
s_err_channel_invalid));
@@ -1377,8 +1584,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()
{
@@ -1386,7 +1597,264 @@
if(pmt_eqv(d_rids[i].owner, PMT_NIL))
return i;
+ if(verbose)
+ std::cout << "[USRP_SERVER] No RIDs left\n";
return -1;
}
+/*!
+ * \brief Called by handle_message() when USRP server gets a response that the
+ * USRP was opened successfully to initialize the registers using the new
+ * register read/write control packets.
+ */
+void
+usrp_server::initialize_registers()
+{
+ // We use handle_cmd_to_control_channel() to create the register writes using
+ // PMT_NIL as the response port to tell usrp_server not to pass the response
+ // up to any application.
+ if(verbose)
+ std::cout << "[USRP_SERVER] Initializing registers...\n";
+
+ // RX mode to normal (0)
+ set_register(FR_MODE, 0);
+
+ // FPGA debugging?
+ if(d_fpga_debug) {
+ set_register(FR_DEBUG_EN, 1);
+ // FIXME: need to figure out exact register writes to control daughterboard
+ // pins that need to be written to
+ } else {
+ set_register(FR_DEBUG_EN, 0);
+ }
+
+ // Set the transmit sample rate divisor, which is 4-1
+ set_register(FR_TX_SAMPLE_RATE_DIV, 3);
+
+ // Dboard IO buffer and register settings
+ set_register(FR_OE_0, (0xffff << 16) | 0x0000);
+ set_register(FR_IO_0, (0xffff << 16) | 0x0000);
+ set_register(FR_OE_1, (0xffff << 16) | 0x0000);
+ set_register(FR_IO_1, (0xffff << 16) | 0x0000);
+ set_register(FR_OE_2, (0xffff << 16) | 0x0000);
+ set_register(FR_IO_2, (0xffff << 16) | 0x0000);
+ set_register(FR_OE_3, (0xffff << 16) | 0x0000);
+ set_register(FR_IO_3, (0xffff << 16) | 0x0000);
+
+ // zero Tx side Auto Transmit/Receive regs
+ set_register(FR_ATR_MASK_0, 0);
+ set_register(FR_ATR_TXVAL_0, 0);
+ set_register(FR_ATR_RXVAL_0, 0);
+ set_register(FR_ATR_MASK_1, 0);
+ set_register(FR_ATR_TXVAL_1, 0);
+ set_register(FR_ATR_RXVAL_1, 0);
+ set_register(FR_ATR_MASK_2, 0);
+ set_register(FR_ATR_TXVAL_2, 0);
+ set_register(FR_ATR_RXVAL_2, 0);
+ set_register(FR_ATR_MASK_3, 0);
+ set_register(FR_ATR_TXVAL_3, 0);
+ set_register(FR_ATR_RXVAL_3, 0);
+
+ // Configure TX mux, this is a hacked value
+ set_register(FR_TX_MUX, 0x00000081);
+
+ // Set the interpolation rate, which is the rate divided by 4, minus 1
+ set_register(FR_INTERP_RATE, (d_interp_tx/4)-1);
+
+ // Apparently this register changes again
+ set_register(FR_TX_MUX, 0x00000981);
+
+ // Set the receive sample rate divisor, which is 2-1
+ set_register(FR_RX_SAMPLE_RATE_DIV, 1);
+
+ // DC offset
+ set_register(FR_DC_OFFSET_CL_EN, 0x0000000f);
+
+ // Reset the DC correction offsets
+ set_register(FR_ADC_OFFSET_0, 0);
+ set_register(FR_ADC_OFFSET_1, 0);
+
+ // Some hard-coded RX configuration
+ set_register(FR_RX_FORMAT, 0x00000300);
+ set_register(FR_RX_MUX, 1);
+
+ // RX decimation rate is divided by two, then subtract 1
+ set_register(FR_DECIM_RATE, (d_decim_rx/2)-1);
+
+ // More hard coding
+ set_register(FR_RX_MUX, 0x000e4e41);
+
+ // Resetting RX registers
+ set_register(FR_RX_PHASE_0, 0);
+ set_register(FR_RX_PHASE_1, 0);
+ set_register(FR_RX_PHASE_2, 0);
+ set_register(FR_RX_PHASE_3, 0);
+ set_register(FR_RX_FREQ_0, 0x28000000);
+ set_register(FR_RX_FREQ_1, 0);
+ set_register(FR_RX_FREQ_2, 0);
+ set_register(FR_RX_FREQ_3, 0);
+
+ // Enable debug bus
+ set_register(FR_DEBUG_EN, 0xf);
+ set_register(FR_OE_0, -1);
+ set_register(FR_OE_1, -1);
+ set_register(FR_OE_2, -1);
+ set_register(FR_OE_3, -1);
+
+ // DEBUGGING
+ //check_register_initialization();
+}
+
+// FIXME: used for debugging to determine if all the registers are actually
+// being set correctly
+void
+usrp_server::check_register_initialization()
+{
+ // RX mode to normal (0)
+ read_register(FR_MODE);
+
+ // FPGA debugging?
+ if(d_fpga_debug) {
+ read_register(FR_DEBUG_EN);
+ // FIXME: need to figure out exact register writes to control daughterboard
+ // pins that need to be written to
+ } else {
+ read_register(FR_DEBUG_EN);
+ }
+
+ // Set the transmit sample rate divisor, which is 4-1
+ read_register(FR_TX_SAMPLE_RATE_DIV);
+
+ // Dboard IO buffer and register settings
+ read_register(FR_OE_0);
+ read_register(FR_IO_0);
+ read_register(FR_OE_1);
+ read_register(FR_IO_1);
+ read_register(FR_OE_2);
+ read_register(FR_IO_2);
+ read_register(FR_OE_3);
+ read_register(FR_IO_3);
+
+ // zero Tx side Auto Transmit/Receive regs
+ read_register(FR_ATR_MASK_0);
+ read_register(FR_ATR_TXVAL_0);
+ read_register(FR_ATR_RXVAL_0);
+ read_register(FR_ATR_MASK_1);
+ read_register(FR_ATR_TXVAL_1);
+ read_register(FR_ATR_RXVAL_1);
+ read_register(FR_ATR_MASK_2);
+ read_register(FR_ATR_TXVAL_2);
+ read_register(FR_ATR_RXVAL_2);
+ read_register(FR_ATR_MASK_3);
+ read_register(FR_ATR_TXVAL_3);
+ read_register(FR_ATR_RXVAL_3);
+
+ // Configure TX mux, this is a hacked value
+ read_register(FR_TX_MUX);
+
+ // Set the interpolation rate, which is the rate divided by 4, minus 1
+ read_register(FR_INTERP_RATE);
+
+ // Apparently this register changes again
+ read_register(FR_TX_MUX);
+
+ // Set the receive sample rate divisor, which is 2-1
+ read_register(FR_RX_SAMPLE_RATE_DIV);
+
+ // DC offset
+ read_register(FR_DC_OFFSET_CL_EN);
+
+ // Reset the DC correction offsets
+ read_register(FR_ADC_OFFSET_0);
+ read_register(FR_ADC_OFFSET_1);
+
+ // Some hard-coded RX configuration
+ read_register(FR_RX_FORMAT);
+ read_register(FR_RX_MUX);
+
+ // RX decimation rate is divided by two, then subtract 1
+ read_register(FR_DECIM_RATE);
+
+ // More hard coding
+ read_register(FR_RX_MUX);
+
+ // Resetting RX registers
+ read_register(FR_RX_PHASE_0);
+ read_register(FR_RX_PHASE_1);
+ read_register(FR_RX_PHASE_2);
+ read_register(FR_RX_PHASE_3);
+ read_register(FR_RX_FREQ_0);
+ read_register(FR_RX_FREQ_1);
+ read_register(FR_RX_FREQ_2);
+ read_register(FR_RX_FREQ_3);
+}
+
+/*!
+ * \brief Used to generate FPGA register write commands to reset all of the
FPGA
+ * registers to a value of 0.
+ */
+void
+usrp_server::reset_all_registers()
+{
+ for(int i=0; i<64; i++)
+ set_register(i, 0);
+}
+
+/*!
+ * \brief Used internally by USRP server to generate a control/status packet
+ * which contains a register write.
+ *
+ * The \p reg parameter is the register number that the value \p val will be
+ * written to.
+ */
+void
+usrp_server::set_register(long reg, long val)
+{
+ size_t psize;
+ long payload_len = 0;
+
+ pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
+ transport_pkt *pkt = (transport_pkt *)
pmt_u8vector_writeable_elements(v_packet, psize);
+
+ pkt->set_header(0, CONTROL_CHAN, 0, payload_len);
+ pkt->set_timestamp(0xffffffff);
+
+ pkt->cs_write_reg(reg, val);
+
+ d_cs_usrp->send(s_cmd_usrp_write,
+ pmt_list3(PMT_NIL,
+ pmt_from_long(CONTROL_CHAN),
+ v_packet));
+}
+
+/*!
+ * \brief Used internally by USRP server to generate a control/status packet
+ * which contains a register read. This is important to use internally so that
+ * USRP server can bypass the use of RIDs with register reads, as they are not
+ * needed and it would use up the finite number of RIDs available for use for
+ * applications to receive responses.
+ *
+ * The \p reg parameter is the register number that the value should be read
+ * from.
+ */
+void
+usrp_server::read_register(long reg)
+{
+ size_t psize;
+ long payload_len = 0;
+
+ pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
+ transport_pkt *pkt = (transport_pkt *)
pmt_u8vector_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/trunk/usrp/host/lib/inband/usrp_server.h
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_server.h 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_server.h 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -51,6 +51,13 @@
long d_ntx_chan;
long d_nrx_chan;
+ pmt_t d_usrp_dict;
+
+ bool d_fpga_debug;
+
+ long d_interp_tx;
+ long d_decim_rx;
+
// Keep track of the request IDs
struct rid_info {
pmt_t owner;
@@ -114,6 +121,11 @@
bool check_valid(mb_port_sptr port, long channel, std::vector<struct
channel_info> &chan_info, pmt_t signal_info);
void parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt);
long next_rid();
+ void initialize_registers();
+ void set_register(long reg, long val);
+ void read_register(long reg);
+ void check_register_initialization();
+ void reset_all_registers();
};
#endif /* INCLUDED_USRP_SERVER_H */
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_server.mbh
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_server.mbh 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_server.mbh 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -202,7 +202,7 @@
(:incoming
- (response-recv-raw-samples invocation-handle status samples timestamp
properties)
+ (response-recv-raw-samples invocation-handle status samples timestamp
channel properties)
;; samples is a uniform numeric vector. The contents of the sample
;; vector is treated as opaque and is passed from the FPGA
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_tx.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_tx.cc 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_tx.cc 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -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)
{
@@ -121,7 +133,7 @@
for(int i=0; i < n_packets; i++) {
if(d_disk_write) {
- if(pkts[i].chan() == 0x1f)
+ if(pkts[i].chan() == CONTROL_CHAN)
d_cs_ofile.write((const char *)&pkts[i],
transport_pkt::max_pkt_size());
else
d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_tx_stub.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_tx_stub.cc 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_tx_stub.cc 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -103,7 +103,7 @@
for(long i=0; i<n_packets; i++) {
if(d_disk_write) {
- if(pkts[i].chan() == 0x1f)
+ if(pkts[i].chan() == CONTROL_CHAN)
d_cs_ofile.write((const char *)&pkts[i],
transport_pkt::max_pkt_size());
else
d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
@@ -112,7 +112,7 @@
d_ofile.flush();
}
- if(pkts[i].chan() == 0x1f)
+ if(pkts[i].chan() == CONTROL_CHAN)
parse_cs(invocation_handle, pkts[i]);
}
@@ -140,7 +140,7 @@
transport_pkt *q_pkt =
(transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
- q_pkt->set_header(0, 0x1f, 0, 0);
+ q_pkt->set_header(0, CONTROL_CHAN, 0, 0);
q_pkt->set_timestamp(0xffffffff);
// We dispatch based on the control packet type, however we can extract the
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.cc 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.cc 2008-04-30
03:52:31 UTC (rev 8295)
@@ -47,12 +47,16 @@
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_fpga_debug(false),
d_fake_usrp(false),
+ d_rx_reading(false),
d_interp_tx(128),
d_decim_rx(128),
d_rf_freq(10e6),
@@ -86,7 +90,7 @@
d_interp_tx = pmt_to_long(interp_tx);
}
- // Read the RX interpolations
+ // Read the RX decimation rate
if(pmt_t decim_rx = pmt_dict_ref(usrp_dict,
pmt_intern("decim-rx"),
PMT_NIL)) {
@@ -134,8 +138,8 @@
d_tx_cs = define_port("tx_cs", "usrp-tx-cs", false, mb_port::INTERNAL);
// Connect to TX and RX
- define_component("tx", tx_interface, PMT_F);
- define_component("rx", rx_interface, PMT_F);
+ define_component("tx", tx_interface, usrp_dict);
+ define_component("rx", rx_interface, usrp_dict);
connect("self", "rx_cs", "rx", "cs");
connect("self", "tx_cs", "tx", "cs");
@@ -146,8 +150,6 @@
d_utx = NULL;
d_urx = NULL;
- d_fpga_debug=true; // WARNING: DO NOT ENABLE WITH D'BOARDS OTHER THAN
BASIC TX/RX
-
}
usrp_usb_interface::~usrp_usb_interface()
@@ -161,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)
{
@@ -256,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)
{
@@ -290,7 +303,7 @@
return;
}
- if(!d_utx->set_tx_freq (0,d_rf_freq)) { // try setting center freq to 0
+ if(!d_utx->set_tx_freq (0,d_rf_freq) || !d_utx->set_tx_freq(1,d_rf_freq)) {
// try setting center freq to 0
if (verbose)
std::cout << "[USRP_USB_INTERFACE] Failed to set center frequency on
TX\n";
reply_data = pmt_list2(invocation_handle, PMT_F);
@@ -298,6 +311,14 @@
return;
}
+ if(!d_utx->set_mux(0xBA98)) {
+ if (verbose)
+ std::cout << "[USRP_USB_INTERFACE] Failed to set TX mux\n";
+ reply_data = pmt_list2(invocation_handle, PMT_F);
+ d_cs->send(s_response_usrp_open, reply_data);
+ return;
+ }
+
d_utx->start();
if (verbose)
@@ -321,33 +342,44 @@
return;
}
- if(!d_urx->set_rx_freq (0, d_rf_freq)) {
+ if(!d_urx->set_rx_freq (0, -d_rf_freq) || !d_urx->set_rx_freq(1,
-d_rf_freq)) {
if (verbose)
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;
}
+
+ // Two channels ... this really needs to end up being set correctly by
+ // querying for what dboards are connected
+ if(!d_urx->set_mux(0x32103210)) {
+ if (verbose)
+ std::cout << "[USRP_USB_INTERFACE] Failed to set RX mux\n";
+ reply_data = pmt_list2(invocation_handle, PMT_F);
+ d_cs->send(s_response_usrp_open, reply_data);
+ return;
+ }
- if(d_fpga_debug) {
- d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf);
- d_utx->_write_oe(0, 0xffff, 0xffff);
- d_urx->_write_oe(0, 0xffff, 0xffff);
- d_utx->_write_oe(1, 0xffff, 0xffff);
- d_urx->_write_oe(1, 0xffff, 0xffff);
-
-// while(1){
-// for(int i=0; i<0xffff; i++)
-// d_urx->write_io(0, i, 0xffff);
-// }
- }
-
if (verbose)
std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
+
+// d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf);
+// d_utx->_write_oe(0, 0xffff, 0xffff);
+// d_urx->_write_oe(0, 0xffff, 0xffff);
+// d_utx->_write_oe(1, 0xffff, 0xffff);
+// d_urx->_write_oe(1, 0xffff, 0xffff);
d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
}
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * write data to the USB bus (cmd-usrp-write).
+ *
+ * The \p data parameter is a PMT list containing 3 mandatory elements in the
+ * following order: an invocation handle, channel, and a uniform vector
+ * representation of the packets.
+ */
void
usrp_usb_interface::handle_cmd_write(pmt_t data)
{
@@ -366,6 +398,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)
{
@@ -381,9 +420,18 @@
d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle));
+ d_rx_reading = true;
+
return;
}
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * stop reading data from the USB bus (cmd-usrp-stop-reading).
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
void
usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
{
@@ -392,22 +440,40 @@
if(!d_fake_usrp) {
if(verbose)
std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n";
+ usrp_rx_stop = true;
+
+ // Used to allow a read() being called by a lower layer to complete before
+ // stopping, else there can be partial data left on the bus and can
generate
+ // errors.
+ while(usrp_rx_stop) {usleep(1);}
d_urx->stop();
}
else {
if(verbose)
std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n";
- usrp_rx_stop = true; // extern to communicate with stub to wait
+ usrp_rx_stop_stub = true; // extern to communicate with stub to wait
}
+ d_rx_reading = false;
+
return;
}
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * close the USB connection to the USRP.
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
void
usrp_usb_interface::handle_cmd_close(pmt_t data)
{
pmt_t invocation_handle = pmt_nth(0, data);
+ if(d_rx_reading)
+ handle_cmd_stop_reading(PMT_NIL);
+
if(d_fake_usrp) {
d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
return;
Modified: gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.h
===================================================================
--- gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.h 2008-04-30
03:50:36 UTC (rev 8294)
+++ gnuradio/trunk/usrp/host/lib/inband/usrp_usb_interface.h 2008-04-30
03:52:31 UTC (rev 8295)
@@ -42,10 +42,10 @@
long d_ntx_chan;
long d_nrx_chan;
- long d_fpga_debug;
-
bool d_fake_usrp;
+ bool d_rx_reading;
+
long d_interp_tx;
long d_decim_rx;
Modified: gnuradio/trunk/usrp/host/lib/legacy/fusb_linux.cc
===================================================================
--- gnuradio/trunk/usrp/host/lib/legacy/fusb_linux.cc 2008-04-30 03:50:36 UTC
(rev 8294)
+++ gnuradio/trunk/usrp/host/lib/legacy/fusb_linux.cc 2008-04-30 03:52:31 UTC
(rev 8295)
@@ -386,15 +386,7 @@
{
if (!d_started)
return true;
-
- d_devhandle->_cancel_pending_rqsts (this);
- d_devhandle->_reap (false);
-
- usbdevfs_urb *urb;
- while ((urb = completed_list_get ()) != 0)
- free_list_add (urb);
-
if (d_write_work_in_progress){
free_list_add (d_write_work_in_progress);
d_write_work_in_progress = 0;
@@ -407,12 +399,20 @@
d_read_buffer_end = 0;
}
- if (d_free_list.size () != (unsigned) d_nblocks)
- fprintf (stderr, "d_free_list.size () = %d, d_nblocks = %d\n",
- d_free_list.size (), d_nblocks);
-
- assert (d_free_list.size () == (unsigned) d_nblocks);
+ d_devhandle->_cancel_pending_rqsts (this);
+ d_devhandle->_reap (false);
+ while (1){
+ usbdevfs_urb *urb;
+ while ((urb = completed_list_get ()) != 0)
+ free_list_add (urb);
+
+ if (d_free_list.size () == (unsigned) d_nblocks)
+ break;
+
+ d_devhandle->_reap(true);
+ }
+
d_started = false;
return true;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r8295 - in gnuradio/trunk: mblock/src/lib pmt/src/lib usrp/fpga usrp/fpga/inband_lib usrp/fpga/megacells usrp/fpga/rbf usrp/fpga/rbf/rev2 usrp/fpga/rbf/rev4 usrp/fpga/toplevel/usrp_inband_usb usrp/host/apps-inband usrp/host/lib/inband usrp/host/lib/legacy,
eb <=