diff options
| -rw-r--r-- | firmware/microblaze/apps/txrx_uhd.c | 120 | ||||
| -rw-r--r-- | firmware/microblaze/lib/banal.c | 18 | ||||
| -rw-r--r-- | firmware/microblaze/lib/banal.h | 3 | ||||
| -rw-r--r-- | firmware/microblaze/lib/memory_map.h | 4 | ||||
| -rw-r--r-- | firmware/microblaze/lib/u2_init.c | 4 | ||||
| -rw-r--r-- | fpga/usrp2/vrt/vita_rx_control.v | 24 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/fw_common.h | 14 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 22 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 59 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_regs.hpp | 21 | 
11 files changed, 83 insertions, 209 deletions
| diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index 8ff3b8c58..d5b400e0c 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -126,14 +126,7 @@ dbsm_t dsp_rx_sm;	// the state machine  // The mac address of the host we're sending to.  eth_mac_addr_t host_mac_addr; -//controls continuous streaming... -static bool   auto_reload_command = false; -static size_t streaming_items_per_frame = 0; -static int    streaming_frame_count = 0; -#define FRAMES_PER_CMD	2 -  static void setup_network(void); -static void setup_vrt(void);  // ----------------------------------------------------------------  // the fast-path setup global variables @@ -154,9 +147,6 @@ void handle_udp_data_packet(      struct socket_address src, struct socket_address dst,      unsigned char *payload, int payload_len  ){ -    //store the 2nd word as the following: -    streaming_items_per_frame = ((uint32_t *)payload)[1]; -      //its a tiny payload, load the fast-path variables      fp_mac_addr_src = *ethernet_mac_addr();      arp_cache_lookup_mac(&src.addr, &fp_mac_addr_dst); @@ -177,23 +167,12 @@ void handle_udp_data_packet(      //setup network and vrt      setup_network(); -    setup_vrt();      // kick off the state machine      dbsm_start(&dsp_rx_sm);  } -static void inline issue_stream_command(size_t nsamps, bool now, bool chain, uint32_t secs, uint32_t ticks, bool start){ -    //printf("Stream cmd: nsamps %d, now %d, chain %d, secs %u, ticks %u\n", (int)nsamps, now, chain, secs, ticks); -    sr_rx_ctrl->cmd = MK_RX_CMD(nsamps, now, chain); - -    if (start) dbsm_start(&dsp_rx_sm); - -    sr_rx_ctrl->time_secs = secs; -    sr_rx_ctrl->time_ticks = ticks;	// enqueue command -} -  #define OTW_GPIO_BANK_TO_NUM(bank) \      (((bank) == USRP2_DIR_RX)? (GPIO_RX_BANK) : (GPIO_TX_BANK)) @@ -304,72 +283,6 @@ void handle_udp_ctrl_packet(          break;      /******************************************************************* -     * Streaming -     ******************************************************************/ -    case USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO:{ - -        //issue two commands and set the auto-reload flag -        if (ctrl_data_in->data.stream_cmd.continuous){ -            printf("Setting up continuous streaming...\n"); -            printf("items per frame: %d\n", (int)streaming_items_per_frame); -            hal_set_leds(LED_A, LEDS_SW); -            auto_reload_command = true; -            streaming_frame_count = FRAMES_PER_CMD; - -            issue_stream_command( -                streaming_items_per_frame * FRAMES_PER_CMD, -                (ctrl_data_in->data.stream_cmd.now == 0)? false : true, //now -                true, //chain -                ctrl_data_in->data.stream_cmd.secs, -                ctrl_data_in->data.stream_cmd.ticks, -                true //start -            ); - -            issue_stream_command( -                streaming_items_per_frame * FRAMES_PER_CMD, -                true, //now -                true, //chain -                0, 0, //time does not matter -                false -            ); - -        } - -        //issue regular stream commands (split commands if too large) -        else{ -            hal_set_leds(0, LEDS_SW); -            auto_reload_command = false; -            size_t num_samps = ctrl_data_in->data.stream_cmd.num_samps; -            if (num_samps == 0) num_samps = 1; //FIXME hack, zero is used when stopping continuous streaming but it somehow makes it inifinite - -            bool chain = num_samps > MAX_SAMPLES_PER_CMD; -            issue_stream_command( -                (chain)? streaming_items_per_frame : num_samps, //nsamps -                (ctrl_data_in->data.stream_cmd.now == 0)? false : true, //now -                (ctrl_data_in->data.stream_cmd.chain == 0)? chain : true, //chain -                ctrl_data_in->data.stream_cmd.secs, -                ctrl_data_in->data.stream_cmd.ticks, -                false -            ); - -            //handle rest of the samples that did not fit into one cmd -            while(chain){ -                num_samps -= MAX_SAMPLES_PER_CMD; -                chain = num_samps > MAX_SAMPLES_PER_CMD; -                issue_stream_command( -                    (chain)? streaming_items_per_frame : num_samps, //nsamps -                    true, //now -                    (ctrl_data_in->data.stream_cmd.chain == 0)? chain : true, //chain -                    0, 0, //time does not matter -                    false -                ); -            } -        } -        ctrl_data_out.id = USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE; -        break; -    } - -    /*******************************************************************       * Peek and Poke Register       ******************************************************************/      case USRP2_CTRL_ID_POKE_THIS_REGISTER_FOR_ME_BRO: @@ -463,25 +376,6 @@ eth_pkt_inspector(dbsm_t *sm, int bufno)  //------------------------------------------------------------------ -static bool vrt_has_trailer(void){ -    return USRP2_HOST_RX_VRT_TRAILER_WORDS32 > 0; -} - -static void setup_vrt(void){ -  // setup RX DSP regs -  sr_rx_ctrl->nsamples_per_pkt = streaming_items_per_frame; -  sr_rx_ctrl->nchannels = 1; -  sr_rx_ctrl->clear_overrun = 1;			// reset -  sr_rx_ctrl->vrt_header = (0 -     | VRTH_PT_IF_DATA_WITH_SID -     | (vrt_has_trailer()? VRTH_HAS_TRAILER : 0) -     | VRTH_TSI_OTHER -     | VRTH_TSF_SAMPLE_CNT -  ); -  sr_rx_ctrl->vrt_stream_id = 0; -  sr_rx_ctrl->vrt_trailer = 0; -} -  /*   * 1's complement sum for IP and UDP headers   * @@ -554,13 +448,6 @@ fw_sets_seqno_inspector(dbsm_t *sm, int buf_this)	// returns false    buff->control_word = MK_RX_CTRL_WORD(vrt_len);    buff->vrt_header[0] = (buff->vrt_header[0] & ~VRTH_PKT_SIZE_MASK) | (vrt_len & VRTH_PKT_SIZE_MASK); -  // queue up another rx command when required -  if (auto_reload_command && --streaming_frame_count == 0){ -    streaming_frame_count = FRAMES_PER_CMD; -    sr_rx_ctrl->time_secs = 0; -    sr_rx_ctrl->time_ticks = 0; //enqueue last command -  } -    return false;		// we didn't handle the packet  } @@ -662,13 +549,6 @@ hal_gpio_set_sels(GPIO_RX_BANK, "aaaaaaaaaaaaaaaa");        // FIXME Figure out how to handle this robustly.        // Any buffers that are emptying should be allowed to drain... -      if (auto_reload_command){ -	// restart_streaming(); -	// FIXME report error -      } -      else { -	// FIXME report error -      }        putchar('O');      }    } diff --git a/firmware/microblaze/lib/banal.c b/firmware/microblaze/lib/banal.c index 23f5f3b8a..42937957f 100644 --- a/firmware/microblaze/lib/banal.c +++ b/firmware/microblaze/lib/banal.c @@ -29,21 +29,3 @@ get_uint64(const unsigned char *s)  {    return (((uint64_t)get_uint32(s)) << 32) | get_uint32(s+4);  } - -uint32_t -divide_uint64(uint64_t dividend, uint32_t divisor) -{ -    uint32_t result = 0; -    uint64_t dividend_ = 0; -    for(int i = 31; i >= 0; i--){ -        //approximate the divisor with the ith result bit set -        uint64_t tmp = dividend_; -        tmp += (uint64_t)divisor << i; -        //set the ith result bit if the approximation is less -        if (tmp <= dividend){ -            dividend_ = tmp; -            result |= 1 << i; -        } -    } -    return result; -} diff --git a/firmware/microblaze/lib/banal.h b/firmware/microblaze/lib/banal.h index 6d9420602..7b3c71a20 100644 --- a/firmware/microblaze/lib/banal.h +++ b/firmware/microblaze/lib/banal.h @@ -87,7 +87,4 @@ get_int64(const unsigned char *s)  void  print_ip(struct ip_addr ip); -uint32_t -divide_uint64(uint64_t dividend, uint32_t divisor); -  #endif /* INCLUDED_BANAL_H */ diff --git a/firmware/microblaze/lib/memory_map.h b/firmware/microblaze/lib/memory_map.h index fed1e5259..cdf3dd338 100644 --- a/firmware/microblaze/lib/memory_map.h +++ b/firmware/microblaze/lib/memory_map.h @@ -525,10 +525,6 @@ typedef struct {    volatile uint32_t     pad[7];         // Make each structure 16 elements long  } sr_rx_ctrl_t; -#define MAX_SAMPLES_PER_CMD 0x3fffffff -#define	MK_RX_CMD(nsamples, now, chain) \ -  ((((now) & 0x1) << 31) | (((chain) & 0x1) << 30) | ((nsamples) & 0x3fffffff)) -  #define sr_rx_ctrl ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL))  // --- dsp rx regs --- diff --git a/firmware/microblaze/lib/u2_init.c b/firmware/microblaze/lib/u2_init.c index 399d834cb..40237ba87 100644 --- a/firmware/microblaze/lib/u2_init.c +++ b/firmware/microblaze/lib/u2_init.c @@ -50,8 +50,8 @@ u2_init(void)    hal_gpio_set_ddr(GPIO_TX_BANK, 0x0000, 0xffff);    hal_gpio_set_ddr(GPIO_RX_BANK, 0x0000, 0xffff); -  hal_gpio_write(GPIO_TX_BANK, 0x0000, 0xffff);	// init s/w output value to zero -  hal_gpio_write(GPIO_RX_BANK, 0x0000, 0xffff); +  //hal_gpio_write(GPIO_TX_BANK, 0x0000, 0xffff);	// init s/w output value to zero +  //hal_gpio_write(GPIO_RX_BANK, 0x0000, 0xffff);    dsp_rx_regs->gpio_stream_enable = 0; // I, Q LSBs come from DSP diff --git a/fpga/usrp2/vrt/vita_rx_control.v b/fpga/usrp2/vrt/vita_rx_control.v index 669b8299d..742dd47e0 100644 --- a/fpga/usrp2/vrt/vita_rx_control.v +++ b/fpga/usrp2/vrt/vita_rx_control.v @@ -31,13 +31,13 @@ module vita_rx_control     wire [63:0] 	  rcvtime_pre;     reg [63:0] 	  rcvtime; -   wire [29:0] 	  numlines_pre; -   wire 	  send_imm_pre, chain_pre; -   reg 		  send_imm, chain; +   wire [28:0] 	  numlines_pre; +   wire 	  send_imm_pre, chain_pre, reload_pre; +   reg 		  send_imm, chain, reload;     wire 	  full_ctrl, read_ctrl, empty_ctrl, write_ctrl;     reg 		  sc_pre2;     wire [33:0] 	  fifo_line; -   reg [29:0] 	  lines_left; +   reg [28:0] 	  lines_left, lines_total;     reg [2:0] 	  ibs_state;     wire 	  now, early, late;     wire 	  sample_fifo_in_rdy; @@ -67,7 +67,7 @@ module vita_rx_control     shortfifo #(.WIDTH(96)) commandfifo       (.clk(clk),.rst(reset),.clear(clear_int),        .datain({new_command,new_time}), .write(write_ctrl&~full_ctrl), .full(full_ctrl), -      .dataout({send_imm_pre,chain_pre,numlines_pre,rcvtime_pre}),  +      .dataout({send_imm_pre,chain_pre,reload_pre,numlines_pre,rcvtime_pre}),         .read(read_ctrl), .empty(empty_ctrl),        .occupied(command_queue_len), .space() ); @@ -98,7 +98,7 @@ module vita_rx_control        .src_rdy_o(sample_fifo_src_rdy_o), .dst_rdy_i(sample_fifo_dst_rdy_i),        .space(), .occupied() ); -   // Inband Signalling State Machine +   // Inband Signallling State Machine     time_compare        time_compare (.time_now(vita_time), .trigger_time(rcvtime), .now(now), .early(early), .late(late)); @@ -111,9 +111,11 @@ module vita_rx_control         begin  	  ibs_state 	   <= IBS_IDLE;  	  lines_left 	   <= 0; +	  lines_total	   <= 0;  	  rcvtime 	   <= 0;  	  send_imm 	   <= 0;  	  chain 	   <= 0; +	  reload	   <= 0;         end       else         case(ibs_state) @@ -121,10 +123,12 @@ module vita_rx_control  	   if(~empty_ctrl)  	     begin  		lines_left <= numlines_pre; +		lines_total <= numlines_pre;  		rcvtime <= rcvtime_pre;  		ibs_state <= IBS_WAITING;  		send_imm <= send_imm_pre;  		chain <= chain_pre; +		reload <= reload_pre;  	     end  	 IBS_WAITING :  	   if(go_now) @@ -141,14 +145,21 @@ module vita_rx_control  		  if(lines_left == 1)  		    if(~chain)  		      ibs_state      <= IBS_IDLE; +		    else if(empty_ctrl & reload) +		      begin +		        ibs_state      <= IBS_RUNNING; +		        lines_left     <= lines_total; +		      end  		    else if(empty_ctrl)  		      ibs_state      <= IBS_BROKENCHAIN;  		    else  		      begin  			 lines_left  <= numlines_pre; +			 lines_total <= numlines_pre;  			 rcvtime     <= rcvtime_pre;  			 send_imm    <= send_imm_pre;  			 chain 	     <= chain_pre; +			 reload      <= reload_pre;  			 if(numlines_pre == 0)  // If we are told to stop here  			   ibs_state <= IBS_IDLE;  			 else @@ -178,3 +189,4 @@ module vita_rx_control  		       { 2'b0, overrun, chain_pre, sample_fifo_in_rdy, attempt_sample_write, sample_fifo_src_rdy_o,sample_fifo_dst_rdy_i} };  endmodule // rx_control + diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 84314a656..bd61ac376 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -77,9 +77,6 @@ void usrp2_impl::init_ddc_config(void){      _ddc_decim = default_decim;      _ddc_freq = 0;      update_ddc_config(); - -    //initial command that kills streaming (in case if was left on) -    issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);  }  void usrp2_impl::update_ddc_config(void){ diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index e80001ff2..f28013cf6 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -34,7 +34,7 @@ extern "C" {  //defines the protocol version in this shared header  //increment this value when the protocol is changed -#define USRP2_PROTO_VERSION 2 +#define USRP2_PROTO_VERSION 3  //used to differentiate control packets over data port  #define USRP2_INVALID_VRT_HEADER 0 @@ -70,9 +70,6 @@ typedef enum{      USRP2_CTRL_ID_WRITE_THESE_I2C_VALUES_BRO = 'h',      USRP2_CTRL_ID_COOL_IM_DONE_I2C_WRITE_DUDE = 'H', -    USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO = '{', -    USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE = '}', -      USRP2_CTRL_ID_POKE_THIS_REGISTER_FOR_ME_BRO = 'p',      USRP2_CTRL_ID_OMG_POKED_REGISTER_SO_BAD_DUDE = 'P', @@ -114,15 +111,6 @@ typedef struct{              _SINS_ uint8_t data[sizeof(_SINS_ uint32_t)];          } i2c_args;          struct { -            _SINS_ uint8_t now; //stream now? -            _SINS_ uint8_t continuous; //auto-reload commmands? -            _SINS_ uint8_t chain; -            _SINS_ uint8_t _pad[1]; -            _SINS_ uint32_t secs; -            _SINS_ uint32_t ticks; -            _SINS_ uint32_t num_samps; -        } stream_cmd; -        struct {              _SINS_ uint32_t addr;              _SINS_ uint32_t data;              _SINS_ uint8_t num_bytes; //1, 2, 4 diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 367a1d9fb..a2e99c824 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -16,6 +16,7 @@  //  #include "usrp2_impl.hpp" +#include "usrp2_regs.hpp"  #include <uhd/transport/convert_types.hpp>  #include <boost/format.hpp>  #include <boost/asio.hpp> //htonl and ntohl @@ -39,14 +40,23 @@ void usrp2_impl::io_init(void){      _rx_copy_buff = asio::buffer("", 0);      //send a small data packet so the usrp2 knows the udp source port -    //and the maximum number of lines (32 bit words) per packet      managed_send_buffer::sptr send_buff = _data_transport->get_send_buff(); -    boost::uint32_t data[2] = { -        htonl(USRP2_INVALID_VRT_HEADER), -        htonl(_max_rx_samples_per_packet) -    }; -    memcpy(send_buff->cast<void*>(), data, sizeof(data)); +    boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER); +    memcpy(send_buff->cast<void*>(), &data, sizeof(data));      send_buff->done(sizeof(data)); + +    //setup RX DSP regs +    _iface->poke32(FR_RX_CTRL_NSAMPS_PER_PKT, _max_rx_samples_per_packet); +    _iface->poke32(FR_RX_CTRL_NCHANNELS, 1); +    _iface->poke32(FR_RX_CTRL_CLEAR_OVERRUN, 1); //reset +    _iface->poke32(FR_RX_CTRL_VRT_HEADER, 0 +        | (0x1 << 28) //if data with stream id +        | (0x1 << 26) //has trailer +        | (0x3 << 22) //integer time other +        | (0x1 << 20) //fractional time sample count +    ); +    _iface->poke32(FR_RX_CTRL_VRT_STREAM_ID, 0); +    _iface->poke32(FR_RX_CTRL_VRT_TRAILER, 0);  }  /*********************************************************************** diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 36bef4f25..48aeb2a62 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -119,40 +119,31 @@ void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){  }  void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ -    //setup the out data -    usrp2_ctrl_data_t out_data; -    out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO); -    out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0; -    out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs); -    out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.get_ticks(get_master_clock_freq())); - -    //set these to defaults, then change in the switch statement -    out_data.data.stream_cmd.continuous = 0; -    out_data.data.stream_cmd.chain = 0; -    out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps); - -    //setup chain, num samps, and continuous below -    switch(stream_cmd.stream_mode){ -    case stream_cmd_t::STREAM_MODE_START_CONTINUOUS: -        out_data.data.stream_cmd.continuous = 1; -        break; - -    case stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS: -        out_data.data.stream_cmd.num_samps = htonl(0); -        break; - -    case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE: -        //all set by defaults above -        break; - -    case stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE: -        out_data.data.stream_cmd.chain = 1; -        break; -    } - -    //send and recv -    usrp2_ctrl_data_t in_data = _iface->ctrl_send_and_recv(out_data); -    UHD_ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE); +    UHD_ASSERT_THROW(stream_cmd.num_samps <= FR_RX_CTRL_MAX_SAMPS_PER_CMD); + +    //setup the mode to instruction flags +    typedef boost::tuple<bool, bool, bool> inst_t; +    static const uhd::dict<stream_cmd_t::stream_mode_t, inst_t> mode_to_inst = boost::assign::map_list_of +                                                            //reload, chain, samps +        (stream_cmd_t::STREAM_MODE_START_CONTINUOUS,   inst_t(true,  true,  false)) +        (stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS,    inst_t(false, false, false)) +        (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE, inst_t(false, false, true)) +        (stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE, inst_t(false, true,  true)) +    ; + +    //setup the instruction flag values +    bool inst_reload, inst_chain, inst_samps; +    boost::tie(inst_reload, inst_chain, inst_samps) = mode_to_inst[stream_cmd.stream_mode]; + +    //issue the stream command +    _iface->poke32(FR_RX_CTRL_STREAM_CMD, FR_RX_CTRL_MAKE_CMD( +        (inst_samps)? stream_cmd.num_samps : ((inst_chain)? _max_rx_samples_per_packet : 1), +        (stream_cmd.stream_now)? 1 : 0, +        (inst_chain)? 1 : 0, +        (inst_reload)? 1 : 0 +    )); +    _iface->poke32(FR_RX_CTRL_TIME_SECS,  stream_cmd.time_spec.secs); +    _iface->poke32(FR_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_ticks(get_master_clock_freq()));  }  /*********************************************************************** diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 0e2a18756..67a342217 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -207,4 +207,25 @@  #define FR_ATR_FULL_TXSIDE  FR_ATR_BASE + 12  #define FR_ATR_FULL_RXSIDE  FR_ATR_BASE + 14 +/////////////////////////////////////////////////// +// ATR Controller, Slave 11 +/////////////////////////////////////////////////// +// The following 3 are logically a single command register. +// They are clocked into the underlying fifo when time_ticks is written. +#define FR_RX_CTRL_STREAM_CMD        _SR_ADDR(SR_RX_CTRL + 0) // {now, chain, num_samples(30) +#define FR_RX_CTRL_TIME_SECS         _SR_ADDR(SR_RX_CTRL + 1) +#define FR_RX_CTRL_TIME_TICKS        _SR_ADDR(SR_RX_CTRL + 2) + +#define FR_RX_CTRL_CLEAR_OVERRUN     _SR_ADDR(SR_RX_CTRL + 3) // write anything to clear overrun +#define FR_RX_CTRL_VRT_HEADER        _SR_ADDR(SR_RX_CTRL + 4) // word 0 of packet.  FPGA fills in packet counter +#define FR_RX_CTRL_VRT_STREAM_ID     _SR_ADDR(SR_RX_CTRL + 5) // word 1 of packet. +#define FR_RX_CTRL_VRT_TRAILER       _SR_ADDR(SR_RX_CTRL + 6) +#define FR_RX_CTRL_NSAMPS_PER_PKT    _SR_ADDR(SR_RX_CTRL + 7) +#define FR_RX_CTRL_NCHANNELS         _SR_ADDR(SR_RX_CTRL + 8) // 1 in basic case, up to 4 for vector sources + +//helpful macros for dealing with stream cmd +#define FR_RX_CTRL_MAX_SAMPS_PER_CMD 0x1fffffff +#define FR_RX_CTRL_MAKE_CMD(nsamples, now, chain, reload) \ +  ((((now) & 0x1) << 31) | (((chain) & 0x1) << 30) | (((reload) & 0x1) << 29) | ((nsamples) & 0x1fffffff)) +  #endif /* INCLUDED_USRP2_REGS_HPP */ | 
