Merged -r6379:6451 from jcorgan/radar into trunk. Adds working receiver implementati...
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 17 Sep 2007 22:08:05 +0000 (22:08 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 17 Sep 2007 22:08:05 +0000 (22:08 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6452 221aa14e-8319-0410-a670-987f0aec2ac5

15 files changed:
config/grc_gr_radar_mono.m4
gr-radar-mono/README
gr-radar-mono/src/fpga/Makefile.am
gr-radar-mono/src/fpga/lib/Makefile.am
gr-radar-mono/src/fpga/lib/radar.v
gr-radar-mono/src/fpga/lib/radar_control.v
gr-radar-mono/src/fpga/lib/radar_rx.v
gr-radar-mono/src/fpga/models/Makefile.am [new file with mode: 0644]
gr-radar-mono/src/fpga/models/fifo_1clk.v [new file with mode: 0644]
gr-radar-mono/src/fpga/tb/radar_tb.sav
gr-radar-mono/src/fpga/tb/radar_tb.sh
gr-radar-mono/src/fpga/top/usrp_radar_mono.rbf
gr-radar-mono/src/fpga/top/usrp_radar_mono.v
gr-radar-mono/src/python/radar_mono.py
gr-radar-mono/src/python/usrp_radar_mono.py

index 9793f51238d404350823fad35f8e29775f6e0db1..cbc2f8de4818a8640a9358b759ec62628908cc0e 100644 (file)
@@ -27,6 +27,7 @@ AC_DEFUN([GRC_GR_RADAR_MONO],[
         gr-radar-mono/src/fpga/Makefile \
         gr-radar-mono/src/fpga/top/Makefile \
          gr-radar-mono/src/fpga/lib/Makefile \
+         gr-radar-mono/src/fpga/models/Makefile \
         gr-radar-mono/src/fpga/tb/Makefile \
         gr-radar-mono/src/lib/Makefile \
         gr-radar-mono/src/python/Makefile \
index 0ecf4e381ee0a506bf60db468f425c30ba75635d..577c8e095fe7ce1e4e922aeaba99f5dca334fb37 100644 (file)
@@ -1,28 +1,32 @@
 This GNU Radio component implements a monostatic radar transmitter
 and receiver.  It uses a custom FPGA build to generate a linear 
-FM chirp waveform directly in the USRP. Echo returns are (will be) 
-recorded to a file for offline analysis.
+FM chirp waveform directly in the USRP. Echo returns are recorded 
+to a file for offline analysis.
 
 The LFM chirp can be up to 32 MHz in width, whose center frequency
 is set by which transmit daughter board is installed.  This gives
 a range resolution of approximately 5 meters.
 
-Only boards in slot A are supported.
-
 The script to run is placed in $prefix/bin:
 
 Usage: usrp_radar_mono.py [options]
 
 Options:
   -h, --help            show this help message and exit
+  -T TX_SUBDEV_SPEC, --tx-subdev-spec=TX_SUBDEV_SPEC
+                        use transmitter board side A or B (default is first
+                        found)
+  -R RX_SUBDEV_SPEC, --rx-subdev-spec=RX_SUBDEV_SPEC
+                        use receiver board side A or B (default is first
+                        found)
+  -g GAIN, --gain=GAIN  set gain in dB (default is midpoint)
   -f FREQ, --frequency=FREQ
                         set transmitter center frequency to FREQ in Hz,
                         default is 0.0
   -w FREQ, --chirp-width=FREQ
-                        set LFM chirp bandwidth in Hz, default is 32000000.0
+                        set LFM chirp bandwidth in Hz, default is 32M
   -a AMPLITUDE, --amplitude=AMPLITUDE
-                        set waveform amplitude in % full scale, default is
-                        100,
+                        set waveform amplitude in % full scale, default is 15,
   --ton=TON             set pulse on period in seconds, default is 5e-06,
   --tsw=TSW             set transmitter switching period in seconds, default
                         is 4.0625e-07,
@@ -31,6 +35,8 @@ Options:
                         10000.0,
   -v, --verbose         enable verbose output, default is disabled
   -D, --debug           enable debugging output, default is disabled
+  -F FILENAME, --filename=FILENAME
+                        log received echos to file
 
 The transmitter creates an LFM chirp, evenly centered on the supplied frequency.
 The four timing parameters are:
@@ -50,15 +56,12 @@ prf     Pulse repetition frequency in Hz.  This establishes to overall pulse
         repetition period, which results in idle time between when the receiver
         is turned off and the next transmitted chirp begins.
 
-Currently, only the transmitter is written. Also, there is not yet any sanity
-checks on the supplied parameters to the script.
-
-The receiver, when completed, will record the radar returns, preserving phase,
-into a file with metadata about each chirp.
+The transmitter is completed.  The receive path is logging echo data to a supplied
+file; however, no meta-data is logged.
 
 This is experimental code.
 
 Johnathan Corgan
 Corgan Enterprises LLC
 jcorgan@corganenterprises.com
-7/18/2007
+9/17/2007
index 3e2ebbfbb1e6f22764da43926a7cf9f4407c4fa8..fb2a09c9c11d5de45352f8cbbb02964adc125ca3 100644 (file)
@@ -21,4 +21,4 @@
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = lib top tb
+SUBDIRS = lib top tb models
index 8aefd754d4bc83c900a7cf57f8c0a6ecbba5f07b..2a7d6d883db967493d8a6f671caf841e80826713 100644 (file)
@@ -31,4 +31,4 @@ EXTRA_DIST =                  \
                fifo32_4k.v     \
                cordic_nco.v
 
-MOSTLYCLEANFILES = *~
+MOSTLYCLEANFILES = *~ *.bak
index 127e9cee3a9877545aff5d5ff3337701b17bc87e..d71d9397c6d582f5af5c31200f0e85cbc14d5459 100644 (file)
@@ -24,8 +24,8 @@
 module radar(clk_i,saddr_i,sdata_i,s_strobe_i,
             tx_side_o,tx_strobe_o,tx_dac_i_o,tx_dac_q_o,
             rx_adc_i_i,rx_adc_q_i,
-            rx_strobe_o,rx_ech_i_o,rx_ech_q_o);
-
+            rx_strobe_o,rx_ech_i_o,rx_ech_q_o,auto_tr_o);
+   
    // System interface
    input         clk_i;                // Master clock @ 64 MHz
    input  [6:0]  saddr_i;      // Configuration bus address
@@ -37,7 +37,8 @@ module radar(clk_i,saddr_i,sdata_i,s_strobe_i,
    output        tx_strobe_o;  // Generate an transmitter output sample
    output [13:0] tx_dac_i_o;   // I channel transmitter output to DAC
    output [13:0] tx_dac_q_o;    // Q channel transmitter output to DAC
-   
+   output        auto_tr_o;     // Transmit/Receive switching
+      
    // Receive subsystem
    input  [15:0] rx_adc_i_i;   // I channel input from ADC
    input  [15:0] rx_adc_q_i;   // Q channel input from ADC
@@ -53,6 +54,7 @@ module radar(clk_i,saddr_i,sdata_i,s_strobe_i,
    wire         rx_enable;     // Receiver enable
    wire          tx_ctrl;       // Transmitter on control
    wire          rx_ctrl;       // Receiver on control
+   wire [15:0]          pulse_num;     // Count of pulses since tx_enabled
         
    // Configuration
    wire [15:0]          ampl;          // Pulse amplitude
@@ -63,7 +65,8 @@ module radar(clk_i,saddr_i,sdata_i,s_strobe_i,
      (.clk_i(clk_i),.saddr_i(saddr_i),.sdata_i(sdata_i),.s_strobe_i(s_strobe_i),
       .reset_o(reset),.tx_side_o(tx_side_o),.dbg_o(debug_enabled),
       .tx_strobe_o(tx_strobe_o),.tx_ctrl_o(tx_ctrl),.rx_ctrl_o(rx_ctrl),
-      .ampl_o(ampl),.fstart_o(fstart),.fincr_o(fincr));
+      .ampl_o(ampl),.fstart_o(fstart),.fincr_o(fincr),.pulse_num_o(pulse_num));
+    assign auto_tr_o = tx_ctrl;
 
    radar_tx transmitter
      ( .clk_i(clk_i),.rst_i(reset),.ena_i(tx_ctrl),.strobe_i(tx_strobe_o),
@@ -72,7 +75,7 @@ module radar(clk_i,saddr_i,sdata_i,s_strobe_i,
    
    radar_rx receiver
      ( .clk_i(clk_i),.rst_i(reset),.ena_i(rx_ctrl),.dbg_i(debug_enabled),
-       .rx_in_i_i(rx_adc_i_i),.rx_in_q_i(rx_adc_q_i),
+       .pulse_num_i(pulse_num),.rx_in_i_i(rx_adc_i_i),.rx_in_q_i(rx_adc_q_i),
        .rx_strobe_o(rx_strobe_o),.rx_i_o(rx_ech_i_o),.rx_q_o(rx_ech_q_o) );
    
 endmodule // radar
index e22da962d611ade3e8c87e06977649c492d516da..864941109e06ce227f5aa6fd7fffbb9053601f9b 100644 (file)
 
 `include "../lib/radar_config.vh"
 
-module radar_control(clk_i,saddr_i,sdata_i,s_strobe_i,
-                    reset_o,tx_side_o,dbg_o,
-                    tx_strobe_o,tx_ctrl_o,rx_ctrl_o,
-                    ampl_o,fstart_o,fincr_o);
+module radar_control(clk_i,saddr_i,sdata_i,s_strobe_i,reset_o,
+                    tx_side_o,dbg_o,tx_strobe_o,tx_ctrl_o,rx_ctrl_o,
+                    ampl_o,fstart_o,fincr_o,pulse_num_o);
 
    // System interface
    input         clk_i;                // Master clock @ 64 MHz
@@ -42,7 +41,8 @@ module radar_control(clk_i,saddr_i,sdata_i,s_strobe_i,
    output [15:0] ampl_o;
    output [31:0] fstart_o;
    output [31:0] fincr_o;
-   
+   output [15:0] pulse_num_o;
+
    // Internal configuration
    wire         lp_ena;
    wire         md_ena;
@@ -94,12 +94,14 @@ module radar_control(clk_i,saddr_i,sdata_i,s_strobe_i,
 
    reg [3:0]  state;
    reg [31:0] count;
-
+   reg [15:0] pulse_num_o;
+   
    always @(posedge clk_i)
      if (reset_o)
        begin
          state <= `ST_ON;
          count <= 32'b0;
+         pulse_num_o <= 16'b0;
        end
      else
        case (state)
@@ -108,6 +110,7 @@ module radar_control(clk_i,saddr_i,sdata_i,s_strobe_i,
             begin
                state <= `ST_SW;
                count <= 32'b0;
+               pulse_num_o <= pulse_num_o + 16'b1;
             end
           else
             count <= count + 32'b1;
index 1ca546134079cd31849f02220a5e6b12a4c75280..29bbadd4dcee3bb30aaeca1d31fa502d525eb40e 100644 (file)
@@ -22,9 +22,8 @@
 `include "../../../../usrp/firmware/include/fpga_regs_common.v"
 `include "../../../../usrp/firmware/include/fpga_regs_standard.v"
 
-module radar_rx(clk_i,rst_i,ena_i,dbg_i,
-               rx_in_i_i,rx_in_q_i,
-               rx_i_o,rx_q_o,rx_strobe_o);
+module radar_rx(clk_i,rst_i,ena_i,dbg_i,pulse_num_i,rx_in_i_i,
+               rx_in_q_i,rx_i_o,rx_q_o,rx_strobe_o);
    
    input clk_i;
    input rst_i;
@@ -33,11 +32,12 @@ module radar_rx(clk_i,rst_i,ena_i,dbg_i,
    
    input [15:0] rx_in_i_i;
    input [15:0] rx_in_q_i;
+   input [15:0] pulse_num_i;
    
    output [15:0] rx_i_o;
    output [15:0] rx_q_o;
    output reg    rx_strobe_o;
-
+   
    reg [15:0] count;
 
    always @(posedge clk_i)
@@ -46,71 +46,63 @@ module radar_rx(clk_i,rst_i,ena_i,dbg_i,
      else
        count <= count + 16'b1;
 
-   wire [31:0] fifo_data = dbg_i ? {count[15:0],16'hAA55} : {rx_in_i_i,rx_in_q_i};
+   wire [31:0] fifo_inp = dbg_i ? {count[15:0],pulse_num_i[15:0]} : {rx_in_i_i,rx_in_q_i};
 
-   // Need to buffer received samples as they come in at 32 bits per cycle
-   // but the rx_buffer.v fifo is only 16 bits wide.
-   //
-   reg         fifo_read;
+   // Buffer incoming samples every clock
    wire [31:0] fifo_out;
+   reg         fifo_ack;
    wire        fifo_empty;
+
+// Use model if simulating, otherwise Altera Megacell
+`ifdef SIMULATION
+   fifo_1clk #(32, 4096) buffer(.clock(clk_i),.sclr(rst_i),
+                               .data(fifo_inp),.wrreq(ena_i),
+                               .rdreq(fifo_ack),.q(fifo_out),
+                               .empty(fifo_empty));
+`else
+   fifo32_4k buffer(.clock(clk_i),.sclr(rst_i),
+                   .data(fifo_inp),.wrreq(ena_i),
+                   .rdreq(fifo_ack),.q(fifo_out),
+                   .empty(fifo_empty));
+`endif
    
-   fifo32_4k fifo(.clock(clk_i),.sclr(rst_i),
-                 .data(fifo_data),.wrreq(ena_i),
-                 .q(fifo_out),.rdreq(fifo_read),
-                 .empty(fifo_empty) );
+   // Write samples to rx_fifo every third clock
+   `define ST_FIFO_IDLE   3'b001
+   `define ST_FIFO_STROBE 3'b010
+   `define ST_FIFO_ACK    3'b100
 
-   `define ST_RD_IDLE     4'b0001
-   `define ST_RD_REQ      4'b0010
-   `define ST_WR_FIFO     4'b0100
-   `define ST_RD_DELAY    4'b1000
+   reg [2:0]   state;
 
-   reg [3:0] state;
-   reg [3:0] delay;
-   
    always @(posedge clk_i)
-     if (rst_i | ~ena_i)
+     if (rst_i)
        begin
-         state <= `ST_RD_IDLE;
-         delay <= 4'd0;
+         state <= `ST_FIFO_IDLE;
          rx_strobe_o <= 1'b0;
-         fifo_read <= 1'b0;
+         fifo_ack <= 1'b0;
        end
      else
        case (state)
-        `ST_RD_IDLE:
-          begin
-             if (!fifo_empty)
-               begin
-                  fifo_read <= 1'b1;
-                  state <= `ST_RD_REQ;
-               end
-          end
-
-        `ST_RD_REQ:
+        `ST_FIFO_IDLE:
+          if (!fifo_empty)
+            begin
+               // Tell rx_fifo sample is ready
+               rx_strobe_o <= 1'b1;
+               state <= `ST_FIFO_STROBE;
+            end
+        `ST_FIFO_STROBE:
           begin
-             fifo_read <= 1'b0;
-             rx_strobe_o <= 1'b1;
-             state <= `ST_WR_FIFO;
+             rx_strobe_o <= 1'b0;
+             // Ack our FIFO
+             fifo_ack <= 1'b1;
+             state <= `ST_FIFO_ACK;
           end
-
-        `ST_WR_FIFO:
+        `ST_FIFO_ACK:
           begin
-             rx_strobe_o <= 1'b0;
-             state <= `ST_RD_DELAY;
+             fifo_ack <= 1'b0;
+             state <= `ST_FIFO_IDLE;
           end
-
-        `ST_RD_DELAY:
-          if (delay == 7)
-            begin
-               delay <= 0;
-               state <= `ST_RD_IDLE;
-            end
-          else
-            delay <= delay + 1'b1;
-
        endcase // case(state)
-   
+
    assign rx_i_o = fifo_out[31:16];
    assign rx_q_o = fifo_out[15:0];
    
diff --git a/gr-radar-mono/src/fpga/models/Makefile.am b/gr-radar-mono/src/fpga/models/Makefile.am
new file mode 100644 (file)
index 0000000..1d51f48
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = \
+       fifo_1clk.v
+
+MOSTLYCLEANFILES = *~
diff --git a/gr-radar-mono/src/fpga/models/fifo_1clk.v b/gr-radar-mono/src/fpga/models/fifo_1clk.v
new file mode 100644 (file)
index 0000000..93ada6c
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- verilog -*- */
+/*
+ * Copyright (C) 2003 Matt Ettus
+ * Copyright (C) 2007 Corgan Enterprises LLC
+ * 
+ * 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 GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// Model of Altera FIFO with common clock domain
+
+module fifo_1clk(data, wrreq, rdreq, clock, sclr, q,
+                full, empty, usedw);
+
+   parameter width = 32;
+   parameter depth = 4096;
+   //`define rd_req 0;  // Set this to 0 for rd_ack, 1 for rd_req
+      
+   input [31:0]  data;
+   input        wrreq;
+   input        rdreq;
+   input        clock;
+   input        sclr;
+   output [31:0] q;
+   output       full;
+   output       empty;
+   output [11:0] usedw;
+   
+   reg [width-1:0] mem [0:depth-1];
+   reg [7:0]      rdptr;
+   reg [7:0]      wrptr;
+   
+`ifdef rd_req
+   reg [width-1:0] q;
+`else
+   wire [width-1:0] q;
+`endif
+   
+   reg [11:0]    usedw;
+   
+   integer         i;
+   
+   always @( sclr)
+     begin
+       wrptr <= #1 0;
+       rdptr <= #1 0;
+       for(i=0;i<depth;i=i+1)
+         mem[i] <= #1 0;
+     end
+   
+   always @(posedge clock)
+     if(wrreq)
+       begin
+         wrptr <= #1 wrptr+1;
+         mem[wrptr] <= #1 data;
+       end
+   
+   always @(posedge clock)
+     if(rdreq)
+       begin
+         rdptr <= #1 rdptr+1;
+`ifdef rd_req
+         q <= #1 mem[rdptr];
+`endif
+       end
+   
+`ifdef rd_req
+`else
+   assign q = mem[rdptr];
+`endif
+   
+   always @(posedge clock)
+     usedw <= #1 wrptr - rdptr;
+   
+   assign empty = (wrptr == rdptr);
+endmodule
index aaf2ffd03affaef6f05977e44569175ec7e40e9c..69e48d2186641ff0923bdb90866050f65348e825 100644 (file)
@@ -1,4 +1,4 @@
-*-24.808464 9235000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+*-24.712317 7100000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 @28
 radar_tb.clk
 radar_tb.ena
@@ -24,11 +24,26 @@ radar_tb.uut.tx_dac_q_o[13:0]
 @28
 radar_tb.uut.controller.tx_ctrl_o
 radar_tb.uut.controller.rx_ctrl_o
+radar_tb.uut.auto_tr_o
 @200
 -
 @28
 radar_tb.fifo_strobe
-@8025
+@8024
 radar_tb.fifo_i[15:0]
 @22
 radar_tb.fifo_q[15:0]
+@200
+-
+@22
+radar_tb.uut.pulse_num[15:0]
+radar_tb.uut.receiver.count[15:0]
+@28
+radar_tb.uut.receiver.fifo_empty
+@22
+radar_tb.uut.receiver.fifo_inp[31:0]
+radar_tb.uut.receiver.fifo_out[31:0]
+@28
+radar_tb.uut.receiver.state[2:0]
+@200
+-
index a255ec8543e5291fa11e5b3e37bfb3d9f45c6484..dabbe6754b1fcf18d9b6be740cab05043ec55112 100755 (executable)
@@ -1,3 +1,7 @@
 #!/bin/sh
-iverilog -y ../lib/ -y ../../../../usrp/fpga/sdr_lib           \
+iverilog \
+    -D SIMULATION \
+    -y ../lib/ \
+    -y ../../../../usrp/fpga/sdr_lib \
+    -y ../models/ \
     radar_tb.v -o radar_tb && ./radar_tb > radar_tb.out
index f36c3ac763d5ab529b54f9bf50d30ad3cf322db1..13c36c78a9844a4334cb62de3700961978c068d2 100644 (file)
Binary files a/gr-radar-mono/src/fpga/top/usrp_radar_mono.rbf and b/gr-radar-mono/src/fpga/top/usrp_radar_mono.rbf differ
index f6f862938f83aaa0dfe0b2fdf005192078cd6f31..0382734b8788f215d2ea3ffe240fbd06de2db83f 100644 (file)
@@ -86,7 +86,7 @@ module usrp_radar_mono
 
    // TX
    wire        tx_sample_strobe;
-   wire        tx_empty;
+   wire        auto_tr;
    
    wire        serial_strobe;
    wire [6:0]  serial_addr;
@@ -145,7 +145,7 @@ module usrp_radar_mono
    radar radar_mono ( .clk_i(clk64),.saddr_i(serial_addr),.sdata_i(serial_data),.s_strobe_i(serial_strobe),
             .tx_side_o(tx_side),.tx_strobe_o(tx_sample_strobe),.tx_dac_i_o(tx_i),.tx_dac_q_o(tx_q),
             .rx_adc_i_i(rx_adc0_i),.rx_adc_q_i(rx_adc0_q),
-            .rx_strobe_o(rx_strobe),.rx_ech_i_o(rx_buf_i),.rx_ech_q_o(rx_buf_q)
+            .rx_strobe_o(rx_strobe),.rx_ech_i_o(rx_buf_i),.rx_ech_q_o(rx_buf_q),.auto_tr_o(auto_tr)
           );
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -155,7 +155,7 @@ module usrp_radar_mono
    assign capabilities[7]   = 0;  // `TX_CAP_HB;
    assign capabilities[6:4] = 1;  // `TX_CAP_NCHAN;
    assign capabilities[3]   = 0;  // `RX_CAP_HB;
-   assign capabilities[2:0] = 1;  // `RX_CAP_NCHAN;
+   assign capabilities[2:0] = 2;  // `RX_CAP_NCHAN;
 
    serial_io serial_io
      ( .master_clk(clk64),.serial_clock(SCLK),.serial_data_in(SDI),
@@ -175,7 +175,7 @@ module usrp_radar_mono
        .interp_rate(),.decim_rate(),
        .tx_sample_strobe(),.strobe_interp(),
        .rx_sample_strobe(),.strobe_decim(),
-       .tx_empty(tx_empty),
+       .tx_empty(auto_tr),
        .debug_0(),.debug_1(),
        .debug_2(),.debug_3(),
        .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3) );
index 7aeec1a778623903c4ffcac4769f6330a3fa84a7..701157cc5236068ded85f4e56932cd6fc9039505 100644 (file)
@@ -22,6 +22,7 @@
 
 from gnuradio import gr, usrp
 from gnuradio import eng_notation
+from gr import gr_threading as _threading
 
 n2s = eng_notation.num_to_str
 
@@ -63,11 +64,11 @@ FR_RADAR_FINCR  = usrp.FR_USER_7    # 32-bit FTW increment per transmit clock
 # Transmitter object.  Uses usrp_sink, but only for a handle to the
 # FPGA registers.
 #-----------------------------------------------------------------------
-class radar_tx:
-    def __init__(self, subdev_spec=None, verbose=False, debug=False):
-        self._subdev_spec = subdev_spec
-       self._verbose = verbose
-       self._debug = debug
+class radar_tx(object):
+    def __init__(self, options):
+        self._subdev_spec = options.tx_subdev_spec
+       self._verbose = options.verbose
+       self._debug = options.debug
         self._u = usrp.sink_s(fpga_filename='usrp_radar_mono.rbf')
 
         if self._subdev_spec == None:
@@ -148,47 +149,26 @@ class radar_tx:
 #-----------------------------------------------------------------------
 # Receiver object.  Uses usrp_source_c to receive echo records.
 #-----------------------------------------------------------------------
-class radar_rx:
-    def __init__(self, gain=None, subdev_spec=None, msgq=None, length=None,
-                 verbose=False, debug=False):
-        self._gain = gain
-        self._subdev_spec = subdev_spec
-        self._msgq = msgq
-        self._length = length
-       self._verbose = verbose
-        self._debug = debug
-       self._length_set = False
-                       
-        self._fg = gr.flow_graph()
-        self._u = usrp.source_c(fpga_filename='usrp_radar_mono.rbf')
-        if self._subdev_spec == None:
-            self._subdev_spec = usrp.pick_rx_subdevice(self._u)
-        self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
-
-       if self._debug:
-           self._usrp_sink = gr.file_sink(gr.sizeof_gr_complex, "usrp.dat")
-           self._fg.connect(self._u, self._usrp_sink)
-       
-        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
-        self.set_gain(gain)
+class radar_rx(gr.top_block):
+    def __init__(self, options, callback):
+       gr.top_block.__init__(self, "radar_rx")
 
-        if self._verbose:
-            print "Using", self._subdev.name(), "for radar receiver."
-            print "Setting receiver gain to", self._gain
-        
+        self._subdev_spec = options.rx_subdev_spec
+        self._gain = options.gain
+       self._verbose = options.verbose
+        self._debug = options.debug
+        self._callback = callback
+       self._length_set = False
+       self._connected = False
+        self._msgq = gr.msg_queue()
+        self._watcher = _queue_watcher_thread(self._msgq, self._callback)
+               
     def set_echo_length(self, length):
         # Only call once
        if self._length_set is True:
            raise RuntimeError("Can only set echo length once.")
        self._length = length
-        self._vblen = gr.sizeof_gr_complex*self._length
-       self._s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self._length)
-        self._sink = gr.message_sink(self._vblen, self._msgq, True)
-        self._fg.connect(self._u, self._s2v, self._sink)
        self._length_set = True
-        if self._verbose:
-            print "Receiving echo vectors of length", self._length, \
-                  "(samples)", self._vblen, "(bytes)"
 
     def tune(self, frequency):
         if self._verbose:
@@ -205,35 +185,61 @@ class radar_rx:
             self._gain = float(g[0]+g[1])/2
         self._subdev.set_gain(self._gain)
 
-    def start(self):
+    def begin(self):
+       if not self._connected:
+           self._setup_connections()
+           
         if self._verbose:
-            print "Starting receiver flow graph."
-        self._fg.start()
+            print "Starting receiver..."
+        self.start()
 
-    def wait(self):
+    def end(self):
         if self._verbose:
-            print "Waiting for threads..."
-        self._fg.wait()
+            print "Stopping receiver..."
+        self.stop()
+       self.wait()
+        if self._verbose:
+            print "Receiver stopped."
+
+    def _setup_usrp(self):
+        self._u = usrp.source_c(fpga_filename='usrp_radar_mono.rbf')
+        if self._subdev_spec == None:
+            self._subdev_spec = usrp.pick_rx_subdevice(self._u)
+        self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
+        self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
 
-    def stop(self):
         if self._verbose:
-            print "Stopping receiver flow graph."
-        self._fg.stop()
-        self.wait()
+            print "Using", self._subdev.side_and_name(), "for radar receiver."
+            print "Setting receiver gain to", self._gain
+        self.set_gain(self._gain)
+       self._subdev.set_auto_tr(True)
+       self._subdev.set_atr_tx_delay(26) # TX CORDIC pipeline delay
+       self._subdev.set_atr_rx_delay(26)
+               
+    def _setup_connections(self):
+       if not self._length_set:
+           raise RuntimeError("Echo length not set.")
+       self._setup_usrp()
+        self._vblen = gr.sizeof_gr_complex*self._length
+       self._s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self._length)
+        self._sink = gr.message_sink(self._vblen, self._msgq, False)
+        self.connect(self._u, self._s2v, self._sink)
+
         if self._verbose:
-            print "Receiver flow graph stopped."
+            print "Generating echo vectors of length", self._length, \
+                  "(samples)", self._vblen, "(bytes)"
 
-class radar:
-    def __init__(self, msgq=None, tx_subdev_spec=None, rx_subdev_spec=None,
-                 gain=None, verbose=False, debug=False):
-        self._msgq = msgq
-        self._verbose = verbose
-        self._debug = debug
+       self._connected = True
+
+class radar(object):
+    def __init__(self, options, callback):
+        
+        self._verbose = options.verbose
+        self._debug = options.debug
 
        self._mode = 0
-        self._trans = radar_tx(subdev_spec=tx_subdev_spec, verbose=self._verbose, debug=self._debug)
-        self._rcvr = radar_rx(gain=gain, msgq=self._msgq, subdev_spec=rx_subdev_spec, 
-                             verbose=self._verbose, debug=self._debug)
+        self._trans = radar_tx(options)        
+        self._rcvr = radar_rx(options, callback)
        self.set_reset(True)
        self.set_tx_board(self._trans.subdev_spec())
         self.set_debug(self._debug)
@@ -285,10 +291,28 @@ class radar:
     def start(self):
        self.set_reset(False)
        self._trans.start()
-       self._rcvr.start()
+       self._rcvr.begin()
        
     def stop(self):
+       self._rcvr.end()
        self._trans.stop()
-       self._rcvr.stop()
        self.set_reset(True)
 
+#-----------------------------------------------------------------------
+# Queue watcher.  Dispatches received echos to callback.
+#-----------------------------------------------------------------------
+class _queue_watcher_thread(_threading.Thread):
+    def __init__(self, msgq, callback):
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self._msgq = msgq
+        self._callback = callback
+        self._keep_running = True
+        self.start()
+
+    def run(self):
+        while self._keep_running == True:
+            msg = self._msgq.delete_head()
+            if self._callback:
+                self._callback(msg.to_string())
+
index e372ec9f04ce792448df9af7ca7403abff0c8066..077b798caadfdb783c85a18ea60557956009913c 100755 (executable)
@@ -25,11 +25,18 @@ from gnuradio.radar_mono import radar
 from gnuradio import eng_notation
 from gnuradio.eng_option import eng_option
 from optparse import OptionParser
-import sys
+import sys, time
 
 n2s = eng_notation.num_to_str
+logfile = None
 
+def process_echo(echo):
+    global logfile
+    #sys.stdout.write('.')
+    logfile.write(echo)
+        
 def main():
+    global logfile
     parser = OptionParser(option_class=eng_option)
     parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
                      help="use transmitter board side A or B (default is first found)")
@@ -55,59 +62,37 @@ def main():
                       help="enable verbose output, default is disabled")
     parser.add_option("-D", "--debug", action="store_true", default=False,
                       help="enable debugging output, default is disabled")
+    parser.add_option("-F", "--filename", default=None,
+                      help="log received echos to file")
 
-    # NOT IMPLEMENTED
-    #parser.add_option("-l", "--loopback", action="store_true", default=False,
-    #                  help="enable digital loopback, default is disabled")
-    #parser.add_option("-F", "--filename", default=None,
-    #                  help="log received echos to file")
-                     
     (options, args) = parser.parse_args()
 
     if len(args) != 0:
         parser.print_help()
         sys.exit(1)
 
-    """
     if options.filename == None:
         print "Must supply filename for logging received data."
         sys.exit(1)
     else:
         if options.verbose:
             print "Logging echo records to file: ", options.filename
-    """
-        
-    msgq = gr.msg_queue()
-    s = radar(msgq=msgq, tx_subdev_spec=options.tx_subdev_spec,
-              rx_subdev_spec=options.rx_subdev_spec,gain=options.gain,
-             verbose=options.verbose, debug=options.debug)
-
-    s.set_ton(options.ton)
-    s.set_tsw(options.tsw)
-    s.set_tlook(options.tlook)
-    s.set_prf(options.prf)
-    s.set_amplitude(options.amplitude)
-    s.set_freq(options.frequency, options.chirp_width)
 
-    s.start()
+    logfile = open(options.filename, 'wb')
+        
+    r = radar(options, process_echo)
 
-    #f = open(options.filename, "wb")
-    print "Enter CTRL-C to stop."
-    try:
-       while 1:
-           if not msgq.empty_p():
-                msg = msgq.delete_head()
-                if msg.type() == 1:
-                    break
-                echo = msg.to_string()
-                if options.debug:
-                    print "Received echo vector of length", len(echo)
-               #f.write(rec)
-               
-    except KeyboardInterrupt:
-        pass
+    r.set_ton(options.ton)
+    r.set_tsw(options.tsw)
+    r.set_tlook(options.tlook)
+    r.set_prf(options.prf)
+    r.set_amplitude(options.amplitude)
+    r.set_freq(options.frequency, options.chirp_width)
 
-    s.stop()
-        
+    r.start()
+    raw_input("Press ENTER to stop.")
+    r.stop()
+    logfile.close()
+            
 if __name__ == "__main__":
     main()