GNU Radio's SOAPY Package
source_impl.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * gr-soapy: Soapy SDR Radio Out-Of-Tree Module
4  *
5  * Copyright (C) 2018, 2019, 2020
6  * Libre Space Foundation <http://libre.space>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 /// \file source_impl.h
22 
23 #ifndef INCLUDED_SOAPY_SOURCE_IMPL_H
24 #define INCLUDED_SOAPY_SOURCE_IMPL_H
25 
26 #include <soapy/source.h>
27 #include <boost/bind.hpp>
28 #include <boost/thread/mutex.hpp>
29 
30 #include <SoapySDR/Version.hpp>
31 #include <SoapySDR/Modules.hpp>
32 #include <SoapySDR/Registry.hpp>
33 #include <SoapySDR/Device.hpp>
34 
35 typedef boost::function<void(pmt::pmt_t, size_t)> cmd_handler_t;
36 
37 namespace gr {
38 namespace soapy {
39 
40 /*!
41  * \brief Source block implementation for SDR devices.
42  */
43 
44 class source_impl : public source {
45 private:
46  const std::string d_dev_str;
47  const std::string d_args;
48 
49  SoapySDR::Device *d_device;
50  SoapySDR::Stream *d_stream;
51 
52  bool d_stopped;
53  size_t d_mtu;
54  size_t d_nchan;
55  std::map<pmt::pmt_t, cmd_handler_t> d_cmd_handlers;
56  std::vector<SoapySDR::Kwargs> d_tune_args;
57 
58  void register_msg_cmd_handler(const pmt::pmt_t &cmd, cmd_handler_t handler);
59 
60  inline io_signature::sptr
61  args_to_io_sig(const std::string type, size_t nchan)
62  {
63  size_t size = 0;
64  if (type == "fc32") {
65  size = 8;
66  }
67  else if (type == "sc16") {
68  size = 4;
69  }
70  else if (type == "sc8") {
71  size = 2;
72  }
73  else if (type == "s16") {
74  size = 2;
75  }
76  else if (type == "s8") {
77  size = 1;
78  }
79  return io_signature::make(nchan, nchan, size);
80  }
81 
82 public:
83  source_impl(size_t nchan, const std::string &device,
84  const std::string &dev_args,
85  const std::string &stream_args,
86  const std::vector<std::string> &tune_args,
87  const std::vector<std::string> &other_settings,
88  double sampling_rate,
89  const std::string &type);
90  ~source_impl();
91 
92  virtual bool start();
93  virtual bool stop();
94 
95  // Where all the action really happens
96  int work(int noutput_items,
97  gr_vector_const_void_star &input_items,
98  gr_vector_void_star &output_items);
99 
100  std::vector<std::string> get_antennas(int channel);
101 
102  /*!
103  * Set the center frequency for the specified RX chain.
104  * Default implementation tunes RF component frequency as close as
105  * possible to the requested frequency. See specific device module
106  * for more information.
107  * \param channel an available channel on the device
108  * \param frequency center frequency in Hz
109  */
110  void set_frequency(size_t channel, double frequency);
111 
112  /*!
113  * Set the center frequency for the specified RX chain of the element.
114  * Default implementation tunes RF component frequency as close as
115  * possible to the requested frequency. See specific device module
116  * for more information
117  * \param channel an available channel on the device
118  * \param name an available element name
119  * \param frequency center frequency in Hz
120  */
121  void set_frequency(size_t channel, const std::string &name, double frequency);
122 
123  /*!
124  * Set the overall gain for the specified RX chain.
125  * The gain will be distributed automatically across available
126  * elements according to Soapy API.
127  * \param channel an available channel on the device
128  * \param gain the new amplification value in dB
129  */
130  void set_gain(size_t channel, float gain);
131 
132  /*!
133  * Set the value for the specified gain for the specified TX chain.
134  * \param channel an available channel on the device
135  * \param name an available gain on the device
136  * \param gain gain the new amplification value in dB
137  */
138  void set_gain(size_t channel, const std::string name, float gain);
139 
140 
141  /**
142  * Checks if the specified gain type for the given channel is
143  * available
144  * @param channel an available channel on the device
145  * @param nane an available gain on the device
146  * @return true if the gain setting exists, false otherwise
147  */
148  bool gain_available(size_t channel, const std::string &name);
149 
150  /*!
151  * Set the automatic gain mode for the specified chain if supported.
152  * If not supported set gain value manually.
153  * \param channel an available channel on the device
154  * \param enable true for automatic gain mode
155  */
156  void set_agc(size_t channel, bool enable);
157 
158  /*!
159  * Set the baseband sample rate for the RX chain.
160  * \param channel an available channel on the device
161  * \param sample_rate the sample rate samples per second
162  */
163  void set_sample_rate(size_t channel, double sample_rate);
164 
165  /*!
166  * Set the baseband filter width of the RX chain
167  * \param channel an available channel on the device
168  * \param bandwidth the baseband filter width in Hz
169  */
170  void set_bandwidth(size_t channel, double bandwidth);
171 
172  /*!
173  * Set the antenna element for the RX chain.
174  * \param channel an available channel on the device
175  * \param name the name of an available antenna
176  */
177  void set_antenna(size_t channel, const std::string &name);
178 
179  /*!
180  * Set the dc offset correction for the RX chain.
181  * If the dc offset correction automatic mode is on
182  * the value is omitted and the device sets the dc offset
183  * correction automatically.
184  * \param channel an available channel on the device
185  * \param dc_offset the relative correction (1.0 max)
186  */
187  void set_dc_offset(size_t channel, gr_complexd dc_offset);
188 
189  /*!
190  * Set automatic DC removal to the RX chain
191  * if supported by the device.
192  * \param channel an available channel on the device
193  * \param automatic true for automatic DC offset correction
194  */
195  void set_dc_removal(size_t channel, bool automatic);
196 
197  /*!
198  * Set the frequency correction to the RX chain.
199  * @param channel an available channel on the device
200  * @param freq_correction the correction value in PPM
201  */
202  void set_frequency_correction(size_t channel, double freq_correction);
203 
204  /*!
205  * Set iq balance correction to the RX chain
206  * \param channel an available channel on the device
207  * \param iq_balance the relative correction (1.0 max)
208  */
209  void set_iq_balance(size_t channel, gr_complexd iq_balance);
210 
211  /*!
212  * Set the master clock rate of the device
213  * \param clock_rate the clock rate in Hz
214  */
215  void set_master_clock_rate(double clock_rate);
216 
217  /*!
218  * Set the clock source of the device
219  * \param clock_source the name of clock source
220  */
221  void set_clock_source(const std::string &clock_source);
222 
223  /*!
224  * Set the frontend mapping of available DSP units to RF frontends.
225  * This mapping controls channel mapping and channel availability.
226  * \param frontend_mapping a vendor-specific mapping string
227  */
228  void set_frontend_mapping(const std::string &frontend_mapping);
229 
230  /*!
231  * Get the down conversion frequency of the chain.
232  * \param channel an available channel on the device
233  * \return the center frequency in Hz
234  */
235  double get_frequency(size_t channel);
236 
237  /*!
238  * Get the overall value of the gain elements in a chain
239  * \param channel an available channel on the device
240  * \return the value of the gain in dB
241  */
242  double get_gain(size_t channel);
243 
244  /*!
245  * Get the automatic gain mode on the RX chain.
246  * \param channel an available channel on the device
247  * \return true for automatic gain setting
248  */
249  bool get_gain_mode(size_t channel);
250 
251  /*!
252  * Get the baseband sample rate of the RX chain.
253  * \param channel an available channel on the device
254  * \return the sample rate in samples per second
255  */
256  double get_sampling_rate(size_t channel);
257 
258  /*!
259  * Get baseband filter width of the RX chain.
260  * \param channel an available channel on the device
261  * \return the baseband filter width in Hz
262  */
263  double get_bandwidth(size_t channel);
264 
265  /*!
266  * Get the selected antenna on RX chain.
267  * \param channel an available channel on the device
268  * \return the name of the selected antenna
269  */
270  std::string get_antenna(size_t channel);
271 
272  /*!
273  * Get the DC offset correction.
274  * \param channel an available channel on the device
275  * \return the relative correction (1.0 max)
276  */
277  std::complex<double> get_dc_offset(size_t channel);
278 
279  /*!
280  * Get the automatic DC offset correction mode.
281  * \param channel an available channel on the device
282  * \return true for automatic offset correction
283  */
284  bool get_dc_offset_mode(size_t channel);
285 
286  /*!
287  * Get the frequency correction value.
288  * \param channel an available channel on the device
289  * \return the correction value in PPM
290  */
291  double get_frequency_correction(size_t channel);
292 
293  /*!
294  * Get the IQ balance correction.
295  * \param channel an available channel on the device
296  * \return the relative correction (1.0 max)
297  */
298  std::complex<double> get_iq_balance(size_t channel);
299 
300  /*!
301  * Get the master clock rate of the device.
302  * \return the clock rate in Hz
303  */
304  double get_master_clock_rate();
305 
306  /*!
307  * Get the clock source of the device
308  * \return the name of the clock source
309  */
310  std::string get_clock_source();
311 
312  /*!
313  * Calls the correct message handler according to the received message symbol.
314  * A dictionary with key the handler name is used in order to call the
315  * corresponding handler.
316  * \param msg a PMT dictionary
317  */
318  void msg_handler_command(pmt::pmt_t msg);
319 
320  /*!
321  * Set the center frequency of the RX chain.
322  * @param val center frequency in Hz
323  * @param chann an available channel on the device
324  */
325  void cmd_handler_frequency(pmt::pmt_t val, size_t chann);
326 
327  /*!
328  * Set the overall gain for the specified chain.
329  * The gain will be distributed automatically across available
330  * elements according to Soapy API.
331  * @param val the new amplification value in dB
332  * @param chann an avalaible channel on the device
333  */
334  void cmd_handler_gain(pmt::pmt_t val, size_t chann);
335 
336  /*!
337  * Set the baseband sample rate for the RX chain.
338  * @param val the sample rate samples per second
339  * @param chann an available channel on the device
340  */
341  void cmd_handler_samp_rate(pmt::pmt_t val, size_t chann);
342 
343  /*!
344  * Set the baseband filter width for the RX chain.
345  * @param val baseband filter width in Hz
346  * @param chann an available channel on the device
347  */
348  void cmd_handler_bw(pmt::pmt_t val, size_t chann);
349 
350  /*!
351  * Set the anntena element for the RX chain.
352  * @param val name of the anntena
353  * @param chann an available channel on the device
354  */
355  void cmd_handler_antenna(pmt::pmt_t val, size_t chann);
356 };
357 } // namespace soapy
358 } // namespace gr
359 
360 #endif /* INCLUDED_SOAPY_SOURCE_IMPL_H */
361 
void set_sample_rate(size_t channel, double sample_rate)
double get_sampling_rate(size_t channel)
void msg_handler_command(pmt::pmt_t msg)
virtual bool start()
void set_frequency_correction(size_t channel, double freq_correction)
void cmd_handler_bw(pmt::pmt_t val, size_t chann)
bool get_dc_offset_mode(size_t channel)
void cmd_handler_frequency(pmt::pmt_t val, size_t chann)
void set_dc_removal(size_t channel, bool automatic)
source_impl(size_t nchan, const std::string &device, const std::string &dev_args, const std::string &stream_args, const std::vector< std::string > &tune_args, const std::vector< std::string > &other_settings, double sampling_rate, const std::string &type)
void set_frequency(size_t channel, double frequency)
void cmd_handler_samp_rate(pmt::pmt_t val, size_t chann)
double get_frequency_correction(size_t channel)
std::string get_clock_source()
void cmd_handler_gain(pmt::pmt_t val, size_t chann)
void set_bandwidth(size_t channel, double bandwidth)
bool get_gain_mode(size_t channel)
virtual bool stop()
Definition: source.h:56
Source block implementation for SDR devices.
Definition: source_impl.h:44
double get_gain(size_t channel)
void set_frontend_mapping(const std::string &frontend_mapping)
bool gain_available(size_t channel, const std::string &name)
void set_antenna(size_t channel, const std::string &name)
void set_agc(size_t channel, bool enable)
void set_gain(size_t channel, float gain)
std::complex< double > get_iq_balance(size_t channel)
Definition: sink.h:29
std::vector< std::string > get_antennas(int channel)
double get_master_clock_rate()
int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
std::string get_antenna(size_t channel)
void set_iq_balance(size_t channel, gr_complexd iq_balance)
boost::function< void(pmt::pmt_t, size_t)> cmd_handler_t
Definition: sink_impl.h:34
double get_frequency(size_t channel)
void cmd_handler_antenna(pmt::pmt_t val, size_t chann)
void set_dc_offset(size_t channel, gr_complexd dc_offset)
void set_clock_source(const std::string &clock_source)
boost::function< void(pmt::pmt_t, size_t)> cmd_handler_t
Definition: source_impl.h:35
void set_master_clock_rate(double clock_rate)
std::complex< double > get_dc_offset(size_t channel)
double get_bandwidth(size_t channel)