summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-05-04 09:32:38 +0000
committerJosh Blum <josh@joshknows.com>2010-05-04 09:32:38 +0000
commit8f21adbed40db490bec8ead6b8d50d2b3d1a4136 (patch)
treee664c69ee78a6409b20d5123bb535c52a24243bc /host/lib/usrp
parentd8c04c4b70f41b27acb33cd69ed88469d7c94482 (diff)
downloaduhd-8f21adbed40db490bec8ead6b8d50d2b3d1a4136.tar.gz
uhd-8f21adbed40db490bec8ead6b8d50d2b3d1a4136.tar.bz2
uhd-8f21adbed40db490bec8ead6b8d50d2b3d1a4136.zip
created codec control for ad9862, wip
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/usrp_e/clock_ctrl.cpp39
-rw-r--r--host/lib/usrp/usrp_e/codec_ctrl.cpp122
-rw-r--r--host/lib/usrp/usrp_e/codec_ctrl.hpp73
-rw-r--r--host/lib/usrp/usrp_e/usrp_e_iface.cpp7
-rw-r--r--host/lib/usrp/usrp_e/usrp_e_impl.cpp8
-rw-r--r--host/lib/usrp/usrp_e/usrp_e_impl.hpp8
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 &);