diff --git a/config/etc/addrtab/v7xx/fanout_fib_v2/ipbus_decode_pdts_fib_v2_io.vhd b/config/etc/addrtab/v7xx/fanout_fib_v2/ipbus_decode_pdts_fib_v2_io.vhd deleted file mode 100644 index 1e34d53..0000000 --- a/config/etc/addrtab/v7xx/fanout_fib_v2/ipbus_decode_pdts_fib_v2_io.vhd +++ /dev/null @@ -1,81 +0,0 @@ --- Address decode logic for ipbus fabric --- --- This file has been AUTOGENERATED from the address table - do not hand edit --- --- We assume the synthesis tool is clever enough to recognise exclusive conditions --- in the if statement. --- --- Dave Newbold, February 2011 - -library IEEE; -use IEEE.STD_LOGIC_1164.all; -use ieee.numeric_std.all; - -package ipbus_decode_pdts_fib_v2_io is - - constant IPBUS_SEL_WIDTH: positive := 4; - subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0); - function ipbus_sel_pdts_fib_v2_io(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t; - --- START automatically generated VHDL (Thu Oct 17 11:01:01 2024) - constant N_SLV_CSR: integer := 0; - constant N_SLV_CONFIG: integer := 1; - constant N_SLV_I2C: integer := 2; - constant N_SLV_I2C_SFP0: integer := 3; - constant N_SLV_I2C_SFP1: integer := 4; - constant N_SLV_I2C_SFP2: integer := 5; - constant N_SLV_I2C_SFP3: integer := 6; - constant N_SLV_I2C_SFP4: integer := 7; - constant N_SLV_I2C_SFP5: integer := 8; - constant N_SLV_I2C_SFP6: integer := 9; - constant N_SLV_I2C_SFP7: integer := 10; - constant N_SLV_FREQ: integer := 11; - constant N_SLAVES: integer := 12; --- END automatically generated VHDL - - -end ipbus_decode_pdts_fib_v2_io; - -package body ipbus_decode_pdts_fib_v2_io is - - function ipbus_sel_pdts_fib_v2_io(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is - variable sel: ipbus_sel_t; - begin - --- START automatically generated VHDL (Thu Oct 17 11:01:01 2024) - if std_match(addr, "-------------------------0000-0-") then - sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x0000007a - elsif std_match(addr, "-------------------------0000-1-") then - sel := ipbus_sel_t(to_unsigned(N_SLV_CONFIG, IPBUS_SEL_WIDTH)); -- config / base 0x00000002 / mask 0x0000007a - elsif std_match(addr, "-------------------------0001---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C, IPBUS_SEL_WIDTH)); -- i2c / base 0x00000008 / mask 0x00000078 - elsif std_match(addr, "-------------------------0010---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP0, IPBUS_SEL_WIDTH)); -- i2c_sfp0 / base 0x00000010 / mask 0x00000078 - elsif std_match(addr, "-------------------------0011---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP1, IPBUS_SEL_WIDTH)); -- i2c_sfp1 / base 0x00000018 / mask 0x00000078 - elsif std_match(addr, "-------------------------0100---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP2, IPBUS_SEL_WIDTH)); -- i2c_sfp2 / base 0x00000020 / mask 0x00000078 - elsif std_match(addr, "-------------------------0101---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP3, IPBUS_SEL_WIDTH)); -- i2c_sfp3 / base 0x00000028 / mask 0x00000078 - elsif std_match(addr, "-------------------------0110---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP4, IPBUS_SEL_WIDTH)); -- i2c_sfp4 / base 0x00000030 / mask 0x00000078 - elsif std_match(addr, "-------------------------0111---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP5, IPBUS_SEL_WIDTH)); -- i2c_sfp5 / base 0x00000038 / mask 0x00000078 - elsif std_match(addr, "-------------------------1000---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP6, IPBUS_SEL_WIDTH)); -- i2c_sfp6 / base 0x00000040 / mask 0x00000078 - elsif std_match(addr, "-------------------------1001---") then - sel := ipbus_sel_t(to_unsigned(N_SLV_I2C_SFP7, IPBUS_SEL_WIDTH)); -- i2c_sfp7 / base 0x00000048 / mask 0x00000078 - elsif std_match(addr, "-------------------------1010-0-") then - sel := ipbus_sel_t(to_unsigned(N_SLV_FREQ, IPBUS_SEL_WIDTH)); -- freq / base 0x00000050 / mask 0x0000007a --- END automatically generated VHDL - - else - sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH)); - end if; - - return sel; - - end function ipbus_sel_pdts_fib_v2_io; - -end ipbus_decode_pdts_fib_v2_io; - diff --git a/include/timing/FIBIONode.hpp b/include/timing/FIBIONode.hpp index 37d6e2b..4d904b6 100644 --- a/include/timing/FIBIONode.hpp +++ b/include/timing/FIBIONode.hpp @@ -111,7 +111,7 @@ class FIBIONode : public SFPMuxIONode { /** * @brief Switch on or off the SFP tx laser via the I2C IO expander controlling the sfp tx disable pin. aOn=1: laster transmitting, tx disable pin = 0; aOn=0: laster NOT transmitting, tx disable pin = 1. */ - void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const; // NOLINT(build/unsigned) + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) // /** // * @brief Fill hardware monitoring structure. diff --git a/include/timing/FIBV2IONode.hpp b/include/timing/FIBV2IONode.hpp index db26261..e9eda40 100644 --- a/include/timing/FIBV2IONode.hpp +++ b/include/timing/FIBV2IONode.hpp @@ -69,7 +69,7 @@ class FIBV2IONode : public IONode { /** * @brief Switch on or off the SFP tx laser via the I2C IO expander controlling the sfp tx disable pin. aOn=1: laster transmitting, tx disable pin = 0; aOn=0: laster NOT transmitting, tx disable pin = 1. */ - void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const; // NOLINT(build/unsigned) + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) /** * @brief Print status of on-board PLL. diff --git a/include/timing/FMCIONode.hpp b/include/timing/FMCIONode.hpp index a4aeffd..35abcff 100644 --- a/include/timing/FMCIONode.hpp +++ b/include/timing/FMCIONode.hpp @@ -69,6 +69,11 @@ class FMCIONode : public IONode */ std::string get_clock_frequencies_table(bool print_out = false) const override; + /** + * @brief control tx laser of on-board SFP + */ + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + // /** // * @brief Fill hardware monitoring structure. // */ @@ -78,6 +83,8 @@ class FMCIONode : public IONode // * @brief Give info to collector. // */ // void get_info(opmonlib::InfoCollector& ci, int level) const override; +private: + void validate_sfp_id(uint32_t sfp_id) const; // NOLINT(build/unsigned) }; } // namespace timing diff --git a/include/timing/GIBIONode.hpp b/include/timing/GIBIONode.hpp index 6e4ebd9..ba66b8d 100644 --- a/include/timing/GIBIONode.hpp +++ b/include/timing/GIBIONode.hpp @@ -79,6 +79,11 @@ class GIBIONode : public IONode */ void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + /** + * @brief control tx laser of on-board SFP softly (I2C command) + */ + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + /** * @brief Fill hardware monitoring structure. */ diff --git a/include/timing/IONode.hpp b/include/timing/IONode.hpp index 35dc641..e756adf 100644 --- a/include/timing/IONode.hpp +++ b/include/timing/IONode.hpp @@ -158,6 +158,11 @@ class IONode : public TimingNode */ virtual void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const; // NOLINT(build/unsigned) + /** + * @brief control tx laser of on-board SFP + */ + virtual void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const = 0; // NOLINT(build/unsigned) + /** * @brief Reset timing node. */ diff --git a/include/timing/MIBIONode.hpp b/include/timing/MIBIONode.hpp index 1ffe4b6..764cef2 100644 --- a/include/timing/MIBIONode.hpp +++ b/include/timing/MIBIONode.hpp @@ -101,6 +101,14 @@ class MIBIONode : public IONode */ void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + /** + * @brief control tx laser of on-board SFP + */ + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override // NOLINT(build/unsigned) + { + TLOG() << "Not implemented in MIB v1 firmware"; + } + // /** // * @brief Fill hardware monitoring structure. // */ diff --git a/include/timing/MIBV2IONode.hpp b/include/timing/MIBV2IONode.hpp index 25519fb..c7c3a0f 100644 --- a/include/timing/MIBV2IONode.hpp +++ b/include/timing/MIBV2IONode.hpp @@ -74,6 +74,11 @@ class MIBV2IONode : public IONode */ void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + /** + * @brief control tx laser of on-board SFP + */ + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + /** * @brief Fill hardware monitoring structure. */ diff --git a/include/timing/PC059IONode.hpp b/include/timing/PC059IONode.hpp index b25a402..56adcdd 100644 --- a/include/timing/PC059IONode.hpp +++ b/include/timing/PC059IONode.hpp @@ -85,6 +85,11 @@ class PC059IONode : public SFPMuxIONode */ void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + /** + * @brief control tx laser of on-board SFP softly (I2C command) + */ + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + // /** // * @brief Fill hardware monitoring structure. // */ @@ -94,6 +99,8 @@ class PC059IONode : public SFPMuxIONode // * @brief Give info to collector. // */ // void get_info(opmonlib::InfoCollector& ci, int level) const override; +private: + void validate_sfp_id(uint32_t sfp_id) const; // NOLINT(build/unsigned) }; } // namespace timing diff --git a/include/timing/SIMIONode.hpp b/include/timing/SIMIONode.hpp index 4293fc6..4edbc09 100644 --- a/include/timing/SIMIONode.hpp +++ b/include/timing/SIMIONode.hpp @@ -108,6 +108,11 @@ class SIMIONode : public IONode * @brief Control tx laser of on-board SFP softly (I2C command) */ void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) + + /** + * @brief Control tx laser of on-board SFP softly (I2C command) + */ + void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override; // NOLINT(build/unsigned) }; } // namespace timing diff --git a/include/timing/TLUIONode.hpp b/include/timing/TLUIONode.hpp index e9ab18d..522e2e7 100644 --- a/include/timing/TLUIONode.hpp +++ b/include/timing/TLUIONode.hpp @@ -75,6 +75,11 @@ class TLUIONode : public IONode */ void switch_sfp_soft_tx_control_bit(uint32_t, bool) const override; // NOLINT(build/unsigned) + /** + * @brief Control tx laser of on-board SFP softly (I2C command) + */ + void switch_sfp_tx(uint32_t, bool) const override; // NOLINT(build/unsigned) + // /** // * @brief Fill hardware monitoring structure. // */ @@ -87,6 +92,8 @@ class TLUIONode : public IONode protected: const std::vector m_dac_devices; +private: + void validate_sfp_id(uint32_t sfp_id) const; // NOLINT(build/unsigned) }; } // namespace timing diff --git a/pybindsrc/io.cpp b/pybindsrc/io.cpp index 42b123c..c29b066 100644 --- a/pybindsrc/io.cpp +++ b/pybindsrc/io.cpp @@ -48,7 +48,8 @@ register_io(py::module& m) .def("get_pll_status", &timing::FMCIONode::get_pll_status, py::arg("print_out") = false) .def("get_hardware_info", &timing::FMCIONode::get_hardware_info, py::arg("print_out") = false) .def("get_sfp_status", &timing::FMCIONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) - .def("switch_sfp_soft_tx_control_bit", &timing::FMCIONode::switch_sfp_soft_tx_control_bit); + .def("switch_sfp_soft_tx_control_bit", &timing::FMCIONode::switch_sfp_soft_tx_control_bit) + .def("switch_sfp_tx", &timing::FMCIONode::switch_sfp_tx); py::class_(m, "PC059IONode") .def(py::init()) @@ -65,7 +66,8 @@ register_io(py::module& m) .def("get_sfp_status", &timing::PC059IONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) .def("switch_sfp_soft_tx_control_bit", &timing::PC059IONode::switch_sfp_soft_tx_control_bit) .def("switch_sfp_mux_channel", &timing::PC059IONode::switch_sfp_mux_channel, py::arg("mux_channel")) - .def("read_active_sfp_mux_channel", &timing::PC059IONode::read_active_sfp_mux_channel); + .def("read_active_sfp_mux_channel", &timing::PC059IONode::read_active_sfp_mux_channel) + .def("switch_sfp_tx", &timing::PC059IONode::switch_sfp_tx); py::class_(m, "FIBIONode") .def(py::init()) @@ -82,7 +84,8 @@ register_io(py::module& m) .def("get_sfp_status", &timing::FIBIONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) .def("switch_sfp_soft_tx_control_bit", &timing::FIBIONode::switch_sfp_soft_tx_control_bit) .def("switch_sfp_mux_channel", &timing::FIBIONode::switch_sfp_mux_channel, py::arg("mux_channel")) - .def("read_active_sfp_mux_channel", &timing::FIBIONode::read_active_sfp_mux_channel); + .def("read_active_sfp_mux_channel", &timing::FIBIONode::read_active_sfp_mux_channel) + .def("switch_sfp_tx", &timing::FIBIONode::switch_sfp_tx); py::class_(m, "FIBV2IONode") .def(py::init()) @@ -95,7 +98,8 @@ register_io(py::module& m) .def("get_pll_status", &timing::FIBV2IONode::get_pll_status, py::arg("print_out") = false) .def("get_hardware_info", &timing::FIBV2IONode::get_hardware_info, py::arg("print_out") = false) .def("get_sfp_status", &timing::FIBV2IONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) - .def("switch_sfp_soft_tx_control_bit", &timing::FIBV2IONode::switch_sfp_soft_tx_control_bit); + .def("switch_sfp_soft_tx_control_bit", &timing::FIBV2IONode::switch_sfp_soft_tx_control_bit) + .def("switch_sfp_tx", &timing::FIBV2IONode::switch_sfp_tx); py::class_(m, "TLUIONode") .def(py::init()) @@ -115,7 +119,8 @@ register_io(py::module& m) &timing::TLUIONode::configure_dac, py::arg("dac_id"), py::arg("dac_value"), - py::arg("internal_ref") = false); + py::arg("internal_ref") = false) + .def("switch_sfp_tx", &timing::TLUIONode::switch_sfp_tx); py::class_(m, "SIMIONode") .def(py::init()) @@ -130,7 +135,8 @@ register_io(py::module& m) .def("get_pll_status", &timing::SIMIONode::get_pll_status, py::arg("print_out") = false) .def("get_hardware_info", &timing::SIMIONode::get_hardware_info, py::arg("print_out") = false) .def("get_sfp_status", &timing::SIMIONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) - .def("switch_sfp_soft_tx_control_bit", &timing::SIMIONode::switch_sfp_soft_tx_control_bit); + .def("switch_sfp_soft_tx_control_bit", &timing::SIMIONode::switch_sfp_soft_tx_control_bit) + .def("switch_sfp_tx", &timing::SIMIONode::switch_sfp_tx); py::class_(m, "MIBIONode") .def(py::init()) @@ -147,6 +153,7 @@ register_io(py::module& m) .def("get_hardware_info", &timing::MIBIONode::get_hardware_info, py::arg("print_out") = false) .def("get_sfp_status", &timing::MIBIONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) .def("switch_sfp_soft_tx_control_bit", &timing::MIBIONode::switch_sfp_soft_tx_control_bit) + .def("switch_sfp_tx", &timing::MIBIONode::switch_sfp_tx) ; py::class_(m, "SwitchyardNode") @@ -169,6 +176,7 @@ register_io(py::module& m) .def("get_hardware_info", &timing::MIBV2IONode::get_hardware_info, py::arg("print_out") = false) .def("get_sfp_status", &timing::MIBV2IONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) .def("switch_sfp_soft_tx_control_bit", &timing::MIBV2IONode::switch_sfp_soft_tx_control_bit) + .def("switch_sfp_tx", &timing::MIBV2IONode::switch_sfp_tx) ; py::class_(m, "GIBIONode") @@ -187,6 +195,7 @@ register_io(py::module& m) .def("get_sfp_status", &timing::GIBIONode::get_sfp_status, py::arg("sfp_id"), py::arg("print_out") = false) .def("switch_sfp_soft_tx_control_bit", &timing::GIBIONode::switch_sfp_soft_tx_control_bit) .def("set_i2c_mux_channels", &timing::GIBIONode::set_i2c_mux_channels) + .def("switch_sfp_tx", &timing::GIBIONode::switch_sfp_tx) ; } // NOLINT diff --git a/python/timing/cli/io.py b/python/timing/cli/io.py index 090b624..e86b412 100644 --- a/python/timing/cli/io.py +++ b/python/timing/cli/io.py @@ -180,9 +180,9 @@ def clkstatus(ctx, obj, verbose): ctx.invoke(status) - #if lBoardType in [kBoardPC059, kBoardFIB]: - # mux_fib = lIO.read_active_downstream_mux_channel() - # secho("Active sfp mux {} ".format(mux_fib)) + if lBoardType == kBoardPC059: #TODO or lBoardRevision == kFIBRev1 + mux_fib = lIO.read_active_downstream_mux_channel() + secho("Active sfp mux {} ".format(mux_fib)) echo() ctx.invoke(freq) @@ -282,17 +282,10 @@ def switchsfptx(ctx, obj, sfp_id, on): if lBoardType in kLibrarySupportedBoards: ctx.invoke(print_hardware_info) - if sfp_id is not None: - lIO.switch_sfp_soft_tx_control_bit(sfp_id, on) - echo(lIO.get_sfp_status(sfp_id)) - else: - if lBoardType == kBoardFMC or lBoardType == kBoardTLU: - lIO.switch_sfp_soft_tx_control_bit(0, on) - echo(lIO.get_sfp_status(0)) - elif ( lBoardType == kBoardPC059 ): - for i in range(9): - lIO.switch_sfp_soft_tx_control_bit(i, on) - echo(lIO.get_sfp_status(i)) + lSFP=sfp_id + if sfp_id is None: + lSFP=0 + lIO.switch_sfp_tx(lSFP, on) else: secho("Board {} not supported by timing library".format(lBoardType), fg='yellow') # do sfp switch here diff --git a/src/FIBV2IONode.cpp b/src/FIBV2IONode.cpp index f5232ca..38095eb 100644 --- a/src/FIBV2IONode.cpp +++ b/src/FIBV2IONode.cpp @@ -124,12 +124,15 @@ FIBV2IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const //----------------------------------------------------------------------------- void FIBV2IONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned) + validate_sfp_id(sfp_id); - - uint8_t current_sfp_tx_control_flags = getNode("csr.ctrl.sfp_tx_disable").read(); // NOLINT(build/unsigned) - getClient().dispatch(); + auto sfp_tx_control_flags = getNode("csr.ctrl.sfp_tx_disable").read(); // NOLINT(build/unsigned) + getClient().dispatch(); + + uint8_t current_sfp_tx_control_flags=sfp_tx_control_flags.value(); uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned) + if (turn_on) { new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id); diff --git a/src/FMCIONode.cpp b/src/FMCIONode.cpp index e377719..18cf96e 100644 --- a/src/FMCIONode.cpp +++ b/src/FMCIONode.cpp @@ -197,5 +197,28 @@ FMCIONode::get_clock_frequencies_table(bool print_out) const // } // } //----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void +FMCIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned) +{ + validate_sfp_id(sfp_id); + + getNode("csr.ctrl.sfp_tx_dis").write(turn_on); + getClient().dispatch(); +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void +FMCIONode::validate_sfp_id(uint32_t sfp_id) const +{ // NOLINT(build/unsigned) + // on this board we have 3 upstream SFPs + if (sfp_id != 0) + { + throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id)); + } +} +//----------------------------------------------------------------------------- } // namespace timing } // namespace dunedaq diff --git a/src/GIBIONode.cpp b/src/GIBIONode.cpp index 412fa2e..49a8a2a 100644 --- a/src/GIBIONode.cpp +++ b/src/GIBIONode.cpp @@ -193,6 +193,28 @@ GIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { } //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void +GIBIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned) + validate_sfp_id(sfp_id); + + auto sfp_expander_1 = get_i2c_device(m_uid_i2c_bus, "SFPExpander1"); + uint8_t current_sfp_tx_control_flags = sfp_expander_1->read_outputs_config(1); // NOLINT(build/unsigned) + + uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned) + if (turn_on) + { + new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id); + } + else + { + new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id); + } + + sfp_expander_1->set_outputs(1, new_sfp_tx_control_flags); +} +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- //void //GIBIONode::get_info(timinghardwareinfo::TimingGIBMonitorData& mon_data) const diff --git a/src/MIBV2IONode.cpp b/src/MIBV2IONode.cpp index 0b5b574..c551765 100644 --- a/src/MIBV2IONode.cpp +++ b/src/MIBV2IONode.cpp @@ -122,6 +122,31 @@ MIBV2IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const } //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void +MIBV2IONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned) +{ + // TODO firmware support needed + //validate_sfp_id(sfp_id); + + //uint8_t current_sfp_tx_control_flags = getNode("csr.ctrl.sfp_tx_disable").read(); // NOLINT(build/unsigned) + //getClient().dispatch(); + + //uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned) + //if (turn_on) + //{ + // new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id); + //} + //else + //{ + // new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id); + //} + + //getNode("csr.ctrl.sfp_tx_disable").write(new_sfp_tx_control_flags); + //getClient().dispatch(); +} +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- //void //MIBV2IONode::get_info(timinghardwareinfo::TimingMIBV2MonitorData& mon_data) const diff --git a/src/PC059IONode.cpp b/src/PC059IONode.cpp index 31987f8..af9267a 100644 --- a/src/PC059IONode.cpp +++ b/src/PC059IONode.cpp @@ -94,7 +94,7 @@ PC059IONode::reset(const std::string& clock_config_file) const sfp_expander->set_inversion(0, 0x00); sfp_expander->set_inversion(1, 0x00); - // Bank 0 input, bank 1 output + // Bank 0 output, bank 1 input sfp_expander->set_io(0, 0x00); sfp_expander->set_io(1, 0xff); @@ -195,6 +195,41 @@ PC059IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const } //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void +PC059IONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned) + + validate_sfp_id(sfp_id); + + auto sfp_expander = get_i2c_device(m_uid_i2c_bus, "SFPExpander"); + uint8_t current_sfp_tx_control_flags = sfp_expander->read_outputs_config(0); // NOLINT(build/unsigned) + + uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned) + if (turn_on) + { + new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id); + } + else + { + new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id); + } + + sfp_expander->set_outputs(0, new_sfp_tx_control_flags); +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void +PC059IONode::validate_sfp_id(uint32_t sfp_id) const // NOLINT(build/unsigned) +{ + // on this board we have 8 downstream SFPs + if (sfp_id > 7) + { + throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id)); + } +} +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // void // PC059IONode::get_info(timinghardwareinfo::TimingPC059MonitorData& mon_data) const diff --git a/src/SIMIONode.cpp b/src/SIMIONode.cpp index be5c995..7b2a6f9 100644 --- a/src/SIMIONode.cpp +++ b/src/SIMIONode.cpp @@ -173,5 +173,13 @@ SIMIONode::switch_sfp_soft_tx_control_bit(uint32_t /*sfp_id*/, bool /*turn_on*/) } //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void +SIMIONode::switch_sfp_tx(uint32_t /*sfp_id*/, bool /*turn_on*/) const // NOLINT(build/unsigned) +{ + TLOG_DEBUG(0) << "Simulation does not support SFP control"; +} +//----------------------------------------------------------------------------- + } // namespace timing } // namespace dunedaq \ No newline at end of file diff --git a/src/TLUIONode.cpp b/src/TLUIONode.cpp index a02dbf1..823e967 100644 --- a/src/TLUIONode.cpp +++ b/src/TLUIONode.cpp @@ -154,6 +154,29 @@ TLUIONode::switch_sfp_soft_tx_control_bit(uint32_t /*sfp_id*/, bool /*turn_on*/) } //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void +TLUIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned) +{ + validate_sfp_id(sfp_id); + + getNode("csr.ctrl.sfp_tx_dis").write(turn_on); + getClient().dispatch(); +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void +TLUIONode::validate_sfp_id(uint32_t sfp_id) const +{ // NOLINT(build/unsigned) + // on this board we have 3 upstream SFPs + if (sfp_id != 0) + { + throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id)); + } +} +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // void // TLUIONode::get_info(timinghardwareinfo::TimingTLUMonitorData& mon_data) const