00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef INCLUDED_USRP2_IMPL_H
00020 #define INCLUDED_USRP2_IMPL_H
00021
00022 #include <usrp2/usrp2.h>
00023 #include <usrp2/data_handler.h>
00024 #include <usrp2_eth_packet.h>
00025 #include <gruel/thread.h>
00026 #include <boost/scoped_ptr.hpp>
00027 #include "control.h"
00028 #include "ring.h"
00029 #include <string>
00030
00031 #define MAX_SUBPKT_LEN 252
00032
00033 namespace usrp2 {
00034
00035 class eth_buffer;
00036 class pktfilter;
00037 class usrp2_thread;
00038 class usrp2_tune_result;
00039 class pending_reply;
00040 class ring;
00041
00042
00043 struct db_info {
00044 int dbid;
00045 double freq_min;
00046 double freq_max;
00047 double gain_min;
00048 double gain_max;
00049 double gain_step_size;
00050
00051 db_info() : dbid(-1), freq_min(0), freq_max(0),
00052 gain_min(0), gain_max(0), gain_step_size(0) {}
00053 };
00054
00055 class usrp2::impl : private data_handler
00056 {
00057 static const size_t NRIDS = 256;
00058 static const size_t NCHANS = 32;
00059
00060 eth_buffer *d_eth_buf;
00061 std::string d_interface_name;
00062 pktfilter *d_pf;
00063 std::string d_addr;
00064
00065 boost::thread_group d_rx_tg;
00066 volatile bool d_bg_running;
00067
00068 int d_rx_seqno;
00069 int d_tx_seqno;
00070 int d_next_rid;
00071 unsigned int d_num_rx_frames;
00072 unsigned int d_num_rx_missing;
00073 unsigned int d_num_rx_overruns;
00074 unsigned int d_num_rx_bytes;
00075
00076 unsigned int d_num_enqueued;
00077 gruel::mutex d_enqueued_mutex;
00078 gruel::condition_variable d_bg_pending_cond;
00079
00080
00081 pending_reply *d_pending_replies[NRIDS];
00082
00083 std::vector<ring_sptr> d_channel_rings;
00084 gruel::mutex d_channel_rings_mutex;
00085
00086 db_info d_tx_db_info;
00087 db_info d_rx_db_info;
00088
00089 int d_tx_interp;
00090 int d_rx_decim;
00091
00092 bool d_dont_enqueue;
00093
00094 void inc_enqueued() {
00095 gruel::scoped_lock l(d_enqueued_mutex);
00096 d_num_enqueued++;
00097 }
00098
00099 void dec_enqueued() {
00100 gruel::scoped_lock l(d_enqueued_mutex);
00101 if (--d_num_enqueued == 0)
00102 d_bg_pending_cond.notify_one();
00103 }
00104
00105 static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
00106 void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst);
00107 void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
00108 int word0_flags, int chan, uint32_t timestamp);
00109 void start_bg();
00110 void stop_bg();
00111 void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd);
00112 void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
00113 bool transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs=0.0);
00114 bool transmit_cmd(void *cmd, size_t len);
00115 virtual data_handler::result operator()(const void *base, size_t len);
00116 data_handler::result handle_control_packet(const void *base, size_t len);
00117 data_handler::result handle_data_packet(const void *base, size_t len);
00118 bool dboard_info();
00119 bool reset_db();
00120
00121 public:
00122 impl(const std::string &ifc, props *p, size_t rx_bufsize);
00123 ~impl();
00124
00125 std::string mac_addr() const { return d_addr; }
00126 std::string interface_name() const { return d_interface_name; }
00127
00128
00129
00130 bool set_rx_antenna(int ant);
00131 bool set_rx_gain(double gain);
00132 double rx_gain_min() { return d_rx_db_info.gain_min; }
00133 double rx_gain_max() { return d_rx_db_info.gain_max; }
00134 double rx_gain_db_per_step() { return d_rx_db_info.gain_step_size; }
00135 bool set_rx_lo_offset(double frequency);
00136 bool set_rx_center_freq(double frequency, tune_result *result);
00137 double rx_freq_min() { return d_rx_db_info.freq_min; }
00138 double rx_freq_max() { return d_rx_db_info.freq_max; }
00139 bool set_rx_decim(int decimation_factor);
00140 int rx_decim() { return d_rx_decim; }
00141 bool set_rx_scale_iq(int scale_i, int scale_q);
00142 bool set_gpio_ddr(int bank, uint16_t value, uint16_t mask);
00143 bool set_gpio_sels(int bank, std::string src);
00144 bool enable_gpio_streaming(int bank, int enable);
00145 bool write_gpio(int bank, uint16_t value, uint16_t mask);
00146 bool read_gpio(int bank, uint16_t *value);
00147 bool start_rx_streaming(unsigned int channel, unsigned int items_per_frame);
00148 bool start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
00149 bool sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
00150 bool rx_samples(unsigned int channel, rx_sample_handler *handler);
00151 bool flush_rx_samples(unsigned int channel);
00152 bool stop_rx_streaming(unsigned int channel);
00153 unsigned int rx_overruns() const { return d_num_rx_overruns; }
00154 unsigned int rx_missing() const { return d_num_rx_missing; }
00155
00156
00157
00158 bool set_tx_antenna(int ant);
00159 bool set_tx_gain(double gain);
00160 double tx_gain_min() { return d_tx_db_info.gain_min; }
00161 double tx_gain_max() { return d_tx_db_info.gain_max; }
00162 double tx_gain_db_per_step() { return d_tx_db_info.gain_step_size; }
00163 bool set_tx_lo_offset(double frequency);
00164 bool set_tx_center_freq(double frequency, tune_result *result);
00165 double tx_freq_min() { return d_tx_db_info.freq_min; }
00166 double tx_freq_max() { return d_tx_db_info.freq_max; }
00167 bool set_tx_interp(int interpolation_factor);
00168 int tx_interp() { return d_tx_interp; }
00169 void default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q);
00170 bool set_tx_scale_iq(int scale_i, int scale_q);
00171
00172 bool tx_32fc(unsigned int channel,
00173 const std::complex<float> *samples,
00174 size_t nsamples,
00175 const tx_metadata *metadata);
00176
00177 bool tx_16sc(unsigned int channel,
00178 const std::complex<int16_t> *samples,
00179 size_t nsamples,
00180 const tx_metadata *metadata);
00181
00182 bool tx_raw(unsigned int channel,
00183 const uint32_t *items,
00184 size_t nitems,
00185 const tx_metadata *metadata);
00186
00187
00188
00189 bool config_mimo(int flags);
00190 bool fpga_master_clock_freq(long *freq);
00191 bool adc_rate(long *rate);
00192 bool dac_rate(long *rate);
00193 bool tx_daughterboard_id(int *dbid);
00194 bool rx_daughterboard_id(int *dbid);
00195
00196
00197
00198 bool burn_mac_addr(const std::string &new_addr);
00199 bool sync_to_pps();
00200 bool sync_every_pps(bool enable);
00201 std::vector<uint32_t> peek32(uint32_t addr, uint32_t words);
00202 bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
00203
00204
00205 void bg_loop();
00206 };
00207
00208 }
00209
00210 #endif