1 /* -*- c++ -*- */ 2 /* 3 * Copyright 2013-2017 Nuand LLC 4 * Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net> 5 * 6 * GNU Radio is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3, or (at your option) 9 * any later version. 10 * 11 * GNU Radio is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with GNU Radio; see the file COPYING. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, 19 * Boston, MA 02110-1301, USA. 20 */ 21 #ifndef INCLUDED_BLADERF_COMMON_H 22 #define INCLUDED_BLADERF_COMMON_H 23 24 #include <list> 25 #include <map> 26 #include <memory> 27 #include <mutex> 28 #include <string> 29 #include <vector> 30 31 #include <libbladeRF.h> 32 33 #include "osmosdr/ranges.h" 34 #include "arg_helpers.h" 35 36 #include "bladerf_compat.h" 37 38 #ifdef _MSC_VER 39 #include <cstddef> 40 typedef ptrdiff_t ssize_t; 41 #endif //_MSC_VER 42 43 #define BLADERF_DEBUG_ENABLE 44 45 typedef std::shared_ptr<struct bladerf> bladerf_sptr; 46 47 /* Identification of the bladeRF hardware in use */ 48 typedef enum { 49 BOARD_TYPE_UNKNOWN, /**< Board type is unknown */ 50 BOARD_TYPE_NONE, /**< Uninitialized or no board present */ 51 BOARD_TYPE_BLADERF_1, /**< bladeRF 1 (LMS6002D-based, 1RX/1TX) */ 52 BOARD_TYPE_BLADERF_2, /**< bladeRF 2 (AD9361-based, 2RX/2TX) */ 53 } bladerf_board_type; 54 55 /* Mapping of bladerf_channel to bool */ 56 typedef std::map<bladerf_channel, bool> bladerf_channel_enable_map; 57 58 /* Mapping of bladerf_channel to gnuradio port/chan */ 59 typedef std::map<bladerf_channel, int> bladerf_channel_map; 60 61 /* Convenience macros for throwing a runtime error */ 62 #define BLADERF_THROW(message) \ 63 { \ 64 throw std::runtime_error(std::string(__FUNCTION__) + ": " + message); \ 65 } 66 67 #define BLADERF_THROW_STATUS(status, message) \ 68 { \ 69 BLADERF_THROW(boost::str(boost::format("%s: %s (%d)") % message \ 70 % bladerf_strerror(status) % status)); \ 71 } 72 73 /* Convenience macros for printing a warning message to stderr */ 74 #define BLADERF_WARNING(message) \ 75 { \ 76 std::cerr << _pfx << __FUNCTION__ << ": " << message << std::endl; \ 77 } 78 79 #define BLADERF_WARN_STATUS(status, message) \ 80 { \ 81 BLADERF_WARNING(message << ": " << bladerf_strerror(status)); \ 82 } \ 83 84 /* Convenience macro for printing an informational message to stdout */ 85 #define BLADERF_INFO(message) \ 86 { \ 87 std::cout << _pfx << __FUNCTION__ << ": " << message << std::endl; \ 88 } 89 90 /* Convenience macro for printing a debug message to stdout */ 91 #ifdef BLADERF_DEBUG_ENABLE 92 #define BLADERF_DEBUG(message) BLADERF_INFO("DEBUG: " << message) 93 #else 94 #define BLADERF_DEBUG(message) 95 #endif // BLADERF_DEBUG_ENABLE 96 97 /* Given a bladerf_channel_layout, calculate the number of streams */ 98 size_t num_streams(bladerf_channel_layout layout); 99 100 /** 101 * Common class for bladeRF interaction 102 */ 103 class bladerf_common 104 { 105 public: 106 /***************************************************************************** 107 * Public methods 108 ****************************************************************************/ 109 bladerf_common(); 110 111 protected: 112 /***************************************************************************** 113 * Protected methods 114 ****************************************************************************/ 115 116 /** 117 * Handle initialization and parameters common to both source & sink 118 * 119 * Specify arguments in key=value,key=value format, e.g. 120 * bladerf=0,buffers=512 121 * 122 * Recognized arguments: 123 * Key Allowed values 124 * --------------------------------------------------------------------------- 125 * REQUIRED: 126 * bladerf a valid instance or serial number 127 * USB INTERFACE CONTROL: 128 * buffers (default: NUM_BUFFERS) 129 * buflen (default: NUM_SAMPLES_PER_BUFFER) 130 * stream_timeout valid time in milliseconds (default: 3000) 131 * transfers (default: NUM_TRANSFERS) 132 * FPGA CONTROL: 133 * enable_metadata 1 to enable metadata 134 * fpga a path to a valid .rbf file 135 * fpga-reload 1 to force reloading the FPGA unconditionally 136 * RF CONTROL: 137 * agc 1 to enable, 0 to disable (default: hardware-dependent) 138 * agc_mode default, manual, fast, slow, hybrid (default: default) 139 * loopback bb_txlpf_rxvga2, bb_txlpf_rxlpf, bb_txvga1_rxvga2, 140 * bb_txvga1_rxlpf, rf_lna1, rf_lna2, rf_lna3, firmware, 141 * ad9361_bist, none (default: none) 142 * ** Note: valid on receive channels only 143 * rxmux baseband, 12bit, 32bit, digital (default: baseband) 144 * ** Note: valid on receive channels only 145 * smb a valid frequency 146 * tamer internal, external_1pps, external (default: internal) 147 * xb200 auto, auto3db, 50M, 144M, 222M, custom (default: auto) 148 * MISC: 149 * verbosity verbose, debug, info, warning, error, critical, silent 150 * (default: info) 151 * ** Note: applies only to libbladeRF logging 152 */ 153 void init(dict_t const &dict, bladerf_direction direction); 154 155 /* Get a vector of available devices */ 156 static std::vector<std::string> devices(); 157 /* Get the type of the open bladeRF board */ 158 bladerf_board_type get_board_type(); 159 /* Get the maximum number of channels supported in a given direction */ 160 size_t get_max_channels(bladerf_direction direction); 161 162 void set_channel_enable(bladerf_channel ch, bool enable); 163 bool get_channel_enable(bladerf_channel ch); 164 165 /* Set libbladeRF verbosity */ 166 void set_verbosity(std::string const &verbosity); 167 168 /* Convert an antenna/channel name (e.g. "RX2") to a bladerf_channel */ 169 bladerf_channel str2channel(std::string const &ch); 170 /* Convert a bladerf_channel to an antenna/channel name (e.g. "RX2") */ 171 std::string channel2str(bladerf_channel ch); 172 /* Convert a bladerf_channel to a hardware port identifier */ 173 int channel2rfport(bladerf_channel ch); 174 175 /* Using the channel map, get the bladerf_channel for a gnuradio chan */ 176 bladerf_channel chan2channel(bladerf_direction direction, size_t chan = 0); 177 178 /* Get range of supported sampling rates for channel ch */ 179 osmosdr::meta_range_t sample_rates(bladerf_channel ch); 180 /* Set sampling rate on channel ch to rate */ 181 double set_sample_rate(double rate, bladerf_channel ch); 182 /* Get the current sampling rate on channel ch */ 183 double get_sample_rate(bladerf_channel ch); 184 185 /* Get range of supported RF frequencies for channel ch */ 186 osmosdr::freq_range_t freq_range(bladerf_channel ch); 187 /* Set center RF frequency of channel ch to freq */ 188 double set_center_freq(double freq, bladerf_channel ch); 189 /* Get the center RF frequency of channel ch */ 190 double get_center_freq(bladerf_channel ch); 191 192 /* Get range of supported bandwidths for channel ch */ 193 osmosdr::freq_range_t filter_bandwidths(bladerf_channel ch); 194 /* Set the bandwidth on channel ch to bandwidth */ 195 double set_bandwidth(double bandwidth, bladerf_channel ch); 196 /* Get the current bandwidth of channel ch */ 197 double get_bandwidth(bladerf_channel ch); 198 199 /* Get the names of gain stages on channel ch */ 200 std::vector<std::string> get_gain_names(bladerf_channel ch); 201 /* Get range of supported overall gain values on channel ch */ 202 osmosdr::gain_range_t get_gain_range(bladerf_channel ch); 203 /* Get range of supported gain values for gain stage 'name' on channel ch */ 204 osmosdr::gain_range_t get_gain_range(std::string const &name, 205 bladerf_channel ch); 206 207 /* Enable or disable the automatic gain control on channel ch */ 208 bool set_gain_mode(bool automatic, bladerf_channel ch, 209 bladerf_gain_mode agc_mode = BLADERF_GAIN_DEFAULT); 210 /* Get the current automatic gain control status on channel ch */ 211 bool get_gain_mode(bladerf_channel ch); 212 213 /* Set the overall gain value on channel ch */ 214 double set_gain(double gain, bladerf_channel ch); 215 /* Set the gain of stage 'name' on channel ch */ 216 double set_gain(double gain, std::string const &name, bladerf_channel ch); 217 /* Get the overall gain value on channel ch */ 218 double get_gain(bladerf_channel ch); 219 /* Get the gain of stage 'name' on channel ch */ 220 double get_gain(std::string const &name, bladerf_channel ch); 221 222 /* Get the list of antennas supported by a channel */ 223 std::vector<std::string> get_antennas(bladerf_direction dir); 224 bool set_antenna(bladerf_direction dir, size_t chan, const std::string &antenna); 225 226 /* Set the DC offset on channel ch */ 227 int set_dc_offset(std::complex<double> const &offset, bladerf_channel ch); 228 /* Set the IQ balance on channel ch */ 229 int set_iq_balance(std::complex<double> const &balance, bladerf_channel ch); 230 231 /* Get the list of supported clock sources */ 232 std::vector<std::string> get_clock_sources(size_t mboard = 0); 233 /* Set the clock source to */ 234 void set_clock_source(std::string const &source, size_t mboard = 0); 235 /* Get the name of the current clock source */ 236 std::string get_clock_source(size_t mboard = 0); 237 238 /* Set the SMB frequency */ 239 void set_smb_frequency(double frequency); 240 /* Get the current SMB frequency */ 241 double get_smb_frequency(); 242 243 /***************************************************************************** 244 * Protected members 245 ****************************************************************************/ 246 bladerf_sptr _dev; /**< shared pointer for the active device */ 247 std::string _pfx; /**< prefix for console messages */ 248 unsigned int _failures; /**< counter for consecutive rx/tx failures */ 249 250 size_t _num_buffers; /**< number of buffers to allocate */ 251 size_t _samples_per_buffer; /**< how many samples per buffer */ 252 size_t _num_transfers; /**< number of active backend transfers */ 253 unsigned int _stream_timeout; /**< timeout for backend transfers */ 254 255 bladerf_format _format; /**< sample format to use */ 256 257 bladerf_channel_map _chanmap; /**< map of antennas to channels */ 258 bladerf_channel_enable_map _enables; /**< enabled channels */ 259 260 /***************************************************************************** 261 * Protected constants 262 ****************************************************************************/ 263 /* Maximum bladerf_sync_{rx,tx} failures to allow before giving up */ 264 static const unsigned int MAX_CONSECUTIVE_FAILURES = 3; 265 266 /* BladeRF IQ correction parameters */ 267 static const int16_t DCOFF_SCALE = 2048; 268 static const int16_t GAIN_SCALE = 4096; 269 static const int16_t PHASE_SCALE = 4096; 270 271 private: 272 /***************************************************************************** 273 * Private methods 274 ****************************************************************************/ 275 /* Open the bladeRF described by device_name. Returns a sptr if successful */ 276 bladerf_sptr open(const std::string &device_name); 277 /* Called by shared_ptr when a bladerf_sptr hits a refcount of 0 */ 278 static void close(void *dev); 279 /* If a device described by devinfo is open, this returns a sptr to it */ 280 static bladerf_sptr get_cached_device(struct bladerf_devinfo devinfo); 281 /* Prints a summary of device information */ 282 void print_device_info(); 283 284 bool is_antenna_valid(bladerf_direction dir, const std::string &antenna); 285 286 /***************************************************************************** 287 * Private members 288 ****************************************************************************/ 289 static std::mutex _devs_mutex; /**< mutex for access to _devs */ 290 static std::list<std::weak_ptr<struct bladerf>> _devs; /**< dev cache */ 291 }; 292 293 #endif 294