//
// 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 .
//
#include "clock_ctrl.hpp"
#include "fpga_regs_standard.h"
#include
#include
#include
#include
#include
#include
using namespace uhd;
/***********************************************************************
* Constants
**********************************************************************/
static const double master_clock_rate = 64e6;
/***********************************************************************
* Clock Control Implementation
**********************************************************************/
class usrp1_clock_ctrl_impl : public usrp1_clock_ctrl {
public:
usrp1_clock_ctrl_impl(usrp1_iface::sptr iface)
{
_iface = iface;
}
double get_master_clock_freq(void)
{
return master_clock_rate;
}
/***********************************************************************
* RX Dboard Clock Control (output 9, divider 3)
**********************************************************************/
void enable_rx_dboard_clock(bool)
{
std::cerr << "USRP: enable_rx_dboard_clock() disabled" << std::endl;
_iface->poke32(FR_RX_A_REFCLK, 0);
_iface->poke32(FR_RX_B_REFCLK, 0);
}
std::vector get_rx_dboard_clock_rates(void)
{
#if 0
std::vector rates;
for (size_t div = 1; div <= 127; div++)
rates.push_back(master_clock_rate / div);
return rates;
#else
return std::vector(1, 64e6);
#endif
}
/*
* Daughterboard reference clock register
*
* Bit 7 - 1 turns on refclk, 0 allows IO use
* Bits 6:0 - Divider value
*/
void set_rx_dboard_clock_rate(double)
{
#if 0
assert_has(get_rx_dboard_clock_rates(), rate, "rx dboard clock rate");
size_t divider = size_t(rate/master_clock_rate);
_iface->poke32(FR_RX_A_REFCLK, (divider & 0x7f) | 0x80);
#else
std::cerr << "USRP: set_rx_dboard_clock_rate() disabled" << std::endl;
_iface->poke32(FR_RX_A_REFCLK, 0);
_iface->poke32(FR_RX_B_REFCLK, 0);
#endif
}
/***********************************************************************
* TX Dboard Clock Control
**********************************************************************/
void enable_tx_dboard_clock(bool)
{
std::cerr << "USRP: set_tx_dboard_clock() disabled" << std::endl;
_iface->poke32(FR_TX_A_REFCLK, 0);
_iface->poke32(FR_TX_B_REFCLK, 0);
}
std::vector get_tx_dboard_clock_rates(void)
{
return get_rx_dboard_clock_rates(); //same master clock, same dividers...
}
void set_tx_dboard_clock_rate(double)
{
std::cerr << "USRP: set_tx_dboard_clock_rate() disabled" << std::endl;
_iface->poke32(FR_TX_A_REFCLK, 0);
_iface->poke32(FR_TX_B_REFCLK, 0);
}
private:
usrp1_iface::sptr _iface;
};
/***********************************************************************
* Clock Control Make
**********************************************************************/
usrp1_clock_ctrl::sptr usrp1_clock_ctrl::make(usrp1_iface::sptr iface)
{
return sptr(new usrp1_clock_ctrl_impl(iface));
}