GNU Radio Manual and C++ API Reference  v3.9.2.0-89-gb7c7001e
The Free & Open Software Radio Ecosystem
block_impl.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2021 Jeff Long
4  * Copyright 2018-2021 Libre Space Foundation <http://libre.space>
5  *
6  * SPDX-License-Identifier: GPL-3.0-or-later
7  */
8 
9 #ifndef INCLUDED_GR_SOAPY_BLOCK_IMPL_H
10 #define INCLUDED_GR_SOAPY_BLOCK_IMPL_H
11 
12 #include <mutex>
13 
14 #include <gnuradio/soapy/block.h>
15 
16 #include <SoapySDR/Device.hpp>
17 #include <SoapySDR/Modules.hpp>
18 #include <SoapySDR/Registry.hpp>
19 #include <SoapySDR/Version.hpp>
20 
21 namespace gr {
22 namespace soapy {
23 
24 using cmd_handler_t = std::function<void(pmt::pmt_t, size_t)>;
26  void operator()(SoapySDR::Device* d) { SoapySDR::Device::unmake(d); }
27 };
28 using device_ptr_t = std::unique_ptr<SoapySDR::Device, device_deleter>;
29 
30 /*!
31  * \brief Base block implementation for SDR devices.
32  */
33 
34 class block_impl : virtual public block
35 {
36 private:
37  const int d_direction;
38  const std::string d_dev_str;
39  const std::string d_args;
40 
41  size_t d_mtu = 0;
42  size_t d_nchan;
43  std::string d_stream_args;
44  std::vector<size_t> d_channels;
45  std::string d_soapy_type;
46  std::map<pmt::pmt_t, cmd_handler_t> d_cmd_handlers;
47  kwargs_list_t d_tune_args;
48 
49  void register_msg_cmd_handler(const pmt::pmt_t& cmd, cmd_handler_t handler);
50 
51  /*!
52  * \brief Raise std::invalid_argument if channel is invalid
53  */
54  void validate_channel(size_t channel) const;
55 
56 protected:
57  block_impl(int direction,
58  const std::string& device,
59  const std::string& type,
60  size_t nchan,
61  const std::string& dev_args,
62  const std::string& stream_args,
63  const std::vector<std::string>& tune_args,
64  const std::vector<std::string>& other_settings);
65  block_impl(const block_impl&) = delete;
66  block_impl(block_impl&&) = delete;
67  block_impl& operator=(const block_impl&) = delete;
69  virtual ~block_impl();
70 
73  SoapySDR::Stream* d_stream = nullptr;
74 
75  static io_signature::sptr args_to_io_sig(const std::string& type, size_t nchan)
76  {
77  size_t size = 0;
78  if (type == "fc32") {
79  size = 8;
80  } else if (type == "sc16") {
81  size = 4;
82  } else if (type == "sc8") {
83  size = 2;
84  } else {
85  size = 1; /* TODO: this is an error */
86  }
87  return io_signature::make(nchan, nchan, size);
88  }
89 
90 public:
91  bool start() override;
92  bool stop() override;
93 
94  /*** Begin public API implementation ***/
95 
96  std::string get_driver_key() const override;
97  std::string get_hardware_key() const override;
98  kwargs_t get_hardware_info() const override;
99 
100  void set_frontend_mapping(const std::string& frontend_mapping) override;
101  std::string get_frontend_mapping() const override;
102 
103  kwargs_t get_channel_info(size_t channel) const override;
104 
105  void set_sample_rate(size_t channel, double sample_rate) override;
106  double get_sample_rate(size_t channel) const override;
107  range_list_t get_sample_rate_range(size_t channel) const override;
108 
109  void set_frequency(size_t channel, double frequency) override;
110  void
111  set_frequency(size_t channel, const std::string& name, double frequency) override;
112  double get_frequency(size_t channel) const override;
113  double get_frequency(size_t channel, const std::string& name) const override;
114  std::vector<std::string> list_frequencies(size_t channel) const override;
115  range_list_t get_frequency_range(size_t channel) const override;
117  const std::string& name) const override;
118  arginfo_list_t get_frequency_args_info(size_t channel) const override;
119 
120  void set_bandwidth(size_t channel, double bandwidth) override;
121  double get_bandwidth(size_t channel) const override;
122  range_list_t get_bandwidth_range(size_t channel) const override;
123 
124  std::vector<std::string> list_antennas(int channel) const override;
125  void set_antenna(size_t channel, const std::string& name) override;
126  std::string get_antenna(size_t channel) const override;
127 
128  bool has_gain_mode(size_t channel) const override;
129  void set_gain_mode(size_t channel, bool enable) override;
130  bool get_gain_mode(size_t channel) const override;
131 
132  std::vector<std::string> list_gains(size_t channel) const override;
133  void set_gain(size_t channel, double gain) override;
134  void set_gain(size_t channel, const std::string& name, double gain) override;
135  double get_gain(size_t channel) const override;
136  double get_gain(size_t channel, const std::string& name) const override;
137  range_t get_gain_range(size_t channel) const override;
138  range_t get_gain_range(size_t channel, const std::string& name) const override;
139 
140  bool has_frequency_correction(size_t channel) const override;
141  void set_frequency_correction(size_t channel, double freq_correction) override;
142  double get_frequency_correction(size_t channel) const override;
143 
144  bool has_dc_offset_mode(size_t channel) const override;
145  void set_dc_offset_mode(size_t channel, bool automatic) override;
146  bool get_dc_offset_mode(size_t channel) const override;
147 
148  bool has_dc_offset(size_t channel) const override;
149  void set_dc_offset(size_t channel, const gr_complexd& dc_offset) override;
150  gr_complexd get_dc_offset(size_t channel) const override;
151 
152  bool has_iq_balance(size_t channel) const override;
153  void set_iq_balance(size_t channel, const gr_complexd& iq_balance) override;
154  gr_complexd get_iq_balance(size_t channel) const override;
155 
156  bool has_iq_balance_mode(size_t channel) const override;
157  void set_iq_balance_mode(size_t channel, bool automatic) override;
158  bool get_iq_balance_mode(size_t channel) const override;
159 
160  void set_master_clock_rate(double clock_rate) override;
161  double get_master_clock_rate() const override;
163 
164  void set_reference_clock_rate(double rate) override;
165  double get_reference_clock_rate() const override;
167 
168  std::vector<std::string> list_clock_sources() const override;
169  void set_clock_source(const std::string& clock_source) override;
170  std::string get_clock_source() const override;
171 
172  std::vector<std::string> list_time_sources() const override;
173  void set_time_source(const std::string& source) override;
174  std::string get_time_source() const override;
175  bool has_hardware_time(const std::string& what) const override;
176  long long get_hardware_time(const std::string& what) const override;
177  void set_hardware_time(long long timeNs, const std::string& what) override;
178 
179  std::vector<std::string> list_sensors() const override;
180  arginfo_t get_sensor_info(const std::string& key) const override;
181  std::string read_sensor(const std::string& key) const override;
182  std::vector<std::string> list_sensors(size_t channel) const override;
183  arginfo_t get_sensor_info(size_t channel, const std::string& key) const override;
184  std::string read_sensor(size_t channel, const std::string& key) const override;
185 
186  std::vector<std::string> list_register_interfaces() const override;
187  void write_register(const std::string& name, unsigned addr, unsigned value) override;
188  unsigned read_register(const std::string& name, unsigned addr) const override;
189  void write_registers(const std::string& name,
190  unsigned addr,
191  const std::vector<unsigned>& value) override;
192  std::vector<unsigned>
193  read_registers(const std::string& name, unsigned addr, size_t length) const override;
194 
195  virtual arginfo_list_t get_setting_info() const override;
196  virtual void write_setting(const std::string& key, const std::string& value) override;
197  virtual std::string read_setting(const std::string& key) const override;
198  virtual arginfo_list_t get_setting_info(size_t channel) const override;
199  virtual void write_setting(size_t channel,
200  const std::string& key,
201  const std::string& value) override;
202  virtual std::string read_setting(size_t channel,
203  const std::string& key) const override;
204 
205  std::vector<std::string> list_gpio_banks() const override;
206  void write_gpio(const std::string& bank, unsigned value) override;
207  void write_gpio(const std::string& bank, unsigned value, unsigned mask) override;
208  unsigned read_gpio(const std::string& bank) const override;
209  void write_gpio_dir(const std::string& bank, unsigned dir) override;
210  void write_gpio_dir(const std::string& bank, unsigned dir, unsigned mask) override;
211  unsigned read_gpio_dir(const std::string& bank) const override;
212 
213  void write_i2c(int addr, const std::string& data) override;
214  std::string read_i2c(int addr, size_t num_bytes) override;
215 
216  unsigned transact_spi(int addr, unsigned data, size_t num_bits) override;
217 
218  std::vector<std::string> list_uarts() const override;
219  void write_uart(const std::string& which, const std::string& data) override;
220  std::string read_uart(const std::string& which, long timeout_us) const override;
221 
222  /*** End public API implementation ***/
223 
224 protected:
225  /*** Begin message handlers ***/
226 
227  /*!
228  * Calls the correct message handler according to the received message symbol.
229  * A dictionary with key the handler name is used in order to call the
230  * corresponding handler.
231  * \param msg a PMT dictionary
232  */
234 
235  /*!
236  * Set the center frequency of the RX chain.
237  * @param val center frequency in Hz
238  * @param channel an available channel on the device
239  */
240  void cmd_handler_frequency(pmt::pmt_t val, size_t channel);
241 
242  /*!
243  * Set the overall gain for the specified chain.
244  * The gain will be distributed automatically across available
245  * elements according to Soapy API.
246  * @param val the new amplification value in dB
247  * @param channel an avalaible channel on the device
248  */
249  void cmd_handler_gain(pmt::pmt_t val, size_t channel);
250 
251  /*!
252  * Set the baseband sample rate for the RX chain.
253  * @param val the sample rate samples per second
254  * @param channel an available channel on the device
255  */
256  void cmd_handler_samp_rate(pmt::pmt_t val, size_t channel);
257 
258  /*!
259  * Set the baseband filter width for the RX chain.
260  * @param val baseband filter width in Hz
261  * @param channel an available channel on the device
262  */
263  void cmd_handler_bw(pmt::pmt_t val, size_t channel);
264 
265  /*!
266  * Set the anntena element for the RX chain.
267  * @param val name of the anntena
268  * @param channel an available channel on the device
269  */
270  void cmd_handler_antenna(pmt::pmt_t val, size_t channel);
271 
272  void cmd_handler_gain_mode(pmt::pmt_t val, size_t channel);
273  void cmd_handler_frequency_correction(pmt::pmt_t val, size_t channel);
274  void cmd_handler_dc_offset_mode(pmt::pmt_t val, size_t channel);
275  void cmd_handler_dc_offset(pmt::pmt_t val, size_t channel);
276  void cmd_handler_iq_balance(pmt::pmt_t val, size_t channel);
277  void cmd_handler_iq_balance_mode(pmt::pmt_t val, size_t channel);
283  void cmd_handler_register(pmt::pmt_t val, size_t);
285  void cmd_handler_setting(pmt::pmt_t val, size_t channel);
286  void cmd_handler_gpio(pmt::pmt_t val, size_t);
287  void cmd_handler_gpio_dir(pmt::pmt_t val, size_t);
288  void cmd_handler_i2c(pmt::pmt_t val, size_t);
289  void cmd_handler_uart(pmt::pmt_t val, size_t);
290 
291  /*** End message handlers ***/
292 };
293 
294 } // namespace soapy
295 } // namespace gr
296 
297 #endif /* INCLUDED_GR_SOAPY_BLOCK_IMPL_H */
std::string name() const
Definition: basic_block.h:137
std::shared_ptr< io_signature > sptr
Definition: io_signature.h:34
Base block implementation for SDR devices.
Definition: block_impl.h:35
void cmd_handler_antenna(pmt::pmt_t val, size_t channel)
block_impl(block_impl &&)=delete
std::vector< std::string > list_sensors(size_t channel) const override
std::string get_hardware_key() const override
void write_gpio(const std::string &bank, unsigned value, unsigned mask) override
void cmd_handler_i2c(pmt::pmt_t val, size_t)
double get_gain(size_t channel, const std::string &name) const override
std::vector< std::string > list_sensors() const override
long long get_hardware_time(const std::string &what) const override
std::string get_antenna(size_t channel) const override
bool stop() override
Called to disable drivers, etc for i/o devices.
void write_gpio_dir(const std::string &bank, unsigned dir) override
virtual arginfo_list_t get_setting_info(size_t channel) const override
void cmd_handler_samp_rate(pmt::pmt_t val, size_t channel)
device_ptr_t d_device
Definition: block_impl.h:72
double get_frequency(size_t channel, const std::string &name) const override
void cmd_handler_iq_balance(pmt::pmt_t val, size_t channel)
std::string get_frontend_mapping() const override
std::string read_sensor(size_t channel, const std::string &key) const override
void set_gain_mode(size_t channel, bool enable) override
double get_sample_rate(size_t channel) const override
std::string read_i2c(int addr, size_t num_bytes) override
bool has_frequency_correction(size_t channel) const override
bool has_dc_offset_mode(size_t channel) const override
std::vector< std::string > list_gpio_banks() const override
void cmd_handler_gpio(pmt::pmt_t val, size_t)
arginfo_t get_sensor_info(const std::string &key) const override
void cmd_handler_gain(pmt::pmt_t val, size_t channel)
bool has_gain_mode(size_t channel) const override
virtual std::string read_setting(const std::string &key) const override
std::vector< std::string > list_time_sources() const override
void cmd_handler_registers(pmt::pmt_t val, size_t)
bool has_iq_balance_mode(size_t channel) const override
void cmd_handler_gain_mode(pmt::pmt_t val, size_t channel)
void cmd_handler_gpio_dir(pmt::pmt_t val, size_t)
void msg_handler_cmd(pmt::pmt_t msg)
void cmd_handler_hardware_time(pmt::pmt_t val, size_t)
void set_iq_balance(size_t channel, const gr_complexd &iq_balance) override
void cmd_handler_setting(pmt::pmt_t val, size_t channel)
virtual void write_setting(size_t channel, const std::string &key, const std::string &value) override
void cmd_handler_reference_clock_rate(pmt::pmt_t val, size_t)
void set_iq_balance_mode(size_t channel, bool automatic) override
void set_dc_offset_mode(size_t channel, bool automatic) override
void write_gpio(const std::string &bank, unsigned value) override
SoapySDR::Stream * d_stream
Definition: block_impl.h:73
double get_gain(size_t channel) const override
void cmd_handler_bw(pmt::pmt_t val, size_t channel)
range_list_t get_bandwidth_range(size_t channel) const override
unsigned transact_spi(int addr, unsigned data, size_t num_bits) override
std::string read_uart(const std::string &which, long timeout_us) const override
bool get_gain_mode(size_t channel) const override
block_impl(const block_impl &)=delete
gr_complexd get_iq_balance(size_t channel) const override
void cmd_handler_frequency(pmt::pmt_t val, size_t channel)
std::vector< unsigned > read_registers(const std::string &name, unsigned addr, size_t length) const override
unsigned read_gpio(const std::string &bank) const override
double get_frequency_correction(size_t channel) const override
range_t get_gain_range(size_t channel) const override
double get_frequency(size_t channel) const override
void set_time_source(const std::string &source) override
bool start() override
Called to enable drivers, etc for i/o devices.
bool get_dc_offset_mode(size_t channel) const override
range_list_t get_sample_rate_range(size_t channel) const override
bool has_dc_offset(size_t channel) const override
void write_registers(const std::string &name, unsigned addr, const std::vector< unsigned > &value) override
range_list_t get_reference_clock_rates() const override
std::vector< std::string > list_clock_sources() const override
block_impl(int direction, const std::string &device, const std::string &type, size_t nchan, const std::string &dev_args, const std::string &stream_args, const std::vector< std::string > &tune_args, const std::vector< std::string > &other_settings)
std::vector< std::string > list_frequencies(size_t channel) const override
void cmd_handler_iq_balance_mode(pmt::pmt_t val, size_t channel)
std::vector< std::string > list_register_interfaces() const override
range_list_t get_frequency_range(size_t channel) const override
block_impl & operator=(block_impl &&)=delete
arginfo_t get_sensor_info(size_t channel, const std::string &key) const override
void write_gpio_dir(const std::string &bank, unsigned dir, unsigned mask) override
unsigned read_gpio_dir(const std::string &bank) const override
void cmd_handler_dc_offset_mode(pmt::pmt_t val, size_t channel)
range_list_t get_frequency_range(size_t channel, const std::string &name) const override
void set_antenna(size_t channel, const std::string &name) override
void set_gain(size_t channel, double gain) override
std::string get_driver_key() const override
void set_frequency(size_t channel, double frequency) override
arginfo_list_t get_frequency_args_info(size_t channel) const override
range_list_t get_master_clock_rates() const override
void set_frequency_correction(size_t channel, double freq_correction) override
void cmd_handler_time_source(pmt::pmt_t val, size_t)
static io_signature::sptr args_to_io_sig(const std::string &type, size_t nchan)
Definition: block_impl.h:75
std::string read_sensor(const std::string &key) const override
void set_frequency(size_t channel, const std::string &name, double frequency) override
void set_gain(size_t channel, const std::string &name, double gain) override
virtual std::string read_setting(size_t channel, const std::string &key) const override
void set_bandwidth(size_t channel, double bandwidth) override
bool has_hardware_time(const std::string &what) const override
void set_reference_clock_rate(double rate) override
block_impl & operator=(const block_impl &)=delete
double get_reference_clock_rate() const override
std::string get_clock_source() const override
std::mutex d_device_mutex
Definition: block_impl.h:71
std::vector< std::string > list_gains(size_t channel) const override
std::vector< std::string > list_uarts() const override
gr_complexd get_dc_offset(size_t channel) const override
std::string get_time_source() const override
double get_bandwidth(size_t channel) const override
void cmd_handler_dc_offset(pmt::pmt_t val, size_t channel)
void write_uart(const std::string &which, const std::string &data) override
std::vector< std::string > list_antennas(int channel) const override
void cmd_handler_clock_source(pmt::pmt_t val, size_t)
double get_master_clock_rate() const override
void cmd_handler_uart(pmt::pmt_t val, size_t)
unsigned read_register(const std::string &name, unsigned addr) const override
bool has_iq_balance(size_t channel) const override
void cmd_handler_register(pmt::pmt_t val, size_t)
void set_master_clock_rate(double clock_rate) override
void set_hardware_time(long long timeNs, const std::string &what) override
void write_register(const std::string &name, unsigned addr, unsigned value) override
bool get_iq_balance_mode(size_t channel) const override
kwargs_t get_hardware_info() const override
void cmd_handler_master_clock_rate(pmt::pmt_t val, size_t)
void cmd_handler_frequency_correction(pmt::pmt_t val, size_t channel)
void write_i2c(int addr, const std::string &data) override
kwargs_t get_channel_info(size_t channel) const override
virtual arginfo_list_t get_setting_info() const override
void set_clock_source(const std::string &clock_source) override
range_t get_gain_range(size_t channel, const std::string &name) const override
void set_sample_rate(size_t channel, double sample_rate) override
void set_dc_offset(size_t channel, const gr_complexd &dc_offset) override
void set_frontend_mapping(const std::string &frontend_mapping) override
virtual void write_setting(const std::string &key, const std::string &value) override
Definition: gr-soapy/include/gnuradio/soapy/block.h:23
Definition: gr-soapy/include/gnuradio/soapy/source.h:41
std::complex< double > gr_complexd
Definition: gr_complex.h:16
static sptr make(int min_streams, int max_streams, int sizeof_stream_item)
Create an i/o signature.
std::unique_ptr< SoapySDR::Device, device_deleter > device_ptr_t
Definition: block_impl.h:28
SoapySDR::KwargsList kwargs_list_t
Definition: soapy_types.h:26
SoapySDR::RangeList range_list_t
Definition: soapy_types.h:29
SoapySDR::ArgInfoList arginfo_list_t
Definition: soapy_types.h:21
SoapySDR::Kwargs kwargs_t
Definition: soapy_types.h:25
SoapySDR::ArgInfo arginfo_t
Definition: soapy_types.h:20
SoapySDR::Range range_t
Definition: soapy_types.h:28
std::function< void(pmt::pmt_t, size_t)> cmd_handler_t
Definition: block_impl.h:24
boost::mutex mutex
Definition: thread.h:37
GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
Definition: basic_block.h:29
PMT_API size_t length(const pmt_t &v)
Return the number of elements in v.
std::shared_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting).
Definition: pmt.h:84
Definition: block_impl.h:25
void operator()(SoapySDR::Device *d)
Definition: block_impl.h:26