Merged features/inband-usb -r6431:8293 into trunk.
authoreb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 30 Apr 2008 03:52:31 +0000 (03:52 +0000)
committereb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 30 Apr 2008 03:52:31 +0000 (03:52 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@8295 221aa14e-8319-0410-a670-987f0aec2ac5

65 files changed:
mblock/src/lib/mb_message.cc
pmt/src/lib/pmt.cc
pmt/src/lib/pmt.h
pmt/src/lib/pmt_pool.cc
pmt/src/lib/pmt_pool.h
pmt/src/lib/qa_pmt_prims.cc
pmt/src/lib/qa_pmt_prims.h
usrp/fpga/Makefile.extra
usrp/fpga/inband_lib/chan_fifo_reader.v
usrp/fpga/inband_lib/channel_demux.v
usrp/fpga/inband_lib/channel_ram.v
usrp/fpga/inband_lib/cmd_reader.v
usrp/fpga/inband_lib/data_packet_fifo.v [deleted file]
usrp/fpga/inband_lib/packet_builder.v
usrp/fpga/inband_lib/register_io.v
usrp/fpga/inband_lib/rx_buffer_inband.v
usrp/fpga/inband_lib/tx_buffer_inband.v
usrp/fpga/inband_lib/usb_fifo_reader.v [deleted file]
usrp/fpga/inband_lib/usb_fifo_writer.v [deleted file]
usrp/fpga/megacells/fifo_1kx16.bsf
usrp/fpga/megacells/fifo_1kx16.v
usrp/fpga/megacells/fifo_1kx16_bb.v
usrp/fpga/rbf/Makefile.am
usrp/fpga/rbf/rev2/inband_1rxhb_1tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev2/inband_2rxhb_2tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev4/inband_1rxhb_1tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev4/inband_2rxhb_2tx.rbf [new file with mode: 0755]
usrp/fpga/toplevel/usrp_inband_usb/config.vh
usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.qsf
usrp/fpga/toplevel/usrp_inband_usb/usrp_inband_usb.v
usrp/host/apps-inband/Makefile.am
usrp/host/apps-inband/gmac.cc [deleted file]
usrp/host/apps-inband/gmac.h [deleted file]
usrp/host/apps-inband/gmac.mbh [deleted file]
usrp/host/apps-inband/gmac_symbols.h [deleted file]
usrp/host/apps-inband/test_gmac_tx.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_2rx.cc [new file with mode: 0644]
usrp/host/apps-inband/test_usrp_inband_2tx.cc [new file with mode: 0644]
usrp/host/apps-inband/test_usrp_inband_cs.cc [deleted file]
usrp/host/apps-inband/test_usrp_inband_overrun.cc
usrp/host/apps-inband/test_usrp_inband_registers.cc
usrp/host/apps-inband/test_usrp_inband_rx.cc
usrp/host/apps-inband/test_usrp_inband_timestamps.cc
usrp/host/apps-inband/test_usrp_inband_tx.cc
usrp/host/apps-inband/test_usrp_inband_underrun.cc
usrp/host/lib/inband/Makefile.am
usrp/host/lib/inband/fake_usrp.cc [deleted file]
usrp/host/lib/inband/fake_usrp.h [deleted file]
usrp/host/lib/inband/qa_inband_usrp_server.cc
usrp/host/lib/inband/qa_inband_usrp_server.h
usrp/host/lib/inband/test_usrp_inband.cc [deleted file]
usrp/host/lib/inband/usrp_inband_usb_packet.cc
usrp/host/lib/inband/usrp_inband_usb_packet.h
usrp/host/lib/inband/usrp_rx.cc
usrp/host/lib/inband/usrp_rx.h
usrp/host/lib/inband/usrp_rx_stub.cc
usrp/host/lib/inband/usrp_rx_stub.h
usrp/host/lib/inband/usrp_server.cc
usrp/host/lib/inband/usrp_server.h
usrp/host/lib/inband/usrp_server.mbh
usrp/host/lib/inband/usrp_tx.cc
usrp/host/lib/inband/usrp_tx_stub.cc
usrp/host/lib/inband/usrp_usb_interface.cc
usrp/host/lib/inband/usrp_usb_interface.h
usrp/host/lib/legacy/fusb_linux.cc

index 0bce455ce0b0a72b80a545243971d33e6445b3e6..ce98a931e3ac5de1769bdb96e321b7f071fe8ba4 100644 (file)
 #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)
index a141224b30761285fd31b1e9437516ad09abae81..537b7a05a0b4165135fcc26a65948947a167268c 100644 (file)
@@ -962,6 +962,12 @@ pmt_list6(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4, pmt_t x5, pmt_t x6)
   return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, pmt_cons(x5, pmt_cons(x6, PMT_NIL))))));
 }
 
+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)
 {
index fa368a6a17eec1e27d5ed7f30c965121aba9b9da..970dd6c7d92b6305d5f4b75e5bc4cc74a90c5a05 100644 (file)
@@ -609,6 +609,11 @@ pmt_t pmt_list5(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4, pmt_t x5);
  */
 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);
+
 
 /*
  * ------------------------------------------------------------------------
index 8f1329a7ea50c7f7827b133d1087f8624a1e76a9..05d9c005bc6278407176e0d9cdb8c8251b4fedb2 100644 (file)
@@ -32,10 +32,13 @@ ROUNDUP(size_t x, size_t stride)
   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 @@ pmt_pool::malloc()
   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 @@ pmt_pool::malloc()
   // now return the first one
   p = d_freelist;
   d_freelist = p->d_next;
+  d_n_items++;
   return p;
 }
 
@@ -93,4 +103,7 @@ pmt_pool::free(void *foo)
   item *p = (item *) foo;
   p->d_next = d_freelist;
   d_freelist = p;
+  d_n_items--;
+  if (d_max_items != 0)
+    d_cond.signal();
 }
index ac0c07bb61fb9d3c2ff72ea6a5853b3e9771c39e..42276a14f0b1bc22e2667d7eeeb5aae9a13ba5bb 100644 (file)
@@ -38,10 +38,13 @@ class pmt_pool {
   };
   
   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 @@ public:
    * \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();
index 26b3e26d38bc0a764f40c8fafa08bac6ac400579..57db4a1a93da8cc1873dc32548341d1e4dd2b6bf 100644 (file)
@@ -301,6 +301,20 @@ qa_pmt_prims::test_io()
   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.
index be49a30e497e9ddd338b5fb4f80b4d10dcd5ce98..919fc2dca491428f3d90081a3bbc48cf6033e366 100644 (file)
@@ -40,6 +40,7 @@ class qa_pmt_prims : public CppUnit::TestCase {
   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 @@ class qa_pmt_prims : public CppUnit::TestCase {
   void test_dict();
   void test_any();
   void test_io();
+  void test_lists();
   void test_serialize();
 };
 
index 8154e2eb0db0d7923fa73f5cf733af6d4774608c..56df23c98baaa6036dfafa8f97e67e43fd721d1e 100644 (file)
@@ -4,14 +4,11 @@ EXTRA_DIST =                                         \
        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                        \
index a6edf2c60b6220f09622caa8345ba854e6e291c0..69da9ec5a02cca0e81697a7e9543b1fbe2ec87ef 100755 (executable)
 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
-    
-    //Samples format
-    // 16 bits interleaved complex samples
-    `define QI16                     4'b0
+   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
     
-    // 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 @@ module chan_fifo_reader
                    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 @@ module chan_fifo_reader
                        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 @@ module chan_fifo_reader
                             tx_q <= fifodata[31:16];
                         end 
                    endcase
-               end
+                 end
                
                default:
-               begin
-                                       //error handling
+                 begin
+                   //error handling
                    reader_state <= IDLE;
-               end
+                 end
            endcase
        end
    end
index d46be9397c6236df62172d9de9c48581edf850b7..cca5cdb65f825d19d6a1f0db3bd4906094a0da44 100644 (file)
@@ -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 @@ module channel_demux
                                                        NUM_CHAN : (usbdata_final[`CHANNEL]);
        
        always @(posedge txclk)
-       begin
+         begin
            if (reset)
              begin
               reader_state <= IDLE;
index 60450f02ddecc3448a0e46409fd9a8a2e16fa1c2..9621246c550c5b2cea34ec0a886fdebe215c6de4 100755 (executable)
 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
index 7604321e40abc3e47eba0c71d4dfa31574690c3e..b69ea02b7b9e103b52050ea8091bd4f761bfd74a 100755 (executable)
-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
-                        state <= IDLE;
+          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;
-                     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
+                        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;
-                               value1 <= value1 + 32'd1;
-                               if (value0[15:0] == value1[15:0])
-                                       state <= TEST;
-                       end
+            DELAY : 
+              begin
+                rdreq <= 0;
+                stop <= 1;
+                stop_time <= value0[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
diff --git a/usrp/fpga/inband_lib/data_packet_fifo.v b/usrp/fpga/inband_lib/data_packet_fifo.v
deleted file mode 100755 (executable)
index a9bcbda..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-module data_packet_fifo 
-  ( input       reset,
-    input       clock,
-    input       [31:0]ram_data_in,
-    input       write_enable,
-    output  reg have_space,
-    output  reg [31:0]ram_data_out,
-    output  reg pkt_waiting,
-       output  reg     isfull,
-       output  reg [1:0]usb_ram_packet_out,
-       output  reg [1:0]usb_ram_packet_in,
-    input       read_enable,
-    input       pkt_complete,
-    input       skip_packet) ;
-
-    /* Some parameters for usage later on */
-    parameter DATA_WIDTH = 32 ;
-    parameter PKT_DEPTH = 128 ;
-    parameter NUM_PACKETS = 4 ;
-
-    /* Create the RAM here */
-    reg [DATA_WIDTH-1:0] usb_ram [PKT_DEPTH*NUM_PACKETS-1:0] ;
-
-    /* Create the address signals */
-    reg [6:0] usb_ram_offset_out ;
-    //reg [1:0] usb_ram_packet_out ;
-    reg [6:0] usb_ram_offset_in ;
-    //reg [1:0] usb_ram_packet_in ;
-
-    wire [6-2+NUM_PACKETS:0] usb_ram_aout ;
-    wire [6-2+NUM_PACKETS:0] usb_ram_ain ;
-    //reg isfull;
-
-    assign usb_ram_aout = {usb_ram_packet_out, usb_ram_offset_out} ;
-    assign usb_ram_ain = {usb_ram_packet_in, usb_ram_offset_in} ;
-    
-    // Check if there is one full packet to process
-    always @(usb_ram_ain, usb_ram_aout, isfull)
-    begin
-        if (usb_ram_ain == usb_ram_aout)
-            pkt_waiting <= isfull ;
-        else if (usb_ram_ain > usb_ram_aout)
-            pkt_waiting <= (usb_ram_ain - usb_ram_aout) >= PKT_DEPTH;
-        else
-            pkt_waiting <= (usb_ram_ain + 10'b1000000000 - usb_ram_aout) >= PKT_DEPTH;
-    end
-    // Check if there is room
-    always @(usb_ram_ain, usb_ram_aout, isfull)
-    begin
-        if (usb_ram_ain == usb_ram_aout)
-            have_space <= ~isfull;   
-        else if (usb_ram_ain > usb_ram_aout)
-            have_space <= ((usb_ram_ain - usb_ram_aout) <= PKT_DEPTH * (NUM_PACKETS - 1))? 1'b1 : 1'b0;
-        else
-            have_space <= (usb_ram_aout - usb_ram_ain) >= PKT_DEPTH;
-    end
-
-
-
-    /* RAM Writing/Reading process */
-    always @(posedge clock)
-    begin
-        if( write_enable ) 
-          begin
-            usb_ram[usb_ram_ain] <= ram_data_in ;
-          end
-               ram_data_out <= usb_ram[usb_ram_aout] ;
-    end
-
-    /* RAM Write/Read Address process */
-    always @(posedge clock)
-    begin
-        if( reset ) 
-          begin
-            usb_ram_packet_out <= 0 ;
-            usb_ram_offset_out <= 0 ;
-                       usb_ram_offset_in <= 0 ;
-            usb_ram_packet_in <= 0 ;
-            isfull <= 0;
-          end
-        else
-                 begin
-            if( skip_packet )
-              begin
-                usb_ram_packet_out <= usb_ram_packet_out + 1 ;
-                usb_ram_offset_out <= 0 ;
-                isfull <= 0;
-              end
-            else if(read_enable) 
-                         begin
-                if( usb_ram_offset_out == 7'b1111111 )
-                  begin
-                    isfull <= 0 ;
-                    usb_ram_offset_out <= 0 ;
-                    usb_ram_packet_out <= usb_ram_packet_out + 1 ;
-                  end
-                else
-                    usb_ram_offset_out <= usb_ram_offset_out + 1 ;  
-              end
-                       if( pkt_complete )
-              begin
-                usb_ram_packet_in <= usb_ram_packet_in + 1 ;
-                usb_ram_offset_in <= 0 ;
-                if ((usb_ram_packet_in + 2'b1) == usb_ram_packet_out)
-                    isfull <= 1 ;
-              end
-            else if( write_enable ) 
-              begin
-                if (usb_ram_offset_in == 7'b1111111)
-                    usb_ram_offset_in <= 7'b1111111 ;    
-                else
-                    usb_ram_offset_in <= usb_ram_offset_in + 1 ;
-              end
-                 end
-    end
-
-endmodule
index fbf0a656ee4f25c84f1496c02b0e3a2becb5e682..2c9122394a76090e76e322baa5d0308a00e42aed 100755 (executable)
@@ -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 @@ module packet_builder #(parameter NUM_CHAN = 1)(
     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 @@ module packet_builder #(parameter NUM_CHAN = 1)(
     `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 = {chan_empty[0], rd_select[0], have_space, 
+                       (chan_usedw >= 10'd504), (chan_usedw ==0),  
+                       ready_to_send, state[1:0]};
 
-       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 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 @@ module packet_builder #(parameter NUM_CHAN = 1)(
             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
index b116b3acec9ab10661d4b4f8b058730e2c32e705..2b0cd1732d6e9536f92ed3cab203d5056d2adc38 100755 (executable)
@@ -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 @@ module register_io
                 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      
index 1eaecabedd32b3d32be7efc07ae8d90c49258aae..cbd2d89589a4f798a2cf763979051827684cc464 100755 (executable)
-//`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"\r
+//`include "../../firmware/include/fpga_regs_standard.v"\r
+module rx_buffer_inband\r
+  ( input usbclk,\r
+    input bus_reset,\r
+    input reset,  // DSP side reset (used here), do not reset registers\r
+    input reset_regs, //Only reset registers\r
+    output [15:0] usbdata,\r
+    input RD,\r
+    output wire have_pkt_rdy,\r
+    output reg rx_overrun,\r
+    input wire [3:0] channels,\r
+    input wire [15:0] ch_0,\r
+    input wire [15:0] ch_1,\r
+    input wire [15:0] ch_2,\r
+    input wire [15:0] ch_3,\r
+    input wire [15:0] ch_4,\r
+    input wire [15:0] ch_5,\r
+    input wire [15:0] ch_6,\r
+    input wire [15:0] ch_7,\r
+    input rxclk,\r
+    input rxstrobe,\r
+    input clear_status,\r
+    input [6:0] serial_addr, \r
+    input [31:0] serial_data, \r
+    input serial_strobe,\r
+    output wire [15:0] debugbus,\r
+       \r
+    //Connection with tx_inband\r
+    input rx_WR,\r
+    input [15:0] rx_databus,\r
+    input rx_WR_done,\r
+    output reg rx_WR_enabled,\r
+    //signal strength\r
+    input wire [31:0] rssi_0, input wire [31:0] rssi_1,\r
+    input wire [31:0] rssi_2, input wire [31:0] rssi_3,\r
+    input wire [1:0] tx_underrun\r
+    );\r
+    \r
+    parameter NUM_CHAN = 1;\r
+    genvar i ;\r
+    \r
+    // FX2 Bug Fix\r
+    reg [8:0] read_count;\r
+    always @(negedge usbclk)\r
+        if(bus_reset)\r
+            read_count <= #1 9'd0;\r
+        else if(RD & ~read_count[8])\r
+            read_count <= #1 read_count + 9'd1;\r
+        else\r
+            read_count <= #1 RD ? read_count : 9'b0;\r
+       \r
+       // Time counter\r
+       reg [31:0] timestamp_clock;\r
+       always @(posedge rxclk)\r
+               if (reset)\r
+                       timestamp_clock <= 0;\r
+               else\r
+                       timestamp_clock <= timestamp_clock + 1;\r
+     \r
+  // USB side fifo\r
+  wire [11:0] rdusedw;\r
+  wire [11:0] wrusedw;\r
+  wire [15:0] fifodata;\r
+  wire [15:0] fifodata_il[0:NUM_CHAN];\r
+  wire WR;\r
+  wire have_space;\r
+  reg sel;\r
+  reg wr;\r
+\r
+  always@(posedge rxclk)\r
+    begin\r
+      if(reset)\r
+        begin\r
+          sel<=1;\r
+          wr<=0;\r
+        end\r
+      else if(rxstrobe)\r
+        begin\r
+          sel<=0;\r
+          wr<=1;\r
+        end\r
+      else if(wr&~sel)\r
+          sel<=1;\r
+      else if(wr&sel)\r
+          wr<=0;\r
+      else\r
+          wr<=0;\r
+    end\r
+\r
+  assign fifodata_il[0] = (sel)?ch_1:ch_0;\r
+  assign fifodata_il[1] = (sel)?ch_3:ch_2;\r
+\r
+  fifo_4kx16_dc        rx_usb_fifo (\r
+    .aclr ( reset ),\r
+    .data ( fifodata ),\r
+    .rdclk ( ~usbclk ),\r
+    .rdreq ( RD & ~read_count[8] ),\r
+    .wrclk ( rxclk ),\r
+    .wrreq ( WR ),\r
+    .q ( usbdata ),\r
+    .rdempty (  ),\r
+    .rdusedw ( rdusedw ),\r
+    .wrfull (  ),\r
+    .wrusedw ( wrusedw ) );\r
+    \r
+  assign have_pkt_rdy = (rdusedw >= 12'd256);\r
+  assign have_space = (wrusedw < 12'd760);\r
+        \r
+  // Rx side fifos\r
+  // These are of size [NUM_CHAN:0] because the extra channel is used for the\r
+  // RX command channel.  If there were no command channel, they would be\r
+  // NUM_CHAN-1.\r
+  wire chan_rdreq;\r
+  wire [15:0] chan_fifodata;\r
+  wire [9:0] chan_usedw;\r
+  wire [NUM_CHAN:0] chan_empty;\r
+  wire [3:0] rd_select;\r
+  wire [NUM_CHAN:0] rx_full;\r
+        \r
+  packet_builder #(NUM_CHAN) rx_pkt_builer (\r
+    .rxclk ( rxclk ),\r
+    .reset ( reset ),\r
+    .timestamp_clock ( timestamp_clock ),\r
+    .channels ( NUM_CHAN ),\r
+    .chan_rdreq ( chan_rdreq ),\r
+    .chan_fifodata ( chan_fifodata ),\r
+    .chan_empty ( chan_empty ),\r
+    .rd_select ( rd_select ),\r
+    .chan_usedw ( chan_usedw ),\r
+    .WR ( WR ),\r
+    .fifodata ( fifodata ),\r
+    .have_space ( have_space ),\r
+      .rssi_0(rssi_0), .rssi_1(rssi_1),\r
+      .rssi_2(rssi_2),.rssi_3(rssi_3), .debugbus(debug),\r
+      .underrun(tx_underrun));\r
+        \r
+  // Detect overrun\r
+  always @(posedge rxclk)\r
+    if(reset)\r
+      rx_overrun <= 1'b0;\r
+    else if(rx_full[0])\r
+      rx_overrun <= 1'b1;\r
+    else if(clear_status)\r
+      rx_overrun <= 1'b0;\r
+\r
+               \r
+  // FIXME: what is the purpose of these two lines?\r
+  wire [15:0]ch[NUM_CHAN:0];\r
+  assign ch[0] = ch_0;\r
+       \r
+  wire cmd_empty;\r
+       \r
+  always @(posedge rxclk)\r
+    if(reset)\r
+      rx_WR_enabled <= 1;\r
+    else if(cmd_empty)\r
+      rx_WR_enabled <= 1;\r
+    else if(rx_WR_done)\r
+      rx_WR_enabled <= 0;\r
+\r
+\r
+  // Of Size 0:NUM_CHAN due to extra command channel.\r
+  wire [15:0] dataout [0:NUM_CHAN];\r
+  wire [9:0]  usedw    [0:NUM_CHAN];\r
+  wire empty[0:NUM_CHAN];\r
+       \r
+  generate for (i = 0 ; i < NUM_CHAN; i = i + 1)\r
+    begin : generate_channel_fifos\r
+\r
+      wire rdreq;\r
+\r
+      assign rdreq = (rd_select == i) & chan_rdreq;\r
+\r
+      fifo_1kx16 rx_chan_fifo (\r
+      .aclr ( reset ),\r
+      .clock ( rxclk ),\r
+      .data ( fifodata_il[i] ),\r
+      .rdreq ( rdreq ),\r
+      .wrreq ( ~rx_full[i] & wr),\r
+      .empty (empty[i]),\r
+      .full (rx_full[i]),\r
+      .q ( dataout[i]),\r
+      .usedw ( usedw[i]),\r
+      .almost_empty(chan_empty[i])\r
+      );\r
+    end\r
+  endgenerate\r
+       \r
+  wire [7:0] debug;\r
+        \r
+  fifo_1kx16 rx_cmd_fifo (\r
+    .aclr ( reset ),\r
+    .clock ( rxclk ),\r
+    .data ( rx_databus ),\r
+    .rdreq ( (rd_select == NUM_CHAN) & chan_rdreq ),\r
+    .wrreq ( rx_WR & rx_WR_enabled),\r
+    .empty ( cmd_empty),\r
+    .full ( rx_full[NUM_CHAN] ),\r
+    .q ( dataout[NUM_CHAN]),\r
+    .usedw ( usedw[NUM_CHAN] )\r
+  );\r
+       \r
+  assign chan_empty[NUM_CHAN] = cmd_empty | rx_WR_enabled;\r
+  assign chan_fifodata = dataout[rd_select];\r
+  assign chan_usedw = usedw[rd_select];\r
+  assign debugbus = {4'd0, rxclk, rxstrobe, rx_full[0], rx_full[1], sel, wr};\r
+\r
+endmodule\r
index fec9dbe3134e573fbc9bdf93b891e0a7fdcb45ba..2dd75f42f2df93a08a8013893815258fb99f1c80 100755 (executable)
 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
 
diff --git a/usrp/fpga/inband_lib/usb_fifo_reader.v b/usrp/fpga/inband_lib/usb_fifo_reader.v
deleted file mode 100755 (executable)
index d002d90..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-module usb_fifo_reader (
-      input usbclk,
-      input bus_reset, 
-      input RD,
-      output rdreq,
-      );
-      
-    // 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;
-            
-    assign rdreq = RD & ~read_count[8];
-    
-    
-endmodule
-       
-   
-   
\ No newline at end of file
diff --git a/usrp/fpga/inband_lib/usb_fifo_writer.v b/usrp/fpga/inband_lib/usb_fifo_writer.v
deleted file mode 100755 (executable)
index abe1dd5..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-
-module usb_fifo_writer
-   #(parameter BUS_WIDTH = 16,
-     parameter NUM_CHAN = 2,
-     parameter FIFO_WIDTH = 32)
-   (     //FX2 Side
-                       input bus_reset, 
-                       input usbclk, 
-                       input WR_fx2, 
-                       input [15:0]usbdata,
-                       
-                       // TX Side
-                       input reset,
-                       input txclk,
-                       output reg [NUM_CHAN:0] WR_channel,
-                       output reg [FIFO_WIDTH-1:0] ram_data,
-                       output reg [NUM_CHAN:0] WR_done_channel );
-   
-
-       reg [8:0] write_count;
-
-       /* Fix FX2 bug */
-       always @(posedge usbclk)
-       if(bus_reset)        // Use bus reset because this is on usbclk
-                       write_count <= #1 0;
-       else if(WR_fx2 & ~write_count[8])
-               write_count <= #1 write_count + 9'd1;
-       else
-               write_count <= #1 WR_fx2 ? write_count : 9'b0;
-
-       reg WR_fx2_fixed;
-       reg [15:0]usbdata_fixed;
-       
-       always @(posedge usbclk) 
-       begin
-          WR_fx2_fixed <= WR_fx2 & ~write_count[8];
-          usbdata_fixed <= usbdata;
-       end
-
-       /* Used to convert 16 bits bus_data to the 32 bits wide fifo */
-    reg                             word_complete ;
-    reg     [BUS_WIDTH-1:0]         usbdata_delayed ;
-    reg                             writing ;
-       wire    [FIFO_WIDTH-1:0]                usbdata_packed ;    
-       wire                                                    WR_packed ;
-   
-    always @(posedge usbclk)
-    begin
-        if (bus_reset)
-          begin
-            word_complete <= 0 ;
-            writing <= 0 ;
-          end
-        else if (WR_fx2_fixed)
-          begin
-            writing <= 1 ;
-            if (word_complete)
-                word_complete <= 0 ;
-            else
-              begin
-                usbdata_delayed <= usbdata_fixed ;
-                word_complete <= 1 ;
-              end
-          end
-        else
-            writing <= 0 ;
-       end
-    
-       assign usbdata_packed = {usbdata_fixed, usbdata_delayed} ;
-    assign WR_packed = word_complete & writing ;
-
-       /* Make sure data are sync with usbclk */
-       reg [31:0]usbdata_usbclk;
-       reg WR_usbclk; 
-    
-    always @(posedge usbclk)
-    begin
-       if (WR_packed)
-               usbdata_usbclk <= usbdata_packed;
-        WR_usbclk <= WR_packed;
-    end
-
-       /* Cross clock boundaries */
-       reg [FIFO_WIDTH-1:0] usbdata_tx ;
-       reg WR_tx;
-    reg WR_1;
-    reg WR_2;
-       reg [31:0] usbdata_final;
-       reg WR_final;
-   
-       always @(posedge txclk) usbdata_tx <= usbdata_usbclk;
-
-    always @(posedge txclk) 
-       if (reset)
-               WR_1 <= 0;
-       else
-                       WR_1 <= WR_usbclk;
-
-    always @(posedge txclk) 
-       if (reset)
-                       WR_2 <= 0;
-       else
-               WR_2 <= WR_1;
-
-       always @(posedge txclk)
-       begin
-               if (reset)
-                       WR_tx <= 0;
-               else
-                  WR_tx <= WR_1 & ~WR_2;
-       end
-       
-       always @(posedge txclk)
-       begin
-          if (reset)
-             WR_final <= 0;
-          else
-          begin
-             WR_final <= WR_tx; 
-             if (WR_tx)
-                usbdata_final <= usbdata_tx;
-          end
-       end
-            
-       /* Parse header and forward to ram */
-       reg [3:0]reader_state;
-       reg [4:0]channel ;
-       reg [9:0]read_length ;
-       
-       parameter IDLE = 4'd0;
-       parameter HEADER = 4'd1;
-       parameter WAIT = 4'd2;
-       parameter FORWARD = 4'd3;
-       
-       `define CHANNEL 20:16
-       `define PKT_SIZE 512
-       
-       always @(posedge txclk)
-       begin
-           if (reset)
-             begin
-              reader_state <= 0;
-              WR_channel <= 0;
-              WR_done_channel <= 0;
-             end
-             else
-               case (reader_state)
-               IDLE: begin
-                   if (WR_final)
-                       reader_state <= HEADER; 
-                   end
-              
-            // Store channel and forware header
-               HEADER: begin
-                   channel <= (usbdata_final[`CHANNEL] == 5'h1f ? NUM_CHAN : usbdata_final[`CHANNEL]) ;
-                   WR_channel[(usbdata_final[`CHANNEL] == 5'h1f ? NUM_CHAN : usbdata_final[`CHANNEL])] <= 1;
-                               //channel <= usbdata_final[`CHANNEL] ;
-                   //WR_channel[usbdata_final[`CHANNEL]] <= 1;
-                   ram_data <= usbdata_final;
-                               read_length <= 10'd4 ;
-                               
-                reader_state <= WAIT;
-               end
-              
-               WAIT: begin
-                  WR_channel[channel] <= 0;
-       
-                          if (read_length == `PKT_SIZE)
-                      reader_state <= IDLE;
-                  else if (WR_final)
-                      reader_state <= FORWARD;
-               end
-              
-               FORWARD: begin
-                  WR_channel[channel] <= 1;
-                  ram_data <= usbdata_final;
-                  read_length <= read_length + 10'd4;
-                  
-                  reader_state <= WAIT;
-               end
-              endcase
-       end
-endmodule  
\ No newline at end of file
index 329be2d4457d7241c5cacf159d487086f3805caa..2de80816f6967c3df20a55c7e88a0b3703bb63b3 100755 (executable)
@@ -95,7 +95,7 @@ applicable agreement for further details.
        )\r
        (drawing\r
                (text "16 bits x 1024 words" (rect 58 132 144 144)(font "Arial" ))\r
-               (text "almost_empty < 126" (rect 58 122 144 134)(font "Arial" ))\r
+               (text "almost_empty < 504" (rect 58 122 144 134)(font "Arial" ))\r
                (line (pt 16 16)(pt 144 16)(line_width 1))\r
                (line (pt 144 16)(pt 144 144)(line_width 1))\r
                (line (pt 144 144)(pt 16 144)(line_width 1))\r
index e22b416e5bb9f31fcf69a7e64d8926f9df7d20f1..4f7e94ef5d132fa3929a7ed72536039e3ebbc149 100755 (executable)
@@ -86,7 +86,7 @@ module fifo_1kx16 (
                                );\r
        defparam\r
                scfifo_component.add_ram_output_register = "OFF",\r
-               scfifo_component.almost_empty_value = 126,\r
+               scfifo_component.almost_empty_value = 504,\r
                scfifo_component.intended_device_family = "Cyclone",\r
                scfifo_component.lpm_hint = "RAM_BLOCK_TYPE=M4K",\r
                scfifo_component.lpm_numwords = 1024,\r
@@ -105,7 +105,7 @@ endmodule
 // CNX file retrieval info\r
 // ============================================================\r
 // Retrieval info: PRIVATE: AlmostEmpty NUMERIC "1"\r
-// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "126"\r
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "504"\r
 // Retrieval info: PRIVATE: AlmostFull NUMERIC "0"\r
 // Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"\r
 // Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"\r
@@ -133,7 +133,7 @@ endmodule
 // Retrieval info: PRIVATE: wsFull NUMERIC "1"\r
 // Retrieval info: PRIVATE: wsUsedW NUMERIC "0"\r
 // Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"\r
-// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "126"\r
+// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "504"\r
 // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"\r
 // Retrieval info: CONSTANT: LPM_HINT STRING "RAM_BLOCK_TYPE=M4K"\r
 // Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"\r
index 283aada818d6fb72b2095b43d486cb754dada11a..9d9912bc29d5313309ede234992d0d178d825c6e 100755 (executable)
@@ -57,7 +57,7 @@ endmodule
 // CNX file retrieval info\r
 // ============================================================\r
 // Retrieval info: PRIVATE: AlmostEmpty NUMERIC "1"\r
-// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "126"\r
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "504"\r
 // Retrieval info: PRIVATE: AlmostFull NUMERIC "0"\r
 // Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"\r
 // Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"\r
@@ -85,7 +85,7 @@ endmodule
 // Retrieval info: PRIVATE: wsFull NUMERIC "1"\r
 // Retrieval info: PRIVATE: wsUsedW NUMERIC "0"\r
 // Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"\r
-// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "126"\r
+// Retrieval info: CONSTANT: ALMOST_EMPTY_VALUE NUMERIC "504"\r
 // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"\r
 // Retrieval info: CONSTANT: LPM_HINT STRING "RAM_BLOCK_TYPE=M4K"\r
 // Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "1024"\r
index 49d2f2592e16af8ce980f1d8a7b41a756769c776..c7c9ce670c082e1b9181d6462234f2983b5bc491 100644 (file)
@@ -26,8 +26,12 @@ datadir = $(prefix)/share/usrp
 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                
 
diff --git a/usrp/fpga/rbf/rev2/inband_1rxhb_1tx.rbf b/usrp/fpga/rbf/rev2/inband_1rxhb_1tx.rbf
new file mode 100755 (executable)
index 0000000..c1c9af2
Binary files /dev/null and b/usrp/fpga/rbf/rev2/inband_1rxhb_1tx.rbf differ
diff --git a/usrp/fpga/rbf/rev2/inband_2rxhb_2tx.rbf b/usrp/fpga/rbf/rev2/inband_2rxhb_2tx.rbf
new file mode 100755 (executable)
index 0000000..ca1a0f9
Binary files /dev/null and b/usrp/fpga/rbf/rev2/inband_2rxhb_2tx.rbf differ
diff --git a/usrp/fpga/rbf/rev4/inband_1rxhb_1tx.rbf b/usrp/fpga/rbf/rev4/inband_1rxhb_1tx.rbf
new file mode 100755 (executable)
index 0000000..c1c9af2
Binary files /dev/null and b/usrp/fpga/rbf/rev4/inband_1rxhb_1tx.rbf differ
diff --git a/usrp/fpga/rbf/rev4/inband_2rxhb_2tx.rbf b/usrp/fpga/rbf/rev4/inband_2rxhb_2tx.rbf
new file mode 100755 (executable)
index 0000000..ca1a0f9
Binary files /dev/null and b/usrp/fpga/rbf/rev4/inband_2rxhb_2tx.rbf differ
index 3291dc10b8db49abab55152c8ede3dcd22570dde..007a529e3f0b2b66781faeab567620daf0aeec58 100644 (file)
@@ -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"
index c9eebc1ada9d4ad2fd25abb29d1553613ddca2ba..ae0807f6fc12048390e3f30ed50a70608495141e 100644 (file)
@@ -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/ram16_2sum.v
 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/serial_io.v
 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
index cc625b0e765a48df534f2a0103291dbcfa51f8f3..79f0dfa4ac2ca67d22c5ab8f6a7f8f4cddbbb8c5 100644 (file)
@@ -97,8 +97,6 @@ module usrp_inband_usb
    // 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 @@ module usrp_inband_usb
    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 @@ wire [1:0] tx_underrun;
           .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 @@ wire [1:0] tx_underrun;
        .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 @@ wire [1:0] tx_underrun;
    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 @@ wire [1:0] tx_underrun;
        .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
index 86bb40618110f5ed5c9272ea75e79fdd65013532..f231b57f7a26ec7395e636f0398f6e544d6d536e 100644 (file)
@@ -30,46 +30,31 @@ AM_CPPFLAGS =       \
 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_underrun_LDADD       = $(USRP_LA) $(USRP_INBAND_LA)
 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)
diff --git a/usrp/host/apps-inband/gmac.cc b/usrp/host/apps-inband/gmac.cc
deleted file mode 100644 (file)
index 107582e..0000000
+++ /dev/null
@@ -1,690 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gmac.h>
-
-#include <mb_mblock.h>
-#include <mb_runtime.h>
-#include <mb_protocol_class.h>
-#include <mb_exception.h>
-#include <mb_msg_queue.h>
-#include <mb_message.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>
-#include <symbols_usrp_rx.h>
-
-#include <gmac_symbols.h>
-
-static bool verbose = true;
-
-gmac::gmac(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg),
-    d_us_rx_chan(PMT_NIL), d_us_tx_chan(PMT_NIL)
-{
-
-  // When the MAC layer is initialized, we must connect to the USRP and setup
-  // channels.  We begin by defining ports to connect to the 'usrp_server' block
-  // and then initialize the USRP by opening it through the 'usrp_server.'
-
-  // Initialize the ports
-  define_ports();
-
-  // Initialize the connection to the USRP
-  initialize_usrp();
-
-}
-
-gmac::~gmac()
-{
-}
-
-// The full functionality of GMAC is based on messages passed back and forth
-// between the application and a physical layer and/or usrp_server.  Each
-// message triggers additional events, states, and messages to be sent.
-void gmac::handle_message(mb_message_sptr msg)
-{
-
-  // The MAC functionality is dispatched based on the event, which is the
-  // driving force of the MAC.  The event can be anything from incoming samples
-  // to a message to change the carrier sense threshold.
-  pmt_t event = msg->signal();
-  pmt_t data = msg->data();
-  pmt_t port_id = msg->port_id();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  pmt_t dict = PMT_NIL;
-  std::string error_msg;
-
-  switch(d_state) {
-    
-    //---------------------------- INIT ------------------------------------//
-    // In the INIT state, there should be no messages across the ports. 
-    case INIT:
-      error_msg = "no messages should be passed during the INIT state:"; 
-      goto unhandled;
-
-    //-------------------------- OPENING USRP -------------------------------//
-    // In this state we expect a response from usrp_server over the CS channel
-    // as to whether or not the opening of the USRP was successful.  If so, we
-    // switch states to allocating the channels for use.
-    case OPENING_USRP:
-
-      if(pmt_eq(event, s_response_open)
-          && pmt_eq(d_us_cs->port_symbol(), port_id)) {
-
-        status = pmt_nth(1, data);          // PMT_T or PMT_F
-
-        if(pmt_eq(status, PMT_T)) {         // on success, allocate channels!
-          allocate_channels();
-          return;
-        }
-        else {
-          error_msg = "failed to open usrp:";
-          goto bail;
-        }
-
-      }
-
-      goto unhandled;   // all other messages not handled in this state
-
-    //------------------------ ALLOCATING CHANNELS --------------------------//
-    // When allocating channels, we need to wait for 2 responses from USRP
-    // server: one for TX and one for RX.  Both are initialized to NIL so we
-    // know to continue to the next state once both are set.
-    case ALLOCATING_CHANNELS:
-
-      // ************* TX ALLOCATION RESPONSE ***************** //
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_us_tx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        if(pmt_eq(status, PMT_T)) {   // extract channel on success
-          d_us_tx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[GMAC] Received TX allocation"
-                      << " on channel " << d_us_tx_chan << std::endl;
-
-          // If the RX has also been allocated already, we can continue
-          if(!pmt_eqv(d_us_rx_chan, PMT_NIL)) {
-            //enter_receiving();
-            initialize_gmac();
-          }
-
-          return;
-        }
-        else {  // TX allocation failed
-          error_msg = "failed to allocate TX channel:";
-          goto bail;
-        }
-      }
-      
-      // ************* RX ALLOCATION RESPONSE ****************//
-      if(pmt_eq(event, s_response_allocate_channel)
-          && pmt_eq(d_us_rx->port_symbol(), port_id)) 
-      {
-        status = pmt_nth(1, data);
-        
-        if(pmt_eq(status, PMT_T)) {
-          
-          d_us_rx_chan = pmt_nth(2, data);
-
-          if(verbose)
-            std::cout << "[GMAC] Received RX allocation"
-                      << " on channel " << d_us_rx_chan << std::endl;
-
-          // If the TX has also been allocated already, we can continue
-          if(!pmt_eqv(d_us_tx_chan, PMT_NIL)) {
-            //enter_receiving();
-            initialize_gmac();
-          }
-
-          return;
-        }
-        else {  // RX allocation failed
-          error_msg = "failed to allocate RX channel:";
-          goto bail;
-        }
-      }
-
-      goto unhandled;
-    
-    //----------------------------- INIT GMAC --------------------------------//
-    // In the INIT_GMAC state, now that the USRP is initialized we can do things
-    // like right the carrier sense threshold to the FPGA register.
-    case INIT_GMAC:
-      goto unhandled;
-
-    
-    //----------------------------- IDLE ------------------------------------//
-    // In the idle state the MAC is not quite 'idle', it is just not doing
-    // anything specific.  It is still being passive with data between the
-    // application and the lower layer.
-    case IDLE:
-      
-      //-------- TX PORT ----------------------------------------------------//
-      if(pmt_eq(d_tx->port_symbol(), port_id)) {
-
-        //-------- INCOMING PACKET ------------------------------------------//
-        if(pmt_eq(event, s_cmd_tx_pkt)) {
-          handle_cmd_tx_pkt(data);
-          return;
-        }
-
-      }
-
-      //--------- USRP TX PORT ----------------------------------------------//
-      if(pmt_eq(d_us_tx->port_symbol(), port_id)) {
-
-        //-------- INCOMING PACKET RESPONSE ---------------------------------//
-        if(pmt_eq(event, s_response_xmit_raw_frame)) {
-          handle_response_xmit_raw_frame(data);
-          return;
-        }
-
-      }
-
-      //--------- CS PORT ---------------------------------------------------//
-      if(pmt_eq(d_cs->port_symbol(), port_id)) {
-        
-        //------- ENABLE CARRIER SENSE --------------------------------------//
-        if(pmt_eq(event, s_cmd_carrier_sense_enable)) {
-          handle_cmd_carrier_sense_enable(data);
-          return;
-        }
-        
-        //------- CARRIER SENSE THRESHOLD -----------------------------------//
-        if(pmt_eq(event, s_cmd_carrier_sense_threshold)) {
-          handle_cmd_carrier_sense_threshold(data);
-          return;
-        }
-
-        //------- CARRIER SENSE DEADLINE ------------------------------------//
-        if(pmt_eq(event, s_cmd_carrier_sense_deadline)) {
-          handle_cmd_carrier_sense_deadline(data);
-          return;
-        }
-
-        //------- DISABLE CARRIER SENSE -------------------------------------//
-        if(pmt_eq(event, s_cmd_carrier_sense_disable)) {
-          handle_cmd_carrier_sense_disable(data);
-          return;
-        }
-
-      }
-
-      goto unhandled;
-
-    //------------------------ CLOSING CHANNELS -----------------------------//
-    case CLOSING_CHANNELS:
-
-      if (pmt_eq(event, s_response_deallocate_channel)
-          && pmt_eq(d_us_tx->port_symbol(), port_id))
-      {
-        status = pmt_nth(1, data);
-
-        if(pmt_eq(status, PMT_T)) {
-          d_us_tx_chan = PMT_NIL;
-
-          if(verbose)
-            std::cout << "[GMAC] Received TX deallocation\n";
-
-          // If the RX is also deallocated, we can close the USRP
-          if(pmt_eq(d_us_rx_chan, PMT_NIL)) 
-            close_usrp();
-
-          return;
-
-        } else {
-
-          error_msg = "failed to deallocate TX channel:";
-          goto bail;
-
-        }
-      }
-
-      if (pmt_eq(event, s_response_deallocate_channel)
-          && pmt_eq(d_us_rx->port_symbol(), port_id))
-      {
-        status = pmt_nth(1, data);
-
-        // If successful, set the port to NIL
-        if(pmt_eq(status, PMT_T)) {
-          d_us_rx_chan = PMT_NIL;
-
-          if(verbose)
-            std::cout << "[GMAC] Received RX deallocation\n";
-
-          // If the TX is also deallocated, we can close the USRP
-          if(pmt_eq(d_us_tx_chan, PMT_NIL)) 
-            close_usrp();
-
-          return;
-
-        } else {
-          
-          error_msg = "failed to deallocate RX channel:";
-          goto bail;
-
-        }
-      }
-
-      goto unhandled;
-
-    //-------------------------- CLOSING USRP -------------------------------//
-    case CLOSING_USRP:
-      goto unhandled;
-      
-  }
-  
- // 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(0 && verbose && !pmt_eq(event, pmt_intern("%shutdown")))
-    std::cout << "[GMAC] unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-}
-
-// The MAC layer connects to 'usrp_server' which has a control/status channel,
-// a TX, and an RX port.  The MAC layer can then relay TX/RX data back and
-// forth to the application, or a physical layer once available.
-void gmac::define_ports()
-{
-  // Ports we use to connect to usrp_server
-  d_us_tx = define_port("us-tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_us_rx = define_port("us-rx0", "usrp-rx", false, mb_port::INTERNAL);
-  d_us_cs = define_port("us-cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  // Ports applications used to connect to us
-  d_tx = define_port("tx0", "gmac-tx", true, mb_port::EXTERNAL);
-  d_rx = define_port("rx0", "gmac-rx", true, mb_port::EXTERNAL);
-  d_cs = define_port("cs", "gmac-cs", true, mb_port::EXTERNAL);
-}
-
-// To initialize the USRP we must pass several parameters to 'usrp_server' such
-// as the RBF to use, and the interpolation/decimation rate.  The MAC layer will
-// then pass these parameters to the block with a message to establish the
-// connection to the USRP.
-void gmac::initialize_usrp()
-{
-
-  if(verbose)
-    std::cout << "[GMAC] Initializing USRP\n";
-
-  // The initialization parameters are passed to usrp_server via a PMT
-  // dictionary.
-  pmt_t usrp_dict = pmt_make_dict();
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("test2.rbf"));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("interp-tx"),
-               pmt_from_long(128));
-
-  pmt_dict_set(usrp_dict,
-               pmt_intern("decim-rx"),
-               pmt_from_long(16));
-  
-  // Center frequency
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rf-freq"),
-               pmt_from_long((long)10e6));
-
-  // Default is to use USRP considered '0' (incase of multiple)
-  d_which_usrp = pmt_from_long(0);
-  
-  define_component("USRP-SERVER", "usrp_server", usrp_dict);
-  
-  connect("self", "us-tx0", "USRP-SERVER", "tx0");
-  connect("self", "us-rx0", "USRP-SERVER", "rx0");
-  connect("self", "us-cs", "USRP-SERVER", "cs");
-
-  // Finally, enter the OPENING_USRP state by sending a request to open the
-  // USRP.
-  open_usrp();
-
-}
-
-// In the initialization state of the MAC layer we set default values for
-// several functionalities.
-void gmac::initialize_gmac()
-{
-
-  // The initial state is the INIT state.
-  d_state = INIT_GMAC;
-
-  // Set carrier sense to enabled by default with the specified threshold and
-  // the deadline to 0 -- which is wait forever.
-  set_carrier_sense(true, 25, 0, PMT_NIL);
-
-  // Can now notify the application that we are initialized
-  d_cs->send(s_response_gmac_initialized,
-             pmt_list2(PMT_NIL, PMT_T));
-
-  // The MAC enters an IDLE state where it waits for messages and dispatches
-  // based on them
-  enter_idle();
-}
-
-// Method for setting the carrier sense and an associated threshold which is
-// written to a register on the FPGA, which it will read if the CS flag is set
-// and perform carrier sense based on.
-//
-// We currently do not wait for the successful response for the write to
-// register command, we assume it will succeed else the MAC must
-void gmac::set_carrier_sense(bool toggle, long threshold, long deadline, pmt_t invocation)
-{
-  d_carrier_sense = toggle;
-
-  // Only waste the bandwidth and processing of a C/S packet if needed
-  if(threshold != d_cs_thresh) {
-    d_us_tx->send(s_cmd_to_control_channel,    // C/S packet
-               pmt_list2(invocation,           // invoc handle
-                         pmt_list1(
-                              pmt_list2(s_op_write_reg, 
-                                        pmt_list2(
-                                        pmt_from_long(REG_CS_THRESH), 
-                                        pmt_from_long(threshold))))));
-    d_cs_thresh = threshold;
-
-    if(verbose)
-      std::cout << "[GMAC] Changing CS threshold: " << d_cs_thresh << std::endl;
-  }
-
-  if(deadline != d_cs_deadline) {
-    d_us_tx->send(s_cmd_to_control_channel,    // C/S packet
-               pmt_list2(invocation,           // invoc handle
-                         pmt_list1(
-                              pmt_list2(s_op_write_reg, 
-                                        pmt_list2(
-                                        pmt_from_long(REG_CS_DEADLINE), 
-                                        pmt_from_long(deadline))))));
-    d_cs_deadline = deadline;
-
-    if(verbose)
-      std::cout << "[GMAC] Changing CS deadline: " << d_cs_deadline << std::endl;
-  }
-
-  if(verbose)
-    std::cout << "[GMAC] Setting carrier sense to " << toggle << std::endl;
-}
-
-// The following sends a command to open the USRP, which will upload the
-// specified RBF when creating the instance of the USRP server and set all other
-// relevant parameters.
-void gmac::open_usrp()
-{
-  d_state = OPENING_USRP;
-
-  d_us_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
-  
-  if(verbose)
-    std::cout << "[GMAC] Opening USRP " 
-              << d_which_usrp << std::endl;
-}
-
-// Before sending the close to the USRP we wait a couple seconds to let any data
-// through the USB exit, else a bug in the driver will kick an error and cause
-// an abnormal termination.
-void gmac::close_usrp()
-{
-  d_state = CLOSING_USRP;
-
-  sleep(2);
-
-  d_us_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-}
-
-// RX and TX channels must be allocated so that the USRP server can
-// properly share bandwidth across multiple USRPs.  No commands will be
-// successful to the USRP through the USRP server on the TX or RX channels until
-// a bandwidth allocation has been received.
-void gmac::allocate_channels()
-{
-  d_state = ALLOCATING_CHANNELS;
-  
-  if(verbose)
-    std::cout << "[GMAC] Sending channel allocation requests\n";
-
-  long capacity = (long) 16e6;
-  d_us_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-  d_us_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity)));
-
-}
-
-// Before closing the USRP connection, we deallocate our channels so that the
-// capacity can be reused.
-void gmac::close_channels()
-{
-  d_state = CLOSING_CHANNELS;
-
-  d_us_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_us_tx_chan));
-  d_us_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_us_rx_chan));
-
-  if(verbose)
-    std::cout << "[GMAC] Closing channels...\n";
-}
-
-// Used to enter the receiving state
-void gmac::enter_receiving()
-{
-  d_us_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_us_rx_chan));
-
-  if(verbose)
-    std::cout << "[GMAC] Started RX sample stream\n";
-}
-
-// A simple idle state, nothing more to it.
-void gmac::enter_idle()
-{
-  d_state = IDLE;
-}
-
-// Handles the transmission of a pkt from the application.  The invocation
-// handle is passed on but a response is not given back to the application until
-// the response is passed from usrp_server.  This ensures that the MAC passes
-// back the success or failure.  Furthermore, the MAC could decide to retransmit
-// on a failure based on the result of the packet transmission.
-//
-// This should eventually be connected to a physically layer rather than
-// directly to usrp_server. (d_us_tx should be replaced with a different
-// connection)
-void gmac::handle_cmd_tx_pkt(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t dst = pmt_nth(1, data);
-  pmt_t samples = pmt_nth(2, data);
-  pmt_t pkt_properties = pmt_nth(3, data);
-
-  pmt_t us_tx_properties = pmt_make_dict();
-
-  // Set the packet to be carrier sensed?
-  if(carrier_sense_pkt(pkt_properties))
-    pmt_dict_set(us_tx_properties,
-                 pmt_intern("carrier-sense"),
-                 PMT_T);
-
-  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
-
-  // Construct the proper message for USRP server
-  d_us_tx->send(s_cmd_xmit_raw_frame,
-                pmt_list5(invocation_handle,
-                                     d_us_tx_chan,
-                                     samples, 
-                          timestamp,
-                          us_tx_properties));
-
-  if(verbose && 0)
-    std::cout << "[GMAC] Transmitted packet\n";
-}
-
-// Handles a response from the USRP server about the transmission of a frame,
-// whether it was successful or failed.  This should eventually be replaced with
-// a response from the PHY layer.  This is where a retransmit could be
-// implemented.
-void gmac::handle_response_xmit_raw_frame(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t status = pmt_nth(1, data);
-
-  d_tx->send(s_response_tx_pkt,
-             pmt_list2(invocation_handle,
-                       status));
-}
-
-// This method determines whether carrier sense should be enabled based on two
-// properties.  The first is the MAC setting, which the user can set to carrier
-// sense packets by default or not.  The second is a per packet setting, which
-// can be used to override the MAC setting for the given packet only.
-bool gmac::carrier_sense_pkt(pmt_t pkt_properties) 
-{
-  // First we extract the per packet properties to check the per packet setting
-  // if it exists
-  if(pmt_is_dict(pkt_properties)) {
-
-    if(pmt_t pkt_cs = pmt_dict_ref(pkt_properties,
-                                   pmt_intern("carrier-sense"),
-                                   PMT_NIL)) {
-      // If the per packet property says true, enable carrier sense regardless
-      // of the MAC setting
-      if(pmt_eqv(pkt_cs, PMT_T))
-        return true;
-      // If the per packet setting says false, disable carrier sense regardless
-      // of the MAC setting
-      else if(pmt_eqv(pkt_cs, PMT_F))
-        return false;
-    }
-  }
-
-  // If we've hit this point, the packet properties did not state whether
-  // carrier sense should be used or not, so we use the MAC setting
-  if(d_carrier_sense)
-    return true;
-  else
-    return false;
-
-}
-
-// This method is envoked by an incoming cmd-enable-carrier-sense signal on the
-// C/S port.  It can be used to re-adjust the threshold or simply enabled
-// carrier sense.  When a threshold is not provided, the MAC will use an
-// averaging algorithm to determine the threshold (in the future).
-void gmac::handle_cmd_carrier_sense_enable(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t threshold = pmt_nth(1, data);
-  pmt_t deadline = pmt_nth(2, data);
-  long l_threshold, l_deadline;
-
-  // FIXME: for now, if threshold is NIL, we do not change the threshold.
-  // This should be replaced with an averaging algorithm
-  if(pmt_eqv(threshold, PMT_NIL))
-    l_threshold = d_cs_thresh;
-  else
-    l_threshold = pmt_to_long(threshold);
-
-  // If the deadline is NIL, we do not change the value
-  if(pmt_eqv(threshold, PMT_NIL))
-    l_deadline = d_cs_deadline;
-  else
-    l_deadline = pmt_to_long(deadline);
-  
-  set_carrier_sense(true, l_threshold, l_deadline, invocation_handle);
-}
-
-// This method is called when an incoming disable carrier sense command is sent
-// over the control status channel.  It so far does not ellicit a response, this
-// needs to be added correctly.  It needs to wait for the response for the C/S
-// packet from usrp_server.
-void gmac::handle_cmd_carrier_sense_disable(pmt_t data) 
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  
-  // We don't change the threshold, we leave it as is because the application
-  // did not request that it changes, only to disable carrier sense.
-  set_carrier_sense(false, d_cs_thresh, d_cs_deadline, invocation_handle);
-}
-
-// When the app requests that the threshold changes, the state of the carrier
-// sense should not change.  If it was enabled, it should remain enabled.
-// Likewise if it was disabled.  The deadline value should also remain
-// unchanged.
-void gmac::handle_cmd_carrier_sense_threshold(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t threshold = pmt_nth(1, data);
-  long l_threshold;
-
-  // FIXME: for now, if threshold is NIL, we do not change the threshold.
-  // This should be replaced with an averaging algorithm
-  if(pmt_eqv(threshold, PMT_NIL))
-    l_threshold = d_cs_thresh;
-  else
-    l_threshold = pmt_to_long(threshold);
-  
-  set_carrier_sense(d_carrier_sense, l_threshold, d_cs_deadline, invocation_handle);
-}
-
-// Ability to change the deadline using a C/S packet.  The state of all other
-// carrier sense parameters should not change.
-void gmac::handle_cmd_carrier_sense_deadline(pmt_t data)
-{
-  pmt_t invocation_handle = pmt_nth(0, data);
-  pmt_t deadline = pmt_nth(1, data);
-  long l_deadline;
-
-  // If the deadline passed is NIL, do *not* change the value.
-  if(pmt_eqv(deadline, PMT_NIL))
-    l_deadline = d_cs_deadline;
-  else
-    l_deadline = pmt_to_long(deadline);
-  
-  set_carrier_sense(d_carrier_sense, d_cs_thresh, l_deadline, invocation_handle);
-}
-
-REGISTER_MBLOCK_CLASS(gmac);
diff --git a/usrp/host/apps-inband/gmac.h b/usrp/host/apps-inband/gmac.h
deleted file mode 100644 (file)
index a6d0bcb..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef INCLUDED_GMAC_H
-#define INCLUDED_GMAC_H
-
-#include <mb_mblock.h>
-
-class gmac;
-
-class gmac : public mb_mblock
-{
-
-  // The state is used to determine how to handle incoming messages and of
-  // course, the state of the MAC protocol.
-  enum state_t {
-    INIT,
-    OPENING_USRP,
-    ALLOCATING_CHANNELS,
-    INIT_GMAC,
-    IDLE,
-    CLOSING_CHANNELS,
-    CLOSING_USRP,
-  };
-  state_t      d_state;
-
-  // Ports used for applications to connect to this block
-  mb_port_sptr           d_tx, d_rx, d_cs;
-
-  // Ports to connect to usrp_server (us)
-  mb_port_sptr      d_us_tx, d_us_rx, d_us_cs;
-
-  // The channel numbers assigned for use
-  pmt_t d_us_rx_chan, d_us_tx_chan;
-
-  pmt_t d_which_usrp;
-
-  bool d_carrier_sense;
-  long d_cs_thresh;
-  long d_cs_deadline;
-
-  enum FPGA_REGISTERS {
-    REG_CS_THRESH = 1,
-    REG_CS_DEADLINE = 2
-  };
-  
- public:
-  gmac(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
-  ~gmac();
-  void handle_message(mb_message_sptr msg);
-
- private:
-  void define_ports();
-  void initialize_usrp();
-  void initialize_gmac();
-  void set_carrier_sense(bool toggle, long threshold, long deadline, pmt_t invocation);
-  void allocate_channels();
-  void enter_receiving();
-  void enter_idle();
-  void close_channels();
-  void open_usrp();
-  void close_usrp();
-  void handle_cmd_tx_pkt(pmt_t data);
-  void handle_response_xmit_raw_frame(pmt_t data);
-  bool carrier_sense_pkt(pmt_t pkt_properties);
-  void handle_cmd_carrier_sense_enable(pmt_t data);
-  void handle_cmd_carrier_sense_threshold(pmt_t data);
-  void handle_cmd_carrier_sense_disable(pmt_t data);
-  void handle_cmd_carrier_sense_deadline(pmt_t data);
-};
-
-#endif // INCLUDED_GMAC_H
diff --git a/usrp/host/apps-inband/gmac.mbh b/usrp/host/apps-inband/gmac.mbh
deleted file mode 100644 (file)
index 4fa9a06..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-;; -*- scheme -*- ; not really, but tells emacs how to format this
-;;
-;; Copyright 2007 Free Software Foundation, Inc.
-;; 
-;; This file is part of GNU Radio
-;; 
-;; GNU Radio is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-;; 
-;; GNU Radio is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;; 
-;; You should have received a copy of the GNU General Public License along
-;; with this program; if not, write to the Free Software Foundation, Inc.,
-;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-;;
-
-;; ----------------------------------------------------------------
-;;              This is an mblock header file
-;;
-;; The format is very much a work-in-progress.
-;; It'll be compiled to C++.
-;; ----------------------------------------------------------------
-
-;; In the outgoing messages described below, invocation-handle is an
-;; identifier provided by the client to tag the method invocation.
-;; The identifier will be returned with the response, to provide the
-;; client with a mechanism to match asynchronous responses with the
-;; commands that generate them.  The value of the invocation-handle is
-;; opaque the the server, and is not required by the server to be
-;; unique.
-;;
-;; In the incoming messages described below, invocation-handle is the
-;; identifier provided by the client in the prompting invocation.  The
-;; identifier is returned with the response, so that the client has a
-;; mechanism to match asynchronous responses with the commands that
-;; generated them.
-;;
-;; status is either #t, indicating success, or a symbol indicating an error.
-;; All symbol's names shall begin with %error-
-
-
-;; ----------------------------------------------------------------
-;; gmac-tx
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-
-(define-protocol-class gmac-tx
-
-  (:outgoing
-
-    ;; Transmitting packets can carry an invocation handle so the application
-    ;; can get TX results on specific packets, such as whether a packet tagged
-    ;; as #1 was successfully transmitted or not.  This would allow the
-    ;; application to implement something sliding window like.
-    ;;
-    ;; 'dst' is the destination MAC address (given a MAC addressing scheme)
-    ;;
-    ;; 'data' will be treated transparently and passed on as samples.
-    ;;
-    ;; 'properties' can be used in the future to set per-packet options such as
-    ;;   carrier sense overriding functionality.
-    (cmd-tx-pkt invocation-handle dst data properties)
-
-   )
-
-  (:incoming
-
-    ;; The response will carry the same invocation-handle passed with cmd-tx-pkt
-    (response-tx-pkt invocation-handle status)
-
-   )
-  )
-
-;; ----------------------------------------------------------------
-;; gmac-rx
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-
-(define-protocol-class gmac-rx
-
-  (:outgoing
-    
-    ;; There are currently no outgoing commands, I believe that the RX
-    ;; should always be enabled, there is no point in having an enable/disable
-    ;; that I can see.
-   
-   )
-
-  (:incoming
-
-    ;; Contains packets decoded by the MAC destined for this machine, sent by
-    ;; the specified address.
-    (response-rx-pkt invocation-handle src data)
-
-   )
-  )
-
-
-;; ----------------------------------------------------------------
-;; gmac-cs
-;;
-;; The protocol class is defined from the client's point-of-view.
-;; (The client port is unconjugated, the server port is conjugated.)
-;;
-;; This defines a control/status interface to the MAC layer, for control over
-;; functionality such as carrier sense and future functionality such as channel
-;; hopping.
-
-
-(define-protocol-class gmac-cs
-
-  (:outgoing
-
-    ;; Threshold represents the carrier sense threshold based on the digital
-    ;; reading out of the DAC.  If the threshold is set to PMT_NIL then the
-    ;; MAC will use averaging to determine an appropriate threshold.
-    (cmd-carrier-sense-enable invocation-handle threshold deadline)
-    (cmd-carrier-sense-threshold invocation-handle threshold)
-    (cmd-carrier-sense-disable invocation-handle)
-
-    ;; Setting the number of fast transmission retries on a failure before
-    ;; reporting a loss back to the application.
-    (cmd-set-tx-retries invocation-handle retries)
-
-   )
-
-  (:incoming
-
-    (response-gmac-initialized invocation-handle status)
-
-    (response-carrier-sense-enable invocation-handle status)
-    (response-carrier-sense-threshold invocation-handle status)
-    (response-carrier-sense-deadline invocation-handle status)
-    (response-carrier-sense-disable invocation-handle status)
-
-    (response-set-tx-retries invocation-handle status)
-
-   )
-  )
diff --git a/usrp/host/apps-inband/gmac_symbols.h b/usrp/host/apps-inband/gmac_symbols.h
deleted file mode 100644 (file)
index 0d7804b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef INCLUDED_GMAC_SYMBOLS_H
-#define INCLUDED_GMAC_SYMBOLS_H
-
-#include <pmt.h>
-
-// TX
-static pmt_t s_cmd_tx_pkt = pmt_intern("cmd-tx-pkt");
-static pmt_t s_response_tx_pkt = pmt_intern("response-tx-pkt");
-
-// RX
-static pmt_t s_response_rx_pkt = pmt_intern("response-rx-pkt");
-
-// CS
-static pmt_t s_cmd_carrier_sense_enable = pmt_intern("cmd-carrier-sense-enable");
-static pmt_t s_cmd_carrier_sense_threshold = pmt_intern("cmd-carrier-sense-threshold");
-static pmt_t s_cmd_carrier_sense_deadline = pmt_intern("cmd-carrier-sense-deadline");
-static pmt_t s_cmd_carrier_sense_disable = pmt_intern("cmd-carrier-sense-disable");
-static pmt_t s_cmd_set_tx_retries = pmt_intern("cmd-set-tx-retries");
-static pmt_t s_response_gmac_initialized = pmt_intern("response-gmac-initialized");
-static pmt_t s_response_carrier_sense_enable = pmt_intern("response-carrier-sense-enable");
-static pmt_t s_response_carrier_sense_treshold = pmt_intern("response-carrier-sense-threshold");
-static pmt_t s_response_carrier_sense_deadline = pmt_intern("response-carrier-sense-deadline");
-static pmt_t s_response_carrier_sense_disable = pmt_intern("response-carrier-sense-disable");
-static pmt_t s_response_set_tx_retries = pmt_intern("response-set-tx-retries");
-
-#endif // INCLUDED_GMAC_SYMBOLS_H
diff --git a/usrp/host/apps-inband/test_gmac_tx.cc b/usrp/host/apps-inband/test_gmac_tx.cc
deleted file mode 100644 (file)
index 74f16c6..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <mb_mblock.h>
-#include <mb_runtime.h>
-#include <mb_protocol_class.h>
-#include <mb_exception.h>
-#include <mb_msg_queue.h>
-#include <mb_message.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 <gmac.h>
-#include <gmac_symbols.h>
-
-static bool verbose = true;
-
-class test_gmac_tx : public mb_mblock
-{
-  mb_port_sptr         d_tx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_tx_chan;      // returned tx channel handle
-
-  enum state_t {
-    INIT,
-    TRANSMITTING,
-  };
-
-  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_gmac_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_gmac_tx();
-  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_gmac_tx::test_gmac_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_nsamples_xmitted(0),
-    d_nframes_xmitted(0),
-    d_samples_per_frame((long)(126 * 4)),      // full packet
-    d_done_sending(false),
-    d_amplitude(16384)
-{ 
-  
-  define_component("GMAC", "gmac", PMT_NIL);
-  d_tx = define_port("tx0", "gmac-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "gmac-cs", false, mb_port::INTERNAL);
-
-  connect("self", "tx0", "GMAC", "tx0");
-  connect("self", "cs", "GMAC", "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);
-
-}
-
-test_gmac_tx::~test_gmac_tx()
-{
-}
-
-void
-test_gmac_tx::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();
-  pmt_t data = msg->data();
-  pmt_t port_id = msg->port_id();
-
-  pmt_t handle = PMT_F;
-  pmt_t status = PMT_F;
-  pmt_t dict = PMT_NIL;
-  std::string error_msg;
-
-  // Dispatch based on state
-  switch(d_state) {
-    
-    //------------------------------ INIT ---------------------------------//
-    // When GMAC is done initializing, it will send a response
-    case INIT:
-      
-      if(pmt_eq(event, s_response_gmac_initialized)) {
-        handle = pmt_nth(0, data);
-        status = pmt_nth(1, data);
-
-        if(pmt_eq(status, PMT_T)) {
-          enter_transmitting();
-          return;
-        }
-        else {
-          error_msg = "error initializing gmac:";
-          goto bail;
-        }
-      }
-      goto unhandled;
-
-    //-------------------------- TRANSMITTING ----------------------------//
-    // In the transmit state we count the number of underruns received and
-    // ballpark the number with an expected count (something >1 for starters)
-    case TRANSMITTING:
-      
-      // Check that the transmits are OK
-      if (pmt_eq(event, s_response_tx_pkt)){
-        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-tx-pkt:";
-          goto bail;
-        }
-      }
-
-      goto unhandled;
-
-  }
-
- // 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_GMAC_TX] unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-}
-
-void
-test_gmac_tx::enter_transmitting()
-{
-  d_state = TRANSMITTING;
-  d_nsamples_xmitted = 0;
-
-  d_cs->send(s_cmd_carrier_sense_deadline,
-             pmt_list2(PMT_NIL,
-                       pmt_from_long(50000000)));
-
-  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_gmac_tx::build_and_send_next_frame()
-{
-  // allocate the uniform vector for the samples
-  // FIXME perhaps hold on to this between calls
-
-#if 0
-  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();
-    }
-  }
-    
-  // Per packet properties
-  pmt_t tx_properties = pmt_make_dict();
-
-  if(d_nframes_xmitted > 25000) {
-    pmt_dict_set(tx_properties,
-                 pmt_intern("carrier-sense"),
-                 PMT_F);
-  }
-
-  if(d_nframes_xmitted > 35000) {
-    pmt_dict_set(tx_properties,
-                 pmt_intern("carrier-sense"),
-                 PMT_NIL);
-  }
-
-  if(d_nframes_xmitted == 45000) {
-    d_cs->send(s_cmd_carrier_sense_threshold, 
-               pmt_list2(PMT_NIL,
-                         pmt_from_long(100)));
-  }
-  
-  if(d_nframes_xmitted == 60000) {
-    d_cs->send(s_cmd_carrier_sense_threshold, 
-               pmt_list2(PMT_NIL,
-                         pmt_from_long(25)));
-  }
-  
-  if(d_nframes_xmitted == 75000) {
-    d_cs->send(s_cmd_carrier_sense_disable, 
-               pmt_list1(PMT_NIL));
-  }
-  
-  if(d_nframes_xmitted > 90000 && d_nframes_xmitted < 110000) {
-    pmt_dict_set(tx_properties,
-                 pmt_intern("carrier-sense"),
-                 PMT_T);
-  }
-  
-  if(d_nframes_xmitted > 110000) {
-
-    if(d_nframes_xmitted % 100 == 0)
-      pmt_dict_set(tx_properties,
-                   pmt_intern("carrier-sense"),
-                   PMT_T);
-}
-
-  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
-  d_tx->send(s_cmd_tx_pkt,
-            pmt_list4(PMT_NIL,   // invocation-handle
-           PMT_NIL,         // destination
-                      uvec,                                // the samples
-           tx_properties)); // per pkt properties
-
-  d_nsamples_xmitted += nsamples_this_frame;
-  d_nframes_xmitted++;
-
-  if(verbose && 0)
-    std::cout << "[TEST_GMAC_TX] Transmitted frame\n";
-}
-
-
-void
-test_gmac_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
-  }
-
-  build_and_send_next_frame();
-}
-
-REGISTER_MBLOCK_CLASS(test_gmac_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("test_gmac_tx", "test_gmac_tx", PMT_F, &result);
-}
diff --git a/usrp/host/apps-inband/test_usrp_inband_2rx.cc b/usrp/host/apps-inband/test_usrp_inband_2rx.cc
new file mode 100644 (file)
index 0000000..da8d727
--- /dev/null
@@ -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);
+
+}
diff --git a/usrp/host/apps-inband/test_usrp_inband_2tx.cc b/usrp/host/apps-inband/test_usrp_inband_2tx.cc
new file mode 100644 (file)
index 0000000..5ab9be0
--- /dev/null
@@ -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);
+}
diff --git a/usrp/host/apps-inband/test_usrp_inband_cs.cc b/usrp/host/apps-inband/test_usrp_inband_cs.cc
deleted file mode 100644 (file)
index 2497f8d..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <mb_mblock.h>
-#include <mb_runtime.h>
-#include <mb_protocol_class.h>
-#include <mb_exception.h>
-#include <mb_msg_queue.h>
-#include <mb_message.h>
-#include <mb_msg_accepter.h>
-#include <mb_class_registry.h>
-#include <pmt.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.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>
-#include <symbols_usrp_rx.h>
-
-#define NBPING  10
-
-static bool verbose = false;
-
-class test_usrp_cs : public mb_mblock
-{
-  mb_port_sptr         d_tx;
-  mb_port_sptr         d_rx;
-  mb_port_sptr         d_cs;
-  pmt_t                d_tx_chan;      // returned tx channel handle
-  pmt_t                d_rx_chan;      // returned tx channel handle
-
-  struct timeval times[NBPING];
-
-  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_cs(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_cs();
-  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 enter_transmitting();
-  void build_and_send_ping();
-  void build_and_send_next_frame();
-  void handle_xmit_response(pmt_t invocation_handle);
-  void enter_closing_channel();
-};
-
-test_usrp_cs::test_usrp_cs(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg),
-    d_tx_chan(PMT_NIL),
-    d_rx_chan(PMT_NIL),
-    d_state(INIT), d_nsamples_to_send((long) 40e6),
-    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)
-{ 
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_CS] Initializing...\n";
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_rx = define_port("rx0", "usrp-rx", 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);
-  }
-
-  // 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("decim-rx"),
-               pmt_from_long(16));
-
-  // Specify the RBF to use
-  pmt_dict_set(usrp_dict,
-               pmt_intern("rbf"),
-               pmt_intern("boe.rbf"));
-
-  define_component("server", "usrp_server", usrp_dict);
-
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "rx0", "server", "rx0");
-  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_cs::~test_usrp_cs()
-{
-}
-
-void
-test_usrp_cs::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_cs::handle_message(mb_message_sptr msg)
-{
-  pmt_t        event = msg->signal();
-  pmt_t data = msg->data();
-  pmt_t port_id = msg->port_id();
-
-  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)){
-
-      if(pmt_eq(d_tx->port_symbol(), port_id)) {
-        status = pmt_nth(1, data);
-        d_tx_chan = pmt_nth(2, data);
-
-        if (pmt_eq(status, PMT_T)){
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_CS] Received allocation for TX\n";
-
-          if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
-            enter_receiving();
-            enter_transmitting();
-          }
-          return;
-        }
-        else {
-          error_msg = "failed to allocate channel:";
-          goto bail;
-        }
-      }
-      
-      if(pmt_eq(d_rx->port_symbol(), port_id)) {
-        status = pmt_nth(1, data);
-        d_rx_chan = pmt_nth(2, data);
-
-        if (pmt_eq(status, PMT_T)){
-
-          if(verbose)
-            std::cout << "[TEST_USRP_INBAND_CS] Received allocation for TX\n";
-          
-          if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
-            enter_receiving();
-            enter_transmitting();
-          }
-          return;
-        }
-        else {
-          error_msg = "failed to allocate channel:";
-          goto bail;
-        }
-      }
-    }
-    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:
-  if(verbose)
-    std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
-              << "in state "<< d_state << std::endl;
-}
-
-
-void
-test_usrp_cs::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;
-}
-
-void
-test_usrp_cs::close_usrp()
-{
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-  d_state = CLOSING_USRP;
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_CS] Closing USRP\n";
-}
-
-void
-test_usrp_cs::allocate_channel()
-{
-  long capacity = (long) 16e6;
-  d_tx->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;
-}
-
-void
-test_usrp_cs::enter_receiving()
-{
-  d_rx->send(s_cmd_start_recv_raw_samples,
-             pmt_list2(PMT_F,
-                       d_rx_chan));
-}
-
-void
-test_usrp_cs::enter_transmitting()
-{
-  d_state = TRANSMITTING;
-  d_nsamples_xmitted = 0;
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_CS] Beginning transmission\n";
-
-  sleep(1);
-
-//  build_and_send_next_frame();       // fire off 4 to start pipeline
-
-  build_and_send_ping();
-  build_and_send_ping();
-  build_and_send_ping();
-  
-}
-
-void
-test_usrp_cs::build_and_send_ping()
-{
-  
-  d_tx->send(s_cmd_to_control_channel,
-             pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed,
-                                                    pmt_list2(pmt_from_long(0),
-                                                              pmt_from_long(0))))));
-
-  std::cout << "[TEST_USRP_INBAND_CS] Ping sent" << std::endl;
-}
-
-void
-test_usrp_cs::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 timestamp = pmt_from_long(0xffffffff); // NOW
-  d_tx->send(s_cmd_xmit_raw_frame,
-            pmt_list4(pmt_from_long(d_nframes_xmitted),  // invocation-handle
-                      d_tx_chan,                         // channel
-                      uvec,                              // the samples
-                      timestamp));
-
-  d_nsamples_xmitted += nsamples_this_frame;
-  d_nframes_xmitted++;
-
-  if(verbose)
-    std::cout << "[TEST_USRP_INBAND_CS] Transmitted frame\n";
-}
-
-
-void
-test_usrp_cs::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_cs::enter_closing_channel()
-{
-  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_CS] Closing channel\n";
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_cs);
-
-
-// ----------------------------------------------------------------
-
-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_cs", PMT_F, &result);
-}
index 9041a0984553d371c5010401776f6698c39c10f6..107668b894907918d85a9331e326ab523cef26f3 100644 (file)
@@ -102,7 +102,7 @@ test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name
   // 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 @@ test_usrp_rx::handle_response_recv_raw_samples(pmt_t 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 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;
 
index 017ccdbf50015138749612b9997870fcaf411d31..a1d9cc14175499f2a51c6272319c879e6208b267 100644 (file)
@@ -118,7 +118,7 @@ test_usrp_inband_registers::test_usrp_inband_registers(mb_runtime *runtime, cons
   // 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,
index 0429951f3cb4552ec6144c3b71316bd29c24cd14..cff2aa723c84403854631a3f05a905a5179b9b4a 100644 (file)
@@ -87,23 +87,30 @@ class test_usrp_rx : public mb_mblock
 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 @@ test_usrp_rx::open_usrp()
 void
 test_usrp_rx::close_usrp()
 {
+
   d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
   d_state = CLOSING_USRP;
   
@@ -302,7 +310,8 @@ test_usrp_rx::handle_response_recv_raw_samples(pmt_t 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 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 @@ void
 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 @@ REGISTER_MBLOCK_CLASS(test_usrp_rx);
 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);
+
 }
index 8824a72feccdd536738bfe987852a7c15c7ac219..297c7126abfd821060f8237b7ea202de03c48d9e 100644 (file)
@@ -147,7 +147,7 @@ test_usrp_inband_timestamps::test_usrp_inband_timestamps(mb_runtime *runtime, co
   // 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);
 
index 7118d2d0f4a7e9725893182fc2b3d42346989bf9..7f894a4c34bd9437182e508f89b216b6c4c8c402 100644 (file)
@@ -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 @@ class test_usrp_tx : public mb_mblock
 
 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,17 +117,13 @@ test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string &instance_name
   // 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 @@ test_usrp_tx::handle_message(mb_message_sptr msg)
     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 @@ test_usrp_tx::handle_message(mb_message_sptr msg)
       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 @@ test_usrp_tx::handle_message(mb_message_sptr msg)
       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 @@ test_usrp_tx::handle_message(mb_message_sptr msg)
       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 @@ test_usrp_tx::handle_message(mb_message_sptr msg)
       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 @@ test_usrp_tx::open_usrp()
 
   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 @@ 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
@@ -287,6 +287,9 @@ test_usrp_tx::allocate_channel()
   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 @@ test_usrp_tx::enter_transmitting()
   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 @@ test_usrp_tx::build_and_send_next_frame()
   }
 
   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 @@ test_usrp_tx::build_and_send_next_frame()
   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 @@ test_usrp_tx::enter_closing_channel()
   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);
index 0404208b432c99032802dfe0dd92619e48db7182..c9630cec2e37e7c29bed0aa5d4778ea7eb255801 100644 (file)
@@ -127,7 +127,7 @@ test_usrp_inband_underrun::test_usrp_inband_underrun(mb_runtime *runtime, const
   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 @@ test_usrp_inband_underrun::test_usrp_inband_underrun(mb_runtime *runtime, const
   // 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 @@ test_usrp_inband_underrun::closing_usrp()
 {
   d_state = CLOSING_USRP;
 
-  sleep(2);
-
   d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
 }
 
index 77d1f6699d26d2f1b8151fb73d0a41f865a5ac2a..a41ac18b84c6b0892643a7ebcc1f1350ef4f452c 100644 (file)
@@ -76,7 +76,6 @@ include_HEADERS =                     \
        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 @@ libusrp_inband_qa_la_LIBADD =     \
 # ------------------------------------------------------------------------
 
 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
diff --git a/usrp/host/lib/inband/fake_usrp.cc b/usrp/host/lib/inband/fake_usrp.cc
deleted file mode 100644 (file)
index 8a66d5c..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <fake_usrp.h>
-#include <iostream>
-#include <usrp_inband_usb_packet.h>
-#include <mb_class_registry.h>
-#include <vector>
-
-typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
-
-fake_usrp::fake_usrp()
-{
-  std::cout << "[fake_usrp] Initializing...\n";
-}
-
-fake_usrp::~fake_usrp() {}
-
-long
-fake_usrp::write_bus(transport_pkt *pkts, long n_bytes)
-{
-  std::cout << "[fake_usrp] Bytes over bus: " << n_bytes << "\n";
-
-  // I'm assuming that a control packet cannot exist in a burst of data packets,
-  // therefore i read only the first packet's channel in the current burst
-  if(pkts[0].chan() == 0x1f) {
-    return control_block(pkts, n_bytes);
-  } else {
-    return data_block(pkts, n_bytes);
-  }
-
-}
-
-long
-fake_usrp::data_block(transport_pkt *pkts, long n_bytes)
-{
-  std::cout << "[fake_usrp] Entering data block\n";
-
-  // Infer the number of packets from the byte count to do logical tests
-  long n_pkts = static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size()));
-  
-  std::cout << "[fake_usrp] Number of packets: " << n_pkts << "\n";
-
-  // The first packet should have the start of burst, and the last packet should have end of burst
-  if(pkts[0].start_of_burst() && pkts[n_pkts-1].end_of_burst()) {
-    std::cout << "[fake_usrp] Correct burst flags set\n";
-  } else {
-    std::cout << "[fake_usrp] Incorrect burst flags set!\n";
-    return 0;
-  }
-
-  // All other flags should be set to 0 (e.g., overrun should not be set yet) on ALL packets
-  for(int i=0; i < n_pkts; i++) {
-    if(pkts[i].overrun()) {
-      std::cout << "[fake_usrp] Incorrect set of overrun flag on transmit\n";
-      return 0;
-    } else if(pkts[i].underrun()) {
-      std::cout << "[fake_usrp] Incorrect set of underrun flag on transmit\n";
-      return 0;
-    } else if(pkts[i].dropped()) {
-      std::cout << "[fake_usrp] Incorrect set of drop flag on transmit\n";
-      return 0;
-    } 
-  }
-  std::cout << "[fake_usrp] Correct overrun, underrun, and drop flags on transmit (initialized to 0)\n";
-  
-  // The first packet should have a timestamp, other packets should have "NOW"
-  if(pkts[0].timestamp() != 0xffffffff) {
-    std::cout << "[fake_usrp] Correct timestamp on first packet\n";
-  } else {
-    std::cout << "[fake_usrp] Initial packet should not have the 0xffffffff timestamp\n";
-    return 0;
-  }
-
-  // Check that all of the other packets include the NOW timestamp
-  int check_stamps=1;
-  for(int i=1; i < n_pkts; i++)           // start at 1 to skip the first packet
-    if(pkts[i].timestamp() != 0xffffffff) 
-      check_stamps=0;
-
-  if(check_stamps) {
-    std::cout << "[fake_usrp] Correct NOW timestamps (0xffffffff) on intermediate burst packets\n";
-  } else {
-    std::cout << "[fake_usrp] Incorrect timestamps on intermediate burst packets\n";
-    return 0;
-  }
-
-  // Since we are being transparent about samples, we do not ensure the payload is correct, however
-  // it should be the case that if there are >1 packets, all packets except the last packet should
-  // have a full payload size
-  if(n_pkts > 1) {
-    int check_size=1;
-    for(int i=0; i < n_pkts-1; i++)
-      if(pkts[i].payload_len() != transport_pkt::max_payload())
-        check_size=0;
-
-    if(check_size) {
-      std::cout << "[fake_usrp] Correct payload size sanity check on packets\n";
-    } else {
-      std::cout << "[fake_usrp] Failed payload size sanity check\n";
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-long
-fake_usrp::control_block(transport_pkt *pkts, long n_bytes)
-{
-  std::cout << "[fake_usrp] Entering control block\n";
-
-  return 1;
-}
diff --git a/usrp/host/lib/inband/fake_usrp.h b/usrp/host/lib/inband/fake_usrp.h
deleted file mode 100644 (file)
index 818c5a5..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef INCLUDED_FAKE_USRP_H
-#define INCLUDED_FAKE_USRP_H
-
-#include <usrp_inband_usb_packet.h>
-typedef usrp_inband_usb_packet transport_pkt;
-
-/*!
- * \brief Implements a fake USRP for testing without hardware
- */
-class fake_usrp
-{
- public:
-  fake_usrp();
-  ~fake_usrp();
-  long write_bus(transport_pkt *pkts, long n_bytes);
-
- protected:
-  long data_block(transport_pkt *pkts, long n_bytes);
-  long control_block(transport_pkt *pkts, long n_bytes);
-};
-
-#endif /* INCLUDED_FAKE_USRP_H */
-
index b01e74e002cdbe9b0afc9b88a5620f30da72174a..e457e8d64c3846ecd40acb8a861d57b4d47bf0e0 100644 (file)
@@ -46,6 +46,8 @@ typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit e
 
 static bool verbose = false;
 
+static pmt_t s_timeout = pmt_intern("%timeout");
+
 // ----------------------------------------------------------------------------------------------
 
 class qa_alloc_top : public mb_mblock
@@ -903,10 +905,10 @@ class qa_rx_top : public mb_mblock
 
   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 @@ qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_
     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 @@ qa_rx_top::run_tests()
              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 @@ qa_rx_top::handle_message(mb_message_sptr msg)
   
   pmt_t expected = pmt_nth(0, data);
   pmt_t status = pmt_nth(1, data);
+
+  // If we get a timeout we shutdown
+  if(pmt_eq(event, s_timeout)) {
+    if(verbose)
+      std::cout << "[qa_rx_top] Got timeout\n";
+    d_rx->send(s_cmd_stop_recv_raw_samples, 
+               pmt_list2(PMT_NIL, 
+                         pmt_from_long(0)));
+
+    d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
+    return;
+  }
   
   // For testing RX, an invocation handle is not generated by the stub,
   // therefore the same approach for testing is not used.  We simply
   // expect all responses to be true.
   if(pmt_eq(event, s_response_recv_raw_samples)) {
-    if(!pmt_eqv(status, PMT_T)) {
-      if(verbose)
-        std::cout << "Got: " << status << " Expected: " << PMT_T << "\n";
-      shutdown_all(PMT_F);
-      return;
-    }
-    else {
+    if(pmt_eqv(status, PMT_T)) {
+
       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 @@ qa_rx_top::handle_message(mb_message_sptr msg)
   } 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 @@ qa_rx_top::handle_message(mb_message_sptr msg)
         std::cout << "[qa_rx_top] No response message before close\n";
       return;
     }
-
   }
-    
-  
-  d_nmsg_recvd++;
-
 }
 
 
@@ -1079,6 +1080,160 @@ qa_rx_top::check_allocation(mb_message_sptr msg)
 
 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);
+
 
 // ----------------------------------------------------------------------------------------------
 
@@ -1398,3 +1553,17 @@ qa_inband_usrp_server::test_cs()
   
   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));
+}
index 5db57c3ed41cbe1a12641134bc5bd024a80eb520..52a4a0b0675ed3a93a216728516a38fc3842f021 100644 (file)
@@ -34,6 +34,7 @@ class qa_inband_usrp_server : public CppUnit::TestCase {
   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 @@ class qa_inband_usrp_server : public CppUnit::TestCase {
   void test_tx();
   void test_rx();
   void test_cs();
+  void test_rid();
 };
 
 #endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */
diff --git a/usrp/host/lib/inband/test_usrp_inband.cc b/usrp/host/lib/inband/test_usrp_inband.cc
deleted file mode 100644 (file)
index 64fbf3a..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- * 
- * This file is part of GNU Radio
- * 
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <usrp_inband_usb_packet.h>
-#include <mb_mblock.h>
-#include <mb_runtime.h>
-#include <mb_protocol_class.h>
-#include <mb_class_registry.h>
-#include <pmt.h>
-#include "usrp_standard.h"
-
-typedef usrp_inband_usb_packet transport_pkt; 
-
-// Signal set for the USRP server
-static pmt_t s_cmd_open = pmt_intern("cmd-open");
-static pmt_t s_response_open = pmt_intern("response-open");
-static pmt_t s_cmd_close = pmt_intern("cmd-close");
-static pmt_t s_response_close = pmt_intern("response-close");
-static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
-static pmt_t s_response_allocate_channel = pmt_intern("response-allocate-channel");
-static pmt_t s_send_allocate_channel = pmt_intern("send-allocate-channel");
-static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
-static pmt_t s_response_deallocate_channel = pmt_intern("response-deallocate-channel");
-static pmt_t s_send_deallocate_channel = pmt_intern("send-deallocate-channel");
-static pmt_t s_cmd_max_capacity = pmt_intern("cmd-max-capacity");
-static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity");
-static pmt_t s_cmd_ntx_chan  = pmt_intern("cmd-ntx-chan");
-static pmt_t s_cmd_nrx_chan  = pmt_intern("cmd-nrx-chan");
-static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan");
-static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
-static pmt_t s_cmd_current_capacity_allocation  = pmt_intern("cmd-current-capacity-allocation");
-static pmt_t s_response_current_capacity_allocation  = pmt_intern("response-current-capacity-allocation");
-static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
-static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
-
-bool loopback_p = false;
-bool counting_p = false;
-bool fake_usrp_p = false;
-char *prog_name;
-
-static void
-set_progname (char *path)
-{
-  char *p = strrchr (path, '/');
-  if (p != 0)
-    prog_name = p+1;
-  else
-    prog_name = path;
-}
-
-static void
-usage()
-{
-  fprintf (stderr, "usage: %s [-l]\n", prog_name);
-  fprintf (stderr, "  [-l] digital loopback in FPGA\n");
-  fprintf (stderr, "  [-c] counting in FPGA\n");
-  fprintf (stderr, "  [-f] fake usrp\n");
-
-  exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
-  int ch;
-
-  set_progname(argv[0]);
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_T;
-
-  while ((ch = getopt(argc, argv, "flc")) != EOF) {
-    switch(ch) {
-    
-      case 'l':
-        loopback_p = true;
-        break;
-
-      case 'c':
-        counting_p = true;
-        break;
-      
-      case 'f':
-        fake_usrp_p = true;
-        break;
-
-      default:
-        usage();
-    }
-  }
-
-
-  std::cout << "[test_usrp_inband] Starting...\n";
-
-  rt->run("top", "test_usrp_inband_top", PMT_F, &result);
-}
-
-class test_usrp_inband_top : public mb_mblock
-{
-  mb_port_sptr d_tx;
-  mb_port_sptr d_cs;
-
-  long d_tx_chan;
-
- public:
-  test_usrp_inband_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_inband_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void check_message(mb_message_sptr msg);
-  void allocate_channel();
-  void send_packets();
-};
-
-test_usrp_inband_top::test_usrp_inband_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-  std::cout << "[TEST_USRP_INBAND_TOP] Initializing...\n";
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  // Test the TX side
-
-  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
-  pmt_t usrp_server_dict = pmt_make_dict();
-
-  if(fake_usrp_p)
-    pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), pmt_intern("usrp_usb_interface_stub"));
-
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "cs", "server", "cs");
-}
-
-test_usrp_inband_top::~test_usrp_inband_top()
-{
-}
-
-void
-test_usrp_inband_top::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_inband_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();         // the "name" of the message
-  pmt_t port_id = msg->port_id();      // which port it came in on
-  pmt_t data = msg->data();
-  pmt_t metadata = msg->metadata();
-  pmt_t status;
-
-  if (pmt_eq(port_id, d_cs->port_symbol())) {  // message came in on our control/status port
-
-    //---------- OPEN RESPONSE ----------//
-    if (pmt_eq(event, s_response_open)) {
-      status = pmt_nth(1, data);
-
-      if(pmt_eq(status, PMT_T)) {
-        std::cout << "[TEST_USRP_INBAND_TOP] Success opening USRP\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Received error message opening USRP\n";
-        shutdown_all(PMT_F);
-      }
-
-      allocate_channel();
-
-      return;
-    }
-    //--------- CLOSE RESPONSE -----------//
-    else if (pmt_eq(event, s_response_close)) {
-      status = pmt_nth(1, data);
-      
-      if(pmt_eq(status, PMT_T)) {
-        std::cout << "[TEST_USRP_INBAND_TOP] Successfully closed USRP\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Received error message closing USRP\n";
-        shutdown_all(PMT_F);
-      }
-
-      shutdown_all(PMT_T);
-
-      return;
-    }
-  }
-    
-  if (pmt_eq(port_id, d_tx->port_symbol())) {
-
-    //---------- ALLOCATE RESPONSE ---------//
-    if(pmt_eq(event, s_response_allocate_channel)) {
-      status = pmt_nth(1, data);
-      pmt_t channel = pmt_nth(2, data);
-
-      if(pmt_eq(status, PMT_T)) {
-        d_tx_chan = pmt_to_long(channel);
-        std::cout << "[TEST_USRP_INBAND_TOP] Received allocation on channel " << d_tx_chan << "\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Error allocating channel\n";
-        shutdown_all(PMT_F);
-      }
-      
-      send_packets();
-
-      return;
-    }
-    //----------- XMIT RESPONSE ------------//
-    else if(pmt_eq(event, s_response_xmit_raw_frame)) {
-      status = pmt_nth(1, data);
-
-      if(pmt_eq(status, PMT_T)) {
-        std::cout << "[TEST_USRP_INBAND_TOP] Transmission successful\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Failed transmission\n";
-        shutdown_all(PMT_F);
-      }
-
-      close_usrp();
-
-      return;
-    }
-  }
-
-  std::cout << "[TEST_USRP_INBAND_TOP] Received unhandled message: " << event << "\n";
-}
-
-void
-test_usrp_inband_top::allocate_channel()
-{
-  std::cout << "[TEST_USRP_INBAND_TOP] Requesting channel allocation...\n";
-  
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-}
-
-void
-test_usrp_inband_top::send_packets()
-{
-  std::cout << "[TEST_USRP_INBAND_TOP] Sending single packet..\n";
-  d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(pmt_from_long(1), pmt_from_long(d_tx_chan), pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
-  
-}
-
-void
-test_usrp_inband_top::open_usrp()
-{
-  pmt_t usrp = pmt_from_long(0);
-
-  long rx_mode = 0;
-
-  if(loopback_p)
-    rx_mode |= usrp_standard_rx::FPGA_MODE_LOOPBACK;
-  if(counting_p)
-    rx_mode |= usrp_standard_rx::FPGA_MODE_COUNTING;
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, usrp));
-}
-
-void
-test_usrp_inband_top::close_usrp()
-{
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_inband_top);
index ee4cb22f3f98c42171d616f709298287ceb39293..2f02ecc3ff4aabe54bf5085fe704ebc0db8f595b 100644 (file)
 #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 @@ bool usrp_inband_usb_packet::align32()
   if((MAX_PAYLOAD - p_len) < bytes_needed)
     return false;
     
-  p_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);
+  incr_header_len(bytes_needed);
 
   return true;
 }
 
+/*!
+ * \brief Adds a ping command to the current control packet.
+ *
+ * The \p rid is the rid to be associated with the ping response and \p ping_val
+ * is currently unused.
+ *
+ * \returns true if adding the ping command was successful, false otherwise
+ * (i.e. no space in the current packet).
+ */
 bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val)
 {
   if(!align32())
@@ -78,17 +88,20 @@ bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val)
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
 
   return true;
 }
 
-
+/*!
+ * \brief Adds a ping response to the packet.  This is used by the fake USRP
+ * code to generate fake responses for pings.
+ *
+ * The \p rid is the RID to be associated with the response and \p ping_val is
+ * currently unused.
+ *
+ * \returns true if the ping reply was added successfully, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val) 
 {
   if(!align32())
@@ -111,16 +124,20 @@ bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val)
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a write register command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written to.
+ *
+ * \returns true if the command was added to the packet successfully, false
+ * otherwise.
+ */
 bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val)
 {
   if(!align32())
@@ -149,16 +166,19 @@ bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val)
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_WRITEREG_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a write register masked command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written, masked by \p mask
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long mask)
 {
   if(!align32())
@@ -190,16 +210,19 @@ bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long ma
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_WRITEREGMASKED_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a read register message to the packet. 
+ *
+ * The \p rid will be the associated RID returned with the response, and \p
+ * reg_num is the register to be read.
+ * 
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num)
 {
   if(!align32())
@@ -222,16 +245,22 @@ bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num)
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_READREG_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a read register reply response to the current packet.  This is
+ * used by the fake USRP code to generate fake register read responses for
+ * testing.
+ *
+ * The \p rid is the associated RID to be included in the response, \p reg_num
+ * is the register the read is coming from, and \p reg_val is the value of the
+ * read.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_val)
 {
   if(!align32())
@@ -258,16 +287,19 @@ bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_READREGREPLY_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a delay command to the current packet.
+ *
+ * The \p ticks parameter is the number of clock ticks the FPGA should delay
+ * parsing for, which is added to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_delay(long ticks)
 {
   if(!align32())
@@ -289,16 +321,16 @@ bool usrp_inband_usb_packet::cs_delay(long ticks)
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_DELAY_LEN);
 
   return true;
 }
 
+/*!
+ * \brief
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len)
 {
   if(!align32())
@@ -328,16 +360,20 @@ bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size
    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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + i2c_len);
 
   return true;
 }
 
+/*!
+ * \brief Adds an I2C read command to the current packet.
+ *
+ * The \p rid is the associated RID to return with the read response, \p
+ * i2c_addr is the address to read from on the I2C bus, and \p n_bytes is the
+ * number of bytes to be read from the bus.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes)
 {
   if(!align32())
@@ -367,16 +403,20 @@ bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes)
   *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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_I2CREAD_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds an I2C read reply response to the current packet.  This is used
+ * by the fake USRP code to generate fake I2C responses.
+ *
+ * The \p rid is the RID to be associated with the response, \p i2c_addr is the
+ * address on the I2C bus that the \p i2c_data of \p i2c_data_len was read from.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len)
 {
   if(!align32())
@@ -406,16 +446,16 @@ bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t
   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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + i2c_len);
 
   return true;
 }
 
+/*!
+ * \brief Adds a SPI write command to the current packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len)
 {
   if(!align32())
@@ -454,16 +494,16 @@ bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_he
   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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + spi_len);
 
   return true;
 }
 
+/*!
+ * \brief Adds a SPI bus read command to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes)
 {
   if(!align32())
@@ -508,16 +548,17 @@ bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, lo
   *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 @@ bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data, long
   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;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + spi_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)));
index 8c19b1aeba401d742606081dbe42e10e245ddf10..8f59d1b656cc735ba1cd8cd8bf9cf4d762650a8a 100644 (file)
@@ -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 @@ public:
                        | ((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);
index caa2d717540db09f2d11eb805c0ee9436f2b220a..71c042a50e9f96369b8ff25882683b6d13196f44 100644 (file)
@@ -40,25 +40,30 @@ typedef usrp_inband_usb_packet transport_pkt;
 
 static const bool verbose = false;
 
+bool usrp_rx_stop;
+
 usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
   : mb_mblock(rt, instance_name, user_arg),
-    d_disk_write(false)
+    d_disk_write(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 @@ usrp_rx::initial_transition()
   
 }
 
+/*!
+ * \brief Handles incoming signals to to the m-block, wihch should only ever be
+ * a single message: cmd-usrrp-rx-start-reading.  There is no signal to stop
+ * reading as the m-block goes in to a forever loop to read inband packets from
+ * the bus.
+ */
 void
 usrp_rx::handle_message(mb_message_sptr msg)
 {
@@ -85,6 +96,17 @@ usrp_rx::handle_message(mb_message_sptr msg)
   }
 }
 
+/*!
+ * \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 @@ usrp_rx::read_and_respond(pmt_t data)
     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 @@ usrp_rx::read_and_respond(pmt_t data)
 
     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);
index e1a90a78135b24f6c6b3726052ca436841a155f4..10104bd665acddb6bab51028a647e3adde0f71c5 100644 (file)
@@ -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 @@ class usrp_rx : public mb_mblock
   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:
index 4bdb106b18ac1822b673bee8e8e06e180381f883..1c96b7a7ac44efb0c96a89db420dc0c61af9d40b 100644 (file)
@@ -43,7 +43,7 @@ typedef usrp_inband_usb_packet transport_pkt;
 
 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 @@ std::queue<pmt_t> d_cs_queue;
 usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
   : mb_mblock(rt, instance_name, user_arg),
     d_samples_per_frame((long)(126)),
+    d_decim_rx(128),
     d_amplitude(16384),
     d_disk_write(false)
 {
+
+  // Information about the rates are passed all the way from the app in the form
+  // of a dictionary.  We use this to read the RX decimation rate and compute
+  // the approximate number of MS/s as a form of flow control for the stub.
+  pmt_t usrp_dict = user_arg;
+
+  if (pmt_is_dict(usrp_dict)) {
+    // Read the RX decimation rate
+    if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, 
+                                      pmt_intern("decim-rx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(decim_rx, PMT_NIL)) 
+        d_decim_rx = pmt_to_long(decim_rx);
+    }
+  }
+
   d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
   
   // initialize NCO
   double freq = 100e3;
   int interp = 32;                         // 32 -> 4MS/s
-  double sample_rate = 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 @@ usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt
   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 @@ usrp_rx_stub::~usrp_rx_stub()
 void 
 usrp_rx_stub::initial_transition()
 {
-  
 }
 
 void
@@ -90,94 +106,121 @@ usrp_rx_stub::handle_message(mb_message_sptr msg)
   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
+
+  // Calculate the inter-packet arrival time.  
+  double samples_per_sec = (64.0/(double)d_decim_rx)*1000000.0;
+  double frames_per_sec = samples_per_sec / (double)d_samples_per_frame;
+  double frame_rate = 1.0 / frames_per_sec;
+
+  if(verbose) {
+    std::cout << "[USRP_RX_STUB] Scheduling periodic packet generator\n";
+    std::cout << "\tsamples_per_sec: " << samples_per_sec << std::endl;
+    std::cout << "\tframes_per_sec: " << frames_per_sec << std::endl;
+    std::cout << "\tframe_rate: " << frame_rate << std::endl;
+  }
 
-  while(!usrp_rx_stop) {
+  schedule_periodic_timeout(d_t0 + frame_rate, mb_time(frame_rate), PMT_T);
+}
 
-    long nsamples_this_frame = d_samples_per_frame;
+void
+usrp_rx_stub::read_and_respond()
+{
 
-    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);
+  long nsamples_this_frame = d_samples_per_frame;
 
-    // fill in the complex sinusoid
+  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);
 
-    for (int i = 0; i < nsamples_this_frame; i++){
+  // fill in the complex sinusoid
 
-      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);
+  for (int i = 0; i < nsamples_this_frame; i++){
 
-        // write 16-bit i & q
-        samples[2*i] =   (int16_t) s.real();
-        samples[2*i+1] = (int16_t) s.imag();
-      }
+    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);
-  
-    pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
-    transport_pkt *pkt =
-      (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
 
-    pkt->set_header(0, channel, 0, n_bytes);
-    pkt->set_timestamp(0xffffffff);
-    memcpy(pkt->payload(), samples, n_bytes);
-    
-    d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt));
-
-    // Now lets check the shared CS queue between the TX and RX stub.  Each
-    // element in a queue is a list where the first element is an invocation
-    // handle and the second element is a PMT u8 vect representation of the
-    // CS packet response which can just be passed transparently.
-    while(!d_cs_queue.empty()) {
-      
-      pmt_t cs_pkt = d_cs_queue.front();
-      d_cs_queue.pop();
-
-      pmt_t invocation_handle = pmt_nth(0, cs_pkt);
-      pmt_t v_pkt = pmt_nth(1, cs_pkt);
-
-      d_cs->send(s_response_usrp_rx_read,   
-                 pmt_list3(invocation_handle, 
-                           PMT_T, 
-                           v_pkt));  // Take the front CS pkt
-
-      
-      if(verbose)
-        std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n";
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
     }
-
   }
   
-  usrp_rx_stop = false;
+  if(d_disk_write)
+    d_ofile.write((const char *)samples, n_bytes);
+
+  pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  transport_pkt *pkt =
+    (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
+
+  pkt->set_header(0, channel, 0, n_bytes);
+  pkt->set_timestamp(0xffffffff);
+  memcpy(pkt->payload(), samples, n_bytes);
+  
+  d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt));
 
-  if(verbose)
-    std::cout << "[USRP_RX_STUB] Got fake RX stop\n";
+  // Now lets check the shared CS queue between the TX and RX stub.  Each
+  // element in a queue is a list where the first element is an invocation
+  // handle and the second element is a PMT u8 vect representation of the
+  // CS packet response which can just be passed transparently.
+  while(!d_cs_queue.empty()) {
+    
+    pmt_t cs_pkt = d_cs_queue.front();
+    d_cs_queue.pop();
+
+    pmt_t invocation_handle = pmt_nth(0, cs_pkt);
+    pmt_t v_pkt = pmt_nth(1, cs_pkt);
+
+    d_cs->send(s_response_usrp_rx_read,   
+               pmt_list3(invocation_handle, 
+                         PMT_T, 
+                         v_pkt));  // Take the front CS pkt
+
+    
+    if(verbose)
+      std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n";
+  }
 
 }
 
index 5a75bf00ac915ef11427857bde40d9f6ebac35ab..9cf308a99206ede776b9ee24577cd74de12a119e 100644 (file)
 
 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 @@ class usrp_rx_stub : public mb_mblock
   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 @@ class usrp_rx_stub : public mb_mblock
   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();
  
 };
   
index 1948a43b2945de042bd356d1f39a7a6cfcf28905..6a3643e568804aef7fa505c4e07a0db2b9049507 100644 (file)
@@ -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,13 +55,42 @@ str(long x)
 
 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); 
@@ -82,7 +113,7 @@ usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t
                                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 @@ usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t
   //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 @@ usrp_server::initial_transition()
   // the initial transition
 }
 
+/*!
+ * \brief Reads all incoming messages to USRP server from the TX, RX, and the CS
+ * ports.  This drives the state of USRP server and dispatches based on the
+ * message.
+ */
 void
 usrp_server::handle_message(mb_message_sptr msg)
 {
@@ -178,6 +218,9 @@ usrp_server::handle_message(mb_message_sptr msg)
       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 @@ usrp_server::handle_message(mb_message_sptr msg)
 
       // 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 @@ usrp_server::handle_message(mb_message_sptr msg)
   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 @@ int usrp_server::tx_port_index(pmt_t port_id) {
   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 @@ int usrp_server::rx_port_index(pmt_t port_id) {
   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 @@ long usrp_server::current_capacity_allocation() {
   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 @@ usrp_server::handle_cmd_allocate_channel(
   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 @@ usrp_server::handle_cmd_deallocate_channel(
   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 @@ void usrp_server::handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struc
               << 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 @@ void usrp_server::handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struc
   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,7 +801,10 @@ void usrp_server::handle_cmd_to_control_channel(mb_port_sptr port, std::vector<s
 
   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
@@ -990,8 +1107,22 @@ void usrp_server::handle_cmd_to_control_channel(mb_port_sptr port, std::vector<s
   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 @@ usrp_server::handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<st
   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 @@ usrp_server::handle_cmd_stop_recv_raw_samples(
   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 @@ usrp_server::handle_response_usrp_read(pmt_t data)
     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 @@ usrp_server::handle_response_usrp_read(pmt_t data)
                  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 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         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 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         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 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         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 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         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 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
   }
 }
 
+/*!
+ * \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 @@ usrp_server::recall_defer_queue()
   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 @@ usrp_server::check_valid(mb_port_sptr port,
   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 @@ usrp_server::check_valid(mb_port_sptr port,
   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 @@ usrp_server::next_rid()
     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);
index 81dceb1f4f1df99627059554e2286f52631ae359..09c82faac446571dce8897dc35d4409af011a5d5 100644 (file)
@@ -51,6 +51,13 @@ public:
   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 @@ private:
   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 */
index 3fd0db139b5c4fdcb65ac2a15328a472feecc139..ed7943fc377751981634131181438fc8ea63f351 100644 (file)
 
   (: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
index a7a5e4a8943930179d7b0e3223b765f47bd55438..da8777513067a8d4a289d84430e2eecf0f521a7e 100644 (file)
@@ -66,6 +66,10 @@ usrp_tx::initial_transition()
   
 }
 
+/*!
+ * \brief Handles incoming signals to to the m-block, wihch should only ever be
+ * a single message: cmd-usrp-tx-write.
+ */
 void
 usrp_tx::handle_message(mb_message_sptr msg)
 {
@@ -82,6 +86,14 @@ usrp_tx::handle_message(mb_message_sptr msg)
   }
 }
 
+/*!
+ * \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 @@ usrp_tx::write(pmt_t data)
   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());
index 7a9876322fd2cf8fc5fd732ee0f952e70bf17509..6cff3b4eefa31340ab546f20df5dfea632200dbc 100644 (file)
@@ -103,7 +103,7 @@ usrp_tx_stub::write(pmt_t data)
   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 @@ usrp_tx_stub::write(pmt_t data)
       d_ofile.flush();
     }
 
-    if(pkts[i].chan() == 0x1f)
+    if(pkts[i].chan() == CONTROL_CHAN)
       parse_cs(invocation_handle, pkts[i]);
   }
 
@@ -140,7 +140,7 @@ usrp_tx_stub::parse_cs(pmt_t invocation_handle, transport_pkt pkt)
   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
index 269ed2706d24548870f57d06abdbe85ae9da7bd3..51b6d4646c04e7c4cbda7ec1fc364d36c0f5d838 100644 (file)
@@ -47,12 +47,16 @@ static pmt_t s_shutdown = pmt_intern("%shutdown");
 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 @@ usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instan
         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 @@ usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instan
   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 @@ usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instan
   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 @@ usrp_usb_interface::initial_transition()
 
 }
 
+/*!
+ * \brief Handles all incoming signals to the block from the lowest m-blocks
+ * which read/write to the bus, or the higher m-block which is the USRP server.
+ */
 void
 usrp_usb_interface::handle_message(mb_message_sptr msg)
 {
@@ -256,6 +262,13 @@ usrp_usb_interface::handle_message(mb_message_sptr msg)
   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 @@ usrp_usb_interface::handle_cmd_open(pmt_t data)
     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 @@ usrp_usb_interface::handle_cmd_open(pmt_t data)
     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 @@ usrp_usb_interface::handle_cmd_open(pmt_t data)
     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;
   }
-
-  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);
-//    }
-  }
   
+  // 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 (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 @@ usrp_usb_interface::handle_cmd_write(pmt_t data)
   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 @@ usrp_usb_interface::handle_cmd_start_reading(pmt_t data)
 
   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 @@ usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
   if(!d_fake_usrp) {
     if(verbose)
       std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n";
+    usrp_rx_stop = true;
+
+    // Used to allow a read() being called by a lower layer to complete before
+    // stopping, else there can be partial data left on the bus and can generate
+    // errors.
+    while(usrp_rx_stop) {usleep(1);}
     d_urx->stop();
   }
   else {
     if(verbose)
       std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n";
-    usrp_rx_stop = 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;
index 8efce2ff66d2ce732bcec17a04aec504f33d24f6..6c2c157680023a294bf89b7e46219ef51d543e2e 100644 (file)
@@ -42,10 +42,10 @@ class usrp_usb_interface : public mb_mblock
   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;
 
index 60687a14991a2a30b31ffc61beaee72d499da188..6dce8d9e04ef3fcc36ea15593af4a619430af642 100644 (file)
@@ -386,14 +386,6 @@ fusb_ephandle_linux::stop ()
 {
   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);
@@ -407,11 +399,19 @@ fusb_ephandle_linux::stop ()
     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;