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
|
//
// Copyright 2010-2012 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#include "codec_ctrl.hpp"
#include "soft_time_ctrl.hpp"
#include "usrp1_iface.hpp"
#include <uhd/device.hpp>
#include <uhd/property_tree.hpp>
#include <uhd/transport/usb_zero_copy.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/stream_cmd.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>
#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/usrp/subdev_spec.hpp>
#include <uhd/utils/pimpl.hpp>
#include <atomic>
#include <complex>
#include <memory>
#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) override;
// the io interface
uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t& args) override;
uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t& args) override;
bool recv_async_msg(uhd::async_metadata_t&, double) override;
static uhd::usrp::mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr);
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
std::weak_ptr<uhd::rx_streamer> _rx_streamer;
std::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 */
|