Rebase on master, cleanup for merge
[debian/gnuradio] / usrp2 / host / lib / usrp2_impl.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008,2009 Free Software Foundation, Inc.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifndef INCLUDED_USRP2_IMPL_H
20 #define INCLUDED_USRP2_IMPL_H
21
22 #include <usrp2/usrp2.h>
23 #include <usrp2/data_handler.h>
24 #include <usrp2_eth_packet.h>
25 #include <boost/scoped_ptr.hpp>
26 #include "control.h"
27 #include "ring.h"
28 #include <string>
29
30 #define MAX_SUBPKT_LEN 252
31
32 namespace usrp2 {
33
34   class eth_buffer;
35   class pktfilter;
36   class usrp2_thread;
37   class usrp2_tune_result;
38   class pending_reply;
39   class ring;
40
41   //! High-level d'board info
42   struct db_info {
43     int         dbid;
44     double      freq_min;               // Hz
45     double      freq_max;               // Hz
46     double      gain_min;               // dB
47     double      gain_max;               // dB
48     double      gain_step_size;         // dB
49
50     db_info() : dbid(-1), freq_min(0), freq_max(0),
51                 gain_min(0), gain_max(0), gain_step_size(0) {}
52   };
53
54   class usrp2::impl : private data_handler
55   {
56     static const size_t NRIDS = 256;
57     static const size_t NCHANS = 32;
58
59     eth_buffer    *d_eth_buf;
60     std::string    d_interface_name;
61     pktfilter     *d_pf;
62     std::string    d_addr;       // FIXME: use u2_mac_addr_t instead
63     usrp2_thread  *d_bg_thread;
64     volatile bool  d_bg_running; // TODO: multistate if needed
65
66     int            d_rx_seqno;
67     int            d_tx_seqno;
68     int            d_next_rid;
69     unsigned int   d_num_rx_frames;
70     unsigned int   d_num_rx_missing;
71     unsigned int   d_num_rx_overruns;
72     unsigned int   d_num_rx_bytes;
73
74     unsigned int   d_num_enqueued;
75     omni_mutex     d_enqueued_mutex;
76     omni_condition d_bg_pending_cond;
77
78     // all pending_replies are stack allocated, thus no possibility of leaking these
79     pending_reply *d_pending_replies[NRIDS]; // indexed by 8-bit reply id
80
81     std::vector<ring_sptr>   d_channel_rings; // indexed by 5-bit channel number
82     omni_mutex     d_channel_rings_mutex;
83
84     db_info        d_tx_db_info;
85     db_info        d_rx_db_info;
86
87     int            d_tx_interp;         // shadow tx interp
88     int            d_rx_decim;          // shadow rx decim
89
90     bool           d_dont_enqueue;
91
92     void inc_enqueued() {
93       omni_mutex_lock l(d_enqueued_mutex);
94       d_num_enqueued++;
95     }
96
97     void dec_enqueued() {
98       omni_mutex_lock l(d_enqueued_mutex);
99       if (--d_num_enqueued == 0)
100         d_bg_pending_cond.signal();
101     }
102
103     static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
104     void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst);
105     void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
106                        int word0_flags, int chan, uint32_t timestamp);
107     void stop_bg();
108     void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd);
109     void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
110     bool transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs=0.0);
111     bool transmit_cmd(void *cmd, size_t len);
112     virtual data_handler::result operator()(const void *base, size_t len);
113     data_handler::result handle_control_packet(const void *base, size_t len);
114     data_handler::result handle_data_packet(const void *base, size_t len);
115     bool dboard_info();
116     bool reset_db();
117
118   public:
119     impl(const std::string &ifc, props *p, size_t rx_bufsize);
120     ~impl();
121
122     void bg_loop();
123
124     std::string mac_addr() const { return d_addr; } // FIXME: convert from u2_mac_addr_t
125     std::string interface_name() const { return d_interface_name; }
126
127     // Rx
128
129     bool set_rx_gain(double gain);
130     double rx_gain_min() { return d_rx_db_info.gain_min; }
131     double rx_gain_max() { return d_rx_db_info.gain_max; }
132     double rx_gain_db_per_step() { return d_rx_db_info.gain_step_size; }
133     bool set_rx_lo_offset(double frequency);
134     bool set_rx_center_freq(double frequency, tune_result *result);
135     double rx_freq_min() { return d_rx_db_info.freq_min; }
136     double rx_freq_max() { return d_rx_db_info.freq_max; }
137     bool set_rx_decim(int decimation_factor);
138     int rx_decim() { return d_rx_decim; }
139     bool set_rx_scale_iq(int scale_i, int scale_q);
140     bool set_gpio_ddr(int bank, uint16_t value, uint16_t mask);
141     bool set_gpio_sels(int bank, std::string src);
142     bool enable_gpio_streaming(int bank, int enable);
143     bool write_gpio(int bank, uint16_t value, uint16_t mask);
144     bool read_gpio(int bank, uint16_t *value);
145     bool start_rx_streaming(unsigned int channel, unsigned int items_per_frame);
146     bool start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
147     bool sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
148     bool rx_samples(unsigned int channel, rx_sample_handler *handler);
149     bool flush_rx_samples(unsigned int channel);
150     bool stop_rx_streaming(unsigned int channel);
151     unsigned int rx_overruns() const { return d_num_rx_overruns; }
152     unsigned int rx_missing() const { return d_num_rx_missing; }
153
154     // Tx
155
156     bool set_tx_gain(double gain);
157     double tx_gain_min() { return d_tx_db_info.gain_min; }
158     double tx_gain_max() { return d_tx_db_info.gain_max; }
159     double tx_gain_db_per_step() { return d_tx_db_info.gain_step_size; }
160     bool set_tx_lo_offset(double frequency);
161     bool set_tx_center_freq(double frequency, tune_result *result);
162     double tx_freq_min() { return d_tx_db_info.freq_min; }
163     double tx_freq_max() { return d_tx_db_info.freq_max; }
164     bool set_tx_interp(int interpolation_factor);
165     int tx_interp() { return d_tx_interp; }
166     void default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q);
167     bool set_tx_scale_iq(int scale_i, int scale_q);
168
169     bool tx_32fc(unsigned int channel,
170                  const std::complex<float> *samples,
171                  size_t nsamples,
172                  const tx_metadata *metadata);
173
174     bool tx_16sc(unsigned int channel,
175                  const std::complex<int16_t> *samples,
176                  size_t nsamples,
177                  const tx_metadata *metadata);
178
179     bool tx_raw(unsigned int channel,
180                 const uint32_t *items,
181                 size_t nitems,
182                 const tx_metadata *metadata);
183
184     // misc
185
186     bool config_mimo(int flags);
187     bool fpga_master_clock_freq(long *freq);
188     bool adc_rate(long *rate);
189     bool dac_rate(long *rate);
190     bool tx_daughterboard_id(int *dbid);
191     bool rx_daughterboard_id(int *dbid);
192
193     // low level
194
195     bool burn_mac_addr(const std::string &new_addr);
196     bool sync_to_pps();
197     bool sync_every_pps(bool enable);
198     std::vector<uint32_t> peek32(uint32_t addr, uint32_t words);
199     bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
200   };
201
202 } // namespace usrp2
203
204 #endif /* INCLUDED_USRP2_IMPL_H */