From 6652eb4a033b38bd952563f3544eb11e98f27327 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Wed, 31 Jan 2018 20:20:14 +0100 Subject: uhd: Move internal headers to uhdlib/ To avoid the proliferation of additional include directories and multiple ways of including project-local headers, we now default to moving all headers that are used across UHD into the uhdlib/ subdirectory. Some #include statements were also reordered as they were modified for closer compliance with the coding guidelines. Internal cpp source files should now include files like this: #include Reviewed-by: Ashish Chaudhari --- host/lib/experts/CMakeLists.txt | 2 - host/lib/experts/expert_container.cpp | 2 +- host/lib/experts/expert_container.hpp | 192 ----- host/lib/experts/expert_factory.cpp | 2 +- host/lib/experts/expert_factory.hpp | 327 ------- host/lib/experts/expert_nodes.hpp | 472 ----------- .../include/uhdlib/experts/expert_container.hpp | 192 +++++ host/lib/include/uhdlib/experts/expert_factory.hpp | 327 +++++++ host/lib/include/uhdlib/experts/expert_nodes.hpp | 472 +++++++++++ host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp | 46 + host/lib/include/uhdlib/rfnoc/graph_impl.hpp | 80 ++ host/lib/include/uhdlib/rfnoc/legacy_compat.hpp | 49 ++ host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp | 247 ++++++ host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp | 41 + .../include/uhdlib/rfnoc/rx_stream_terminator.hpp | 79 ++ .../include/uhdlib/rfnoc/tx_stream_terminator.hpp | 80 ++ host/lib/include/uhdlib/rfnoc/utils.hpp | 67 ++ host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp | 60 ++ host/lib/include/uhdlib/rfnoc/xports.hpp | 29 + .../lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp | 161 ++++ .../include/uhdlib/usrp/common/ad936x_manager.hpp | 122 +++ .../include/uhdlib/usrp/common/adf4001_ctrl.hpp | 131 +++ host/lib/include/uhdlib/usrp/common/adf435x.hpp | 422 ++++++++++ host/lib/include/uhdlib/usrp/common/adf535x.hpp | 477 +++++++++++ .../uhdlib/usrp/common/apply_corrections.hpp | 43 + .../uhdlib/usrp/common/async_packet_handler.hpp | 74 ++ .../uhdlib/usrp/common/fifo_ctrl_excelsior.hpp | 51 ++ host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp | 138 +++ host/lib/include/uhdlib/usrp/common/max287x.hpp | 935 +++++++++++++++++++++ .../uhdlib/usrp/common/recv_packet_demuxer.hpp | 33 + .../usrp/common/recv_packet_demuxer_3000.hpp | 145 ++++ .../uhdlib/usrp/common/validate_subdev_spec.hpp | 28 + .../uhdlib/usrp/cores/dma_fifo_core_3000.hpp | 76 ++ .../include/uhdlib/usrp/cores/dsp_core_utils.hpp | 23 + .../include/uhdlib/usrp/cores/gpio_atr_3000.hpp | 178 ++++ .../include/uhdlib/usrp/cores/gpio_core_200.hpp | 77 ++ .../uhdlib/usrp/cores/i2c_core_100_wb32.hpp | 29 + .../lib/include/uhdlib/usrp/cores/i2c_core_200.hpp | 27 + .../uhdlib/usrp/cores/radio_ctrl_core_3000.hpp | 54 ++ .../include/uhdlib/usrp/cores/rx_dsp_core_200.hpp | 59 ++ .../include/uhdlib/usrp/cores/rx_dsp_core_3000.hpp | 58 ++ .../uhdlib/usrp/cores/rx_frontend_core_200.hpp | 43 + .../uhdlib/usrp/cores/rx_frontend_core_3000.hpp | 59 ++ .../uhdlib/usrp/cores/rx_vita_core_3000.hpp | 51 ++ .../include/uhdlib/usrp/cores/spi_core_3000.hpp | 38 + .../include/uhdlib/usrp/cores/time64_core_200.hpp | 55 ++ .../include/uhdlib/usrp/cores/time_core_3000.hpp | 52 ++ .../include/uhdlib/usrp/cores/tx_dsp_core_200.hpp | 51 ++ .../include/uhdlib/usrp/cores/tx_dsp_core_3000.hpp | 52 ++ .../uhdlib/usrp/cores/tx_frontend_core_200.hpp | 40 + .../uhdlib/usrp/cores/tx_vita_core_3000.hpp | 51 ++ .../uhdlib/usrp/cores/user_settings_core_200.hpp | 28 + .../uhdlib/usrp/cores/user_settings_core_3000.hpp | 25 + host/lib/include/uhdlib/utils/eeprom_utils.hpp | 20 + host/lib/include/uhdlib/utils/ihex.hpp | 69 ++ host/lib/include/uhdlib/utils/rpc.hpp | 191 +++++ host/lib/rfnoc/CMakeLists.txt | 2 - host/lib/rfnoc/block_ctrl_base.cpp | 2 +- host/lib/rfnoc/ctrl_iface.cpp | 3 +- host/lib/rfnoc/ctrl_iface.hpp | 46 - host/lib/rfnoc/ddc_block_ctrl_impl.cpp | 2 +- host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp | 4 +- host/lib/rfnoc/duc_block_ctrl_impl.cpp | 2 +- host/lib/rfnoc/graph_impl.cpp | 2 +- host/lib/rfnoc/graph_impl.hpp | 80 -- host/lib/rfnoc/legacy_compat.cpp | 3 +- host/lib/rfnoc/legacy_compat.hpp | 49 -- host/lib/rfnoc/radio_ctrl_impl.cpp | 4 +- host/lib/rfnoc/radio_ctrl_impl.hpp | 247 ------ host/lib/rfnoc/rpc_block_ctrl.hpp | 40 - host/lib/rfnoc/rx_stream_terminator.cpp | 4 +- host/lib/rfnoc/rx_stream_terminator.hpp | 79 -- host/lib/rfnoc/sink_block_ctrl_base.cpp | 2 +- host/lib/rfnoc/sink_node_ctrl.cpp | 2 +- host/lib/rfnoc/source_block_ctrl_base.cpp | 2 +- host/lib/rfnoc/source_node_ctrl.cpp | 2 +- host/lib/rfnoc/tx_stream_terminator.cpp | 4 +- host/lib/rfnoc/tx_stream_terminator.hpp | 80 -- host/lib/rfnoc/utils.hpp | 67 -- host/lib/rfnoc/wb_iface_adapter.cpp | 2 +- host/lib/rfnoc/wb_iface_adapter.hpp | 60 -- host/lib/rfnoc/xports.hpp | 29 - host/lib/transport/super_recv_packet_handler.hpp | 2 +- host/lib/transport/super_send_packet_handler.hpp | 2 +- host/lib/usrp/b100/b100_impl.cpp | 2 +- host/lib/usrp/b100/b100_impl.hpp | 20 +- host/lib/usrp/b100/dboard_iface.cpp | 5 +- host/lib/usrp/b100/io_impl.cpp | 8 +- host/lib/usrp/b100/mb_eeprom.cpp | 2 +- host/lib/usrp/b200/b200_cores.hpp | 4 +- host/lib/usrp/b200/b200_iface.cpp | 8 +- host/lib/usrp/b200/b200_iface.hpp | 4 +- host/lib/usrp/b200/b200_impl.hpp | 23 +- host/lib/usrp/b200/b200_io_impl.cpp | 4 +- host/lib/usrp/b200/b200_mb_eeprom.cpp | 2 +- host/lib/usrp/common/CMakeLists.txt | 1 - host/lib/usrp/common/ad9361_ctrl.cpp | 4 +- host/lib/usrp/common/ad9361_ctrl.hpp | 161 ---- host/lib/usrp/common/ad936x_manager.cpp | 2 +- host/lib/usrp/common/ad936x_manager.hpp | 122 --- host/lib/usrp/common/adf4001_ctrl.cpp | 4 +- host/lib/usrp/common/adf4001_ctrl.hpp | 131 --- host/lib/usrp/common/adf435x.cpp | 2 +- host/lib/usrp/common/adf435x.hpp | 422 ---------- host/lib/usrp/common/adf535x.cpp | 2 +- host/lib/usrp/common/adf535x.hpp | 477 ----------- host/lib/usrp/common/apply_corrections.cpp | 2 +- host/lib/usrp/common/apply_corrections.hpp | 43 - host/lib/usrp/common/async_packet_handler.hpp | 74 -- host/lib/usrp/common/fifo_ctrl_excelsior.cpp | 4 +- host/lib/usrp/common/fifo_ctrl_excelsior.hpp | 51 -- host/lib/usrp/common/fx2_ctrl.cpp | 2 +- host/lib/usrp/common/fx2_ctrl.hpp | 138 --- host/lib/usrp/common/lmk04828.cpp | 86 -- host/lib/usrp/common/lmk04828.hpp | 56 -- host/lib/usrp/common/max287x.hpp | 935 --------------------- host/lib/usrp/common/recv_packet_demuxer.cpp | 5 +- host/lib/usrp/common/recv_packet_demuxer.hpp | 33 - host/lib/usrp/common/recv_packet_demuxer_3000.hpp | 145 ---- host/lib/usrp/common/validate_subdev_spec.cpp | 2 +- host/lib/usrp/common/validate_subdev_spec.hpp | 28 - host/lib/usrp/cores/CMakeLists.txt | 3 - host/lib/usrp/cores/dma_fifo_core_3000.cpp | 5 +- host/lib/usrp/cores/dma_fifo_core_3000.hpp | 76 -- host/lib/usrp/cores/dsp_core_utils.cpp | 2 +- host/lib/usrp/cores/dsp_core_utils.hpp | 23 - host/lib/usrp/cores/gpio_atr_3000.cpp | 2 +- host/lib/usrp/cores/gpio_atr_3000.hpp | 178 ---- host/lib/usrp/cores/gpio_core_200.cpp | 2 +- host/lib/usrp/cores/gpio_core_200.hpp | 77 -- host/lib/usrp/cores/i2c_core_100_wb32.cpp | 2 +- host/lib/usrp/cores/i2c_core_100_wb32.hpp | 29 - host/lib/usrp/cores/i2c_core_200.cpp | 2 +- host/lib/usrp/cores/i2c_core_200.hpp | 27 - host/lib/usrp/cores/radio_ctrl_core_3000.cpp | 4 +- host/lib/usrp/cores/radio_ctrl_core_3000.hpp | 54 -- host/lib/usrp/cores/rx_dsp_core_200.cpp | 4 +- host/lib/usrp/cores/rx_dsp_core_200.hpp | 59 -- host/lib/usrp/cores/rx_dsp_core_3000.cpp | 4 +- host/lib/usrp/cores/rx_dsp_core_3000.hpp | 58 -- host/lib/usrp/cores/rx_frontend_core_200.cpp | 2 +- host/lib/usrp/cores/rx_frontend_core_200.hpp | 43 - host/lib/usrp/cores/rx_frontend_core_3000.cpp | 6 +- host/lib/usrp/cores/rx_frontend_core_3000.hpp | 59 -- host/lib/usrp/cores/rx_vita_core_3000.cpp | 2 +- host/lib/usrp/cores/rx_vita_core_3000.hpp | 51 -- host/lib/usrp/cores/spi_core_3000.cpp | 2 +- host/lib/usrp/cores/spi_core_3000.hpp | 38 - host/lib/usrp/cores/time64_core_200.cpp | 2 +- host/lib/usrp/cores/time64_core_200.hpp | 55 -- host/lib/usrp/cores/time_core_3000.cpp | 2 +- host/lib/usrp/cores/time_core_3000.hpp | 52 -- host/lib/usrp/cores/tx_dsp_core_200.cpp | 4 +- host/lib/usrp/cores/tx_dsp_core_200.hpp | 51 -- host/lib/usrp/cores/tx_dsp_core_3000.cpp | 4 +- host/lib/usrp/cores/tx_dsp_core_3000.hpp | 52 -- host/lib/usrp/cores/tx_frontend_core_200.cpp | 2 +- host/lib/usrp/cores/tx_frontend_core_200.hpp | 40 - host/lib/usrp/cores/tx_vita_core_3000.cpp | 2 +- host/lib/usrp/cores/tx_vita_core_3000.hpp | 51 -- host/lib/usrp/cores/user_settings_core_200.cpp | 2 +- host/lib/usrp/cores/user_settings_core_200.hpp | 28 - host/lib/usrp/cores/user_settings_core_3000.cpp | 2 +- host/lib/usrp/cores/user_settings_core_3000.hpp | 25 - host/lib/usrp/dboard/db_sbx_common.hpp | 4 +- host/lib/usrp/dboard/db_twinrx.cpp | 3 +- host/lib/usrp/dboard/db_ubx.cpp | 4 +- host/lib/usrp/dboard/db_wbx_common.hpp | 2 +- .../usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp | 4 +- .../dboard/magnesium/magnesium_ad9371_iface.hpp | 2 +- .../dboard/magnesium/magnesium_radio_ctrl_impl.hpp | 8 +- .../dboard/magnesium/magnesium_radio_ctrl_init.cpp | 2 +- host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp | 4 +- host/lib/usrp/dboard/twinrx/twinrx_experts.hpp | 2 +- host/lib/usrp/dboard/twinrx/twinrx_io.hpp | 2 +- host/lib/usrp/device3/device3_impl.cpp | 4 +- host/lib/usrp/device3/device3_impl.hpp | 2 +- host/lib/usrp/device3/device3_io_impl.cpp | 7 +- host/lib/usrp/e300/e300_impl.hpp | 22 +- host/lib/usrp/e300/e300_io_impl.cpp | 4 +- host/lib/usrp/e300/e300_network.cpp | 4 +- host/lib/usrp/e300/e300_remote_codec_ctrl.hpp | 2 +- host/lib/usrp/mpmd/mpmd_impl.cpp | 9 +- host/lib/usrp/mpmd/mpmd_impl.hpp | 2 +- host/lib/usrp/multi_usrp.cpp | 2 +- host/lib/usrp/n230/n230_clk_pps_ctrl.hpp | 8 +- host/lib/usrp/n230/n230_cores.hpp | 4 +- host/lib/usrp/n230/n230_frontend_ctrl.hpp | 8 +- host/lib/usrp/n230/n230_impl.cpp | 15 +- host/lib/usrp/n230/n230_impl.hpp | 2 +- host/lib/usrp/n230/n230_resource_manager.hpp | 37 +- host/lib/usrp/n230/n230_stream_manager.cpp | 4 +- host/lib/usrp/n230/n230_stream_manager.hpp | 9 +- host/lib/usrp/usrp1/io_impl.cpp | 6 +- host/lib/usrp/usrp1/mb_eeprom.cpp | 2 +- host/lib/usrp/usrp1/usrp1_calc_mux.hpp | 1 + host/lib/usrp/usrp1/usrp1_iface.hpp | 2 +- host/lib/usrp/usrp2/dboard_iface.cpp | 8 +- host/lib/usrp/usrp2/io_impl.cpp | 4 +- host/lib/usrp/usrp2/mb_eeprom.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 18 +- host/lib/usrp/x300/x300_dboard_iface.hpp | 10 +- host/lib/usrp/x300/x300_impl.cpp | 15 +- host/lib/usrp/x300/x300_impl.hpp | 18 +- host/lib/usrp/x300/x300_io_impl.cpp | 4 +- host/lib/usrp/x300/x300_mb_eeprom.cpp | 2 +- host/lib/usrp/x300/x300_radio_ctrl_impl.cpp | 7 +- host/lib/usrp/x300/x300_radio_ctrl_impl.hpp | 8 +- .../octoclock/octoclock_image_loader.cpp | 4 +- host/lib/utils/CMakeLists.txt | 2 - host/lib/utils/eeprom_utils.cpp | 2 +- host/lib/utils/eeprom_utils.hpp | 20 - host/lib/utils/ihex.cpp | 2 +- host/lib/utils/ihex.hpp | 69 -- host/lib/utils/rpc.hpp | 191 ----- host/tests/expert_test.cpp | 4 +- host/utils/CMakeLists.txt | 1 + 218 files changed, 6203 insertions(+), 6340 deletions(-) delete mode 100644 host/lib/experts/expert_container.hpp delete mode 100644 host/lib/experts/expert_factory.hpp delete mode 100644 host/lib/experts/expert_nodes.hpp create mode 100644 host/lib/include/uhdlib/experts/expert_container.hpp create mode 100644 host/lib/include/uhdlib/experts/expert_factory.hpp create mode 100644 host/lib/include/uhdlib/experts/expert_nodes.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/graph_impl.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/legacy_compat.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/utils.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp create mode 100644 host/lib/include/uhdlib/rfnoc/xports.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/adf435x.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/adf535x.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/apply_corrections.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/fifo_ctrl_excelsior.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/max287x.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/dma_fifo_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/gpio_atr_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/rx_dsp_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/tx_dsp_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp create mode 100644 host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp create mode 100644 host/lib/include/uhdlib/utils/eeprom_utils.hpp create mode 100644 host/lib/include/uhdlib/utils/ihex.hpp create mode 100644 host/lib/include/uhdlib/utils/rpc.hpp delete mode 100644 host/lib/rfnoc/ctrl_iface.hpp delete mode 100644 host/lib/rfnoc/graph_impl.hpp delete mode 100644 host/lib/rfnoc/legacy_compat.hpp delete mode 100644 host/lib/rfnoc/radio_ctrl_impl.hpp delete mode 100644 host/lib/rfnoc/rpc_block_ctrl.hpp delete mode 100644 host/lib/rfnoc/rx_stream_terminator.hpp delete mode 100644 host/lib/rfnoc/tx_stream_terminator.hpp delete mode 100644 host/lib/rfnoc/utils.hpp delete mode 100644 host/lib/rfnoc/wb_iface_adapter.hpp delete mode 100644 host/lib/rfnoc/xports.hpp delete mode 100644 host/lib/usrp/common/ad9361_ctrl.hpp delete mode 100644 host/lib/usrp/common/ad936x_manager.hpp delete mode 100644 host/lib/usrp/common/adf4001_ctrl.hpp delete mode 100644 host/lib/usrp/common/adf435x.hpp delete mode 100644 host/lib/usrp/common/adf535x.hpp delete mode 100644 host/lib/usrp/common/apply_corrections.hpp delete mode 100644 host/lib/usrp/common/async_packet_handler.hpp delete mode 100644 host/lib/usrp/common/fifo_ctrl_excelsior.hpp delete mode 100644 host/lib/usrp/common/fx2_ctrl.hpp delete mode 100644 host/lib/usrp/common/lmk04828.cpp delete mode 100644 host/lib/usrp/common/lmk04828.hpp delete mode 100644 host/lib/usrp/common/max287x.hpp delete mode 100644 host/lib/usrp/common/recv_packet_demuxer.hpp delete mode 100644 host/lib/usrp/common/recv_packet_demuxer_3000.hpp delete mode 100644 host/lib/usrp/common/validate_subdev_spec.hpp delete mode 100644 host/lib/usrp/cores/dma_fifo_core_3000.hpp delete mode 100644 host/lib/usrp/cores/dsp_core_utils.hpp delete mode 100644 host/lib/usrp/cores/gpio_atr_3000.hpp delete mode 100644 host/lib/usrp/cores/gpio_core_200.hpp delete mode 100644 host/lib/usrp/cores/i2c_core_100_wb32.hpp delete mode 100644 host/lib/usrp/cores/i2c_core_200.hpp delete mode 100644 host/lib/usrp/cores/radio_ctrl_core_3000.hpp delete mode 100644 host/lib/usrp/cores/rx_dsp_core_200.hpp delete mode 100644 host/lib/usrp/cores/rx_dsp_core_3000.hpp delete mode 100644 host/lib/usrp/cores/rx_frontend_core_200.hpp delete mode 100644 host/lib/usrp/cores/rx_frontend_core_3000.hpp delete mode 100644 host/lib/usrp/cores/rx_vita_core_3000.hpp delete mode 100644 host/lib/usrp/cores/spi_core_3000.hpp delete mode 100644 host/lib/usrp/cores/time64_core_200.hpp delete mode 100644 host/lib/usrp/cores/time_core_3000.hpp delete mode 100644 host/lib/usrp/cores/tx_dsp_core_200.hpp delete mode 100644 host/lib/usrp/cores/tx_dsp_core_3000.hpp delete mode 100644 host/lib/usrp/cores/tx_frontend_core_200.hpp delete mode 100644 host/lib/usrp/cores/tx_vita_core_3000.hpp delete mode 100644 host/lib/usrp/cores/user_settings_core_200.hpp delete mode 100644 host/lib/usrp/cores/user_settings_core_3000.hpp delete mode 100644 host/lib/utils/eeprom_utils.hpp delete mode 100644 host/lib/utils/ihex.hpp delete mode 100644 host/lib/utils/rpc.hpp (limited to 'host') diff --git a/host/lib/experts/CMakeLists.txt b/host/lib/experts/CMakeLists.txt index 2c72721a4..3101a7330 100644 --- a/host/lib/experts/CMakeLists.txt +++ b/host/lib/experts/CMakeLists.txt @@ -8,8 +8,6 @@ ######################################################################## # This file included, use CMake directory variables ######################################################################## -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/expert_container.cpp ${CMAKE_CURRENT_SOURCE_DIR}/expert_factory.cpp diff --git a/host/lib/experts/expert_container.cpp b/host/lib/experts/expert_container.cpp index 8d01337f8..1cdc7841b 100644 --- a/host/lib/experts/expert_container.cpp +++ b/host/lib/experts/expert_container.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "expert_container.hpp" +#include #include #include #include diff --git a/host/lib/experts/expert_container.hpp b/host/lib/experts/expert_container.hpp deleted file mode 100644 index 1f7193813..000000000 --- a/host/lib/experts/expert_container.hpp +++ /dev/null @@ -1,192 +0,0 @@ -// -// Copyright 2016 Ettus Research -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP -#define INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP - -#include "expert_nodes.hpp" -#include -#include -#include -#include - -namespace uhd { namespace experts { - - enum auto_resolve_mode_t { - AUTO_RESOLVE_OFF, - AUTO_RESOLVE_ON_READ, - AUTO_RESOLVE_ON_WRITE, - AUTO_RESOLVE_ON_READ_WRITE - }; - - class UHD_API expert_container : private boost::noncopyable, public node_retriever_t { - public: //Methods - typedef boost::shared_ptr sptr; - - virtual ~expert_container() {}; - - /*! - * Return the name of this container - */ - virtual const std::string& get_name() const = 0; - - /*! - * Resolves all the nodes in this expert graph. - * - * Dependency analysis is performed on the graph and nodes - * are resolved in a topologically sorted order to ensure - * that no nodes receive stale data. - * Nodes and their dependencies are resolved only if they are - * dirty i.e. their contained values have changed since the - * last resolve. - * This call requires an acyclic expert graph. - * - * \param force If true then ignore dirty state and resolve all nodes - * \throws uhd::runtime_error if graph cannot be resolved - */ - virtual void resolve_all(bool force = false) = 0; - - /*! - * Resolves all the nodes that depend on the specified node. - * - * Dependency analysis is performed on the graph and nodes - * are resolved in a topologically sorted order to ensure - * that no nodes receive stale data. - * Nodes and their dependencies are resolved only if they are - * dirty i.e. their contained values have changed since the - * last resolve. - * This call requires an acyclic expert graph. - * - * \param node_name Name of the node to start resolving from - * \throws uhd::lookup_error if node_name not in container - * \throws uhd::runtime_error if graph cannot be resolved - * - */ - virtual void resolve_from(const std::string& node_name) = 0; - - /*! - * Resolves all the specified node and all of its dependencies. - * - * Dependency analysis is performed on the graph and nodes - * are resolved in a topologically sorted order to ensure - * that no nodes receive stale data. - * Nodes and their dependencies are resolved only if they are - * dirty i.e. their contained values have changed since the - * last resolve. - * This call requires an acyclic expert graph. - * - * \param node_name Name of the node to resolve - * \throws uhd::lookup_error if node_name not in container - * \throws uhd::runtime_error if graph cannot be resolved - * - */ - virtual void resolve_to(const std::string& node_name) = 0; - - /*! - * Return a node retriever object for this container - */ - virtual const node_retriever_t& node_retriever() const = 0; - - /*! - * Returns a DOT (graph description language) representation - * of the expert graph. The output has labels for the node - * name, node type (data or worker) and the underlying - * data type for each node. - * - */ - virtual std::string to_dot() const = 0; - - /*! - * Runs several sanity checks on the underlying graph to - * flag dependency issues. Outputs of the checks are - * logged to the console so UHD_EXPERTS_VERBOSE_LOGGING - * must be enabled to see the results - * - */ - virtual void debug_audit() const = 0; - - private: - /*! - * Lookup a node with the specified name in the contained graph - * - * If the node is found, a reference to the node is returned. - * If the node is not found, uhd::lookup_error is thrown - * lookup can return a data or a worker node - * \implements uhd::experts::node_retriever_t - * - * \param name Name of the node to find - * - */ - virtual const dag_vertex_t& lookup(const std::string& name) const = 0; - virtual dag_vertex_t& retrieve(const std::string& name) const = 0; - - /*! - * expert_factory is a friend of expert_container and - * handles all operations that change the structure of - * the underlying dependency graph. - * The expert_container instance owns all data and worker - * nodes and is responsible for release storage on destruction. - * However, the expert_factory allocates storage for the - * node and passes them into the expert_container using the - * following "protected" API calls. - * - */ - friend class expert_factory; - - /*! - * Creates an empty instance of expert_container with the - * specified name. - * - * \param name Name of the container - */ - static sptr make(const std::string& name); - - /*! - * Returns a reference to the resolver mutex. - * - * The resolver mutex guarantees that external operations - * to data-nodes are serialized with resolves of this - * container. - * - */ - virtual boost::recursive_mutex& resolve_mutex() = 0; - - /*! - * Add a data node to the expert graph - * - * \param data_node Pointer to a fully constructed data node object - * \resolve_mode Auto resolve options: Choose from "disabled" and resolve on "read", "write" or "both" - * \throws uhd::runtime_error if node already exists or is of a wrong type (recoverable) - * \throws uhd::assertion_error for other failures (unrecoverable. will clear the graph) - * - */ - virtual void add_data_node(dag_vertex_t* data_node, auto_resolve_mode_t resolve_mode = AUTO_RESOLVE_OFF) = 0; - - /*! - * Add a worker node to the expert graph - * - * \param worker Pointer to a fully constructed worker object - * \throws uhd::runtime_error if worker already exists or is of a wrong type (recoverable) - * \throws uhd::assertion_error for other failures (unrecoverable. will clear the graph) - * - */ - virtual void add_worker(worker_node_t* worker) = 0; - - /*! - * Release all storage for this object. This will delete all contained - * data and worker nodes and remove all dependency relationship and - * resolve callbacks. - * - * The object will be restored to its newly constructed state. Will not - * throw. - */ - virtual void clear() = 0; - }; - -}} - -#endif /* INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP */ diff --git a/host/lib/experts/expert_factory.cpp b/host/lib/experts/expert_factory.cpp index 54286eee8..abc718d28 100644 --- a/host/lib/experts/expert_factory.cpp +++ b/host/lib/experts/expert_factory.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "expert_factory.hpp" +#include namespace uhd { namespace experts { diff --git a/host/lib/experts/expert_factory.hpp b/host/lib/experts/expert_factory.hpp deleted file mode 100644 index 4f24c747d..000000000 --- a/host/lib/experts/expert_factory.hpp +++ /dev/null @@ -1,327 +0,0 @@ -// -// Copyright 2016 Ettus Research -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_UHD_EXPERTS_EXPERT_FACTORY_HPP -#define INCLUDED_UHD_EXPERTS_EXPERT_FACTORY_HPP - -#include "expert_container.hpp" -#include -#include -#include -#include -#include - -namespace uhd { namespace experts { - - /*! - * expert_factory is a friend of expert_container and - * handles all operations to create and change the structure of - * the an expert container. - * The expert_factory allocates storage for the nodes in the - * expert_container and passes allocated objects to the container - * using private APIs. The expert_container instance owns all - * data and workernodes and is responsible for releasing their - * storage on destruction. - * - */ - class UHD_API expert_factory : public boost::noncopyable { - public: - - /*! - * Creates an empty instance of expert_container with the - * specified name. - * - * \param name Name of the container - */ - static expert_container::sptr create_container( - const std::string& name - ); - - /*! - * Add a data node to the expert graph. - * - * \param container A shared pointer to the container to add the node to - * \param name The name of the data node - * \param init_val The initial value of the data node - * \param mode The auto resolve mode - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - */ - template - inline static void add_data_node( - expert_container::sptr container, - const std::string& name, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - container->add_data_node(new data_node_t(name, init_val), mode); - } - - /*! - * Add a expert property to a property tree AND an expert graph - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param name The name of the data node in the expert graph - * \param init_val The initial value of the data node - * \param mode The auto resolve mode - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - */ - template - inline static property& add_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const std::string& name, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - property& prop = subtree->create(path, property_tree::MANUAL_COERCE); - data_node_t* node_ptr = - new data_node_t(name, init_val, &container->resolve_mutex()); - prop.set(init_val); - prop.add_desired_subscriber(boost::bind(&data_node_t::commit, node_ptr, _1)); - prop.set_publisher(boost::bind(&data_node_t::retrieve, node_ptr)); - container->add_data_node(node_ptr, mode); - return prop; - } - - /*! - * Add a expert property to a property tree AND an expert graph. - * The property is registered with the path as the identifier for - * both the property subtree and the expert container - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param init_val The initial value of the data node - * \param mode The auto resolve mode - * - */ - template - inline static property& add_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - return add_prop_node(container, subtree, path, path, init_val, mode); - } - - /*! - * Add a dual expert property to a property tree AND an expert graph. - * A dual property is a desired and coerced value pair - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param desired_name The name of the desired data node in the expert graph - * \param desired_name The name of the coerced data node in the expert graph - * \param init_val The initial value of both the data nodes - * \param mode The auto resolve mode - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - */ - template - inline static property& add_dual_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const std::string& desired_name, - const std::string& coerced_name, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - bool auto_resolve_desired = (mode==AUTO_RESOLVE_ON_WRITE or mode==AUTO_RESOLVE_ON_READ_WRITE); - bool auto_resolve_coerced = (mode==AUTO_RESOLVE_ON_READ or mode==AUTO_RESOLVE_ON_READ_WRITE); - - property& prop = subtree->create(path, property_tree::MANUAL_COERCE); - data_node_t* desired_node_ptr = - new data_node_t(desired_name, init_val, &container->resolve_mutex()); - data_node_t* coerced_node_ptr = - new data_node_t(coerced_name, init_val, &container->resolve_mutex()); - prop.set(init_val); - prop.set_coerced(init_val); - prop.add_desired_subscriber(boost::bind(&data_node_t::commit, desired_node_ptr, _1)); - prop.set_publisher(boost::bind(&data_node_t::retrieve, coerced_node_ptr)); - - container->add_data_node(desired_node_ptr, - auto_resolve_desired ? AUTO_RESOLVE_ON_WRITE : AUTO_RESOLVE_OFF); - container->add_data_node(coerced_node_ptr, - auto_resolve_coerced ? AUTO_RESOLVE_ON_READ : AUTO_RESOLVE_OFF); - return prop; - } - - /*! - * Add a dual expert property to a property tree AND an expert graph. - * A dual property is a desired and coerced value pair - * The property is registered with path/desired as the desired node - * name and path/coerced as the coerced node name - * - * \param container A shared pointer to the expert container to add the node to - * \param subtree A shared pointer to subtree to add the property to - * \param path The path of the property in the subtree - * \param init_val The initial value of both the data nodes - * \param mode The auto resolve mode - * - */ - template - inline static property& add_dual_prop_node( - expert_container::sptr container, - property_tree::sptr subtree, - const fs_path &path, - const data_t& init_val, - const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF - ) { - return add_dual_prop_node(container, subtree, path, path + "/desired", path + "/coerced", init_val, mode); - } - - /*! - * Add a worker node to the expert graph. - * The expert_container owns and manages storage for the worker - * - * \tparam worker_t Data type of the worker class - * - * \param container A shared pointer to the container to add the node to - * - */ - template - inline static void add_worker_node( - expert_container::sptr container - ) { - container->add_worker(new worker_t()); - } - - /*! - * Add a worker node to the expert graph. - * The expert_container owns and manages storage for the worker - * - * \tparam worker_t Data type of the worker class - * \tparam arg1_t Data type of the first argument to the constructor - * \tparam ... - * \tparam argN_t Data type of the Nth argument to the constructor - * - * \param container A shared pointer to the container to add the node to - * \param arg1 First arg to ctor - * \param ... - * \param argN Nth arg to ctor - * - */ - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1 - ) { - container->add_worker(new worker_t(arg1)); - } - - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2 - ) { - container->add_worker(new worker_t(arg1, arg2)); - } - - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3)); - } - - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4)); - } - - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5)); - } - - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5, - arg6_t const & arg6 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6)); - } - - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5, - arg6_t const & arg6, - arg7_t const & arg7 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); - } - - template - inline static void add_worker_node( - expert_container::sptr container, - arg1_t const & arg1, - arg2_t const & arg2, - arg3_t const & arg3, - arg4_t const & arg4, - arg5_t const & arg5, - arg6_t const & arg6, - arg7_t const & arg7, - arg7_t const & arg8 - ) { - container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); - } - }; -}} - -#endif /* INCLUDED_UHD_EXPERTS_EXPERT_FACTORY_HPP */ diff --git a/host/lib/experts/expert_nodes.hpp b/host/lib/experts/expert_nodes.hpp deleted file mode 100644 index 697ca19c3..000000000 --- a/host/lib/experts/expert_nodes.hpp +++ /dev/null @@ -1,472 +0,0 @@ -// -// Copyright 2016 Ettus Research -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_UHD_EXPERTS_EXPERT_NODES_HPP -#define INCLUDED_UHD_EXPERTS_EXPERT_NODES_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace uhd { namespace experts { - - enum node_class_t { CLASS_WORKER, CLASS_DATA, CLASS_PROPERTY }; - enum node_access_t { ACCESS_READER, ACCESS_WRITER }; - enum node_author_t { AUTHOR_NONE, AUTHOR_USER, AUTHOR_EXPERT }; - - /*!--------------------------------------------------------- - * class dag_vertex_t - * - * This serves as the base class for all nodes in the expert - * graph. Data nodes and workers are derived from this class. - * --------------------------------------------------------- - */ - class dag_vertex_t : private boost::noncopyable { - public: - typedef boost::function callback_func_t; - - virtual ~dag_vertex_t() {} - - // Getters for basic info about the node - inline node_class_t get_class() const { - return _class; - } - - inline const std::string& get_name() const { - return _name; - } - - virtual const std::string& get_dtype() const = 0; - - virtual std::string to_string() const = 0; - - // Graph resolution specific - virtual bool is_dirty() const = 0; - virtual void mark_clean() = 0; - virtual void resolve() = 0; - - // External callbacks - virtual void set_write_callback(const callback_func_t& func) = 0; - virtual bool has_write_callback() const = 0; - virtual void clear_write_callback() = 0; - virtual void set_read_callback(const callback_func_t& func) = 0; - virtual bool has_read_callback() const = 0; - virtual void clear_read_callback() = 0; - - protected: - dag_vertex_t(const node_class_t c, const std::string& n): - _class(c), _name(n) {} - - private: - const node_class_t _class; - const std::string _name; - }; - - class data_node_printer { - public: - //Generic implementation - template - static std::string print(const data_t& val) { - std::ostringstream os; - os << val; - return os.str(); - } - - static std::string print(const uint8_t& val) { - std::ostringstream os; - os << int(val); - return os.str(); - } - - static std::string print(const time_spec_t time) { - std::ostringstream os; - os << time.get_real_secs(); - return os.str(); - } - }; - - /*!--------------------------------------------------------- - * class data_node_t - * - * The data node class hold a passive piece of data in the - * expert graph. A data node is clean if its underlying data - * is clean. Access to the underlying data is provided using - * two methods: - * 1. Special accessor classes (for R/W enforcement) - * 2. External clients (via commit and retrieve). This access - * is protected by the callback mutex. - * - * Requirements for data_t - * - Must have a default constructor - * - Must have a copy constructor - * - Must have an assignment operator (=) - * - Must have an equality operator (==) - * --------------------------------------------------------- - */ - template - class data_node_t : public dag_vertex_t { - public: - // A data_node_t instance can have a type of CLASS_DATA or CLASS_PROPERTY - // In general a data node is a property if it can be accessed and modified - // from the outside world (of experts) using read and write callbacks. We - // assume that if a callback mutex is passed into the data node that it will - // be accessed from the outside and tag the data node as a PROPERTY. - data_node_t(const std::string& name, boost::recursive_mutex* mutex = NULL) : - dag_vertex_t(mutex?CLASS_PROPERTY:CLASS_DATA, name), _callback_mutex(mutex), _data(), _author(AUTHOR_NONE) {} - - data_node_t(const std::string& name, const data_t& value, boost::recursive_mutex* mutex = NULL) : - dag_vertex_t(mutex?CLASS_PROPERTY:CLASS_DATA, name), _callback_mutex(mutex), _data(value), _author(AUTHOR_NONE) {} - - // Basic info - virtual const std::string& get_dtype() const { - static const std::string dtype( - boost::units::detail::demangle(typeid(data_t).name())); - return dtype; - } - - virtual std::string to_string() const { - return data_node_printer::print(get()); - } - - inline node_author_t get_author() const { - return _author; - } - - // Graph resolution specific - virtual bool is_dirty() const { - return _data.is_dirty(); - } - - virtual void mark_clean() { - _data.mark_clean(); - } - - void resolve() { - //NOP - } - - // Data node specific setters and getters (for the framework) - void set(const data_t& value) { - _data = value; - _author = AUTHOR_EXPERT; - } - - const data_t& get() const { - return _data; - } - - // Data node specific setters and getters (for external entities) - void commit(const data_t& value) { - if (_callback_mutex == NULL) throw uhd::assertion_error("node " + get_name() + " is missing the callback mutex"); - boost::lock_guard lock(*_callback_mutex); - set(value); - _author = AUTHOR_USER; - if (is_dirty() and has_write_callback()) { - _wr_callback(std::string(get_name())); //Put the name on the stack before calling - } - } - - const data_t retrieve() const { - if (_callback_mutex == NULL) throw uhd::assertion_error("node " + get_name() + " is missing the callback mutex"); - boost::lock_guard lock(*_callback_mutex); - if (has_read_callback()) { - _rd_callback(std::string(get_name())); - } - return get(); - } - - private: - // External callbacks - virtual void set_write_callback(const callback_func_t& func) { - _wr_callback = func; - } - - virtual bool has_write_callback() const { - return not _wr_callback.empty(); - } - - virtual void clear_write_callback() { - _wr_callback.clear(); - } - - virtual void set_read_callback(const callback_func_t& func) { - _rd_callback = func; - } - - virtual bool has_read_callback() const { - return not _rd_callback.empty(); - } - - virtual void clear_read_callback() { - _rd_callback.clear(); - } - - boost::recursive_mutex* _callback_mutex; - callback_func_t _rd_callback; - callback_func_t _wr_callback; - dirty_tracked _data; - node_author_t _author; - }; - - /*!--------------------------------------------------------- - * class node_retriever_t - * - * Node storage is managed by a framework class so we need - * and interface to find and retrieve data nodes to associate - * with accessors. - * --------------------------------------------------------- - */ - class node_retriever_t { - public: - virtual ~node_retriever_t() {} - virtual const dag_vertex_t& lookup(const std::string& name) const = 0; - private: - friend class data_accessor_t; - virtual dag_vertex_t& retrieve(const std::string& name) const = 0; - }; - - /*!--------------------------------------------------------- - * class data_accessor_t - * - * Accessors provide protected access to data nodes and help - * establish dependency relationships. - * --------------------------------------------------------- - */ - class data_accessor_t { - public: - virtual ~data_accessor_t() {} - - virtual bool is_reader() const = 0; - virtual bool is_writer() const = 0; - virtual dag_vertex_t& node() const = 0; - protected: - data_accessor_t(const node_retriever_t& r, const std::string& n): - _vertex(r.retrieve(n)) {} - dag_vertex_t& _vertex; - }; - - template - class data_accessor_base : public data_accessor_t { - public: - virtual ~data_accessor_base() {} - - virtual bool is_reader() const { - return _access == ACCESS_READER; - } - - virtual bool is_writer() const { - return _access == ACCESS_WRITER; - } - - inline bool is_dirty() const { - return _datanode->is_dirty(); - } - - inline node_class_t get_class() const { - return _datanode->get_class(); - } - - inline node_author_t get_author() const { - return _datanode->get_author(); - } - - protected: - data_accessor_base( - const node_retriever_t& r, const std::string& n, const node_access_t a) : - data_accessor_t(r, n), _datanode(NULL), _access(a) - { - _datanode = dynamic_cast< data_node_t* >(&node()); - if (_datanode == NULL) { - throw uhd::type_error("Expected data type for node " + n + - " was " + boost::units::detail::demangle(typeid(data_t).name()) + - " but got " + node().get_dtype()); - } - } - - data_node_t* _datanode; - const node_access_t _access; - - private: - virtual dag_vertex_t& node() const { - return _vertex; - } - }; - - /*!--------------------------------------------------------- - * class data_reader_t - * - * Accessor to read the value of a data node and to establish - * a data node => worker node dependency - * --------------------------------------------------------- - */ - template - class data_reader_t : public data_accessor_base { - public: - data_reader_t(const node_retriever_t& retriever, const std::string& node) : - data_accessor_base( - retriever, node, ACCESS_READER) {} - - inline const data_t& get() const { - return data_accessor_base::_datanode->get(); - } - - inline operator const data_t&() const { - return get(); - } - - inline bool operator==(const data_t& rhs) { - return get() == rhs; - } - - inline bool operator!=(const data_t& rhs) { - return !(get() == rhs); - } - }; - - /*!--------------------------------------------------------- - * class data_reader_t - * - * Accessor to read and write the value of a data node and - * to establish a worker node => data node dependency - * --------------------------------------------------------- - */ - template - class data_writer_t : public data_accessor_base { - public: - data_writer_t(const node_retriever_t& retriever, const std::string& node) : - data_accessor_base( - retriever, node, ACCESS_WRITER) {} - - inline const data_t& get() const { - return data_accessor_base::_datanode->get(); - } - - inline operator const data_t&() const { - return get(); - } - - inline bool operator==(const data_t& rhs) { - return get() == rhs; - } - - inline bool operator!=(const data_t& rhs) { - return !(get() == rhs); - } - - inline void set(const data_t& value) { - data_accessor_base::_datanode->set(value); - } - - inline data_writer_t& operator=(const data_t& value) { - set(value); - return *this; - } - - inline data_writer_t& operator=(const data_writer_t& value) { - set(value.get()); - return *this; - } -}; - - /*!--------------------------------------------------------- - * class worker_node_t - * - * A node class to implement a function that consumes - * zero or more input data nodes and emits zero or more output - * data nodes. The worker can also operate on other non-expert - * interfaces because worker_node_t is abstract and the client - * is required to implement the "resolve" method in a subclass. - * --------------------------------------------------------- - */ - class worker_node_t : public dag_vertex_t { - public: - worker_node_t(const std::string& name) : - dag_vertex_t(CLASS_WORKER, name) {} - - // Worker node specific - std::list get_inputs() const { - std::list retval; - for(data_accessor_t* acc: _inputs) { - retval.push_back(acc->node().get_name()); - } - return retval; - } - - std::list get_outputs() const { - std::list retval; - for(data_accessor_t* acc: _outputs) { - retval.push_back(acc->node().get_name()); - } - return retval; - } - - protected: - // This function is used to bind data accessors - // to this worker. Accessors can be read/write - // and the binding will ensure proper dependency - // handling. - void bind_accessor(data_accessor_t& accessor) { - if (accessor.is_reader()) { - _inputs.push_back(&accessor); - } else if (accessor.is_writer()) { - _outputs.push_back(&accessor); - } else { - throw uhd::assertion_error("Invalid accessor type"); - } - } - - private: - // Graph resolution specific - virtual bool is_dirty() const { - bool inputs_dirty = false; - for(data_accessor_t* acc: _inputs) { - inputs_dirty |= acc->node().is_dirty(); - } - return inputs_dirty; - } - - virtual void mark_clean() { - for(data_accessor_t* acc: _inputs) { - acc->node().mark_clean(); - } - } - - virtual void resolve() = 0; - - // Basic type info - virtual const std::string& get_dtype() const { - static const std::string dtype = ""; - return dtype; - } - - virtual std::string to_string() const { - return ""; - } - - // Workers don't have callbacks so implement stubs - virtual void set_write_callback(const callback_func_t&) {} - virtual bool has_write_callback() const { return false; } - virtual void clear_write_callback() {} - virtual void set_read_callback(const callback_func_t&) {} - virtual bool has_read_callback() const { return false; } - virtual void clear_read_callback() {} - - std::list _inputs; - std::list _outputs; - }; - -}} - -#endif /* INCLUDED_UHD_EXPERTS_EXPERT_NODE_HPP */ diff --git a/host/lib/include/uhdlib/experts/expert_container.hpp b/host/lib/include/uhdlib/experts/expert_container.hpp new file mode 100644 index 000000000..c50e45847 --- /dev/null +++ b/host/lib/include/uhdlib/experts/expert_container.hpp @@ -0,0 +1,192 @@ +// +// Copyright 2016 Ettus Research +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP +#define INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP + +#include +#include +#include +#include +#include + +namespace uhd { namespace experts { + + enum auto_resolve_mode_t { + AUTO_RESOLVE_OFF, + AUTO_RESOLVE_ON_READ, + AUTO_RESOLVE_ON_WRITE, + AUTO_RESOLVE_ON_READ_WRITE + }; + + class UHD_API expert_container : private boost::noncopyable, public node_retriever_t { + public: //Methods + typedef boost::shared_ptr sptr; + + virtual ~expert_container() {}; + + /*! + * Return the name of this container + */ + virtual const std::string& get_name() const = 0; + + /*! + * Resolves all the nodes in this expert graph. + * + * Dependency analysis is performed on the graph and nodes + * are resolved in a topologically sorted order to ensure + * that no nodes receive stale data. + * Nodes and their dependencies are resolved only if they are + * dirty i.e. their contained values have changed since the + * last resolve. + * This call requires an acyclic expert graph. + * + * \param force If true then ignore dirty state and resolve all nodes + * \throws uhd::runtime_error if graph cannot be resolved + */ + virtual void resolve_all(bool force = false) = 0; + + /*! + * Resolves all the nodes that depend on the specified node. + * + * Dependency analysis is performed on the graph and nodes + * are resolved in a topologically sorted order to ensure + * that no nodes receive stale data. + * Nodes and their dependencies are resolved only if they are + * dirty i.e. their contained values have changed since the + * last resolve. + * This call requires an acyclic expert graph. + * + * \param node_name Name of the node to start resolving from + * \throws uhd::lookup_error if node_name not in container + * \throws uhd::runtime_error if graph cannot be resolved + * + */ + virtual void resolve_from(const std::string& node_name) = 0; + + /*! + * Resolves all the specified node and all of its dependencies. + * + * Dependency analysis is performed on the graph and nodes + * are resolved in a topologically sorted order to ensure + * that no nodes receive stale data. + * Nodes and their dependencies are resolved only if they are + * dirty i.e. their contained values have changed since the + * last resolve. + * This call requires an acyclic expert graph. + * + * \param node_name Name of the node to resolve + * \throws uhd::lookup_error if node_name not in container + * \throws uhd::runtime_error if graph cannot be resolved + * + */ + virtual void resolve_to(const std::string& node_name) = 0; + + /*! + * Return a node retriever object for this container + */ + virtual const node_retriever_t& node_retriever() const = 0; + + /*! + * Returns a DOT (graph description language) representation + * of the expert graph. The output has labels for the node + * name, node type (data or worker) and the underlying + * data type for each node. + * + */ + virtual std::string to_dot() const = 0; + + /*! + * Runs several sanity checks on the underlying graph to + * flag dependency issues. Outputs of the checks are + * logged to the console so UHD_EXPERTS_VERBOSE_LOGGING + * must be enabled to see the results + * + */ + virtual void debug_audit() const = 0; + + private: + /*! + * Lookup a node with the specified name in the contained graph + * + * If the node is found, a reference to the node is returned. + * If the node is not found, uhd::lookup_error is thrown + * lookup can return a data or a worker node + * \implements uhd::experts::node_retriever_t + * + * \param name Name of the node to find + * + */ + virtual const dag_vertex_t& lookup(const std::string& name) const = 0; + virtual dag_vertex_t& retrieve(const std::string& name) const = 0; + + /*! + * expert_factory is a friend of expert_container and + * handles all operations that change the structure of + * the underlying dependency graph. + * The expert_container instance owns all data and worker + * nodes and is responsible for release storage on destruction. + * However, the expert_factory allocates storage for the + * node and passes them into the expert_container using the + * following "protected" API calls. + * + */ + friend class expert_factory; + + /*! + * Creates an empty instance of expert_container with the + * specified name. + * + * \param name Name of the container + */ + static sptr make(const std::string& name); + + /*! + * Returns a reference to the resolver mutex. + * + * The resolver mutex guarantees that external operations + * to data-nodes are serialized with resolves of this + * container. + * + */ + virtual boost::recursive_mutex& resolve_mutex() = 0; + + /*! + * Add a data node to the expert graph + * + * \param data_node Pointer to a fully constructed data node object + * \resolve_mode Auto resolve options: Choose from "disabled" and resolve on "read", "write" or "both" + * \throws uhd::runtime_error if node already exists or is of a wrong type (recoverable) + * \throws uhd::assertion_error for other failures (unrecoverable. will clear the graph) + * + */ + virtual void add_data_node(dag_vertex_t* data_node, auto_resolve_mode_t resolve_mode = AUTO_RESOLVE_OFF) = 0; + + /*! + * Add a worker node to the expert graph + * + * \param worker Pointer to a fully constructed worker object + * \throws uhd::runtime_error if worker already exists or is of a wrong type (recoverable) + * \throws uhd::assertion_error for other failures (unrecoverable. will clear the graph) + * + */ + virtual void add_worker(worker_node_t* worker) = 0; + + /*! + * Release all storage for this object. This will delete all contained + * data and worker nodes and remove all dependency relationship and + * resolve callbacks. + * + * The object will be restored to its newly constructed state. Will not + * throw. + */ + virtual void clear() = 0; + }; + +}} + +#endif /* INCLUDED_UHD_EXPERTS_EXPERT_CONTAINER_HPP */ diff --git a/host/lib/include/uhdlib/experts/expert_factory.hpp b/host/lib/include/uhdlib/experts/expert_factory.hpp new file mode 100644 index 000000000..72798eccc --- /dev/null +++ b/host/lib/include/uhdlib/experts/expert_factory.hpp @@ -0,0 +1,327 @@ +// +// Copyright 2016 Ettus Research +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_UHD_EXPERTS_EXPERT_FACTORY_HPP +#define INCLUDED_UHD_EXPERTS_EXPERT_FACTORY_HPP + +#include +#include +#include +#include +#include +#include + +namespace uhd { namespace experts { + + /*! + * expert_factory is a friend of expert_container and + * handles all operations to create and change the structure of + * the an expert container. + * The expert_factory allocates storage for the nodes in the + * expert_container and passes allocated objects to the container + * using private APIs. The expert_container instance owns all + * data and workernodes and is responsible for releasing their + * storage on destruction. + * + */ + class UHD_API expert_factory : public boost::noncopyable { + public: + + /*! + * Creates an empty instance of expert_container with the + * specified name. + * + * \param name Name of the container + */ + static expert_container::sptr create_container( + const std::string& name + ); + + /*! + * Add a data node to the expert graph. + * + * \param container A shared pointer to the container to add the node to + * \param name The name of the data node + * \param init_val The initial value of the data node + * \param mode The auto resolve mode + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + */ + template + inline static void add_data_node( + expert_container::sptr container, + const std::string& name, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF + ) { + container->add_data_node(new data_node_t(name, init_val), mode); + } + + /*! + * Add a expert property to a property tree AND an expert graph + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param name The name of the data node in the expert graph + * \param init_val The initial value of the data node + * \param mode The auto resolve mode + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + */ + template + inline static property& add_prop_node( + expert_container::sptr container, + property_tree::sptr subtree, + const fs_path &path, + const std::string& name, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF + ) { + property& prop = subtree->create(path, property_tree::MANUAL_COERCE); + data_node_t* node_ptr = + new data_node_t(name, init_val, &container->resolve_mutex()); + prop.set(init_val); + prop.add_desired_subscriber(boost::bind(&data_node_t::commit, node_ptr, _1)); + prop.set_publisher(boost::bind(&data_node_t::retrieve, node_ptr)); + container->add_data_node(node_ptr, mode); + return prop; + } + + /*! + * Add a expert property to a property tree AND an expert graph. + * The property is registered with the path as the identifier for + * both the property subtree and the expert container + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param init_val The initial value of the data node + * \param mode The auto resolve mode + * + */ + template + inline static property& add_prop_node( + expert_container::sptr container, + property_tree::sptr subtree, + const fs_path &path, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF + ) { + return add_prop_node(container, subtree, path, path, init_val, mode); + } + + /*! + * Add a dual expert property to a property tree AND an expert graph. + * A dual property is a desired and coerced value pair + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param desired_name The name of the desired data node in the expert graph + * \param desired_name The name of the coerced data node in the expert graph + * \param init_val The initial value of both the data nodes + * \param mode The auto resolve mode + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + */ + template + inline static property& add_dual_prop_node( + expert_container::sptr container, + property_tree::sptr subtree, + const fs_path &path, + const std::string& desired_name, + const std::string& coerced_name, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF + ) { + bool auto_resolve_desired = (mode==AUTO_RESOLVE_ON_WRITE or mode==AUTO_RESOLVE_ON_READ_WRITE); + bool auto_resolve_coerced = (mode==AUTO_RESOLVE_ON_READ or mode==AUTO_RESOLVE_ON_READ_WRITE); + + property& prop = subtree->create(path, property_tree::MANUAL_COERCE); + data_node_t* desired_node_ptr = + new data_node_t(desired_name, init_val, &container->resolve_mutex()); + data_node_t* coerced_node_ptr = + new data_node_t(coerced_name, init_val, &container->resolve_mutex()); + prop.set(init_val); + prop.set_coerced(init_val); + prop.add_desired_subscriber(boost::bind(&data_node_t::commit, desired_node_ptr, _1)); + prop.set_publisher(boost::bind(&data_node_t::retrieve, coerced_node_ptr)); + + container->add_data_node(desired_node_ptr, + auto_resolve_desired ? AUTO_RESOLVE_ON_WRITE : AUTO_RESOLVE_OFF); + container->add_data_node(coerced_node_ptr, + auto_resolve_coerced ? AUTO_RESOLVE_ON_READ : AUTO_RESOLVE_OFF); + return prop; + } + + /*! + * Add a dual expert property to a property tree AND an expert graph. + * A dual property is a desired and coerced value pair + * The property is registered with path/desired as the desired node + * name and path/coerced as the coerced node name + * + * \param container A shared pointer to the expert container to add the node to + * \param subtree A shared pointer to subtree to add the property to + * \param path The path of the property in the subtree + * \param init_val The initial value of both the data nodes + * \param mode The auto resolve mode + * + */ + template + inline static property& add_dual_prop_node( + expert_container::sptr container, + property_tree::sptr subtree, + const fs_path &path, + const data_t& init_val, + const auto_resolve_mode_t mode = AUTO_RESOLVE_OFF + ) { + return add_dual_prop_node(container, subtree, path, path + "/desired", path + "/coerced", init_val, mode); + } + + /*! + * Add a worker node to the expert graph. + * The expert_container owns and manages storage for the worker + * + * \tparam worker_t Data type of the worker class + * + * \param container A shared pointer to the container to add the node to + * + */ + template + inline static void add_worker_node( + expert_container::sptr container + ) { + container->add_worker(new worker_t()); + } + + /*! + * Add a worker node to the expert graph. + * The expert_container owns and manages storage for the worker + * + * \tparam worker_t Data type of the worker class + * \tparam arg1_t Data type of the first argument to the constructor + * \tparam ... + * \tparam argN_t Data type of the Nth argument to the constructor + * + * \param container A shared pointer to the container to add the node to + * \param arg1 First arg to ctor + * \param ... + * \param argN Nth arg to ctor + * + */ + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1 + ) { + container->add_worker(new worker_t(arg1)); + } + + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1, + arg2_t const & arg2 + ) { + container->add_worker(new worker_t(arg1, arg2)); + } + + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1, + arg2_t const & arg2, + arg3_t const & arg3 + ) { + container->add_worker(new worker_t(arg1, arg2, arg3)); + } + + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1, + arg2_t const & arg2, + arg3_t const & arg3, + arg4_t const & arg4 + ) { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4)); + } + + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1, + arg2_t const & arg2, + arg3_t const & arg3, + arg4_t const & arg4, + arg5_t const & arg5 + ) { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5)); + } + + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1, + arg2_t const & arg2, + arg3_t const & arg3, + arg4_t const & arg4, + arg5_t const & arg5, + arg6_t const & arg6 + ) { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6)); + } + + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1, + arg2_t const & arg2, + arg3_t const & arg3, + arg4_t const & arg4, + arg5_t const & arg5, + arg6_t const & arg6, + arg7_t const & arg7 + ) { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7)); + } + + template + inline static void add_worker_node( + expert_container::sptr container, + arg1_t const & arg1, + arg2_t const & arg2, + arg3_t const & arg3, + arg4_t const & arg4, + arg5_t const & arg5, + arg6_t const & arg6, + arg7_t const & arg7, + arg7_t const & arg8 + ) { + container->add_worker(new worker_t(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); + } + }; +}} + +#endif /* INCLUDED_UHD_EXPERTS_EXPERT_FACTORY_HPP */ diff --git a/host/lib/include/uhdlib/experts/expert_nodes.hpp b/host/lib/include/uhdlib/experts/expert_nodes.hpp new file mode 100644 index 000000000..697ca19c3 --- /dev/null +++ b/host/lib/include/uhdlib/experts/expert_nodes.hpp @@ -0,0 +1,472 @@ +// +// Copyright 2016 Ettus Research +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_UHD_EXPERTS_EXPERT_NODES_HPP +#define INCLUDED_UHD_EXPERTS_EXPERT_NODES_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace uhd { namespace experts { + + enum node_class_t { CLASS_WORKER, CLASS_DATA, CLASS_PROPERTY }; + enum node_access_t { ACCESS_READER, ACCESS_WRITER }; + enum node_author_t { AUTHOR_NONE, AUTHOR_USER, AUTHOR_EXPERT }; + + /*!--------------------------------------------------------- + * class dag_vertex_t + * + * This serves as the base class for all nodes in the expert + * graph. Data nodes and workers are derived from this class. + * --------------------------------------------------------- + */ + class dag_vertex_t : private boost::noncopyable { + public: + typedef boost::function callback_func_t; + + virtual ~dag_vertex_t() {} + + // Getters for basic info about the node + inline node_class_t get_class() const { + return _class; + } + + inline const std::string& get_name() const { + return _name; + } + + virtual const std::string& get_dtype() const = 0; + + virtual std::string to_string() const = 0; + + // Graph resolution specific + virtual bool is_dirty() const = 0; + virtual void mark_clean() = 0; + virtual void resolve() = 0; + + // External callbacks + virtual void set_write_callback(const callback_func_t& func) = 0; + virtual bool has_write_callback() const = 0; + virtual void clear_write_callback() = 0; + virtual void set_read_callback(const callback_func_t& func) = 0; + virtual bool has_read_callback() const = 0; + virtual void clear_read_callback() = 0; + + protected: + dag_vertex_t(const node_class_t c, const std::string& n): + _class(c), _name(n) {} + + private: + const node_class_t _class; + const std::string _name; + }; + + class data_node_printer { + public: + //Generic implementation + template + static std::string print(const data_t& val) { + std::ostringstream os; + os << val; + return os.str(); + } + + static std::string print(const uint8_t& val) { + std::ostringstream os; + os << int(val); + return os.str(); + } + + static std::string print(const time_spec_t time) { + std::ostringstream os; + os << time.get_real_secs(); + return os.str(); + } + }; + + /*!--------------------------------------------------------- + * class data_node_t + * + * The data node class hold a passive piece of data in the + * expert graph. A data node is clean if its underlying data + * is clean. Access to the underlying data is provided using + * two methods: + * 1. Special accessor classes (for R/W enforcement) + * 2. External clients (via commit and retrieve). This access + * is protected by the callback mutex. + * + * Requirements for data_t + * - Must have a default constructor + * - Must have a copy constructor + * - Must have an assignment operator (=) + * - Must have an equality operator (==) + * --------------------------------------------------------- + */ + template + class data_node_t : public dag_vertex_t { + public: + // A data_node_t instance can have a type of CLASS_DATA or CLASS_PROPERTY + // In general a data node is a property if it can be accessed and modified + // from the outside world (of experts) using read and write callbacks. We + // assume that if a callback mutex is passed into the data node that it will + // be accessed from the outside and tag the data node as a PROPERTY. + data_node_t(const std::string& name, boost::recursive_mutex* mutex = NULL) : + dag_vertex_t(mutex?CLASS_PROPERTY:CLASS_DATA, name), _callback_mutex(mutex), _data(), _author(AUTHOR_NONE) {} + + data_node_t(const std::string& name, const data_t& value, boost::recursive_mutex* mutex = NULL) : + dag_vertex_t(mutex?CLASS_PROPERTY:CLASS_DATA, name), _callback_mutex(mutex), _data(value), _author(AUTHOR_NONE) {} + + // Basic info + virtual const std::string& get_dtype() const { + static const std::string dtype( + boost::units::detail::demangle(typeid(data_t).name())); + return dtype; + } + + virtual std::string to_string() const { + return data_node_printer::print(get()); + } + + inline node_author_t get_author() const { + return _author; + } + + // Graph resolution specific + virtual bool is_dirty() const { + return _data.is_dirty(); + } + + virtual void mark_clean() { + _data.mark_clean(); + } + + void resolve() { + //NOP + } + + // Data node specific setters and getters (for the framework) + void set(const data_t& value) { + _data = value; + _author = AUTHOR_EXPERT; + } + + const data_t& get() const { + return _data; + } + + // Data node specific setters and getters (for external entities) + void commit(const data_t& value) { + if (_callback_mutex == NULL) throw uhd::assertion_error("node " + get_name() + " is missing the callback mutex"); + boost::lock_guard lock(*_callback_mutex); + set(value); + _author = AUTHOR_USER; + if (is_dirty() and has_write_callback()) { + _wr_callback(std::string(get_name())); //Put the name on the stack before calling + } + } + + const data_t retrieve() const { + if (_callback_mutex == NULL) throw uhd::assertion_error("node " + get_name() + " is missing the callback mutex"); + boost::lock_guard lock(*_callback_mutex); + if (has_read_callback()) { + _rd_callback(std::string(get_name())); + } + return get(); + } + + private: + // External callbacks + virtual void set_write_callback(const callback_func_t& func) { + _wr_callback = func; + } + + virtual bool has_write_callback() const { + return not _wr_callback.empty(); + } + + virtual void clear_write_callback() { + _wr_callback.clear(); + } + + virtual void set_read_callback(const callback_func_t& func) { + _rd_callback = func; + } + + virtual bool has_read_callback() const { + return not _rd_callback.empty(); + } + + virtual void clear_read_callback() { + _rd_callback.clear(); + } + + boost::recursive_mutex* _callback_mutex; + callback_func_t _rd_callback; + callback_func_t _wr_callback; + dirty_tracked _data; + node_author_t _author; + }; + + /*!--------------------------------------------------------- + * class node_retriever_t + * + * Node storage is managed by a framework class so we need + * and interface to find and retrieve data nodes to associate + * with accessors. + * --------------------------------------------------------- + */ + class node_retriever_t { + public: + virtual ~node_retriever_t() {} + virtual const dag_vertex_t& lookup(const std::string& name) const = 0; + private: + friend class data_accessor_t; + virtual dag_vertex_t& retrieve(const std::string& name) const = 0; + }; + + /*!--------------------------------------------------------- + * class data_accessor_t + * + * Accessors provide protected access to data nodes and help + * establish dependency relationships. + * --------------------------------------------------------- + */ + class data_accessor_t { + public: + virtual ~data_accessor_t() {} + + virtual bool is_reader() const = 0; + virtual bool is_writer() const = 0; + virtual dag_vertex_t& node() const = 0; + protected: + data_accessor_t(const node_retriever_t& r, const std::string& n): + _vertex(r.retrieve(n)) {} + dag_vertex_t& _vertex; + }; + + template + class data_accessor_base : public data_accessor_t { + public: + virtual ~data_accessor_base() {} + + virtual bool is_reader() const { + return _access == ACCESS_READER; + } + + virtual bool is_writer() const { + return _access == ACCESS_WRITER; + } + + inline bool is_dirty() const { + return _datanode->is_dirty(); + } + + inline node_class_t get_class() const { + return _datanode->get_class(); + } + + inline node_author_t get_author() const { + return _datanode->get_author(); + } + + protected: + data_accessor_base( + const node_retriever_t& r, const std::string& n, const node_access_t a) : + data_accessor_t(r, n), _datanode(NULL), _access(a) + { + _datanode = dynamic_cast< data_node_t* >(&node()); + if (_datanode == NULL) { + throw uhd::type_error("Expected data type for node " + n + + " was " + boost::units::detail::demangle(typeid(data_t).name()) + + " but got " + node().get_dtype()); + } + } + + data_node_t* _datanode; + const node_access_t _access; + + private: + virtual dag_vertex_t& node() const { + return _vertex; + } + }; + + /*!--------------------------------------------------------- + * class data_reader_t + * + * Accessor to read the value of a data node and to establish + * a data node => worker node dependency + * --------------------------------------------------------- + */ + template + class data_reader_t : public data_accessor_base { + public: + data_reader_t(const node_retriever_t& retriever, const std::string& node) : + data_accessor_base( + retriever, node, ACCESS_READER) {} + + inline const data_t& get() const { + return data_accessor_base::_datanode->get(); + } + + inline operator const data_t&() const { + return get(); + } + + inline bool operator==(const data_t& rhs) { + return get() == rhs; + } + + inline bool operator!=(const data_t& rhs) { + return !(get() == rhs); + } + }; + + /*!--------------------------------------------------------- + * class data_reader_t + * + * Accessor to read and write the value of a data node and + * to establish a worker node => data node dependency + * --------------------------------------------------------- + */ + template + class data_writer_t : public data_accessor_base { + public: + data_writer_t(const node_retriever_t& retriever, const std::string& node) : + data_accessor_base( + retriever, node, ACCESS_WRITER) {} + + inline const data_t& get() const { + return data_accessor_base::_datanode->get(); + } + + inline operator const data_t&() const { + return get(); + } + + inline bool operator==(const data_t& rhs) { + return get() == rhs; + } + + inline bool operator!=(const data_t& rhs) { + return !(get() == rhs); + } + + inline void set(const data_t& value) { + data_accessor_base::_datanode->set(value); + } + + inline data_writer_t& operator=(const data_t& value) { + set(value); + return *this; + } + + inline data_writer_t& operator=(const data_writer_t& value) { + set(value.get()); + return *this; + } +}; + + /*!--------------------------------------------------------- + * class worker_node_t + * + * A node class to implement a function that consumes + * zero or more input data nodes and emits zero or more output + * data nodes. The worker can also operate on other non-expert + * interfaces because worker_node_t is abstract and the client + * is required to implement the "resolve" method in a subclass. + * --------------------------------------------------------- + */ + class worker_node_t : public dag_vertex_t { + public: + worker_node_t(const std::string& name) : + dag_vertex_t(CLASS_WORKER, name) {} + + // Worker node specific + std::list get_inputs() const { + std::list retval; + for(data_accessor_t* acc: _inputs) { + retval.push_back(acc->node().get_name()); + } + return retval; + } + + std::list get_outputs() const { + std::list retval; + for(data_accessor_t* acc: _outputs) { + retval.push_back(acc->node().get_name()); + } + return retval; + } + + protected: + // This function is used to bind data accessors + // to this worker. Accessors can be read/write + // and the binding will ensure proper dependency + // handling. + void bind_accessor(data_accessor_t& accessor) { + if (accessor.is_reader()) { + _inputs.push_back(&accessor); + } else if (accessor.is_writer()) { + _outputs.push_back(&accessor); + } else { + throw uhd::assertion_error("Invalid accessor type"); + } + } + + private: + // Graph resolution specific + virtual bool is_dirty() const { + bool inputs_dirty = false; + for(data_accessor_t* acc: _inputs) { + inputs_dirty |= acc->node().is_dirty(); + } + return inputs_dirty; + } + + virtual void mark_clean() { + for(data_accessor_t* acc: _inputs) { + acc->node().mark_clean(); + } + } + + virtual void resolve() = 0; + + // Basic type info + virtual const std::string& get_dtype() const { + static const std::string dtype = ""; + return dtype; + } + + virtual std::string to_string() const { + return ""; + } + + // Workers don't have callbacks so implement stubs + virtual void set_write_callback(const callback_func_t&) {} + virtual bool has_write_callback() const { return false; } + virtual void clear_write_callback() {} + virtual void set_read_callback(const callback_func_t&) {} + virtual bool has_read_callback() const { return false; } + virtual void clear_read_callback() {} + + std::list _inputs; + std::list _outputs; + }; + +}} + +#endif /* INCLUDED_UHD_EXPERTS_EXPERT_NODE_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp b/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp new file mode 100644 index 000000000..2ef50a1a1 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/ctrl_iface.hpp @@ -0,0 +1,46 @@ +// +// Copyright 2012-2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP +#define INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace uhd { namespace rfnoc { + +/*! + * Provide access to peek, poke for the radio ctrl module + */ +class ctrl_iface : public uhd::timed_wb_iface +{ +public: + typedef boost::shared_ptr sptr; + + virtual ~ctrl_iface(void) = 0; + + //! Make a new control object + static sptr make( + const bool big_endian, + uhd::transport::zero_copy_if::sptr ctrl_xport, + uhd::transport::zero_copy_if::sptr resp_xport, + const uint32_t sid, + const std::string &name = "0" + ); + + //! Set the tick rate (converting time into ticks) + virtual void set_tick_rate(const double rate) = 0; +}; + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/graph_impl.hpp b/host/lib/include/uhdlib/rfnoc/graph_impl.hpp new file mode 100644 index 000000000..182befbf4 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/graph_impl.hpp @@ -0,0 +1,80 @@ +// +// Copyright 2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP +#define INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP + +#include +#include + +namespace uhd { namespace rfnoc { + +class graph_impl : public graph +{ +public: + /*! + * \param name An optional name to describe this graph + * \param device_ptr Weak pointer to the originating device3 + * \param msg_handler Pointer to the async message handler + */ + graph_impl( + const std::string &name, + boost::weak_ptr device_ptr + //async_msg_handler::sptr msg_handler + ); + virtual ~graph_impl() {}; + + /************************************************************************ + * Connection API + ***********************************************************************/ + void connect( + const block_id_t &src_block, + size_t src_block_port, + const block_id_t &dst_block, + size_t dst_block_port, + const size_t pkt_size = 0 + ); + + void connect( + const block_id_t &src_block, + const block_id_t &dst_block + ); + + void connect_src( + const block_id_t &src_block, + const size_t src_block_port, + const uhd::sid_t dst_sid, + const size_t buf_size_dst_bytes, + const size_t pkt_size_ + ); + + void connect_sink( + const block_id_t &sink_block, + const size_t dst_block_port, + const size_t pkts_per_ack + ); + + /************************************************************************ + * Utilities + ***********************************************************************/ + std::string get_name() const { return _name; } + + +private: + + //! Optional: A string to describe this graph + const std::string _name; + + //! Reference to the generating device object + const boost::weak_ptr _device_ptr; + +}; + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP */ +// vim: sw=4 et: diff --git a/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp b/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp new file mode 100644 index 000000000..185b89f82 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/legacy_compat.hpp @@ -0,0 +1,49 @@ +// +// Copyright 2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_RFNOC_LEGACY_COMPAT_HPP +#define INCLUDED_RFNOC_LEGACY_COMPAT_HPP + +#include +#include + +namespace uhd { namespace rfnoc { + + /*! Legacy compatibility layer class. + */ + class legacy_compat + { + public: + typedef boost::shared_ptr sptr; + + virtual uhd::fs_path rx_dsp_root(const size_t mboard_idx, const size_t chan) = 0; + + virtual uhd::fs_path tx_dsp_root(const size_t mboard_idx, const size_t chan) = 0; + + virtual uhd::fs_path rx_fe_root(const size_t mboard_idx, const size_t chan) = 0; + + virtual uhd::fs_path tx_fe_root(const size_t mboard_idx, const size_t chan) = 0; + + virtual void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, size_t mboard, size_t chan) = 0; + + virtual uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args) = 0; + + virtual uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args) = 0; + + virtual void set_rx_rate(const double rate, const size_t chan) = 0; + + virtual void set_tx_rate(const double rate, const size_t chan) = 0; + + static sptr make( + uhd::device3::sptr device, + const uhd::device_addr_t &args + ); + }; + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_RFNOC_LEGACY_COMPAT_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp new file mode 100644 index 000000000..a5876584e --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/radio_ctrl_impl.hpp @@ -0,0 +1,247 @@ +// +// Copyright 2014-2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP +#define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +//! Shorthand for radio block constructor +#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(CLASS_NAME) \ + CLASS_NAME##_impl(const make_args_t &make_args); + +#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(CLASS_NAME) \ + CLASS_NAME##_impl::CLASS_NAME##_impl( \ + const make_args_t &make_args \ + ) : block_ctrl_base(make_args), radio_ctrl_impl() + +namespace uhd { + namespace rfnoc { + +/*! \brief Provide access to a radio. + * + */ +class radio_ctrl_impl : public radio_ctrl +{ +public: + /************************************************************************ + * Structors + ***********************************************************************/ + radio_ctrl_impl(); + virtual ~radio_ctrl_impl() {}; + + /************************************************************************ + * Public Radio API calls + ***********************************************************************/ + virtual double set_rate(double rate); + virtual void set_tx_antenna(const std::string &ant, const size_t chan); + virtual void set_rx_antenna(const std::string &ant, const size_t chan); + virtual double set_tx_frequency(const double freq, const size_t chan); + virtual double set_rx_frequency(const double freq, const size_t chan); + virtual double set_tx_gain(const double gain, const size_t chan); + virtual double set_rx_gain(const double gain, const size_t chan); + virtual double set_tx_bandwidth(const double bandwidth, const size_t chan); + virtual double set_rx_bandwidth(const double bandwidth, const size_t chan); + + virtual double get_rate() const; + virtual std::string get_tx_antenna(const size_t chan) /* const */; + virtual std::string get_rx_antenna(const size_t chan) /* const */; + virtual double get_tx_frequency(const size_t) /* const */; + virtual double get_rx_frequency(const size_t) /* const */; + virtual double get_tx_gain(const size_t) /* const */; + virtual double get_rx_gain(const size_t) /* const */; + virtual double get_tx_bandwidth(const size_t) /* const */; + virtual double get_rx_bandwidth(const size_t) /* const */; + + virtual std::vector get_rx_lo_names(const size_t chan); + virtual std::vector get_rx_lo_sources(const std::string &name, const size_t chan); + virtual freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan); + + virtual void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan); + virtual const std::string get_rx_lo_source(const std::string &name, const size_t chan); + + virtual void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan); + virtual bool get_rx_lo_export_enabled(const std::string &name, const size_t chan); + + virtual double set_rx_lo_freq(const double freq, const std::string &name, const size_t chan); + virtual double get_rx_lo_freq(const std::string &name, const size_t chan); + + virtual std::vector get_tx_lo_names(const size_t chan); + virtual std::vector get_tx_lo_sources(const std::string &name, const size_t chan); + virtual freq_range_t get_tx_lo_freq_range(const std::string &name, const size_t chan); + + virtual void set_tx_lo_source(const std::string &src, const std::string &name, const size_t chan); + virtual const std::string get_tx_lo_source(const std::string &name, const size_t chan); + + virtual void set_tx_lo_export_enabled(const bool enabled, const std::string &name, const size_t chan); + virtual bool get_tx_lo_export_enabled(const std::string &name, const size_t chan); + + virtual double set_tx_lo_freq(const double freq, const std::string &name, const size_t chan); + virtual double get_tx_lo_freq(const std::string &name, const size_t chan); + + void set_time_now(const time_spec_t &time_spec); + void set_time_next_pps(const time_spec_t &time_spec); + void set_time_sync(const uhd::time_spec_t &time); + time_spec_t get_time_now(); + time_spec_t get_time_last_pps(); + virtual void set_time_source(const std::string &source); + virtual std::string get_time_source(); + virtual std::vector get_time_sources(); + virtual void set_clock_source(const std::string &source); + virtual std::string get_clock_source(); + virtual std::vector get_clock_sources(); + + virtual std::vector get_gpio_banks() const; + virtual void set_gpio_attr( + const std::string &bank, + const std::string &attr, + const uint32_t value, + const uint32_t mask + ); + virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr); + + /*********************************************************************** + * Block control API calls + **********************************************************************/ + void set_rx_streamer(bool active, const size_t port); + void set_tx_streamer(bool active, const size_t port); + + void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t port); + + virtual double get_input_samp_rate(size_t /* port */) { return get_rate(); } + virtual double get_output_samp_rate(size_t /* port */) { return get_rate(); } + double _get_tick_rate() { return get_rate(); } + + std::vector get_active_rx_ports(); + bool in_continuous_streaming_mode(const size_t chan) { return _continuous_streaming.at(chan); } + void rx_ctrl_clear_cmds(const size_t port) { sr_write(regs::RX_CTRL_CLEAR_CMDS, 0, port); } + +protected: // TODO see what's protected and what's private + void _register_loopback_self_test(size_t chan); + + /*********************************************************************** + * Registers + **********************************************************************/ + struct regs { + static inline uint32_t sr_addr(const uint32_t offset) + { + return offset * 4; + } + + static const uint32_t BASE = 128; + + // defined in radio_core_regs.vh + static const uint32_t TIME = 128; // time hi - 128, time lo - 129, ctrl - 130 + static const uint32_t CLEAR_CMDS = 131; // Any write to this reg clears the command FIFO + static const uint32_t LOOPBACK = 132; + static const uint32_t TEST = 133; + static const uint32_t CODEC_IDLE = 134; + static const uint32_t TX_CTRL_ERROR_POLICY = 144; + static const uint32_t RX_CTRL_CMD = 152; + static const uint32_t RX_CTRL_TIME_HI = 153; + static const uint32_t RX_CTRL_TIME_LO = 154; + static const uint32_t RX_CTRL_HALT = 155; + static const uint32_t RX_CTRL_MAXLEN = 156; + static const uint32_t RX_CTRL_CLEAR_CMDS = 157; + static const uint32_t MISC_OUTS = 160; + static const uint32_t DACSYNC = 161; + static const uint32_t SPI = 168; + static const uint32_t LEDS = 176; + static const uint32_t FP_GPIO = 184; + static const uint32_t GPIO = 192; + // NOTE: Upper 32 registers (224-255) are reserved for the output settings bus for use with + // device specific front end control + + // frontend control: needs rethinking TODO + //static const uint32_t TX_FRONT = BASE + 96; + //static const uint32_t RX_FRONT = BASE + 112; + //static const uint32_t READBACK = BASE + 127; + + static const uint32_t RB_TIME_NOW = 0; + static const uint32_t RB_TIME_PPS = 1; + static const uint32_t RB_TEST = 2; + static const uint32_t RB_CODEC_READBACK = 3; + static const uint32_t RB_RADIO_NUM = 4; + static const uint32_t RB_MISC_IO = 16; + static const uint32_t RB_SPI = 17; + static const uint32_t RB_LEDS = 18; + static const uint32_t RB_DB_GPIO = 19; + static const uint32_t RB_FP_GPIO = 20; + }; + + /*********************************************************************** + * Block control API calls + **********************************************************************/ + void _update_spp(int spp); + + inline size_t _get_num_radios() const { + return std::max(_num_rx_channels, _num_tx_channels); + } + + inline timed_wb_iface::sptr _get_ctrl(size_t radio_num) const { + return _perifs.at(radio_num).ctrl; + } + + inline bool _is_streamer_active(uhd::direction_t dir, const size_t chan) const { + switch (dir) { + case uhd::TX_DIRECTION: + return _tx_streamer_active.at(chan); + case uhd::RX_DIRECTION: + return _rx_streamer_active.at(chan); + case uhd::DX_DIRECTION: + return _rx_streamer_active.at(chan) and _tx_streamer_active.at(chan); + default: + return false; + } + } + + virtual bool check_radio_config() { return true; }; + + //! There is always only one time core per radio + time_core_3000::sptr _time64; + + std::mutex _mutex; + +private: + /************************************************************************ + * Peripherals + ***********************************************************************/ + //! Stores pointers to all streaming-related radio cores + struct radio_perifs_t + { + timed_wb_iface::sptr ctrl; + }; + std::map _perifs; + + size_t _num_tx_channels; + size_t _num_rx_channels; + + // Cached values + double _tick_rate; + std::map _tx_antenna; + std::map _rx_antenna; + std::map _tx_freq; + std::map _rx_freq; + std::map _tx_gain; + std::map _rx_gain; + std::map _tx_bandwidth; + std::map _rx_bandwidth; + + std::vector _continuous_streaming; +}; /* class radio_ctrl_impl */ + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP */ +// vim: sw=4 et: diff --git a/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp b/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp new file mode 100644 index 000000000..91091d8c2 --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/rpc_block_ctrl.hpp @@ -0,0 +1,41 @@ +// +// Copyright 2017 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP +#define INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP + +#include +#include + +namespace uhd { + namespace rfnoc { + +/*! Abstraction for RPC client + * + * Purpose of this class is to wrap the underlying RPC implementation. + * This class holds a connection to an RPC server (the connection is severed on + * destruction). + */ +class rpc_block_ctrl +{ +public: + virtual ~rpc_block_ctrl() {} + + /*! Pass in an RPC client for the block to use + * + * \param rpcc Reference to the RPC client + * \param block_args Additional block arguments + */ + virtual void set_rpc_client( + uhd::rpc_client::sptr rpcc, + const uhd::device_addr_t &block_args + ) = 0; + +}; + +}} + +#endif /* INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp b/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp new file mode 100644 index 000000000..3f82ab12f --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/rx_stream_terminator.hpp @@ -0,0 +1,79 @@ +// +// Copyright 2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP +#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP + +#include +#include +#include +#include +#include +#include // For the block macros +#include + +namespace uhd { + namespace rfnoc { + +/*! \brief Terminator node for Rx streamers. + * + * This node is only used by rx_streamers. It terminates the flow graph + * inside the streamer and does not have a counterpart on the FPGA. + */ +class rx_stream_terminator : + public sink_node_ctrl, + public rate_node_ctrl, + public tick_node_ctrl, + public scalar_node_ctrl, + public terminator_node_ctrl +{ +public: + UHD_RFNOC_BLOCK_OBJECT(rx_stream_terminator) + + static sptr make() + { + return sptr(new rx_stream_terminator); + } + + // If this is called, then by a send terminator at the other end + // of a flow graph. + double get_input_samp_rate(size_t) { return _samp_rate; }; + + // Same for the scaling factor + double get_input_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; }; + + std::string unique_id() const; + + void set_rx_streamer(bool active, const size_t port); + + void set_tx_streamer(bool active, const size_t port); + + virtual ~rx_stream_terminator(); + + void handle_overrun(boost::weak_ptr, const size_t); + +protected: + rx_stream_terminator(); + + virtual double _get_tick_rate() { return _tick_rate; }; + +private: + //! Every terminator has a unique index + const size_t _term_index; + static size_t _count; + + double _samp_rate; + double _tick_rate; + + std::mutex _overrun_handler_mutex; + +}; /* class rx_stream_terminator */ + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP */ +// vim: sw=4 et: diff --git a/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp b/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp new file mode 100644 index 000000000..0a07e48ef --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/tx_stream_terminator.hpp @@ -0,0 +1,80 @@ +// +// Copyright 2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP +#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP + +#include +#include +#include +#include +#include +#include // For the block macros +#include + +namespace uhd { + namespace rfnoc { + +/*! \brief Terminator node for Tx streamers. + * + * This node is only used by tx_streamers. It terminates the flow graph + * inside the streamer and does not have a counterpart on the FPGA. + */ +class tx_stream_terminator : + public source_node_ctrl, + public rate_node_ctrl, + public tick_node_ctrl, + public scalar_node_ctrl, + public terminator_node_ctrl +{ +public: + UHD_RFNOC_BLOCK_OBJECT(tx_stream_terminator) + + static sptr make() + { + return sptr(new tx_stream_terminator); + } + + void issue_stream_cmd(const uhd::stream_cmd_t &, const size_t) + { + UHD_RFNOC_BLOCK_TRACE() << "tx_stream_terminator::issue_stream_cmd()" ; + } + + // If this is called, then by a send terminator at the other end + // of a flow graph. + double get_output_samp_rate(size_t) { return _samp_rate; }; + + // Same for the scaling factor + double get_output_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; }; + + std::string unique_id() const; + + void set_rx_streamer(bool active, const size_t port); + + void set_tx_streamer(bool active, const size_t port); + + virtual ~tx_stream_terminator(); + +protected: + tx_stream_terminator(); + + virtual double _get_tick_rate() { return _tick_rate; }; + +private: + //! Every terminator has a unique index + const size_t _term_index; + static size_t _count; + + double _samp_rate; + double _tick_rate; + +}; /* class tx_stream_terminator */ + +}} /* namespace uhd::rfnoc */ + +#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP */ +// vim: sw=4 et: diff --git a/host/lib/include/uhdlib/rfnoc/utils.hpp b/host/lib/include/uhdlib/rfnoc/utils.hpp new file mode 100644 index 000000000..28c69987f --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/utils.hpp @@ -0,0 +1,67 @@ +// +// Copyright 2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_RFNOC_UTILS_HPP +#define INCLUDED_LIBUHD_RFNOC_UTILS_HPP + +#include +#include +#include + +namespace uhd { namespace rfnoc { namespace utils { + + /*! If \p suggested_port equals ANY_PORT, return the first available + * port number on \p nodes. Otherwise, return \p suggested_port. + * + * If \p allowed_ports is given, another condition is that the port + * number must be listed in here. + * If \p allowed_ports is not specified or empty, the assumption is + * that all ports are valid. + * + * On failure, ANY_PORT is returned. + */ + static size_t node_map_find_first_free( + node_ctrl_base::node_map_t nodes, + const size_t suggested_port, + const std::set allowed_ports=std::set() + ) { + size_t port = suggested_port; + if (port == ANY_PORT) { + if (allowed_ports.empty()) { + port = 0; + while (nodes.count(port) and (port != ANY_PORT)) { + port++; + } + } else { + for(const size_t allowed_port: allowed_ports) { + if (not nodes.count(port)) { + return allowed_port; + } + return ANY_PORT; + } + } + } else { + if (not (allowed_ports.empty() or allowed_ports.count(port))) { + return ANY_PORT; + } + } + return port; + } + + template + static std::set str_list_to_set(const std::vector &list) { + std::set return_set; + for(const std::string &S: list) { + return_set.insert(boost::lexical_cast(S)); + } + return return_set; + } + +}}}; /* namespace uhd::rfnoc::utils */ + +#endif /* INCLUDED_LIBUHD_RFNOC_UTILS_HPP */ +// vim: sw=4 et: diff --git a/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp b/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp new file mode 100644 index 000000000..753fa13af --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/wb_iface_adapter.hpp @@ -0,0 +1,60 @@ +// +// Copyright 2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP +#define INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP + +#include +#include +#include + +namespace uhd { + namespace rfnoc { + +class UHD_API wb_iface_adapter : public uhd::timed_wb_iface +{ +public: + typedef boost::shared_ptr sptr; + typedef boost::function poke32_type; + typedef boost::function peek32_type; + typedef boost::function peek64_type; + typedef boost::function gettime_type; + typedef boost::function settime_type; + + wb_iface_adapter( + const poke32_type &, + const peek32_type &, + const peek64_type &, + const gettime_type &, + const settime_type & + ); + + wb_iface_adapter( + const poke32_type &, + const peek32_type &, + const peek64_type & + ); + + virtual ~wb_iface_adapter(void) {}; + + virtual void poke32(const wb_addr_type addr, const uint32_t data); + virtual uint32_t peek32(const wb_addr_type addr); + virtual uint64_t peek64(const wb_addr_type addr); + virtual time_spec_t get_time(void); + virtual void set_time(const time_spec_t& t); + +private: + const poke32_type poke32_functor; + const peek32_type peek32_functor; + const peek64_type peek64_functor; + const gettime_type gettime_functor; + const settime_type settime_functor; +}; + +}} // namespace uhd::rfnoc + +#endif /* INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP */ diff --git a/host/lib/include/uhdlib/rfnoc/xports.hpp b/host/lib/include/uhdlib/rfnoc/xports.hpp new file mode 100644 index 000000000..5ee65175a --- /dev/null +++ b/host/lib/include/uhdlib/rfnoc/xports.hpp @@ -0,0 +1,29 @@ +// +// Copyright 2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include +#include +#include + +namespace uhd { + + /*! Holds all necessary items for a bidirectional link + */ + struct both_xports_t + { + both_xports_t(): recv_buff_size(0), send_buff_size(0) {} + uhd::transport::zero_copy_if::sptr recv; + uhd::transport::zero_copy_if::sptr send; + size_t recv_buff_size; + size_t send_buff_size; + uhd::sid_t send_sid; + uhd::sid_t recv_sid; + uhd::endianness_t endianness; + }; + +}; + diff --git a/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp b/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp new file mode 100644 index 000000000..b9e81074b --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/ad9361_ctrl.hpp @@ -0,0 +1,161 @@ +// +// Copyright 2012-2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_AD9361_CTRL_HPP +#define INCLUDED_AD9361_CTRL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace uhd { namespace usrp { + +/*! AD936x Control Interface + * + * This is a convenient way to access the AD936x RF IC. + * It basically encodes knowledge of register values etc. into + * accessible API calls. + * + * \section ad936x_which The `which` parameter + * + * Many function calls require a `which` parameter to select + * the RF frontend. Valid values for `which` are: + * - RX1, RX2 + * - TX1, TX2 + * + * Frontend numbering is as designed by the AD9361. + */ +class ad9361_ctrl : public boost::noncopyable +{ +public: + typedef boost::shared_ptr sptr; + + virtual ~ad9361_ctrl(void) {}; + + //! make a new codec control object + static sptr make_spi( + ad9361_params::sptr client_settings, + uhd::spi_iface::sptr spi_iface, + uint32_t slave_num + ); + + virtual void set_timed_spi(uhd::spi_iface::sptr spi_iface, uint32_t slave_num) = 0; + virtual void set_safe_spi(uhd::spi_iface::sptr spi_iface, uint32_t slave_num) = 0; + + //! Get a list of gain names for RX or TX + static std::vector get_gain_names(const std::string &/*which*/) + { + return std::vector(1, "PGA"); + } + + //! get the gain range for a particular gain element + static uhd::meta_range_t get_gain_range(const std::string &which) + { + if(which[0] == 'R') { + return uhd::meta_range_t(0.0, 76.0, 1.0); + } else { + return uhd::meta_range_t(0.0, 89.75, 0.25); + } + } + + //! get the freq range for the frontend which + static uhd::meta_range_t get_rf_freq_range(void) + { + return uhd::meta_range_t(50e6, 6e9); + } + + //! get the filter range for the frontend which + static uhd::meta_range_t get_bw_filter_range(const std::string &/*which*/) + { + return uhd::meta_range_t(200e3, 56e6); + } + + //! get the clock rate range for the frontend + static uhd::meta_range_t get_clock_rate_range(void) + { + return uhd::meta_range_t( + ad9361_device_t::AD9361_MIN_CLOCK_RATE, + ad9361_device_t::AD9361_MAX_CLOCK_RATE + ); + } + + //! set the filter bandwidth for the frontend's analog low pass + virtual double set_bw_filter(const std::string &/*which*/, const double /*bw*/) = 0; + + //! set the gain for a particular gain element + virtual double set_gain(const std::string &which, const double value) = 0; + + //! Enable or disable the AGC module + virtual void set_agc(const std::string &which, bool enable) = 0; + + //! configure the AGC module to slow or fast mode + virtual void set_agc_mode(const std::string &which, const std::string &mode) = 0; + + //! set a new clock rate, return the exact value + virtual double set_clock_rate(const double rate) = 0; + + //! set which RX and TX chains/antennas are active + virtual void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) = 0; + + //! tune the given frontend, return the exact value + virtual double tune(const std::string &which, const double value) = 0; + + //! set the DC offset for I and Q manually + void set_dc_offset(const std::string &, const std::complex) + { + //This feature should not be used according to Analog Devices + throw uhd::runtime_error("ad9361_ctrl::set_dc_offset this feature is not supported on this device."); + } + + //! enable or disable the BB/RF DC tracking feature + virtual void set_dc_offset_auto(const std::string &which, const bool on) = 0; + + //! set the IQ correction value manually + void set_iq_balance(const std::string &, const std::complex) + { + //This feature should not be used according to Analog Devices + throw uhd::runtime_error("ad9361_ctrl::set_iq_balance this feature is not supported on this device."); + } + + //! enable or disable the quadrature calibration + virtual void set_iq_balance_auto(const std::string &which, const bool on) = 0; + + //! get the current frequency for the given frontend + virtual double get_freq(const std::string &which) = 0; + + //! turn on/off Catalina's data port loopback + virtual void data_port_loopback(const bool on) = 0; + + //! read internal RSSI sensor + virtual sensor_value_t get_rssi(const std::string &which) = 0; + + //! read the internal temp sensor + virtual sensor_value_t get_temperature() = 0; + + //! List all available filters by name + virtual std::vector get_filter_names(const std::string &which) = 0; + + //! Return a list of all filters + virtual filter_info_base::sptr get_filter(const std::string &which, const std::string &filter_name) = 0; + + //! Write back a filter + virtual void set_filter(const std::string &which, const std::string &filter_name, const filter_info_base::sptr) = 0; + + virtual void output_digital_test_tone(bool enb) = 0; +}; + +}} + +#endif /* INCLUDED_AD9361_CTRL_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp b/host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp new file mode 100644 index 000000000..7934b1050 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/ad936x_manager.hpp @@ -0,0 +1,122 @@ +// +// Copyright 2015 Ettus Research +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_AD9361_MANAGER_HPP +#define INCLUDED_AD9361_MANAGER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace uhd { namespace usrp { + +/*! AD936x Manager class + * + * This class performs higher (management) tasks on the AD936x. + * It requires a uhd::usrp::ad9361_ctrl object to do the actual + * register peeks/pokes etc. + */ +class ad936x_manager +{ +public: + typedef boost::shared_ptr sptr; + + static const double DEFAULT_GAIN; + static const double DEFAULT_BANDWIDTH; + static const double DEFAULT_TICK_RATE; + static const double DEFAULT_FREQ; // Hz + static const uint32_t DEFAULT_DECIM; + static const uint32_t DEFAULT_INTERP; + static const bool DEFAULT_AUTO_DC_OFFSET; + static const bool DEFAULT_AUTO_IQ_BALANCE; + static const bool DEFAULT_AGC_ENABLE; + + /*! + * \param codec_ctrl The actual AD936x control object + * \param n_frontends Number of frontends (1 or 2) + */ + static sptr make( + const ad9361_ctrl::sptr &codec_ctrl, + const size_t n_frontends + ); + + virtual ~ad936x_manager(void) {}; + + /*! Put the AD936x into a default state. + * + * Sets gains, LOs, bandwidths, etc. according to the DEFAULT_* constants. + */ + virtual void init_codec(void) = 0; + + /*! Run a loopback self test. + * + * This will write data to the AD936x and read it back again. + * If this test fails, it generally means the interface is broken, + * so we assume it passes and throw otherwise. Running this requires + * a core that we can peek and poke the loopback values into. + * + * \param iface An interface to the associated radio control core + * \param iface The radio control core's address to write the loopback value + * \param iface The radio control core's readback address to read back the returned value + * + * \throws a uhd::runtime_error if the loopback value didn't match. + */ + virtual void loopback_self_test( + boost::function poker_functor, + boost::function peeker_functor + ) = 0; + + /*! Determine a tick rate that will work with a given sampling rate + * (assuming a DDC/DUC chain is also available elsewhere). + * + * Example: If we want to stream with a rate of 5 Msps, then the AD936x + * must run at an integer multiple of that. Although not strictly necessary, + * we always try and return a multiple of 2. Let's say we need those 5 Msps + * on two channels, then a good rate is 20 MHz, which is 4 times the sampling + * rate (thus we can use 2 halfbands elsewhere). + * If different rates are used on different channels, this can be particularly + * useful. The clock rate of the AD936x needs to be a multiple of the least + * common multiple of all the rates. Example: We want to transmit with 3 Msps + * and receive with 5 Msps. The LCM of this is 15 Msps, which is used as an + * argument for this function. A good rate is then 30 MHz, which is twice + * the LCM. + * + * \param lcm_rate Least Common Multiple of all the rates involved. + * \param num_chans The number of channels used for the stream. + * + * \returns a valid tick rate that can be used with the given rate + * \throws a uhd::value_error if \p lcm_rate exceeds the max tick rate + */ + virtual double get_auto_tick_rate( + const double lcm_rate, + size_t num_chans + ) = 0; + + /*! Check if a given sampling rate is within the available analog bandwidth. + * + * If not, outputs a warning message and returns false. + */ + virtual bool check_bandwidth(double rate, const std::string dir) = 0; + + /*! Populate the property tree for the device frontend + */ + virtual void populate_frontend_subtree( + uhd::property_tree::sptr subtree, + const std::string &key, + uhd::direction_t dir + ) = 0; + +}; /* class ad936x_manager */ + +}} /* namespace uhd::usrp */ + +#endif /* INCLUDED_AD9361_MANAGER_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp b/host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp new file mode 100644 index 000000000..8aa449539 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/adf4001_ctrl.hpp @@ -0,0 +1,131 @@ +// +// Copyright 2013 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// Original ADF4001 driver written by: bistromath +// Mar 1, 2013 +// +// Re-used and re-licensed with permission. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_ADF4001_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_ADF4001_HPP + +#include +#include +#include +#include + +namespace uhd { namespace usrp { + +class adf4001_regs_t { +public: + + /* Function prototypes */ + uint32_t get_reg(uint8_t addr); + adf4001_regs_t(void); + + /* Register values / addresses */ + uint16_t ref_counter; //14 bits + uint16_t n; //13 bits + uint8_t charge_pump_current_1; //3 bits + uint8_t charge_pump_current_2; //3 bits + + enum anti_backlash_width_t { + ANTI_BACKLASH_WIDTH_2_9NS = 0, + ANTI_BACKLASH_WIDTH_1_3NS = 1, + ANTI_BACKLASH_WIDTH_6_0NS = 2, + ANTI_BACKLASH_WIDTH_2_9NS_WAT = 3 + }; + anti_backlash_width_t anti_backlash_width; + + enum lock_detect_precision_t { + LOCK_DETECT_PRECISION_3CYC = 0, + LOCK_DETECT_PRECISION_5CYC = 1 + }; + lock_detect_precision_t lock_detect_precision; + enum charge_pump_gain_t { + CHARGE_PUMP_GAIN_1 = 0, + CHARGE_PUMP_GAIN_2 = 1 + }; + charge_pump_gain_t charge_pump_gain; + enum counter_reset_t { + COUNTER_RESET_NORMAL = 0, + COUNTER_RESET_RESET = 1 + }; + counter_reset_t counter_reset; + enum power_down_t { + POWER_DOWN_NORMAL = 0, + POWER_DOWN_ASYNC = 1, + POWER_DOWN_SYNC = 3 + }; + power_down_t power_down; + enum muxout_t { + MUXOUT_TRISTATE_OUT = 0, + MUXOUT_DLD = 1, + MUXOUT_NDIV = 2, + MUXOUT_AVDD = 3, + MUXOUT_RDIV = 4, + MUXOUT_NCH_OD_ALD = 5, + MUXOUT_SDO = 6, + MUXOUT_GND = 7 + }; + muxout_t muxout; + enum phase_detector_polarity_t { + PHASE_DETECTOR_POLARITY_NEGATIVE = 0, + PHASE_DETECTOR_POLARITY_POSITIVE = 1 + }; + phase_detector_polarity_t phase_detector_polarity; + enum charge_pump_mode_t { + CHARGE_PUMP_NORMAL = 0, + CHARGE_PUMP_TRISTATE = 1 + }; + charge_pump_mode_t charge_pump_mode; + enum fastlock_mode_t { + FASTLOCK_MODE_DISABLED = 0, + FASTLOCK_MODE_1 = 1, + FASTLOCK_MODE_2 = 2 + }; + fastlock_mode_t fastlock_mode; + enum timer_counter_control_t { + TIMEOUT_3CYC = 0, + TIMEOUT_7CYC = 1, + TIMEOUT_11CYC = 2, + TIMEOUT_15CYC = 3, + TIMEOUT_19CYC = 4, + TIMEOUT_23CYC = 5, + TIMEOUT_27CYC = 6, + TIMEOUT_31CYC = 7, + TIMEOUT_35CYC = 8, + TIMEOUT_39CYC = 9, + TIMEOUT_43CYC = 10, + TIMEOUT_47CYC = 11, + TIMEOUT_51CYC = 12, + TIMEOUT_55CYC = 13, + TIMEOUT_59CYC = 14, + TIMEOUT_63CYC = 15, + }; + timer_counter_control_t timer_counter_control; +}; + + +class adf4001_ctrl { +public: + adf4001_ctrl(uhd::spi_iface::sptr _spi, int slaveno); + virtual void set_lock_to_ext_ref(bool external); + +private: + uhd::spi_iface::sptr spi_iface; + int slaveno; + spi_config_t spi_config; + adf4001_regs_t adf4001_regs; + + void program_regs(void); + void write_reg(uint8_t addr); +}; + +}} + +#endif diff --git a/host/lib/include/uhdlib/usrp/common/adf435x.hpp b/host/lib/include/uhdlib/usrp/common/adf435x.hpp new file mode 100644 index 000000000..bd7b91b95 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/adf435x.hpp @@ -0,0 +1,422 @@ +// +// Copyright 2015 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_ADF435X_HPP +#define INCLUDED_ADF435X_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "adf4350_regs.hpp" +#include "adf4351_regs.hpp" + +class adf435x_iface +{ +public: + typedef boost::shared_ptr sptr; + typedef boost::function)> write_fn_t; + + static sptr make_adf4350(write_fn_t write); + static sptr make_adf4351(write_fn_t write); + + virtual ~adf435x_iface() = 0; + + enum output_t { RF_OUTPUT_A, RF_OUTPUT_B }; + + enum prescaler_t { PRESCALER_4_5, PRESCALER_8_9 }; + + enum feedback_sel_t { FB_SEL_FUNDAMENTAL, FB_SEL_DIVIDED }; + + enum output_power_t { OUTPUT_POWER_M4DBM, OUTPUT_POWER_M1DBM, OUTPUT_POWER_2DBM, OUTPUT_POWER_5DBM }; + + enum muxout_t { MUXOUT_3STATE, MUXOUT_DVDD, MUXOUT_DGND, MUXOUT_RDIV, MUXOUT_NDIV, MUXOUT_ALD, MUXOUT_DLD }; + + /** + * Charge Pump Currents + */ + enum charge_pump_current_t { + CHARGE_PUMP_CURRENT_0_31MA = 0, + CHARGE_PUMP_CURRENT_0_63MA = 1, + CHARGE_PUMP_CURRENT_0_94MA = 2, + CHARGE_PUMP_CURRENT_1_25MA = 3, + CHARGE_PUMP_CURRENT_1_56MA = 4, + CHARGE_PUMP_CURRENT_1_88MA = 5, + CHARGE_PUMP_CURRENT_2_19MA = 6, + CHARGE_PUMP_CURRENT_2_50MA = 7, + CHARGE_PUMP_CURRENT_2_81MA = 8, + CHARGE_PUMP_CURRENT_3_13MA = 9, + CHARGE_PUMP_CURRENT_3_44MA = 10, + CHARGE_PUMP_CURRENT_3_75MA = 11, + CHARGE_PUMP_CURRENT_4_07MA = 12, + CHARGE_PUMP_CURRENT_4_38MA = 13, + CHARGE_PUMP_CURRENT_4_69MA = 14, + CHARGE_PUMP_CURRENT_5_00MA = 15 + }; + + + virtual void set_reference_freq(double fref) = 0; + + virtual void set_prescaler(prescaler_t prescaler) = 0; + + virtual void set_feedback_select(feedback_sel_t fb_sel) = 0; + + virtual void set_output_power(output_t output, output_power_t power) = 0; + + void set_output_power(output_power_t power) { + set_output_power(RF_OUTPUT_A, power); + } + + virtual void set_output_enable(output_t output, bool enable) = 0; + + virtual void set_muxout_mode(muxout_t mode) = 0; + + virtual void set_charge_pump_current(charge_pump_current_t cp_current) = 0; + + virtual uhd::range_t get_int_range() = 0; + + virtual double set_frequency(double target_freq, bool int_n_mode, bool flush = false) = 0; + + virtual void commit(void) = 0; +}; + +template +class adf435x_impl : public adf435x_iface +{ +public: + adf435x_impl(write_fn_t write_fn) : + _write_fn(write_fn), + _regs(), + _fb_after_divider(false), + _reference_freq(0.0), + _N_min(-1) + {} + + virtual ~adf435x_impl() {}; + + void set_reference_freq(double fref) + { + _reference_freq = fref; + } + + void set_feedback_select(feedback_sel_t fb_sel) + { + _fb_after_divider = (fb_sel == FB_SEL_DIVIDED); + } + + void set_prescaler(prescaler_t prescaler) + { + if (prescaler == PRESCALER_8_9) { + _regs.prescaler = adf435x_regs_t::PRESCALER_8_9; + _N_min = 75; + } else { + _regs.prescaler = adf435x_regs_t::PRESCALER_4_5; + _N_min = 23; + } + } + + void set_output_power(output_t output, output_power_t power) + { + switch (output) { + case RF_OUTPUT_A: + switch (power) { + case OUTPUT_POWER_M4DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M4DBM; break; + case OUTPUT_POWER_M1DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M1DBM; break; + case OUTPUT_POWER_2DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_2DBM; break; + case OUTPUT_POWER_5DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_5DBM; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + break; + case RF_OUTPUT_B: + switch (power) { + case OUTPUT_POWER_M4DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M4DBM; break; + case OUTPUT_POWER_M1DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M1DBM; break; + case OUTPUT_POWER_2DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_2DBM; break; + case OUTPUT_POWER_5DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_5DBM; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } + } + + void set_output_enable(output_t output, bool enable) + { + switch (output) { + case RF_OUTPUT_A: _regs.rf_output_enable = enable ? adf435x_regs_t::RF_OUTPUT_ENABLE_ENABLED: + adf435x_regs_t::RF_OUTPUT_ENABLE_DISABLED; + break; + case RF_OUTPUT_B: _regs.aux_output_enable = enable ? adf435x_regs_t::AUX_OUTPUT_ENABLE_ENABLED: + adf435x_regs_t::AUX_OUTPUT_ENABLE_DISABLED; + break; + } + } + + void set_muxout_mode(muxout_t mode) + { + switch (mode) { + case MUXOUT_3STATE: _regs.muxout = adf435x_regs_t::MUXOUT_3STATE; break; + case MUXOUT_DVDD: _regs.muxout = adf435x_regs_t::MUXOUT_DVDD; break; + case MUXOUT_DGND: _regs.muxout = adf435x_regs_t::MUXOUT_DGND; break; + case MUXOUT_RDIV: _regs.muxout = adf435x_regs_t::MUXOUT_RDIV; break; + case MUXOUT_NDIV: _regs.muxout = adf435x_regs_t::MUXOUT_NDIV; break; + case MUXOUT_ALD: _regs.muxout = adf435x_regs_t::MUXOUT_ANALOG_LD; break; + case MUXOUT_DLD: _regs.muxout = adf435x_regs_t::MUXOUT_DLD; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + } + + void set_charge_pump_current(charge_pump_current_t cp_current) + { + switch (cp_current) { + case CHARGE_PUMP_CURRENT_0_31MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_31MA; break; + case CHARGE_PUMP_CURRENT_0_63MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_63MA; break; + case CHARGE_PUMP_CURRENT_0_94MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_94MA; break; + case CHARGE_PUMP_CURRENT_1_25MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_25MA; break; + case CHARGE_PUMP_CURRENT_1_56MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_56MA; break; + case CHARGE_PUMP_CURRENT_1_88MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_88MA; break; + case CHARGE_PUMP_CURRENT_2_19MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_19MA; break; + case CHARGE_PUMP_CURRENT_2_50MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_50MA; break; + case CHARGE_PUMP_CURRENT_2_81MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_81MA; break; + case CHARGE_PUMP_CURRENT_3_13MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_13MA; break; + case CHARGE_PUMP_CURRENT_3_44MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_44MA; break; + case CHARGE_PUMP_CURRENT_3_75MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_75MA; break; + case CHARGE_PUMP_CURRENT_4_07MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_07MA; break; + case CHARGE_PUMP_CURRENT_4_38MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_38MA; break; + case CHARGE_PUMP_CURRENT_4_69MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_69MA; break; + case CHARGE_PUMP_CURRENT_5_00MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_5_00MA; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + } + + uhd::range_t get_int_range() + { + if (_N_min < 0) throw uhd::runtime_error("set_prescaler must be called before get_int_range"); + return uhd::range_t(_N_min, 4095); + } + + double set_frequency(double target_freq, bool int_n_mode, bool flush = false) + { + static const double REF_DOUBLER_THRESH_FREQ = 12.5e6; + static const double PFD_FREQ_MAX = 25.0e6; + static const double BAND_SEL_FREQ_MAX = 100e3; + static const double VCO_FREQ_MIN = 2.2e9; + static const double VCO_FREQ_MAX = 4.4e9; + + //Default invalid value for actual_freq + double actual_freq = 0; + + uhd::range_t rf_divider_range = _get_rfdiv_range(); + uhd::range_t int_range = get_int_range(); + + double pfd_freq = 0; + uint16_t R = 0, BS = 0, N = 0, FRAC = 0, MOD = 0; + uint16_t RFdiv = static_cast(rf_divider_range.start()); + bool D = false, T = false; + + //Reference doubler for 50% duty cycle + D = (_reference_freq <= REF_DOUBLER_THRESH_FREQ); + + //increase RF divider until acceptable VCO frequency + double vco_freq = target_freq; + while (vco_freq < VCO_FREQ_MIN && RFdiv < static_cast(rf_divider_range.stop())) { + vco_freq *= 2; + RFdiv *= 2; + } + + /* + * The goal here is to loop though possible R dividers, + * band select clock dividers, N (int) dividers, and FRAC + * (frac) dividers. + * + * Calculate the N and F dividers for each set of values. + * The loop exits when it meets all of the constraints. + * The resulting loop values are loaded into the registers. + * + * from pg.21 + * + * f_pfd = f_ref*(1+D)/(R*(1+T)) + * f_vco = (N + (FRAC/MOD))*f_pfd + * N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD + * f_actual = f_vco/RFdiv) + */ + double feedback_freq = _fb_after_divider ? target_freq : vco_freq; + + for(R = 1; R <= 1023; R+=1){ + //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T) + pfd_freq = _reference_freq*(D?2:1)/(R*(T?2:1)); + + //keep the PFD frequency at or below 25MHz (Loop Filter Bandwidth) + if (pfd_freq > PFD_FREQ_MAX) continue; + + //First, ignore fractional part of tuning + N = uint16_t(std::floor(feedback_freq/pfd_freq)); + + //keep N > minimum int divider requirement + if (N < static_cast(int_range.start())) continue; + + for(BS=1; BS <= 255; BS+=1){ + //keep the band select frequency at or below band_sel_freq_max + //constraint on band select clock + if (pfd_freq/BS > BAND_SEL_FREQ_MAX) continue; + goto done_loop; + } + } done_loop: + + //Fractional-N calculation + MOD = 4095; //max fractional accuracy + FRAC = static_cast(boost::math::round((feedback_freq/pfd_freq - N)*MOD)); + if (int_n_mode) { + if (FRAC > (MOD / 2)) { //Round integer such that actual freq is closest to target + N++; + } + FRAC = 0; + } + + //Reference divide-by-2 for 50% duty cycle + // if R even, move one divide by 2 to to regs.reference_divide_by_2 + if(R % 2 == 0) { + T = true; + R /= 2; + } + + //Typical phase resync time documented in data sheet pg.24 + static const double PHASE_RESYNC_TIME = 400e-6; + + //If feedback after divider, then compensation for the divider is pulled into the INT value + int rf_div_compensation = _fb_after_divider ? 1 : RFdiv; + + //Compute the actual frequency in terms of _reference_freq, N, FRAC, MOD, D, R and T. + actual_freq = ( + double((N + (double(FRAC)/double(MOD))) * + (_reference_freq*(D?2:1)/(R*(T?2:1)))) + ) / rf_div_compensation; + + _regs.frac_12_bit = FRAC; + _regs.int_16_bit = N; + _regs.mod_12_bit = MOD; + _regs.clock_divider_12_bit = std::max(1, uint16_t(std::ceil(PHASE_RESYNC_TIME*pfd_freq/MOD))); + _regs.feedback_select = _fb_after_divider ? + adf435x_regs_t::FEEDBACK_SELECT_DIVIDED : + adf435x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; + _regs.clock_div_mode = _fb_after_divider ? + adf435x_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE : + adf435x_regs_t::CLOCK_DIV_MODE_FAST_LOCK; + _regs.r_counter_10_bit = R; + _regs.reference_divide_by_2 = T ? + adf435x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : + adf435x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; + _regs.reference_doubler = D ? + adf435x_regs_t::REFERENCE_DOUBLER_ENABLED : + adf435x_regs_t::REFERENCE_DOUBLER_DISABLED; + _regs.band_select_clock_div = uint8_t(BS); + _regs.rf_divider_select = static_cast(_get_rfdiv_setting(RFdiv)); + _regs.ldf = int_n_mode ? + adf435x_regs_t::LDF_INT_N : + adf435x_regs_t::LDF_FRAC_N; + + std::string tuning_str = (int_n_mode) ? "Integer-N" : "Fractional"; + UHD_LOGGER_TRACE("ADF435X") + << boost::format("ADF 435X Frequencies (MHz): REQUESTED=%0.9f, ACTUAL=%0.9f") + % (target_freq/1e6) % (actual_freq/1e6) + << boost::format("ADF 435X Intermediates (MHz): Feedback=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f, REF=%0.2f") + % (feedback_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) % (_reference_freq/1e6) + << boost::format("ADF 435X Tuning: %s") % tuning_str.c_str() + << boost::format("ADF 435X Settings: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d") + % R % BS % N % FRAC % MOD % T % D % RFdiv + ; + + UHD_ASSERT_THROW((_regs.frac_12_bit & ((uint16_t)~0xFFF)) == 0); + UHD_ASSERT_THROW((_regs.mod_12_bit & ((uint16_t)~0xFFF)) == 0); + UHD_ASSERT_THROW((_regs.clock_divider_12_bit & ((uint16_t)~0xFFF)) == 0); + UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0); + + UHD_ASSERT_THROW(vco_freq >= VCO_FREQ_MIN and vco_freq <= VCO_FREQ_MAX); + UHD_ASSERT_THROW(RFdiv >= static_cast(rf_divider_range.start())); + UHD_ASSERT_THROW(RFdiv <= static_cast(rf_divider_range.stop())); + UHD_ASSERT_THROW(_regs.int_16_bit >= static_cast(int_range.start())); + UHD_ASSERT_THROW(_regs.int_16_bit <= static_cast(int_range.stop())); + + if (flush) commit(); + return actual_freq; + } + + void commit() + { + //reset counters + _regs.counter_reset = adf435x_regs_t::COUNTER_RESET_ENABLED; + std::vector regs; + regs.push_back(_regs.get_reg(uint32_t(2))); + _write_fn(regs); + _regs.counter_reset = adf435x_regs_t::COUNTER_RESET_DISABLED; + + //write the registers + //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0) + regs.clear(); + for (int addr = 5; addr >= 0; addr--) { + regs.push_back(_regs.get_reg(uint32_t(addr))); + } + _write_fn(regs); + } + +protected: + uhd::range_t _get_rfdiv_range(); + int _get_rfdiv_setting(uint16_t div); + + write_fn_t _write_fn; + adf435x_regs_t _regs; + double _fb_after_divider; + double _reference_freq; + int _N_min; +}; + +template <> +inline uhd::range_t adf435x_impl::_get_rfdiv_range() +{ + return uhd::range_t(1, 16); +} + +template <> +inline uhd::range_t adf435x_impl::_get_rfdiv_range() +{ + return uhd::range_t(1, 64); +} + +template <> +inline int adf435x_impl::_get_rfdiv_setting(uint16_t div) +{ + switch (div) { + case 1: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV1); + case 2: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV2); + case 4: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV4); + case 8: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV8); + case 16: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV16); + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + +template <> +inline int adf435x_impl::_get_rfdiv_setting(uint16_t div) +{ + switch (div) { + case 1: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV1); + case 2: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV2); + case 4: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV4); + case 8: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV8); + case 16: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV16); + case 32: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV32); + case 64: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV64); + default: UHD_THROW_INVALID_CODE_PATH(); + } +} + +#endif // INCLUDED_ADF435X_HPP diff --git a/host/lib/include/uhdlib/usrp/common/adf535x.hpp b/host/lib/include/uhdlib/usrp/common/adf535x.hpp new file mode 100644 index 000000000..8380c9d04 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/adf535x.hpp @@ -0,0 +1,477 @@ +// +// Copyright 2015, 2017 Ettus Research, A National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_ADF535X_HPP +#define INCLUDED_ADF535X_HPP + +#include "adf5355_regs.hpp" +#include "adf5356_regs.hpp" +#include +#include +#include +#include //gcd +#include +#include +#include +#include +#include +#include + +class adf535x_iface +{ +public: + typedef std::shared_ptr sptr; + typedef std::function)> write_fn_t; + + static sptr make_adf5355(write_fn_t write); + static sptr make_adf5356(write_fn_t write); + + virtual ~adf535x_iface() = default; + + enum output_t { RF_OUTPUT_A, RF_OUTPUT_B }; + + enum feedback_sel_t { FB_SEL_FUNDAMENTAL, FB_SEL_DIVIDED }; + + enum output_power_t { OUTPUT_POWER_M4DBM, OUTPUT_POWER_M1DBM, OUTPUT_POWER_2DBM, OUTPUT_POWER_5DBM }; + + enum muxout_t { MUXOUT_3STATE, MUXOUT_DVDD, MUXOUT_DGND, MUXOUT_RDIV, MUXOUT_NDIV, MUXOUT_ALD, MUXOUT_DLD }; + + virtual void set_reference_freq(double fref, bool force = false) = 0; + + virtual void set_pfd_freq(double pfd_freq) = 0; + + virtual void set_feedback_select(feedback_sel_t fb_sel) = 0; + + virtual void set_output_power(output_power_t power) = 0; + + virtual void set_output_enable(output_t output, bool enable) = 0; + + virtual void set_muxout_mode(muxout_t mode) = 0; + + virtual double set_frequency(double target_freq, double freq_resolution, bool flush = false) = 0; + + virtual void commit() = 0; +}; + +using namespace uhd; + +namespace { + const double ADF535X_DOUBLER_MAX_REF_FREQ = 60e6; + const double ADF535X_MAX_FREQ_PFD = 125e6; +//const double ADF535X_PRESCALER_THRESH = 7e9; + + const double ADF535X_MIN_VCO_FREQ = 3.4e9; +//const double ADF535X_MAX_VCO_FREQ = 6.8e9; + const double ADF535X_MAX_OUT_FREQ = 6.8e9; + const double ADF535X_MIN_OUT_FREQ = (3.4e9 / 64); +//const double ADF535X_MAX_OUTB_FREQ = (6.8e9 * 2); +//const double ADF535X_MIN_OUTB_FREQ = (3.4e9 * 2); + + const double ADF535X_PHASE_RESYNC_TIME = 400e-6; + + const uint32_t ADF535X_MOD1 = 16777216; + const uint32_t ADF535X_MAX_MOD2 = 16383; + const uint32_t ADF535X_MAX_FRAC2 = 16383; +//const uint16_t ADF535X_MIN_INT_PRESCALER_89 = 75; +} + +template +class adf535x_impl : public adf535x_iface +{ +public: + explicit adf535x_impl(write_fn_t write_fn) : + _write_fn(std::move(write_fn)), + _regs(), + _rewrite_regs(true), + _wait_time_us(0), + _ref_freq(0.0), + _pfd_freq(0.0), + _fb_after_divider(false) + { + + _regs.vco_band_div = 3; + _regs.timeout = 11; + _regs.auto_level_timeout = 30; + _regs.synth_lock_timeout = 12; + + _regs.adc_clock_divider = 16; + _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED; + _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED; + + // TODO Needs to be enabled for phase resync + _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED; + + // TODO Default should be divided, but there seems to be a bug preventing that. Needs rechecking + _regs.feedback_select = adf535x_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; + } + + ~adf535x_impl() override + { + UHD_SAFE_CALL( + _regs.power_down = adf535x_regs_t::POWER_DOWN_ENABLED; + commit(); + ) + } + + void set_feedback_select(const feedback_sel_t fb_sel) override + { + _fb_after_divider = (fb_sel == FB_SEL_DIVIDED); + + if (_fb_after_divider) { + _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_DIVIDED; + } else { + _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; + } + } + + void set_pfd_freq(const double pfd_freq) override + { + if (pfd_freq > ADF535X_MAX_FREQ_PFD) { + UHD_LOGGER_ERROR("ADF535x") << boost::format("%f MHz is above the maximum PFD frequency of %f MHz\n") + % (pfd_freq/1e6) % (ADF535X_MAX_FREQ_PFD/1e6); + return; + } + _pfd_freq = pfd_freq; + + set_reference_freq(_ref_freq); + } + + void set_reference_freq(const double fref, const bool force = false) override + { + //Skip the body if the reference frequency does not change + if (uhd::math::frequencies_are_equal(fref, _ref_freq) and (not force)) + return; + + _ref_freq = fref; + + //----------------------------------------------------------- + //Set reference settings + int ref_div_factor = static_cast(std::floor(_ref_freq / _pfd_freq)); + + //Reference doubler for 50% duty cycle + const bool doubler_en = (_ref_freq <= ADF535X_DOUBLER_MAX_REF_FREQ); + if (doubler_en) { + ref_div_factor *= 2; + } + + //Reference divide-by-2 for 50% duty cycle + // if R even, move one divide by 2 to to regs.reference_divide_by_2 + const bool div2_en = (ref_div_factor % 2 == 0); + if (div2_en) { + ref_div_factor /= 2; + } + + _regs.reference_divide_by_2 = div2_en ? + adf535x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : + adf535x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; + _regs.reference_doubler = doubler_en ? + adf535x_regs_t::REFERENCE_DOUBLER_ENABLED : + adf535x_regs_t::REFERENCE_DOUBLER_DISABLED; + _regs.r_counter_10_bit = ref_div_factor; + UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0); + + //----------------------------------------------------------- + //Set timeouts (code from ADI driver) + _regs.timeout = std::max(1, std::min(int(ceil(_pfd_freq / (20e3 * 30))), 1023)); + + UHD_ASSERT_THROW((_regs.timeout & ((uint16_t)~0x3FF)) == 0); + _regs.synth_lock_timeout = + static_cast(ceil((_pfd_freq * 2) / (100e3 * _regs.timeout))); + UHD_ASSERT_THROW((_regs.synth_lock_timeout & ((uint16_t)~0x1F)) == 0); + _regs.auto_level_timeout = + static_cast(ceil((_pfd_freq * 5) / (100e3 * _regs.timeout))); + + //----------------------------------------------------------- + //Set VCO band divider + _regs.vco_band_div = + static_cast(ceil(_pfd_freq / 2.4e6)); + + //----------------------------------------------------------- + //Set ADC delay (code from ADI driver) + _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED; + _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED; + _regs.adc_clock_divider = std::max(1, std::min(int(ceil(((_pfd_freq / 100e3) - 2) / 4)),255)); + + _wait_time_us = static_cast( + ceil(16e6 / (_pfd_freq / ((4 * _regs.adc_clock_divider) + 2)))); + + //----------------------------------------------------------- + //Phase resync + // TODO Renable here, in initialization, or through separate set_phase_resync(bool enable) function + _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED; + + _regs.phase_adjust = adf535x_regs_t::PHASE_ADJUST_DISABLED; + _regs.sd_load_reset = adf535x_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE; + _regs.phase_resync_clk_div = static_cast( + floor(ADF535X_PHASE_RESYNC_TIME * _pfd_freq)); + + _rewrite_regs = true; + } + + double set_frequency(const double target_freq, const double freq_resolution, const bool flush = false) override + { + return _set_frequency(target_freq, freq_resolution, flush); + } + + void set_output_power(const output_power_t power) override + { + typename adf535x_regs_t::output_power_t setting; + switch (power) { + case OUTPUT_POWER_M4DBM: setting = adf535x_regs_t::OUTPUT_POWER_M4DBM; break; + case OUTPUT_POWER_M1DBM: setting = adf535x_regs_t::OUTPUT_POWER_M1DBM; break; + case OUTPUT_POWER_2DBM: setting = adf535x_regs_t::OUTPUT_POWER_2DBM; break; + case OUTPUT_POWER_5DBM: setting = adf535x_regs_t::OUTPUT_POWER_5DBM; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + if (_regs.output_power != setting) _rewrite_regs = true; + _regs.output_power = setting; + } + + void set_output_enable(const output_t output, const bool enable) override + { + switch (output) { + case RF_OUTPUT_A: _regs.rf_out_a_enabled = enable ? adf535x_regs_t::RF_OUT_A_ENABLED_ENABLED : + adf535x_regs_t::RF_OUT_A_ENABLED_DISABLED; + break; + case RF_OUTPUT_B: _regs.rf_out_b_enabled = enable ? adf535x_regs_t::RF_OUT_B_ENABLED_ENABLED : + adf535x_regs_t::RF_OUT_B_ENABLED_DISABLED; + break; + } + } + + void set_muxout_mode(const muxout_t mode) override + { + switch (mode) { + case MUXOUT_3STATE: _regs.muxout = adf535x_regs_t::MUXOUT_3STATE; break; + case MUXOUT_DVDD: _regs.muxout = adf535x_regs_t::MUXOUT_DVDD; break; + case MUXOUT_DGND: _regs.muxout = adf535x_regs_t::MUXOUT_DGND; break; + case MUXOUT_RDIV: _regs.muxout = adf535x_regs_t::MUXOUT_RDIV; break; + case MUXOUT_NDIV: _regs.muxout = adf535x_regs_t::MUXOUT_NDIV; break; + case MUXOUT_ALD: _regs.muxout = adf535x_regs_t::MUXOUT_ANALOG_LD; break; + case MUXOUT_DLD: _regs.muxout = adf535x_regs_t::MUXOUT_DLD; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + } + + void commit() override + { + _commit(); + } + +protected: + double _set_frequency(double, double, bool); + void _commit(); + +private: //Members + typedef std::vector addr_vtr_t; + + write_fn_t _write_fn; + adf535x_regs_t _regs; + bool _rewrite_regs; + uint32_t _wait_time_us; + double _ref_freq; + double _pfd_freq; + double _fb_after_divider; +}; + +// ADF5355 Functions +template <> +inline double adf535x_impl::_set_frequency(double target_freq, double freq_resolution, bool flush) +{ + if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { + throw uhd::runtime_error("requested frequency out of range."); + } + if ((uint32_t) freq_resolution == 0) { + throw uhd::runtime_error("requested resolution cannot be less than 1."); + } + + /* Calculate target VCOout frequency */ + //Increase RF divider until acceptable VCO frequency + double target_vco_freq = target_freq; + uint32_t rf_divider = 1; + while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { + target_vco_freq *= 2; + rf_divider *= 2; + } + + switch (rf_divider) { + case 1: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV1; break; + case 2: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV2; break; + case 4: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV4; break; + case 8: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV8; break; + case 16: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV16; break; + case 32: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV32; break; + case 64: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV64; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + + //Compute fractional PLL params + double prescaler_input_freq = target_vco_freq; + if (_fb_after_divider) { + prescaler_input_freq /= rf_divider; + } + + const double N = prescaler_input_freq / _pfd_freq; + const auto INT = static_cast(floor(N)); + const auto FRAC1 = static_cast(floor((N - INT) * ADF535X_MOD1)); + const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; + + const double gcd = boost::math::gcd(static_cast(_pfd_freq), static_cast(freq_resolution)); + const auto MOD2 = static_cast(std::min(floor(_pfd_freq / gcd), static_cast(ADF535X_MAX_MOD2))); + const auto FRAC2 = static_cast(std::min(ceil(residue * MOD2), static_cast(ADF535X_MAX_FRAC2))); + + const double coerced_vco_freq = _pfd_freq * ( + double(INT) + ( + (double(FRAC1) + + (double(FRAC2) / double(MOD2))) + / double(ADF535X_MOD1) + ) + ); + + const double coerced_out_freq = coerced_vco_freq / rf_divider; + + /* Update registers */ + _regs.int_16_bit = INT; + _regs.frac1_24_bit = FRAC1; + _regs.frac2_14_bit = FRAC2; + _regs.mod2_14_bit = MOD2; + _regs.phase_24_bit = 0; + + if (flush) commit(); + return coerced_out_freq; +} + +template <> +inline void adf535x_impl::_commit() +{ + const size_t ONE_REG = 1; + + if (_rewrite_regs) { + //For a full state sync write registers in reverse order 12 - 0 + addr_vtr_t regs; + for (uint8_t addr = 12; addr > 0; addr--) { + regs.push_back(_regs.get_reg(addr)); + } + _write_fn(regs); + // TODO Add FPGA based delay between these writes + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); + _rewrite_regs = false; + + } else { + //Frequency update sequence from data sheet + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); + _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_ENABLED; + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); + _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_DISABLED; + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); + _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED; + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); + // TODO Add FPGA based delay between these writes + _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED; + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); + } +} + +// ADF5356 Functions +template <> +inline double adf535x_impl::_set_frequency(double target_freq, double freq_resolution, bool flush) +{ + if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { + throw uhd::runtime_error("requested frequency out of range."); + } + if ((uint32_t) freq_resolution == 0) { + throw uhd::runtime_error("requested resolution cannot be less than 1."); + } + + /* Calculate target VCOout frequency */ + //Increase RF divider until acceptable VCO frequency + double target_vco_freq = target_freq; + uint32_t rf_divider = 1; + while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { + target_vco_freq *= 2; + rf_divider *= 2; + } + + switch (rf_divider) { + case 1: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV1; break; + case 2: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV2; break; + case 4: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV4; break; + case 8: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV8; break; + case 16: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV16; break; + case 32: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV32; break; + case 64: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV64; break; + default: UHD_THROW_INVALID_CODE_PATH(); + } + + //Compute fractional PLL params + double prescaler_input_freq = target_vco_freq; + if (_fb_after_divider) { + prescaler_input_freq /= rf_divider; + } + + const double N = prescaler_input_freq / _pfd_freq; + const auto INT = static_cast(floor(N)); + const auto FRAC1 = static_cast(floor((N - INT) * ADF535X_MOD1)); + const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; + + const double gcd = boost::math::gcd(static_cast(_pfd_freq), static_cast(freq_resolution)); + const auto MOD2 = static_cast(std::min(floor(_pfd_freq / gcd), static_cast(ADF535X_MAX_MOD2))); + const auto FRAC2 = static_cast(std::min(ceil(residue * MOD2), static_cast(ADF535X_MAX_FRAC2))); + + const double coerced_vco_freq = _pfd_freq * ( + double(INT) + ( + (double(FRAC1) + + (double(FRAC2) / double(MOD2))) + / double(ADF535X_MOD1) + ) + ); + + const double coerced_out_freq = coerced_vco_freq / rf_divider; + + /* Update registers */ + _regs.int_16_bit = INT; + _regs.frac1_24_bit = FRAC1; + _regs.frac2_msb = FRAC2; + _regs.mod2_msb = MOD2; + _regs.phase_24_bit = 0; + + if (flush) commit(); + return coerced_out_freq; +} + +template <> +inline void adf535x_impl::_commit() +{ + const size_t ONE_REG = 1; + if (_rewrite_regs) { + //For a full state sync write registers in reverse order 12 - 0 + addr_vtr_t regs; + for (uint8_t addr = 13; addr > 0; addr--) { + regs.push_back(_regs.get_reg(addr)); + } + _write_fn(regs); + // TODO Add FPGA based delay between these writes + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); + _rewrite_regs = false; + + } else { + //Frequency update sequence from data sheet + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(13))); + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(10))); + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); + // TODO Add FPGA based delay between these writes + _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); + } +} + +#endif // INCLUDED_ADF535X_HPP diff --git a/host/lib/include/uhdlib/usrp/common/apply_corrections.hpp b/host/lib/include/uhdlib/usrp/common/apply_corrections.hpp new file mode 100644 index 000000000..3b4669f9a --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/apply_corrections.hpp @@ -0,0 +1,43 @@ +// +// Copyright 2011-2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP + +#include +#include +#include + +namespace uhd{ namespace usrp{ + + void apply_tx_fe_corrections( + property_tree::sptr sub_tree, //starts at mboards/x + const fs_path db_path, + const fs_path tx_fe_corr_path, + const double tx_lo_freq //actual lo freq + ); + + void apply_tx_fe_corrections( + property_tree::sptr sub_tree, //starts at mboards/x + const std::string &slot, //name of dboard slot + const double tx_lo_freq //actual lo freq + ); + void apply_rx_fe_corrections( + property_tree::sptr sub_tree, //starts at mboards/x + const std::string &slot, //name of dboard slot + const double rx_lo_freq //actual lo freq + ); + + void apply_rx_fe_corrections( + property_tree::sptr sub_tree, //starts at mboards/x + const fs_path db_path, + const fs_path rx_fe_corr_path, + const double rx_lo_freq //actual lo freq + ); +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp b/host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp new file mode 100644 index 000000000..de9d17001 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/async_packet_handler.hpp @@ -0,0 +1,74 @@ +// +// Copyright 2012 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP + +#include +#include +#include +#include +#include + +namespace uhd{ namespace usrp{ + + template + void load_metadata_from_buff( + const to_host_type &to_host, + async_metadata_t &metadata, + const transport::vrt::if_packet_info_t &if_packet_info, + const uint32_t *vrt_hdr, + const double tick_rate, + const size_t channel = 0 + ){ + const uint32_t *payload = vrt_hdr + if_packet_info.num_header_words32; + + //load into metadata + metadata.channel = channel; + metadata.has_time_spec = if_packet_info.has_tsf; + if (tick_rate == 0.0) { + metadata.time_spec = 0.0; + } else { + metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); + } + metadata.event_code = async_metadata_t::event_code_t(to_host(payload[0]) & 0xff); + + //load user payload + for (size_t i = 1; i < if_packet_info.num_payload_words32; i++){ + if (i-1 == 4) break; //limit of 4 words32 + metadata.user_payload[i-1] = to_host(payload[i]); + } + } + + UHD_INLINE void standard_async_msg_prints(const async_metadata_t &metadata) + { + if (metadata.event_code & + ( async_metadata_t::EVENT_CODE_UNDERFLOW + | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) + ) + { + UHD_LOG_FASTPATH("U") + } + else if (metadata.event_code & + ( async_metadata_t::EVENT_CODE_SEQ_ERROR + | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) + ) + { + UHD_LOG_FASTPATH("S") + } + else if (metadata.event_code & + async_metadata_t::EVENT_CODE_TIME_ERROR + ) + { + UHD_LOG_FASTPATH("L") + } + } + + +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/fifo_ctrl_excelsior.hpp b/host/lib/include/uhdlib/usrp/common/fifo_ctrl_excelsior.hpp new file mode 100644 index 000000000..91c006a1a --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/fifo_ctrl_excelsior.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2012,2015 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_B200_CTRL_HPP +#define INCLUDED_B200_CTRL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + + +struct fifo_ctrl_excelsior_config +{ + size_t async_sid_base; + size_t num_async_chan; + size_t ctrl_sid_base; + size_t spi_base; + size_t spi_rb; +}; + +/*! + * Provide access to peek, poke, spi, and async messages. + */ +class fifo_ctrl_excelsior : public uhd::timed_wb_iface, public uhd::spi_iface +{ +public: + typedef boost::shared_ptr sptr; + + //! Make a new control object + static sptr make( + uhd::transport::zero_copy_if::sptr xport, + const fifo_ctrl_excelsior_config &config + ); + + //! Set the tick rate (converting time into ticks) + virtual void set_tick_rate(const double rate) = 0; + + //! Pop an async message from the queue or timeout + virtual bool pop_async_msg(uhd::async_metadata_t &async_metadata, double timeout) = 0; +}; + +#endif /* INCLUDED_B200_CTRL_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp b/host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp new file mode 100644 index 000000000..258aa7d04 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/fx2_ctrl.hpp @@ -0,0 +1,138 @@ +// +// Copyright 2010-2012 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_FX2_CTRL_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_FX2_CTRL_HPP + +#include +#include //i2c iface +#include +#include + +#define FL_BEGIN 0 +#define FL_END 2 +#define FL_XFER 1 +#define USRP_HASH_SLOT_0_ADDR 0xe1e0 +#define USRP_HASH_SLOT_1_ADDR 0xe1f0 +#define VRQ_FPGA_LOAD 0x02 +#define VRQ_FPGA_SET_RESET 0x04 +#define VRQ_FPGA_SET_TX_ENABLE 0x05 +#define VRQ_FPGA_SET_RX_ENABLE 0x06 +#define VRQ_FPGA_SET_TX_RESET 0x0a +#define VRQ_FPGA_SET_RX_RESET 0x0b +#define VRQ_I2C_READ 0x81 +#define VRQ_I2C_WRITE 0x08 +#define VRQ_SET_LED 0x01 +#define VRT_VENDOR_IN 0xC0 +#define VRT_VENDOR_OUT 0x40 + +namespace uhd{ namespace usrp{ + +class fx2_ctrl : boost::noncopyable, public uhd::i2c_iface{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a usrp control object from a control transport + * \param ctrl_transport a USB control transport + * \return a new usrp control object + */ + static sptr make(uhd::transport::usb_control::sptr ctrl_transport); + + //! Call init after the fpga is loaded + virtual void usrp_init(void) = 0; + + //! For emergency situations + virtual void usrp_fx2_reset(void) = 0; + + /*! + * Load firmware in Intel HEX Format onto device + * \param filename name of firmware file + * \param force reload firmware if already loaded + */ + virtual void usrp_load_firmware(std::string filename, + bool force = false) = 0; + + /*! + * Load fpga file onto usrp + * \param filename name of fpga image + */ + virtual void usrp_load_fpga(std::string filename) = 0; + + /*! + * Load USB descriptor file in Intel HEX format into EEPROM + * \param filestring name of EEPROM image + */ + virtual void usrp_load_eeprom(std::string filestring) = 0; + + /*! + * Submit an IN transfer + * \param request device specific request + * \param value device specific field + * \param index device specific field + * \param buff buffer to place data + * \param length length of buffer + * \return number of bytes read or error + */ + virtual int usrp_control_read(uint8_t request, + uint16_t value, + uint16_t index, + unsigned char *buff, + uint16_t length) = 0; + + /*! + * Submit an OUT transfer + * \param request device specific request + * \param value device specific field + * \param index device specific field + * \param buff buffer of data to be sent + * \param length length of buffer + * \return number of bytes written or error + */ + virtual int usrp_control_write(uint8_t request, + uint16_t value, + uint16_t index, + unsigned char *buff, + uint16_t length) = 0; + + /*! + * Perform an I2C write + * \param i2c_addr I2C device address + * \param buf data to be written + * \param len length of data in bytes + * \return number of bytes written or error + */ + + virtual int usrp_i2c_write(uint16_t i2c_addr, + unsigned char *buf, + uint16_t len) = 0; + + /*! + * Perform an I2C read + * \param i2c_addr I2C device address + * \param buf data to be read + * \param len length of data in bytes + * \return number of bytes read or error + */ + + virtual int usrp_i2c_read(uint16_t i2c_addr, + unsigned char *buf, + uint16_t len) = 0; + + //! enable/disable the rx path + virtual void usrp_rx_enable(bool on) = 0; + + //! enable/disable the tx path + virtual void usrp_tx_enable(bool on) = 0; + + //! reset the fpga + virtual void usrp_fpga_reset(bool on) = 0; +}; + +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_COMMON_FX2_CTRL_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/max287x.hpp b/host/lib/include/uhdlib/usrp/common/max287x.hpp new file mode 100644 index 000000000..762daf7b6 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/max287x.hpp @@ -0,0 +1,935 @@ +// +// Copyright 2015-2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef MAX287X_HPP_INCLUDED +#define MAX287X_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "max2870_regs.hpp" +#include "max2871_regs.hpp" + +/** + * MAX287x interface + */ +class max287x_iface +{ +public: + typedef boost::shared_ptr sptr; + + typedef boost::function)> write_fn; + + /** + * LD Pin Modes + */ + typedef enum{ + LD_PIN_MODE_LOW, + LD_PIN_MODE_DLD, + LD_PIN_MODE_ALD, + LD_PIN_MODE_HIGH + } ld_pin_mode_t; + + /** + * MUXOUT Modes + */ + typedef enum{ + MUXOUT_TRI_STATE, + MUXOUT_HIGH, + MUXOUT_LOW, + MUXOUT_RDIV, + MUXOUT_NDIV, + MUXOUT_ALD, + MUXOUT_DLD, + MUXOUT_SYNC, + MUXOUT_SPI + } muxout_mode_t; + + /** + * Charge Pump Currents + */ + typedef enum{ + CHARGE_PUMP_CURRENT_0_32MA, + CHARGE_PUMP_CURRENT_0_64MA, + CHARGE_PUMP_CURRENT_0_96MA, + CHARGE_PUMP_CURRENT_1_28MA, + CHARGE_PUMP_CURRENT_1_60MA, + CHARGE_PUMP_CURRENT_1_92MA, + CHARGE_PUMP_CURRENT_2_24MA, + CHARGE_PUMP_CURRENT_2_56MA, + CHARGE_PUMP_CURRENT_2_88MA, + CHARGE_PUMP_CURRENT_3_20MA, + CHARGE_PUMP_CURRENT_3_52MA, + CHARGE_PUMP_CURRENT_3_84MA, + CHARGE_PUMP_CURRENT_4_16MA, + CHARGE_PUMP_CURRENT_4_48MA, + CHARGE_PUMP_CURRENT_4_80MA, + CHARGE_PUMP_CURRENT_5_12MA + } charge_pump_current_t; + + /** + * Output Powers + */ + typedef enum{ + OUTPUT_POWER_M4DBM, + OUTPUT_POWER_M1DBM, + OUTPUT_POWER_2DBM, + OUTPUT_POWER_5DBM + } output_power_t; + + typedef enum { + LOW_NOISE_AND_SPUR_LOW_NOISE, + LOW_NOISE_AND_SPUR_LOW_SPUR_1, + LOW_NOISE_AND_SPUR_LOW_SPUR_2 + } low_noise_and_spur_t; + + typedef enum { + CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF, + CLOCK_DIV_MODE_FAST_LOCK, + CLOCK_DIV_MODE_PHASE + } clock_divider_mode_t; + + /** + * Make a synthesizer + * @param write write function + * @return shared pointer to object + */ + template static sptr make(write_fn write) + { + return sptr(new max287X_t(write)); + } + + /** + * Destructor + */ + virtual ~max287x_iface() {}; + + /** + * Power up the synthesizer + */ + virtual void power_up(void) = 0; + + /** + * Shut down the synthesizer + */ + virtual void shutdown(void) = 0; + + /** + * Check if the synthesizer is shut down + */ + virtual bool is_shutdown(void) = 0; + + /** + * Set frequency + * @param target_freq target frequency + * @param ref_freq reference frequency + * @param target_pfd_freq target phase detector frequency + * @param is_int_n enable integer-N tuning + * @return actual frequency + */ + virtual double set_frequency( + double target_freq, + double ref_freq, + double target_pfd_freq, + bool is_int_n) = 0; + + /** + * Set output power + * @param power output power + */ + virtual void set_output_power(output_power_t power) = 0; + + /** + * Set lock detect pin mode + * @param mode lock detect pin mode + */ + virtual void set_ld_pin_mode(ld_pin_mode_t mode) = 0; + + /** + * Set muxout pin mode + * @param mode muxout mode + */ + virtual void set_muxout_mode(muxout_mode_t mode) = 0; + + /** + * Set charge pump current + * @param cp_current charge pump current + */ + virtual void set_charge_pump_current(charge_pump_current_t cp_current) = 0; + + /** + * Enable or disable auto retune + * @param enabled enable auto retune + */ + virtual void set_auto_retune(bool enabled) = 0; + + /** + * Set clock divider mode + * @param mode clock divider mode + */ + virtual void set_clock_divider_mode(clock_divider_mode_t mode) = 0; + + /** + * Enable or disable cycle slip mode + * @param enabled enable cycle slip mode + */ + virtual void set_cycle_slip_mode(bool enabled) = 0; + + /** + * Set low noise and spur mode + * @param mode low noise and spur mode + */ + virtual void set_low_noise_and_spur(low_noise_and_spur_t mode) = 0; + + /** + * Set phase + * @param phase the phase offset + */ + virtual void set_phase(uint16_t phase) = 0; + + /** + * Write values configured by the set_* functions. + */ + virtual void commit(void) = 0; + + /** + * Check whether this is in a state where it can be synchronized + */ + virtual bool can_sync(void) = 0; + + /** + * Configure synthesizer for phase synchronization + */ + virtual void config_for_sync(bool enable) = 0; +}; + +/** + * MAX287x + * Base class for all MAX287x synthesizers + */ +template +class max287x : public max287x_iface +{ +public: + max287x(write_fn func); + virtual ~max287x(); + virtual void power_up(void); + virtual void shutdown(void); + virtual bool is_shutdown(void); + virtual double set_frequency( + double target_freq, + double ref_freq, + double target_pfd_freq, + bool is_int_n); + virtual void set_output_power(output_power_t power); + virtual void set_ld_pin_mode(ld_pin_mode_t mode); + virtual void set_muxout_mode(muxout_mode_t mode); + virtual void set_charge_pump_current(charge_pump_current_t cp_current); + virtual void set_auto_retune(bool enabled); + virtual void set_clock_divider_mode(clock_divider_mode_t mode); + virtual void set_cycle_slip_mode(bool enabled); + virtual void set_low_noise_and_spur(low_noise_and_spur_t mode); + virtual void set_phase(uint16_t phase); + virtual void commit(); + virtual bool can_sync(); + virtual void config_for_sync(bool enable); + +protected: + max287x_regs_t _regs; + bool _can_sync; + bool _config_for_sync; + bool _write_all_regs; + +private: + write_fn _write; + bool _delay_after_write; +}; + +/** + * MAX2870 + */ +class max2870 : public max287x +{ +public: + max2870(write_fn func) : max287x(func) {} + ~max2870() {} + double set_frequency( + double target_freq, + double ref_freq, + double target_pfd_freq, + bool is_int_n) + { + _regs.cpoc = is_int_n ? max2870_regs_t::CPOC_ENABLED : max2870_regs_t::CPOC_DISABLED; + _regs.feedback_select = target_freq >= 3.0e9 ? + max2870_regs_t::FEEDBACK_SELECT_DIVIDED : + max2870_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; + + return max287x::set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + } + void commit(void) + { + // For MAX2870, we always need to write all registers. + _write_all_regs = true; + max287x::commit(); + } +}; + +/** + * MAX2871 + */ +// Table of frequency ranges for each VCO value. +// The values were derived from sampling multiple +// units over a temperature range of -10 to 40 deg C. +typedef std::map vco_map_t; +static const vco_map_t max2871_vco_map = + boost::assign::map_list_of + (0,uhd::range_t(2767776024.0,2838472816.0)) + (1,uhd::range_t(2838472816.0,2879070053.0)) + (1,uhd::range_t(2879070053.0,2921202504.0)) + (3,uhd::range_t(2921202504.0,2960407579.0)) + (4,uhd::range_t(2960407579.0,3001687422.0)) + (5,uhd::range_t(3001687422.0,3048662562.0)) + (6,uhd::range_t(3048662562.0,3097511550.0)) + (7,uhd::range_t(3097511550.0,3145085864.0)) + (8,uhd::range_t(3145085864.0,3201050835.0)) + (9,uhd::range_t(3201050835.0,3259581909.0)) + (10,uhd::range_t(3259581909.0,3321408729.0)) + (11,uhd::range_t(3321408729.0,3375217285.0)) + (12,uhd::range_t(3375217285.0,3432807972.0)) + (13,uhd::range_t(3432807972.0,3503759088.0)) + (14,uhd::range_t(3503759088.0,3579011283.0)) + (15,uhd::range_t(3579011283.0,3683570865.0)) + (20,uhd::range_t(3683570865.0,3711845712.0)) + (21,uhd::range_t(3711845712.0,3762188221.0)) + (22,uhd::range_t(3762188221.0,3814209551.0)) + (23,uhd::range_t(3814209551.0,3865820020.0)) + (24,uhd::range_t(3865820020.0,3922520021.0)) + (25,uhd::range_t(3922520021.0,3981682709.0)) + (26,uhd::range_t(3981682709.0,4043154280.0)) + (27,uhd::range_t(4043154280.0,4100400020.0)) + (28,uhd::range_t(4100400020.0,4159647583.0)) + (29,uhd::range_t(4159647583.0,4228164842.0)) + (30,uhd::range_t(4228164842.0,4299359879.0)) + (31,uhd::range_t(4299359879.0,4395947962.0)) + (33,uhd::range_t(4395947962.0,4426512061.0)) + (34,uhd::range_t(4426512061.0,4480333656.0)) + (35,uhd::range_t(4480333656.0,4526297331.0)) + (36,uhd::range_t(4526297331.0,4574689510.0)) + (37,uhd::range_t(4574689510.0,4633102021.0)) + (38,uhd::range_t(4633102021.0,4693755616.0)) + (39,uhd::range_t(4693755616.0,4745624435.0)) + (40,uhd::range_t(4745624435.0,4803922123.0)) + (41,uhd::range_t(4803922123.0,4871523881.0)) + (42,uhd::range_t(4871523881.0,4942111286.0)) + (43,uhd::range_t(4942111286.0,5000192446.0)) + (44,uhd::range_t(5000192446.0,5059567510.0)) + (45,uhd::range_t(5059567510.0,5136258187.0)) + (46,uhd::range_t(5136258187.0,5215827295.0)) + (47,uhd::range_t(5215827295.0,5341282949.0)) + (49,uhd::range_t(5341282949.0,5389819310.0)) + (50,uhd::range_t(5389819310.0,5444868434.0)) + (51,uhd::range_t(5444868434.0,5500079705.0)) + (52,uhd::range_t(5500079705.0,5555329630.0)) + (53,uhd::range_t(5555329630.0,5615049833.0)) + (54,uhd::range_t(5615049833.0,5676098527.0)) + (55,uhd::range_t(5676098527.0,5744191577.0)) + (56,uhd::range_t(5744191577.0,5810869917.0)) + (57,uhd::range_t(5810869917.0,5879176194.0)) + (58,uhd::range_t(5879176194.0,5952430629.0)) + (59,uhd::range_t(5952430629.0,6016743964.0)) + (60,uhd::range_t(6016743964.0,6090658690.0)) + (61,uhd::range_t(6090658690.0,6128133570.0)); + +class max2871 : public max287x +{ +public: + max2871(write_fn func) : max287x(func) {} + ~max2871() {}; + void set_muxout_mode(muxout_mode_t mode) + { + switch(mode) + { + case MUXOUT_SYNC: + _regs.muxout = max2871_regs_t::MUXOUT_SYNC; + break; + case MUXOUT_SPI: + _regs.muxout = max2871_regs_t::MUXOUT_SPI; + break; + default: + max287x::set_muxout_mode(mode); + } + } + + double set_frequency( + double target_freq, + double ref_freq, + double target_pfd_freq, + bool is_int_n) + { + _regs.feedback_select = max2871_regs_t::FEEDBACK_SELECT_DIVIDED; + double freq = max287x::set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); + + // To support phase synchronization on MAX2871, the same VCO + // subband must be manually programmed on all synthesizers and + // several registers must be set to specific values. + if (_config_for_sync) + { + // Need to manually program VCO value + static const double MIN_VCO_FREQ = 3e9; + double vco_freq = target_freq; + while (vco_freq < MIN_VCO_FREQ) + vco_freq *=2; + uint8_t vco_index = 0xFF; + for(const vco_map_t::value_type &vco: max2871_vco_map) + { + if (uhd::math::fp_compare::fp_compare_epsilon(vco_freq) < vco.second.stop()) + { + vco_index = vco.first; + break; + } + } + if (vco_index == 0xFF) + throw uhd::index_error("Invalid VCO frequency"); + + // Settings required for phase synchronization as per MAX2871 datasheet + _regs.shutdown_vas = max2871_regs_t::SHUTDOWN_VAS_DISABLED; + _regs.vco = vco_index; + _regs.low_noise_and_spur = max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE; + _regs.f01 = max2871_regs_t::F01_FRAC_N; + _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED; + } + else + { + // Reset values to defaults + _regs.shutdown_vas = max2871_regs_t::SHUTDOWN_VAS_ENABLED; // turn VCO auto selection on + _regs.low_noise_and_spur = max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_2; + _regs.f01 = max2871_regs_t::F01_AUTO; + _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_FUNDAMENTAL; + } + + return freq; + } + + void commit() + { + max287x::commit(); + + // According to Maxim support, the following factors must be true to allow for phase synchronization + if (_regs.int_n_mode == max2871_regs_t::INT_N_MODE_FRAC_N and + _regs.feedback_select == max2871_regs_t::FEEDBACK_SELECT_DIVIDED and + _regs.aux_output_select == max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED and + _regs.rf_divider_select <= max2871_regs_t::RF_DIVIDER_SELECT_DIV16 and + _regs.low_noise_and_spur == max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE and + _regs.f01 == max2871_regs_t::F01_FRAC_N and + _regs.reference_doubler == max2871_regs_t::REFERENCE_DOUBLER_DISABLED and + _regs.reference_divide_by_2 == max2871_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED and + _regs.r_counter_10_bit == 1) + { + _can_sync = true; + } else { + _can_sync = false; + } + } +}; + + +// Implementation of max287x template class +// To avoid linker errors, it was either include +// it here or put it in a .cpp file and include +// that file in this header file. Decided to just +// include it here. + +template +max287x::max287x(write_fn func) : + _can_sync(false), + _config_for_sync(false), + _write_all_regs(true), + _write(func), + _delay_after_write(true) +{ + power_up(); +} + +template +max287x::~max287x() +{ + UHD_SAFE_CALL + ( + shutdown(); + ) +} + +template +void max287x::power_up(void) +{ + _regs.power_down = max287x_regs_t::POWER_DOWN_NORMAL; + _regs.double_buffer = max287x_regs_t::DOUBLE_BUFFER_ENABLED; + + // According to MAX287x data sheets: + // "Upon power-up, the registers should be programmed twice with at + // least a 20ms pause between writes. The first write ensures that + // the device is enabled, and the second write starts the VCO + // selection process." + // The first write and the 20ms wait are done here. The second write + // is done when any other function that does a write to the registers + // is called (such as tuning). + _write_all_regs = true; + _delay_after_write = true; + commit(); + _write_all_regs = true; // Next call to commit() writes all regs +} + +template +void max287x::shutdown(void) +{ + _regs.rf_output_enable = max287x_regs_t::RF_OUTPUT_ENABLE_DISABLED; + _regs.aux_output_enable = max287x_regs_t::AUX_OUTPUT_ENABLE_DISABLED; + _regs.power_down = max287x_regs_t::POWER_DOWN_SHUTDOWN; + commit(); +} + +template +bool max287x::is_shutdown(void) +{ + return (_regs.power_down == max287x_regs_t::POWER_DOWN_SHUTDOWN); +} + +template +double max287x::set_frequency( + double target_freq, + double ref_freq, + double target_pfd_freq, + bool is_int_n) +{ + //map rf divider select output dividers to enums + static const uhd::dict rfdivsel_to_enum = + boost::assign::map_list_of + (1, max287x_regs_t::RF_DIVIDER_SELECT_DIV1) + (2, max287x_regs_t::RF_DIVIDER_SELECT_DIV2) + (4, max287x_regs_t::RF_DIVIDER_SELECT_DIV4) + (8, max287x_regs_t::RF_DIVIDER_SELECT_DIV8) + (16, max287x_regs_t::RF_DIVIDER_SELECT_DIV16) + (32, max287x_regs_t::RF_DIVIDER_SELECT_DIV32) + (64, max287x_regs_t::RF_DIVIDER_SELECT_DIV64) + (128, max287x_regs_t::RF_DIVIDER_SELECT_DIV128); + + //map mode setting to valid integer divider (N) values + static const uhd::range_t int_n_mode_div_range(16,65535,1); + static const uhd::range_t frac_n_mode_div_range(19,4091,1); + + //other ranges and constants from MAX287X datasheets + static const uhd::range_t clock_div_range(1,4095,1); + static const uhd::range_t r_range(1,1023,1); + static const double MIN_VCO_FREQ = 3e9; + static const double BS_FREQ = 50e3; + static const int MAX_BS_VALUE = 1023; + + int T = 0; + int D = ref_freq <= 10.0e6 ? 1 : 0; + int R = 0; + int BS = 0; + int N = 0; + int FRAC = 0; + int MOD = 4095; + int RFdiv = 1; + double pfd_freq = target_pfd_freq; + bool feedback_divided = (_regs.feedback_select == max287x_regs_t::FEEDBACK_SELECT_DIVIDED); + + //increase RF divider until acceptable VCO frequency (MIN freq for MAX287x VCO is 3GHz) + UHD_ASSERT_THROW(target_freq > 0); + double vco_freq = target_freq; + while (vco_freq < MIN_VCO_FREQ) + { + vco_freq *= 2; + RFdiv *= 2; + } + + // The feedback frequency can be the fundamental VCO frequency or + // divided frequency. The output divider for MAX287x is actually + // 2 dividers, but only the first (1/2/4/8/16) is included in the + // feedback loop. + int fb_divisor = feedback_divided ? (RFdiv > 16 ? 16 : RFdiv) : 1; + + /* + * The goal here is to loop though possible R dividers, + * band select clock dividers, N (int) dividers, and FRAC + * (frac) dividers. + * + * Calculate the N and F dividers for each set of values. + * The loop exits when it meets all of the constraints. + * The resulting loop values are loaded into the registers. + * + * f_pfd = f_ref*(1+D)/(R*(1+T)) + * f_vco = (N + (FRAC/MOD))*f_pfd + * N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD + * f_rf = f_vco/RFdiv + */ + for(R = int(ref_freq*(1+D)/(target_pfd_freq*(1+T))); R <= r_range.stop(); R++) + { + //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T) + pfd_freq = ref_freq*(1+D)/(R*(1+T)); + + //keep the PFD frequency at or below target + if (pfd_freq > target_pfd_freq) + continue; + + //ignore fractional part of tuning + N = int((vco_freq/pfd_freq)/fb_divisor); + + //Fractional-N calculation + FRAC = int(boost::math::round(((vco_freq/pfd_freq)/fb_divisor - N)*MOD)); + + if(is_int_n) + { + if (FRAC > (MOD / 2)) //Round integer such that actual freq is closest to target + N++; + FRAC = 0; + } + + //keep N within int divider requirements + if(is_int_n) + { + if(N <= int_n_mode_div_range.start()) continue; + if(N >= int_n_mode_div_range.stop()) continue; + } + else + { + if(N <= frac_n_mode_div_range.start()) continue; + if(N >= frac_n_mode_div_range.stop()) continue; + } + + //keep pfd freq low enough to achieve 50kHz BS clock + BS = std::ceil(pfd_freq / BS_FREQ); + if(BS <= MAX_BS_VALUE) break; + } + UHD_ASSERT_THROW(R <= r_range.stop()); + + //Reference divide-by-2 for 50% duty cycle + // if R even, move one divide by 2 to to regs.reference_divide_by_2 + if(R % 2 == 0) + { + T = 1; + R /= 2; + } + + //actual frequency calculation + double actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))) * fb_divisor / RFdiv; + + UHD_LOGGER_TRACE("MAX287X") + << boost::format("MAX287x: Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") + % ref_freq % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) + << boost::format("MAX287x: tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, type=%s") + % R % BS % N % FRAC % MOD % T % D % RFdiv % ((is_int_n) ? "Integer-N" : "Fractional") + << boost::format("MAX287x: Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f") + % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) + ; + + //load the register values + _regs.rf_output_enable = max287x_regs_t::RF_OUTPUT_ENABLE_ENABLED; + + if(is_int_n) { + _regs.cpl = max287x_regs_t::CPL_DISABLED; + _regs.ldf = max287x_regs_t::LDF_INT_N; + _regs.int_n_mode = max287x_regs_t::INT_N_MODE_INT_N; + } else { + _regs.cpl = max287x_regs_t::CPL_ENABLED; + _regs.ldf = max287x_regs_t::LDF_FRAC_N; + _regs.int_n_mode = max287x_regs_t::INT_N_MODE_FRAC_N; + } + + _regs.lds = pfd_freq <= 32e6 ? max287x_regs_t::LDS_SLOW : max287x_regs_t::LDS_FAST; + + _regs.frac_12_bit = FRAC; + _regs.int_16_bit = N; + _regs.mod_12_bit = MOD; + _regs.clock_divider_12_bit = std::max(int(clock_div_range.start()), int(std::ceil(400e-6*pfd_freq/MOD))); + UHD_ASSERT_THROW(_regs.clock_divider_12_bit <= clock_div_range.stop()); + _regs.r_counter_10_bit = R; + _regs.reference_divide_by_2 = T ? + max287x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : + max287x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; + _regs.reference_doubler = D ? + max287x_regs_t::REFERENCE_DOUBLER_ENABLED : + max287x_regs_t::REFERENCE_DOUBLER_DISABLED; + _regs.band_select_clock_div = BS & 0xFF; + _regs.bs_msb = (BS & 0x300) >> 8; + UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv)); + _regs.rf_divider_select = rfdivsel_to_enum[RFdiv]; + + if (_regs.clock_div_mode == max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK) + { + // Charge pump current needs to be set to lowest value in fast lock mode + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_32MA; + // Make sure the register containing the charge pump current is written + _write_all_regs = true; + } + + return actual_freq; +} + +template +void max287x::set_output_power(output_power_t power) +{ + switch (power) + { + case OUTPUT_POWER_M4DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_M4DBM; + break; + case OUTPUT_POWER_M1DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_M1DBM; + break; + case OUTPUT_POWER_2DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_2DBM; + break; + case OUTPUT_POWER_5DBM: + _regs.output_power = max287x_regs_t::OUTPUT_POWER_5DBM; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +template +void max287x::set_ld_pin_mode(ld_pin_mode_t mode) +{ + switch(mode) + { + case LD_PIN_MODE_LOW: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_LOW; + break; + case LD_PIN_MODE_DLD: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_DLD; + break; + case LD_PIN_MODE_ALD: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_ALD; + break; + case LD_PIN_MODE_HIGH: + _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_HIGH; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +template +void max287x::set_muxout_mode(muxout_mode_t mode) +{ + switch(mode) + { + case MUXOUT_TRI_STATE: + _regs.muxout = max287x_regs_t::MUXOUT_TRI_STATE; + break; + case MUXOUT_HIGH: + _regs.muxout = max287x_regs_t::MUXOUT_HIGH; + break; + case MUXOUT_LOW: + _regs.muxout = max287x_regs_t::MUXOUT_LOW; + break; + case MUXOUT_RDIV: + _regs.muxout = max287x_regs_t::MUXOUT_RDIV; + break; + case MUXOUT_NDIV: + _regs.muxout = max287x_regs_t::MUXOUT_NDIV; + break; + case MUXOUT_ALD: + _regs.muxout = max287x_regs_t::MUXOUT_ALD; + break; + case MUXOUT_DLD: + _regs.muxout = max287x_regs_t::MUXOUT_DLD; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +template +void max287x::set_charge_pump_current(charge_pump_current_t cp_current) +{ + switch(cp_current) + { + case CHARGE_PUMP_CURRENT_0_32MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_32MA; + break; + case CHARGE_PUMP_CURRENT_0_64MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_64MA; + break; + case CHARGE_PUMP_CURRENT_0_96MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_96MA; + break; + case CHARGE_PUMP_CURRENT_1_28MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_28MA; + break; + case CHARGE_PUMP_CURRENT_1_60MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_60MA; + break; + case CHARGE_PUMP_CURRENT_1_92MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_92MA; + break; + case CHARGE_PUMP_CURRENT_2_24MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_24MA; + break; + case CHARGE_PUMP_CURRENT_2_56MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_56MA; + break; + case CHARGE_PUMP_CURRENT_2_88MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_88MA; + break; + case CHARGE_PUMP_CURRENT_3_20MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_20MA; + break; + case CHARGE_PUMP_CURRENT_3_52MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_52MA; + break; + case CHARGE_PUMP_CURRENT_3_84MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_84MA; + break; + case CHARGE_PUMP_CURRENT_4_16MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_16MA; + break; + case CHARGE_PUMP_CURRENT_4_48MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_48MA; + break; + case CHARGE_PUMP_CURRENT_4_80MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_80MA; + break; + case CHARGE_PUMP_CURRENT_5_12MA: + _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_5_12MA; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +template +void max287x::set_auto_retune(bool enabled) +{ + _regs.retune = enabled ? max287x_regs_t::RETUNE_ENABLED : max287x_regs_t::RETUNE_DISABLED; +} + +template <> +inline void max287x::set_auto_retune(bool enabled) +{ + _regs.retune = enabled ? max2871_regs_t::RETUNE_ENABLED : max2871_regs_t::RETUNE_DISABLED; + _regs.vas_dly = enabled ? max2871_regs_t::VAS_DLY_ENABLED : max2871_regs_t::VAS_DLY_DISABLED; +} + +template +void max287x::set_clock_divider_mode(clock_divider_mode_t mode) +{ + switch(mode) + { + case CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF: + _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF; + break; + case CLOCK_DIV_MODE_FAST_LOCK: + _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK; + break; + case CLOCK_DIV_MODE_PHASE: + _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_PHASE; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +template +void max287x::set_cycle_slip_mode(bool enabled) +{ + if (enabled) + throw uhd::runtime_error("Cycle slip mode not supported on this MAX287x synthesizer."); +} + +template +void max287x::set_low_noise_and_spur(low_noise_and_spur_t mode) +{ + switch(mode) + { + case LOW_NOISE_AND_SPUR_LOW_NOISE: + _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE; + break; + case LOW_NOISE_AND_SPUR_LOW_SPUR_1: + _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_1; + break; + case LOW_NOISE_AND_SPUR_LOW_SPUR_2: + _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_2; + break; + default: + UHD_THROW_INVALID_CODE_PATH(); + } +} + +template +void max287x::set_phase(uint16_t phase) +{ + _regs.phase_12_bit = phase & 0xFFF; +} + +template +void max287x::commit() +{ + std::vector regs; + std::set changed_regs; + + // Get only regs with changes + if (_write_all_regs) + { + for (int addr = 5; addr >= 0; addr--) + regs.push_back(_regs.get_reg(uint32_t(addr))); + } else { + try { + changed_regs = _regs.template get_changed_addrs (); + // register 0 must be written to apply double buffered fields + if (changed_regs.size() > 0) + { + changed_regs.insert(0); + } + + for (int addr = 5; addr >= 0; addr--) + { + if (changed_regs.find(uint32_t(addr)) != changed_regs.end()) + regs.push_back(_regs.get_reg(uint32_t(addr))); + } + } catch (uhd::runtime_error&) { + // No saved state - write all regs + for (int addr = 5; addr >= 0; addr--) + regs.push_back(_regs.get_reg(uint32_t(addr))); + } + } + + _write(regs); + _regs.save_state(); + _write_all_regs = false; + + if (_delay_after_write) + { + boost::this_thread::sleep(boost::posix_time::milliseconds(20)); + _delay_after_write = false; + } +} + +template +bool max287x::can_sync(void) +{ + return _can_sync; +} + +template +void max287x::config_for_sync(bool enable) +{ + _config_for_sync = enable; +} + +#endif // MAX287X_HPP_INCLUDED diff --git a/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp new file mode 100644 index 000000000..d158a919e --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer.hpp @@ -0,0 +1,33 @@ +// +// Copyright 2011,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_HPP + +#include +#include +#include +#include + +namespace uhd{ namespace usrp{ + + class recv_packet_demuxer{ + public: + typedef boost::shared_ptr sptr; + + virtual ~recv_packet_demuxer(void) = 0; + + //! Make a new demuxer from a transport and parameters + static sptr make(transport::zero_copy_if::sptr transport, const size_t size, const uint32_t sid_base); + + //! Get a buffer at the given index from the transport + virtual transport::managed_recv_buffer::sptr get_recv_buff(const size_t index, const double timeout) = 0; + }; + +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp new file mode 100644 index 000000000..74807741f --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/recv_packet_demuxer_3000.hpp @@ -0,0 +1,145 @@ +// +// Copyright 2013,2017 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_3000_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_3000_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace uhd{ namespace usrp{ + + struct recv_packet_demuxer_3000 : boost::enable_shared_from_this + { + typedef boost::shared_ptr sptr; + static sptr make(transport::zero_copy_if::sptr xport) + { + return sptr(new recv_packet_demuxer_3000(xport)); + } + + recv_packet_demuxer_3000(transport::zero_copy_if::sptr xport): + _xport(xport) + {/*NOP*/} + + transport::managed_recv_buffer::sptr get_recv_buff(const uint32_t sid, const double timeout) + { + const time_spec_t exit_time = + time_spec_t(timeout) + uhd::get_system_time(); + transport::managed_recv_buffer::sptr buff; + buff = _internal_get_recv_buff(sid, timeout); + while (not buff) //loop until timeout + { + const time_spec_t delta = exit_time - uhd::get_system_time(); + const double new_timeout = delta.get_real_secs(); + if (new_timeout < 0.0) break; + buff = _internal_get_recv_buff(sid, new_timeout); + } + return buff; + } + + transport::managed_recv_buffer::sptr _internal_get_recv_buff(const uint32_t sid, const double timeout) + { + transport::managed_recv_buffer::sptr buff; + + //---------------------------------------------------------- + //-- Check the queue to see if we already have a buffer + //---------------------------------------------------------- + { + boost::mutex::scoped_lock l(mutex); + queue_type_t &queue = _queues[sid]; + if (not queue.empty()) + { + buff = queue.front(); + queue.front().reset(); + queue.pop(); + return buff; + } + } + { + buff = _xport->get_recv_buff(timeout); + if (buff) + { + const uint32_t new_sid = uhd::wtohx(buff->cast()[1]); + if (new_sid != sid) + { + boost::mutex::scoped_lock l(mutex); + if (_queues.count(new_sid) == 0) UHD_LOGGER_ERROR("STREAMER") + << "recv packet demuxer unexpected sid 0x" << std::hex << new_sid << std::dec + ; + else _queues[new_sid].push(buff); + buff.reset(); + } + } + } + return buff; + } + + void realloc_sid(const uint32_t sid) + { + boost::mutex::scoped_lock l(mutex); + while(not _queues[sid].empty()) //allocated and clears if already allocated + { + _queues[sid].pop(); + } + } + + transport::zero_copy_if::sptr make_proxy(const uint32_t sid); + + typedef std::queue queue_type_t; + std::map _queues; + transport::zero_copy_if::sptr _xport; + boost::mutex mutex; + }; + + struct recv_packet_demuxer_proxy_3000 : transport::zero_copy_if + { + recv_packet_demuxer_proxy_3000(recv_packet_demuxer_3000::sptr demux, transport::zero_copy_if::sptr xport, const uint32_t sid): + _demux(demux), _xport(xport), _sid(sid) + { + _demux->realloc_sid(_sid); //causes clear + } + + ~recv_packet_demuxer_proxy_3000(void) + { + _demux->realloc_sid(_sid); //causes clear + } + + size_t get_num_recv_frames(void) const {return _xport->get_num_recv_frames();} + size_t get_recv_frame_size(void) const {return _xport->get_recv_frame_size();} + transport::managed_recv_buffer::sptr get_recv_buff(double timeout) + { + return _demux->get_recv_buff(_sid, timeout); + } + size_t get_num_send_frames(void) const {return _xport->get_num_send_frames();} + size_t get_send_frame_size(void) const {return _xport->get_send_frame_size();} + transport::managed_send_buffer::sptr get_send_buff(double timeout) + { + return _xport->get_send_buff(timeout); + } + + recv_packet_demuxer_3000::sptr _demux; + transport::zero_copy_if::sptr _xport; + const uint32_t _sid; + }; + + inline transport::zero_copy_if::sptr recv_packet_demuxer_3000::make_proxy(const uint32_t sid) + { + return transport::zero_copy_if::sptr(new recv_packet_demuxer_proxy_3000(this->shared_from_this(), _xport, sid)); + } + +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp b/host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp new file mode 100644 index 000000000..f2f3ce035 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/common/validate_subdev_spec.hpp @@ -0,0 +1,28 @@ +// +// Copyright 2011 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP +#define INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP + +#include +#include +#include +#include + +namespace uhd{ namespace usrp{ + + //! Validate a subdev spec against a property tree + void validate_subdev_spec( + property_tree::sptr tree, + const subdev_spec_t &spec, + const std::string &type, //rx or tx + const std::string &mb = "0" + ); + +}} //namespace uhd::usrp + +#endif /* INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/dma_fifo_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/dma_fifo_core_3000.hpp new file mode 100644 index 000000000..17c02c93a --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/dma_fifo_core_3000.hpp @@ -0,0 +1,76 @@ +// +// Copyright 2015 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP + +#include +#include +#include +#include + + +class dma_fifo_core_3000 : boost::noncopyable +{ +public: + typedef boost::shared_ptr sptr; + virtual ~dma_fifo_core_3000(void) = 0; + + /*! + * Create a DMA FIFO controller using the given bus, settings and readback base + * Throws uhd::runtime_error if a DMA FIFO is not instantiated in the FPGA + */ + static sptr make(uhd::wb_iface::sptr iface, const size_t set_base, const size_t rb_addr); + + /*! + * Check if a DMA FIFO is instantiated in the FPGA + */ + static bool check(uhd::wb_iface::sptr iface, const size_t set_base, const size_t rb_addr); + + /*! + * Flush the DMA FIFO. Will clear all contents. + */ + virtual void flush() = 0; + + /*! + * Resize and rebase the DMA FIFO. Will clear all contents. + */ + virtual void resize(const uint32_t base_addr, const uint32_t size) = 0; + + /*! + * Get the (approx) number of bytes currently in the DMA FIFO + */ + virtual uint32_t get_bytes_occupied() = 0; + + /*! + * Run the built-in-self-test routine for the DMA FIFO + */ + virtual uint8_t run_bist(bool finite = true, uint32_t timeout_ms = 500) = 0; + + /*! + * Is extended BIST supported + */ + virtual bool ext_bist_supported() = 0; + + /*! + * Run the built-in-self-test routine for the DMA FIFO (extended BIST only) + */ + virtual uint8_t run_ext_bist( + bool finite, + uint32_t rx_samp_delay, + uint32_t tx_pkt_delay, + uint32_t sid, + uint32_t timeout_ms = 500) = 0; + + /*! + * Get the throughput measured from the last invocation of the BIST (extended BIST only) + */ + virtual double get_bist_throughput() = 0; + +}; + +#endif /* INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp b/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp new file mode 100644 index 000000000..739b973cb --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp @@ -0,0 +1,23 @@ +// +// Copyright 2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_DSP_CORE_UTILS_HPP +#define INCLUDED_LIBUHD_DSP_CORE_UTILS_HPP + +#include + +/*! For a requested frequency and sampling rate, return the + * correct frequency word (to set the CORDIC) and the actual frequency. + */ +void get_freq_and_freq_word( + const double requested_freq, + const double tick_rate, + double &actual_freq, + int32_t &freq_word +); + +#endif /* INCLUDED_LIBUHD_DSP_CORE_UTILS_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/gpio_atr_3000.hpp b/host/lib/include/uhdlib/usrp/cores/gpio_atr_3000.hpp new file mode 100644 index 000000000..30c7d6fb7 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/gpio_atr_3000.hpp @@ -0,0 +1,178 @@ +// +// Copyright 2011,2014,2015 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP + +#include +#include +#include +#include +#include +#include + +namespace uhd { namespace usrp { namespace gpio_atr { + +class gpio_atr_3000 : boost::noncopyable { +public: + typedef boost::shared_ptr sptr; + + static const uint32_t MASK_SET_ALL = 0xFFFFFFFF; + + virtual ~gpio_atr_3000(void) {}; + + /*! + * Create a read-write GPIO ATR interface object + * + * \param iface register iface to GPIO ATR registers + * \param base base settings offset for GPIO ATR registers + * \param rb_addr readback offset for GPIO ATR registers + */ + static sptr make( + uhd::wb_iface::sptr iface, + const uhd::wb_iface::wb_addr_type base, + const uhd::wb_iface::wb_addr_type rb_addr); + + /*! + * Create a write-only GPIO ATR interface object + * + * \param iface register iface to GPIO ATR registers + * \param base base settings offset for GPIO ATR registers + */ + static sptr make_write_only( + uhd::wb_iface::sptr iface, const uhd::wb_iface::wb_addr_type base); + + /*! + * Select the ATR mode for all bits in the mask + * + * \param mode the mode to apply {ATR = outputs driven by ATR state machine, GPIO = outputs static} + * \param mask apply the mode to all non-zero bits in the mask + */ + virtual void set_atr_mode(const gpio_atr_mode_t mode, const uint32_t mask) = 0; + + /*! + * Select the data direction for all bits in the mask + * + * \param dir the direction {OUTPUT, INPUT} + * \param mask apply the mode to all non-zero bits in the mask + */ + virtual void set_gpio_ddr(const gpio_ddr_t dir, const uint32_t mask) = 0; + + /*! + * Write the specified (masked) value to the ATR register + * + * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX} + * \param value the value to write + * \param mask only writes to the bits where mask is non-zero + */ + virtual void set_atr_reg(const gpio_atr_reg_t atr, const uint32_t value, const uint32_t mask = MASK_SET_ALL) = 0; + + /*! + * Write to a static GPIO output + * + * \param value the value to write + * \param mask only writes to the bits where mask is non-zero + */ + virtual void set_gpio_out(const uint32_t value, const uint32_t mask = MASK_SET_ALL) = 0; + + /*! + * Read the state of the GPIO pins + * If a pin is configured as an input, reads the actual value of the pin + * If a pin is configured as an output, reads the last value written to the pin + * + * \return the value read back + */ + virtual uint32_t read_gpio() = 0; + + /*! + * Set a GPIO attribute + * + * \param attr the attribute to set + * \param value the value to write to the attribute + */ + virtual void set_gpio_attr(const gpio_attr_t attr, const uint32_t value) = 0; +}; + +class db_gpio_atr_3000 { +public: + typedef boost::shared_ptr sptr; + + typedef uhd::usrp::dboard_iface::unit_t db_unit_t; + + virtual ~db_gpio_atr_3000(void) {}; + + /*! + * Create a read-write GPIO ATR interface object for a daughterboard connector + * + * \param iface register iface to GPIO ATR registers + * \param base base settings offset for GPIO ATR registers + * \param rb_addr readback offset for GPIO ATR registers + */ + static sptr make( + uhd::wb_iface::sptr iface, + const uhd::wb_iface::wb_addr_type base, + const uhd::wb_iface::wb_addr_type rb_addr); + + /*! + * Configure the GPIO mode for all pins in the daughterboard connector + * + * \param unit the side of the daughterboard interface to configure (TX or RX) + * \param value if value[i] is 1, the i'th bit is in ATR mode otherwise it is in GPIO mode + * \param mask mask + */ + virtual void set_pin_ctrl(const db_unit_t unit, const uint32_t value, const uint32_t mask) = 0; + + virtual uint32_t get_pin_ctrl(const db_unit_t unit) = 0; + + /*! + * Configure the direction for all pins in the daughterboard connector + * + * \param unit the side of the daughterboard interface to configure (TX or RX) + * \param value if value[i] is 1, the i'th bit is an output otherwise it is an input + * \param mask mask + */ + virtual void set_gpio_ddr(const db_unit_t unit, const uint32_t value, const uint32_t mask) = 0; + + virtual uint32_t get_gpio_ddr(const db_unit_t unit) = 0; + + /*! + * Write the specified value to the ATR register (all bits) + * + * \param unit the side of the daughterboard interface to configure (TX or RX) + * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX} + * \param value the value to write + * \param mask mask + */ + virtual void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const uint32_t value, const uint32_t mask) = 0; + + virtual uint32_t get_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr) = 0; + + /*! + * Write the specified value to the GPIO register (all bits) + * + * \param unit the side of the daughterboard interface to configure (TX or RX) + * \param value the value to write + * \param mask mask + */ + virtual void set_gpio_out(const db_unit_t unit, const uint32_t value, const uint32_t mask) = 0; + + virtual uint32_t get_gpio_out(const db_unit_t unit) = 0; + + /*! + * Read the state of the GPIO pins + * If a pin is configured as an input, reads the actual value of the pin + * If a pin is configured as an output, reads the last value written to the pin + * + * \param unit the side of the daughterboard interface to configure (TX or RX) + * \return the value read back + */ + virtual uint32_t read_gpio(const db_unit_t unit) = 0; +}; + +}}} //namespaces + +#endif /* INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp new file mode 100644 index 000000000..d5dff890e --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/gpio_core_200.hpp @@ -0,0 +1,77 @@ +// +// Copyright 2011,2014,2015 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_GPIO_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_GPIO_CORE_200_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class gpio_core_200 : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + typedef uhd::usrp::dboard_iface::unit_t unit_t; + typedef uhd::usrp::dboard_iface::atr_reg_t atr_reg_t; + + virtual ~gpio_core_200(void) = 0; + + //! makes a new GPIO core from iface and slave base + static sptr make( + uhd::wb_iface::sptr iface, const size_t base, const size_t rb_addr); + + //! 1 = ATR + virtual void set_pin_ctrl( + const unit_t unit, const uint16_t value, const uint16_t mask) = 0; + + virtual uint16_t get_pin_ctrl(unit_t unit) = 0; + + virtual void set_atr_reg( + const unit_t unit, const atr_reg_t atr, const uint16_t value, const uint16_t mask) = 0; + + virtual uint16_t get_atr_reg(unit_t unit, atr_reg_t reg) = 0; + + //! 1 = OUTPUT + virtual void set_gpio_ddr( + const unit_t unit, const uint16_t value, const uint16_t mask) = 0; + + virtual uint16_t get_gpio_ddr(unit_t unit) = 0; + + virtual void set_gpio_out( + const unit_t unit, const uint16_t value, const uint16_t mask) = 0; + + virtual uint16_t get_gpio_out(unit_t unit) = 0; + + virtual uint16_t read_gpio(const unit_t unit) = 0; +}; + +//! Simple wrapper for 32 bit write only +class gpio_core_200_32wo : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + typedef uhd::usrp::dboard_iface::atr_reg_t atr_reg_t; + + virtual ~gpio_core_200_32wo(void) = 0; + + static sptr make(uhd::wb_iface::sptr iface, const size_t); + + virtual void set_ddr_reg() = 0; + + virtual void set_atr_reg(const atr_reg_t atr, const uint32_t value) = 0; + + virtual void set_all_regs(const uint32_t value) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_GPIO_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp b/host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp new file mode 100644 index 000000000..6c4182544 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/i2c_core_100_wb32.hpp @@ -0,0 +1,29 @@ +// +// Copyright 2011-2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_I2C_CORE_100_WB32_HPP +#define INCLUDED_LIBUHD_USRP_I2C_CORE_100_WB32_HPP + +#include +#include +#include +#include +#include + +class i2c_core_100_wb32 : boost::noncopyable, public uhd::i2c_iface{ +public: + typedef boost::shared_ptr sptr; + + virtual ~i2c_core_100_wb32(void) = 0; + + //! makes a new i2c core from iface and slave base + static sptr make(uhd::wb_iface::sptr iface, const size_t base); + + virtual void set_clock_rate(const double rate) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_I2C_CORE_100_WB32_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp new file mode 100644 index 000000000..354244891 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/i2c_core_200.hpp @@ -0,0 +1,27 @@ +// +// Copyright 2011-2012,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_I2C_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_I2C_CORE_200_HPP + +#include +#include +#include +#include +#include + +class i2c_core_200 : boost::noncopyable, public uhd::i2c_iface{ +public: + typedef boost::shared_ptr sptr; + + virtual ~i2c_core_200(void) = 0; + + //! makes a new i2c core from iface and slave base + static sptr make(uhd::wb_iface::sptr iface, const size_t base, const size_t readback); +}; + +#endif /* INCLUDED_LIBUHD_USRP_I2C_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp new file mode 100644 index 000000000..f7be7ef91 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/radio_ctrl_core_3000.hpp @@ -0,0 +1,54 @@ +// +// Copyright 2012-2015 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP +#define INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP + +#include +#include +#include +#include +#include +#include +#include + +/*! + * Provide access to peek, poke for the radio ctrl module + */ +class radio_ctrl_core_3000 : public uhd::timed_wb_iface +{ +public: + typedef boost::shared_ptr sptr; + + virtual ~radio_ctrl_core_3000(void) = 0; + + //! Make a new control object + static sptr make( + const bool big_endian, + uhd::transport::zero_copy_if::sptr ctrl_xport, + uhd::transport::zero_copy_if::sptr resp_xport, + const uint32_t sid, + const std::string &name = "0" + ); + + //! Hold a ref to a task thats feeding push response + virtual void hold_task(uhd::msg_task::sptr task) = 0; + + //! Push a response externall (resp_xport is NULL) + virtual void push_response(const uint32_t *buff) = 0; + + //! Set the command time that will activate + virtual void set_time(const uhd::time_spec_t &time) = 0; + + //! Get the command time that will activate + virtual uhd::time_spec_t get_time(void) = 0; + + //! Set the tick rate (converting time into ticks) + virtual void set_tick_rate(const double rate) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp new file mode 100644 index 000000000..e9b6b98cf --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_200.hpp @@ -0,0 +1,59 @@ +// +// Copyright 2011,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +class rx_dsp_core_200 : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + virtual ~rx_dsp_core_200(void) = 0; + + static sptr make( + uhd::wb_iface::sptr iface, + const size_t dsp_base, const size_t ctrl_base, + const uint32_t sid, const bool lingering_packet = false + ); + + virtual void clear(void) = 0; + + virtual void set_nsamps_per_packet(const size_t nsamps) = 0; + + virtual void issue_stream_command(const uhd::stream_cmd_t &stream_cmd) = 0; + + virtual void set_mux(const std::string &mode, const bool fe_swapped = false) = 0; + + virtual void set_tick_rate(const double rate) = 0; + + virtual void set_link_rate(const double rate) = 0; + + virtual double set_host_rate(const double rate) = 0; + + virtual uhd::meta_range_t get_host_rates(void) = 0; + + virtual double get_scaling_adjustment(void) = 0; + + virtual uhd::meta_range_t get_freq_range(void) = 0; + + virtual double set_freq(const double freq) = 0; + + virtual void handle_overflow(void) = 0; + + virtual void setup(const uhd::stream_args_t &stream_args) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_3000.hpp new file mode 100644 index 000000000..0fba8ed65 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/rx_dsp_core_3000.hpp @@ -0,0 +1,58 @@ +// +// Copyright 2011-2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_RX_DSP_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_RX_DSP_CORE_3000_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class rx_dsp_core_3000 : boost::noncopyable{ +public: + static const double DEFAULT_CORDIC_FREQ; + static const double DEFAULT_RATE; + + typedef boost::shared_ptr sptr; + + virtual ~rx_dsp_core_3000(void) = 0; + + static sptr make( + uhd::wb_iface::sptr iface, + const size_t dsp_base, + const bool is_b200 = false //TODO: Obsolete this when we switch to the new DDC on the B200 + ); + + virtual void set_mux(const uhd::usrp::fe_connection_t& fe_conn) = 0; + + virtual void set_tick_rate(const double rate) = 0; + + virtual void set_link_rate(const double rate) = 0; + + virtual double set_host_rate(const double rate) = 0; + + virtual uhd::meta_range_t get_host_rates(void) = 0; + + virtual double get_scaling_adjustment(void) = 0; + + virtual uhd::meta_range_t get_freq_range(void) = 0; + + virtual double set_freq(const double freq) = 0; + + virtual void setup(const uhd::stream_args_t &stream_args) = 0; + + virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp new file mode 100644 index 000000000..c4848bde2 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_200.hpp @@ -0,0 +1,43 @@ +// +// Copyright 2011,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP + +#include +#include +#include +#include +#include +#include +#include + +class rx_frontend_core_200 : boost::noncopyable{ +public: + static const std::complex DEFAULT_DC_OFFSET_VALUE; + static const bool DEFAULT_DC_OFFSET_ENABLE; + static const std::complex DEFAULT_IQ_BALANCE_VALUE; + + typedef boost::shared_ptr sptr; + + virtual ~rx_frontend_core_200(void) = 0; + + static sptr make(uhd::wb_iface::sptr iface, const size_t base); + + virtual void set_mux(const bool swap) = 0; + + virtual void set_dc_offset_auto(const bool enb) = 0; + + virtual std::complex set_dc_offset(const std::complex &off) = 0; + + virtual void set_iq_balance(const std::complex &cor) = 0; + + virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; + +}; + +#endif /* INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp new file mode 100644 index 000000000..e425e51a4 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/rx_frontend_core_3000.hpp @@ -0,0 +1,59 @@ +// +// Copyright 2011,2014-2016 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_3000_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +class rx_frontend_core_3000 : boost::noncopyable{ +public: + static const std::complex DEFAULT_DC_OFFSET_VALUE; + static const bool DEFAULT_DC_OFFSET_ENABLE; + static const std::complex DEFAULT_IQ_BALANCE_VALUE; + + typedef boost::shared_ptr sptr; + + virtual ~rx_frontend_core_3000(void) = 0; + + static sptr make(uhd::wb_iface::sptr iface, const size_t base); + + /*! Set the input sampling rate (i.e. ADC rate) + */ + virtual void set_adc_rate(const double rate) = 0; + + virtual void bypass_all(bool bypass_en) = 0; + + virtual void set_fe_connection(const uhd::usrp::fe_connection_t& fe_conn) = 0; + + virtual void set_dc_offset_auto(const bool enb) = 0; + + virtual std::complex set_dc_offset(const std::complex &off) = 0; + + virtual void set_iq_balance(const std::complex &cor) = 0; + + virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; + + /*! Return the sampling rate at the output + * + * In real mode, the frontend core will decimate the sampling rate by a + * factor of 2. + * + * \returns RX sampling rate + */ + virtual double get_output_rate(void) = 0; + +}; + +#endif /* INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp new file mode 100644 index 000000000..919631300 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/rx_vita_core_3000.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2013,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_RX_VITA_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_RX_VITA_CORE_3000_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +class rx_vita_core_3000 : boost::noncopyable +{ +public: + typedef boost::shared_ptr sptr; + + virtual ~rx_vita_core_3000(void) = 0; + + static sptr make( + uhd::wb_iface::sptr iface, + const size_t base + ); + + virtual void clear(void) = 0; + + virtual void set_nsamps_per_packet(const size_t nsamps) = 0; + + virtual void issue_stream_command(const uhd::stream_cmd_t &stream_cmd) = 0; + + virtual void set_tick_rate(const double rate) = 0; + + virtual void set_sid(const uint32_t sid) = 0; + + virtual void handle_overflow(void) = 0; + + virtual void setup(const uhd::stream_args_t &stream_args) = 0; + + virtual void configure_flow_control(const size_t window_size) = 0; + + virtual bool in_continuous_streaming_mode(void) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_RX_VITA_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp new file mode 100644 index 000000000..ea0507754 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/spi_core_3000.hpp @@ -0,0 +1,38 @@ +// +// Copyright 2013-2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_SPI_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_SPI_CORE_3000_HPP + +#include +#include +#include +#include +#include + +class spi_core_3000 : boost::noncopyable, public uhd::spi_iface +{ +public: + typedef boost::shared_ptr sptr; + + virtual ~spi_core_3000(void) = 0; + + //! makes a new spi core from iface and slave base + static sptr make(uhd::wb_iface::sptr iface, const size_t base, const size_t readback); + + //! Set the spi clock divider to something usable + virtual void set_divider(const double div) = 0; + + //! Place SPI core in shutdown mode. All attempted SPI transactions are dropped by + // the core. + virtual void set_shutdown(const bool shutdown) = 0; + + //! Get state of shutdown register + virtual bool get_shutdown() = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_SPI_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp new file mode 100644 index 000000000..23e0da922 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/time64_core_200.hpp @@ -0,0 +1,55 @@ +// +// Copyright 2011-2012,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP + +#include +#include +#include +#include +#include +#include +#include + +class time64_core_200 : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + struct readback_bases_type{ + size_t rb_hi_now, rb_lo_now; + size_t rb_hi_pps, rb_lo_pps; + }; + + virtual ~time64_core_200(void) = 0; + + //! makes a new time64 core from iface and slave base + static sptr make( + uhd::wb_iface::sptr iface, const size_t base, + const readback_bases_type &readback_bases, + const size_t mimo_delay_cycles = 0 // 0 means no-mimo + ); + + virtual void enable_gpsdo(void) = 0; + + virtual void set_tick_rate(const double rate) = 0; + + virtual uhd::time_spec_t get_time_now(void) = 0; + + virtual uhd::time_spec_t get_time_last_pps(void) = 0; + + virtual void set_time_now(const uhd::time_spec_t &time) = 0; + + virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0; + + virtual void set_time_source(const std::string &source) = 0; + + virtual std::vector get_time_sources(void) = 0; + +}; + +#endif /* INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp new file mode 100644 index 000000000..4fa2ae657 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/time_core_3000.hpp @@ -0,0 +1,52 @@ +// +// Copyright 2013-2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_TIME_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_TIME_CORE_3000_HPP + +#include +#include +#include +#include +#include + +class time_core_3000 : boost::noncopyable +{ +public: + typedef boost::shared_ptr sptr; + + struct readback_bases_type + { + size_t rb_now; + size_t rb_pps; + }; + + virtual ~time_core_3000(void) = 0; + + //! makes a new time core from iface and slave base + static sptr make( + uhd::wb_iface::sptr iface, const size_t base, + const readback_bases_type &readback_bases + ); + + virtual void self_test(void) = 0; + + virtual void set_tick_rate(const double rate) = 0; + + virtual uhd::time_spec_t get_time_now(void) = 0; + + virtual uhd::time_spec_t get_time_last_pps(void) = 0; + + virtual void set_time_now(const uhd::time_spec_t &time) = 0; + + virtual void set_time_sync(const uhd::time_spec_t &time) = 0; + + virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0; + +}; + +#endif /* INCLUDED_LIBUHD_USRP_TIME_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp new file mode 100644 index 000000000..98e8b5225 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_200.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2011,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP + +#include +#include +#include +#include +#include +#include + +class tx_dsp_core_200 : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + virtual ~tx_dsp_core_200(void) = 0; + + static sptr make( + uhd::wb_iface::sptr iface, + const size_t dsp_base, const size_t ctrl_base, + const uint32_t sid + ); + + virtual void clear(void) = 0; + + virtual void set_tick_rate(const double rate) = 0; + + virtual void set_link_rate(const double rate) = 0; + + virtual double set_host_rate(const double rate) = 0; + + virtual uhd::meta_range_t get_host_rates(void) = 0; + + virtual double get_scaling_adjustment(void) = 0; + + virtual uhd::meta_range_t get_freq_range(void) = 0; + + virtual double set_freq(const double freq) = 0; + + virtual void set_updates(const size_t cycles_per_up, const size_t packets_per_up) = 0; + + virtual void setup(const uhd::stream_args_t &stream_args) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_3000.hpp new file mode 100644 index 000000000..3eb53da0d --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/tx_dsp_core_3000.hpp @@ -0,0 +1,52 @@ +// +// Copyright 2011-2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_TX_DSP_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_TX_DSP_CORE_3000_HPP + +#include +#include +#include +#include +#include +#include +#include + +class tx_dsp_core_3000 : boost::noncopyable{ +public: + static const double DEFAULT_CORDIC_FREQ; + static const double DEFAULT_RATE; + + typedef boost::shared_ptr sptr; + + virtual ~tx_dsp_core_3000(void) = 0; + + static sptr make( + uhd::wb_iface::sptr iface, + const size_t dsp_base + ); + + virtual void set_tick_rate(const double rate) = 0; + + virtual void set_link_rate(const double rate) = 0; + + virtual double set_host_rate(const double rate) = 0; + + virtual uhd::meta_range_t get_host_rates(void) = 0; + + virtual double get_scaling_adjustment(void) = 0; + + virtual uhd::meta_range_t get_freq_range(void) = 0; + + virtual double set_freq(const double freq) = 0; + + virtual void setup(const uhd::stream_args_t &stream_args) = 0; + + virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_TX_DSP_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp new file mode 100644 index 000000000..eb86bf85d --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/tx_frontend_core_200.hpp @@ -0,0 +1,40 @@ +// +// Copyright 2011,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP + +#include +#include +#include +#include +#include +#include +#include + +class tx_frontend_core_200 : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + static const std::complex DEFAULT_DC_OFFSET_VALUE; + static const std::complex DEFAULT_IQ_BALANCE_VALUE; + + virtual ~tx_frontend_core_200(void) = 0; + + static sptr make(uhd::wb_iface::sptr iface, const size_t base); + + virtual void set_mux(const std::string &mode) = 0; + + virtual std::complex set_dc_offset(const std::complex &off) = 0; + + virtual void set_iq_balance(const std::complex &cor) = 0; + + virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; + +}; + +#endif /* INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp new file mode 100644 index 000000000..4d33bb0c2 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/tx_vita_core_3000.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2013-2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_TX_VITA_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_TX_VITA_CORE_3000_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +class tx_vita_core_3000 : boost::noncopyable +{ +public: + typedef boost::shared_ptr sptr; + + enum fc_monitor_loc { + FC_DEFAULT, + FC_PRE_RADIO, + FC_PRE_FIFO + }; + + virtual ~tx_vita_core_3000(void) = 0; + + static sptr make( + uhd::wb_iface::sptr iface, + const size_t base, + fc_monitor_loc fc_location = FC_PRE_RADIO + ); + + static sptr make_no_radio_buff( + uhd::wb_iface::sptr iface, + const size_t base + ); + + virtual void clear(void) = 0; + + virtual void setup(const uhd::stream_args_t &stream_args) = 0; + + virtual void configure_flow_control(const size_t cycs_per_up, const size_t pkts_per_up) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_TX_VITA_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp b/host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp new file mode 100644 index 000000000..354b5e637 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/user_settings_core_200.hpp @@ -0,0 +1,28 @@ +// +// Copyright 2012,2014 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP +#define INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP + +#include +#include +#include +#include + +class user_settings_core_200 : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + typedef std::pair user_reg_t; + + virtual ~user_settings_core_200(void) = 0; + + static sptr make(uhd::wb_iface::sptr iface, const size_t base); + + virtual void set_reg(const user_reg_t ®) = 0; +}; + +#endif /* INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP */ diff --git a/host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp b/host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp new file mode 100644 index 000000000..bc281e396 --- /dev/null +++ b/host/lib/include/uhdlib/usrp/cores/user_settings_core_3000.hpp @@ -0,0 +1,25 @@ +// +// Copyright 2012 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP +#define INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP + +#include +#include +#include +#include + +class user_settings_core_3000 : public uhd::wb_iface { +public: + virtual ~user_settings_core_3000() {} + + static sptr make( + wb_iface::sptr iface, + const wb_addr_type sr_base_addr, const wb_addr_type rb_reg_addr); +}; + +#endif /* INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP */ diff --git a/host/lib/include/uhdlib/utils/eeprom_utils.hpp b/host/lib/include/uhdlib/utils/eeprom_utils.hpp new file mode 100644 index 000000000..28deca790 --- /dev/null +++ b/host/lib/include/uhdlib/utils/eeprom_utils.hpp @@ -0,0 +1,20 @@ +// +// Copyright 2017 Ettus Research (National Instruments Corp.) +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include +#include +#include +#include +#include + +static const size_t SERIAL_LEN = 9; +static const size_t NAME_MAX_LEN = 32 - SERIAL_LEN; + +//! convert a string to a byte vector to write to eeprom +uhd::byte_vector_t string_to_uint16_bytes(const std::string &num_str); + +//! convert a byte vector read from eeprom to a string +std::string uint16_bytes_to_string(const uhd::byte_vector_t &bytes); diff --git a/host/lib/include/uhdlib/utils/ihex.hpp b/host/lib/include/uhdlib/utils/ihex.hpp new file mode 100644 index 000000000..4b1be77f1 --- /dev/null +++ b/host/lib/include/uhdlib/utils/ihex.hpp @@ -0,0 +1,69 @@ +// +// Copyright 2015 Ettus Research LLC +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_IHEX_READER_HPP +#define INCLUDED_IHEX_READER_HPP + +#include +#include +#include +#include +#include + +namespace uhd { + +class ihex_reader +{ +public: + // Arguments are: lower address bits, upper address bits, buff, length + typedef boost::function record_handle_type; + + /* + * \param ihex_filename Path to the *.ihx file + */ + ihex_reader(const std::string &ihex_filename); + + /*! Read an Intel HEX file and handle it record by record. + * + * Every record is individually passed off to a record handler function. + * + * \param record_handler The functor that will handle the records. + * + * \throws uhd::io_error if the HEX file is corrupted or unreadable. + */ + void read(record_handle_type record_handler); + + /* Convert the ihex file to a bin file. + * + * *Note:* This function makes the assumption that the hex file is + * contiguous, and starts at address zero. + * + * \param bin_filename Output filename. + * + * \throws uhd::io_error if the HEX file is corrupted or unreadable. + */ + void to_bin_file(const std::string &bin_filename); + + /*! Copy the ihex file into a buffer. + * + * Very similar functionality as to_bin_file(). + * + * *Note:* This function makes the assumption that the hex file is + * contiguous, and starts at address zero. + * + * \throws uhd::io_error if the HEX file is corrupted or unreadable. + */ + std::vector to_vector(const size_t size_estimate = 0); + +private: + const std::string _ihex_filename; +}; + +}; /* namespace uhd */ + +#endif /* INCLUDED_IHEX_READER_HPP */ + diff --git a/host/lib/include/uhdlib/utils/rpc.hpp b/host/lib/include/uhdlib/utils/rpc.hpp new file mode 100644 index 000000000..c7c27afd2 --- /dev/null +++ b/host/lib/include/uhdlib/utils/rpc.hpp @@ -0,0 +1,191 @@ +// +// Copyright 2017 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_UTILS_RPC_HPP +#define INCLUDED_UTILS_RPC_HPP + +#include +#include +#include +#include +#include + +namespace uhd { + +/*! Abstraction for RPC client + * + * Purpose of this class is to wrap the underlying RPC implementation. + * This class holds a connection to an RPC server (the connection is severed on + * destruction). + */ +class rpc_client +{ + public: + using sptr = std::shared_ptr; + + static sptr make( + const std::string &addr, + const uint16_t port, + const std::string &get_last_error_cmd="" + ) { + return std::make_shared(addr, port, get_last_error_cmd); + } + + /*! + * \param addr An IP address to connect to + * \param port Port to connect to + * \param get_last_error_cmd A command that queries an error string from + * the RPC server. If set, the RPC client will + * try and use this command to fetch information + * about what went wrong on the client side. + */ + rpc_client( + const std::string &addr, + const uint16_t port, + std::string const &get_last_error_cmd="" + ) : _client(addr, port) + , _get_last_error_cmd(get_last_error_cmd) + { + // nop + } + + /*! Perform an RPC request. + * + * Thread safe (locked). This function blocks until it receives a valid + * response from the server. + * + * \param func_name The function name that is called via RPC + * \param args All these arguments are passed to the RPC call + * + * \throws uhd::runtime_error in case of failure + */ + template + return_type request(std::string const& func_name, Args&&... args) + { + std::lock_guard lock(_mutex); + try { + return _client.call(func_name, std::forward(args)...) + .template as(); + } catch (const ::rpc::rpc_error &ex) { + const std::string error = _get_last_error_safe(); + if (not error.empty()) { + UHD_LOG_ERROR("RPC", error); + } + throw uhd::runtime_error(str( + boost::format("Error during RPC call to `%s'. Error message: %s") + % func_name % (error.empty() ? ex.what() : error) + )); + } catch (const std::bad_cast& ex) { + throw uhd::runtime_error(str( + boost::format("Error during RPC call to `%s'. Error message: %s") + % func_name % ex.what() + )); + } + }; + + /*! Perform an RPC notification. + * + * Thread safe (locked). This function does not require a response from the + * server, although the underlying implementation may provide one. + * + * \param func_name The function name that is called via RPC + * \param args All these arguments are passed to the RPC call + * + * \throws uhd::runtime_error in case of failure + */ + template + void notify(std::string const& func_name, Args&&... args) + { + std::lock_guard lock(_mutex); + try { + _client.call(func_name, std::forward(args)...); + } catch (const ::rpc::rpc_error &ex) { + const std::string error = _get_last_error_safe(); + if (not error.empty()) { + UHD_LOG_ERROR("RPC", error); + } + throw uhd::runtime_error(str( + boost::format("Error during RPC call to `%s'. Error message: %s") + % func_name % (error.empty() ? ex.what() : error) + )); + } catch (const std::bad_cast& ex) { + throw uhd::runtime_error(str( + boost::format("Error during RPC call to `%s'. Error message: %s") + % func_name % ex.what() + )); + } + }; + + /*! Like request(), also provides a token. + * + * This is a convenience wrapper to directly call a function that requires + * a token without having to have a copy of the token. + */ + template + return_type request_with_token(std::string const& func_name, Args&&... args) + { + return request(func_name, _token, std::forward(args)...); + }; + + /*! Like notify(), also provides a token. + * + * This is a convenience wrapper to directly call a function that requires + * a token without having to have a copy of the token. + */ + template + void notify_with_token(std::string const& func_name, Args&&... args) + { + notify(func_name, _token, std::forward(args)...); + }; + + /*! Sets the token value. This is used by the `_with_token` methods. + */ + void set_token(const std::string &token) + { + _token = token; + } + + void set_timeout(size_t timeout_ms) + { + _client.set_timeout(timeout_ms); + } + + private: + /*! Pull the last error out of the RPC server. Not thread-safe, meant to + * be called from notify() or request(). + * + * This function will do its best not to get in anyone's way. If it can't + * get an error string, it'll return an empty string. + */ + std::string _get_last_error_safe() + { + if (_get_last_error_cmd.empty()) { + return ""; + } + try { + return _client.call(_get_last_error_cmd).as(); + } catch (const ::rpc::rpc_error &ex) { + // nop + } catch (const std::bad_cast& ex) { + // nop + } catch (...) { + // nop + } + return ""; + } + + //! Reference the actual RPC client + ::rpc::client _client; + //! If set, this is the command that will retrieve an error + const std::string _get_last_error_cmd; + + std::string _token; + std::mutex _mutex; +}; + +} /* namespace uhd */ + +#endif /* INCLUDED_UTILS_RPC_HPP */ diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt index 76e5cbd9d..9ee4970a3 100644 --- a/host/lib/rfnoc/CMakeLists.txt +++ b/host/lib/rfnoc/CMakeLists.txt @@ -9,8 +9,6 @@ # This file included, use CMake directory variables ######################################################################## -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - LIBUHD_APPEND_SOURCES( # Infrastructure: ${CMAKE_CURRENT_SOURCE_DIR}/block_ctrl_base.cpp diff --git a/host/lib/rfnoc/block_ctrl_base.cpp b/host/lib/rfnoc/block_ctrl_base.cpp index 3bf0edd87..e842dabff 100644 --- a/host/lib/rfnoc/block_ctrl_base.cpp +++ b/host/lib/rfnoc/block_ctrl_base.cpp @@ -8,7 +8,6 @@ // This file contains the block control functions for block controller classes. // See block_ctrl_base_factory.cpp for discovery and factory functions. -#include "ctrl_iface.hpp" #include "nocscript/block_iface.hpp" #include @@ -16,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/host/lib/rfnoc/ctrl_iface.cpp b/host/lib/rfnoc/ctrl_iface.cpp index d9975f874..147f81e0c 100644 --- a/host/lib/rfnoc/ctrl_iface.cpp +++ b/host/lib/rfnoc/ctrl_iface.cpp @@ -5,15 +5,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "ctrl_iface.hpp" #include - #include #include #include #include #include #include +#include #include #include #include diff --git a/host/lib/rfnoc/ctrl_iface.hpp b/host/lib/rfnoc/ctrl_iface.hpp deleted file mode 100644 index 2ef50a1a1..000000000 --- a/host/lib/rfnoc/ctrl_iface.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2012-2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP -#define INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace uhd { namespace rfnoc { - -/*! - * Provide access to peek, poke for the radio ctrl module - */ -class ctrl_iface : public uhd::timed_wb_iface -{ -public: - typedef boost::shared_ptr sptr; - - virtual ~ctrl_iface(void) = 0; - - //! Make a new control object - static sptr make( - const bool big_endian, - uhd::transport::zero_copy_if::sptr ctrl_xport, - uhd::transport::zero_copy_if::sptr resp_xport, - const uint32_t sid, - const std::string &name = "0" - ); - - //! Set the tick rate (converting time into ticks) - virtual void set_tick_rate(const double rate) = 0; -}; - -}} /* namespace uhd::rfnoc */ - -#endif /* INCLUDED_LIBUHD_RFNOC_CTRL_IFACE_HPP */ diff --git a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp b/host/lib/rfnoc/ddc_block_ctrl_impl.cpp index 6b28fcb63..2919c163b 100644 --- a/host/lib/rfnoc/ddc_block_ctrl_impl.cpp +++ b/host/lib/rfnoc/ddc_block_ctrl_impl.cpp @@ -4,7 +4,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "dsp_core_utils.hpp" #include #include #include @@ -12,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp b/host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp index dc16bcce7..cbbd59323 100644 --- a/host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp +++ b/host/lib/rfnoc/dma_fifo_block_ctrl_impl.cpp @@ -6,11 +6,11 @@ // #include -#include "dma_fifo_core_3000.hpp" -#include "wb_iface_adapter.hpp" #include #include #include +#include +#include #include #include #include diff --git a/host/lib/rfnoc/duc_block_ctrl_impl.cpp b/host/lib/rfnoc/duc_block_ctrl_impl.cpp index e9567adb9..68109ec26 100644 --- a/host/lib/rfnoc/duc_block_ctrl_impl.cpp +++ b/host/lib/rfnoc/duc_block_ctrl_impl.cpp @@ -4,7 +4,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "dsp_core_utils.hpp" #include #include #include @@ -12,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/host/lib/rfnoc/graph_impl.cpp b/host/lib/rfnoc/graph_impl.cpp index 20862333b..c361ea8f2 100644 --- a/host/lib/rfnoc/graph_impl.cpp +++ b/host/lib/rfnoc/graph_impl.cpp @@ -5,10 +5,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "graph_impl.hpp" #include #include #include +#include using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/graph_impl.hpp b/host/lib/rfnoc/graph_impl.hpp deleted file mode 100644 index 182befbf4..000000000 --- a/host/lib/rfnoc/graph_impl.hpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright 2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP -#define INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP - -#include -#include - -namespace uhd { namespace rfnoc { - -class graph_impl : public graph -{ -public: - /*! - * \param name An optional name to describe this graph - * \param device_ptr Weak pointer to the originating device3 - * \param msg_handler Pointer to the async message handler - */ - graph_impl( - const std::string &name, - boost::weak_ptr device_ptr - //async_msg_handler::sptr msg_handler - ); - virtual ~graph_impl() {}; - - /************************************************************************ - * Connection API - ***********************************************************************/ - void connect( - const block_id_t &src_block, - size_t src_block_port, - const block_id_t &dst_block, - size_t dst_block_port, - const size_t pkt_size = 0 - ); - - void connect( - const block_id_t &src_block, - const block_id_t &dst_block - ); - - void connect_src( - const block_id_t &src_block, - const size_t src_block_port, - const uhd::sid_t dst_sid, - const size_t buf_size_dst_bytes, - const size_t pkt_size_ - ); - - void connect_sink( - const block_id_t &sink_block, - const size_t dst_block_port, - const size_t pkts_per_ack - ); - - /************************************************************************ - * Utilities - ***********************************************************************/ - std::string get_name() const { return _name; } - - -private: - - //! Optional: A string to describe this graph - const std::string _name; - - //! Reference to the generating device object - const boost::weak_ptr _device_ptr; - -}; - -}} /* namespace uhd::rfnoc */ - -#endif /* INCLUDED_LIBUHD_RFNOC_GRAPH_IMPL_HPP */ -// vim: sw=4 et: diff --git a/host/lib/rfnoc/legacy_compat.cpp b/host/lib/rfnoc/legacy_compat.cpp index 5e62c69da..f6e3d5eb5 100644 --- a/host/lib/rfnoc/legacy_compat.cpp +++ b/host/lib/rfnoc/legacy_compat.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "legacy_compat.hpp" #include "../usrp/device3/device3_impl.hpp" #include #include @@ -16,10 +15,10 @@ #include #include #include - #include #include #include +#include #include #include diff --git a/host/lib/rfnoc/legacy_compat.hpp b/host/lib/rfnoc/legacy_compat.hpp deleted file mode 100644 index 185b89f82..000000000 --- a/host/lib/rfnoc/legacy_compat.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// -// Copyright 2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_RFNOC_LEGACY_COMPAT_HPP -#define INCLUDED_RFNOC_LEGACY_COMPAT_HPP - -#include -#include - -namespace uhd { namespace rfnoc { - - /*! Legacy compatibility layer class. - */ - class legacy_compat - { - public: - typedef boost::shared_ptr sptr; - - virtual uhd::fs_path rx_dsp_root(const size_t mboard_idx, const size_t chan) = 0; - - virtual uhd::fs_path tx_dsp_root(const size_t mboard_idx, const size_t chan) = 0; - - virtual uhd::fs_path rx_fe_root(const size_t mboard_idx, const size_t chan) = 0; - - virtual uhd::fs_path tx_fe_root(const size_t mboard_idx, const size_t chan) = 0; - - virtual void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, size_t mboard, size_t chan) = 0; - - virtual uhd::rx_streamer::sptr get_rx_stream(const uhd::stream_args_t &args) = 0; - - virtual uhd::tx_streamer::sptr get_tx_stream(const uhd::stream_args_t &args) = 0; - - virtual void set_rx_rate(const double rate, const size_t chan) = 0; - - virtual void set_tx_rate(const double rate, const size_t chan) = 0; - - static sptr make( - uhd::device3::sptr device, - const uhd::device_addr_t &args - ); - }; - -}} /* namespace uhd::rfnoc */ - -#endif /* INCLUDED_RFNOC_LEGACY_COMPAT_HPP */ diff --git a/host/lib/rfnoc/radio_ctrl_impl.cpp b/host/lib/rfnoc/radio_ctrl_impl.cpp index c0b9a0f82..1de854266 100644 --- a/host/lib/rfnoc/radio_ctrl_impl.cpp +++ b/host/lib/rfnoc/radio_ctrl_impl.cpp @@ -5,13 +5,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "wb_iface_adapter.hpp" #include #include #include #include #include -#include "radio_ctrl_impl.hpp" +#include +#include #include "../../transport/super_recv_packet_handler.hpp" #include diff --git a/host/lib/rfnoc/radio_ctrl_impl.hpp b/host/lib/rfnoc/radio_ctrl_impl.hpp deleted file mode 100644 index 83c32c771..000000000 --- a/host/lib/rfnoc/radio_ctrl_impl.hpp +++ /dev/null @@ -1,247 +0,0 @@ -// -// Copyright 2014-2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP -#define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP - -#include "rx_vita_core_3000.hpp" -#include "tx_vita_core_3000.hpp" -#include "time_core_3000.hpp" -#include "gpio_atr_3000.hpp" -#include -#include -#include -#include - -//! Shorthand for radio block constructor -#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(CLASS_NAME) \ - CLASS_NAME##_impl(const make_args_t &make_args); - -#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(CLASS_NAME) \ - CLASS_NAME##_impl::CLASS_NAME##_impl( \ - const make_args_t &make_args \ - ) : block_ctrl_base(make_args), radio_ctrl_impl() - -namespace uhd { - namespace rfnoc { - -/*! \brief Provide access to a radio. - * - */ -class radio_ctrl_impl : public radio_ctrl -{ -public: - /************************************************************************ - * Structors - ***********************************************************************/ - radio_ctrl_impl(); - virtual ~radio_ctrl_impl() {}; - - /************************************************************************ - * Public Radio API calls - ***********************************************************************/ - virtual double set_rate(double rate); - virtual void set_tx_antenna(const std::string &ant, const size_t chan); - virtual void set_rx_antenna(const std::string &ant, const size_t chan); - virtual double set_tx_frequency(const double freq, const size_t chan); - virtual double set_rx_frequency(const double freq, const size_t chan); - virtual double set_tx_gain(const double gain, const size_t chan); - virtual double set_rx_gain(const double gain, const size_t chan); - virtual double set_tx_bandwidth(const double bandwidth, const size_t chan); - virtual double set_rx_bandwidth(const double bandwidth, const size_t chan); - - virtual double get_rate() const; - virtual std::string get_tx_antenna(const size_t chan) /* const */; - virtual std::string get_rx_antenna(const size_t chan) /* const */; - virtual double get_tx_frequency(const size_t) /* const */; - virtual double get_rx_frequency(const size_t) /* const */; - virtual double get_tx_gain(const size_t) /* const */; - virtual double get_rx_gain(const size_t) /* const */; - virtual double get_tx_bandwidth(const size_t) /* const */; - virtual double get_rx_bandwidth(const size_t) /* const */; - - virtual std::vector get_rx_lo_names(const size_t chan); - virtual std::vector get_rx_lo_sources(const std::string &name, const size_t chan); - virtual freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan); - - virtual void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan); - virtual const std::string get_rx_lo_source(const std::string &name, const size_t chan); - - virtual void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan); - virtual bool get_rx_lo_export_enabled(const std::string &name, const size_t chan); - - virtual double set_rx_lo_freq(const double freq, const std::string &name, const size_t chan); - virtual double get_rx_lo_freq(const std::string &name, const size_t chan); - - virtual std::vector get_tx_lo_names(const size_t chan); - virtual std::vector get_tx_lo_sources(const std::string &name, const size_t chan); - virtual freq_range_t get_tx_lo_freq_range(const std::string &name, const size_t chan); - - virtual void set_tx_lo_source(const std::string &src, const std::string &name, const size_t chan); - virtual const std::string get_tx_lo_source(const std::string &name, const size_t chan); - - virtual void set_tx_lo_export_enabled(const bool enabled, const std::string &name, const size_t chan); - virtual bool get_tx_lo_export_enabled(const std::string &name, const size_t chan); - - virtual double set_tx_lo_freq(const double freq, const std::string &name, const size_t chan); - virtual double get_tx_lo_freq(const std::string &name, const size_t chan); - - void set_time_now(const time_spec_t &time_spec); - void set_time_next_pps(const time_spec_t &time_spec); - void set_time_sync(const uhd::time_spec_t &time); - time_spec_t get_time_now(); - time_spec_t get_time_last_pps(); - virtual void set_time_source(const std::string &source); - virtual std::string get_time_source(); - virtual std::vector get_time_sources(); - virtual void set_clock_source(const std::string &source); - virtual std::string get_clock_source(); - virtual std::vector get_clock_sources(); - - virtual std::vector get_gpio_banks() const; - virtual void set_gpio_attr( - const std::string &bank, - const std::string &attr, - const uint32_t value, - const uint32_t mask - ); - virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr); - - /*********************************************************************** - * Block control API calls - **********************************************************************/ - void set_rx_streamer(bool active, const size_t port); - void set_tx_streamer(bool active, const size_t port); - - void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t port); - - virtual double get_input_samp_rate(size_t /* port */) { return get_rate(); } - virtual double get_output_samp_rate(size_t /* port */) { return get_rate(); } - double _get_tick_rate() { return get_rate(); } - - std::vector get_active_rx_ports(); - bool in_continuous_streaming_mode(const size_t chan) { return _continuous_streaming.at(chan); } - void rx_ctrl_clear_cmds(const size_t port) { sr_write(regs::RX_CTRL_CLEAR_CMDS, 0, port); } - -protected: // TODO see what's protected and what's private - void _register_loopback_self_test(size_t chan); - - /*********************************************************************** - * Registers - **********************************************************************/ - struct regs { - static inline uint32_t sr_addr(const uint32_t offset) - { - return offset * 4; - } - - static const uint32_t BASE = 128; - - // defined in radio_core_regs.vh - static const uint32_t TIME = 128; // time hi - 128, time lo - 129, ctrl - 130 - static const uint32_t CLEAR_CMDS = 131; // Any write to this reg clears the command FIFO - static const uint32_t LOOPBACK = 132; - static const uint32_t TEST = 133; - static const uint32_t CODEC_IDLE = 134; - static const uint32_t TX_CTRL_ERROR_POLICY = 144; - static const uint32_t RX_CTRL_CMD = 152; - static const uint32_t RX_CTRL_TIME_HI = 153; - static const uint32_t RX_CTRL_TIME_LO = 154; - static const uint32_t RX_CTRL_HALT = 155; - static const uint32_t RX_CTRL_MAXLEN = 156; - static const uint32_t RX_CTRL_CLEAR_CMDS = 157; - static const uint32_t MISC_OUTS = 160; - static const uint32_t DACSYNC = 161; - static const uint32_t SPI = 168; - static const uint32_t LEDS = 176; - static const uint32_t FP_GPIO = 184; - static const uint32_t GPIO = 192; - // NOTE: Upper 32 registers (224-255) are reserved for the output settings bus for use with - // device specific front end control - - // frontend control: needs rethinking TODO - //static const uint32_t TX_FRONT = BASE + 96; - //static const uint32_t RX_FRONT = BASE + 112; - //static const uint32_t READBACK = BASE + 127; - - static const uint32_t RB_TIME_NOW = 0; - static const uint32_t RB_TIME_PPS = 1; - static const uint32_t RB_TEST = 2; - static const uint32_t RB_CODEC_READBACK = 3; - static const uint32_t RB_RADIO_NUM = 4; - static const uint32_t RB_MISC_IO = 16; - static const uint32_t RB_SPI = 17; - static const uint32_t RB_LEDS = 18; - static const uint32_t RB_DB_GPIO = 19; - static const uint32_t RB_FP_GPIO = 20; - }; - - /*********************************************************************** - * Block control API calls - **********************************************************************/ - void _update_spp(int spp); - - inline size_t _get_num_radios() const { - return std::max(_num_rx_channels, _num_tx_channels); - } - - inline timed_wb_iface::sptr _get_ctrl(size_t radio_num) const { - return _perifs.at(radio_num).ctrl; - } - - inline bool _is_streamer_active(uhd::direction_t dir, const size_t chan) const { - switch (dir) { - case uhd::TX_DIRECTION: - return _tx_streamer_active.at(chan); - case uhd::RX_DIRECTION: - return _rx_streamer_active.at(chan); - case uhd::DX_DIRECTION: - return _rx_streamer_active.at(chan) and _tx_streamer_active.at(chan); - default: - return false; - } - } - - virtual bool check_radio_config() { return true; }; - - //! There is always only one time core per radio - time_core_3000::sptr _time64; - - std::mutex _mutex; - -private: - /************************************************************************ - * Peripherals - ***********************************************************************/ - //! Stores pointers to all streaming-related radio cores - struct radio_perifs_t - { - timed_wb_iface::sptr ctrl; - }; - std::map _perifs; - - size_t _num_tx_channels; - size_t _num_rx_channels; - - // Cached values - double _tick_rate; - std::map _tx_antenna; - std::map _rx_antenna; - std::map _tx_freq; - std::map _rx_freq; - std::map _tx_gain; - std::map _rx_gain; - std::map _tx_bandwidth; - std::map _rx_bandwidth; - - std::vector _continuous_streaming; -}; /* class radio_ctrl_impl */ - -}} /* namespace uhd::rfnoc */ - -#endif /* INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP */ -// vim: sw=4 et: diff --git a/host/lib/rfnoc/rpc_block_ctrl.hpp b/host/lib/rfnoc/rpc_block_ctrl.hpp deleted file mode 100644 index 36170716e..000000000 --- a/host/lib/rfnoc/rpc_block_ctrl.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright 2017 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP -#define INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP - -#include "../utils/rpc.hpp" - -namespace uhd { - namespace rfnoc { - -/*! Abstraction for RPC client - * - * Purpose of this class is to wrap the underlying RPC implementation. - * This class holds a connection to an RPC server (the connection is severed on - * destruction). - */ -class rpc_block_ctrl -{ -public: - virtual ~rpc_block_ctrl() {} - - /*! Pass in an RPC client for the block to use - * - * \param rpcc Reference to the RPC client - * \param block_args Additional block arguments - */ - virtual void set_rpc_client( - uhd::rpc_client::sptr rpcc, - const uhd::device_addr_t &block_args - ) = 0; - -}; - -}} - -#endif /* INCLUDED_LIBUHD_RFNOC_RPC_BLOCK_CTRL_HPP */ diff --git a/host/lib/rfnoc/rx_stream_terminator.cpp b/host/lib/rfnoc/rx_stream_terminator.cpp index c43602cef..83c0420e2 100644 --- a/host/lib/rfnoc/rx_stream_terminator.cpp +++ b/host/lib/rfnoc/rx_stream_terminator.cpp @@ -5,11 +5,11 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "rx_stream_terminator.hpp" -#include "radio_ctrl_impl.hpp" #include "../transport/super_recv_packet_handler.hpp" #include #include +#include +#include #include using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/rx_stream_terminator.hpp b/host/lib/rfnoc/rx_stream_terminator.hpp deleted file mode 100644 index 3f82ab12f..000000000 --- a/host/lib/rfnoc/rx_stream_terminator.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright 2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP -#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP - -#include -#include -#include -#include -#include -#include // For the block macros -#include - -namespace uhd { - namespace rfnoc { - -/*! \brief Terminator node for Rx streamers. - * - * This node is only used by rx_streamers. It terminates the flow graph - * inside the streamer and does not have a counterpart on the FPGA. - */ -class rx_stream_terminator : - public sink_node_ctrl, - public rate_node_ctrl, - public tick_node_ctrl, - public scalar_node_ctrl, - public terminator_node_ctrl -{ -public: - UHD_RFNOC_BLOCK_OBJECT(rx_stream_terminator) - - static sptr make() - { - return sptr(new rx_stream_terminator); - } - - // If this is called, then by a send terminator at the other end - // of a flow graph. - double get_input_samp_rate(size_t) { return _samp_rate; }; - - // Same for the scaling factor - double get_input_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; }; - - std::string unique_id() const; - - void set_rx_streamer(bool active, const size_t port); - - void set_tx_streamer(bool active, const size_t port); - - virtual ~rx_stream_terminator(); - - void handle_overrun(boost::weak_ptr, const size_t); - -protected: - rx_stream_terminator(); - - virtual double _get_tick_rate() { return _tick_rate; }; - -private: - //! Every terminator has a unique index - const size_t _term_index; - static size_t _count; - - double _samp_rate; - double _tick_rate; - - std::mutex _overrun_handler_mutex; - -}; /* class rx_stream_terminator */ - -}} /* namespace uhd::rfnoc */ - -#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_RECV_HPP */ -// vim: sw=4 et: diff --git a/host/lib/rfnoc/sink_block_ctrl_base.cpp b/host/lib/rfnoc/sink_block_ctrl_base.cpp index d619f1f8a..b620f917f 100644 --- a/host/lib/rfnoc/sink_block_ctrl_base.cpp +++ b/host/lib/rfnoc/sink_block_ctrl_base.cpp @@ -5,10 +5,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "utils.hpp" #include #include #include +#include using namespace uhd; using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/sink_node_ctrl.cpp b/host/lib/rfnoc/sink_node_ctrl.cpp index 56b95f4c1..03e259783 100644 --- a/host/lib/rfnoc/sink_node_ctrl.cpp +++ b/host/lib/rfnoc/sink_node_ctrl.cpp @@ -5,10 +5,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "utils.hpp" #include #include #include +#include using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/source_block_ctrl_base.cpp b/host/lib/rfnoc/source_block_ctrl_base.cpp index b7683840f..d71905a1f 100644 --- a/host/lib/rfnoc/source_block_ctrl_base.cpp +++ b/host/lib/rfnoc/source_block_ctrl_base.cpp @@ -5,10 +5,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "utils.hpp" #include #include #include +#include using namespace uhd; using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/source_node_ctrl.cpp b/host/lib/rfnoc/source_node_ctrl.cpp index 91f114b60..54e65b16c 100644 --- a/host/lib/rfnoc/source_node_ctrl.cpp +++ b/host/lib/rfnoc/source_node_ctrl.cpp @@ -5,10 +5,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "utils.hpp" #include #include #include +#include using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/tx_stream_terminator.cpp b/host/lib/rfnoc/tx_stream_terminator.cpp index 4064d8eb9..14e800a1c 100644 --- a/host/lib/rfnoc/tx_stream_terminator.cpp +++ b/host/lib/rfnoc/tx_stream_terminator.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "tx_stream_terminator.hpp" -#include #include +#include +#include using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/tx_stream_terminator.hpp b/host/lib/rfnoc/tx_stream_terminator.hpp deleted file mode 100644 index 0a07e48ef..000000000 --- a/host/lib/rfnoc/tx_stream_terminator.hpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright 2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP -#define INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP - -#include -#include -#include -#include -#include -#include // For the block macros -#include - -namespace uhd { - namespace rfnoc { - -/*! \brief Terminator node for Tx streamers. - * - * This node is only used by tx_streamers. It terminates the flow graph - * inside the streamer and does not have a counterpart on the FPGA. - */ -class tx_stream_terminator : - public source_node_ctrl, - public rate_node_ctrl, - public tick_node_ctrl, - public scalar_node_ctrl, - public terminator_node_ctrl -{ -public: - UHD_RFNOC_BLOCK_OBJECT(tx_stream_terminator) - - static sptr make() - { - return sptr(new tx_stream_terminator); - } - - void issue_stream_cmd(const uhd::stream_cmd_t &, const size_t) - { - UHD_RFNOC_BLOCK_TRACE() << "tx_stream_terminator::issue_stream_cmd()" ; - } - - // If this is called, then by a send terminator at the other end - // of a flow graph. - double get_output_samp_rate(size_t) { return _samp_rate; }; - - // Same for the scaling factor - double get_output_scale_factor(size_t) { return scalar_node_ctrl::SCALE_UNDEFINED; }; - - std::string unique_id() const; - - void set_rx_streamer(bool active, const size_t port); - - void set_tx_streamer(bool active, const size_t port); - - virtual ~tx_stream_terminator(); - -protected: - tx_stream_terminator(); - - virtual double _get_tick_rate() { return _tick_rate; }; - -private: - //! Every terminator has a unique index - const size_t _term_index; - static size_t _count; - - double _samp_rate; - double _tick_rate; - -}; /* class tx_stream_terminator */ - -}} /* namespace uhd::rfnoc */ - -#endif /* INCLUDED_LIBUHD_RFNOC_TERMINATOR_SEND_HPP */ -// vim: sw=4 et: diff --git a/host/lib/rfnoc/utils.hpp b/host/lib/rfnoc/utils.hpp deleted file mode 100644 index 28c69987f..000000000 --- a/host/lib/rfnoc/utils.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright 2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_RFNOC_UTILS_HPP -#define INCLUDED_LIBUHD_RFNOC_UTILS_HPP - -#include -#include -#include - -namespace uhd { namespace rfnoc { namespace utils { - - /*! If \p suggested_port equals ANY_PORT, return the first available - * port number on \p nodes. Otherwise, return \p suggested_port. - * - * If \p allowed_ports is given, another condition is that the port - * number must be listed in here. - * If \p allowed_ports is not specified or empty, the assumption is - * that all ports are valid. - * - * On failure, ANY_PORT is returned. - */ - static size_t node_map_find_first_free( - node_ctrl_base::node_map_t nodes, - const size_t suggested_port, - const std::set allowed_ports=std::set() - ) { - size_t port = suggested_port; - if (port == ANY_PORT) { - if (allowed_ports.empty()) { - port = 0; - while (nodes.count(port) and (port != ANY_PORT)) { - port++; - } - } else { - for(const size_t allowed_port: allowed_ports) { - if (not nodes.count(port)) { - return allowed_port; - } - return ANY_PORT; - } - } - } else { - if (not (allowed_ports.empty() or allowed_ports.count(port))) { - return ANY_PORT; - } - } - return port; - } - - template - static std::set str_list_to_set(const std::vector &list) { - std::set return_set; - for(const std::string &S: list) { - return_set.insert(boost::lexical_cast(S)); - } - return return_set; - } - -}}}; /* namespace uhd::rfnoc::utils */ - -#endif /* INCLUDED_LIBUHD_RFNOC_UTILS_HPP */ -// vim: sw=4 et: diff --git a/host/lib/rfnoc/wb_iface_adapter.cpp b/host/lib/rfnoc/wb_iface_adapter.cpp index 1749f3635..00e2b466a 100644 --- a/host/lib/rfnoc/wb_iface_adapter.cpp +++ b/host/lib/rfnoc/wb_iface_adapter.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "wb_iface_adapter.hpp" +#include using namespace uhd::rfnoc; diff --git a/host/lib/rfnoc/wb_iface_adapter.hpp b/host/lib/rfnoc/wb_iface_adapter.hpp deleted file mode 100644 index 753fa13af..000000000 --- a/host/lib/rfnoc/wb_iface_adapter.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright 2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP -#define INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP - -#include -#include -#include - -namespace uhd { - namespace rfnoc { - -class UHD_API wb_iface_adapter : public uhd::timed_wb_iface -{ -public: - typedef boost::shared_ptr sptr; - typedef boost::function poke32_type; - typedef boost::function peek32_type; - typedef boost::function peek64_type; - typedef boost::function gettime_type; - typedef boost::function settime_type; - - wb_iface_adapter( - const poke32_type &, - const peek32_type &, - const peek64_type &, - const gettime_type &, - const settime_type & - ); - - wb_iface_adapter( - const poke32_type &, - const peek32_type &, - const peek64_type & - ); - - virtual ~wb_iface_adapter(void) {}; - - virtual void poke32(const wb_addr_type addr, const uint32_t data); - virtual uint32_t peek32(const wb_addr_type addr); - virtual uint64_t peek64(const wb_addr_type addr); - virtual time_spec_t get_time(void); - virtual void set_time(const time_spec_t& t); - -private: - const poke32_type poke32_functor; - const peek32_type peek32_functor; - const peek64_type peek64_functor; - const gettime_type gettime_functor; - const settime_type settime_functor; -}; - -}} // namespace uhd::rfnoc - -#endif /* INCLUDED_RFNOC_WB_IFACE_ADAPTER_HPP */ diff --git a/host/lib/rfnoc/xports.hpp b/host/lib/rfnoc/xports.hpp deleted file mode 100644 index 5ee65175a..000000000 --- a/host/lib/rfnoc/xports.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright 2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#include -#include -#include - -namespace uhd { - - /*! Holds all necessary items for a bidirectional link - */ - struct both_xports_t - { - both_xports_t(): recv_buff_size(0), send_buff_size(0) {} - uhd::transport::zero_copy_if::sptr recv; - uhd::transport::zero_copy_if::sptr send; - size_t recv_buff_size; - size_t send_buff_size; - uhd::sid_t send_sid; - uhd::sid_t recv_sid; - uhd::endianness_t endianness; - }; - -}; - diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index f202eab54..b66972f4f 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -8,7 +8,6 @@ #ifndef INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP #define INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP -#include "../rfnoc/rx_stream_terminator.hpp" #include #include #include @@ -19,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index 0306d2171..9c18e2080 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -8,7 +8,6 @@ #ifndef INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP #define INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP -#include "../rfnoc/tx_stream_terminator.hpp" #include #include #include @@ -20,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/host/lib/usrp/b100/b100_impl.cpp b/host/lib/usrp/b100/b100_impl.cpp index 8f9f5c15f..6f649b0eb 100644 --- a/host/lib/usrp/b100/b100_impl.cpp +++ b/host/lib/usrp/b100/b100_impl.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "apply_corrections.hpp" #include "b100_impl.hpp" #include "b100_regs.hpp" #include @@ -15,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/host/lib/usrp/b100/b100_impl.hpp b/host/lib/usrp/b100/b100_impl.hpp index dc4b43040..c6947deb7 100644 --- a/host/lib/usrp/b100/b100_impl.hpp +++ b/host/lib/usrp/b100/b100_impl.hpp @@ -8,18 +8,8 @@ #ifndef INCLUDED_B100_IMPL_HPP #define INCLUDED_B100_IMPL_HPP -#include "fx2_ctrl.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" -#include "i2c_core_200.hpp" -#include "rx_frontend_core_200.hpp" -#include "tx_frontend_core_200.hpp" -#include "rx_dsp_core_200.hpp" -#include "tx_dsp_core_200.hpp" -#include "time64_core_200.hpp" -#include "fifo_ctrl_excelsior.hpp" -#include "user_settings_core_200.hpp" -#include "recv_packet_demuxer_3000.hpp" #include #include #include @@ -31,6 +21,16 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include static const double B100_LINK_RATE_BPS = 256e6/5; //pratical link rate (< 480 Mbps) diff --git a/host/lib/usrp/b100/dboard_iface.cpp b/host/lib/usrp/b100/dboard_iface.cpp index 0820d1427..2ea467fe4 100644 --- a/host/lib/usrp/b100/dboard_iface.cpp +++ b/host/lib/usrp/b100/dboard_iface.cpp @@ -5,17 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "gpio_core_200.hpp" -#include #include "b100_regs.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include #include #include #include +#include #include - using namespace uhd; using namespace uhd::usrp; using namespace boost::assign; diff --git a/host/lib/usrp/b100/io_impl.cpp b/host/lib/usrp/b100/io_impl.cpp index f6c5c3fb0..ed90b11ba 100644 --- a/host/lib/usrp/b100/io_impl.cpp +++ b/host/lib/usrp/b100/io_impl.cpp @@ -5,16 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "validate_subdev_spec.hpp" +#include "b100_impl.hpp" +#include +#include #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" -#include "b100_impl.hpp" + #include #include #include #include - -#include #include using namespace uhd; diff --git a/host/lib/usrp/b100/mb_eeprom.cpp b/host/lib/usrp/b100/mb_eeprom.cpp index e353ceec4..3e46d7d1f 100644 --- a/host/lib/usrp/b100/mb_eeprom.cpp +++ b/host/lib/usrp/b100/mb_eeprom.cpp @@ -5,7 +5,7 @@ // #include "b100_impl.hpp" -#include "eeprom_utils.hpp" +#include #include namespace { diff --git a/host/lib/usrp/b200/b200_cores.hpp b/host/lib/usrp/b200/b200_cores.hpp index 2227ca3ea..4d327f8f6 100644 --- a/host/lib/usrp/b200/b200_cores.hpp +++ b/host/lib/usrp/b200/b200_cores.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_B200_CORES_HPP #define INCLUDED_B200_CORES_HPP -#include "spi_core_3000.hpp" -#include "adf4001_ctrl.hpp" +#include +#include #include class b200_local_spi_core : boost::noncopyable, public uhd::spi_iface { diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp index 2b20adf1a..836a92ff7 100644 --- a/host/lib/usrp/b200/b200_iface.cpp +++ b/host/lib/usrp/b200/b200_iface.cpp @@ -7,22 +7,22 @@ #include "b200_iface.hpp" -#include "../../utils/ihex.hpp" #include - #include #include +#include + #include #include -#include #include #include +#include #include #include #include #include #include -#include +#include //! libusb_error_name is only in newer API #ifndef HAVE_LIBUSB_ERROR_NAME diff --git a/host/lib/usrp/b200/b200_iface.hpp b/host/lib/usrp/b200/b200_iface.hpp index e5f11840c..86307bc21 100644 --- a/host/lib/usrp/b200/b200_iface.hpp +++ b/host/lib/usrp/b200/b200_iface.hpp @@ -8,14 +8,14 @@ #ifndef INCLUDED_B200_IFACE_HPP #define INCLUDED_B200_IFACE_HPP -#include #include #include //i2c iface #include +#include #include #include #include -#include "ad9361_ctrl.hpp" +#include enum b200_product_t { B200, diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp index 9abe031b1..13d282959 100644 --- a/host/lib/usrp/b200/b200_impl.hpp +++ b/host/lib/usrp/b200/b200_impl.hpp @@ -11,16 +11,6 @@ #include "b200_iface.hpp" #include "b200_uart.hpp" #include "b200_cores.hpp" -#include "ad9361_ctrl.hpp" -#include "ad936x_manager.hpp" -#include "adf4001_ctrl.hpp" -#include "rx_vita_core_3000.hpp" -#include "tx_vita_core_3000.hpp" -#include "time_core_3000.hpp" -#include "gpio_atr_3000.hpp" -#include "radio_ctrl_core_3000.hpp" -#include "rx_dsp_core_3000.hpp" -#include "tx_dsp_core_3000.hpp" #include #include #include @@ -34,9 +24,20 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include "recv_packet_demuxer_3000.hpp" + static const uint8_t B200_FW_COMPAT_NUM_MAJOR = 8; static const uint8_t B200_FW_COMPAT_NUM_MINOR = 0; static const uint16_t B200_FPGA_COMPAT_NUM = 14; diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp index c589aacb0..b40ea5d82 100644 --- a/host/lib/usrp/b200/b200_io_impl.cpp +++ b/host/lib/usrp/b200/b200_io_impl.cpp @@ -7,10 +7,10 @@ #include "b200_regs.hpp" #include "b200_impl.hpp" -#include "validate_subdev_spec.hpp" +#include +#include #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" -#include "async_packet_handler.hpp" #include #include #include diff --git a/host/lib/usrp/b200/b200_mb_eeprom.cpp b/host/lib/usrp/b200/b200_mb_eeprom.cpp index a7f51f6d9..2be014fd5 100644 --- a/host/lib/usrp/b200/b200_mb_eeprom.cpp +++ b/host/lib/usrp/b200/b200_mb_eeprom.cpp @@ -5,7 +5,7 @@ // #include "b200_impl.hpp" -#include "eeprom_utils.hpp" +#include #include namespace { diff --git a/host/lib/usrp/common/CMakeLists.txt b/host/lib/usrp/common/CMakeLists.txt index dca3663bb..9e27fb880 100644 --- a/host/lib/usrp/common/CMakeLists.txt +++ b/host/lib/usrp/common/CMakeLists.txt @@ -33,5 +33,4 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/validate_subdev_spec.cpp ${CMAKE_CURRENT_SOURCE_DIR}/recv_packet_demuxer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fifo_ctrl_excelsior.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/lmk04828.cpp ) diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp index a6f219185..ea3fdc416 100644 --- a/host/lib/usrp/common/ad9361_ctrl.cpp +++ b/host/lib/usrp/common/ad9361_ctrl.cpp @@ -5,16 +5,16 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "ad9361_ctrl.hpp" #include #include #include -#include +#include #include #include #include #include #include +#include using namespace uhd; using namespace uhd::usrp; diff --git a/host/lib/usrp/common/ad9361_ctrl.hpp b/host/lib/usrp/common/ad9361_ctrl.hpp deleted file mode 100644 index b9e81074b..000000000 --- a/host/lib/usrp/common/ad9361_ctrl.hpp +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright 2012-2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_AD9361_CTRL_HPP -#define INCLUDED_AD9361_CTRL_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace uhd { namespace usrp { - -/*! AD936x Control Interface - * - * This is a convenient way to access the AD936x RF IC. - * It basically encodes knowledge of register values etc. into - * accessible API calls. - * - * \section ad936x_which The `which` parameter - * - * Many function calls require a `which` parameter to select - * the RF frontend. Valid values for `which` are: - * - RX1, RX2 - * - TX1, TX2 - * - * Frontend numbering is as designed by the AD9361. - */ -class ad9361_ctrl : public boost::noncopyable -{ -public: - typedef boost::shared_ptr sptr; - - virtual ~ad9361_ctrl(void) {}; - - //! make a new codec control object - static sptr make_spi( - ad9361_params::sptr client_settings, - uhd::spi_iface::sptr spi_iface, - uint32_t slave_num - ); - - virtual void set_timed_spi(uhd::spi_iface::sptr spi_iface, uint32_t slave_num) = 0; - virtual void set_safe_spi(uhd::spi_iface::sptr spi_iface, uint32_t slave_num) = 0; - - //! Get a list of gain names for RX or TX - static std::vector get_gain_names(const std::string &/*which*/) - { - return std::vector(1, "PGA"); - } - - //! get the gain range for a particular gain element - static uhd::meta_range_t get_gain_range(const std::string &which) - { - if(which[0] == 'R') { - return uhd::meta_range_t(0.0, 76.0, 1.0); - } else { - return uhd::meta_range_t(0.0, 89.75, 0.25); - } - } - - //! get the freq range for the frontend which - static uhd::meta_range_t get_rf_freq_range(void) - { - return uhd::meta_range_t(50e6, 6e9); - } - - //! get the filter range for the frontend which - static uhd::meta_range_t get_bw_filter_range(const std::string &/*which*/) - { - return uhd::meta_range_t(200e3, 56e6); - } - - //! get the clock rate range for the frontend - static uhd::meta_range_t get_clock_rate_range(void) - { - return uhd::meta_range_t( - ad9361_device_t::AD9361_MIN_CLOCK_RATE, - ad9361_device_t::AD9361_MAX_CLOCK_RATE - ); - } - - //! set the filter bandwidth for the frontend's analog low pass - virtual double set_bw_filter(const std::string &/*which*/, const double /*bw*/) = 0; - - //! set the gain for a particular gain element - virtual double set_gain(const std::string &which, const double value) = 0; - - //! Enable or disable the AGC module - virtual void set_agc(const std::string &which, bool enable) = 0; - - //! configure the AGC module to slow or fast mode - virtual void set_agc_mode(const std::string &which, const std::string &mode) = 0; - - //! set a new clock rate, return the exact value - virtual double set_clock_rate(const double rate) = 0; - - //! set which RX and TX chains/antennas are active - virtual void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) = 0; - - //! tune the given frontend, return the exact value - virtual double tune(const std::string &which, const double value) = 0; - - //! set the DC offset for I and Q manually - void set_dc_offset(const std::string &, const std::complex) - { - //This feature should not be used according to Analog Devices - throw uhd::runtime_error("ad9361_ctrl::set_dc_offset this feature is not supported on this device."); - } - - //! enable or disable the BB/RF DC tracking feature - virtual void set_dc_offset_auto(const std::string &which, const bool on) = 0; - - //! set the IQ correction value manually - void set_iq_balance(const std::string &, const std::complex) - { - //This feature should not be used according to Analog Devices - throw uhd::runtime_error("ad9361_ctrl::set_iq_balance this feature is not supported on this device."); - } - - //! enable or disable the quadrature calibration - virtual void set_iq_balance_auto(const std::string &which, const bool on) = 0; - - //! get the current frequency for the given frontend - virtual double get_freq(const std::string &which) = 0; - - //! turn on/off Catalina's data port loopback - virtual void data_port_loopback(const bool on) = 0; - - //! read internal RSSI sensor - virtual sensor_value_t get_rssi(const std::string &which) = 0; - - //! read the internal temp sensor - virtual sensor_value_t get_temperature() = 0; - - //! List all available filters by name - virtual std::vector get_filter_names(const std::string &which) = 0; - - //! Return a list of all filters - virtual filter_info_base::sptr get_filter(const std::string &which, const std::string &filter_name) = 0; - - //! Write back a filter - virtual void set_filter(const std::string &which, const std::string &filter_name, const filter_info_base::sptr) = 0; - - virtual void output_digital_test_tone(bool enb) = 0; -}; - -}} - -#endif /* INCLUDED_AD9361_CTRL_HPP */ diff --git a/host/lib/usrp/common/ad936x_manager.cpp b/host/lib/usrp/common/ad936x_manager.cpp index 34e51ec0e..9d07350ea 100644 --- a/host/lib/usrp/common/ad936x_manager.cpp +++ b/host/lib/usrp/common/ad936x_manager.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "ad936x_manager.hpp" +#include #include #include #include diff --git a/host/lib/usrp/common/ad936x_manager.hpp b/host/lib/usrp/common/ad936x_manager.hpp deleted file mode 100644 index dd5c38337..000000000 --- a/host/lib/usrp/common/ad936x_manager.hpp +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright 2015 Ettus Research -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_AD9361_MANAGER_HPP -#define INCLUDED_AD9361_MANAGER_HPP - -#include -#include -#include -#include -#include -#include -#include "ad9361_ctrl.hpp" -#include - -namespace uhd { namespace usrp { - -/*! AD936x Manager class - * - * This class performs higher (management) tasks on the AD936x. - * It requires a uhd::usrp::ad9361_ctrl object to do the actual - * register peeks/pokes etc. - */ -class ad936x_manager -{ -public: - typedef boost::shared_ptr sptr; - - static const double DEFAULT_GAIN; - static const double DEFAULT_BANDWIDTH; - static const double DEFAULT_TICK_RATE; - static const double DEFAULT_FREQ; // Hz - static const uint32_t DEFAULT_DECIM; - static const uint32_t DEFAULT_INTERP; - static const bool DEFAULT_AUTO_DC_OFFSET; - static const bool DEFAULT_AUTO_IQ_BALANCE; - static const bool DEFAULT_AGC_ENABLE; - - /*! - * \param codec_ctrl The actual AD936x control object - * \param n_frontends Number of frontends (1 or 2) - */ - static sptr make( - const ad9361_ctrl::sptr &codec_ctrl, - const size_t n_frontends - ); - - virtual ~ad936x_manager(void) {}; - - /*! Put the AD936x into a default state. - * - * Sets gains, LOs, bandwidths, etc. according to the DEFAULT_* constants. - */ - virtual void init_codec(void) = 0; - - /*! Run a loopback self test. - * - * This will write data to the AD936x and read it back again. - * If this test fails, it generally means the interface is broken, - * so we assume it passes and throw otherwise. Running this requires - * a core that we can peek and poke the loopback values into. - * - * \param iface An interface to the associated radio control core - * \param iface The radio control core's address to write the loopback value - * \param iface The radio control core's readback address to read back the returned value - * - * \throws a uhd::runtime_error if the loopback value didn't match. - */ - virtual void loopback_self_test( - boost::function poker_functor, - boost::function peeker_functor - ) = 0; - - /*! Determine a tick rate that will work with a given sampling rate - * (assuming a DDC/DUC chain is also available elsewhere). - * - * Example: If we want to stream with a rate of 5 Msps, then the AD936x - * must run at an integer multiple of that. Although not strictly necessary, - * we always try and return a multiple of 2. Let's say we need those 5 Msps - * on two channels, then a good rate is 20 MHz, which is 4 times the sampling - * rate (thus we can use 2 halfbands elsewhere). - * If different rates are used on different channels, this can be particularly - * useful. The clock rate of the AD936x needs to be a multiple of the least - * common multiple of all the rates. Example: We want to transmit with 3 Msps - * and receive with 5 Msps. The LCM of this is 15 Msps, which is used as an - * argument for this function. A good rate is then 30 MHz, which is twice - * the LCM. - * - * \param lcm_rate Least Common Multiple of all the rates involved. - * \param num_chans The number of channels used for the stream. - * - * \returns a valid tick rate that can be used with the given rate - * \throws a uhd::value_error if \p lcm_rate exceeds the max tick rate - */ - virtual double get_auto_tick_rate( - const double lcm_rate, - size_t num_chans - ) = 0; - - /*! Check if a given sampling rate is within the available analog bandwidth. - * - * If not, outputs a warning message and returns false. - */ - virtual bool check_bandwidth(double rate, const std::string dir) = 0; - - /*! Populate the property tree for the device frontend - */ - virtual void populate_frontend_subtree( - uhd::property_tree::sptr subtree, - const std::string &key, - uhd::direction_t dir - ) = 0; - -}; /* class ad936x_manager */ - -}} /* namespace uhd::usrp */ - -#endif /* INCLUDED_AD9361_MANAGER_HPP */ diff --git a/host/lib/usrp/common/adf4001_ctrl.cpp b/host/lib/usrp/common/adf4001_ctrl.cpp index 5fb9fd223..138ca7f81 100644 --- a/host/lib/usrp/common/adf4001_ctrl.cpp +++ b/host/lib/usrp/common/adf4001_ctrl.cpp @@ -10,9 +10,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "adf4001_ctrl.hpp" - +#include #include + #include #include diff --git a/host/lib/usrp/common/adf4001_ctrl.hpp b/host/lib/usrp/common/adf4001_ctrl.hpp deleted file mode 100644 index c7f6668b8..000000000 --- a/host/lib/usrp/common/adf4001_ctrl.hpp +++ /dev/null @@ -1,131 +0,0 @@ -// -// Copyright 2013 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// Original ADF4001 driver written by: bistromath -// Mar 1, 2013 -// -// Re-used and re-licensed with permission. -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_COMMON_ADF4001_HPP -#define INCLUDED_LIBUHD_USRP_COMMON_ADF4001_HPP - -#include "spi_core_3000.hpp" -#include -#include -#include - -namespace uhd { namespace usrp { - -class adf4001_regs_t { -public: - - /* Function prototypes */ - uint32_t get_reg(uint8_t addr); - adf4001_regs_t(void); - - /* Register values / addresses */ - uint16_t ref_counter; //14 bits - uint16_t n; //13 bits - uint8_t charge_pump_current_1; //3 bits - uint8_t charge_pump_current_2; //3 bits - - enum anti_backlash_width_t { - ANTI_BACKLASH_WIDTH_2_9NS = 0, - ANTI_BACKLASH_WIDTH_1_3NS = 1, - ANTI_BACKLASH_WIDTH_6_0NS = 2, - ANTI_BACKLASH_WIDTH_2_9NS_WAT = 3 - }; - anti_backlash_width_t anti_backlash_width; - - enum lock_detect_precision_t { - LOCK_DETECT_PRECISION_3CYC = 0, - LOCK_DETECT_PRECISION_5CYC = 1 - }; - lock_detect_precision_t lock_detect_precision; - enum charge_pump_gain_t { - CHARGE_PUMP_GAIN_1 = 0, - CHARGE_PUMP_GAIN_2 = 1 - }; - charge_pump_gain_t charge_pump_gain; - enum counter_reset_t { - COUNTER_RESET_NORMAL = 0, - COUNTER_RESET_RESET = 1 - }; - counter_reset_t counter_reset; - enum power_down_t { - POWER_DOWN_NORMAL = 0, - POWER_DOWN_ASYNC = 1, - POWER_DOWN_SYNC = 3 - }; - power_down_t power_down; - enum muxout_t { - MUXOUT_TRISTATE_OUT = 0, - MUXOUT_DLD = 1, - MUXOUT_NDIV = 2, - MUXOUT_AVDD = 3, - MUXOUT_RDIV = 4, - MUXOUT_NCH_OD_ALD = 5, - MUXOUT_SDO = 6, - MUXOUT_GND = 7 - }; - muxout_t muxout; - enum phase_detector_polarity_t { - PHASE_DETECTOR_POLARITY_NEGATIVE = 0, - PHASE_DETECTOR_POLARITY_POSITIVE = 1 - }; - phase_detector_polarity_t phase_detector_polarity; - enum charge_pump_mode_t { - CHARGE_PUMP_NORMAL = 0, - CHARGE_PUMP_TRISTATE = 1 - }; - charge_pump_mode_t charge_pump_mode; - enum fastlock_mode_t { - FASTLOCK_MODE_DISABLED = 0, - FASTLOCK_MODE_1 = 1, - FASTLOCK_MODE_2 = 2 - }; - fastlock_mode_t fastlock_mode; - enum timer_counter_control_t { - TIMEOUT_3CYC = 0, - TIMEOUT_7CYC = 1, - TIMEOUT_11CYC = 2, - TIMEOUT_15CYC = 3, - TIMEOUT_19CYC = 4, - TIMEOUT_23CYC = 5, - TIMEOUT_27CYC = 6, - TIMEOUT_31CYC = 7, - TIMEOUT_35CYC = 8, - TIMEOUT_39CYC = 9, - TIMEOUT_43CYC = 10, - TIMEOUT_47CYC = 11, - TIMEOUT_51CYC = 12, - TIMEOUT_55CYC = 13, - TIMEOUT_59CYC = 14, - TIMEOUT_63CYC = 15, - }; - timer_counter_control_t timer_counter_control; -}; - - -class adf4001_ctrl { -public: - adf4001_ctrl(uhd::spi_iface::sptr _spi, int slaveno); - virtual void set_lock_to_ext_ref(bool external); - -private: - uhd::spi_iface::sptr spi_iface; - int slaveno; - spi_config_t spi_config; - adf4001_regs_t adf4001_regs; - - void program_regs(void); - void write_reg(uint8_t addr); -}; - -}} - -#endif diff --git a/host/lib/usrp/common/adf435x.cpp b/host/lib/usrp/common/adf435x.cpp index d1d533ad2..6d59befaa 100644 --- a/host/lib/usrp/common/adf435x.cpp +++ b/host/lib/usrp/common/adf435x.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "adf435x.hpp" +#include using namespace uhd; diff --git a/host/lib/usrp/common/adf435x.hpp b/host/lib/usrp/common/adf435x.hpp deleted file mode 100644 index bd7b91b95..000000000 --- a/host/lib/usrp/common/adf435x.hpp +++ /dev/null @@ -1,422 +0,0 @@ -// -// Copyright 2015 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_ADF435X_HPP -#define INCLUDED_ADF435X_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include "adf4350_regs.hpp" -#include "adf4351_regs.hpp" - -class adf435x_iface -{ -public: - typedef boost::shared_ptr sptr; - typedef boost::function)> write_fn_t; - - static sptr make_adf4350(write_fn_t write); - static sptr make_adf4351(write_fn_t write); - - virtual ~adf435x_iface() = 0; - - enum output_t { RF_OUTPUT_A, RF_OUTPUT_B }; - - enum prescaler_t { PRESCALER_4_5, PRESCALER_8_9 }; - - enum feedback_sel_t { FB_SEL_FUNDAMENTAL, FB_SEL_DIVIDED }; - - enum output_power_t { OUTPUT_POWER_M4DBM, OUTPUT_POWER_M1DBM, OUTPUT_POWER_2DBM, OUTPUT_POWER_5DBM }; - - enum muxout_t { MUXOUT_3STATE, MUXOUT_DVDD, MUXOUT_DGND, MUXOUT_RDIV, MUXOUT_NDIV, MUXOUT_ALD, MUXOUT_DLD }; - - /** - * Charge Pump Currents - */ - enum charge_pump_current_t { - CHARGE_PUMP_CURRENT_0_31MA = 0, - CHARGE_PUMP_CURRENT_0_63MA = 1, - CHARGE_PUMP_CURRENT_0_94MA = 2, - CHARGE_PUMP_CURRENT_1_25MA = 3, - CHARGE_PUMP_CURRENT_1_56MA = 4, - CHARGE_PUMP_CURRENT_1_88MA = 5, - CHARGE_PUMP_CURRENT_2_19MA = 6, - CHARGE_PUMP_CURRENT_2_50MA = 7, - CHARGE_PUMP_CURRENT_2_81MA = 8, - CHARGE_PUMP_CURRENT_3_13MA = 9, - CHARGE_PUMP_CURRENT_3_44MA = 10, - CHARGE_PUMP_CURRENT_3_75MA = 11, - CHARGE_PUMP_CURRENT_4_07MA = 12, - CHARGE_PUMP_CURRENT_4_38MA = 13, - CHARGE_PUMP_CURRENT_4_69MA = 14, - CHARGE_PUMP_CURRENT_5_00MA = 15 - }; - - - virtual void set_reference_freq(double fref) = 0; - - virtual void set_prescaler(prescaler_t prescaler) = 0; - - virtual void set_feedback_select(feedback_sel_t fb_sel) = 0; - - virtual void set_output_power(output_t output, output_power_t power) = 0; - - void set_output_power(output_power_t power) { - set_output_power(RF_OUTPUT_A, power); - } - - virtual void set_output_enable(output_t output, bool enable) = 0; - - virtual void set_muxout_mode(muxout_t mode) = 0; - - virtual void set_charge_pump_current(charge_pump_current_t cp_current) = 0; - - virtual uhd::range_t get_int_range() = 0; - - virtual double set_frequency(double target_freq, bool int_n_mode, bool flush = false) = 0; - - virtual void commit(void) = 0; -}; - -template -class adf435x_impl : public adf435x_iface -{ -public: - adf435x_impl(write_fn_t write_fn) : - _write_fn(write_fn), - _regs(), - _fb_after_divider(false), - _reference_freq(0.0), - _N_min(-1) - {} - - virtual ~adf435x_impl() {}; - - void set_reference_freq(double fref) - { - _reference_freq = fref; - } - - void set_feedback_select(feedback_sel_t fb_sel) - { - _fb_after_divider = (fb_sel == FB_SEL_DIVIDED); - } - - void set_prescaler(prescaler_t prescaler) - { - if (prescaler == PRESCALER_8_9) { - _regs.prescaler = adf435x_regs_t::PRESCALER_8_9; - _N_min = 75; - } else { - _regs.prescaler = adf435x_regs_t::PRESCALER_4_5; - _N_min = 23; - } - } - - void set_output_power(output_t output, output_power_t power) - { - switch (output) { - case RF_OUTPUT_A: - switch (power) { - case OUTPUT_POWER_M4DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M4DBM; break; - case OUTPUT_POWER_M1DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_M1DBM; break; - case OUTPUT_POWER_2DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_2DBM; break; - case OUTPUT_POWER_5DBM: _regs.output_power = adf435x_regs_t::OUTPUT_POWER_5DBM; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - break; - case RF_OUTPUT_B: - switch (power) { - case OUTPUT_POWER_M4DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M4DBM; break; - case OUTPUT_POWER_M1DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_M1DBM; break; - case OUTPUT_POWER_2DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_2DBM; break; - case OUTPUT_POWER_5DBM: _regs.aux_output_power = adf435x_regs_t::AUX_OUTPUT_POWER_5DBM; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - break; - default: - UHD_THROW_INVALID_CODE_PATH(); - } - } - - void set_output_enable(output_t output, bool enable) - { - switch (output) { - case RF_OUTPUT_A: _regs.rf_output_enable = enable ? adf435x_regs_t::RF_OUTPUT_ENABLE_ENABLED: - adf435x_regs_t::RF_OUTPUT_ENABLE_DISABLED; - break; - case RF_OUTPUT_B: _regs.aux_output_enable = enable ? adf435x_regs_t::AUX_OUTPUT_ENABLE_ENABLED: - adf435x_regs_t::AUX_OUTPUT_ENABLE_DISABLED; - break; - } - } - - void set_muxout_mode(muxout_t mode) - { - switch (mode) { - case MUXOUT_3STATE: _regs.muxout = adf435x_regs_t::MUXOUT_3STATE; break; - case MUXOUT_DVDD: _regs.muxout = adf435x_regs_t::MUXOUT_DVDD; break; - case MUXOUT_DGND: _regs.muxout = adf435x_regs_t::MUXOUT_DGND; break; - case MUXOUT_RDIV: _regs.muxout = adf435x_regs_t::MUXOUT_RDIV; break; - case MUXOUT_NDIV: _regs.muxout = adf435x_regs_t::MUXOUT_NDIV; break; - case MUXOUT_ALD: _regs.muxout = adf435x_regs_t::MUXOUT_ANALOG_LD; break; - case MUXOUT_DLD: _regs.muxout = adf435x_regs_t::MUXOUT_DLD; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - } - - void set_charge_pump_current(charge_pump_current_t cp_current) - { - switch (cp_current) { - case CHARGE_PUMP_CURRENT_0_31MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_31MA; break; - case CHARGE_PUMP_CURRENT_0_63MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_63MA; break; - case CHARGE_PUMP_CURRENT_0_94MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_0_94MA; break; - case CHARGE_PUMP_CURRENT_1_25MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_25MA; break; - case CHARGE_PUMP_CURRENT_1_56MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_56MA; break; - case CHARGE_PUMP_CURRENT_1_88MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_1_88MA; break; - case CHARGE_PUMP_CURRENT_2_19MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_19MA; break; - case CHARGE_PUMP_CURRENT_2_50MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_50MA; break; - case CHARGE_PUMP_CURRENT_2_81MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_2_81MA; break; - case CHARGE_PUMP_CURRENT_3_13MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_13MA; break; - case CHARGE_PUMP_CURRENT_3_44MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_44MA; break; - case CHARGE_PUMP_CURRENT_3_75MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_3_75MA; break; - case CHARGE_PUMP_CURRENT_4_07MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_07MA; break; - case CHARGE_PUMP_CURRENT_4_38MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_38MA; break; - case CHARGE_PUMP_CURRENT_4_69MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_4_69MA; break; - case CHARGE_PUMP_CURRENT_5_00MA : _regs.charge_pump_current = adf435x_regs_t::CHARGE_PUMP_CURRENT_5_00MA; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - } - - uhd::range_t get_int_range() - { - if (_N_min < 0) throw uhd::runtime_error("set_prescaler must be called before get_int_range"); - return uhd::range_t(_N_min, 4095); - } - - double set_frequency(double target_freq, bool int_n_mode, bool flush = false) - { - static const double REF_DOUBLER_THRESH_FREQ = 12.5e6; - static const double PFD_FREQ_MAX = 25.0e6; - static const double BAND_SEL_FREQ_MAX = 100e3; - static const double VCO_FREQ_MIN = 2.2e9; - static const double VCO_FREQ_MAX = 4.4e9; - - //Default invalid value for actual_freq - double actual_freq = 0; - - uhd::range_t rf_divider_range = _get_rfdiv_range(); - uhd::range_t int_range = get_int_range(); - - double pfd_freq = 0; - uint16_t R = 0, BS = 0, N = 0, FRAC = 0, MOD = 0; - uint16_t RFdiv = static_cast(rf_divider_range.start()); - bool D = false, T = false; - - //Reference doubler for 50% duty cycle - D = (_reference_freq <= REF_DOUBLER_THRESH_FREQ); - - //increase RF divider until acceptable VCO frequency - double vco_freq = target_freq; - while (vco_freq < VCO_FREQ_MIN && RFdiv < static_cast(rf_divider_range.stop())) { - vco_freq *= 2; - RFdiv *= 2; - } - - /* - * The goal here is to loop though possible R dividers, - * band select clock dividers, N (int) dividers, and FRAC - * (frac) dividers. - * - * Calculate the N and F dividers for each set of values. - * The loop exits when it meets all of the constraints. - * The resulting loop values are loaded into the registers. - * - * from pg.21 - * - * f_pfd = f_ref*(1+D)/(R*(1+T)) - * f_vco = (N + (FRAC/MOD))*f_pfd - * N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD - * f_actual = f_vco/RFdiv) - */ - double feedback_freq = _fb_after_divider ? target_freq : vco_freq; - - for(R = 1; R <= 1023; R+=1){ - //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T) - pfd_freq = _reference_freq*(D?2:1)/(R*(T?2:1)); - - //keep the PFD frequency at or below 25MHz (Loop Filter Bandwidth) - if (pfd_freq > PFD_FREQ_MAX) continue; - - //First, ignore fractional part of tuning - N = uint16_t(std::floor(feedback_freq/pfd_freq)); - - //keep N > minimum int divider requirement - if (N < static_cast(int_range.start())) continue; - - for(BS=1; BS <= 255; BS+=1){ - //keep the band select frequency at or below band_sel_freq_max - //constraint on band select clock - if (pfd_freq/BS > BAND_SEL_FREQ_MAX) continue; - goto done_loop; - } - } done_loop: - - //Fractional-N calculation - MOD = 4095; //max fractional accuracy - FRAC = static_cast(boost::math::round((feedback_freq/pfd_freq - N)*MOD)); - if (int_n_mode) { - if (FRAC > (MOD / 2)) { //Round integer such that actual freq is closest to target - N++; - } - FRAC = 0; - } - - //Reference divide-by-2 for 50% duty cycle - // if R even, move one divide by 2 to to regs.reference_divide_by_2 - if(R % 2 == 0) { - T = true; - R /= 2; - } - - //Typical phase resync time documented in data sheet pg.24 - static const double PHASE_RESYNC_TIME = 400e-6; - - //If feedback after divider, then compensation for the divider is pulled into the INT value - int rf_div_compensation = _fb_after_divider ? 1 : RFdiv; - - //Compute the actual frequency in terms of _reference_freq, N, FRAC, MOD, D, R and T. - actual_freq = ( - double((N + (double(FRAC)/double(MOD))) * - (_reference_freq*(D?2:1)/(R*(T?2:1)))) - ) / rf_div_compensation; - - _regs.frac_12_bit = FRAC; - _regs.int_16_bit = N; - _regs.mod_12_bit = MOD; - _regs.clock_divider_12_bit = std::max(1, uint16_t(std::ceil(PHASE_RESYNC_TIME*pfd_freq/MOD))); - _regs.feedback_select = _fb_after_divider ? - adf435x_regs_t::FEEDBACK_SELECT_DIVIDED : - adf435x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; - _regs.clock_div_mode = _fb_after_divider ? - adf435x_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE : - adf435x_regs_t::CLOCK_DIV_MODE_FAST_LOCK; - _regs.r_counter_10_bit = R; - _regs.reference_divide_by_2 = T ? - adf435x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : - adf435x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; - _regs.reference_doubler = D ? - adf435x_regs_t::REFERENCE_DOUBLER_ENABLED : - adf435x_regs_t::REFERENCE_DOUBLER_DISABLED; - _regs.band_select_clock_div = uint8_t(BS); - _regs.rf_divider_select = static_cast(_get_rfdiv_setting(RFdiv)); - _regs.ldf = int_n_mode ? - adf435x_regs_t::LDF_INT_N : - adf435x_regs_t::LDF_FRAC_N; - - std::string tuning_str = (int_n_mode) ? "Integer-N" : "Fractional"; - UHD_LOGGER_TRACE("ADF435X") - << boost::format("ADF 435X Frequencies (MHz): REQUESTED=%0.9f, ACTUAL=%0.9f") - % (target_freq/1e6) % (actual_freq/1e6) - << boost::format("ADF 435X Intermediates (MHz): Feedback=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f, REF=%0.2f") - % (feedback_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) % (_reference_freq/1e6) - << boost::format("ADF 435X Tuning: %s") % tuning_str.c_str() - << boost::format("ADF 435X Settings: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d") - % R % BS % N % FRAC % MOD % T % D % RFdiv - ; - - UHD_ASSERT_THROW((_regs.frac_12_bit & ((uint16_t)~0xFFF)) == 0); - UHD_ASSERT_THROW((_regs.mod_12_bit & ((uint16_t)~0xFFF)) == 0); - UHD_ASSERT_THROW((_regs.clock_divider_12_bit & ((uint16_t)~0xFFF)) == 0); - UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0); - - UHD_ASSERT_THROW(vco_freq >= VCO_FREQ_MIN and vco_freq <= VCO_FREQ_MAX); - UHD_ASSERT_THROW(RFdiv >= static_cast(rf_divider_range.start())); - UHD_ASSERT_THROW(RFdiv <= static_cast(rf_divider_range.stop())); - UHD_ASSERT_THROW(_regs.int_16_bit >= static_cast(int_range.start())); - UHD_ASSERT_THROW(_regs.int_16_bit <= static_cast(int_range.stop())); - - if (flush) commit(); - return actual_freq; - } - - void commit() - { - //reset counters - _regs.counter_reset = adf435x_regs_t::COUNTER_RESET_ENABLED; - std::vector regs; - regs.push_back(_regs.get_reg(uint32_t(2))); - _write_fn(regs); - _regs.counter_reset = adf435x_regs_t::COUNTER_RESET_DISABLED; - - //write the registers - //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0) - regs.clear(); - for (int addr = 5; addr >= 0; addr--) { - regs.push_back(_regs.get_reg(uint32_t(addr))); - } - _write_fn(regs); - } - -protected: - uhd::range_t _get_rfdiv_range(); - int _get_rfdiv_setting(uint16_t div); - - write_fn_t _write_fn; - adf435x_regs_t _regs; - double _fb_after_divider; - double _reference_freq; - int _N_min; -}; - -template <> -inline uhd::range_t adf435x_impl::_get_rfdiv_range() -{ - return uhd::range_t(1, 16); -} - -template <> -inline uhd::range_t adf435x_impl::_get_rfdiv_range() -{ - return uhd::range_t(1, 64); -} - -template <> -inline int adf435x_impl::_get_rfdiv_setting(uint16_t div) -{ - switch (div) { - case 1: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV1); - case 2: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV2); - case 4: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV4); - case 8: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV8); - case 16: return int(adf4350_regs_t::RF_DIVIDER_SELECT_DIV16); - default: UHD_THROW_INVALID_CODE_PATH(); - } -} - -template <> -inline int adf435x_impl::_get_rfdiv_setting(uint16_t div) -{ - switch (div) { - case 1: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV1); - case 2: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV2); - case 4: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV4); - case 8: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV8); - case 16: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV16); - case 32: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV32); - case 64: return int(adf4351_regs_t::RF_DIVIDER_SELECT_DIV64); - default: UHD_THROW_INVALID_CODE_PATH(); - } -} - -#endif // INCLUDED_ADF435X_HPP diff --git a/host/lib/usrp/common/adf535x.cpp b/host/lib/usrp/common/adf535x.cpp index 4885f4b5a..67a94bcc1 100644 --- a/host/lib/usrp/common/adf535x.cpp +++ b/host/lib/usrp/common/adf535x.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "adf535x.hpp" +#include adf535x_iface::sptr adf535x_iface::make_adf5355(write_fn_t write) { diff --git a/host/lib/usrp/common/adf535x.hpp b/host/lib/usrp/common/adf535x.hpp deleted file mode 100644 index 8380c9d04..000000000 --- a/host/lib/usrp/common/adf535x.hpp +++ /dev/null @@ -1,477 +0,0 @@ -// -// Copyright 2015, 2017 Ettus Research, A National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_ADF535X_HPP -#define INCLUDED_ADF535X_HPP - -#include "adf5355_regs.hpp" -#include "adf5356_regs.hpp" -#include -#include -#include -#include //gcd -#include -#include -#include -#include -#include -#include - -class adf535x_iface -{ -public: - typedef std::shared_ptr sptr; - typedef std::function)> write_fn_t; - - static sptr make_adf5355(write_fn_t write); - static sptr make_adf5356(write_fn_t write); - - virtual ~adf535x_iface() = default; - - enum output_t { RF_OUTPUT_A, RF_OUTPUT_B }; - - enum feedback_sel_t { FB_SEL_FUNDAMENTAL, FB_SEL_DIVIDED }; - - enum output_power_t { OUTPUT_POWER_M4DBM, OUTPUT_POWER_M1DBM, OUTPUT_POWER_2DBM, OUTPUT_POWER_5DBM }; - - enum muxout_t { MUXOUT_3STATE, MUXOUT_DVDD, MUXOUT_DGND, MUXOUT_RDIV, MUXOUT_NDIV, MUXOUT_ALD, MUXOUT_DLD }; - - virtual void set_reference_freq(double fref, bool force = false) = 0; - - virtual void set_pfd_freq(double pfd_freq) = 0; - - virtual void set_feedback_select(feedback_sel_t fb_sel) = 0; - - virtual void set_output_power(output_power_t power) = 0; - - virtual void set_output_enable(output_t output, bool enable) = 0; - - virtual void set_muxout_mode(muxout_t mode) = 0; - - virtual double set_frequency(double target_freq, double freq_resolution, bool flush = false) = 0; - - virtual void commit() = 0; -}; - -using namespace uhd; - -namespace { - const double ADF535X_DOUBLER_MAX_REF_FREQ = 60e6; - const double ADF535X_MAX_FREQ_PFD = 125e6; -//const double ADF535X_PRESCALER_THRESH = 7e9; - - const double ADF535X_MIN_VCO_FREQ = 3.4e9; -//const double ADF535X_MAX_VCO_FREQ = 6.8e9; - const double ADF535X_MAX_OUT_FREQ = 6.8e9; - const double ADF535X_MIN_OUT_FREQ = (3.4e9 / 64); -//const double ADF535X_MAX_OUTB_FREQ = (6.8e9 * 2); -//const double ADF535X_MIN_OUTB_FREQ = (3.4e9 * 2); - - const double ADF535X_PHASE_RESYNC_TIME = 400e-6; - - const uint32_t ADF535X_MOD1 = 16777216; - const uint32_t ADF535X_MAX_MOD2 = 16383; - const uint32_t ADF535X_MAX_FRAC2 = 16383; -//const uint16_t ADF535X_MIN_INT_PRESCALER_89 = 75; -} - -template -class adf535x_impl : public adf535x_iface -{ -public: - explicit adf535x_impl(write_fn_t write_fn) : - _write_fn(std::move(write_fn)), - _regs(), - _rewrite_regs(true), - _wait_time_us(0), - _ref_freq(0.0), - _pfd_freq(0.0), - _fb_after_divider(false) - { - - _regs.vco_band_div = 3; - _regs.timeout = 11; - _regs.auto_level_timeout = 30; - _regs.synth_lock_timeout = 12; - - _regs.adc_clock_divider = 16; - _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED; - _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED; - - // TODO Needs to be enabled for phase resync - _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED; - - // TODO Default should be divided, but there seems to be a bug preventing that. Needs rechecking - _regs.feedback_select = adf535x_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; - } - - ~adf535x_impl() override - { - UHD_SAFE_CALL( - _regs.power_down = adf535x_regs_t::POWER_DOWN_ENABLED; - commit(); - ) - } - - void set_feedback_select(const feedback_sel_t fb_sel) override - { - _fb_after_divider = (fb_sel == FB_SEL_DIVIDED); - - if (_fb_after_divider) { - _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_DIVIDED; - } else { - _regs.feedback_select = adf535x_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; - } - } - - void set_pfd_freq(const double pfd_freq) override - { - if (pfd_freq > ADF535X_MAX_FREQ_PFD) { - UHD_LOGGER_ERROR("ADF535x") << boost::format("%f MHz is above the maximum PFD frequency of %f MHz\n") - % (pfd_freq/1e6) % (ADF535X_MAX_FREQ_PFD/1e6); - return; - } - _pfd_freq = pfd_freq; - - set_reference_freq(_ref_freq); - } - - void set_reference_freq(const double fref, const bool force = false) override - { - //Skip the body if the reference frequency does not change - if (uhd::math::frequencies_are_equal(fref, _ref_freq) and (not force)) - return; - - _ref_freq = fref; - - //----------------------------------------------------------- - //Set reference settings - int ref_div_factor = static_cast(std::floor(_ref_freq / _pfd_freq)); - - //Reference doubler for 50% duty cycle - const bool doubler_en = (_ref_freq <= ADF535X_DOUBLER_MAX_REF_FREQ); - if (doubler_en) { - ref_div_factor *= 2; - } - - //Reference divide-by-2 for 50% duty cycle - // if R even, move one divide by 2 to to regs.reference_divide_by_2 - const bool div2_en = (ref_div_factor % 2 == 0); - if (div2_en) { - ref_div_factor /= 2; - } - - _regs.reference_divide_by_2 = div2_en ? - adf535x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : - adf535x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; - _regs.reference_doubler = doubler_en ? - adf535x_regs_t::REFERENCE_DOUBLER_ENABLED : - adf535x_regs_t::REFERENCE_DOUBLER_DISABLED; - _regs.r_counter_10_bit = ref_div_factor; - UHD_ASSERT_THROW((_regs.r_counter_10_bit & ((uint16_t)~0x3FF)) == 0); - - //----------------------------------------------------------- - //Set timeouts (code from ADI driver) - _regs.timeout = std::max(1, std::min(int(ceil(_pfd_freq / (20e3 * 30))), 1023)); - - UHD_ASSERT_THROW((_regs.timeout & ((uint16_t)~0x3FF)) == 0); - _regs.synth_lock_timeout = - static_cast(ceil((_pfd_freq * 2) / (100e3 * _regs.timeout))); - UHD_ASSERT_THROW((_regs.synth_lock_timeout & ((uint16_t)~0x1F)) == 0); - _regs.auto_level_timeout = - static_cast(ceil((_pfd_freq * 5) / (100e3 * _regs.timeout))); - - //----------------------------------------------------------- - //Set VCO band divider - _regs.vco_band_div = - static_cast(ceil(_pfd_freq / 2.4e6)); - - //----------------------------------------------------------- - //Set ADC delay (code from ADI driver) - _regs.adc_enable = adf535x_regs_t::ADC_ENABLE_ENABLED; - _regs.adc_conversion = adf535x_regs_t::ADC_CONVERSION_ENABLED; - _regs.adc_clock_divider = std::max(1, std::min(int(ceil(((_pfd_freq / 100e3) - 2) / 4)),255)); - - _wait_time_us = static_cast( - ceil(16e6 / (_pfd_freq / ((4 * _regs.adc_clock_divider) + 2)))); - - //----------------------------------------------------------- - //Phase resync - // TODO Renable here, in initialization, or through separate set_phase_resync(bool enable) function - _regs.phase_resync = adf535x_regs_t::PHASE_RESYNC_DISABLED; - - _regs.phase_adjust = adf535x_regs_t::PHASE_ADJUST_DISABLED; - _regs.sd_load_reset = adf535x_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE; - _regs.phase_resync_clk_div = static_cast( - floor(ADF535X_PHASE_RESYNC_TIME * _pfd_freq)); - - _rewrite_regs = true; - } - - double set_frequency(const double target_freq, const double freq_resolution, const bool flush = false) override - { - return _set_frequency(target_freq, freq_resolution, flush); - } - - void set_output_power(const output_power_t power) override - { - typename adf535x_regs_t::output_power_t setting; - switch (power) { - case OUTPUT_POWER_M4DBM: setting = adf535x_regs_t::OUTPUT_POWER_M4DBM; break; - case OUTPUT_POWER_M1DBM: setting = adf535x_regs_t::OUTPUT_POWER_M1DBM; break; - case OUTPUT_POWER_2DBM: setting = adf535x_regs_t::OUTPUT_POWER_2DBM; break; - case OUTPUT_POWER_5DBM: setting = adf535x_regs_t::OUTPUT_POWER_5DBM; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - if (_regs.output_power != setting) _rewrite_regs = true; - _regs.output_power = setting; - } - - void set_output_enable(const output_t output, const bool enable) override - { - switch (output) { - case RF_OUTPUT_A: _regs.rf_out_a_enabled = enable ? adf535x_regs_t::RF_OUT_A_ENABLED_ENABLED : - adf535x_regs_t::RF_OUT_A_ENABLED_DISABLED; - break; - case RF_OUTPUT_B: _regs.rf_out_b_enabled = enable ? adf535x_regs_t::RF_OUT_B_ENABLED_ENABLED : - adf535x_regs_t::RF_OUT_B_ENABLED_DISABLED; - break; - } - } - - void set_muxout_mode(const muxout_t mode) override - { - switch (mode) { - case MUXOUT_3STATE: _regs.muxout = adf535x_regs_t::MUXOUT_3STATE; break; - case MUXOUT_DVDD: _regs.muxout = adf535x_regs_t::MUXOUT_DVDD; break; - case MUXOUT_DGND: _regs.muxout = adf535x_regs_t::MUXOUT_DGND; break; - case MUXOUT_RDIV: _regs.muxout = adf535x_regs_t::MUXOUT_RDIV; break; - case MUXOUT_NDIV: _regs.muxout = adf535x_regs_t::MUXOUT_NDIV; break; - case MUXOUT_ALD: _regs.muxout = adf535x_regs_t::MUXOUT_ANALOG_LD; break; - case MUXOUT_DLD: _regs.muxout = adf535x_regs_t::MUXOUT_DLD; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - } - - void commit() override - { - _commit(); - } - -protected: - double _set_frequency(double, double, bool); - void _commit(); - -private: //Members - typedef std::vector addr_vtr_t; - - write_fn_t _write_fn; - adf535x_regs_t _regs; - bool _rewrite_regs; - uint32_t _wait_time_us; - double _ref_freq; - double _pfd_freq; - double _fb_after_divider; -}; - -// ADF5355 Functions -template <> -inline double adf535x_impl::_set_frequency(double target_freq, double freq_resolution, bool flush) -{ - if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { - throw uhd::runtime_error("requested frequency out of range."); - } - if ((uint32_t) freq_resolution == 0) { - throw uhd::runtime_error("requested resolution cannot be less than 1."); - } - - /* Calculate target VCOout frequency */ - //Increase RF divider until acceptable VCO frequency - double target_vco_freq = target_freq; - uint32_t rf_divider = 1; - while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { - target_vco_freq *= 2; - rf_divider *= 2; - } - - switch (rf_divider) { - case 1: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV1; break; - case 2: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV2; break; - case 4: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV4; break; - case 8: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV8; break; - case 16: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV16; break; - case 32: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV32; break; - case 64: _regs.rf_divider_select = adf5355_regs_t::RF_DIVIDER_SELECT_DIV64; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - - //Compute fractional PLL params - double prescaler_input_freq = target_vco_freq; - if (_fb_after_divider) { - prescaler_input_freq /= rf_divider; - } - - const double N = prescaler_input_freq / _pfd_freq; - const auto INT = static_cast(floor(N)); - const auto FRAC1 = static_cast(floor((N - INT) * ADF535X_MOD1)); - const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; - - const double gcd = boost::math::gcd(static_cast(_pfd_freq), static_cast(freq_resolution)); - const auto MOD2 = static_cast(std::min(floor(_pfd_freq / gcd), static_cast(ADF535X_MAX_MOD2))); - const auto FRAC2 = static_cast(std::min(ceil(residue * MOD2), static_cast(ADF535X_MAX_FRAC2))); - - const double coerced_vco_freq = _pfd_freq * ( - double(INT) + ( - (double(FRAC1) + - (double(FRAC2) / double(MOD2))) - / double(ADF535X_MOD1) - ) - ); - - const double coerced_out_freq = coerced_vco_freq / rf_divider; - - /* Update registers */ - _regs.int_16_bit = INT; - _regs.frac1_24_bit = FRAC1; - _regs.frac2_14_bit = FRAC2; - _regs.mod2_14_bit = MOD2; - _regs.phase_24_bit = 0; - - if (flush) commit(); - return coerced_out_freq; -} - -template <> -inline void adf535x_impl::_commit() -{ - const size_t ONE_REG = 1; - - if (_rewrite_regs) { - //For a full state sync write registers in reverse order 12 - 0 - addr_vtr_t regs; - for (uint8_t addr = 12; addr > 0; addr--) { - regs.push_back(_regs.get_reg(addr)); - } - _write_fn(regs); - // TODO Add FPGA based delay between these writes - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); - _rewrite_regs = false; - - } else { - //Frequency update sequence from data sheet - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); - _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_ENABLED; - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); - _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_DISABLED; - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); - _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED; - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(4))); - // TODO Add FPGA based delay between these writes - _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED; - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); - } -} - -// ADF5356 Functions -template <> -inline double adf535x_impl::_set_frequency(double target_freq, double freq_resolution, bool flush) -{ - if (target_freq > ADF535X_MAX_OUT_FREQ or target_freq < ADF535X_MIN_OUT_FREQ) { - throw uhd::runtime_error("requested frequency out of range."); - } - if ((uint32_t) freq_resolution == 0) { - throw uhd::runtime_error("requested resolution cannot be less than 1."); - } - - /* Calculate target VCOout frequency */ - //Increase RF divider until acceptable VCO frequency - double target_vco_freq = target_freq; - uint32_t rf_divider = 1; - while (target_vco_freq < ADF535X_MIN_VCO_FREQ && rf_divider < 64) { - target_vco_freq *= 2; - rf_divider *= 2; - } - - switch (rf_divider) { - case 1: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV1; break; - case 2: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV2; break; - case 4: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV4; break; - case 8: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV8; break; - case 16: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV16; break; - case 32: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV32; break; - case 64: _regs.rf_divider_select = adf5356_regs_t::RF_DIVIDER_SELECT_DIV64; break; - default: UHD_THROW_INVALID_CODE_PATH(); - } - - //Compute fractional PLL params - double prescaler_input_freq = target_vco_freq; - if (_fb_after_divider) { - prescaler_input_freq /= rf_divider; - } - - const double N = prescaler_input_freq / _pfd_freq; - const auto INT = static_cast(floor(N)); - const auto FRAC1 = static_cast(floor((N - INT) * ADF535X_MOD1)); - const double residue = (N - INT) * ADF535X_MOD1 - FRAC1; - - const double gcd = boost::math::gcd(static_cast(_pfd_freq), static_cast(freq_resolution)); - const auto MOD2 = static_cast(std::min(floor(_pfd_freq / gcd), static_cast(ADF535X_MAX_MOD2))); - const auto FRAC2 = static_cast(std::min(ceil(residue * MOD2), static_cast(ADF535X_MAX_FRAC2))); - - const double coerced_vco_freq = _pfd_freq * ( - double(INT) + ( - (double(FRAC1) + - (double(FRAC2) / double(MOD2))) - / double(ADF535X_MOD1) - ) - ); - - const double coerced_out_freq = coerced_vco_freq / rf_divider; - - /* Update registers */ - _regs.int_16_bit = INT; - _regs.frac1_24_bit = FRAC1; - _regs.frac2_msb = FRAC2; - _regs.mod2_msb = MOD2; - _regs.phase_24_bit = 0; - - if (flush) commit(); - return coerced_out_freq; -} - -template <> -inline void adf535x_impl::_commit() -{ - const size_t ONE_REG = 1; - if (_rewrite_regs) { - //For a full state sync write registers in reverse order 12 - 0 - addr_vtr_t regs; - for (uint8_t addr = 13; addr > 0; addr--) { - regs.push_back(_regs.get_reg(addr)); - } - _write_fn(regs); - // TODO Add FPGA based delay between these writes - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); - _rewrite_regs = false; - - } else { - //Frequency update sequence from data sheet - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(13))); - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(10))); - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(6))); - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(2))); - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(1))); - // TODO Add FPGA based delay between these writes - _write_fn(addr_vtr_t(ONE_REG, _regs.get_reg(0))); - } -} - -#endif // INCLUDED_ADF535X_HPP diff --git a/host/lib/usrp/common/apply_corrections.cpp b/host/lib/usrp/common/apply_corrections.cpp index 3d7127bfe..5c606c338 100644 --- a/host/lib/usrp/common/apply_corrections.cpp +++ b/host/lib/usrp/common/apply_corrections.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "apply_corrections.hpp" +#include #include #include #include diff --git a/host/lib/usrp/common/apply_corrections.hpp b/host/lib/usrp/common/apply_corrections.hpp deleted file mode 100644 index 3b4669f9a..000000000 --- a/host/lib/usrp/common/apply_corrections.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright 2011-2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP -#define INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP - -#include -#include -#include - -namespace uhd{ namespace usrp{ - - void apply_tx_fe_corrections( - property_tree::sptr sub_tree, //starts at mboards/x - const fs_path db_path, - const fs_path tx_fe_corr_path, - const double tx_lo_freq //actual lo freq - ); - - void apply_tx_fe_corrections( - property_tree::sptr sub_tree, //starts at mboards/x - const std::string &slot, //name of dboard slot - const double tx_lo_freq //actual lo freq - ); - void apply_rx_fe_corrections( - property_tree::sptr sub_tree, //starts at mboards/x - const std::string &slot, //name of dboard slot - const double rx_lo_freq //actual lo freq - ); - - void apply_rx_fe_corrections( - property_tree::sptr sub_tree, //starts at mboards/x - const fs_path db_path, - const fs_path rx_fe_corr_path, - const double rx_lo_freq //actual lo freq - ); -}} //namespace uhd::usrp - -#endif /* INCLUDED_LIBUHD_USRP_COMMON_APPLY_CORRECTIONS_HPP */ diff --git a/host/lib/usrp/common/async_packet_handler.hpp b/host/lib/usrp/common/async_packet_handler.hpp deleted file mode 100644 index de9d17001..000000000 --- a/host/lib/usrp/common/async_packet_handler.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2012 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP -#define INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP - -#include -#include -#include -#include -#include - -namespace uhd{ namespace usrp{ - - template - void load_metadata_from_buff( - const to_host_type &to_host, - async_metadata_t &metadata, - const transport::vrt::if_packet_info_t &if_packet_info, - const uint32_t *vrt_hdr, - const double tick_rate, - const size_t channel = 0 - ){ - const uint32_t *payload = vrt_hdr + if_packet_info.num_header_words32; - - //load into metadata - metadata.channel = channel; - metadata.has_time_spec = if_packet_info.has_tsf; - if (tick_rate == 0.0) { - metadata.time_spec = 0.0; - } else { - metadata.time_spec = time_spec_t::from_ticks(if_packet_info.tsf, tick_rate); - } - metadata.event_code = async_metadata_t::event_code_t(to_host(payload[0]) & 0xff); - - //load user payload - for (size_t i = 1; i < if_packet_info.num_payload_words32; i++){ - if (i-1 == 4) break; //limit of 4 words32 - metadata.user_payload[i-1] = to_host(payload[i]); - } - } - - UHD_INLINE void standard_async_msg_prints(const async_metadata_t &metadata) - { - if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_UNDERFLOW - | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET) - ) - { - UHD_LOG_FASTPATH("U") - } - else if (metadata.event_code & - ( async_metadata_t::EVENT_CODE_SEQ_ERROR - | async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST) - ) - { - UHD_LOG_FASTPATH("S") - } - else if (metadata.event_code & - async_metadata_t::EVENT_CODE_TIME_ERROR - ) - { - UHD_LOG_FASTPATH("L") - } - } - - -}} //namespace uhd::usrp - -#endif /* INCLUDED_LIBUHD_USRP_COMMON_ASYNC_PACKET_HANDLER_HPP */ diff --git a/host/lib/usrp/common/fifo_ctrl_excelsior.cpp b/host/lib/usrp/common/fifo_ctrl_excelsior.cpp index b25b76f6b..e110919f9 100644 --- a/host/lib/usrp/common/fifo_ctrl_excelsior.cpp +++ b/host/lib/usrp/common/fifo_ctrl_excelsior.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "fifo_ctrl_excelsior.hpp" -#include "async_packet_handler.hpp" +#include +#include #include #include #include diff --git a/host/lib/usrp/common/fifo_ctrl_excelsior.hpp b/host/lib/usrp/common/fifo_ctrl_excelsior.hpp deleted file mode 100644 index 91c006a1a..000000000 --- a/host/lib/usrp/common/fifo_ctrl_excelsior.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright 2012,2015 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_B200_CTRL_HPP -#define INCLUDED_B200_CTRL_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - - -struct fifo_ctrl_excelsior_config -{ - size_t async_sid_base; - size_t num_async_chan; - size_t ctrl_sid_base; - size_t spi_base; - size_t spi_rb; -}; - -/*! - * Provide access to peek, poke, spi, and async messages. - */ -class fifo_ctrl_excelsior : public uhd::timed_wb_iface, public uhd::spi_iface -{ -public: - typedef boost::shared_ptr sptr; - - //! Make a new control object - static sptr make( - uhd::transport::zero_copy_if::sptr xport, - const fifo_ctrl_excelsior_config &config - ); - - //! Set the tick rate (converting time into ticks) - virtual void set_tick_rate(const double rate) = 0; - - //! Pop an async message from the queue or timeout - virtual bool pop_async_msg(uhd::async_metadata_t &async_metadata, double timeout) = 0; -}; - -#endif /* INCLUDED_B200_CTRL_HPP */ diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index 3d8ff6e67..6e1b374ca 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "fx2_ctrl.hpp" +#include #include #include #include diff --git a/host/lib/usrp/common/fx2_ctrl.hpp b/host/lib/usrp/common/fx2_ctrl.hpp deleted file mode 100644 index 258aa7d04..000000000 --- a/host/lib/usrp/common/fx2_ctrl.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// Copyright 2010-2012 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_COMMON_FX2_CTRL_HPP -#define INCLUDED_LIBUHD_USRP_COMMON_FX2_CTRL_HPP - -#include -#include //i2c iface -#include -#include - -#define FL_BEGIN 0 -#define FL_END 2 -#define FL_XFER 1 -#define USRP_HASH_SLOT_0_ADDR 0xe1e0 -#define USRP_HASH_SLOT_1_ADDR 0xe1f0 -#define VRQ_FPGA_LOAD 0x02 -#define VRQ_FPGA_SET_RESET 0x04 -#define VRQ_FPGA_SET_TX_ENABLE 0x05 -#define VRQ_FPGA_SET_RX_ENABLE 0x06 -#define VRQ_FPGA_SET_TX_RESET 0x0a -#define VRQ_FPGA_SET_RX_RESET 0x0b -#define VRQ_I2C_READ 0x81 -#define VRQ_I2C_WRITE 0x08 -#define VRQ_SET_LED 0x01 -#define VRT_VENDOR_IN 0xC0 -#define VRT_VENDOR_OUT 0x40 - -namespace uhd{ namespace usrp{ - -class fx2_ctrl : boost::noncopyable, public uhd::i2c_iface{ -public: - typedef boost::shared_ptr sptr; - - /*! - * Make a usrp control object from a control transport - * \param ctrl_transport a USB control transport - * \return a new usrp control object - */ - static sptr make(uhd::transport::usb_control::sptr ctrl_transport); - - //! Call init after the fpga is loaded - virtual void usrp_init(void) = 0; - - //! For emergency situations - virtual void usrp_fx2_reset(void) = 0; - - /*! - * Load firmware in Intel HEX Format onto device - * \param filename name of firmware file - * \param force reload firmware if already loaded - */ - virtual void usrp_load_firmware(std::string filename, - bool force = false) = 0; - - /*! - * Load fpga file onto usrp - * \param filename name of fpga image - */ - virtual void usrp_load_fpga(std::string filename) = 0; - - /*! - * Load USB descriptor file in Intel HEX format into EEPROM - * \param filestring name of EEPROM image - */ - virtual void usrp_load_eeprom(std::string filestring) = 0; - - /*! - * Submit an IN transfer - * \param request device specific request - * \param value device specific field - * \param index device specific field - * \param buff buffer to place data - * \param length length of buffer - * \return number of bytes read or error - */ - virtual int usrp_control_read(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length) = 0; - - /*! - * Submit an OUT transfer - * \param request device specific request - * \param value device specific field - * \param index device specific field - * \param buff buffer of data to be sent - * \param length length of buffer - * \return number of bytes written or error - */ - virtual int usrp_control_write(uint8_t request, - uint16_t value, - uint16_t index, - unsigned char *buff, - uint16_t length) = 0; - - /*! - * Perform an I2C write - * \param i2c_addr I2C device address - * \param buf data to be written - * \param len length of data in bytes - * \return number of bytes written or error - */ - - virtual int usrp_i2c_write(uint16_t i2c_addr, - unsigned char *buf, - uint16_t len) = 0; - - /*! - * Perform an I2C read - * \param i2c_addr I2C device address - * \param buf data to be read - * \param len length of data in bytes - * \return number of bytes read or error - */ - - virtual int usrp_i2c_read(uint16_t i2c_addr, - unsigned char *buf, - uint16_t len) = 0; - - //! enable/disable the rx path - virtual void usrp_rx_enable(bool on) = 0; - - //! enable/disable the tx path - virtual void usrp_tx_enable(bool on) = 0; - - //! reset the fpga - virtual void usrp_fpga_reset(bool on) = 0; -}; - -}} //namespace uhd::usrp - -#endif /* INCLUDED_LIBUHD_USRP_COMMON_FX2_CTRL_HPP */ diff --git a/host/lib/usrp/common/lmk04828.cpp b/host/lib/usrp/common/lmk04828.cpp deleted file mode 100644 index 46766e8d2..000000000 --- a/host/lib/usrp/common/lmk04828.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright 2017 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#include "lmk04828.hpp" -#include "lmk04828_regs.hpp" -#include "uhd/exception.hpp" -#include - -using namespace uhd; - - -lmk04828_iface::lmk04828_iface(write_fn_t write_fn, read_fn_t read_fn) : _write_fn(write_fn), _read_fn(read_fn) -{ - -} - -bool lmk04828_iface::verify_chip_id() -{ - // Check ID Device Type, ID Prod, and ID Maskrev registers - uint8_t id_device_type = get_chip_id(); - - std::cout << "LMK device ID: " << int(id_device_type) << std::endl; - - // assert(id_device_type == 6); - if (id_device_type != 6){ - std::cout << "id_device_type is not 6!" << std::endl; - return false; - } - - return true; -} - -uint8_t lmk04828_iface::get_chip_id(){ - uint8_t id_device_type = _read_fn(3); - return id_device_type; -} - -void lmk04828_iface::init() -{ - // Configure the LMK to start producing clocks -// TODO: Convert to use ic_reg_map fields once values are finalized/working - std::vector write_addrs = { - 0x000000,0x000000,0x000002,0x000149,0x00014A,0x000100,0x000101,0x000103,0x000104,0x000105,0x000106,0x000107,0x000120,0x000121,0x000123,0x000124,0x000125,0x000126,0x000127,0x000130,0x000131,0x000133,0x000134,0x000135,0x000136,0x000137,0x000128,0x000129,0x00012B,0x00012C,0x00012D,0x00012E,0x00012F,0x000108,0x000109,0x00010B,0x00010C,0x00010D,0x00010E,0x00010F,0x000118,0x000119,0x00011B,0x00011C,0x00011D,0x00011E,0x00011F,0x000138,0x00013F,0x000140,0x000144,0x000146,0x000147,0x00014B,0x00014C,0x000153,0x000154,0x000155,0x000156,0x000157,0x000158,0x000159,0x00015A,0x00015B,0x00015E,0x000160,0x000161,0x000162,0x000163,0x000164,0x000165,0x000166,0x000167,0x000168,0x00016E,0x000173,0x000169,0x00016C,0x00016D}; - - std::vector write_data = { - 0x000090,0x000010,0x000000,0x000040,0x000033,0x000078,0x000055,0x000000,0x000020,0x000000,0x0000F1,0x000055,0x000078,0x000055,0x000000,0x000020,0x000000,0x0000F1,0x000055,0x000078,0x000055,0x000000,0x000020,0x000000,0x0000F1,0x000005,0x000078,0x000055,0x000000,0x000000,0x000000,0x0000F0,0x000050,0x00007E,0x000055,0x000000,0x000000,0x000000,0x0000F0,0x000055,0x000078,0x000055,0x000000,0x000020,0x000000,0x0000F1,0x000000,0x000030,0x000009,0x000000,0x000000,0x000010,0x00001A,0x00000D,0x0000F6,0x000000,0x000001,0x000000,0x00000A,0x000000,0x000001,0x000000,0x00007D,0x0000DB,0x000000,0x000000,0x000004,0x0000A0,0x000000,0x000000,0x000019,0x000000,0x000000,0x000019,0x00006B,0x000000,0x000051,0x000000,0x000000}; - - std::vector writes {}; - for (size_t index = 0; index < write_addrs.size(); index++) { - writes.push_back((write_addrs[index] << 8) | write_data[index]); - } - - std::cout << "LMK Initialization writes" << std::endl; - for (uint32_t reg : writes) { - std::cout << std::hex << reg << " "; - } - std::cout << std::endl; - - _write_fn(writes); - - if (!verify_chip_id()) { - throw uhd::runtime_error("LMK ID not correct!"); - } -} - -void lmk04828_iface::enable_sysref_pulse() -{ - // Configure the LMK to issue a single SysRef pulse each time SYNC is asserted - - // TODO: Convert to use ic reg map fields once functional - // Addr 0x139 Value 0x2 - // Addr 0x144 Value 0xFF - // Addr 0x143 Value 0x52 - - std::vector writes = { - (0x139 << 11) | 0x2, - (0x144 << 11) | 0xFF, - (0x143 << 11) | 0x52 - }; - - _write_fn(writes); -} - diff --git a/host/lib/usrp/common/lmk04828.hpp b/host/lib/usrp/common/lmk04828.hpp deleted file mode 100644 index e2f1b8669..000000000 --- a/host/lib/usrp/common/lmk04828.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright 2017 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDE_LMK04828_HPP -#define INCLUDE_LMK04828_HPP - -#include -#include -#include -#include - -static const uint32_t LMK04828_ID_DEVICE_TYPE = 6; -static const uint32_t LMK04828_ID_PROD_LSB = 91; -static const uint32_t LMK04828_ID_PROD_MSB = 208; -static const uint32_t LMK04828_ID_MASKREV = 32; - -class lmk04828_iface -{ -public: - typedef boost::shared_ptr sptr; - typedef boost::function)> write_fn_t; - typedef boost::function read_fn_t; - - //static sptr (write_fn_t write_fn, read_fn_t read_fn); - lmk04828_iface(write_fn_t, read_fn_t); - - ~lmk04828_iface() {} - - //! Checks if the chip ID is what we expect - // - // Does not throw - // - // \returns false if chip ID is incorrect - bool verify_chip_id(); - - uint8_t get_chip_id(); - - void init(); - - /*! Enable SYSREF pulses - * - * After calling this, triggering the sync pin will emit a SYSREF pulse. - */ - void enable_sysref_pulse(); - -private: - // use IC Reg Map once values stabilize -// lmk04828_regs_t _regs; - - write_fn_t _write_fn; - read_fn_t _read_fn; -}; -#endif diff --git a/host/lib/usrp/common/max287x.hpp b/host/lib/usrp/common/max287x.hpp deleted file mode 100644 index 762daf7b6..000000000 --- a/host/lib/usrp/common/max287x.hpp +++ /dev/null @@ -1,935 +0,0 @@ -// -// Copyright 2015-2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef MAX287X_HPP_INCLUDED -#define MAX287X_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "max2870_regs.hpp" -#include "max2871_regs.hpp" - -/** - * MAX287x interface - */ -class max287x_iface -{ -public: - typedef boost::shared_ptr sptr; - - typedef boost::function)> write_fn; - - /** - * LD Pin Modes - */ - typedef enum{ - LD_PIN_MODE_LOW, - LD_PIN_MODE_DLD, - LD_PIN_MODE_ALD, - LD_PIN_MODE_HIGH - } ld_pin_mode_t; - - /** - * MUXOUT Modes - */ - typedef enum{ - MUXOUT_TRI_STATE, - MUXOUT_HIGH, - MUXOUT_LOW, - MUXOUT_RDIV, - MUXOUT_NDIV, - MUXOUT_ALD, - MUXOUT_DLD, - MUXOUT_SYNC, - MUXOUT_SPI - } muxout_mode_t; - - /** - * Charge Pump Currents - */ - typedef enum{ - CHARGE_PUMP_CURRENT_0_32MA, - CHARGE_PUMP_CURRENT_0_64MA, - CHARGE_PUMP_CURRENT_0_96MA, - CHARGE_PUMP_CURRENT_1_28MA, - CHARGE_PUMP_CURRENT_1_60MA, - CHARGE_PUMP_CURRENT_1_92MA, - CHARGE_PUMP_CURRENT_2_24MA, - CHARGE_PUMP_CURRENT_2_56MA, - CHARGE_PUMP_CURRENT_2_88MA, - CHARGE_PUMP_CURRENT_3_20MA, - CHARGE_PUMP_CURRENT_3_52MA, - CHARGE_PUMP_CURRENT_3_84MA, - CHARGE_PUMP_CURRENT_4_16MA, - CHARGE_PUMP_CURRENT_4_48MA, - CHARGE_PUMP_CURRENT_4_80MA, - CHARGE_PUMP_CURRENT_5_12MA - } charge_pump_current_t; - - /** - * Output Powers - */ - typedef enum{ - OUTPUT_POWER_M4DBM, - OUTPUT_POWER_M1DBM, - OUTPUT_POWER_2DBM, - OUTPUT_POWER_5DBM - } output_power_t; - - typedef enum { - LOW_NOISE_AND_SPUR_LOW_NOISE, - LOW_NOISE_AND_SPUR_LOW_SPUR_1, - LOW_NOISE_AND_SPUR_LOW_SPUR_2 - } low_noise_and_spur_t; - - typedef enum { - CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF, - CLOCK_DIV_MODE_FAST_LOCK, - CLOCK_DIV_MODE_PHASE - } clock_divider_mode_t; - - /** - * Make a synthesizer - * @param write write function - * @return shared pointer to object - */ - template static sptr make(write_fn write) - { - return sptr(new max287X_t(write)); - } - - /** - * Destructor - */ - virtual ~max287x_iface() {}; - - /** - * Power up the synthesizer - */ - virtual void power_up(void) = 0; - - /** - * Shut down the synthesizer - */ - virtual void shutdown(void) = 0; - - /** - * Check if the synthesizer is shut down - */ - virtual bool is_shutdown(void) = 0; - - /** - * Set frequency - * @param target_freq target frequency - * @param ref_freq reference frequency - * @param target_pfd_freq target phase detector frequency - * @param is_int_n enable integer-N tuning - * @return actual frequency - */ - virtual double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) = 0; - - /** - * Set output power - * @param power output power - */ - virtual void set_output_power(output_power_t power) = 0; - - /** - * Set lock detect pin mode - * @param mode lock detect pin mode - */ - virtual void set_ld_pin_mode(ld_pin_mode_t mode) = 0; - - /** - * Set muxout pin mode - * @param mode muxout mode - */ - virtual void set_muxout_mode(muxout_mode_t mode) = 0; - - /** - * Set charge pump current - * @param cp_current charge pump current - */ - virtual void set_charge_pump_current(charge_pump_current_t cp_current) = 0; - - /** - * Enable or disable auto retune - * @param enabled enable auto retune - */ - virtual void set_auto_retune(bool enabled) = 0; - - /** - * Set clock divider mode - * @param mode clock divider mode - */ - virtual void set_clock_divider_mode(clock_divider_mode_t mode) = 0; - - /** - * Enable or disable cycle slip mode - * @param enabled enable cycle slip mode - */ - virtual void set_cycle_slip_mode(bool enabled) = 0; - - /** - * Set low noise and spur mode - * @param mode low noise and spur mode - */ - virtual void set_low_noise_and_spur(low_noise_and_spur_t mode) = 0; - - /** - * Set phase - * @param phase the phase offset - */ - virtual void set_phase(uint16_t phase) = 0; - - /** - * Write values configured by the set_* functions. - */ - virtual void commit(void) = 0; - - /** - * Check whether this is in a state where it can be synchronized - */ - virtual bool can_sync(void) = 0; - - /** - * Configure synthesizer for phase synchronization - */ - virtual void config_for_sync(bool enable) = 0; -}; - -/** - * MAX287x - * Base class for all MAX287x synthesizers - */ -template -class max287x : public max287x_iface -{ -public: - max287x(write_fn func); - virtual ~max287x(); - virtual void power_up(void); - virtual void shutdown(void); - virtual bool is_shutdown(void); - virtual double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n); - virtual void set_output_power(output_power_t power); - virtual void set_ld_pin_mode(ld_pin_mode_t mode); - virtual void set_muxout_mode(muxout_mode_t mode); - virtual void set_charge_pump_current(charge_pump_current_t cp_current); - virtual void set_auto_retune(bool enabled); - virtual void set_clock_divider_mode(clock_divider_mode_t mode); - virtual void set_cycle_slip_mode(bool enabled); - virtual void set_low_noise_and_spur(low_noise_and_spur_t mode); - virtual void set_phase(uint16_t phase); - virtual void commit(); - virtual bool can_sync(); - virtual void config_for_sync(bool enable); - -protected: - max287x_regs_t _regs; - bool _can_sync; - bool _config_for_sync; - bool _write_all_regs; - -private: - write_fn _write; - bool _delay_after_write; -}; - -/** - * MAX2870 - */ -class max2870 : public max287x -{ -public: - max2870(write_fn func) : max287x(func) {} - ~max2870() {} - double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) - { - _regs.cpoc = is_int_n ? max2870_regs_t::CPOC_ENABLED : max2870_regs_t::CPOC_DISABLED; - _regs.feedback_select = target_freq >= 3.0e9 ? - max2870_regs_t::FEEDBACK_SELECT_DIVIDED : - max2870_regs_t::FEEDBACK_SELECT_FUNDAMENTAL; - - return max287x::set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); - } - void commit(void) - { - // For MAX2870, we always need to write all registers. - _write_all_regs = true; - max287x::commit(); - } -}; - -/** - * MAX2871 - */ -// Table of frequency ranges for each VCO value. -// The values were derived from sampling multiple -// units over a temperature range of -10 to 40 deg C. -typedef std::map vco_map_t; -static const vco_map_t max2871_vco_map = - boost::assign::map_list_of - (0,uhd::range_t(2767776024.0,2838472816.0)) - (1,uhd::range_t(2838472816.0,2879070053.0)) - (1,uhd::range_t(2879070053.0,2921202504.0)) - (3,uhd::range_t(2921202504.0,2960407579.0)) - (4,uhd::range_t(2960407579.0,3001687422.0)) - (5,uhd::range_t(3001687422.0,3048662562.0)) - (6,uhd::range_t(3048662562.0,3097511550.0)) - (7,uhd::range_t(3097511550.0,3145085864.0)) - (8,uhd::range_t(3145085864.0,3201050835.0)) - (9,uhd::range_t(3201050835.0,3259581909.0)) - (10,uhd::range_t(3259581909.0,3321408729.0)) - (11,uhd::range_t(3321408729.0,3375217285.0)) - (12,uhd::range_t(3375217285.0,3432807972.0)) - (13,uhd::range_t(3432807972.0,3503759088.0)) - (14,uhd::range_t(3503759088.0,3579011283.0)) - (15,uhd::range_t(3579011283.0,3683570865.0)) - (20,uhd::range_t(3683570865.0,3711845712.0)) - (21,uhd::range_t(3711845712.0,3762188221.0)) - (22,uhd::range_t(3762188221.0,3814209551.0)) - (23,uhd::range_t(3814209551.0,3865820020.0)) - (24,uhd::range_t(3865820020.0,3922520021.0)) - (25,uhd::range_t(3922520021.0,3981682709.0)) - (26,uhd::range_t(3981682709.0,4043154280.0)) - (27,uhd::range_t(4043154280.0,4100400020.0)) - (28,uhd::range_t(4100400020.0,4159647583.0)) - (29,uhd::range_t(4159647583.0,4228164842.0)) - (30,uhd::range_t(4228164842.0,4299359879.0)) - (31,uhd::range_t(4299359879.0,4395947962.0)) - (33,uhd::range_t(4395947962.0,4426512061.0)) - (34,uhd::range_t(4426512061.0,4480333656.0)) - (35,uhd::range_t(4480333656.0,4526297331.0)) - (36,uhd::range_t(4526297331.0,4574689510.0)) - (37,uhd::range_t(4574689510.0,4633102021.0)) - (38,uhd::range_t(4633102021.0,4693755616.0)) - (39,uhd::range_t(4693755616.0,4745624435.0)) - (40,uhd::range_t(4745624435.0,4803922123.0)) - (41,uhd::range_t(4803922123.0,4871523881.0)) - (42,uhd::range_t(4871523881.0,4942111286.0)) - (43,uhd::range_t(4942111286.0,5000192446.0)) - (44,uhd::range_t(5000192446.0,5059567510.0)) - (45,uhd::range_t(5059567510.0,5136258187.0)) - (46,uhd::range_t(5136258187.0,5215827295.0)) - (47,uhd::range_t(5215827295.0,5341282949.0)) - (49,uhd::range_t(5341282949.0,5389819310.0)) - (50,uhd::range_t(5389819310.0,5444868434.0)) - (51,uhd::range_t(5444868434.0,5500079705.0)) - (52,uhd::range_t(5500079705.0,5555329630.0)) - (53,uhd::range_t(5555329630.0,5615049833.0)) - (54,uhd::range_t(5615049833.0,5676098527.0)) - (55,uhd::range_t(5676098527.0,5744191577.0)) - (56,uhd::range_t(5744191577.0,5810869917.0)) - (57,uhd::range_t(5810869917.0,5879176194.0)) - (58,uhd::range_t(5879176194.0,5952430629.0)) - (59,uhd::range_t(5952430629.0,6016743964.0)) - (60,uhd::range_t(6016743964.0,6090658690.0)) - (61,uhd::range_t(6090658690.0,6128133570.0)); - -class max2871 : public max287x -{ -public: - max2871(write_fn func) : max287x(func) {} - ~max2871() {}; - void set_muxout_mode(muxout_mode_t mode) - { - switch(mode) - { - case MUXOUT_SYNC: - _regs.muxout = max2871_regs_t::MUXOUT_SYNC; - break; - case MUXOUT_SPI: - _regs.muxout = max2871_regs_t::MUXOUT_SPI; - break; - default: - max287x::set_muxout_mode(mode); - } - } - - double set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) - { - _regs.feedback_select = max2871_regs_t::FEEDBACK_SELECT_DIVIDED; - double freq = max287x::set_frequency(target_freq, ref_freq, target_pfd_freq, is_int_n); - - // To support phase synchronization on MAX2871, the same VCO - // subband must be manually programmed on all synthesizers and - // several registers must be set to specific values. - if (_config_for_sync) - { - // Need to manually program VCO value - static const double MIN_VCO_FREQ = 3e9; - double vco_freq = target_freq; - while (vco_freq < MIN_VCO_FREQ) - vco_freq *=2; - uint8_t vco_index = 0xFF; - for(const vco_map_t::value_type &vco: max2871_vco_map) - { - if (uhd::math::fp_compare::fp_compare_epsilon(vco_freq) < vco.second.stop()) - { - vco_index = vco.first; - break; - } - } - if (vco_index == 0xFF) - throw uhd::index_error("Invalid VCO frequency"); - - // Settings required for phase synchronization as per MAX2871 datasheet - _regs.shutdown_vas = max2871_regs_t::SHUTDOWN_VAS_DISABLED; - _regs.vco = vco_index; - _regs.low_noise_and_spur = max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE; - _regs.f01 = max2871_regs_t::F01_FRAC_N; - _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED; - } - else - { - // Reset values to defaults - _regs.shutdown_vas = max2871_regs_t::SHUTDOWN_VAS_ENABLED; // turn VCO auto selection on - _regs.low_noise_and_spur = max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_2; - _regs.f01 = max2871_regs_t::F01_AUTO; - _regs.aux_output_select = max2871_regs_t::AUX_OUTPUT_SELECT_FUNDAMENTAL; - } - - return freq; - } - - void commit() - { - max287x::commit(); - - // According to Maxim support, the following factors must be true to allow for phase synchronization - if (_regs.int_n_mode == max2871_regs_t::INT_N_MODE_FRAC_N and - _regs.feedback_select == max2871_regs_t::FEEDBACK_SELECT_DIVIDED and - _regs.aux_output_select == max2871_regs_t::AUX_OUTPUT_SELECT_DIVIDED and - _regs.rf_divider_select <= max2871_regs_t::RF_DIVIDER_SELECT_DIV16 and - _regs.low_noise_and_spur == max2871_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE and - _regs.f01 == max2871_regs_t::F01_FRAC_N and - _regs.reference_doubler == max2871_regs_t::REFERENCE_DOUBLER_DISABLED and - _regs.reference_divide_by_2 == max2871_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED and - _regs.r_counter_10_bit == 1) - { - _can_sync = true; - } else { - _can_sync = false; - } - } -}; - - -// Implementation of max287x template class -// To avoid linker errors, it was either include -// it here or put it in a .cpp file and include -// that file in this header file. Decided to just -// include it here. - -template -max287x::max287x(write_fn func) : - _can_sync(false), - _config_for_sync(false), - _write_all_regs(true), - _write(func), - _delay_after_write(true) -{ - power_up(); -} - -template -max287x::~max287x() -{ - UHD_SAFE_CALL - ( - shutdown(); - ) -} - -template -void max287x::power_up(void) -{ - _regs.power_down = max287x_regs_t::POWER_DOWN_NORMAL; - _regs.double_buffer = max287x_regs_t::DOUBLE_BUFFER_ENABLED; - - // According to MAX287x data sheets: - // "Upon power-up, the registers should be programmed twice with at - // least a 20ms pause between writes. The first write ensures that - // the device is enabled, and the second write starts the VCO - // selection process." - // The first write and the 20ms wait are done here. The second write - // is done when any other function that does a write to the registers - // is called (such as tuning). - _write_all_regs = true; - _delay_after_write = true; - commit(); - _write_all_regs = true; // Next call to commit() writes all regs -} - -template -void max287x::shutdown(void) -{ - _regs.rf_output_enable = max287x_regs_t::RF_OUTPUT_ENABLE_DISABLED; - _regs.aux_output_enable = max287x_regs_t::AUX_OUTPUT_ENABLE_DISABLED; - _regs.power_down = max287x_regs_t::POWER_DOWN_SHUTDOWN; - commit(); -} - -template -bool max287x::is_shutdown(void) -{ - return (_regs.power_down == max287x_regs_t::POWER_DOWN_SHUTDOWN); -} - -template -double max287x::set_frequency( - double target_freq, - double ref_freq, - double target_pfd_freq, - bool is_int_n) -{ - //map rf divider select output dividers to enums - static const uhd::dict rfdivsel_to_enum = - boost::assign::map_list_of - (1, max287x_regs_t::RF_DIVIDER_SELECT_DIV1) - (2, max287x_regs_t::RF_DIVIDER_SELECT_DIV2) - (4, max287x_regs_t::RF_DIVIDER_SELECT_DIV4) - (8, max287x_regs_t::RF_DIVIDER_SELECT_DIV8) - (16, max287x_regs_t::RF_DIVIDER_SELECT_DIV16) - (32, max287x_regs_t::RF_DIVIDER_SELECT_DIV32) - (64, max287x_regs_t::RF_DIVIDER_SELECT_DIV64) - (128, max287x_regs_t::RF_DIVIDER_SELECT_DIV128); - - //map mode setting to valid integer divider (N) values - static const uhd::range_t int_n_mode_div_range(16,65535,1); - static const uhd::range_t frac_n_mode_div_range(19,4091,1); - - //other ranges and constants from MAX287X datasheets - static const uhd::range_t clock_div_range(1,4095,1); - static const uhd::range_t r_range(1,1023,1); - static const double MIN_VCO_FREQ = 3e9; - static const double BS_FREQ = 50e3; - static const int MAX_BS_VALUE = 1023; - - int T = 0; - int D = ref_freq <= 10.0e6 ? 1 : 0; - int R = 0; - int BS = 0; - int N = 0; - int FRAC = 0; - int MOD = 4095; - int RFdiv = 1; - double pfd_freq = target_pfd_freq; - bool feedback_divided = (_regs.feedback_select == max287x_regs_t::FEEDBACK_SELECT_DIVIDED); - - //increase RF divider until acceptable VCO frequency (MIN freq for MAX287x VCO is 3GHz) - UHD_ASSERT_THROW(target_freq > 0); - double vco_freq = target_freq; - while (vco_freq < MIN_VCO_FREQ) - { - vco_freq *= 2; - RFdiv *= 2; - } - - // The feedback frequency can be the fundamental VCO frequency or - // divided frequency. The output divider for MAX287x is actually - // 2 dividers, but only the first (1/2/4/8/16) is included in the - // feedback loop. - int fb_divisor = feedback_divided ? (RFdiv > 16 ? 16 : RFdiv) : 1; - - /* - * The goal here is to loop though possible R dividers, - * band select clock dividers, N (int) dividers, and FRAC - * (frac) dividers. - * - * Calculate the N and F dividers for each set of values. - * The loop exits when it meets all of the constraints. - * The resulting loop values are loaded into the registers. - * - * f_pfd = f_ref*(1+D)/(R*(1+T)) - * f_vco = (N + (FRAC/MOD))*f_pfd - * N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD - * f_rf = f_vco/RFdiv - */ - for(R = int(ref_freq*(1+D)/(target_pfd_freq*(1+T))); R <= r_range.stop(); R++) - { - //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T) - pfd_freq = ref_freq*(1+D)/(R*(1+T)); - - //keep the PFD frequency at or below target - if (pfd_freq > target_pfd_freq) - continue; - - //ignore fractional part of tuning - N = int((vco_freq/pfd_freq)/fb_divisor); - - //Fractional-N calculation - FRAC = int(boost::math::round(((vco_freq/pfd_freq)/fb_divisor - N)*MOD)); - - if(is_int_n) - { - if (FRAC > (MOD / 2)) //Round integer such that actual freq is closest to target - N++; - FRAC = 0; - } - - //keep N within int divider requirements - if(is_int_n) - { - if(N <= int_n_mode_div_range.start()) continue; - if(N >= int_n_mode_div_range.stop()) continue; - } - else - { - if(N <= frac_n_mode_div_range.start()) continue; - if(N >= frac_n_mode_div_range.stop()) continue; - } - - //keep pfd freq low enough to achieve 50kHz BS clock - BS = std::ceil(pfd_freq / BS_FREQ); - if(BS <= MAX_BS_VALUE) break; - } - UHD_ASSERT_THROW(R <= r_range.stop()); - - //Reference divide-by-2 for 50% duty cycle - // if R even, move one divide by 2 to to regs.reference_divide_by_2 - if(R % 2 == 0) - { - T = 1; - R /= 2; - } - - //actual frequency calculation - double actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))) * fb_divisor / RFdiv; - - UHD_LOGGER_TRACE("MAX287X") - << boost::format("MAX287x: Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") - % ref_freq % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) - << boost::format("MAX287x: tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, type=%s") - % R % BS % N % FRAC % MOD % T % D % RFdiv % ((is_int_n) ? "Integer-N" : "Fractional") - << boost::format("MAX287x: Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f") - % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) - ; - - //load the register values - _regs.rf_output_enable = max287x_regs_t::RF_OUTPUT_ENABLE_ENABLED; - - if(is_int_n) { - _regs.cpl = max287x_regs_t::CPL_DISABLED; - _regs.ldf = max287x_regs_t::LDF_INT_N; - _regs.int_n_mode = max287x_regs_t::INT_N_MODE_INT_N; - } else { - _regs.cpl = max287x_regs_t::CPL_ENABLED; - _regs.ldf = max287x_regs_t::LDF_FRAC_N; - _regs.int_n_mode = max287x_regs_t::INT_N_MODE_FRAC_N; - } - - _regs.lds = pfd_freq <= 32e6 ? max287x_regs_t::LDS_SLOW : max287x_regs_t::LDS_FAST; - - _regs.frac_12_bit = FRAC; - _regs.int_16_bit = N; - _regs.mod_12_bit = MOD; - _regs.clock_divider_12_bit = std::max(int(clock_div_range.start()), int(std::ceil(400e-6*pfd_freq/MOD))); - UHD_ASSERT_THROW(_regs.clock_divider_12_bit <= clock_div_range.stop()); - _regs.r_counter_10_bit = R; - _regs.reference_divide_by_2 = T ? - max287x_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED : - max287x_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; - _regs.reference_doubler = D ? - max287x_regs_t::REFERENCE_DOUBLER_ENABLED : - max287x_regs_t::REFERENCE_DOUBLER_DISABLED; - _regs.band_select_clock_div = BS & 0xFF; - _regs.bs_msb = (BS & 0x300) >> 8; - UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv)); - _regs.rf_divider_select = rfdivsel_to_enum[RFdiv]; - - if (_regs.clock_div_mode == max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK) - { - // Charge pump current needs to be set to lowest value in fast lock mode - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_32MA; - // Make sure the register containing the charge pump current is written - _write_all_regs = true; - } - - return actual_freq; -} - -template -void max287x::set_output_power(output_power_t power) -{ - switch (power) - { - case OUTPUT_POWER_M4DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_M4DBM; - break; - case OUTPUT_POWER_M1DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_M1DBM; - break; - case OUTPUT_POWER_2DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_2DBM; - break; - case OUTPUT_POWER_5DBM: - _regs.output_power = max287x_regs_t::OUTPUT_POWER_5DBM; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); - } -} - -template -void max287x::set_ld_pin_mode(ld_pin_mode_t mode) -{ - switch(mode) - { - case LD_PIN_MODE_LOW: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_LOW; - break; - case LD_PIN_MODE_DLD: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_DLD; - break; - case LD_PIN_MODE_ALD: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_ALD; - break; - case LD_PIN_MODE_HIGH: - _regs.ld_pin_mode = max287x_regs_t::LD_PIN_MODE_HIGH; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); - } -} - -template -void max287x::set_muxout_mode(muxout_mode_t mode) -{ - switch(mode) - { - case MUXOUT_TRI_STATE: - _regs.muxout = max287x_regs_t::MUXOUT_TRI_STATE; - break; - case MUXOUT_HIGH: - _regs.muxout = max287x_regs_t::MUXOUT_HIGH; - break; - case MUXOUT_LOW: - _regs.muxout = max287x_regs_t::MUXOUT_LOW; - break; - case MUXOUT_RDIV: - _regs.muxout = max287x_regs_t::MUXOUT_RDIV; - break; - case MUXOUT_NDIV: - _regs.muxout = max287x_regs_t::MUXOUT_NDIV; - break; - case MUXOUT_ALD: - _regs.muxout = max287x_regs_t::MUXOUT_ALD; - break; - case MUXOUT_DLD: - _regs.muxout = max287x_regs_t::MUXOUT_DLD; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); - } -} - -template -void max287x::set_charge_pump_current(charge_pump_current_t cp_current) -{ - switch(cp_current) - { - case CHARGE_PUMP_CURRENT_0_32MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_32MA; - break; - case CHARGE_PUMP_CURRENT_0_64MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_64MA; - break; - case CHARGE_PUMP_CURRENT_0_96MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_0_96MA; - break; - case CHARGE_PUMP_CURRENT_1_28MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_28MA; - break; - case CHARGE_PUMP_CURRENT_1_60MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_60MA; - break; - case CHARGE_PUMP_CURRENT_1_92MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_1_92MA; - break; - case CHARGE_PUMP_CURRENT_2_24MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_24MA; - break; - case CHARGE_PUMP_CURRENT_2_56MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_56MA; - break; - case CHARGE_PUMP_CURRENT_2_88MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_2_88MA; - break; - case CHARGE_PUMP_CURRENT_3_20MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_20MA; - break; - case CHARGE_PUMP_CURRENT_3_52MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_52MA; - break; - case CHARGE_PUMP_CURRENT_3_84MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_3_84MA; - break; - case CHARGE_PUMP_CURRENT_4_16MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_16MA; - break; - case CHARGE_PUMP_CURRENT_4_48MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_48MA; - break; - case CHARGE_PUMP_CURRENT_4_80MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_4_80MA; - break; - case CHARGE_PUMP_CURRENT_5_12MA: - _regs.charge_pump_current = max287x_regs_t::CHARGE_PUMP_CURRENT_5_12MA; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); - } -} - -template -void max287x::set_auto_retune(bool enabled) -{ - _regs.retune = enabled ? max287x_regs_t::RETUNE_ENABLED : max287x_regs_t::RETUNE_DISABLED; -} - -template <> -inline void max287x::set_auto_retune(bool enabled) -{ - _regs.retune = enabled ? max2871_regs_t::RETUNE_ENABLED : max2871_regs_t::RETUNE_DISABLED; - _regs.vas_dly = enabled ? max2871_regs_t::VAS_DLY_ENABLED : max2871_regs_t::VAS_DLY_DISABLED; -} - -template -void max287x::set_clock_divider_mode(clock_divider_mode_t mode) -{ - switch(mode) - { - case CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF: - _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF; - break; - case CLOCK_DIV_MODE_FAST_LOCK: - _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_FAST_LOCK; - break; - case CLOCK_DIV_MODE_PHASE: - _regs.clock_div_mode = max287x_regs_t::CLOCK_DIV_MODE_PHASE; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); - } -} - -template -void max287x::set_cycle_slip_mode(bool enabled) -{ - if (enabled) - throw uhd::runtime_error("Cycle slip mode not supported on this MAX287x synthesizer."); -} - -template -void max287x::set_low_noise_and_spur(low_noise_and_spur_t mode) -{ - switch(mode) - { - case LOW_NOISE_AND_SPUR_LOW_NOISE: - _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_NOISE; - break; - case LOW_NOISE_AND_SPUR_LOW_SPUR_1: - _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_1; - break; - case LOW_NOISE_AND_SPUR_LOW_SPUR_2: - _regs.low_noise_and_spur = max287x_regs_t::LOW_NOISE_AND_SPUR_LOW_SPUR_2; - break; - default: - UHD_THROW_INVALID_CODE_PATH(); - } -} - -template -void max287x::set_phase(uint16_t phase) -{ - _regs.phase_12_bit = phase & 0xFFF; -} - -template -void max287x::commit() -{ - std::vector regs; - std::set changed_regs; - - // Get only regs with changes - if (_write_all_regs) - { - for (int addr = 5; addr >= 0; addr--) - regs.push_back(_regs.get_reg(uint32_t(addr))); - } else { - try { - changed_regs = _regs.template get_changed_addrs (); - // register 0 must be written to apply double buffered fields - if (changed_regs.size() > 0) - { - changed_regs.insert(0); - } - - for (int addr = 5; addr >= 0; addr--) - { - if (changed_regs.find(uint32_t(addr)) != changed_regs.end()) - regs.push_back(_regs.get_reg(uint32_t(addr))); - } - } catch (uhd::runtime_error&) { - // No saved state - write all regs - for (int addr = 5; addr >= 0; addr--) - regs.push_back(_regs.get_reg(uint32_t(addr))); - } - } - - _write(regs); - _regs.save_state(); - _write_all_regs = false; - - if (_delay_after_write) - { - boost::this_thread::sleep(boost::posix_time::milliseconds(20)); - _delay_after_write = false; - } -} - -template -bool max287x::can_sync(void) -{ - return _can_sync; -} - -template -void max287x::config_for_sync(bool enable) -{ - _config_for_sync = enable; -} - -#endif // MAX287X_HPP_INCLUDED diff --git a/host/lib/usrp/common/recv_packet_demuxer.cpp b/host/lib/usrp/common/recv_packet_demuxer.cpp index 62d88d0ec..96eafa4be 100644 --- a/host/lib/usrp/common/recv_packet_demuxer.cpp +++ b/host/lib/usrp/common/recv_packet_demuxer.cpp @@ -5,12 +5,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "recv_packet_demuxer.hpp" +#include #include #include -#include #include #include + +#include #include #include #include diff --git a/host/lib/usrp/common/recv_packet_demuxer.hpp b/host/lib/usrp/common/recv_packet_demuxer.hpp deleted file mode 100644 index d158a919e..000000000 --- a/host/lib/usrp/common/recv_packet_demuxer.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright 2011,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_HPP -#define INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_HPP - -#include -#include -#include -#include - -namespace uhd{ namespace usrp{ - - class recv_packet_demuxer{ - public: - typedef boost::shared_ptr sptr; - - virtual ~recv_packet_demuxer(void) = 0; - - //! Make a new demuxer from a transport and parameters - static sptr make(transport::zero_copy_if::sptr transport, const size_t size, const uint32_t sid_base); - - //! Get a buffer at the given index from the transport - virtual transport::managed_recv_buffer::sptr get_recv_buff(const size_t index, const double timeout) = 0; - }; - -}} //namespace uhd::usrp - -#endif /* INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_HPP */ diff --git a/host/lib/usrp/common/recv_packet_demuxer_3000.hpp b/host/lib/usrp/common/recv_packet_demuxer_3000.hpp deleted file mode 100644 index 74807741f..000000000 --- a/host/lib/usrp/common/recv_packet_demuxer_3000.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// Copyright 2013,2017 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_3000_HPP -#define INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_3000_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace uhd{ namespace usrp{ - - struct recv_packet_demuxer_3000 : boost::enable_shared_from_this - { - typedef boost::shared_ptr sptr; - static sptr make(transport::zero_copy_if::sptr xport) - { - return sptr(new recv_packet_demuxer_3000(xport)); - } - - recv_packet_demuxer_3000(transport::zero_copy_if::sptr xport): - _xport(xport) - {/*NOP*/} - - transport::managed_recv_buffer::sptr get_recv_buff(const uint32_t sid, const double timeout) - { - const time_spec_t exit_time = - time_spec_t(timeout) + uhd::get_system_time(); - transport::managed_recv_buffer::sptr buff; - buff = _internal_get_recv_buff(sid, timeout); - while (not buff) //loop until timeout - { - const time_spec_t delta = exit_time - uhd::get_system_time(); - const double new_timeout = delta.get_real_secs(); - if (new_timeout < 0.0) break; - buff = _internal_get_recv_buff(sid, new_timeout); - } - return buff; - } - - transport::managed_recv_buffer::sptr _internal_get_recv_buff(const uint32_t sid, const double timeout) - { - transport::managed_recv_buffer::sptr buff; - - //---------------------------------------------------------- - //-- Check the queue to see if we already have a buffer - //---------------------------------------------------------- - { - boost::mutex::scoped_lock l(mutex); - queue_type_t &queue = _queues[sid]; - if (not queue.empty()) - { - buff = queue.front(); - queue.front().reset(); - queue.pop(); - return buff; - } - } - { - buff = _xport->get_recv_buff(timeout); - if (buff) - { - const uint32_t new_sid = uhd::wtohx(buff->cast()[1]); - if (new_sid != sid) - { - boost::mutex::scoped_lock l(mutex); - if (_queues.count(new_sid) == 0) UHD_LOGGER_ERROR("STREAMER") - << "recv packet demuxer unexpected sid 0x" << std::hex << new_sid << std::dec - ; - else _queues[new_sid].push(buff); - buff.reset(); - } - } - } - return buff; - } - - void realloc_sid(const uint32_t sid) - { - boost::mutex::scoped_lock l(mutex); - while(not _queues[sid].empty()) //allocated and clears if already allocated - { - _queues[sid].pop(); - } - } - - transport::zero_copy_if::sptr make_proxy(const uint32_t sid); - - typedef std::queue queue_type_t; - std::map _queues; - transport::zero_copy_if::sptr _xport; - boost::mutex mutex; - }; - - struct recv_packet_demuxer_proxy_3000 : transport::zero_copy_if - { - recv_packet_demuxer_proxy_3000(recv_packet_demuxer_3000::sptr demux, transport::zero_copy_if::sptr xport, const uint32_t sid): - _demux(demux), _xport(xport), _sid(sid) - { - _demux->realloc_sid(_sid); //causes clear - } - - ~recv_packet_demuxer_proxy_3000(void) - { - _demux->realloc_sid(_sid); //causes clear - } - - size_t get_num_recv_frames(void) const {return _xport->get_num_recv_frames();} - size_t get_recv_frame_size(void) const {return _xport->get_recv_frame_size();} - transport::managed_recv_buffer::sptr get_recv_buff(double timeout) - { - return _demux->get_recv_buff(_sid, timeout); - } - size_t get_num_send_frames(void) const {return _xport->get_num_send_frames();} - size_t get_send_frame_size(void) const {return _xport->get_send_frame_size();} - transport::managed_send_buffer::sptr get_send_buff(double timeout) - { - return _xport->get_send_buff(timeout); - } - - recv_packet_demuxer_3000::sptr _demux; - transport::zero_copy_if::sptr _xport; - const uint32_t _sid; - }; - - inline transport::zero_copy_if::sptr recv_packet_demuxer_3000::make_proxy(const uint32_t sid) - { - return transport::zero_copy_if::sptr(new recv_packet_demuxer_proxy_3000(this->shared_from_this(), _xport, sid)); - } - -}} //namespace uhd::usrp - -#endif /* INCLUDED_LIBUHD_USRP_COMMON_RECV_PACKET_DEMUXER_3000_HPP */ diff --git a/host/lib/usrp/common/validate_subdev_spec.cpp b/host/lib/usrp/common/validate_subdev_spec.cpp index 72e901929..369119e4a 100644 --- a/host/lib/usrp/common/validate_subdev_spec.cpp +++ b/host/lib/usrp/common/validate_subdev_spec.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "validate_subdev_spec.hpp" +#include #include #include #include diff --git a/host/lib/usrp/common/validate_subdev_spec.hpp b/host/lib/usrp/common/validate_subdev_spec.hpp deleted file mode 100644 index f2f3ce035..000000000 --- a/host/lib/usrp/common/validate_subdev_spec.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright 2011 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP -#define INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP - -#include -#include -#include -#include - -namespace uhd{ namespace usrp{ - - //! Validate a subdev spec against a property tree - void validate_subdev_spec( - property_tree::sptr tree, - const subdev_spec_t &spec, - const std::string &type, //rx or tx - const std::string &mb = "0" - ); - -}} //namespace uhd::usrp - -#endif /* INCLUDED_LIBUHD_USRP_COMMON_VALIDATE_SUBDEV_SPEC_HPP */ diff --git a/host/lib/usrp/cores/CMakeLists.txt b/host/lib/usrp/cores/CMakeLists.txt index 713c78a30..95102f29d 100644 --- a/host/lib/usrp/cores/CMakeLists.txt +++ b/host/lib/usrp/cores/CMakeLists.txt @@ -9,8 +9,6 @@ # This file included, use CMake directory variables ######################################################################## -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - IF(ENABLE_B100 OR ENABLE_USRP2) LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/gpio_core_200.cpp @@ -22,7 +20,6 @@ IF(ENABLE_B100 OR ENABLE_USRP2) ) ENDIF(ENABLE_B100 OR ENABLE_USRP2) - LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/dma_fifo_core_3000.cpp ${CMAKE_CURRENT_SOURCE_DIR}/dsp_core_utils.cpp diff --git a/host/lib/usrp/cores/dma_fifo_core_3000.cpp b/host/lib/usrp/cores/dma_fifo_core_3000.cpp index d2d190af1..618f81f64 100644 --- a/host/lib/usrp/cores/dma_fifo_core_3000.cpp +++ b/host/lib/usrp/cores/dma_fifo_core_3000.cpp @@ -5,12 +5,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "dma_fifo_core_3000.hpp" #include -#include //sleep #include #include +#include #include +#include //sleep + using namespace uhd; #define SR_DRAM_BIST_BASE 16 diff --git a/host/lib/usrp/cores/dma_fifo_core_3000.hpp b/host/lib/usrp/cores/dma_fifo_core_3000.hpp deleted file mode 100644 index db665a6c9..000000000 --- a/host/lib/usrp/cores/dma_fifo_core_3000.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright 2015 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP - -#include -#include -#include -#include - - -class dma_fifo_core_3000 : boost::noncopyable -{ -public: - typedef boost::shared_ptr sptr; - virtual ~dma_fifo_core_3000(void) = 0; - - /*! - * Create a DMA FIFO controller using the given bus, settings and readback base - * Throws uhd::runtime_error if a DMA FIFO is not instantiated in the FPGA - */ - static sptr make(uhd::wb_iface::sptr iface, const size_t set_base, const size_t rb_addr); - - /*! - * Check if a DMA FIFO is instantiated in the FPGA - */ - static bool check(uhd::wb_iface::sptr iface, const size_t set_base, const size_t rb_addr); - - /*! - * Flush the DMA FIFO. Will clear all contents. - */ - virtual void flush() = 0; - - /*! - * Resize and rebase the DMA FIFO. Will clear all contents. - */ - virtual void resize(const uint32_t base_addr, const uint32_t size) = 0; - - /*! - * Get the (approx) number of bytes currently in the DMA FIFO - */ - virtual uint32_t get_bytes_occupied() = 0; - - /*! - * Run the built-in-self-test routine for the DMA FIFO - */ - virtual uint8_t run_bist(bool finite = true, uint32_t timeout_ms = 500) = 0; - - /*! - * Is extended BIST supported - */ - virtual bool ext_bist_supported() = 0; - - /*! - * Run the built-in-self-test routine for the DMA FIFO (extended BIST only) - */ - virtual uint8_t run_ext_bist( - bool finite, - uint32_t rx_samp_delay, - uint32_t tx_pkt_delay, - uint32_t sid, - uint32_t timeout_ms = 500) = 0; - - /*! - * Get the throughput measured from the last invocation of the BIST (extended BIST only) - */ - virtual double get_bist_throughput() = 0; - -}; - -#endif /* INCLUDED_LIBUHD_USRP_DMA_FIFO_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/dsp_core_utils.cpp b/host/lib/usrp/cores/dsp_core_utils.cpp index a37fea3bc..282073597 100644 --- a/host/lib/usrp/cores/dsp_core_utils.cpp +++ b/host/lib/usrp/cores/dsp_core_utils.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "dsp_core_utils.hpp" #include #include +#include #include #include diff --git a/host/lib/usrp/cores/dsp_core_utils.hpp b/host/lib/usrp/cores/dsp_core_utils.hpp deleted file mode 100644 index 739b973cb..000000000 --- a/host/lib/usrp/cores/dsp_core_utils.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright 2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_DSP_CORE_UTILS_HPP -#define INCLUDED_LIBUHD_DSP_CORE_UTILS_HPP - -#include - -/*! For a requested frequency and sampling rate, return the - * correct frequency word (to set the CORDIC) and the actual frequency. - */ -void get_freq_and_freq_word( - const double requested_freq, - const double tick_rate, - double &actual_freq, - int32_t &freq_word -); - -#endif /* INCLUDED_LIBUHD_DSP_CORE_UTILS_HPP */ diff --git a/host/lib/usrp/cores/gpio_atr_3000.cpp b/host/lib/usrp/cores/gpio_atr_3000.cpp index 6e5df02ed..1cfbacfab 100644 --- a/host/lib/usrp/cores/gpio_atr_3000.cpp +++ b/host/lib/usrp/cores/gpio_atr_3000.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "gpio_atr_3000.hpp" #include #include +#include using namespace uhd; using namespace usrp; diff --git a/host/lib/usrp/cores/gpio_atr_3000.hpp b/host/lib/usrp/cores/gpio_atr_3000.hpp deleted file mode 100644 index 30c7d6fb7..000000000 --- a/host/lib/usrp/cores/gpio_atr_3000.hpp +++ /dev/null @@ -1,178 +0,0 @@ -// -// Copyright 2011,2014,2015 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP - -#include -#include -#include -#include -#include -#include - -namespace uhd { namespace usrp { namespace gpio_atr { - -class gpio_atr_3000 : boost::noncopyable { -public: - typedef boost::shared_ptr sptr; - - static const uint32_t MASK_SET_ALL = 0xFFFFFFFF; - - virtual ~gpio_atr_3000(void) {}; - - /*! - * Create a read-write GPIO ATR interface object - * - * \param iface register iface to GPIO ATR registers - * \param base base settings offset for GPIO ATR registers - * \param rb_addr readback offset for GPIO ATR registers - */ - static sptr make( - uhd::wb_iface::sptr iface, - const uhd::wb_iface::wb_addr_type base, - const uhd::wb_iface::wb_addr_type rb_addr); - - /*! - * Create a write-only GPIO ATR interface object - * - * \param iface register iface to GPIO ATR registers - * \param base base settings offset for GPIO ATR registers - */ - static sptr make_write_only( - uhd::wb_iface::sptr iface, const uhd::wb_iface::wb_addr_type base); - - /*! - * Select the ATR mode for all bits in the mask - * - * \param mode the mode to apply {ATR = outputs driven by ATR state machine, GPIO = outputs static} - * \param mask apply the mode to all non-zero bits in the mask - */ - virtual void set_atr_mode(const gpio_atr_mode_t mode, const uint32_t mask) = 0; - - /*! - * Select the data direction for all bits in the mask - * - * \param dir the direction {OUTPUT, INPUT} - * \param mask apply the mode to all non-zero bits in the mask - */ - virtual void set_gpio_ddr(const gpio_ddr_t dir, const uint32_t mask) = 0; - - /*! - * Write the specified (masked) value to the ATR register - * - * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX} - * \param value the value to write - * \param mask only writes to the bits where mask is non-zero - */ - virtual void set_atr_reg(const gpio_atr_reg_t atr, const uint32_t value, const uint32_t mask = MASK_SET_ALL) = 0; - - /*! - * Write to a static GPIO output - * - * \param value the value to write - * \param mask only writes to the bits where mask is non-zero - */ - virtual void set_gpio_out(const uint32_t value, const uint32_t mask = MASK_SET_ALL) = 0; - - /*! - * Read the state of the GPIO pins - * If a pin is configured as an input, reads the actual value of the pin - * If a pin is configured as an output, reads the last value written to the pin - * - * \return the value read back - */ - virtual uint32_t read_gpio() = 0; - - /*! - * Set a GPIO attribute - * - * \param attr the attribute to set - * \param value the value to write to the attribute - */ - virtual void set_gpio_attr(const gpio_attr_t attr, const uint32_t value) = 0; -}; - -class db_gpio_atr_3000 { -public: - typedef boost::shared_ptr sptr; - - typedef uhd::usrp::dboard_iface::unit_t db_unit_t; - - virtual ~db_gpio_atr_3000(void) {}; - - /*! - * Create a read-write GPIO ATR interface object for a daughterboard connector - * - * \param iface register iface to GPIO ATR registers - * \param base base settings offset for GPIO ATR registers - * \param rb_addr readback offset for GPIO ATR registers - */ - static sptr make( - uhd::wb_iface::sptr iface, - const uhd::wb_iface::wb_addr_type base, - const uhd::wb_iface::wb_addr_type rb_addr); - - /*! - * Configure the GPIO mode for all pins in the daughterboard connector - * - * \param unit the side of the daughterboard interface to configure (TX or RX) - * \param value if value[i] is 1, the i'th bit is in ATR mode otherwise it is in GPIO mode - * \param mask mask - */ - virtual void set_pin_ctrl(const db_unit_t unit, const uint32_t value, const uint32_t mask) = 0; - - virtual uint32_t get_pin_ctrl(const db_unit_t unit) = 0; - - /*! - * Configure the direction for all pins in the daughterboard connector - * - * \param unit the side of the daughterboard interface to configure (TX or RX) - * \param value if value[i] is 1, the i'th bit is an output otherwise it is an input - * \param mask mask - */ - virtual void set_gpio_ddr(const db_unit_t unit, const uint32_t value, const uint32_t mask) = 0; - - virtual uint32_t get_gpio_ddr(const db_unit_t unit) = 0; - - /*! - * Write the specified value to the ATR register (all bits) - * - * \param unit the side of the daughterboard interface to configure (TX or RX) - * \param atr the type of ATR register to write to {IDLE, RX, TX, FDX} - * \param value the value to write - * \param mask mask - */ - virtual void set_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr, const uint32_t value, const uint32_t mask) = 0; - - virtual uint32_t get_atr_reg(const db_unit_t unit, const gpio_atr_reg_t atr) = 0; - - /*! - * Write the specified value to the GPIO register (all bits) - * - * \param unit the side of the daughterboard interface to configure (TX or RX) - * \param value the value to write - * \param mask mask - */ - virtual void set_gpio_out(const db_unit_t unit, const uint32_t value, const uint32_t mask) = 0; - - virtual uint32_t get_gpio_out(const db_unit_t unit) = 0; - - /*! - * Read the state of the GPIO pins - * If a pin is configured as an input, reads the actual value of the pin - * If a pin is configured as an output, reads the last value written to the pin - * - * \param unit the side of the daughterboard interface to configure (TX or RX) - * \return the value read back - */ - virtual uint32_t read_gpio(const db_unit_t unit) = 0; -}; - -}}} //namespaces - -#endif /* INCLUDED_LIBUHD_USRP_GPIO_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/gpio_core_200.cpp b/host/lib/usrp/cores/gpio_core_200.cpp index 3cd3574e1..7df8e3c19 100644 --- a/host/lib/usrp/cores/gpio_core_200.cpp +++ b/host/lib/usrp/cores/gpio_core_200.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "gpio_core_200.hpp" #include +#include #define REG_GPIO_IDLE _base + 0 #define REG_GPIO_RX_ONLY _base + 4 diff --git a/host/lib/usrp/cores/gpio_core_200.hpp b/host/lib/usrp/cores/gpio_core_200.hpp deleted file mode 100644 index d5dff890e..000000000 --- a/host/lib/usrp/cores/gpio_core_200.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright 2011,2014,2015 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_GPIO_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_GPIO_CORE_200_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class gpio_core_200 : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - typedef uhd::usrp::dboard_iface::unit_t unit_t; - typedef uhd::usrp::dboard_iface::atr_reg_t atr_reg_t; - - virtual ~gpio_core_200(void) = 0; - - //! makes a new GPIO core from iface and slave base - static sptr make( - uhd::wb_iface::sptr iface, const size_t base, const size_t rb_addr); - - //! 1 = ATR - virtual void set_pin_ctrl( - const unit_t unit, const uint16_t value, const uint16_t mask) = 0; - - virtual uint16_t get_pin_ctrl(unit_t unit) = 0; - - virtual void set_atr_reg( - const unit_t unit, const atr_reg_t atr, const uint16_t value, const uint16_t mask) = 0; - - virtual uint16_t get_atr_reg(unit_t unit, atr_reg_t reg) = 0; - - //! 1 = OUTPUT - virtual void set_gpio_ddr( - const unit_t unit, const uint16_t value, const uint16_t mask) = 0; - - virtual uint16_t get_gpio_ddr(unit_t unit) = 0; - - virtual void set_gpio_out( - const unit_t unit, const uint16_t value, const uint16_t mask) = 0; - - virtual uint16_t get_gpio_out(unit_t unit) = 0; - - virtual uint16_t read_gpio(const unit_t unit) = 0; -}; - -//! Simple wrapper for 32 bit write only -class gpio_core_200_32wo : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - typedef uhd::usrp::dboard_iface::atr_reg_t atr_reg_t; - - virtual ~gpio_core_200_32wo(void) = 0; - - static sptr make(uhd::wb_iface::sptr iface, const size_t); - - virtual void set_ddr_reg() = 0; - - virtual void set_atr_reg(const atr_reg_t atr, const uint32_t value) = 0; - - virtual void set_all_regs(const uint32_t value) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_GPIO_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/i2c_core_100_wb32.cpp b/host/lib/usrp/cores/i2c_core_100_wb32.cpp index 3f037f519..c6a0e8d84 100644 --- a/host/lib/usrp/cores/i2c_core_100_wb32.cpp +++ b/host/lib/usrp/cores/i2c_core_100_wb32.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "i2c_core_100_wb32.hpp" #include #include +#include #include //sleep #define REG_I2C_PRESCALER_LO _base + 0 diff --git a/host/lib/usrp/cores/i2c_core_100_wb32.hpp b/host/lib/usrp/cores/i2c_core_100_wb32.hpp deleted file mode 100644 index 6c4182544..000000000 --- a/host/lib/usrp/cores/i2c_core_100_wb32.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright 2011-2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_I2C_CORE_100_WB32_HPP -#define INCLUDED_LIBUHD_USRP_I2C_CORE_100_WB32_HPP - -#include -#include -#include -#include -#include - -class i2c_core_100_wb32 : boost::noncopyable, public uhd::i2c_iface{ -public: - typedef boost::shared_ptr sptr; - - virtual ~i2c_core_100_wb32(void) = 0; - - //! makes a new i2c core from iface and slave base - static sptr make(uhd::wb_iface::sptr iface, const size_t base); - - virtual void set_clock_rate(const double rate) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_I2C_CORE_100_WB32_HPP */ diff --git a/host/lib/usrp/cores/i2c_core_200.cpp b/host/lib/usrp/cores/i2c_core_200.cpp index ce98f7512..c0a6cb949 100644 --- a/host/lib/usrp/cores/i2c_core_200.cpp +++ b/host/lib/usrp/cores/i2c_core_200.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "i2c_core_200.hpp" #include #include +#include #include //sleep #include diff --git a/host/lib/usrp/cores/i2c_core_200.hpp b/host/lib/usrp/cores/i2c_core_200.hpp deleted file mode 100644 index 354244891..000000000 --- a/host/lib/usrp/cores/i2c_core_200.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright 2011-2012,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_I2C_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_I2C_CORE_200_HPP - -#include -#include -#include -#include -#include - -class i2c_core_200 : boost::noncopyable, public uhd::i2c_iface{ -public: - typedef boost::shared_ptr sptr; - - virtual ~i2c_core_200(void) = 0; - - //! makes a new i2c core from iface and slave base - static sptr make(uhd::wb_iface::sptr iface, const size_t base, const size_t readback); -}; - -#endif /* INCLUDED_LIBUHD_USRP_I2C_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp index 631291d18..fe4a01b35 100644 --- a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp +++ b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp @@ -5,14 +5,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "radio_ctrl_core_3000.hpp" -#include "async_packet_handler.hpp" #include #include #include #include #include #include +#include +#include #include #include #include diff --git a/host/lib/usrp/cores/radio_ctrl_core_3000.hpp b/host/lib/usrp/cores/radio_ctrl_core_3000.hpp deleted file mode 100644 index f7be7ef91..000000000 --- a/host/lib/usrp/cores/radio_ctrl_core_3000.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2012-2015 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP -#define INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP - -#include -#include -#include -#include -#include -#include -#include - -/*! - * Provide access to peek, poke for the radio ctrl module - */ -class radio_ctrl_core_3000 : public uhd::timed_wb_iface -{ -public: - typedef boost::shared_ptr sptr; - - virtual ~radio_ctrl_core_3000(void) = 0; - - //! Make a new control object - static sptr make( - const bool big_endian, - uhd::transport::zero_copy_if::sptr ctrl_xport, - uhd::transport::zero_copy_if::sptr resp_xport, - const uint32_t sid, - const std::string &name = "0" - ); - - //! Hold a ref to a task thats feeding push response - virtual void hold_task(uhd::msg_task::sptr task) = 0; - - //! Push a response externall (resp_xport is NULL) - virtual void push_response(const uint32_t *buff) = 0; - - //! Set the command time that will activate - virtual void set_time(const uhd::time_spec_t &time) = 0; - - //! Get the command time that will activate - virtual uhd::time_spec_t get_time(void) = 0; - - //! Set the tick rate (converting time into ticks) - virtual void set_tick_rate(const double rate) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_RADIO_CTRL_3000_HPP */ diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index 723c96de0..730985fdd 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -5,13 +5,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "rx_dsp_core_200.hpp" -#include "dsp_core_utils.hpp" #include #include #include #include #include +#include +#include #include #include //thread sleep #include diff --git a/host/lib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/usrp/cores/rx_dsp_core_200.hpp deleted file mode 100644 index e9b6b98cf..000000000 --- a/host/lib/usrp/cores/rx_dsp_core_200.hpp +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright 2011,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -class rx_dsp_core_200 : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - virtual ~rx_dsp_core_200(void) = 0; - - static sptr make( - uhd::wb_iface::sptr iface, - const size_t dsp_base, const size_t ctrl_base, - const uint32_t sid, const bool lingering_packet = false - ); - - virtual void clear(void) = 0; - - virtual void set_nsamps_per_packet(const size_t nsamps) = 0; - - virtual void issue_stream_command(const uhd::stream_cmd_t &stream_cmd) = 0; - - virtual void set_mux(const std::string &mode, const bool fe_swapped = false) = 0; - - virtual void set_tick_rate(const double rate) = 0; - - virtual void set_link_rate(const double rate) = 0; - - virtual double set_host_rate(const double rate) = 0; - - virtual uhd::meta_range_t get_host_rates(void) = 0; - - virtual double get_scaling_adjustment(void) = 0; - - virtual uhd::meta_range_t get_freq_range(void) = 0; - - virtual double set_freq(const double freq) = 0; - - virtual void handle_overflow(void) = 0; - - virtual void setup(const uhd::stream_args_t &stream_args) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.cpp b/host/lib/usrp/cores/rx_dsp_core_3000.cpp index bfe3fdab3..27fc760af 100644 --- a/host/lib/usrp/cores/rx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_3000.cpp @@ -5,13 +5,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "rx_dsp_core_3000.hpp" -#include "dsp_core_utils.hpp" #include #include #include #include #include +#include +#include #include #include //thread sleep #include diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.hpp b/host/lib/usrp/cores/rx_dsp_core_3000.hpp deleted file mode 100644 index 0fba8ed65..000000000 --- a/host/lib/usrp/cores/rx_dsp_core_3000.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright 2011-2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_RX_DSP_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_RX_DSP_CORE_3000_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class rx_dsp_core_3000 : boost::noncopyable{ -public: - static const double DEFAULT_CORDIC_FREQ; - static const double DEFAULT_RATE; - - typedef boost::shared_ptr sptr; - - virtual ~rx_dsp_core_3000(void) = 0; - - static sptr make( - uhd::wb_iface::sptr iface, - const size_t dsp_base, - const bool is_b200 = false //TODO: Obsolete this when we switch to the new DDC on the B200 - ); - - virtual void set_mux(const uhd::usrp::fe_connection_t& fe_conn) = 0; - - virtual void set_tick_rate(const double rate) = 0; - - virtual void set_link_rate(const double rate) = 0; - - virtual double set_host_rate(const double rate) = 0; - - virtual uhd::meta_range_t get_host_rates(void) = 0; - - virtual double get_scaling_adjustment(void) = 0; - - virtual uhd::meta_range_t get_freq_range(void) = 0; - - virtual double set_freq(const double freq) = 0; - - virtual void setup(const uhd::stream_args_t &stream_args) = 0; - - virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_RX_DSP_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/rx_frontend_core_200.cpp b/host/lib/usrp/cores/rx_frontend_core_200.cpp index 2b7fac2d8..38710db15 100644 --- a/host/lib/usrp/cores/rx_frontend_core_200.cpp +++ b/host/lib/usrp/cores/rx_frontend_core_200.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "rx_frontend_core_200.hpp" +#include #include #include diff --git a/host/lib/usrp/cores/rx_frontend_core_200.hpp b/host/lib/usrp/cores/rx_frontend_core_200.hpp deleted file mode 100644 index c4848bde2..000000000 --- a/host/lib/usrp/cores/rx_frontend_core_200.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright 2011,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP - -#include -#include -#include -#include -#include -#include -#include - -class rx_frontend_core_200 : boost::noncopyable{ -public: - static const std::complex DEFAULT_DC_OFFSET_VALUE; - static const bool DEFAULT_DC_OFFSET_ENABLE; - static const std::complex DEFAULT_IQ_BALANCE_VALUE; - - typedef boost::shared_ptr sptr; - - virtual ~rx_frontend_core_200(void) = 0; - - static sptr make(uhd::wb_iface::sptr iface, const size_t base); - - virtual void set_mux(const bool swap) = 0; - - virtual void set_dc_offset_auto(const bool enb) = 0; - - virtual std::complex set_dc_offset(const std::complex &off) = 0; - - virtual void set_iq_balance(const std::complex &cor) = 0; - - virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; - -}; - -#endif /* INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/rx_frontend_core_3000.cpp b/host/lib/usrp/cores/rx_frontend_core_3000.cpp index 92a3aacfe..cf1a105d8 100644 --- a/host/lib/usrp/cores/rx_frontend_core_3000.cpp +++ b/host/lib/usrp/cores/rx_frontend_core_3000.cpp @@ -5,12 +5,12 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "rx_frontend_core_3000.hpp" -#include "dsp_core_utils.hpp" +#include +#include +#include #include #include #include -#include using namespace uhd; diff --git a/host/lib/usrp/cores/rx_frontend_core_3000.hpp b/host/lib/usrp/cores/rx_frontend_core_3000.hpp deleted file mode 100644 index e425e51a4..000000000 --- a/host/lib/usrp/cores/rx_frontend_core_3000.hpp +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright 2011,2014-2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_3000_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -class rx_frontend_core_3000 : boost::noncopyable{ -public: - static const std::complex DEFAULT_DC_OFFSET_VALUE; - static const bool DEFAULT_DC_OFFSET_ENABLE; - static const std::complex DEFAULT_IQ_BALANCE_VALUE; - - typedef boost::shared_ptr sptr; - - virtual ~rx_frontend_core_3000(void) = 0; - - static sptr make(uhd::wb_iface::sptr iface, const size_t base); - - /*! Set the input sampling rate (i.e. ADC rate) - */ - virtual void set_adc_rate(const double rate) = 0; - - virtual void bypass_all(bool bypass_en) = 0; - - virtual void set_fe_connection(const uhd::usrp::fe_connection_t& fe_conn) = 0; - - virtual void set_dc_offset_auto(const bool enb) = 0; - - virtual std::complex set_dc_offset(const std::complex &off) = 0; - - virtual void set_iq_balance(const std::complex &cor) = 0; - - virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; - - /*! Return the sampling rate at the output - * - * In real mode, the frontend core will decimate the sampling rate by a - * factor of 2. - * - * \returns RX sampling rate - */ - virtual double get_output_rate(void) = 0; - -}; - -#endif /* INCLUDED_LIBUHD_USRP_TX_FRONTEND_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/rx_vita_core_3000.cpp b/host/lib/usrp/cores/rx_vita_core_3000.cpp index 44fa63441..1572266a5 100644 --- a/host/lib/usrp/cores/rx_vita_core_3000.cpp +++ b/host/lib/usrp/cores/rx_vita_core_3000.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "rx_vita_core_3000.hpp" #include #include +#include #include #include #include diff --git a/host/lib/usrp/cores/rx_vita_core_3000.hpp b/host/lib/usrp/cores/rx_vita_core_3000.hpp deleted file mode 100644 index 919631300..000000000 --- a/host/lib/usrp/cores/rx_vita_core_3000.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright 2013,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_RX_VITA_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_RX_VITA_CORE_3000_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -class rx_vita_core_3000 : boost::noncopyable -{ -public: - typedef boost::shared_ptr sptr; - - virtual ~rx_vita_core_3000(void) = 0; - - static sptr make( - uhd::wb_iface::sptr iface, - const size_t base - ); - - virtual void clear(void) = 0; - - virtual void set_nsamps_per_packet(const size_t nsamps) = 0; - - virtual void issue_stream_command(const uhd::stream_cmd_t &stream_cmd) = 0; - - virtual void set_tick_rate(const double rate) = 0; - - virtual void set_sid(const uint32_t sid) = 0; - - virtual void handle_overflow(void) = 0; - - virtual void setup(const uhd::stream_args_t &stream_args) = 0; - - virtual void configure_flow_control(const size_t window_size) = 0; - - virtual bool in_continuous_streaming_mode(void) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_RX_VITA_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/spi_core_3000.cpp b/host/lib/usrp/cores/spi_core_3000.cpp index 5ec1079b6..f4b42f26d 100644 --- a/host/lib/usrp/cores/spi_core_3000.cpp +++ b/host/lib/usrp/cores/spi_core_3000.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "spi_core_3000.hpp" #include #include +#include #include //sleep #define SPI_DIV _base + 0 diff --git a/host/lib/usrp/cores/spi_core_3000.hpp b/host/lib/usrp/cores/spi_core_3000.hpp deleted file mode 100644 index ea0507754..000000000 --- a/host/lib/usrp/cores/spi_core_3000.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright 2013-2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_SPI_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_SPI_CORE_3000_HPP - -#include -#include -#include -#include -#include - -class spi_core_3000 : boost::noncopyable, public uhd::spi_iface -{ -public: - typedef boost::shared_ptr sptr; - - virtual ~spi_core_3000(void) = 0; - - //! makes a new spi core from iface and slave base - static sptr make(uhd::wb_iface::sptr iface, const size_t base, const size_t readback); - - //! Set the spi clock divider to something usable - virtual void set_divider(const double div) = 0; - - //! Place SPI core in shutdown mode. All attempted SPI transactions are dropped by - // the core. - virtual void set_shutdown(const bool shutdown) = 0; - - //! Get state of shutdown register - virtual bool get_shutdown() = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_SPI_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/time64_core_200.cpp b/host/lib/usrp/cores/time64_core_200.cpp index 27d395778..09fa92dcd 100644 --- a/host/lib/usrp/cores/time64_core_200.cpp +++ b/host/lib/usrp/cores/time64_core_200.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "time64_core_200.hpp" #include #include +#include #include #define REG_TIME64_TICKS_HI _base + 0 diff --git a/host/lib/usrp/cores/time64_core_200.hpp b/host/lib/usrp/cores/time64_core_200.hpp deleted file mode 100644 index 23e0da922..000000000 --- a/host/lib/usrp/cores/time64_core_200.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright 2011-2012,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP - -#include -#include -#include -#include -#include -#include -#include - -class time64_core_200 : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - struct readback_bases_type{ - size_t rb_hi_now, rb_lo_now; - size_t rb_hi_pps, rb_lo_pps; - }; - - virtual ~time64_core_200(void) = 0; - - //! makes a new time64 core from iface and slave base - static sptr make( - uhd::wb_iface::sptr iface, const size_t base, - const readback_bases_type &readback_bases, - const size_t mimo_delay_cycles = 0 // 0 means no-mimo - ); - - virtual void enable_gpsdo(void) = 0; - - virtual void set_tick_rate(const double rate) = 0; - - virtual uhd::time_spec_t get_time_now(void) = 0; - - virtual uhd::time_spec_t get_time_last_pps(void) = 0; - - virtual void set_time_now(const uhd::time_spec_t &time) = 0; - - virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0; - - virtual void set_time_source(const std::string &source) = 0; - - virtual std::vector get_time_sources(void) = 0; - -}; - -#endif /* INCLUDED_LIBUHD_USRP_TIME64_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/time_core_3000.cpp b/host/lib/usrp/cores/time_core_3000.cpp index a56b233fe..14636edec 100644 --- a/host/lib/usrp/cores/time_core_3000.cpp +++ b/host/lib/usrp/cores/time_core_3000.cpp @@ -5,9 +5,9 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "time_core_3000.hpp" #include #include +#include #include #define REG_TIME_HI _base + 0 diff --git a/host/lib/usrp/cores/time_core_3000.hpp b/host/lib/usrp/cores/time_core_3000.hpp deleted file mode 100644 index 4fa2ae657..000000000 --- a/host/lib/usrp/cores/time_core_3000.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright 2013-2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_TIME_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_TIME_CORE_3000_HPP - -#include -#include -#include -#include -#include - -class time_core_3000 : boost::noncopyable -{ -public: - typedef boost::shared_ptr sptr; - - struct readback_bases_type - { - size_t rb_now; - size_t rb_pps; - }; - - virtual ~time_core_3000(void) = 0; - - //! makes a new time core from iface and slave base - static sptr make( - uhd::wb_iface::sptr iface, const size_t base, - const readback_bases_type &readback_bases - ); - - virtual void self_test(void) = 0; - - virtual void set_tick_rate(const double rate) = 0; - - virtual uhd::time_spec_t get_time_now(void) = 0; - - virtual uhd::time_spec_t get_time_last_pps(void) = 0; - - virtual void set_time_now(const uhd::time_spec_t &time) = 0; - - virtual void set_time_sync(const uhd::time_spec_t &time) = 0; - - virtual void set_time_next_pps(const uhd::time_spec_t &time) = 0; - -}; - -#endif /* INCLUDED_LIBUHD_USRP_TIME_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 7d11cbb91..efd64f7e5 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "tx_dsp_core_200.hpp" -#include "dsp_core_utils.hpp" +#include +#include #include #include #include diff --git a/host/lib/usrp/cores/tx_dsp_core_200.hpp b/host/lib/usrp/cores/tx_dsp_core_200.hpp deleted file mode 100644 index 98e8b5225..000000000 --- a/host/lib/usrp/cores/tx_dsp_core_200.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright 2011,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP - -#include -#include -#include -#include -#include -#include - -class tx_dsp_core_200 : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - virtual ~tx_dsp_core_200(void) = 0; - - static sptr make( - uhd::wb_iface::sptr iface, - const size_t dsp_base, const size_t ctrl_base, - const uint32_t sid - ); - - virtual void clear(void) = 0; - - virtual void set_tick_rate(const double rate) = 0; - - virtual void set_link_rate(const double rate) = 0; - - virtual double set_host_rate(const double rate) = 0; - - virtual uhd::meta_range_t get_host_rates(void) = 0; - - virtual double get_scaling_adjustment(void) = 0; - - virtual uhd::meta_range_t get_freq_range(void) = 0; - - virtual double set_freq(const double freq) = 0; - - virtual void set_updates(const size_t cycles_per_up, const size_t packets_per_up) = 0; - - virtual void setup(const uhd::stream_args_t &stream_args) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/tx_dsp_core_3000.cpp b/host/lib/usrp/cores/tx_dsp_core_3000.cpp index 1afa73eed..b04a20497 100644 --- a/host/lib/usrp/cores/tx_dsp_core_3000.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_3000.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "tx_dsp_core_3000.hpp" -#include "dsp_core_utils.hpp" +#include +#include #include #include #include diff --git a/host/lib/usrp/cores/tx_dsp_core_3000.hpp b/host/lib/usrp/cores/tx_dsp_core_3000.hpp deleted file mode 100644 index 3eb53da0d..000000000 --- a/host/lib/usrp/cores/tx_dsp_core_3000.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright 2011-2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_TX_DSP_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_TX_DSP_CORE_3000_HPP - -#include -#include -#include -#include -#include -#include -#include - -class tx_dsp_core_3000 : boost::noncopyable{ -public: - static const double DEFAULT_CORDIC_FREQ; - static const double DEFAULT_RATE; - - typedef boost::shared_ptr sptr; - - virtual ~tx_dsp_core_3000(void) = 0; - - static sptr make( - uhd::wb_iface::sptr iface, - const size_t dsp_base - ); - - virtual void set_tick_rate(const double rate) = 0; - - virtual void set_link_rate(const double rate) = 0; - - virtual double set_host_rate(const double rate) = 0; - - virtual uhd::meta_range_t get_host_rates(void) = 0; - - virtual double get_scaling_adjustment(void) = 0; - - virtual uhd::meta_range_t get_freq_range(void) = 0; - - virtual double set_freq(const double freq) = 0; - - virtual void setup(const uhd::stream_args_t &stream_args) = 0; - - virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_TX_DSP_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/tx_frontend_core_200.cpp b/host/lib/usrp/cores/tx_frontend_core_200.cpp index 92c44602c..7e23e2515 100644 --- a/host/lib/usrp/cores/tx_frontend_core_200.cpp +++ b/host/lib/usrp/cores/tx_frontend_core_200.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "tx_frontend_core_200.hpp" +#include #include #include #include diff --git a/host/lib/usrp/cores/tx_frontend_core_200.hpp b/host/lib/usrp/cores/tx_frontend_core_200.hpp deleted file mode 100644 index eb86bf85d..000000000 --- a/host/lib/usrp/cores/tx_frontend_core_200.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright 2011,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP - -#include -#include -#include -#include -#include -#include -#include - -class tx_frontend_core_200 : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - - static const std::complex DEFAULT_DC_OFFSET_VALUE; - static const std::complex DEFAULT_IQ_BALANCE_VALUE; - - virtual ~tx_frontend_core_200(void) = 0; - - static sptr make(uhd::wb_iface::sptr iface, const size_t base); - - virtual void set_mux(const std::string &mode) = 0; - - virtual std::complex set_dc_offset(const std::complex &off) = 0; - - virtual void set_iq_balance(const std::complex &cor) = 0; - - virtual void populate_subtree(uhd::property_tree::sptr subtree) = 0; - -}; - -#endif /* INCLUDED_LIBUHD_USRP_RX_FRONTEND_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/tx_vita_core_3000.cpp b/host/lib/usrp/cores/tx_vita_core_3000.cpp index e398f065d..689a6cf45 100644 --- a/host/lib/usrp/cores/tx_vita_core_3000.cpp +++ b/host/lib/usrp/cores/tx_vita_core_3000.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "tx_vita_core_3000.hpp" #include +#include #define REG_CTRL_ERROR_POLICY (_base + 0) #define REG_FC_PRE_RADIO_RESP_BASE (_base + 2*4) diff --git a/host/lib/usrp/cores/tx_vita_core_3000.hpp b/host/lib/usrp/cores/tx_vita_core_3000.hpp deleted file mode 100644 index 4d33bb0c2..000000000 --- a/host/lib/usrp/cores/tx_vita_core_3000.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright 2013-2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_TX_VITA_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_TX_VITA_CORE_3000_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -class tx_vita_core_3000 : boost::noncopyable -{ -public: - typedef boost::shared_ptr sptr; - - enum fc_monitor_loc { - FC_DEFAULT, - FC_PRE_RADIO, - FC_PRE_FIFO - }; - - virtual ~tx_vita_core_3000(void) = 0; - - static sptr make( - uhd::wb_iface::sptr iface, - const size_t base, - fc_monitor_loc fc_location = FC_PRE_RADIO - ); - - static sptr make_no_radio_buff( - uhd::wb_iface::sptr iface, - const size_t base - ); - - virtual void clear(void) = 0; - - virtual void setup(const uhd::stream_args_t &stream_args) = 0; - - virtual void configure_flow_control(const size_t cycs_per_up, const size_t pkts_per_up) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_TX_VITA_CORE_3000_HPP */ diff --git a/host/lib/usrp/cores/user_settings_core_200.cpp b/host/lib/usrp/cores/user_settings_core_200.cpp index 9b8a0bd5f..7de18d11c 100644 --- a/host/lib/usrp/cores/user_settings_core_200.cpp +++ b/host/lib/usrp/cores/user_settings_core_200.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "user_settings_core_200.hpp" +#include using namespace uhd; diff --git a/host/lib/usrp/cores/user_settings_core_200.hpp b/host/lib/usrp/cores/user_settings_core_200.hpp deleted file mode 100644 index 354b5e637..000000000 --- a/host/lib/usrp/cores/user_settings_core_200.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright 2012,2014 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP -#define INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP - -#include -#include -#include -#include - -class user_settings_core_200 : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - typedef std::pair user_reg_t; - - virtual ~user_settings_core_200(void) = 0; - - static sptr make(uhd::wb_iface::sptr iface, const size_t base); - - virtual void set_reg(const user_reg_t ®) = 0; -}; - -#endif /* INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_200_HPP */ diff --git a/host/lib/usrp/cores/user_settings_core_3000.cpp b/host/lib/usrp/cores/user_settings_core_3000.cpp index 10650d6b6..66baed57a 100644 --- a/host/lib/usrp/cores/user_settings_core_3000.cpp +++ b/host/lib/usrp/cores/user_settings_core_3000.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "user_settings_core_3000.hpp" +#include #include #include diff --git a/host/lib/usrp/cores/user_settings_core_3000.hpp b/host/lib/usrp/cores/user_settings_core_3000.hpp deleted file mode 100644 index bc281e396..000000000 --- a/host/lib/usrp/cores/user_settings_core_3000.hpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright 2012 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP -#define INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP - -#include -#include -#include -#include - -class user_settings_core_3000 : public uhd::wb_iface { -public: - virtual ~user_settings_core_3000() {} - - static sptr make( - wb_iface::sptr iface, - const wb_addr_type sr_base_addr, const wb_addr_type rb_reg_addr); -}; - -#endif /* INCLUDED_LIBUHD_USRP_USER_SETTINGS_CORE_3000_HPP */ diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp index 1098c44f8..4d463603f 100644 --- a/host/lib/usrp/dboard/db_sbx_common.hpp +++ b/host/lib/usrp/dboard/db_sbx_common.hpp @@ -6,8 +6,8 @@ // #include -#include "adf435x.hpp" -#include "max287x.hpp" +#include +#include // LO Related #define ADF435X_CE (1 << 3) diff --git a/host/lib/usrp/dboard/db_twinrx.cpp b/host/lib/usrp/dboard/db_twinrx.cpp index d1ee97e90..0d14c7632 100644 --- a/host/lib/usrp/dboard/db_twinrx.cpp +++ b/host/lib/usrp/dboard/db_twinrx.cpp @@ -9,7 +9,8 @@ #include "twinrx/twinrx_ctrl.hpp" #include "twinrx/twinrx_io.hpp" #include "twinrx/twinrx_ids.hpp" -#include + +#include #include #include #include diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp index b55a6c22a..7b153d170 100644 --- a/host/lib/usrp/dboard/db_ubx.cpp +++ b/host/lib/usrp/dboard/db_ubx.cpp @@ -16,9 +16,10 @@ #include #include #include - #include #include +#include + #include #include #include @@ -26,7 +27,6 @@ #include #include #include -#include "max287x.hpp" using namespace uhd; using namespace uhd::usrp; diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp index 6c47ed5d0..ea012c91c 100644 --- a/host/lib/usrp/dboard/db_wbx_common.hpp +++ b/host/lib/usrp/dboard/db_wbx_common.hpp @@ -9,7 +9,7 @@ #define INCLUDED_LIBUHD_USRP_DBOARD_DB_WBX_COMMON_HPP #include -#include "adf435x.hpp" +#include // LO Related #define ADF435X_CE (1 << 3) diff --git a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp index 33548c5f7..959e5aa74 100644 --- a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp @@ -7,9 +7,9 @@ #ifndef INCLUDED_LIBUHD_RFNOC_EISCAT_RADIO_CTRL_IMPL_HPP #define INCLUDED_LIBUHD_RFNOC_EISCAT_RADIO_CTRL_IMPL_HPP -#include "radio_ctrl_impl.hpp" -#include "rpc_block_ctrl.hpp" #include +#include +#include namespace uhd { namespace rfnoc { diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp index 332414ef1..5da9e68e5 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp @@ -7,8 +7,8 @@ #ifndef INCLUDED_LIBUHD_RFNOC_MAGNESIUM_AD9371_IFACE_HPP #define INCLUDED_LIBUHD_RFNOC_MAGNESIUM_AD9371_IFACE_HPP -#include "../../../utils/rpc.hpp" #include +#include #include #include diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp index a429cd058..27c5db240 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp @@ -7,16 +7,16 @@ #ifndef INCLUDED_LIBUHD_RFNOC_MAGNESIUM_RADIO_CTRL_IMPL_HPP #define INCLUDED_LIBUHD_RFNOC_MAGNESIUM_RADIO_CTRL_IMPL_HPP -#include "radio_ctrl_impl.hpp" -#include "rpc_block_ctrl.hpp" #include "magnesium_cpld_ctrl.hpp" #include "magnesium_cpld_regs.hpp" #include "magnesium_ad9371_iface.hpp" -#include "adf435x.hpp" -#include "gpio_atr_3000.hpp" #include #include #include +#include +#include +#include +#include #include namespace uhd { diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp index f89b26de2..a95343574 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp @@ -6,11 +6,11 @@ #include "magnesium_radio_ctrl_impl.hpp" #include "magnesium_constants.hpp" -#include "spi_core_3000.hpp" #include #include #include #include +#include #include #include #include diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp index 8f394f997..3e8473087 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp @@ -6,8 +6,8 @@ #include "twinrx_ctrl.hpp" #include "twinrx_ids.hpp" -#include "adf435x.hpp" -#include "adf535x.hpp" +#include +#include #include #include #include diff --git a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp index e346d3d08..c070765d9 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_experts.hpp @@ -9,7 +9,7 @@ #define INCLUDED_DBOARD_TWINRX_EXPERTS_HPP #include "twinrx_ctrl.hpp" -#include "expert_nodes.hpp" +#include #include namespace uhd { namespace usrp { namespace dboard { namespace twinrx { diff --git a/host/lib/usrp/dboard/twinrx/twinrx_io.hpp b/host/lib/usrp/dboard/twinrx/twinrx_io.hpp index 3ff497ab4..c9665f1dd 100644 --- a/host/lib/usrp/dboard/twinrx/twinrx_io.hpp +++ b/host/lib/usrp/dboard/twinrx/twinrx_io.hpp @@ -11,8 +11,8 @@ #include #include #include +#include #include -#include "gpio_atr_3000.hpp" namespace uhd { namespace usrp { namespace dboard { namespace twinrx { diff --git a/host/lib/usrp/device3/device3_impl.cpp b/host/lib/usrp/device3/device3_impl.cpp index 7792a4b73..d4ea8a19f 100644 --- a/host/lib/usrp/device3/device3_impl.cpp +++ b/host/lib/usrp/device3/device3_impl.cpp @@ -6,10 +6,10 @@ // #include "device3_impl.hpp" -#include "graph_impl.hpp" -#include "ctrl_iface.hpp" #include #include +#include +#include #include #include diff --git a/host/lib/usrp/device3/device3_impl.hpp b/host/lib/usrp/device3/device3_impl.hpp index 1dbb78155..8ecb1f72b 100644 --- a/host/lib/usrp/device3/device3_impl.hpp +++ b/host/lib/usrp/device3/device3_impl.hpp @@ -21,7 +21,7 @@ #include #include #include -#include "xports.hpp" +#include namespace uhd { namespace usrp { diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp index 26b3a29e9..fed273ae2 100644 --- a/host/lib/usrp/device3/device3_io_impl.cpp +++ b/host/lib/usrp/device3/device3_io_impl.cpp @@ -13,15 +13,14 @@ #include #include #include - -#include "../common/async_packet_handler.hpp" #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" -#include "../../rfnoc/rx_stream_terminator.hpp" -#include "../../rfnoc/tx_stream_terminator.hpp" #include #include #include +#include +#include +#include #include #define UHD_TX_STREAMER_LOG() UHD_LOGGER_TRACE("STREAMER") diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp index 121ef00e2..489bdd014 100644 --- a/host/lib/usrp/e300/e300_impl.hpp +++ b/host/lib/usrp/e300/e300_impl.hpp @@ -17,21 +17,21 @@ #include #include #include +#include #include #include #include #include "e300_fifo_config.hpp" -#include "radio_ctrl_core_3000.hpp" -#include "rx_frontend_core_200.hpp" -#include "tx_frontend_core_200.hpp" -#include "rx_vita_core_3000.hpp" -#include "tx_vita_core_3000.hpp" -#include "time_core_3000.hpp" -#include "rx_dsp_core_3000.hpp" -#include "tx_dsp_core_3000.hpp" -#include "ad9361_ctrl.hpp" -#include "ad936x_manager.hpp" -#include "gpio_atr_3000.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "e300_global_regs.hpp" #include "e300_i2c.hpp" diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp index f91f627dd..4d4b54b73 100644 --- a/host/lib/usrp/e300/e300_io_impl.cpp +++ b/host/lib/usrp/e300/e300_io_impl.cpp @@ -8,10 +8,10 @@ #include "e300_regs.hpp" #include "e300_impl.hpp" #include "e300_fpga_defs.hpp" -#include "validate_subdev_spec.hpp" +#include #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" -#include "async_packet_handler.hpp" +#include #include #include #include diff --git a/host/lib/usrp/e300/e300_network.cpp b/host/lib/usrp/e300/e300_network.cpp index 404ac0c19..d7473d2ee 100644 --- a/host/lib/usrp/e300/e300_network.cpp +++ b/host/lib/usrp/e300/e300_network.cpp @@ -11,8 +11,6 @@ #include "e300_impl.hpp" -#include "ad9361_ctrl.hpp" - #include "e300_sensor_manager.hpp" #include "e300_fifo_config.hpp" #include "e300_spi.hpp" @@ -25,6 +23,8 @@ #include #include +#include + #include #include #include diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp index ea8db305e..9c9e16672 100644 --- a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp +++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_E300_REMOTE_CODEC_CTRL_HPP #define INCLUDED_E300_REMOTE_CODEC_CTRL_HPP -#include "ad9361_ctrl.hpp" #include +#include namespace uhd { namespace usrp { namespace e300 { diff --git a/host/lib/usrp/mpmd/mpmd_impl.cpp b/host/lib/usrp/mpmd/mpmd_impl.cpp index 4d3fba8a1..d63a2cfa0 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.cpp +++ b/host/lib/usrp/mpmd/mpmd_impl.cpp @@ -5,11 +5,18 @@ // #include "mpmd_impl.hpp" -#include "rpc_block_ctrl.hpp" #include <../device3/device3_impl.hpp> #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include diff --git a/host/lib/usrp/mpmd/mpmd_impl.hpp b/host/lib/usrp/mpmd/mpmd_impl.hpp index e3c44a5a0..0a5ed4545 100644 --- a/host/lib/usrp/mpmd/mpmd_impl.hpp +++ b/host/lib/usrp/mpmd/mpmd_impl.hpp @@ -8,7 +8,6 @@ #define INCLUDED_MPMD_IMPL_HPP #include "mpmd_xport_mgr.hpp" -#include "../../utils/rpc.hpp" #include "../device3/device3_impl.hpp" #include #include @@ -16,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 6ff619b55..b7d131bac 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -18,7 +18,7 @@ #include #include #include -#include "legacy_compat.hpp" +#include #include #include #include diff --git a/host/lib/usrp/n230/n230_clk_pps_ctrl.hpp b/host/lib/usrp/n230/n230_clk_pps_ctrl.hpp index 53ff0571f..af9ffc307 100644 --- a/host/lib/usrp/n230/n230_clk_pps_ctrl.hpp +++ b/host/lib/usrp/n230/n230_clk_pps_ctrl.hpp @@ -8,14 +8,14 @@ #ifndef INCLUDED_N230_CLK_PPS_CTRL_HPP #define INCLUDED_N230_CLK_PPS_CTRL_HPP -#include "time_core_3000.hpp" -#include "ad9361_ctrl.hpp" +#include "n230_cores.hpp" +#include "n230_fpga_defs.h" #include +#include +#include #include #include #include -#include "n230_cores.hpp" -#include "n230_fpga_defs.h" namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/n230/n230_cores.hpp b/host/lib/usrp/n230/n230_cores.hpp index ac454cc39..2768ada41 100644 --- a/host/lib/usrp/n230/n230_cores.hpp +++ b/host/lib/usrp/n230/n230_cores.hpp @@ -8,8 +8,8 @@ #ifndef INCLUDED_N230_CORES_HPP #define INCLUDED_N230_CORES_HPP -#include "spi_core_3000.hpp" -#include "adf4001_ctrl.hpp" +#include +#include #include namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/n230/n230_frontend_ctrl.hpp b/host/lib/usrp/n230/n230_frontend_ctrl.hpp index 6faa35ac8..842814213 100644 --- a/host/lib/usrp/n230/n230_frontend_ctrl.hpp +++ b/host/lib/usrp/n230/n230_frontend_ctrl.hpp @@ -8,14 +8,14 @@ #ifndef INCLUDED_N230_FRONTEND_CTRL_HPP #define INCLUDED_N230_FRONTEND_CTRL_HPP -#include "radio_ctrl_core_3000.hpp" -#include "ad9361_ctrl.hpp" -#include "gpio_atr_3000.hpp" +#include "n230_fpga_defs.h" +#include +#include +#include #include #include #include #include -#include "n230_fpga_defs.h" namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/n230/n230_impl.cpp b/host/lib/usrp/n230/n230_impl.cpp index 04d404311..c4e3af0b2 100644 --- a/host/lib/usrp/n230/n230_impl.cpp +++ b/host/lib/usrp/n230/n230_impl.cpp @@ -6,9 +6,14 @@ // #include "n230_impl.hpp" - #include "n230_fw_ctrl_iface.hpp" -#include "validate_subdev_spec.hpp" +#include "n230_defaults.h" +#include "n230_fpga_defs.h" +#include "n230_fw_defs.h" +#include "n230_fw_host_iface.h" + +#include + #include #include #include @@ -22,6 +27,7 @@ #include #include #include + #include #include #include @@ -31,11 +37,6 @@ #include //used for htonl and ntohl #include -#include "n230_defaults.h" -#include "n230_fpga_defs.h" -#include "n230_fw_defs.h" -#include "n230_fw_host_iface.h" - namespace uhd { namespace usrp { namespace n230 { using namespace uhd::transport; diff --git a/host/lib/usrp/n230/n230_impl.hpp b/host/lib/usrp/n230/n230_impl.hpp index d0547922a..213f0f61e 100644 --- a/host/lib/usrp/n230/n230_impl.hpp +++ b/host/lib/usrp/n230/n230_impl.hpp @@ -16,7 +16,7 @@ #include "n230_eeprom_manager.hpp" #include "n230_resource_manager.hpp" #include "n230_stream_manager.hpp" -#include "recv_packet_demuxer_3000.hpp" +#include namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/n230/n230_resource_manager.hpp b/host/lib/usrp/n230/n230_resource_manager.hpp index b2a9b6a9d..4b4065e8f 100644 --- a/host/lib/usrp/n230/n230_resource_manager.hpp +++ b/host/lib/usrp/n230/n230_resource_manager.hpp @@ -8,17 +8,25 @@ #ifndef INCLUDED_N230_RESOURCE_MANAGER_HPP #define INCLUDED_N230_RESOURCE_MANAGER_HPP -#include "radio_ctrl_core_3000.hpp" -#include "spi_core_3000.hpp" -#include "gpio_atr_3000.hpp" -#include "rx_vita_core_3000.hpp" -#include "tx_vita_core_3000.hpp" -#include "time_core_3000.hpp" -#include "rx_dsp_core_3000.hpp" -#include "tx_dsp_core_3000.hpp" -#include "user_settings_core_3000.hpp" -#include "ad9361_ctrl.hpp" -#include "ad936x_manager.hpp" +#include "n230_fw_ctrl_iface.hpp" +#include "n230_clk_pps_ctrl.hpp" +#include "n230_cores.hpp" +#include "n230_fpga_defs.h" +#include "n230_frontend_ctrl.hpp" +#include "n230_uart.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -27,13 +35,6 @@ #include #include -#include "n230_fw_ctrl_iface.hpp" -#include "n230_clk_pps_ctrl.hpp" -#include "n230_cores.hpp" -#include "n230_fpga_defs.h" -#include "n230_frontend_ctrl.hpp" -#include "n230_uart.hpp" - namespace uhd { namespace usrp { namespace n230 { enum n230_eth_port_t { diff --git a/host/lib/usrp/n230/n230_stream_manager.cpp b/host/lib/usrp/n230/n230_stream_manager.cpp index 3071adf3a..5c44992ca 100644 --- a/host/lib/usrp/n230/n230_stream_manager.cpp +++ b/host/lib/usrp/n230/n230_stream_manager.cpp @@ -9,11 +9,11 @@ #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" -#include "async_packet_handler.hpp" +#include #include -#include #include #include +#include #include static const double N230_RX_SW_BUFF_FULL_FACTOR = 0.90; //Buffer should ideally be 90% full. diff --git a/host/lib/usrp/n230/n230_stream_manager.hpp b/host/lib/usrp/n230/n230_stream_manager.hpp index a6acb602d..6ec219f0b 100644 --- a/host/lib/usrp/n230/n230_stream_manager.hpp +++ b/host/lib/usrp/n230/n230_stream_manager.hpp @@ -8,8 +8,11 @@ #ifndef INCLUDED_N230_STREAM_MANAGER_HPP #define INCLUDED_N230_STREAM_MANAGER_HPP -#include "time_core_3000.hpp" -#include "rx_vita_core_3000.hpp" +#include "n230_device_args.hpp" +#include "n230_resource_manager.hpp" + +#include +#include #include #include #include @@ -19,8 +22,6 @@ #include #include #include -#include "n230_device_args.hpp" -#include "n230_resource_manager.hpp" namespace uhd { namespace usrp { namespace n230 { diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index a4ffac3db..0e79a5985 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -5,13 +5,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "validate_subdev_spec.hpp" +#include "usrp1_calc_mux.hpp" +#include "usrp1_impl.hpp" +#include #define SRPH_DONT_CHECK_SEQUENCE #include "../../transport/super_recv_packet_handler.hpp" #define SSPH_DONT_PAD_TO_ONE #include "../../transport/super_send_packet_handler.hpp" -#include "usrp1_calc_mux.hpp" -#include "usrp1_impl.hpp" #include #include #include diff --git a/host/lib/usrp/usrp1/mb_eeprom.cpp b/host/lib/usrp/usrp1/mb_eeprom.cpp index cedbb8944..9b868fd4e 100644 --- a/host/lib/usrp/usrp1/mb_eeprom.cpp +++ b/host/lib/usrp/usrp1/mb_eeprom.cpp @@ -5,7 +5,7 @@ // #include "usrp1_impl.hpp" -#include "eeprom_utils.hpp" +#include #include #include diff --git a/host/lib/usrp/usrp1/usrp1_calc_mux.hpp b/host/lib/usrp/usrp1/usrp1_calc_mux.hpp index 76e0bf971..1169f2fe8 100644 --- a/host/lib/usrp/usrp1/usrp1_calc_mux.hpp +++ b/host/lib/usrp/usrp1/usrp1_calc_mux.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/host/lib/usrp/usrp1/usrp1_iface.hpp b/host/lib/usrp/usrp1/usrp1_iface.hpp index ec6bc52d4..4ae4e83e0 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.hpp +++ b/host/lib/usrp/usrp1/usrp1_iface.hpp @@ -8,7 +8,7 @@ #ifndef INCLUDED_USRP1_IFACE_HPP #define INCLUDED_USRP1_IFACE_HPP -#include "fx2_ctrl.hpp" +#include #include #include #include diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index 5187d000e..a245705df 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -5,11 +5,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "gpio_core_200.hpp" -#include #include "clock_ctrl.hpp" #include "usrp2_regs.hpp" //wishbone address constants #include "usrp2_fifo_ctrl.hpp" +#include "ad7922_regs.hpp" //aux adc +#include "ad5623_regs.hpp" //aux dac +#include +#include #include #include #include @@ -17,8 +19,6 @@ #include #include //htonl and ntohl #include -#include "ad7922_regs.hpp" //aux adc -#include "ad5623_regs.hpp" //aux dac using namespace uhd; using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 2d6d7c11d..2b8c7a5d1 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "validate_subdev_spec.hpp" -#include "async_packet_handler.hpp" +#include +#include #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" #include "usrp2_impl.hpp" diff --git a/host/lib/usrp/usrp2/mb_eeprom.cpp b/host/lib/usrp/usrp2/mb_eeprom.cpp index b1c8ab8b0..bd91b527c 100644 --- a/host/lib/usrp/usrp2/mb_eeprom.cpp +++ b/host/lib/usrp/usrp2/mb_eeprom.cpp @@ -5,7 +5,7 @@ // #include "usrp2_impl.hpp" -#include "eeprom_utils.hpp" +#include #include #include #include diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 4afdfae56..88591333a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -6,7 +6,7 @@ #include "usrp2_impl.hpp" #include "fw_common.h" -#include "apply_corrections.hpp" +#include #include #include diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 81d72ccdd..0e164e537 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -8,17 +8,17 @@ #ifndef INCLUDED_USRP2_IMPL_HPP #define INCLUDED_USRP2_IMPL_HPP -#include "gpio_core_200.hpp" #include "usrp2_iface.hpp" #include "usrp2_fifo_ctrl.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" -#include "rx_frontend_core_200.hpp" -#include "tx_frontend_core_200.hpp" -#include "rx_dsp_core_200.hpp" -#include "tx_dsp_core_200.hpp" -#include "time64_core_200.hpp" -#include "user_settings_core_200.hpp" +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include @@ -36,6 +34,8 @@ #include #include #include +#include +#include #include static const double USRP2_LINK_RATE_BPS = 1000e6/8; diff --git a/host/lib/usrp/x300/x300_dboard_iface.hpp b/host/lib/usrp/x300/x300_dboard_iface.hpp index 1c78f8705..807879bad 100644 --- a/host/lib/usrp/x300/x300_dboard_iface.hpp +++ b/host/lib/usrp/x300/x300_dboard_iface.hpp @@ -9,13 +9,13 @@ #define INCLUDED_X300_DBOARD_IFACE_HPP #include "x300_clock_ctrl.hpp" -#include "spi_core_3000.hpp" -#include "i2c_core_100_wb32.hpp" -#include "gpio_atr_3000.hpp" -#include "rx_frontend_core_3000.hpp" -#include +#include +#include +#include +#include #include "ad7922_regs.hpp" //aux adc #include "ad5623_regs.hpp" //aux dac +#include #include struct x300_dboard_iface_config_t diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index 97c8c0682..9ea3a814d 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -9,19 +9,13 @@ #include "x300_lvbitx.hpp" #include "x310_lvbitx.hpp" #include "x300_mb_eeprom_iface.hpp" -#include "apply_corrections.hpp" -#include -#include +#include #include #include #include #include #include #include -#include -#include -#include -#include #include #include #include @@ -29,6 +23,13 @@ #include #include #include + +#include +#include +#include +#include +#include +#include #include #define NIUSRPRIO_DEFAULT_RPC_PORT "5444" diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp index 9e89ca542..df6af5521 100644 --- a/host/lib/usrp/x300/x300_impl.hpp +++ b/host/lib/usrp/x300/x300_impl.hpp @@ -8,27 +8,29 @@ #ifndef INCLUDED_X300_IMPL_HPP #define INCLUDED_X300_IMPL_HPP -#include +#include "x300_radio_ctrl_impl.hpp" +#include "x300_clock_ctrl.hpp" +#include "x300_fw_common.h" +#include "x300_regs.hpp" + #include "../device3/device3_impl.hpp" +#include #include #include #include -#include "x300_radio_ctrl_impl.hpp" -#include "x300_clock_ctrl.hpp" -#include "x300_fw_common.h" #include //mtu -#include "i2c_core_100_wb32.hpp" -#include #include #include #include #include -#include "recv_packet_demuxer_3000.hpp" -#include "x300_regs.hpp" ///////////// RFNOC ///////////////////// #include ///////////// RFNOC ///////////////////// + +#include +#include #include +#include #include static const std::string X300_FW_FILE_NAME = "usrp_x300_fw.bin"; diff --git a/host/lib/usrp/x300/x300_io_impl.cpp b/host/lib/usrp/x300/x300_io_impl.cpp index b6e93c421..082d83185 100644 --- a/host/lib/usrp/x300/x300_io_impl.cpp +++ b/host/lib/usrp/x300/x300_io_impl.cpp @@ -9,12 +9,12 @@ #include "x300_impl.hpp" #include "../../transport/super_recv_packet_handler.hpp" #include "../../transport/super_send_packet_handler.hpp" +#include #include -#include "async_packet_handler.hpp" #include -#include #include #include +#include #include using namespace uhd; diff --git a/host/lib/usrp/x300/x300_mb_eeprom.cpp b/host/lib/usrp/x300/x300_mb_eeprom.cpp index d72a27a77..b8fb59538 100644 --- a/host/lib/usrp/x300/x300_mb_eeprom.cpp +++ b/host/lib/usrp/x300/x300_mb_eeprom.cpp @@ -5,7 +5,7 @@ // #include "x300_impl.hpp" -#include "eeprom_utils.hpp" +#include #include #include diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp index 38d9c2c66..d7c206aec 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp @@ -5,17 +5,16 @@ // #include "x300_radio_ctrl_impl.hpp" - #include "x300_dboard_iface.hpp" -#include "wb_iface_adapter.hpp" -#include "gpio_atr_3000.hpp" -#include "apply_corrections.hpp" #include #include #include #include #include #include +#include +#include +#include #include #include #include diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp index 72e5b3933..ead546a63 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp @@ -8,17 +8,17 @@ #ifndef INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP #define INCLUDED_LIBUHD_RFNOC_X300_RADIO_CTRL_IMPL_HPP -#include "radio_ctrl_impl.hpp" #include "x300_clock_ctrl.hpp" -#include "spi_core_3000.hpp" #include "x300_adc_ctrl.hpp" #include "x300_dac_ctrl.hpp" #include "x300_regs.hpp" -#include "rx_frontend_core_3000.hpp" -#include "tx_frontend_core_200.hpp" #include #include #include +#include +#include +#include +#include namespace uhd { namespace rfnoc { diff --git a/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp b/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp index 348ac7dcb..594d10df6 100644 --- a/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp +++ b/host/lib/usrp_clock/octoclock/octoclock_image_loader.cpp @@ -8,7 +8,6 @@ #include "octoclock_impl.hpp" #include "common.h" -#include "../../utils/ihex.hpp" #include #include #include @@ -17,8 +16,8 @@ #include #include #include +#include -#include #include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include namespace fs = boost::filesystem; using namespace uhd; diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt index ea59df081..0af642f90 100644 --- a/host/lib/utils/CMakeLists.txt +++ b/host/lib/utils/CMakeLists.txt @@ -9,8 +9,6 @@ # This file included, use CMake directory variables ######################################################################## -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - ######################################################################## # Setup defines for process scheduling ######################################################################## diff --git a/host/lib/utils/eeprom_utils.cpp b/host/lib/utils/eeprom_utils.cpp index 0090a3612..6999827c0 100644 --- a/host/lib/utils/eeprom_utils.cpp +++ b/host/lib/utils/eeprom_utils.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "eeprom_utils.hpp" +#include #include uhd::byte_vector_t string_to_uint16_bytes(const std::string &num_str){ diff --git a/host/lib/utils/eeprom_utils.hpp b/host/lib/utils/eeprom_utils.hpp deleted file mode 100644 index 28deca790..000000000 --- a/host/lib/utils/eeprom_utils.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright 2017 Ettus Research (National Instruments Corp.) -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#include -#include -#include -#include -#include - -static const size_t SERIAL_LEN = 9; -static const size_t NAME_MAX_LEN = 32 - SERIAL_LEN; - -//! convert a string to a byte vector to write to eeprom -uhd::byte_vector_t string_to_uint16_bytes(const std::string &num_str); - -//! convert a byte vector read from eeprom to a string -std::string uint16_bytes_to_string(const uhd::byte_vector_t &bytes); diff --git a/host/lib/utils/ihex.cpp b/host/lib/utils/ihex.cpp index ce0dd6e69..6bb0ba9d4 100644 --- a/host/lib/utils/ihex.cpp +++ b/host/lib/utils/ihex.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later // -#include "ihex.hpp" #include +#include #include #include #include diff --git a/host/lib/utils/ihex.hpp b/host/lib/utils/ihex.hpp deleted file mode 100644 index 4b1be77f1..000000000 --- a/host/lib/utils/ihex.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2015 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_IHEX_READER_HPP -#define INCLUDED_IHEX_READER_HPP - -#include -#include -#include -#include -#include - -namespace uhd { - -class ihex_reader -{ -public: - // Arguments are: lower address bits, upper address bits, buff, length - typedef boost::function record_handle_type; - - /* - * \param ihex_filename Path to the *.ihx file - */ - ihex_reader(const std::string &ihex_filename); - - /*! Read an Intel HEX file and handle it record by record. - * - * Every record is individually passed off to a record handler function. - * - * \param record_handler The functor that will handle the records. - * - * \throws uhd::io_error if the HEX file is corrupted or unreadable. - */ - void read(record_handle_type record_handler); - - /* Convert the ihex file to a bin file. - * - * *Note:* This function makes the assumption that the hex file is - * contiguous, and starts at address zero. - * - * \param bin_filename Output filename. - * - * \throws uhd::io_error if the HEX file is corrupted or unreadable. - */ - void to_bin_file(const std::string &bin_filename); - - /*! Copy the ihex file into a buffer. - * - * Very similar functionality as to_bin_file(). - * - * *Note:* This function makes the assumption that the hex file is - * contiguous, and starts at address zero. - * - * \throws uhd::io_error if the HEX file is corrupted or unreadable. - */ - std::vector to_vector(const size_t size_estimate = 0); - -private: - const std::string _ihex_filename; -}; - -}; /* namespace uhd */ - -#endif /* INCLUDED_IHEX_READER_HPP */ - diff --git a/host/lib/utils/rpc.hpp b/host/lib/utils/rpc.hpp deleted file mode 100644 index c7c27afd2..000000000 --- a/host/lib/utils/rpc.hpp +++ /dev/null @@ -1,191 +0,0 @@ -// -// Copyright 2017 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#ifndef INCLUDED_UTILS_RPC_HPP -#define INCLUDED_UTILS_RPC_HPP - -#include -#include -#include -#include -#include - -namespace uhd { - -/*! Abstraction for RPC client - * - * Purpose of this class is to wrap the underlying RPC implementation. - * This class holds a connection to an RPC server (the connection is severed on - * destruction). - */ -class rpc_client -{ - public: - using sptr = std::shared_ptr; - - static sptr make( - const std::string &addr, - const uint16_t port, - const std::string &get_last_error_cmd="" - ) { - return std::make_shared(addr, port, get_last_error_cmd); - } - - /*! - * \param addr An IP address to connect to - * \param port Port to connect to - * \param get_last_error_cmd A command that queries an error string from - * the RPC server. If set, the RPC client will - * try and use this command to fetch information - * about what went wrong on the client side. - */ - rpc_client( - const std::string &addr, - const uint16_t port, - std::string const &get_last_error_cmd="" - ) : _client(addr, port) - , _get_last_error_cmd(get_last_error_cmd) - { - // nop - } - - /*! Perform an RPC request. - * - * Thread safe (locked). This function blocks until it receives a valid - * response from the server. - * - * \param func_name The function name that is called via RPC - * \param args All these arguments are passed to the RPC call - * - * \throws uhd::runtime_error in case of failure - */ - template - return_type request(std::string const& func_name, Args&&... args) - { - std::lock_guard lock(_mutex); - try { - return _client.call(func_name, std::forward(args)...) - .template as(); - } catch (const ::rpc::rpc_error &ex) { - const std::string error = _get_last_error_safe(); - if (not error.empty()) { - UHD_LOG_ERROR("RPC", error); - } - throw uhd::runtime_error(str( - boost::format("Error during RPC call to `%s'. Error message: %s") - % func_name % (error.empty() ? ex.what() : error) - )); - } catch (const std::bad_cast& ex) { - throw uhd::runtime_error(str( - boost::format("Error during RPC call to `%s'. Error message: %s") - % func_name % ex.what() - )); - } - }; - - /*! Perform an RPC notification. - * - * Thread safe (locked). This function does not require a response from the - * server, although the underlying implementation may provide one. - * - * \param func_name The function name that is called via RPC - * \param args All these arguments are passed to the RPC call - * - * \throws uhd::runtime_error in case of failure - */ - template - void notify(std::string const& func_name, Args&&... args) - { - std::lock_guard lock(_mutex); - try { - _client.call(func_name, std::forward(args)...); - } catch (const ::rpc::rpc_error &ex) { - const std::string error = _get_last_error_safe(); - if (not error.empty()) { - UHD_LOG_ERROR("RPC", error); - } - throw uhd::runtime_error(str( - boost::format("Error during RPC call to `%s'. Error message: %s") - % func_name % (error.empty() ? ex.what() : error) - )); - } catch (const std::bad_cast& ex) { - throw uhd::runtime_error(str( - boost::format("Error during RPC call to `%s'. Error message: %s") - % func_name % ex.what() - )); - } - }; - - /*! Like request(), also provides a token. - * - * This is a convenience wrapper to directly call a function that requires - * a token without having to have a copy of the token. - */ - template - return_type request_with_token(std::string const& func_name, Args&&... args) - { - return request(func_name, _token, std::forward(args)...); - }; - - /*! Like notify(), also provides a token. - * - * This is a convenience wrapper to directly call a function that requires - * a token without having to have a copy of the token. - */ - template - void notify_with_token(std::string const& func_name, Args&&... args) - { - notify(func_name, _token, std::forward(args)...); - }; - - /*! Sets the token value. This is used by the `_with_token` methods. - */ - void set_token(const std::string &token) - { - _token = token; - } - - void set_timeout(size_t timeout_ms) - { - _client.set_timeout(timeout_ms); - } - - private: - /*! Pull the last error out of the RPC server. Not thread-safe, meant to - * be called from notify() or request(). - * - * This function will do its best not to get in anyone's way. If it can't - * get an error string, it'll return an empty string. - */ - std::string _get_last_error_safe() - { - if (_get_last_error_cmd.empty()) { - return ""; - } - try { - return _client.call(_get_last_error_cmd).as(); - } catch (const ::rpc::rpc_error &ex) { - // nop - } catch (const std::bad_cast& ex) { - // nop - } catch (...) { - // nop - } - return ""; - } - - //! Reference the actual RPC client - ::rpc::client _client; - //! If set, this is the command that will retrieve an error - const std::string _get_last_error_cmd; - - std::string _token; - std::mutex _mutex; -}; - -} /* namespace uhd */ - -#endif /* INCLUDED_UTILS_RPC_HPP */ diff --git a/host/tests/expert_test.cpp b/host/tests/expert_test.cpp index 5b1c1ff92..efd4f1d08 100644 --- a/host/tests/expert_test.cpp +++ b/host/tests/expert_test.cpp @@ -8,9 +8,9 @@ #include #include #include -#include "../lib/experts/expert_container.hpp" -#include "../lib/experts/expert_factory.hpp" #include +#include +#include #include using namespace uhd::experts; diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 769314f33..0b78f45fc 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -56,6 +56,7 @@ IF(ENABLE_USB) ) # Additional include directories for b2xx_fx3_utils INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/../lib/include ${CMAKE_CURRENT_SOURCE_DIR}/../lib/usrp/b200 ${CMAKE_CURRENT_SOURCE_DIR}/../lib/usrp/common ${CMAKE_CURRENT_SOURCE_DIR}/../lib/usrp/common/ad9361_driver -- cgit v1.2.3