diff options
| -rw-r--r-- | firmware/microblaze/apps/txrx.c | 174 | ||||
| -rw-r--r-- | firmware/microblaze/lib/memory_map.h | 3 | ||||
| -rw-r--r-- | host/examples/rx_timed_samples.cpp | 14 | ||||
| -rw-r--r-- | host/include/uhd/props.hpp | 2 | ||||
| -rw-r--r-- | host/include/uhd/simple_device.hpp | 4 | ||||
| -rw-r--r-- | host/include/uhd/time_spec.hpp | 10 | ||||
| -rw-r--r-- | host/include/uhd/types.hpp | 52 | ||||
| -rw-r--r-- | host/lib/simple_device.cpp | 13 | ||||
| -rw-r--r-- | host/lib/time_spec.cpp | 5 | ||||
| -rw-r--r-- | host/lib/transport/udp_zero_copy_asio.cpp | 2 | ||||
| -rw-r--r-- | host/lib/types.cpp | 15 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dsp_impl.cpp | 42 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/fw_common.h | 16 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 77 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 10 | 
16 files changed, 233 insertions, 214 deletions
| diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c index 5eec99c4f..a2e3f0430 100644 --- a/firmware/microblaze/apps/txrx.c +++ b/firmware/microblaze/apps/txrx.c @@ -54,11 +54,6 @@  #define FW_SETS_SEQNO	1	// define to 0 or 1 (FIXME must be 1 for now) -#if (FW_SETS_SEQNO) -static int fw_seqno;	// used when f/w is filling in sequence numbers -#endif - -  /*   * Full duplex Tx and Rx between ethernet and DSP pipelines   * @@ -127,18 +122,14 @@ 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; -#define TIME_NOW ((uint32_t)(~0)) - -// variables for streaming mode - -static bool         streaming_p = false; -static unsigned int streaming_items_per_frame = 0; -static uint32_t     time_secs = TIME_NOW; -static uint32_t     time_ticks = TIME_NOW; -static int          streaming_frame_count = 0; +//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 -bool is_streaming(void){ return streaming_p; } +static void setup_network(void); +static void setup_vrt(void);  // ----------------------------------------------------------------  // the fast-path setup global variables @@ -159,6 +150,9 @@ 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); @@ -176,6 +170,24 @@ void handle_udp_data_packet(      print_ip_addr(&fp_socket_dst.addr); newline();      printf("  destination udp port: %d\n", fp_socket_dst.port);      newline(); + +    //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) \ @@ -443,20 +455,68 @@ void handle_udp_ctrl_packet(          ctrl_data_out.id = USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE;          break; -    case USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO: -        time_secs =  ctrl_data_in->data.streaming.secs; -        time_ticks = ctrl_data_in->data.streaming.ticks; -        streaming_items_per_frame = ctrl_data_in->data.streaming.samples; +    /******************************************************************* +     * 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"); +            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 +            ); -        if (ctrl_data_in->data.streaming.enabled == 0){ -            stop_rx_cmd();          } + +        //issue regular stream commands (split commands if too large)          else{ -            start_rx_streaming_cmd(); -        } +            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 +                chain, //chain +                ctrl_data_in->data.stream_cmd.secs, +                ctrl_data_in->data.stream_cmd.ticks, +                false +            ); -        ctrl_data_out.id = USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE; +            //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 +                    chain, //chain +                    0, 0, //time does not matter +                    false +                ); +            } +        } +        ctrl_data_out.id = USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE;          break; +    }      /*******************************************************************       * DUC @@ -531,7 +591,7 @@ eth_pkt_inspector(dbsm_t *sm, int bufno)    // In the future, a hardware state machine will do this...    if ( //warning! magic numbers approaching....        (((buff + ((2 + 14 + 20)/sizeof(uint32_t)))[0] & 0xffff) == USRP2_UDP_DATA_PORT) && -      ((buff + ((2 + 14 + 20 + 8)/sizeof(uint32_t)))[0] != 0) +      ((buff + ((2 + 14 + 20 + 8)/sizeof(uint32_t)))[0] != USRP2_INVALID_VRT_HEADER)    ) return false;    //test if its an ip recovery packet @@ -557,7 +617,7 @@ eth_pkt_inspector(dbsm_t *sm, int bufno)  //------------------------------------------------------------------ -static uint16_t get_vrt_packet_words(void){ +static size_t get_vrt_packet_words(void){      return streaming_items_per_frame + \          USRP2_HOST_RX_VRT_HEADER_WORDS32 + \          USRP2_HOST_RX_VRT_TRAILER_WORDS32; @@ -567,9 +627,7 @@ static bool vrt_has_trailer(void){      return USRP2_HOST_RX_VRT_TRAILER_WORDS32 > 0;  } -void -restart_streaming(void) -{ +static void setup_vrt(void){    // setup RX DSP regs    sr_rx_ctrl->nsamples_per_pkt = streaming_items_per_frame;    sr_rx_ctrl->nchannels = 1; @@ -582,26 +640,6 @@ restart_streaming(void)    );    sr_rx_ctrl->vrt_stream_id = 0;    sr_rx_ctrl->vrt_trailer = 0; - -  streaming_p = true; -  streaming_frame_count = FRAMES_PER_CMD; - -  sr_rx_ctrl->cmd = -    MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame, -    (time_ticks==TIME_NOW)?1:0, 1);  // conditionally set "now" bit, set "chain" bit - -  // kick off the state machine -  dbsm_start(&dsp_rx_sm); - -  sr_rx_ctrl->time_secs = time_secs; -  sr_rx_ctrl->time_ticks = time_ticks;		// enqueue first of two commands - -  // make sure this one and the rest have the "now" and "chain" bits set. -  sr_rx_ctrl->cmd = -    MK_RX_CMD(FRAMES_PER_CMD * streaming_items_per_frame, 1, 1); - -  sr_rx_ctrl->time_secs = 0; -  sr_rx_ctrl->time_ticks = 0;		// enqueue second command  }  /* @@ -630,19 +668,15 @@ link_changed_callback(int speed)    printf("\neth link changed: speed = %d\n", speed);  } -void -start_rx_streaming_cmd(void) -{ -  /* -   * Construct  ethernet header and preload into two buffers -   */ +static void setup_network(void){ +  //setup header and load into two buffers    struct {      uint32_t ctrl_word;    } mem _AL4;    memset(&mem, 0, sizeof(mem)); -  printf("samples per frame: %d\n", streaming_items_per_frame); -  printf("words in a vrt packet %d\n", get_vrt_packet_words()); +  printf("items per frame: %d\n", (int)streaming_items_per_frame); +  printf("words in a vrt packet %d\n", (int)get_vrt_packet_words());    mem.ctrl_word = get_vrt_packet_words()*sizeof(uint32_t) | 1 << 16;    memcpy_wa(buffer_ram(DSP_RX_BUF_0), &mem, sizeof(mem)); @@ -678,26 +712,6 @@ start_rx_streaming_cmd(void)    sr_udp_sm->udp_hdr.dst_port = fp_socket_dst.port;    sr_udp_sm->udp_hdr.length = UDP_SM_INS_UDP_LEN;    sr_udp_sm->udp_hdr.checksum = UDP_SM_LAST_WORD;		// zero UDP checksum - -  if (FW_SETS_SEQNO) -    fw_seqno = 0; - -  restart_streaming(); -} - -void -stop_rx_cmd(void) -{ -  if (is_streaming()){ -    streaming_p = false; - -    // no samples, "now", not chained -    sr_rx_ctrl->cmd = MK_RX_CMD(0, 1, 0); - -    sr_rx_ctrl->time_secs = 0; -    sr_rx_ctrl->time_ticks = 0;	// enqueue command -  } -  }  #if (FW_SETS_SEQNO) @@ -713,10 +727,10 @@ bool  fw_sets_seqno_inspector(dbsm_t *sm, int buf_this)	// returns false  {    // queue up another rx command when required -  if (streaming_p && --streaming_frame_count == 0){ +  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; +    sr_rx_ctrl->time_ticks = 0; //enqueue last command    }    return false;		// we didn't handle the packet @@ -820,7 +834,7 @@ main(void)        // FIXME Figure out how to handle this robustly.        // Any buffers that are emptying should be allowed to drain... -      if (streaming_p){ +      if (auto_reload_command){  	// restart_streaming();  	// FIXME report error        } diff --git a/firmware/microblaze/lib/memory_map.h b/firmware/microblaze/lib/memory_map.h index bb6a1036d..fed1e5259 100644 --- a/firmware/microblaze/lib/memory_map.h +++ b/firmware/microblaze/lib/memory_map.h @@ -525,8 +525,9 @@ 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)) +  ((((now) & 0x1) << 31) | (((chain) & 0x1) << 30) | ((nsamples) & 0x3fffffff))  #define sr_rx_ctrl ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL)) diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 97f75647e..7d58187cd 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -65,9 +65,14 @@ int main(int argc, char *argv[]){      //setup streaming      std::cout << std::endl; -    std::cout << boost::format("Begin streaming %u seconds in the future...") -        % seconds_in_future << std::endl; -    sdev->set_streaming_at(uhd::time_spec_t(seconds_in_future)); +    std::cout << boost::format("Begin streaming %u samples, %d seconds in the future...") +        % total_num_samps % seconds_in_future << std::endl; +    uhd::stream_cmd_t stream_cmd; +    stream_cmd.stream_now = false; +    stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); +    stream_cmd.continuous = false; +    stream_cmd.num_samps = total_num_samps; +    sdev->issue_stream_cmd(stream_cmd);      //loop until total number of samples reached      size_t num_acc_samps = 0; //number of accumulated samples @@ -83,8 +88,7 @@ int main(int argc, char *argv[]){          num_acc_samps += num_rx_samps;      } -    //finished, stop streaming -    sdev->set_streaming(false); +    //finished      std::cout << std::endl << "Done!" << std::endl << std::endl;      return 0; diff --git a/host/include/uhd/props.hpp b/host/include/uhd/props.hpp index 41e0eff63..01746f853 100644 --- a/host/include/uhd/props.hpp +++ b/host/include/uhd/props.hpp @@ -76,8 +76,6 @@ namespace uhd{          MBOARD_PROP_TX_DBOARD,         //ro, wax::obj          MBOARD_PROP_TX_DBOARD_NAMES,   //ro, prop_names_t          MBOARD_PROP_CLOCK_CONFIG,      //rw, clock_config_t -        MBOARD_PROP_PPS_SOURCE_NAMES,  //ro, prop_names_t -        MBOARD_PROP_REF_SOURCE_NAMES,  //ro, prop_names_t          MBOARD_PROP_TIME_NOW,          //wo, time_spec_t          MBOARD_PROP_TIME_NEXT_PPS      //wo, time_spec_t      }; diff --git a/host/include/uhd/simple_device.hpp b/host/include/uhd/simple_device.hpp index 035757936..bbe0258c7 100644 --- a/host/include/uhd/simple_device.hpp +++ b/host/include/uhd/simple_device.hpp @@ -51,9 +51,7 @@ public:      /*******************************************************************       * Streaming       ******************************************************************/ -    virtual void set_streaming_at(const time_spec_t &time_spec) = 0; -    virtual void set_streaming(bool enb) = 0; -    virtual bool get_streaming(void) = 0; +    virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0;      /*******************************************************************       * RX methods diff --git a/host/include/uhd/time_spec.hpp b/host/include/uhd/time_spec.hpp index c1e7cf3a1..e863746ba 100644 --- a/host/include/uhd/time_spec.hpp +++ b/host/include/uhd/time_spec.hpp @@ -35,17 +35,11 @@ namespace uhd{          boost::uint32_t ticks;          /*! -         * Create a time_spec_t that holds a wildcard time. -         * This will have implementation-specific meaning. -         */ -        time_spec_t(void); - -        /*!           * Create a time_spec_t from seconds and ticks. -         * \param new_secs the new seconds +         * \param new_secs the new seconds (default = 0)           * \param new_ticks the new ticks (default = 0)           */ -        time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks = 0); +        time_spec_t(boost::uint32_t new_secs = 0, boost::uint32_t new_ticks = 0);          /*!           * Create a time_spec_t from boost posix time. diff --git a/host/include/uhd/types.hpp b/host/include/uhd/types.hpp index 1439f57a1..3ad3dae82 100644 --- a/host/include/uhd/types.hpp +++ b/host/include/uhd/types.hpp @@ -19,6 +19,7 @@  #define INCLUDED_UHD_TYPES_HPP  #include <uhd/config.hpp> +#include <uhd/time_spec.hpp>  #include <string>  namespace uhd{ @@ -66,18 +67,53 @@ namespace uhd{       * Clock configuration settings:       * The source for the 10MHz reference clock.       * The source and polarity for the PPS clock. -     * Possible settings for the reference and pps source -     * are implementation specific motherboard properties. -     * See the MBOARD_PROP_XXX_SOURCE_NAMES properties.       */ -    struct clock_config_t{ -        enum polarity_t {POLARITY_NEG, POLARITY_POS}; -        std::string ref_source; -        std::string pps_source; -        polarity_t  pps_polarity; +    struct UHD_API clock_config_t{ +        enum ref_source_t { +            REF_INT, //internal reference +            REF_SMA, //external sma port +            REF_MIMO //mimo cable (usrp2 only) +        } ref_source; +        enum pps_source_t { +            PPS_INT, //there is no internal +            PPS_SMA, //external sma port +            PPS_MIMO //mimo cable (usrp2 only) +        } pps_source; +        enum pps_polarity_t { +            PPS_NEG, //negative edge +            PPS_POS  //positive edge +        } pps_polarity;          clock_config_t(void);      }; +    /*! +     * Command struct for configuration and control of streaming: +     * +     * A stream command defines how the device sends samples to the host. +     * Streaming is controlled by submitting a stream command to the rx dsp. +     * Granular control over what the device streams to the host can be +     * achieved through submission of multiple (carefully-crafted) commands. +     * +     * The stream_now parameter controls when the stream begins. +     * When true, the device will begin streaming ASAP. When false, +     * the device will begin streaming at a time specified by time_spec. +     * +     * The continuous parameter controls the number of samples received. +     * When true, the device continues streaming indefinitely. When false, +     * the device will stream the number of samples specified by num_samps. +     * +     * Standard usage case: +     * To start continuous streaming, set stream_now to true and continuous to true. +     * To end continuous streaming, set stream_now to true and continuous to false. +     */ +    struct UHD_API stream_cmd_t{ +        bool stream_now; +        time_spec_t time_spec; +        bool continuous; +        size_t num_samps; +        stream_cmd_t(void); +    }; +  } //namespace uhd  #endif /* INCLUDED_UHD_TYPES_HPP */ diff --git a/host/lib/simple_device.cpp b/host/lib/simple_device.cpp index bb7ddfc68..a25cb12e0 100644 --- a/host/lib/simple_device.cpp +++ b/host/lib/simple_device.cpp @@ -167,17 +167,8 @@ public:      /*******************************************************************       * Streaming       ******************************************************************/ -    void set_streaming_at(const time_spec_t &time_spec){ -        _rx_ddc[std::string("stream_at")] = time_spec; -        _rx_ddc[std::string("enabled")] = true; -    } - -    void set_streaming(bool enb){ -        _rx_ddc[std::string("enabled")] = enb; -    } - -    bool get_streaming(void){ -        return _rx_ddc[std::string("enabled")].as<bool>(); +    void issue_stream_cmd(const stream_cmd_t &stream_cmd){ +        _rx_ddc[std::string("stream_cmd")] = stream_cmd;      }      /******************************************************************* diff --git a/host/lib/time_spec.cpp b/host/lib/time_spec.cpp index 210010394..98bf28077 100644 --- a/host/lib/time_spec.cpp +++ b/host/lib/time_spec.cpp @@ -19,11 +19,6 @@  using namespace uhd; -time_spec_t::time_spec_t(void){ -    secs = ~0; -    ticks = ~0; -} -  time_spec_t::time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks){      secs = new_secs;      ticks = new_ticks; diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 219ae8720..9436f2a13 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -115,7 +115,7 @@ smart_buffer::sptr udp_zero_copy_impl::recv(void){      //implement timeout through polling and sleeping      boost::asio::deadline_timer timer(_socket->get_io_service()); -    timer.expires_from_now(boost::posix_time::milliseconds(50)); +    timer.expires_from_now(boost::posix_time::milliseconds(100));      while (not ((available = _socket->available()) or timer.expires_from_now().is_negative())){          boost::this_thread::sleep(boost::posix_time::milliseconds(1));      } diff --git a/host/lib/types.cpp b/host/lib/types.cpp index f8a9a9b36..273f87a2d 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -51,7 +51,16 @@ tune_result_t::tune_result_t(void){   * clock config   **********************************************************************/  clock_config_t::clock_config_t(void){ -    ref_source = ""; //not a valid setting -    pps_source = ""; //not a valid setting -    pps_polarity = POLARITY_NEG; +    ref_source = REF_INT, +    pps_source = PPS_INT, +    pps_polarity = PPS_NEG; +} + +/*********************************************************************** + * stream command + **********************************************************************/ +stream_cmd_t::stream_cmd_t(void){ +    stream_now = true; +    continuous = false; +    num_samps = 0;  } diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 34cce0afb..44f654863 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -63,9 +63,8 @@ void usrp2_impl::init_ddc_config(void){      _ddc_freq = 0;      update_ddc_config(); -    _ddc_stream_at = time_spec_t(); -    _ddc_enabled = false; -    update_ddc_enabled(); +    //initial command that kills streaming (in case if was left on) +    //issue_ddc_stream_cmd(TODO)  }  void usrp2_impl::update_ddc_config(void){ @@ -86,21 +85,19 @@ void usrp2_impl::update_ddc_config(void){      ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE);  } -void usrp2_impl::update_ddc_enabled(void){ +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_CONFIGURE_STREAMING_FOR_ME_BRO); -    out_data.data.streaming.enabled = (_ddc_enabled)? 1 : 0; -    out_data.data.streaming.secs =  htonl(_ddc_stream_at.secs); -    out_data.data.streaming.ticks = htonl(_ddc_stream_at.ticks); -    out_data.data.streaming.samples = htonl(_max_rx_samples_per_packet); +    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.continuous = (stream_cmd.continuous)? 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.ticks); +    out_data.data.stream_cmd.num_samps = htonl(stream_cmd.num_samps);      //send and recv      usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); -    ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE); - -    //clear the stream at time spec (it must be set for the next round of enable/disable) -    _ddc_stream_at = time_spec_t(); +    ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE);  }  /*********************************************************************** @@ -120,8 +117,7 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){                      ("decim")                      ("decims")                      ("freq") -                    ("enabled") -                    ("stream_at") +                    ("stream_cmd")                  ;                  val = others;              } @@ -147,10 +143,6 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){          val = _ddc_freq;          return;      } -    else if (key_name == "enabled"){ -        val = _ddc_enabled; -        return; -    }      throw std::invalid_argument(str(          boost::format("error getting: unknown key with name %s") % key_name @@ -178,16 +170,8 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){          update_ddc_config();          return;      } -    else if (key_name == "enabled"){ -        bool new_enabled = val.as<bool>(); -        _ddc_enabled = new_enabled; //shadow -        update_ddc_enabled(); -        return; -    } -    else if (key_name == "stream_at"){ -        time_spec_t new_stream_at = val.as<time_spec_t>(); -        _ddc_stream_at = new_stream_at; //shadow -        //update_ddc_enabled(); //dont update from here +    else if (key_name == "stream_cmd"){ +        issue_ddc_stream_cmd(val.as<stream_cmd_t>());          return;      } diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 7fcae6fb2..30fee6c32 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -32,6 +32,9 @@ extern "C" {  #define _SINS_  #endif +//used to differentiate control packets over data port +#define USRP2_INVALID_VRT_HEADER 0 +  // size of the vrt header and trailer to the host  #define USRP2_HOST_RX_VRT_HEADER_WORDS32 5  #define USRP2_HOST_RX_VRT_TRAILER_WORDS32 1 //FIXME fpga sets wrong header size when no trailer present @@ -90,8 +93,8 @@ typedef enum{      USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO,      USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE, -    USRP2_CTRL_ID_CONFIGURE_STREAMING_FOR_ME_BRO, -    USRP2_CTRL_ID_CONFIGURED_THAT_STREAMING_DUDE, +    USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO, +    USRP2_CTRL_ID_GOT_THAT_STREAM_COMMAND_DUDE,      USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO,      USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE, @@ -186,12 +189,13 @@ typedef struct{              _SINS_ uint32_t scale_iq;          } ddc_args;          struct { -            _SINS_ uint8_t enabled; -            _SINS_ uint8_t _pad[3]; +            _SINS_ uint8_t now; //stream now? +            _SINS_ uint8_t continuous; //auto-reload commmands? +            _SINS_ uint8_t _pad[2];              _SINS_ uint32_t secs;              _SINS_ uint32_t ticks; -            _SINS_ uint32_t samples; -        } streaming; +            _SINS_ uint32_t num_samps; +        } stream_cmd;          struct {              _SINS_ uint32_t freq_word;              _SINS_ uint32_t interp; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index df0736863..280f124d2 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -41,8 +41,12 @@ 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 -    boost::uint32_t zero_data = 0; -    _data_transport->send(asio::buffer(&zero_data, sizeof(zero_data))); +    //and the maximum number of lines (32 bit words) per packet +    boost::uint32_t data[2] = { +        htonl(USRP2_INVALID_VRT_HEADER), +        htonl(_max_rx_samples_per_packet) +    }; +    _data_transport->send(asio::buffer(&data, sizeof(data)));  }  #define unrolled_loop(__inst, __len){ \ diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index cbca8eec7..c56782c4b 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -35,27 +35,10 @@ void usrp2_impl::mboard_init(void){  }  void usrp2_impl::init_clock_config(void){ -    //init the ref source clock config -    _ref_source_dict = boost::assign::map_list_of -        ("int", USRP2_REF_SOURCE_INT) -        ("sma", USRP2_REF_SOURCE_SMA) -        ("mimo", USRP2_REF_SOURCE_MIMO) -    ; -    _clock_config.ref_source = "int"; - -    //init the pps source clock config -    _pps_source_dict = boost::assign::map_list_of -        ("sma", USRP2_PPS_SOURCE_SMA) -        ("mimo", USRP2_PPS_SOURCE_MIMO) -    ; -    _clock_config.pps_source = "sma"; - -    //init the pps polarity clock config -    _pps_polarity_dict = boost::assign::map_list_of -        (clock_config_t::POLARITY_POS, USRP2_PPS_POLARITY_POS) -        (clock_config_t::POLARITY_NEG, USRP2_PPS_POLARITY_NEG) -    ; -    _clock_config.pps_polarity = clock_config_t::POLARITY_NEG; +    //setup the clock configuration settings +    _clock_config.ref_source = clock_config_t::REF_INT; +    _clock_config.pps_source = clock_config_t::PPS_SMA; +    _clock_config.pps_polarity = clock_config_t::PPS_NEG;      //update the clock config (sends a control packet)      update_clock_config(); @@ -65,9 +48,35 @@ void usrp2_impl::update_clock_config(void){      //setup the out data      usrp2_ctrl_data_t out_data;      out_data.id = htonl(USRP2_CTRL_ID_HERES_A_NEW_CLOCK_CONFIG_BRO); -    out_data.data.clock_config.ref_source   = _ref_source_dict  [_clock_config.ref_source]; -    out_data.data.clock_config.pps_source   = _pps_source_dict  [_clock_config.pps_source]; -    out_data.data.clock_config.pps_polarity = _pps_polarity_dict[_clock_config.pps_polarity]; + +    //translate ref source enums +    switch(_clock_config.ref_source){ +    case clock_config_t::REF_INT: +        out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_INT; break; +    case clock_config_t::REF_SMA: +        out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_SMA; break; +    case clock_config_t::REF_MIMO: +        out_data.data.clock_config.ref_source = USRP2_REF_SOURCE_MIMO; break; +    default: throw std::runtime_error("usrp2: unhandled clock configuration ref source"); +    } + +    //translate pps source enums +    switch(_clock_config.pps_source){ +    case clock_config_t::PPS_SMA: +        out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_SMA; break; +    case clock_config_t::PPS_MIMO: +        out_data.data.clock_config.pps_source = USRP2_PPS_SOURCE_MIMO; break; +    default: throw std::runtime_error("usrp2: unhandled clock configuration pps source"); +    } + +    //translate pps polarity enums +    switch(_clock_config.pps_polarity){ +    case clock_config_t::PPS_POS: +        out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_POS; break; +    case clock_config_t::PPS_NEG: +        out_data.data.clock_config.pps_source = USRP2_PPS_POLARITY_NEG; break; +    default: throw std::runtime_error("usrp2: unhandled clock configuration pps polarity"); +    }      //send and recv      usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); @@ -184,14 +193,6 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){          val = _clock_config;          return; -    case MBOARD_PROP_PPS_SOURCE_NAMES: -        val = prop_names_t(_pps_source_dict.get_keys()); -        return; - -    case MBOARD_PROP_REF_SOURCE_NAMES: -        val = prop_names_t(_ref_source_dict.get_keys()); -        return; -      case MBOARD_PROP_TIME_NOW:      case MBOARD_PROP_TIME_NEXT_PPS:          throw std::runtime_error("Error: trying to get write-only property on usrp2 mboard"); @@ -234,13 +235,9 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<mboard_prop_t>()){ -    case MBOARD_PROP_CLOCK_CONFIG:{ -            clock_config_t clock_config = val.as<clock_config_t>(); -            assert_has(_pps_source_dict.get_keys(), clock_config.pps_source, "usrp2 pps source"); -            assert_has(_ref_source_dict.get_keys(), clock_config.ref_source, "usrp2 ref source"); -            _clock_config = clock_config; //shadow -            update_clock_config(); -        } +    case MBOARD_PROP_CLOCK_CONFIG: +        _clock_config = val.as<clock_config_t>(); +        update_clock_config();          return;      case MBOARD_PROP_TIME_NOW:{ @@ -264,8 +261,6 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){      case MBOARD_PROP_RX_DBOARD_NAMES:      case MBOARD_PROP_TX_DBOARD:      case MBOARD_PROP_TX_DBOARD_NAMES: -    case MBOARD_PROP_PPS_SOURCE_NAMES: -    case MBOARD_PROP_REF_SOURCE_NAMES:          throw std::runtime_error("Error: trying to set read-only property on usrp2 mboard");      } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 55ac0b192..2794cc666 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -21,7 +21,6 @@  #include <uhd/usrp/usrp2.hpp>  #include <uhd/dict.hpp>  #include <uhd/types.hpp> -#include <uhd/time_spec.hpp>  #include <boost/thread.hpp>  #include <boost/shared_ptr.hpp>  #include <boost/function.hpp> @@ -146,11 +145,6 @@ private:      void update_clock_config(void);      void set_time_spec(const uhd::time_spec_t &time_spec, bool now); -    //mappings from clock config strings to over the wire enums -    uhd::dict<std::string, usrp2_ref_source_t> _ref_source_dict; -    uhd::dict<std::string, usrp2_pps_source_t> _pps_source_dict; -    uhd::dict<uhd::clock_config_t::polarity_t, usrp2_pps_polarity_t> _pps_polarity_dict; -      //rx and tx dboard methods and objects      uhd::usrp::dboard_manager::sptr _dboard_manager;      void dboard_init(void); @@ -178,11 +172,9 @@ private:      std::vector<size_t> _allowed_decim_and_interp_rates;      size_t _ddc_decim;      uhd::freq_t _ddc_freq; -    bool _ddc_enabled; -    uhd::time_spec_t _ddc_stream_at;      void init_ddc_config(void);      void update_ddc_config(void); -    void update_ddc_enabled(void); +    void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd);      //methods and shadows for the duc dsp      size_t _duc_interp; | 
