23 , m_calibration_parameter_start_addresses({ 0x4C, 0x50, 0x54, 0x58 })
56std::pair<double, double>
62 auto parameter_array = this->read_i2cArray(0x51, m_calibration_parameter_start_addresses.at(calib_parameter_id), 0x4);
65 double slope = parameter_array.at(0) + (parameter_array.at(1) / 256.0);
67 uint32_t offset_raw = (parameter_array.at(2) & 0x7f) << 8 | parameter_array.at(3);
70 double offset = parameter_array.at(2) & (1UL << 7) ? offset_raw - 0x8000 : offset_raw;
72 return std::make_pair(slope,
offset);
81 auto temperature_array = this->
read_i2cArray(0x51, 0x60, 0x2);
84 double temperature = temperature_array.at(0) & (1UL << 7) ? (temperature_array.at(0) & 0x7f) - 0xff : temperature_array.at(0);
85 return temperature + (temperature_array.at(1) / 256.0);
95 return temperature_raw * temp_calib_pair.first + temp_calib_pair.second;
105 return (voltage_array.at(0) << 8) | voltage_array.at(1);
115 return ((voltage_raw * temp_calib_pair.first) + temp_calib_pair.second) * 1e-4;
125 return (rx_power_array.at(0) << 8) | rx_power_array.at(1);
135 std::vector<uint32_t> rx_param_start_adr = { 0x48, 0x44, 0x40, 0x3C, 0x38 };
136 std::vector<double> rx_parameters;
137 for (
auto it = rx_param_start_adr.begin(); it != rx_param_start_adr.end(); ++it) {
138 uint32_t parameter_bits = 0;
141 for (
auto jt = parameter_array.begin(); jt != parameter_array.end(); ++jt)
142 parameter_bits = (parameter_bits << 8) | *jt;
146 rx_parameters.push_back(parameter);
149 double rx_power_calib = 0;
150 for (uint32_t i = 0; i < rx_parameters.size(); ++i) {
151 double parameter = rx_parameters.at(i);
152 rx_power_calib = rx_power_calib + (parameter * pow(rx_power_raw, i));
154 return rx_power_calib * 0.1;
164 return (tx_power_array.at(0) << 8) | tx_power_array.at(1);
174 return ((tx_power_raw * temp_calib_pair.first) + temp_calib_pair.second) * 0.1;
184 return (current_array.at(0) << 8) | current_array.at(1);
194 return ((current_raw * temp_calib_pair.first) + temp_calib_pair.second) * 0.002;
204 std::stringstream vendor_name;
205 auto vendor_name_characters = this->
read_i2cArray(0x14, 0x10);
206 for (
auto it = vendor_name_characters.begin(); it != vendor_name_characters.end(); ++it) {
209 return vendor_name.str();
219 std::stringstream vendor_pn;
221 for (
auto it = vendor_pn_characters.begin(); it != vendor_pn_characters.end(); ++it) {
224 return vendor_pn.str();
234 std::stringstream serial_number;
235 auto serial_number_characters = this->
read_i2cArray(0x44, 0x10);
236 for (
auto it = serial_number_characters.begin(); it != serial_number_characters.end(); ++it) {
237 serial_number << *it;
239 return serial_number.str();
250 auto ddm_info_byte = this->
read_i2c(0x5C);
251 return ddm_info_byte & 0x40;
262 auto enhanced_options_byte = this->
read_i2c(0x5d);
263 return enhanced_options_byte & 0x40;
272 auto opt_status_ctrl_byte = this->
read_i2c(0x51, 0x6e);
274 return opt_status_ctrl_byte & 0x40;
283 auto opt_status_ctrl_byte = this->
read_i2c(0x51, 0x6e);
285 return opt_status_ctrl_byte & 0x80;
295 auto ddm_info_byte = this->
read_i2c(0x5C);
297 return ddm_info_byte & 0x4;
312 auto opt_status_ctrl_byte = this->
read_i2c(0x51, 0x6e);
314 uint8_t new_opt_status_ctrl_byte;
317 new_opt_status_ctrl_byte = opt_status_ctrl_byte & ~(1UL << 6);
319 new_opt_status_ctrl_byte = opt_status_ctrl_byte | (1UL << 6);
321 this->
write_i2c(0x51, 0x6e, new_opt_status_ctrl_byte);
331 std::stringstream status;
332 std::vector<std::pair<std::string, std::string>> sfp_info;
348 TLOG() << status.str();
352 TLOG() <<
"SFP DDM I2C address swap not supported. SFP on I2C bus: " <<
get_master_id();
355 TLOG() << status.str();
360 std::stringstream temperature_stream;
361 temperature_stream << std::dec << std::fixed << std::setprecision(2) <<
read_temperature() <<
" C";
362 sfp_info.push_back(std::make_pair(
"Temperature", temperature_stream.str()));
364 std::stringstream voltage_stream;
365 voltage_stream << std::dec << std::fixed << std::setprecision(2) <<
read_voltage() <<
" V";
366 sfp_info.push_back(std::make_pair(
"Supply voltage", voltage_stream.str()));
368 std::stringstream rx_power_stream;
369 rx_power_stream << std::dec << std::fixed << std::setprecision(2) <<
read_rx_ower() <<
" uW";
370 sfp_info.push_back(std::make_pair(
"Rx power", rx_power_stream.str()));
372 std::stringstream tx_power_stream;
373 tx_power_stream << std::dec << std::fixed << std::setprecision(2) <<
read_tx_power() <<
" uW";
374 sfp_info.push_back(std::make_pair(
"Tx power", tx_power_stream.str()));
376 std::stringstream current_stream;
377 current_stream << std::dec << std::fixed << std::setprecision(2) <<
read_current() <<
" uA";
378 sfp_info.push_back(std::make_pair(
"Tx current", current_stream.str()));
384 sfp_info.push_back(std::make_pair(
"Soft Tx disbale supported",
"False"));
391 TLOG() << status.str();
460 ,
I2CSFPSlave(this, this->get_slave_address("SFP_EEProm"))
467 ,
I2CSFPSlave(this, this->get_slave_address(
"SFP_EEProm"))
I2CSFPNode(const uhal::Node &node)
I2C slave class to control SFP transceivers.
double read_temperature_raw() const
Read the raw SFP temperature.
double read_rx_power_raw() const
Read the raw SFP temperature.
double read_tx_power_raw() const
Read the raw SFP tx power.
I2CSFPSlave(const I2CMasterNode *i2c_master, uint8_t i2c_device_address)
std::string read_serial_number() const
Read the SFP serial number.
bool read_tx_disable_pin_state() const
Read the state of the tx disable control pin.
void sfp_reachable() const
Check if SFP responds.
std::string read_vendor_part_number() const
Read the vendor name.
bool read_ddm_support_bit() const
Find out if SFP supports DDM.
void switch_soft_tx_control_bit(bool turn_on) const
Switch on or off the SFP tx laser via the soft control bit.
double read_rx_ower() const
Read the raw SFP temperature.
double read_temperature() const
Read the calibrated SFP temperature.
bool read_soft_tx_control_support_bit() const
Find out if SFP supports soft tx laser disable.
std::string get_status(bool print_out=false) const
Get SFP status.
bool read_i2c_reg_addressSwapBit() const
Read whether the SFP has seperate I2C addresses, or if a special I2C address swap is required....
double read_voltage_raw() const
Read the raw SFP voltage.
double read_current_raw() const
Read the raw SFP current.
void ddm_available() const
Check if DDM is supported.
std::string read_vendor_name() const
Read the vendor name.
std::pair< double, double > read_calibration_parameter_pair(uint32_t calib_parameter_id) const
Read the raw SFP temperature.
double read_tx_power() const
Read the calibrated SFP tx power.
bool read_soft_tx_control_state() const
Read the value of the soft tx disable control bit.
double read_voltage() const
Read the calibrated SFP voltage.
double read_current() const
Read the calibrated SFP current.
uint8_t read_i2c(uint32_t i2c_device_address, uint32_t i2c_reg_address) const
comodity functions
std::vector< uint8_t > read_i2cArray(uint32_t i2c_device_address, uint32_t i2c_reg_address, uint32_t number_of_words) const
std::string get_master_id() const
void write_i2c(uint32_t i2c_device_address, uint32_t i2c_reg_address, uint8_t data, bool send_stop=true) const
std::string format_reg_table(T data, std::string title, std::vector< std::string > headers)
Format reg-value table.
double convert_bits_to_float(uint64_t bits, bool is_double_precision=false)