aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp1/usrp1_impl.hpp
blob: b45d138d13c180287ac5ee442fe53fbccf6dde2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//
// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#include "usrp1_iface.hpp"
#include "codec_ctrl.hpp"
#include "soft_time_ctrl.hpp"
#include <uhd/device.hpp>
#include <uhd/property_tree.hpp>
#include <uhd/utils/pimpl.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/otw_type.hpp>
#include <uhd/types/clock_config.hpp>
#include <uhd/types/stream_cmd.hpp>
#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/transport/usb_zero_copy.hpp>
#include <boost/weak_ptr.hpp>
#include <complex>
#include <atomic>

#ifndef INCLUDED_USRP1_IMPL_HPP
#define INCLUDED_USRP1_IMPL_HPP

static const std::string USRP1_EEPROM_MAP_KEY = "B000";
static const size_t      USRP1_MAX_RATE_USB2  =  32000000; // bytes/s

#define FR_RB_CAPS          3
#define FR_MODE             13
#define FR_DEBUG_EN         14
#define FR_DC_OFFSET_CL_EN  15
#define FR_ADC_OFFSET_0     16
#define FR_ADC_OFFSET_1     17
#define FR_ADC_OFFSET_2     18
#define FR_ADC_OFFSET_3     19

#define I2C_DEV_EEPROM      0x50
#define I2C_ADDR_BOOT       (I2C_DEV_EEPROM | 0x0)
#define I2C_ADDR_TX_A       (I2C_DEV_EEPROM | 0x4)
#define I2C_ADDR_RX_A       (I2C_DEV_EEPROM | 0x5)
#define I2C_ADDR_TX_B       (I2C_DEV_EEPROM | 0x6)
#define I2C_ADDR_RX_B       (I2C_DEV_EEPROM | 0x7)

#define SPI_ENABLE_CODEC_A  0x02
#define SPI_ENABLE_CODEC_B  0x04

/*!
 * USRP1 implementation guts:
 * The implementation details are encapsulated here.
 * Handles properties on the mboard, dboard, dsps...
 */
class usrp1_impl : public uhd::device {
public:
    //! used everywhere to differentiate slots/sides...
    enum dboard_slot_t{
        DBOARD_SLOT_A = 'A',
        DBOARD_SLOT_B = 'B'
    };
    //and a way to enumerate through a list of the above...
    static const std::vector<dboard_slot_t> _dboard_slots;

    //structors
    usrp1_impl(const uhd::device_addr_t &);
    ~usrp1_impl(void);

    //the io interface
    uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args);
    uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args);
    bool recv_async_msg(uhd::async_metadata_t &, double);

private:
    //controllers
    uhd::usrp::fx2_ctrl::sptr _fx2_ctrl;
    usrp1_iface::sptr _iface;
    uhd::usrp::soft_time_ctrl::sptr _soft_time_ctrl;
    uhd::transport::usb_zero_copy::sptr _data_transport;
    struct db_container_type{
        usrp1_codec_ctrl::sptr codec;
        uhd::usrp::dboard_manager::sptr dboard_manager;
    };
    uhd::dict<std::string, db_container_type> _dbc;

    double _master_clock_rate; //clock rate shadow

    //weak pointers to streamers for update purposes
    boost::weak_ptr<uhd::rx_streamer> _rx_streamer;
    boost::weak_ptr<uhd::tx_streamer> _tx_streamer;

    void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &);
    void set_db_eeprom(const std::string &, const std::string &, const uhd::usrp::dboard_eeprom_t &);
    double update_rx_codec_gain(const std::string &, const double); //sets A and B at once
    void update_rx_subdev_spec(const uhd::usrp::subdev_spec_t &);
    void update_tx_subdev_spec(const uhd::usrp::subdev_spec_t &);
    double update_rx_samp_rate(size_t dspno, const double);
    double update_tx_samp_rate(size_t dspno, const double);
    void update_rates(void);
    double update_rx_dsp_freq(const size_t, const double);
    double update_tx_dsp_freq(const size_t, const double);
    void update_tick_rate(const double rate);
    uhd::meta_range_t get_rx_dsp_freq_range(void);
    uhd::meta_range_t get_tx_dsp_freq_range(void);
    uhd::meta_range_t get_rx_dsp_host_rates(void);
    uhd::meta_range_t get_tx_dsp_host_rates(void);
    size_t _rx_dc_offset_shadow;
    void set_enb_rx_dc_offset(const std::string &db, const bool);
    std::complex<double> set_rx_dc_offset(const std::string &db, const std::complex<double> &);

    static uhd::usrp::dboard_iface::sptr make_dboard_iface(
        usrp1_iface::sptr,
        usrp1_codec_ctrl::sptr,
        dboard_slot_t,
        const double &,
        const uhd::usrp::dboard_id_t &
    );

    //handle io stuff
    UHD_PIMPL_DECL(io_impl) _io_impl;
    void io_init(void);
    void rx_stream_on_off(bool);
    void tx_stream_on_off(bool);
    void handle_overrun(size_t);

    //channel mapping shadows
    uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec;

    //capabilities
    size_t get_num_ducs(void);
    size_t get_num_ddcs(void);
    bool has_rx_halfband(void);
    bool has_tx_halfband(void);

    void vandal_conquest_loop(std::atomic<bool> &);

    void set_reg(const std::pair<uint8_t, uint32_t> &reg);

    //handle the enables
    bool _rx_enabled, _tx_enabled;
    void enable_rx(bool enb){
        _rx_enabled = enb;
        _fx2_ctrl->usrp_rx_enable(enb);
    }
    void enable_tx(bool enb){
        _tx_enabled = enb;
        _fx2_ctrl->usrp_tx_enable(enb);
        for(const std::string &key:  _dbc.keys())
        {
            _dbc[key].codec->enable_tx_digital(enb);
        }
    }

    //conditionally disable and enable rx
    bool disable_rx(void){
        if (_rx_enabled){
            enable_rx(false);
            return true;
        }
        return false;
    }
    void restore_rx(bool last){
        if (last != _rx_enabled){
            enable_rx(last);
        }
    }

    //conditionally disable and enable tx
    bool disable_tx(void){
        if (_tx_enabled){
            enable_tx(false);
            return true;
        }
        return false;
    }
    void restore_tx(bool last){
        if (last != _tx_enabled){
            enable_tx(last);
        }
    }
};

#endif /* INCLUDED_USRP1_IMPL_HPP */