blob: 5e2e270414a85aa1c28c6674308d8e34621a113a [file] [log] [blame]
/**
* Copyright © 2020 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cmath>
#include <cstdint>
#include <string>
/**
* @namespace pmbus_utils
*
* Contains utilities for sending PMBus commands over an I2C interface.
*/
namespace phosphor::power::regulators::pmbus_utils
{
/*
* PMBus command codes.
*
* The constant names are all uppercase to match the PMBus documentation.
*
* Only the commands that are currently used by this application are defined.
* See the PMBus documentation for all valid command codes.
*/
const uint8_t VOUT_MODE{0x20u};
const uint8_t VOUT_COMMAND{0x21u};
/**
* Sensor data format.
*/
enum class SensorDataFormat
{
/**
* Linear data format used for values not related to voltage output, such
* as output current, input voltage, and temperature. Two byte value with
* an 11-bit, two's complement mantissa and a 5-bit, two's complement
* exponent.
*/
linear_11,
/**
* Linear data format used for values related to voltage output. Two
* byte (16-bit), unsigned integer that is raised to the power of an
* exponent. The exponent is not stored within the two bytes.
*/
linear_16
};
/**
* Sensor Value Type.
*/
enum class SensorValueType
{
/**
* Output current.
*/
iout,
/**
* Highest output current.
*/
iout_peak,
/**
* Lowest output current.
*/
iout_valley,
/**
* Output power.
*/
pout,
/**
* Temperature.
*/
temperature,
/**
* Highest temperature.
*/
temperature_peak,
/**
* Output voltage.
*/
vout,
/**
* Highest output voltage.
*/
vout_peak,
/**
* Lowest output voltage.
*/
vout_valley
};
/**
* Data formats for output voltage.
*
* These formats are used for commanding and reading output voltage and related
* parameters.
*/
enum class VoutDataFormat
{
/**
* Linear scale that uses a two byte unsigned binary integer with a scaling
* factor.
*/
linear,
/**
* Format that supports transmitting VID codes.
*/
vid,
/**
* Direct format that uses an equation and device supplied coefficients.
*/
direct,
/**
* Half-precision floating point format that follows the IEEE-754 standard
* for representing magnitudes in 16 bits.
*/
ieee
};
/**
* Parse the one byte value of the VOUT_MODE command.
*
* VOUT_MODE contains a 'mode' field that indicates the data format used for
* output voltage values.
*
* VOUT_MODE also contains a 'parameter' field whose value is dependent on the
* data format:
* - Linear format: value is an exponent
* - VID format: value is a VID code
* - IEEE and Direct formats: value is not used
*
* @param voutModeValue one byte value of VOUT_MODE command
* @param format data format from the 'mode' field
* @param parameter parameter value from the 'parameter' field
*/
void parseVoutMode(uint8_t voutModeValue, VoutDataFormat& format,
int8_t& parameter);
/**
* Converts the specified SensorDataFormat value to a string.
*
* @param format SensorDataFormat value
* @return string corresponding to the enum value
*/
std::string toString(SensorDataFormat format);
/**
* Converts the specified SensorValueType value to string.
*
* @param type SensorValueType type
* @return string corresponding to the enum value
*/
std::string toString(SensorValueType type);
/**
* Converts the specified VoutDataFormat value to string.
*
* @param format VoutDataFormat format
* @return string corresponding to the enum value
*/
std::string toString(VoutDataFormat format);
/**
* Converts a volts value to the linear data format for output voltage.
*
* This data format consists of the following:
* - Two byte value
* - 16-bit unsigned mantissa value stored in the two bytes
* - 5-bit signed exponent value that is not stored in the two bytes
*
* The exponent value is typically obtained from the PMBus VOUT_MODE command
* or from the hardware device documentation (data sheet).
*
* Note that this format differs from the linear data format for values
* unrelated to output voltage.
*
* @param volts volts value to convert; must not be negative
* @param exponent 5-bit signed exponent used to convert value
* @return linear data format value
*/
inline uint16_t convertToVoutLinear(double volts, int8_t exponent)
{
// Obtain mantissa using equation 'mantissa = volts / 2^exponent'
double mantissa = volts / std::pow(2.0, static_cast<double>(exponent));
// Return the mantissa value after converting to a rounded uint16_t
return static_cast<uint16_t>(std::lround(mantissa));
}
} // namespace phosphor::power::regulators::pmbus_utils