GNU Radio 3.4.2 C++ API
usrp2_impl.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2008,2009,2010 Free Software Foundation, Inc.
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation, either version 3 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
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   //! High-level d'board info
00043   struct db_info {
00044     int         dbid;
00045     double      freq_min;               // Hz
00046     double      freq_max;               // Hz
00047     double      gain_min;               // dB
00048     double      gain_max;               // dB
00049     double      gain_step_size;         // dB
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;       // FIXME: use u2_mac_addr_t instead
00064 
00065     boost::thread_group d_rx_tg;
00066     volatile bool  d_bg_running; // TODO: multistate if needed
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     // all pending_replies are stack allocated, thus no possibility of leaking these
00081     pending_reply *d_pending_replies[NRIDS]; // indexed by 8-bit reply id
00082 
00083     std::vector<ring_sptr>   d_channel_rings; // indexed by 5-bit channel number
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;         // shadow tx interp
00090     int            d_rx_decim;          // shadow 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; } // FIXME: convert from u2_mac_addr_t
00126     std::string interface_name() const { return d_interface_name; }
00127 
00128     // Rx
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     // Tx
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     // misc
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     // low level
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     // Receive thread, need to be public for boost::bind
00205     void bg_loop();
00206   };
00207 
00208 } // namespace usrp2
00209 
00210 #endif /* INCLUDED_USRP2_IMPL_H */