root / host / lib / usrp / dboard / db_sbx_common.cpp @ 4b9d692f
History | View | Annotate | Download (15.5 KB)
| 1 |
//
|
|---|---|
| 2 |
// Copyright 2011 Ettus Research LLC
|
| 3 |
//
|
| 4 |
// This program is free software: you can redistribute it and/or modify
|
| 5 |
// it under the terms of the GNU General Public License as published by
|
| 6 |
// the Free Software Foundation, either version 3 of the License, or
|
| 7 |
// (at your option) any later version.
|
| 8 |
//
|
| 9 |
// This program is distributed in the hope that it will be useful,
|
| 10 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 11 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 12 |
// GNU General Public License for more details.
|
| 13 |
//
|
| 14 |
// You should have received a copy of the GNU General Public License
|
| 15 |
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| 16 |
//
|
| 17 |
|
| 18 |
#include "db_sbx_common.hpp" |
| 19 |
#include "adf4350_regs.hpp" |
| 20 |
|
| 21 |
using namespace uhd; |
| 22 |
using namespace uhd::usrp; |
| 23 |
using namespace boost::assign; |
| 24 |
|
| 25 |
|
| 26 |
/***********************************************************************
|
| 27 |
* Register the SBX dboard (min freq, max freq, rx div2, tx div2)
|
| 28 |
**********************************************************************/
|
| 29 |
static dboard_base::sptr make_sbx(dboard_base::ctor_args_t args){
|
| 30 |
return dboard_base::sptr(new sbx_xcvr(args)); |
| 31 |
} |
| 32 |
|
| 33 |
UHD_STATIC_BLOCK(reg_sbx_dboards){
|
| 34 |
dboard_manager::register_dboard(0x0054, 0x0055, &make_sbx, "SBX"); |
| 35 |
dboard_manager::register_dboard(0x0065, 0x0064, &make_sbx, "SBX v4"); |
| 36 |
} |
| 37 |
|
| 38 |
|
| 39 |
/***********************************************************************
|
| 40 |
* Gain Handling
|
| 41 |
**********************************************************************/
|
| 42 |
static int rx_pga0_gain_to_iobits(double &gain){ |
| 43 |
//clip the input
|
| 44 |
gain = sbx_rx_gain_ranges["PGA0"].clip(gain);
|
| 45 |
|
| 46 |
//convert to attenuation and update iobits for atr
|
| 47 |
double attn = sbx_rx_gain_ranges["PGA0"].stop() - gain; |
| 48 |
|
| 49 |
//calculate the RX attenuation
|
| 50 |
int attn_code = int(floor(attn*2)); |
| 51 |
int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK;
|
| 52 |
|
| 53 |
UHD_LOGV(often) << boost::format( |
| 54 |
"SBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x"
|
| 55 |
) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK << std::endl; |
| 56 |
|
| 57 |
//the actual gain setting
|
| 58 |
gain = sbx_rx_gain_ranges["PGA0"].stop() - double(attn_code)/2; |
| 59 |
|
| 60 |
return iobits;
|
| 61 |
} |
| 62 |
|
| 63 |
static int tx_pga0_gain_to_iobits(double &gain){ |
| 64 |
//clip the input
|
| 65 |
gain = sbx_tx_gain_ranges["PGA0"].clip(gain);
|
| 66 |
|
| 67 |
//convert to attenuation and update iobits for atr
|
| 68 |
double attn = sbx_tx_gain_ranges["PGA0"].stop() - gain; |
| 69 |
|
| 70 |
//calculate the TX attenuation
|
| 71 |
int attn_code = int(floor(attn*2)); |
| 72 |
int iobits = ((~attn_code) << TX_ATTN_SHIFT) & TX_ATTN_MASK;
|
| 73 |
|
| 74 |
UHD_LOGV(often) << boost::format( |
| 75 |
"SBX TX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x"
|
| 76 |
) % attn % attn_code % (iobits & TX_ATTN_MASK) % TX_ATTN_MASK << std::endl; |
| 77 |
|
| 78 |
//the actual gain setting
|
| 79 |
gain = sbx_tx_gain_ranges["PGA0"].stop() - double(attn_code)/2; |
| 80 |
|
| 81 |
return iobits;
|
| 82 |
} |
| 83 |
|
| 84 |
double sbx_xcvr::set_tx_gain(double gain, const std::string &name){ |
| 85 |
assert_has(sbx_tx_gain_ranges.keys(), name, "sbx tx gain name");
|
| 86 |
if(name == "PGA0"){ |
| 87 |
tx_pga0_gain_to_iobits(gain); |
| 88 |
_tx_gains[name] = gain; |
| 89 |
|
| 90 |
//write the new gain to atr regs
|
| 91 |
update_atr(); |
| 92 |
} |
| 93 |
else UHD_THROW_INVALID_CODE_PATH();
|
| 94 |
return _tx_gains[name];
|
| 95 |
} |
| 96 |
|
| 97 |
double sbx_xcvr::set_rx_gain(double gain, const std::string &name){ |
| 98 |
assert_has(sbx_rx_gain_ranges.keys(), name, "sbx rx gain name");
|
| 99 |
if(name == "PGA0"){ |
| 100 |
rx_pga0_gain_to_iobits(gain); |
| 101 |
_rx_gains[name] = gain; |
| 102 |
|
| 103 |
//write the new gain to atr regs
|
| 104 |
update_atr(); |
| 105 |
} |
| 106 |
else UHD_THROW_INVALID_CODE_PATH();
|
| 107 |
return _rx_gains[name];
|
| 108 |
} |
| 109 |
|
| 110 |
|
| 111 |
/***********************************************************************
|
| 112 |
* Structors
|
| 113 |
**********************************************************************/
|
| 114 |
sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
|
| 115 |
switch(get_rx_id().to_uint16()) {
|
| 116 |
case 0x054: |
| 117 |
db_actual = sbx_versionx_sptr(new sbx_version3(this)); |
| 118 |
break;
|
| 119 |
case 0x065: |
| 120 |
db_actual = sbx_versionx_sptr(new sbx_version4(this)); |
| 121 |
break;
|
| 122 |
default:
|
| 123 |
/* We didn't recognize the version of the board... */
|
| 124 |
UHD_THROW_INVALID_CODE_PATH(); |
| 125 |
} |
| 126 |
|
| 127 |
////////////////////////////////////////////////////////////////////
|
| 128 |
// Register RX properties
|
| 129 |
////////////////////////////////////////////////////////////////////
|
| 130 |
this->get_rx_subtree()->create<std::string>("name").set("SBX RX"); |
| 131 |
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked") |
| 132 |
.publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_RX));
|
| 133 |
BOOST_FOREACH(const std::string &name, sbx_rx_gain_ranges.keys()){ |
| 134 |
this->get_rx_subtree()->create<double>("gains/"+name+"/value") |
| 135 |
.coerce(boost::bind(&sbx_xcvr::set_rx_gain, this, _1, name))
|
| 136 |
.set(sbx_rx_gain_ranges[name].start()); |
| 137 |
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range") |
| 138 |
.set(sbx_rx_gain_ranges[name]); |
| 139 |
} |
| 140 |
this->get_rx_subtree()->create<double>("freq/value") |
| 141 |
.coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
|
| 142 |
.set((sbx_freq_range.start() + sbx_freq_range.stop())/2.0); |
| 143 |
this->get_rx_subtree()->create<meta_range_t>("freq/range").set(sbx_freq_range); |
| 144 |
this->get_rx_subtree()->create<std::string>("antenna/value") |
| 145 |
.subscribe(boost::bind(&sbx_xcvr::set_rx_ant, this, _1))
|
| 146 |
.set("RX2");
|
| 147 |
this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options") |
| 148 |
.set(sbx_rx_antennas); |
| 149 |
this->get_rx_subtree()->create<std::string>("connection").set("IQ"); |
| 150 |
this->get_rx_subtree()->create<bool>("enabled").set(true); //always enabled |
| 151 |
this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); |
| 152 |
this->get_rx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided |
| 153 |
this->get_rx_subtree()->create<meta_range_t>("bandwidth/range") |
| 154 |
.set(freq_range_t(2*20.0e6, 2*20.0e6)); |
| 155 |
|
| 156 |
////////////////////////////////////////////////////////////////////
|
| 157 |
// Register TX properties
|
| 158 |
////////////////////////////////////////////////////////////////////
|
| 159 |
this->get_tx_subtree()->create<std::string>("name").set("SBX TX"); |
| 160 |
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked") |
| 161 |
.publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_TX));
|
| 162 |
BOOST_FOREACH(const std::string &name, sbx_tx_gain_ranges.keys()){ |
| 163 |
this->get_tx_subtree()->create<double>("gains/"+name+"/value") |
| 164 |
.coerce(boost::bind(&sbx_xcvr::set_tx_gain, this, _1, name))
|
| 165 |
.set(sbx_tx_gain_ranges[name].start()); |
| 166 |
this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range") |
| 167 |
.set(sbx_tx_gain_ranges[name]); |
| 168 |
} |
| 169 |
this->get_tx_subtree()->create<double>("freq/value") |
| 170 |
.coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
|
| 171 |
.set((sbx_freq_range.start() + sbx_freq_range.stop())/2.0); |
| 172 |
this->get_tx_subtree()->create<meta_range_t>("freq/range").set(sbx_freq_range); |
| 173 |
this->get_tx_subtree()->create<std::string>("antenna/value") |
| 174 |
.subscribe(boost::bind(&sbx_xcvr::set_tx_ant, this, _1))
|
| 175 |
.set(sbx_tx_antennas.at(0));
|
| 176 |
this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options") |
| 177 |
.set(sbx_tx_antennas); |
| 178 |
this->get_tx_subtree()->create<std::string>("connection").set("QI"); |
| 179 |
this->get_tx_subtree()->create<bool>("enabled").set(true); //always enabled |
| 180 |
this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); |
| 181 |
this->get_tx_subtree()->create<double>("bandwidth/value").set(2*20.0e6); //20MHz low-pass, we want complex double-sided |
| 182 |
this->get_tx_subtree()->create<meta_range_t>("bandwidth/range") |
| 183 |
.set(freq_range_t(2*20.0e6, 2*20.0e6)); |
| 184 |
|
| 185 |
//enable the clocks that we need
|
| 186 |
this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); |
| 187 |
this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); |
| 188 |
|
| 189 |
//set the gpio directions and atr controls (identically)
|
| 190 |
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
|
| 191 |
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
|
| 192 |
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
|
| 193 |
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
|
| 194 |
|
| 195 |
//flash LEDs
|
| 196 |
flash_leds(); |
| 197 |
|
| 198 |
UHD_LOGV(often) << boost::format( |
| 199 |
"SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x"
|
| 200 |
) % RXIO_MASK % TXIO_MASK << std::endl; |
| 201 |
} |
| 202 |
|
| 203 |
sbx_xcvr::~sbx_xcvr(void){
|
| 204 |
/* NOP */
|
| 205 |
} |
| 206 |
|
| 207 |
/***********************************************************************
|
| 208 |
* Antenna Handling
|
| 209 |
**********************************************************************/
|
| 210 |
void sbx_xcvr::update_atr(void){ |
| 211 |
//calculate atr pins
|
| 212 |
int rx_pga0_iobits = rx_pga0_gain_to_iobits(_rx_gains["PGA0"]); |
| 213 |
int tx_pga0_iobits = tx_pga0_gain_to_iobits(_tx_gains["PGA0"]); |
| 214 |
int rx_lo_lpf_en = (_rx_lo_freq == sbx_enable_rx_lo_filter.clip(_rx_lo_freq)) ? LO_LPF_EN : 0; |
| 215 |
int tx_lo_lpf_en = (_tx_lo_freq == sbx_enable_tx_lo_filter.clip(_tx_lo_freq)) ? LO_LPF_EN : 0; |
| 216 |
int rx_ld_led = get_locked(dboard_iface::UNIT_RX).to_bool() ? 0 : RX_LED_LD; |
| 217 |
int tx_ld_led = get_locked(dboard_iface::UNIT_TX).to_bool() ? 0 : TX_LED_LD; |
| 218 |
int rx_ant_led = _rx_ant == "TX/RX" ? RX_LED_RX1RX2 : 0; |
| 219 |
int tx_ant_led = _tx_ant == "TX/RX" ? 0 : TX_LED_TXRX; |
| 220 |
|
| 221 |
//setup the tx atr (this does not change with antenna)
|
| 222 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,
|
| 223 |
tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | ANT_XX | TX_MIXER_DIS); |
| 224 |
|
| 225 |
//setup the rx atr (this does not change with antenna)
|
| 226 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE,
|
| 227 |
rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP | ANT_XX | RX_MIXER_DIS); |
| 228 |
|
| 229 |
//set the RX atr regs that change with antenna setting
|
| 230 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY,
|
| 231 |
rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB | |
| 232 |
((_rx_ant != "RX2")? ANT_TXRX : ANT_RX2));
|
| 233 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY,
|
| 234 |
rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_DIS | |
| 235 |
((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2));
|
| 236 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX,
|
| 237 |
rx_pga0_iobits | rx_lo_lpf_en | rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB | |
| 238 |
((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2));
|
| 239 |
|
| 240 |
//set the TX atr regs that change with antenna setting
|
| 241 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,
|
| 242 |
tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_DIS | |
| 243 |
((_rx_ant != "RX2")? ANT_RX : ANT_TX));
|
| 244 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,
|
| 245 |
tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB | |
| 246 |
((_tx_ant == "CAL")? ANT_RX : ANT_TX));
|
| 247 |
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX,
|
| 248 |
tx_pga0_iobits | tx_lo_lpf_en | tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB | |
| 249 |
((_tx_ant == "CAL")? ANT_RX : ANT_TX));
|
| 250 |
} |
| 251 |
|
| 252 |
void sbx_xcvr::set_rx_ant(const std::string &ant){ |
| 253 |
//validate input
|
| 254 |
assert_has(sbx_rx_antennas, ant, "sbx rx antenna name");
|
| 255 |
|
| 256 |
//shadow the setting
|
| 257 |
_rx_ant = ant; |
| 258 |
|
| 259 |
//write the new antenna setting to atr regs
|
| 260 |
update_atr(); |
| 261 |
} |
| 262 |
|
| 263 |
void sbx_xcvr::set_tx_ant(const std::string &ant){ |
| 264 |
assert_has(sbx_tx_antennas, ant, "sbx tx antenna name");
|
| 265 |
|
| 266 |
//shadow the setting
|
| 267 |
_tx_ant = ant; |
| 268 |
|
| 269 |
//write the new antenna setting to atr regs
|
| 270 |
update_atr(); |
| 271 |
} |
| 272 |
|
| 273 |
/***********************************************************************
|
| 274 |
* Tuning
|
| 275 |
**********************************************************************/
|
| 276 |
void sbx_xcvr::set_rx_lo_freq(double freq){ |
| 277 |
_rx_lo_freq = db_actual->set_lo_freq(dboard_iface::UNIT_RX, freq); |
| 278 |
} |
| 279 |
|
| 280 |
void sbx_xcvr::set_tx_lo_freq(double freq){ |
| 281 |
_tx_lo_freq = db_actual->set_lo_freq(dboard_iface::UNIT_TX, freq); |
| 282 |
} |
| 283 |
|
| 284 |
double sbx_xcvr::set_lo_freq(dboard_iface::unit_t unit, double target_freq) { |
| 285 |
return db_actual->set_lo_freq(unit, target_freq);
|
| 286 |
} |
| 287 |
|
| 288 |
sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) {
|
| 289 |
const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; |
| 290 |
return sensor_value_t("LO", locked, "locked", "unlocked"); |
| 291 |
} |
| 292 |
|
| 293 |
|
| 294 |
void sbx_xcvr::flash_leds(void) { |
| 295 |
//Remove LED gpios from ATR control temporarily and set to outputs
|
| 296 |
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXIO_MASK);
|
| 297 |
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXIO_MASK);
|
| 298 |
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|RX_LED_IO));
|
| 299 |
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
|
| 300 |
|
| 301 |
/*
|
| 302 |
//flash All LEDs
|
| 303 |
for (int i = 0; i < 3; i++) {
|
| 304 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_IO, RX_LED_IO);
|
| 305 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_IO, TX_LED_IO);
|
| 306 |
|
| 307 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 308 |
|
| 309 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0, RX_LED_IO);
|
| 310 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, 0, TX_LED_IO);
|
| 311 |
|
| 312 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 313 |
}
|
| 314 |
*/
|
| 315 |
|
| 316 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_LD, TX_LED_IO);
|
| 317 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 318 |
|
| 319 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_TXRX|TX_LED_LD, TX_LED_IO);
|
| 320 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 321 |
|
| 322 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_LD, RX_LED_IO);
|
| 323 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 324 |
|
| 325 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_RX1RX2|RX_LED_LD, RX_LED_IO);
|
| 326 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 327 |
|
| 328 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_LD, RX_LED_IO);
|
| 329 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 330 |
|
| 331 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0, RX_LED_IO); |
| 332 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 333 |
|
| 334 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_LD, TX_LED_IO);
|
| 335 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 336 |
|
| 337 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, 0, TX_LED_IO); |
| 338 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 339 |
|
| 340 |
/*
|
| 341 |
//flash All LEDs
|
| 342 |
for (int i = 0; i < 3; i++) {
|
| 343 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0, RX_LED_IO);
|
| 344 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, 0, TX_LED_IO);
|
| 345 |
|
| 346 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 347 |
|
| 348 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_IO, RX_LED_IO);
|
| 349 |
this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_IO, TX_LED_IO);
|
| 350 |
|
| 351 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
| 352 |
}
|
| 353 |
*/
|
| 354 |
//Put LED gpios back in ATR control and update atr
|
| 355 |
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
|
| 356 |
this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
|
| 357 |
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
|
| 358 |
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
|
| 359 |
} |
| 360 |
|