diff options
| author | Nick Foster <nick@nerdnetworks.org> | 2010-09-21 10:41:05 -0700 | 
|---|---|---|
| committer | Nick Foster <nick@nerdnetworks.org> | 2010-09-21 10:41:05 -0700 | 
| commit | ba658f4d2cac9fb0f9d22060da989c9078cc4d1e (patch) | |
| tree | 10bdc9d29f71c4def00208ce82fd289f228c51e5 | |
| parent | 1b3b856f5a5d06628d4176071cad424a146433c9 (diff) | |
| download | uhd-ba658f4d2cac9fb0f9d22060da989c9078cc4d1e.tar.gz uhd-ba658f4d2cac9fb0f9d22060da989c9078cc4d1e.tar.bz2 uhd-ba658f4d2cac9fb0f9d22060da989c9078cc4d1e.zip | |
added db_tvrx, regmap gen_dtt75403_regs.py
| -rw-r--r-- | host/lib/ic_reg_maps/CMakeLists.txt | 5 | ||||
| -rwxr-xr-x | host/lib/ic_reg_maps/gen_dtt75403_regs.py | 85 | ||||
| -rwxr-xr-x[-rw-r--r--] | host/lib/ic_reg_maps/gen_max2118_regs.py | 0 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/db_tvrx.cpp | 316 | 
4 files changed, 406 insertions, 0 deletions
| diff --git a/host/lib/ic_reg_maps/CMakeLists.txt b/host/lib/ic_reg_maps/CMakeLists.txt index f8e15c13d..b396db4ca 100644 --- a/host/lib/ic_reg_maps/CMakeLists.txt +++ b/host/lib/ic_reg_maps/CMakeLists.txt @@ -68,3 +68,8 @@ LIBUHD_PYTHON_GEN_SOURCE(      ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad9522_regs.py      ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad9522_regs.hpp  ) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_dtt75403_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/dtt75403_regs.py +) diff --git a/host/lib/ic_reg_maps/gen_dtt75403_regs.py b/host/lib/ic_reg_maps/gen_dtt75403_regs.py new file mode 100755 index 000000000..fe64bd92a --- /dev/null +++ b/host/lib/ic_reg_maps/gen_dtt75403_regs.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# +# Copyright 2010 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/>. +# + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_TMPL="""\ +######################################################################## +## Note: offsets given from perspective of data bits (excludes address) +######################################################################## +## +######################################################################## +## Address byte +######################################################################## +adb                   0[1:2]        0 +######################################################################## +## Divider byte 1 +######################################################################## +db1                   1[0:6]        0x00 +######################################################################## +## Divider byte 2 +######################################################################## +db2                   2[0:7]        0x00 +######################################################################## +## Control byte 1 +######################################################################## +atp                   3[3:5]        0       112, 109, 106, 103, 100, 94, 94, disable +refdiv                3[0:2]        0       166.667khz, 142.857khz, 80khz, 62.5khz, 31.25khz, 50khz +######################################################################## +## Band switch byte +######################################################################## +cpsel                 4[6:7]        0 +filterbw              4[4]          0       8mhz, 7mhz +bandsel               4[0:3]        0 +######################################################################## +## Control byte 2 +######################################################################## +atc                   5[5]          0       low, high +stby                  5[4]          0       standby, on +xto                   5[0]          0       disable, enable +""" + +######################################################################## +# Template for methods in the body of the struct +######################################################################## +BODY_TMPL="""\ +boost::uint8_t get_reg(boost::uint8_t addr){ +    boost::uint8_t reg = 0; +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); +        #end for +        break; +    #end for +    } +    return boost::uint8_t(reg); +} + +""" + +if __name__ == '__main__': +    import common; common.generate( +        name='dtt75403_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_max2118_regs.py b/host/lib/ic_reg_maps/gen_max2118_regs.py index 506fbaec8..506fbaec8 100644..100755 --- a/host/lib/ic_reg_maps/gen_max2118_regs.py +++ b/host/lib/ic_reg_maps/gen_max2118_regs.py diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp new file mode 100644 index 000000000..5582dbe33 --- /dev/null +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -0,0 +1,316 @@ +// +// Copyright 2010 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/>. +// + +// No RX IO Pins Used + +// RX IO Functions + +//ADC/DAC functions: +//DAC 1: RF AGC +//DAC 2: IF AGC + +//min freq: 50e6 +//max freq: 860e6 +//gain range: [0:1dB:115dB] + +#include <uhd/utils/static.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/warning.hpp> +#include <uhd/types/ranges.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/usrp/subdev_props.hpp> +#include <uhd/usrp/dboard_base.hpp> +#include <uhd/usrp/dboard_manager.hpp> +#include <boost/assign/list_of.hpp> +#include <boost/format.hpp> +#include <boost/thread.hpp> +#include <boost/math/special_functions/round.hpp> +#include <utility> +#include <cmath> + +using namespace uhd; +using namespace uhd::usrp; +using namespace boost::assign; + +/*********************************************************************** + * The tvrx constants + **********************************************************************/ +static const bool tvrx_debug = true; + +static const freq_range_t tvrx_freq_range(50e6, 860e6); + +static const prop_names_t tvrx_antennas = ""; //only got one + +static const uhd::dict<std::string, gain_range_t> tvrx_gain_ranges = map_list_of +    ("RF", gain_range_t(0, 60, float(60.0/4096))) //both gains are analog and controlled by DAC +    ("IF", gain_range_t(0, 35, float(35.0/4096))) //the old driver used 1dB for both; i don't think that's right? +; + +static const uhd::dict<std::string, freq_range_t> tvrx_freq_ranges = map_list_of +    ("VHFLO", freq_range_t(50e6, 158e6)) //this isn't used outside this driver. just for us. +    ("VHFHI", freq_range_t(158e6, 454e6)) +    ("UHF"  , freq_range_t(454e6, 860e6)) +; + +//we might need to spec the various bands for band selection. + +static const double tvrx_lo_freq = 36e6; //LO freq of TVRX module + +/*********************************************************************** + * The tvrx dboard class + **********************************************************************/ +class tvrx : public rx_dboard_base{ +public: +    tvrx(ctor_args_t args); +    ~tvrx(void); +     +    void rx_get(const wax::obj &key, wax::obj &val); +    void rx_set(const wax::obj &key, const wax::obj &val); + +private: +    uhd::dict<std::string, float> _gains; +    dtt75403_regs_t _dtt75403_regs; +    boost::uint8_t _dtt75403_addr(void){ +        return (this->get_iface()->get_special_props().mangle_i2c_addrs)? 0x60 : 0x61; //ok really? we could rename that call +    }; + +    void set_gain(float gain, const std::string &name); + +    void send_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){ +        //why is this an inline anyway? bring this out +        start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0x5)); +        stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0x5)); + +        for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t) - 1){ +            int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) - 1 ? sizeof(boost::uint32_t) - 1 : stop_reg - start_addr + 1; + +            //create buffer for register data (+1 for start address) +            byte_vector_t regs_vector(num_bytes + 1); + +            //first byte is the address of first register +            regs_vector[0] = start_addr; + +            //get the register data +            for(int i=0; i<num_bytes; i++){ +                regs_vector[1+i] = _max2118_write_regs.get_reg(start_addr+i); +                if(tvrx_debug) std::cerr << boost::format( +                    "tvrx: send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d" +                ) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes << std::endl; +            } + +            //send the data +            this->get_iface()->write_i2c( +                _max2118_addr(), regs_vector +            ); +        } +    } + +}; + +/*********************************************************************** + * Register the tvrx dboard + **********************************************************************/ +static dboard_base::sptr make_tvrx(dboard_base::ctor_args_t args){ +    return dboard_base::sptr(new tvrx(args)); +} + +UHD_STATIC_BLOCK(reg_tvrx_dboard){ +    //register the factory function for the rx dbid +    dboard_manager::register_dboard(0x0003, &make_tvrx, "tvrx"); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){ +    //enable only the clocks we need +     +    //TODO: YOU GOT SOME CLOCK SETUP TO DO HERE, DOGGGG +     +    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); + +    //set the gpio directions and atr controls (identically) +    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0); // All unused in atr +    if (this->get_iface()->get_special_props().soft_clock_divider){ +        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x1); // GPIO0 is clock +    } +    else{ +        this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0x0); // All Inputs +    } + +    //send initial register settings +    //HAAAAY GUYYYYYSSS +     +    //set default gains +    BOOST_FOREACH(const std::string &name, tvrx_gain_ranges.keys()){ +        set_gain(tvrx_gain_ranges[name].min, name); +    } +} + +tvrx::~tvrx(void){ +} + +/*********************************************************************** + * Gain Handling + **********************************************************************/ +/*! + * Convert a requested gain for the GC2 vga into the integer register value. + * The gain passed into the function will be set to the actual value. + * \param gain the requested gain in dB + * \return 5 bit the register value + */ + +//yo this should look the same as the below one for the IF, dogg +static int gain_to_gc2_vga_reg(float &gain){ +    int reg = 0; +    gain = std::clip<float>(float(boost::math::iround(gain)), tvrx_gain_ranges["GC2"].min, tvrx_gain_ranges["GC2"].max); + +    // Half dB steps from 0-5dB, 1dB steps from 5-24dB +    if (gain < 5) { +        reg = boost::math::iround(31.0 - gain/0.5); +        gain = float(boost::math::iround(gain) * 0.5); +    } else { +        reg = boost::math::iround(22.0 - (gain - 4.0)); +        gain = float(boost::math::iround(gain)); +    } + +    if (tvrx_debug) std::cerr << boost::format( +        "tvrx GC2 Gain: %f dB, reg: %d" +    ) % gain % reg << std::endl; + +    return reg; +} + +/*! + * Convert a requested gain for the RF gain into the dac_volts value. + * The gain passed into the function will be set to the actual value. + * \param gain the requested gain in dB + * \return dac voltage value + */ + +//yo what about the 1.22 opamp gain of the USRP1 -- is this replicated on U2? +static float gain_to_rfgain_dac(float &gain){ +    //clip the input +    gain = std::clip<float>(gain, tvrx_gain_ranges["RF"].min, tvrx_gain_ranges["RF"].max); + +    //voltage level constants +    static const float max_volts = float(0), min_volts = float(3.3); +    static const float slope = (max_volts-min_volts)/tvrx_gain_ranges["RF"].max; + +    //calculate the voltage for the aux dac +    float dac_volts = gain*slope + min_volts; + +    if (tvrx_debug) std::cerr << boost::format( +        "tvrx RFAGC Gain: %f dB, dac_volts: %f V" +    ) % gain % dac_volts << std::endl; + +    //the actual gain setting +    gain = (dac_volts - min_volts)/slope; + +    return dac_volts; +} + +void tvrx::set_gain(float gain, const std::string &name){ +    assert_has(tvrx_gain_ranges.keys(), name, "tvrx gain name"); +    if (name == "RF"){ +//should look the same as below +    } +    else if(name == "IF"){ +        //write the new voltage to the aux dac                                CHECK THIS +        this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, dboard_iface::AUX_DAC_A, gain_to_gc1_rfvga_dac(gain)); +    } +    else UHD_THROW_INVALID_CODE_PATH(); +    _gains[name] = gain; +} + +/*********************************************************************** + * RX Get and Set + **********************************************************************/ +void tvrx::rx_get(const wax::obj &key_, wax::obj &val){ +    named_prop_t key = named_prop_t::extract(key_); + +    //handle the get request conditioned on the key +    switch(key.as<subdev_prop_t>()){ +    case SUBDEV_PROP_NAME: +        val = get_rx_id().to_pp_string(); +        return; + +    case SUBDEV_PROP_OTHERS: +        val = prop_names_t(); //empty +        return; + +    case SUBDEV_PROP_GAIN: +        assert_has(_gains.keys(), key.name, "tvrx gain name"); +        val = _gains[key.name]; +        return; + +    case SUBDEV_PROP_GAIN_RANGE: +        assert_has(tvrx_gain_ranges.keys(), key.name, "tvrx gain name"); +        val = tvrx_gain_ranges[key.name]; +        return; + +    case SUBDEV_PROP_GAIN_NAMES: +        val = prop_names_t(tvrx_gain_ranges.keys()); +        return; + +    case SUBDEV_PROP_FREQ: +        val = tvrx_lo_freq; +        return; + +    case SUBDEV_PROP_FREQ_RANGE: +        val = tvrx_freq_range; +        return; + +    case SUBDEV_PROP_ANTENNA: +        val = std::string(tvrx_antennas); +        return; + +    case SUBDEV_PROP_ANTENNA_NAMES: +        val = tvrx_antennas; +        return; + +    case SUBDEV_PROP_CONNECTION: +        val = SUBDEV_CONN_COMPLEX_IQ; +        return; + +    case SUBDEV_PROP_USE_LO_OFFSET: +        val = false; +        return; + +    case SUBDEV_PROP_LO_LOCKED: +        val = true; +        return; + +    default: UHD_THROW_PROP_GET_ERROR(); +    } +} + +//for smaaht kids to use to set advanced props +void tvrx::rx_set(const wax::obj &key_, const wax::obj &val){ +    named_prop_t key = named_prop_t::extract(key_); + +    //handle the get request conditioned on the key +    switch(key.as<subdev_prop_t>()){ +    case SUBDEV_PROP_GAIN: +        this->set_gain(val.as<float>(), key.name); +        return; + +    default: UHD_THROW_PROP_SET_ERROR(); +    } +} + | 
