GNU Radio's SOAPY Package
sink_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
6  * Libre Space Foundation <http://librespacefoundation.org/>
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 
22 #ifndef INCLUDED_SOAPY_SINK_IMPL_H
23 #define INCLUDED_SOAPY_SINK_IMPL_H
24 
25 #include <soapy/sink.h>
26 #include <boost/bind.hpp>
27 #include <boost/thread/mutex.hpp>
28 
29 #include <SoapySDR/Version.hpp>
30 #include <SoapySDR/Modules.hpp>
31 #include <SoapySDR/Registry.hpp>
32 #include <SoapySDR/Device.hpp>
33 
34 typedef boost::function<void(pmt::pmt_t, size_t)> cmd_handler_t;
35 
36 namespace gr {
37 namespace soapy {
38 
39 /*!
40  * \brief Sink block implementation for SDR devices.
41  */
42 
43 class sink_impl : public sink {
44 private:
45  SoapySDR::Device *d_device;
46  SoapySDR::Stream *d_stream;
47 
48  bool d_stopped;
49  pmt::pmt_t d_message_port;
50 
51  double d_frequency;
52  float d_gain;
53  double d_sampling_rate;
54  double d_bandwidth;
55  std::string d_antenna;
56  size_t d_nchan;
57  gr_complex d_dc_offset;
58  bool d_dc_offset_auto_mode;
59  bool d_gain_auto_mode;
60  double d_frequency_correction;
61  gr_complex d_iq_balance;
62  double d_clock_rate;
63  std::string d_clock_source;
64  std::string d_frontend_mapping;
65  std::string d_type;
66  uint8_t d_type_size;
67 
68  const pmt::pmt_t d_length_tag_key;
69  long d_burst_remaining;
70 
71  virtual bool is_gain_valid(size_t channel, std::string gainType);
72 
73  void register_msg_cmd_handler(const pmt::pmt_t &cmd, cmd_handler_t handler);
74  std::map<pmt::pmt_t, cmd_handler_t> d_cmd_handlers;
75 
76  inline io_signature::sptr
77  args_to_io_sig(const std::string type, size_t nchan)
78  {
79  size_t size = 0;
80  if (type == "fc32") {
81  size = 8;
82  }
83  if (type == "s16") {
84  size = 2;
85  }
86  return io_signature::make(nchan, nchan, size);
87  }
88 
89  void tag_work(int noutput_items);
90 
91 public:
92  sink_impl(size_t nchan, const std::string &device,
93  const std::string &args, double sampling_rate,
94  const std::string &type,
95  const std::string &length_tag_name);
96  ~sink_impl();
97 
98  virtual bool start();
99  virtual bool stop();
100 
101  // Where all the action really happens
102  int work(int noutput_items,
103  gr_vector_const_void_star &input_items,
104  gr_vector_void_star &output_items);
105 
106  virtual std::vector<std::string> listAntennas(int channel);
107 
108  /*!
109  * Set the center frequency for the specified TX chain.
110  * Default implementation tunes RF component frequency as close as
111  * possible to the requested frequency. See specific device module
112  * for more information.
113  * \param channel an available channel on the device
114  * \param frequency center frequency in Hz
115  */
116  void set_frequency(size_t channel, double frequency);
117 
118  /*!
119  * Set the center frequency for the specified TX chain of the element.
120  * Default implementation tunes RF component frequency as close as
121  * possible to the requested frequency. See specific device module
122  * for more information
123  * \param channel an available channel on the device
124  * \param name an available element name
125  * \param frequency center frequency in Hz
126  */
127  void set_frequency(size_t channel, const std::string &name, double frequency);
128 
129  virtual bool DC_offset_support(int channel);
130  virtual bool IQ_balance_support(int channel);
131  virtual bool freq_correction_support(int channel);
132 
133  /*!
134  * Set the overall gain for the specified TX chain.
135  * The gain will be distributed automatically across available
136  * elements according to Soapy API.
137  * \param channel an available channel on the device
138  * \param gain the new amplification value in dB
139  */
140  void set_gain(size_t channel, float gain);
141 
142  /*!
143  * Set the value for the specified gain for the specified TX chain.
144  * \param channel an available channel on the device
145  * \param name an available gain on the device
146  * \param gain gain the new amplification value in dB
147  */
148  void set_gain(size_t channel, const std::string name, float gain);
149 
150  /*!
151  * Set the automatic gain mode for the TX chain if supported.
152  * If not supported set gain value manually.
153  * \param channel an available channel on the device
154  * \param gain_auto_mode true for automatic gain mode
155  */
156  void set_gain_mode(size_t channel, bool gain_auto_mode);
157 
158  /*!
159  * Set the baseband sample rate for the TX 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 TX 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 TX 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 TX 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  * \param dc_offset_auto_mode true for automatic dc offset correction
187  */
188  void set_dc_offset(size_t channel, gr_complexd dc_offset,
189  bool dc_offset_auto_mode);
190 
191  /*!
192  * Set automatic dc offset correction to the TX chain
193  * if supported by the device.
194  * \param channel an available channel on the device
195  * \param dc_offset_auto_mode true for automatic dc offset correction
196  */
197  void set_dc_offset_mode(size_t channel, bool dc_offset_auto_mode);
198 
199  /*!
200  * Set the frequency correction to the TX chain.
201  * @param channel an available channel on the device
202  * @param freq_correction the correction value in PPM
203  */
204  void set_frequency_correction(size_t channel, double freq_correction);
205 
206  /*!
207  * Set iq balance correction to the TX chain
208  * \param channel an available channel on the device
209  * \param iq_balance the relative correction (1.0 max)
210  */
211  void set_iq_balance(size_t channel, gr_complexd iq_balance);
212 
213  /*!
214  * Set the master clock rate of the device
215  * \param clock_rate the clock rate in Hz
216  */
217  void set_master_clock_rate(double clock_rate);
218 
219  /*!
220  * Set the clock source of the device
221  * \param clock_source the name of clock source
222  */
223  void set_clock_source(const std::string &clock_source);
224 
225  /*!
226  * Set the frontend mapping of available DSP units to RF frontends.
227  * This mapping controls channel mapping and channel availability.
228  * \param frontend_mapping a vendor-specific mapping string
229  */
230  void set_frontend_mapping(const std::string &frontend_mapping);
231 
232  /*!
233  * Get the down conversion frequency of the TX chain.
234  * \param channel an available channel on the device
235  * \return the center frequency in Hz
236  */
237  double get_frequency(size_t channel);
238 
239  /*!
240  * Get the overall value of the gain elements of the TX chain
241  * \param channel an available channel on the device
242  * \return the value of the gain in dB
243  */
244  double get_gain(size_t channel);
245 
246  /*!
247  * Get the automatic gain mode on the TX chain.
248  * \param channel an available channel on the device
249  * \return true for automatic gain setting
250  */
251  bool get_gain_mode(size_t channel);
252 
253  /*!
254  * Get the baseband sample rate of the TX chain.
255  * \param channel an available channel on the device
256  * \return the sample rate in samples per second
257  */
258  double get_sampling_rate(size_t channel);
259 
260  /*!
261  * Get baseband filter width of the TX chain.
262  * \param channel an available channel on the device
263  * \return the baseband filter width in Hz
264  */
265  double get_bandwidth(size_t channel);
266 
267  /*!
268  * Get the selected antenna on TX chain.
269  * \param channel an available channel on the device
270  * \return the name of the selected antenna
271  */
272  std::string get_antenna(size_t channel);
273 
274  /*!
275  * Get the DC offset correction.
276  * \param channel an available channel on the device
277  * \return the relative correction (1.0 max)
278  */
279  std::complex<double> get_dc_offset(size_t channel);
280 
281  /*!
282  * Get the automatic DC offset correction mode.
283  * \param channel an available channel on the device
284  * \return true for automatic offset correction
285  */
286  bool get_dc_offset_mode(size_t channel);
287 
288  /*!
289  * Get the frequency correction value.
290  * \param channel an available channel on the device
291  * \return the correction value in PPM
292  */
293  double get_frequency_correction(size_t channel);
294 
295  /*!
296  * Get the IQ balance correction.
297  * \param channel an available channel on the device
298  * \return the relative correction (1.0 max)
299  */
300  std::complex<double> get_iq_balance(size_t channel);
301 
302  /*!
303  * Get the master clock rate of the device.
304  * \return the clock rate in Hz
305  */
306  double get_master_clock_rate();
307 
308  /*!
309  * Get the clock source of the device
310  * \return the name of the clock source
311  */
312  std::string get_clock_source();
313 
314  /*!
315  * Calls the correct message handler according to the received message symbol.
316  * A dictionary with key the handler name is used in order to call the
317  * corresponding handler.
318  * \param msg a PMT dictionary
319  */
320  void msg_handler_command(pmt::pmt_t msg);
321 
322  /*!
323  * Set the center frequency of the RX chain.
324  * @param val center frequency in Hz
325  * @param chann an available channel on the device
326  */
327  void cmd_handler_frequency(pmt::pmt_t val, size_t chann);
328 
329  /*!
330  * Set the overall gain for the specified chain.
331  * The gain will be distributed automatically across available
332  * elements according to Soapy API.
333  * @param val the new amplification value in dB
334  * @param chann an avalaible channel on the device
335  */
336  void cmd_handler_gain(pmt::pmt_t val, size_t chann);
337 
338  /*!
339  * Set the baseband sample rate for the RX chain.
340  * @param val the sample rate samples per second
341  * @param chann an available channel on the device
342  */
343  void cmd_handler_samp_rate(pmt::pmt_t val, size_t chann);
344 
345  /*!
346  * Set the baseband filter width for the TX chain.
347  * @param val baseband filter width in Hz
348  * @param chann an available channel on the device
349  */
350  void cmd_handler_bw(pmt::pmt_t val, size_t chann);
351 
352  /*!
353  * Set the anntena element for the TX chain.
354  * @param val name of the anntena
355  * @param chann an available channel on the device
356  */
357  void cmd_handler_antenna(pmt::pmt_t val, size_t chann);
358 };
359 } // namespace soapy
360 } // namespace gr
361 
362 #endif /* INCLUDED_SOAPY_SINK_IMPL_H */
363 
virtual bool DC_offset_support(int channel)
sink_impl(size_t nchan, const std::string &device, const std::string &args, double sampling_rate, const std::string &type, const std::string &length_tag_name)
std::complex< double > get_dc_offset(size_t channel)
double get_sampling_rate(size_t channel)
void cmd_handler_samp_rate(pmt::pmt_t val, size_t chann)
void set_dc_offset_mode(size_t channel, bool dc_offset_auto_mode)
Definition: sink.h:52
double get_frequency(size_t channel)
void msg_handler_command(pmt::pmt_t msg)
virtual bool freq_correction_support(int channel)
void set_frequency(size_t channel, double frequency)
void set_clock_source(const std::string &clock_source)
std::complex< double > get_iq_balance(size_t channel)
virtual bool IQ_balance_support(int channel)
void set_antenna(size_t channel, const std::string &name)
double get_master_clock_rate()
virtual bool stop()
virtual bool start()
void set_bandwidth(size_t channel, double bandwidth)
void set_dc_offset(size_t channel, gr_complexd dc_offset, bool dc_offset_auto_mode)
bool get_gain_mode(size_t channel)
double get_gain(size_t channel)
void set_gain(size_t channel, float gain)
std::string get_antenna(size_t channel)
bool get_dc_offset_mode(size_t channel)
void set_gain_mode(size_t channel, bool gain_auto_mode)
void set_master_clock_rate(double clock_rate)
Definition: sink.h:29
double get_bandwidth(size_t channel)
void cmd_handler_antenna(pmt::pmt_t val, size_t chann)
void set_sample_rate(size_t channel, double sample_rate)
void set_frequency_correction(size_t channel, double freq_correction)
void set_iq_balance(size_t channel, gr_complexd iq_balance)
void cmd_handler_bw(pmt::pmt_t val, size_t chann)
int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items)
double get_frequency_correction(size_t channel)
std::string get_clock_source()
void set_frontend_mapping(const std::string &frontend_mapping)
boost::function< void(pmt::pmt_t, size_t)> cmd_handler_t
Definition: sink_impl.h:34
Sink block implementation for SDR devices.
Definition: sink_impl.h:43
virtual std::vector< std::string > listAntennas(int channel)
void cmd_handler_frequency(pmt::pmt_t val, size_t chann)
void cmd_handler_gain(pmt::pmt_t val, size_t chann)