From 457e94dd2be98dece8215b993d94a11af55cba96 Mon Sep 17 00:00:00 2001 From: michael-west Date: Wed, 25 Jan 2017 11:59:24 -0800 Subject: X300: Added code to handle case where older firmware was slow to release the claim causing discovery to fail --- host/lib/usrp/x300/x300_impl.cpp | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index d6e2a6fdc..028058a58 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -1478,13 +1478,32 @@ void x300_impl::claimer_loop(wb_iface::sptr iface) x300_impl::claim_status_t x300_impl::claim_status(wb_iface::sptr iface) { - //If timed out, then device is definitely unclaimed - if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) - return UNCLAIMED; + claim_status_t claim_status = CLAIMED_BY_OTHER; // Default to most restrictive + boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::seconds(1); + while (boost::get_system_time() < timeout_time) + { + //If timed out, then device is definitely unclaimed + if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0) + { + claim_status = UNCLAIMED; + break; + } - //otherwise check claim src to determine if another thread with the same src has claimed the device - uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); - return (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER); + //otherwise check claim src to determine if another thread with the same src has claimed the device + uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC)); + if (hash == 0) + { + // A non-zero claim status and an empty hash means the claim might + // be in the process of being released. This is possible because + // older firmware takes a long time to update the status. Wait and + // check status again. + boost::this_thread::sleep(boost::posix_time::milliseconds(5)); + continue; + } + claim_status = (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER); + break; + } + return claim_status; } void x300_impl::claim(wb_iface::sptr iface) -- cgit v1.2.3 From b99f94f65040363b25dc2db18b1d2b6a8575457f Mon Sep 17 00:00:00 2001 From: michael-west Date: Mon, 23 Jan 2017 16:32:27 -0800 Subject: X300: Fix issue with GPSDO sometimes not being recognized properly --- host/lib/usrp/x300/x300_fw_uart.cpp | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/x300/x300_fw_uart.cpp b/host/lib/usrp/x300/x300_fw_uart.cpp index 6e7425c4d..a2cbcc908 100644 --- a/host/lib/usrp/x300/x300_fw_uart.cpp +++ b/host/lib/usrp/x300/x300_fw_uart.cpp @@ -76,8 +76,9 @@ struct x300_uart_iface : uart_iface if (rxoffset == _last_device_rxoffset) return -1; + int ret = static_cast(_rxcache[((rxoffset)/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF); rxoffset++; - return static_cast(_rxcache[(rxoffset/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF); + return ret; } void update_cache(void) @@ -91,30 +92,42 @@ struct x300_uart_iface : uart_iface { // all the data is new - reload the entire cache for (uint32_t i = 0; i < poolsize; i++) + { _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i)); + } + + // set the head to the same character as the current device + // offset (tail) one loop earlier + rxoffset = device_rxoffset - (poolsize*4); + + // set the tail to the current device offset + _last_device_rxoffset = device_rxoffset; - // set rxoffset to the end of the first string - rxoffset = device_rxoffset - (poolsize*4) + 1; - while (static_cast((_rxcache[(rxoffset/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF)) != '\n') - ++rxoffset; + // the string at the head is a partial, so skip it + for (int c = getchar(); c != '\n' and c != -1; c = getchar()) {} - // clear the partial string in the buffer; + // clear the partial string in the buffer, if any _rxbuff.clear(); } else if (rxoffset == _last_device_rxoffset) { // new data was added - refresh the portion of the cache that was updated - for (uint32_t i = ((_last_device_rxoffset+1)/4) % poolsize; i != (((device_rxoffset)/4)+1) % poolsize; i = (i+1) % poolsize) + for (uint32_t i = (_last_device_rxoffset/4) % poolsize; + i != ((device_rxoffset/4)+1) % poolsize; + i = (i+1) % poolsize) { _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i)); } - } else { + + // set the tail to the current device offset + _last_device_rxoffset = device_rxoffset; + } + else + { // there is new data, but we aren't done with what we have - check back later break; } - _last_device_rxoffset = device_rxoffset; - // check again to see if anything changed while we were updating the cache device_rxoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX)); delta = device_rxoffset - rxoffset; -- cgit v1.2.3 From be4dda6d4666988fc8624bd336a22ee6d1a82f59 Mon Sep 17 00:00:00 2001 From: Derek Kozel Date: Wed, 25 Jan 2017 00:42:36 -0800 Subject: X300: Move property tree check to subscriber Command Time path in the daughterboard does not yet exist during X300 initialization, so check cannot be done while subscribing. --- host/lib/usrp/x300/x300_radio_ctrl_impl.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp index bb17eb2ec..0e11cb42c 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp @@ -126,8 +126,7 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl) // Bind the daughterboard command time to the motherboard level property //////////////////////////////////////////////////////////////// - if (_tree->exists(fs_path("time") / "cmd") and - _tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(i).db_fe_name / "time" / "cmd"))) { + if (_tree->exists(fs_path("time") / "cmd")) { _tree->access(fs_path("time") / "cmd") .add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i)); } @@ -180,9 +179,11 @@ double x300_radio_ctrl_impl::set_rate(double rate) void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t &time, const size_t chan) { - _tree->access( - fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd") - ).set(time); + if (_tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) { + _tree->access( + fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd") + ).set(time); + } } void x300_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan) -- cgit v1.2.3 From 92d3054d5917e5256a652c7f16a1bf0ee9859f9a Mon Sep 17 00:00:00 2001 From: Jonathon Pendlum Date: Wed, 25 Jan 2017 13:27:32 -0600 Subject: x300: Increase PCIe TX frame size to 8184 --- host/lib/usrp/x300/x300_impl.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 81d8cd3ba..133938daf 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -54,10 +54,7 @@ static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib //where an element is 8 bytes. For best throughput ensure that the data frame fits in these buffers. //Also ensure that the kernel has enough frames to hold buffered TX and RX data static const size_t X300_PCIE_RX_DATA_FRAME_SIZE = 8184; //bytes -//static const size_t X300_PCIE_TX_DATA_FRAME_SIZE = 8192; //bytes -// This is a temporary solution: We're throttling PCIe MTU to avoid -// underruns on Tx. Once we solve it on the FPGA side, need revert this commit. -static const size_t X300_PCIE_TX_DATA_FRAME_SIZE = 3000; //bytes +static const size_t X300_PCIE_TX_DATA_FRAME_SIZE = 8184; //bytes static const size_t X300_PCIE_DATA_NUM_FRAMES = 2048; static const size_t X300_PCIE_MSG_FRAME_SIZE = 256; //bytes static const size_t X300_PCIE_MSG_NUM_FRAMES = 64; -- cgit v1.2.3 From 7e11bd090058685c1477e4439e53eefe42979451 Mon Sep 17 00:00:00 2001 From: Jonathon Pendlum Date: Fri, 27 Jan 2017 11:35:36 -0600 Subject: device3: Reset sequence number in get_tx_streamer() --- host/lib/usrp/device3/device3_io_impl.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp index ea6bedb74..c1bfd1606 100644 --- a/host/lib/usrp/device3/device3_io_impl.cpp +++ b/host/lib/usrp/device3/device3_io_impl.cpp @@ -808,6 +808,7 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_) ) ); + blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_RX_FC, 0xc1ea12, block_port); blk_ctrl->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, xport.recv_sid.get_dst(), block_port); UHD_STREAMER_LOG() << "[TX Streamer] resp_in_dst_sid == " << boost::format("0x%04X") % xport.recv_sid.get_dst() << std::endl; -- cgit v1.2.3 From c613c7edb41de76a667e106c0b31684ac890da03 Mon Sep 17 00:00:00 2001 From: michael-west Date: Thu, 26 Jan 2017 12:53:36 -0800 Subject: GPS: Improvements to query_gpsdo_sensor - Reordered operations to make sure setting clock and time sources is first - Reduced delay waiting for ref lock - Added wait for GPSDO warm up - Made warning messages in gps_ctrl function into log messages to prevent unnecessary output --- host/lib/usrp/gps_ctrl.cpp | 10 ++-- host/utils/query_gpsdo_sensors.cpp | 99 ++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 47 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index 28f5a28cd..f4a42af34 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -92,7 +92,7 @@ private: sentences[which].get<2>() = true; } } catch(std::exception &e) { - UHD_MSG(warning) << "get_sentence: " << e.what(); + UHD_LOGV(often) << "get_sentence: " << e.what(); } if (not sentence.empty() or now > exit_time) @@ -134,7 +134,7 @@ private: } void update_cache() { - if(not gps_detected() or (_gps_type != GPS_TYPE_INTERNAL_GPSDO)) { + if(not gps_detected()) { return; } @@ -352,11 +352,11 @@ private: return gps_time; } catch(std::exception &e) { - UHD_MSG(warning) << "get_time: " << e.what(); + UHD_LOGV(often) << "get_time: " << e.what(); error_cnt++; } } - throw uhd::value_error("Timeout after no valid message found"); + throw uhd::value_error("get_time: Timeout after no valid message found"); return gps_time; //keep gcc from complaining } @@ -379,7 +379,7 @@ private: else return (get_token(reply, 6) != "0"); } catch(std::exception &e) { - UHD_MSG(warning) << "locked: " << e.what(); + UHD_LOGV(often) << "locked: " << e.what(); error_cnt++; } } diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp index 7420e62e9..6c2ec0bd1 100644 --- a/host/utils/query_gpsdo_sensors.cpp +++ b/host/utils/query_gpsdo_sensors.cpp @@ -120,67 +120,83 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ return EXIT_FAILURE; } - // Explicitly set time source to gpsdo - boost::this_thread::sleep(boost::posix_time::seconds(1)); + std::cout << "\nSetting the reference clock source to \"gpsdo\"...\n"; try { - usrp->set_time_source("gpsdo"); + usrp->set_clock_source("gpsdo"); } catch (uhd::value_error &e) { - std::cout << "could not set the time source to \"gpsdo\"; error was:" <set_time_source("external"); + try{ + usrp->set_clock_source("external"); } catch (uhd::value_error&) { std::cout << "\"external\" failed, too." << std::endl; } } - std::cout<< std::endl << "Time source is now " << usrp->get_time_source(0) << std::endl; + std::cout<< std::endl << "Clock source is now " << usrp->get_clock_source(0) << std::endl; - //Check for GPS lock - uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0); - if(not gps_locked.to_bool()) { - std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n"); - std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n"); + //Check for 10 MHz lock + if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { + uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0); + for (size_t i = 0; not ref_locked.to_bool() and i < 100; i++) { + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + ref_locked = usrp->get_mboard_sensor("ref_locked",0); + } + if(not ref_locked.to_bool()) { + std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n"); + std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n"); + return EXIT_FAILURE; + } else { + std::cout << boost::format("USRP Locked to GPSDO 10 MHz Reference.\n"); + } } else { - std::cout << boost::format("GPS Locked"); + std::cout << boost::format("ref_locked sensor not present on this board.\n"); } - std::cout << "\nSetting the reference clock source to \"gpsdo\"...\n"; + // Explicitly set time source to gpsdo try { - usrp->set_clock_source("gpsdo"); + usrp->set_time_source("gpsdo"); } catch (uhd::value_error &e) { - std::cout << "could not set the clock source to \"gpsdo\"; error was:" <set_clock_source("external"); + try { + usrp->set_time_source("external"); } catch (uhd::value_error&) { std::cout << "\"external\" failed, too." << std::endl; } } - std::cout<< std::endl << "Clock source is now " << usrp->get_clock_source(0) << std::endl; + std::cout << std::endl << "Time source is now " << usrp->get_time_source(0) << std::endl; print_notes(); + // The TCXO has a long warm up time, so wait up to 30 seconds for sensor data to show up + std::cout << "Waiting for the GPSDO to warm up..." << std::endl; + for (size_t i = 0; i < 300; i++) { + try { + usrp->get_mboard_sensor("gps_locked",0); + break; + } catch (std::exception &) {} + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + } + try { + usrp->get_mboard_sensor("gps_locked",0); + } catch (std::exception &) { + std::cout << "No response from GPSDO in 30 seconds" << std::endl; + return EXIT_FAILURE; + } + std::cout << "The GPSDO is warmed up and talking." << std::endl; - //Check for 10 MHz lock - if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { - uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("ref_locked",0); - if(not gps_locked.to_bool()) { - std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n"); - std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n"); - std::cout << boost::format("Locking the internal reference to the GPSDO might take a second to reach stability. Retrying in 10 s...\n\n"); - boost::this_thread::sleep(boost::posix_time::seconds(10)); - } - if(usrp->get_mboard_sensor("ref_locked",0).to_bool()) { - std::cout << boost::format("USRP Locked to GPSDO 10 MHz Reference.\n"); - } + //Check for GPS lock + uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0);; + if(not gps_locked.to_bool()) { + std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n"); + std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n"); } else { - std::cout << boost::format("ref_locked sensor not present on this board.\n"); + std::cout << boost::format("GPS Locked"); } //Check PPS and compare UHD device time to GPS time - boost::this_thread::sleep(boost::posix_time::seconds(1)); uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time"); uhd::time_spec_t last_pps_time = usrp->get_time_last_pps(); @@ -189,13 +205,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ long long pps_seconds = last_pps_time.to_ticks(1.0); if(pps_seconds != gps_seconds) { - std::cout << boost::format("\nGPS and UHD Device time are NOT aligned;\nlast_pps: %ld vs gps: %ld. Trying to set the device time to GPS time...") - % pps_seconds % gps_seconds + std::cout << "\nTrying to align the device time to GPS time..." << std::endl; - //full next after next second - uhd::time_spec_t next_pps_time(gps_seconds + 2.0); - //instruct the USRP to wait for the next PPS edge, then set the new time on the following PPS - usrp->set_time_unknown_pps(next_pps_time); + //set the device time to the GPS time + //getting the GPS time returns just after the PPS edge, so just add a + //second and set the device time at the next PPS edge + usrp->set_time_next_pps(uhd::time_spec_t(gps_time.to_int() + 1.0)); //allow some time to make sure the PPS has come… boost::this_thread::sleep(boost::posix_time::milliseconds(1100)); //…then ask @@ -203,14 +218,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ pps_seconds = usrp->get_time_last_pps().to_ticks(1.0); } - std::cout << boost::format("last_pps: %ld vs gps: %ld.") - % pps_seconds % gps_seconds - << std::endl; if (pps_seconds == gps_seconds) { std::cout << boost::format("GPS and UHD Device time are aligned.\n"); } else { std::cout << boost::format("Could not align UHD Device time to GPS time. Giving up.\n"); } + std::cout << boost::format("last_pps: %ld vs gps: %ld.") + % pps_seconds % gps_seconds + << std::endl; //print NMEA strings try { -- cgit v1.2.3 From 75e6ae59b3f4832372c08d7da390c5fdcc283067 Mon Sep 17 00:00:00 2001 From: Derek Kozel Date: Tue, 1 Nov 2016 10:55:10 -0700 Subject: Moved default register values into ic_reg_map --- host/lib/ic_reg_maps/gen_adf5355_regs.py | 8 ++--- host/lib/usrp/common/adf5355.cpp | 45 +++++++++-------------------- host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp | 2 ++ 3 files changed, 19 insertions(+), 36 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/ic_reg_maps/gen_adf5355_regs.py b/host/lib/ic_reg_maps/gen_adf5355_regs.py index 9644f2e53..a69f126cc 100755 --- a/host/lib/ic_reg_maps/gen_adf5355_regs.py +++ b/host/lib/ic_reg_maps/gen_adf5355_regs.py @@ -26,7 +26,7 @@ REGS_TMPL="""\ ######################################################################## int_16_bit 0[4:19] 0 prescaler 0[20] 0 4_5, 8_9 -autocal_en 0[21] 0 disabled, enabled +autocal_en 0[21] 1 disabled, enabled reg0_reserved0 0[22:31] 0x000 ######################################################################## ## address 1 @@ -53,13 +53,13 @@ counter_reset 4[4] 0 disabled, enabled cp_three_state 4[5] 0 disabled, enabled power_down 4[6] 0 disabled, enabled pd_polarity 4[7] 1 negative, positive -mux_logic 4[8] 0 1_8V, 3_3V +mux_logic 4[8] 1 1_8V, 3_3V ref_mode 4[9] 0 single, diff <% current_setting_enums = ', '.join(map(lambda x: '_'.join(("%0.2fma"%(round(x*31.27 + 31.27)/100)).split('.')), range(0,16))) %>\ charge_pump_current 4[10:13] 0 ${current_setting_enums} double_buff_div 4[14] 0 disabled, enabled r_counter_10_bit 4[15:24] 0 -reference_divide_by_2 4[25] 1 disabled, enabled +reference_divide_by_2 4[25] 0 disabled, enabled reference_doubler 4[26] 0 disabled, enabled muxout 4[27:29] 1 3state, dvdd, dgnd, rdiv, ndiv, analog_ld, dld, reserved reg4_reserved0 4[30:31] 0 @@ -91,7 +91,7 @@ frac_n_ld_precision 7[5:6] 0 5ns, 6ns, 8ns, 12ns loss_of_lock_mode 7[7] 0 disabled, enabled ld_cyc_count 7[8:9] 0 1024, 2048, 4096, 8192 reg7_reserved0 7[10:24] 0x0 -le_sync 7[25] 0 disabled, le_synced_to_refin +le_sync 7[25] 1 disabled, le_synced_to_refin reg7_reserved1 7[26:31] 0x4 ######################################################################## ## address 8 diff --git a/host/lib/usrp/common/adf5355.cpp b/host/lib/usrp/common/adf5355.cpp index ee9d1d1d9..e3fd66bc2 100644 --- a/host/lib/usrp/common/adf5355.cpp +++ b/host/lib/usrp/common/adf5355.cpp @@ -62,43 +62,14 @@ public: _pfd_freq(0.0), _fb_after_divider(false) { - _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED; - _regs.cp_three_state = adf5355_regs_t::CP_THREE_STATE_DISABLED; - _regs.power_down = adf5355_regs_t::POWER_DOWN_DISABLED; - _regs.pd_polarity = adf5355_regs_t::PD_POLARITY_POSITIVE; - _regs.mux_logic = adf5355_regs_t::MUX_LOGIC_3_3V; - _regs.ref_mode = adf5355_regs_t::REF_MODE_SINGLE; - _regs.muxout = adf5355_regs_t::MUXOUT_DLD; - _regs.double_buff_div = adf5355_regs_t::DOUBLE_BUFF_DIV_DISABLED; - - _regs.rf_out_a_enabled = adf5355_regs_t::RF_OUT_A_ENABLED_ENABLED; - _regs.rf_out_b_enabled = adf5355_regs_t::RF_OUT_B_ENABLED_DISABLED; - _regs.mute_till_lock_detect = adf5355_regs_t::MUTE_TILL_LOCK_DETECT_MUTE_DISABLED; - _regs.ld_mode = adf5355_regs_t::LD_MODE_FRAC_N; - _regs.frac_n_ld_precision = adf5355_regs_t::FRAC_N_LD_PRECISION_5NS; - _regs.ld_cyc_count = adf5355_regs_t::LD_CYC_COUNT_1024; - _regs.le_sync = adf5355_regs_t::LE_SYNC_LE_SYNCED_TO_REFIN; - _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; - _regs.reference_divide_by_2 = adf5355_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; - _regs.reference_doubler = adf5355_regs_t::REFERENCE_DOUBLER_DISABLED; - _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED; - _regs.prescaler = adf5355_regs_t::PRESCALER_4_5; + // TODO This is a hardware specific value, but can be made the default in the ic_reg_map _regs.charge_pump_current = adf5355_regs_t::CHARGE_PUMP_CURRENT_0_94MA; - _regs.gated_bleed = adf5355_regs_t::GATED_BLEED_DISABLED; - _regs.negative_bleed = adf5355_regs_t::NEGATIVE_BLEED_ENABLED; - _regs.feedback_select = adf5355_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; - _regs.output_power = adf5355_regs_t::OUTPUT_POWER_5DBM; + // TODO cleanup these magic numbers _regs.cp_bleed_current = 2; _regs.r_counter_10_bit = 8; - - _regs.ld_cyc_count = adf5355_regs_t::LD_CYC_COUNT_1024; - _regs.loss_of_lock_mode = adf5355_regs_t::LOSS_OF_LOCK_MODE_DISABLED; - _regs.frac_n_ld_precision = adf5355_regs_t::FRAC_N_LD_PRECISION_5NS; - _regs.ld_mode = adf5355_regs_t::LD_MODE_FRAC_N; - _regs.vco_band_div = 3; _regs.timeout = 11; _regs.auto_level_timeout = 30; @@ -108,6 +79,14 @@ public: _regs.adc_conversion = adf5355_regs_t::ADC_CONVERSION_ENABLED; _regs.adc_enable = adf5355_regs_t::ADC_ENABLE_ENABLED; + + // TODO Needs to be enabled for phase resync + _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; + + // TODO Default should be divided, but there seems to be a bug preventing that. Needs rechecking + _regs.feedback_select = adf5355_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; + + // TODO 0 is an invalid value for this field. Setting to 1 seemed to break phase sync, needs retesting. _regs.phase_resync_clk_div = 0; } @@ -193,7 +172,9 @@ public: //----------------------------------------------------------- //Phase resync - _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; // Disabled during development + // TODO Renable here, in initialization, or through separate set_phase_resync(bool enable) function + _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; + _regs.phase_adjust = adf5355_regs_t::PHASE_ADJUST_DISABLED; _regs.sd_load_reset = adf5355_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE; _regs.phase_resync_clk_div = static_cast( diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp index dfbea9917..346f39589 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp @@ -106,6 +106,8 @@ public: _config_lo2_route(i==0?LO_CONFIG_CH1:LO_CONFIG_CH2); _lo1_iface[i]->set_output_power(adf5355_iface::OUTPUT_POWER_5DBM); _lo1_iface[i]->set_reference_freq(TWINRX_DESIRED_REFERENCE_FREQ); + // Divided feedback did not appear to be correctly implemented during bringup. Necessary for phase resync +// _lo1_iface[i]->set_feedback_select(adf5355_iface::FB_SEL_DIVIDED); _lo1_iface[i]->set_muxout_mode(adf5355_iface::MUXOUT_DLD); _lo1_iface[i]->set_frequency(3e9, 1.0e3); _lo2_iface[i]->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED); -- cgit v1.2.3