diff options
Diffstat (limited to 'host/lib/usrp')
-rw-r--r-- | host/lib/usrp/usrp_e/clock_ctrl.cpp | 39 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/codec_ctrl.cpp | 122 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/codec_ctrl.hpp | 73 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_iface.cpp | 7 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_impl.cpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_impl.hpp | 8 |
6 files changed, 250 insertions, 7 deletions
diff --git a/host/lib/usrp/usrp_e/clock_ctrl.cpp b/host/lib/usrp/usrp_e/clock_ctrl.cpp index fa4028cc5..2fe3c9294 100644 --- a/host/lib/usrp/usrp_e/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e/clock_ctrl.cpp @@ -37,6 +37,7 @@ public: void enable_rx_dboard_clock(bool enb); void enable_tx_dboard_clock(bool enb); + void enable_codec_clock(bool enb); private: usrp_e_iface::sptr _iface; @@ -79,10 +80,22 @@ clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ _ad9522_regs.vco_divider = ad9522_regs_t::VCO_DIVIDER_DIV5; _ad9522_regs.select_vco_or_clock = ad9522_regs_t::SELECT_VCO_OR_CLOCK_VCO; + //setup fpga master clock _ad9522_regs.out0_format = ad9522_regs_t::OUT0_FORMAT_LVDS; _ad9522_regs.divider0_low_cycles = 2; //3 low _ad9522_regs.divider0_high_cycles = 1; //2 high + //setup codec clock + _ad9522_regs.out3_format = ad9522_regs_t::OUT3_FORMAT_LVDS; + _ad9522_regs.divider1_low_cycles = 2; //3 low + _ad9522_regs.divider1_high_cycles = 1; //2 high + + //setup test clock (same divider as codec clock) + _ad9522_regs.out4_format = ad9522_regs_t::OUT4_FORMAT_CMOS; + _ad9522_regs.out4_cmos_configuration = (true)? + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON : + ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; + //setup a list of register ranges to write typedef std::pair<boost::uint16_t, boost::uint16_t> range_t; static const std::vector<range_t> ranges = boost::assign::list_of @@ -106,6 +119,8 @@ clock_ctrl_impl::clock_ctrl_impl(usrp_e_iface::sptr iface){ // reg, 24, true /*no*/ //); //std::cout << "result " << std::hex << result << std::endl; + this->enable_rx_dboard_clock(false); + this->enable_tx_dboard_clock(false); } clock_ctrl_impl::~clock_ctrl_impl(void){ @@ -114,16 +129,34 @@ clock_ctrl_impl::~clock_ctrl_impl(void){ } void clock_ctrl_impl::enable_rx_dboard_clock(bool enb){ - + _ad9522_regs.out9_format = ad9522_regs_t::OUT9_FORMAT_CMOS; + _ad9522_regs.out9_cmos_configuration = (enb)? + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT9_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F9); + + _ad9522_regs.divider3_low_cycles = 2; //3 low + _ad9522_regs.divider3_high_cycles = 1; //2 high + this->send_reg(0x199); + this->latch_regs(); } void clock_ctrl_impl::enable_tx_dboard_clock(bool enb){ - + _ad9522_regs.out6_format = ad9522_regs_t::OUT6_FORMAT_CMOS; + _ad9522_regs.out6_cmos_configuration = (enb)? + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_B_ON : + ad9522_regs_t::OUT6_CMOS_CONFIGURATION_OFF; + this->send_reg(0x0F6); + + _ad9522_regs.divider2_low_cycles = 2; //3 low + _ad9522_regs.divider2_high_cycles = 1; //2 high + this->send_reg(0x196); + this->latch_regs(); } void clock_ctrl_impl::send_reg(boost::uint16_t addr){ boost::uint32_t reg = _ad9522_regs.get_write_reg(addr); - std::cout << "clock control write reg: " << std::hex << reg << std::endl; + //std::cout << "clock control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( UE_SPI_SS_AD9522, spi_config_t::EDGE_RISE, diff --git a/host/lib/usrp/usrp_e/codec_ctrl.cpp b/host/lib/usrp/usrp_e/codec_ctrl.cpp new file mode 100644 index 000000000..daa6ed3e3 --- /dev/null +++ b/host/lib/usrp/usrp_e/codec_ctrl.cpp @@ -0,0 +1,122 @@ +// +// 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/>. +// + +#include "codec_ctrl.hpp" +#include "ad9862_regs.hpp" +#include <boost/cstdint.hpp> +#include "usrp_e_regs.hpp" //spi slave constants +#include <boost/assign/list_of.hpp> +//#include <boost/foreach.hpp> +//#include <utility> +#include <iostream> + + //test out codec ls dac/adc + //ad9862_regs_t ad9862_regs; + //ad9862_regs.select_a = ad9862_regs_t::SELECT_A_AUX_ADC1; + //ad9862_regs.aux_dac_a = 0xff/2; + //_iface->transact_spi( + // UE_SPI_SS_AD9862, + // spi_config_t::EDGE_RISE, + // ad9862_regs.get_write_reg(34), 16, false /*no rb*/ + //); + //_iface->transact_spi( + // UE_SPI_SS_AD9862, + // spi_config_t::EDGE_RISE, + // ad9862_regs.get_write_reg(36), 16, false /*no rb*/ + //); + //boost::uint32_t val = _iface->transact_spi( + // UE_SPI_SS_AD9862, + // spi_config_t::EDGE_RISE, + // ad9862_regs.get_read_reg(29), 16, true + //); + //std::cout << "value: " << std::hex << val << std::endl; + +using namespace uhd; + +/*********************************************************************** + * Codec Control Implementation + **********************************************************************/ +class codec_ctrl_impl : public codec_ctrl{ +public: + //structors + codec_ctrl_impl(usrp_e_iface::sptr iface); + ~codec_ctrl_impl(void); + + //aux adc and dac control + float read_aux_adc(aux_adc_t which); + void read_aux_adc(aux_dac_t which, float volts); + +private: + usrp_e_iface::sptr _iface; + ad9862_regs_t _ad9862_regs; + void send_reg(boost::uint8_t addr); +}; + +/*********************************************************************** + * Codec Control Methods + **********************************************************************/ +codec_ctrl_impl::codec_ctrl_impl(usrp_e_iface::sptr iface){ + _iface = iface; + + //soft reset + _ad9862_regs.soft_reset = 1; + this->send_reg(0); + + //initialize the codec register settings + _ad9862_regs.sdio_bidir = ad9862_regs_t::SDIO_BIDIR_SDIO_SDO; + _ad9862_regs.lsb_first = ad9862_regs_t::LSB_FIRST_MSB; + _ad9862_regs.soft_reset = 0; + + //write the register settings to the codec + for (uint8_t addr = 0; addr <= 50; addr++){ + this->send_reg(addr); + } +} + +codec_ctrl_impl::~codec_ctrl_impl(void){ + _ad9862_regs.all_rx_pd = 1; + this->send_reg(1); + _ad9862_regs.tx_digital_pd = 1; + _ad9862_regs.tx_analog_pd = ad9862_regs_t::TX_ANALOG_PD_BOTH; + this->send_reg(8); +} + +float codec_ctrl_impl::read_aux_adc(aux_adc_t which){ + return 0; + +} + +void codec_ctrl_impl::read_aux_adc(aux_dac_t which, float volts){ + +} + +void codec_ctrl_impl::send_reg(boost::uint8_t addr){ + boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); + //std::cout << "codec control write reg: " << std::hex << reg << std::endl; + _iface->transact_spi( + UE_SPI_SS_AD9862, + spi_config_t::EDGE_RISE, + reg, 24, false /*no rb*/ + ); +} + +/*********************************************************************** + * Codec Control Make + **********************************************************************/ +codec_ctrl::sptr codec_ctrl::make(usrp_e_iface::sptr iface){ + return sptr(new codec_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e/codec_ctrl.hpp b/host/lib/usrp/usrp_e/codec_ctrl.hpp new file mode 100644 index 000000000..0fe70c4a2 --- /dev/null +++ b/host/lib/usrp/usrp_e/codec_ctrl.hpp @@ -0,0 +1,73 @@ +// +// 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/>. +// + +#ifndef INCLUDED_USRP_E_CODEC_CTRL_HPP +#define INCLUDED_USRP_E_CODEC_CTRL_HPP + +#include "usrp_e_iface.hpp" +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> + +/*! + * The usrp-e codec control: + * - Init/power down codec. + * - Read aux adc, write aux dac. + */ +class codec_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr<codec_ctrl> sptr; + + /*! + * Make a new clock control object. + * \param iface the usrp_e iface object + * \return the clock control object + */ + static sptr make(usrp_e_iface::sptr iface); + + //! aux adc identifier constants + enum aux_adc_t{ + AUX_ADC_A2 = 0xA2, + AUX_ADC_A1 = 0xA1, + AUX_ADC_B2 = 0xB2, + AUX_ADC_B1 = 0xB1 + }; + + /*! + * Read the aux adc. + * \param which which of the 4 adcs + * \return a value in volts + */ + virtual float read_aux_adc(aux_adc_t which) = 0; + + //! aux dac identifier constants + enum aux_dac_t{ + AUX_DAC_A = 0xA, + AUX_DAC_B = 0xB, + AUX_DAC_C = 0xC, + AUX_DAC_D = 0xD + }; + + /*! + * Write the aux dac. + * \param which which of the 4 dacs + * \param volts the level in in volts + */ + virtual void read_aux_adc(aux_dac_t which, float volts) = 0; + +}; + +#endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp index 41737a716..1dbe383fa 100644 --- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp @@ -20,6 +20,7 @@ #include <sys/ioctl.h> //ioctl #include <linux/usrp_e.h> //ioctl structures and constants #include <boost/format.hpp> +#include <boost/thread.hpp> //mutex #include <stdexcept> using namespace uhd; @@ -42,6 +43,8 @@ public: * IOCTL: provides the communication base for all other calls ******************************************************************/ void ioctl(int request, void *mem){ + boost::mutex::scoped_lock lock(_ctrl_mutex); + if (::ioctl(_node_fd, request, mem) < 0){ throw std::runtime_error(str( boost::format("ioctl failed with request %d") % request @@ -167,7 +170,9 @@ public: return data.data; } -private: int _node_fd; +private: + int _node_fd; + boost::mutex _ctrl_mutex; }; /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 52bbcdd32..b6fed6a74 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -23,7 +23,6 @@ #include <boost/filesystem.hpp> #include <iostream> #include <fcntl.h> //open -#include "clock_ctrl.hpp" using namespace uhd; using namespace uhd::usrp; @@ -84,9 +83,12 @@ usrp_e_impl::usrp_e_impl(const std::string &node){ )); } - _iface = usrp_e_iface::make(_node_fd); + sleep(1); //FIXME sleep here until the kernel driver stops hanging - clock_ctrl::sptr my_clk_ctrl = clock_ctrl::make(_iface); + //setup various interfaces into hardware + _iface = usrp_e_iface::make(_node_fd); + _clock_ctrl = clock_ctrl::make(_iface); + _codec_ctrl = codec_ctrl::make(_iface); //initialize the mboard mboard_init(); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 23e36ed05..6746e012a 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -16,6 +16,8 @@ // #include "usrp_e_iface.hpp" +#include "clock_ctrl.hpp" +#include "codec_ctrl.hpp" #include <uhd/usrp/usrp_e.hpp> #include <uhd/usrp/dboard_eeprom.hpp> #include <uhd/types/clock_config.hpp> @@ -91,6 +93,12 @@ private: uhd::clock_config_t _clock_config; + //ad9522 clock control + clock_ctrl::sptr _clock_ctrl; + + //ad9862 codec control + codec_ctrl::sptr _codec_ctrl; + //device functions and settings void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); |