GNU Radio 3.3.0 C++ API
|
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 */