1 /** 2 * Copyright © 2020 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <cmath> 19 #include <cstdint> 20 #include <string> 21 22 /** 23 * @namespace pmbus_utils 24 * 25 * Contains utilities for sending PMBus commands over an I2C interface. 26 */ 27 namespace phosphor::power::regulators::pmbus_utils 28 { 29 30 /* 31 * PMBus command codes. 32 * 33 * The constant names are all uppercase to match the PMBus documentation. 34 * 35 * Only the commands that are currently used by this application are defined. 36 * See the PMBus documentation for all valid command codes. 37 */ 38 const uint8_t VOUT_MODE{0x20u}; 39 const uint8_t VOUT_COMMAND{0x21u}; 40 41 /** 42 * Sensor data format. 43 */ 44 enum class SensorDataFormat 45 { 46 /** 47 * Linear data format used for values not related to voltage output, such 48 * as output current, input voltage, and temperature. Two byte value with 49 * an 11-bit, two's complement mantissa and a 5-bit, two's complement 50 * exponent. 51 */ 52 linear_11, 53 54 /** 55 * Linear data format used for values related to voltage output. Two 56 * byte (16-bit), unsigned integer that is raised to the power of an 57 * exponent. The exponent is not stored within the two bytes. 58 */ 59 linear_16 60 }; 61 62 /** 63 * Sensor Value Type. 64 */ 65 enum class SensorValueType 66 { 67 /** 68 * Output current. 69 */ 70 iout, 71 72 /** 73 * Highest output current. 74 */ 75 iout_peak, 76 77 /** 78 * Lowest output current. 79 */ 80 iout_valley, 81 82 /** 83 * Output power. 84 */ 85 pout, 86 87 /** 88 * Temperature. 89 */ 90 temperature, 91 92 /** 93 * Highest temperature. 94 */ 95 temperature_peak, 96 97 /** 98 * Output voltage. 99 */ 100 vout, 101 102 /** 103 * Highest output voltage. 104 */ 105 vout_peak, 106 107 /** 108 * Lowest output voltage. 109 */ 110 vout_valley 111 }; 112 113 /** 114 * Data formats for output voltage. 115 * 116 * These formats are used for commanding and reading output voltage and related 117 * parameters. 118 */ 119 enum class VoutDataFormat 120 { 121 /** 122 * Linear scale that uses a two byte unsigned binary integer with a scaling 123 * factor. 124 */ 125 linear, 126 127 /** 128 * Format that supports transmitting VID codes. 129 */ 130 vid, 131 132 /** 133 * Direct format that uses an equation and device supplied coefficients. 134 */ 135 direct, 136 137 /** 138 * Half-precision floating point format that follows the IEEE-754 standard 139 * for representing magnitudes in 16 bits. 140 */ 141 ieee 142 }; 143 144 /** 145 * Parse the one byte value of the VOUT_MODE command. 146 * 147 * VOUT_MODE contains a 'mode' field that indicates the data format used for 148 * output voltage values. 149 * 150 * VOUT_MODE also contains a 'parameter' field whose value is dependent on the 151 * data format: 152 * - Linear format: value is an exponent 153 * - VID format: value is a VID code 154 * - IEEE and Direct formats: value is not used 155 * 156 * @param voutModeValue one byte value of VOUT_MODE command 157 * @param format data format from the 'mode' field 158 * @param parameter parameter value from the 'parameter' field 159 */ 160 void parseVoutMode(uint8_t voutModeValue, VoutDataFormat& format, 161 int8_t& parameter); 162 163 /** 164 * Converts the specified SensorDataFormat value to a string. 165 * 166 * @param format SensorDataFormat value 167 * @return string corresponding to the enum value 168 */ 169 std::string toString(SensorDataFormat format); 170 171 /** 172 * Converts the specified SensorValueType value to string. 173 * 174 * @param type SensorValueType type 175 * @return string corresponding to the enum value 176 */ 177 std::string toString(SensorValueType type); 178 179 /** 180 * Converts the specified VoutDataFormat value to string. 181 * 182 * @param format VoutDataFormat format 183 * @return string corresponding to the enum value 184 */ 185 std::string toString(VoutDataFormat format); 186 187 /** 188 * Converts a volts value to the linear data format for output voltage. 189 * 190 * This data format consists of the following: 191 * - Two byte value 192 * - 16-bit unsigned mantissa value stored in the two bytes 193 * - 5-bit signed exponent value that is not stored in the two bytes 194 * 195 * The exponent value is typically obtained from the PMBus VOUT_MODE command 196 * or from the hardware device documentation (data sheet). 197 * 198 * Note that this format differs from the linear data format for values 199 * unrelated to output voltage. 200 * 201 * @param volts volts value to convert; must not be negative 202 * @param exponent 5-bit signed exponent used to convert value 203 * @return linear data format value 204 */ 205 inline uint16_t convertToVoutLinear(double volts, int8_t exponent) 206 { 207 // Obtain mantissa using equation 'mantissa = volts / 2^exponent' 208 double mantissa = volts / std::pow(2.0, static_cast<double>(exponent)); 209 210 // Return the mantissa value after converting to a rounded uint16_t 211 return static_cast<uint16_t>(std::lround(mantissa)); 212 } 213 214 } // namespace phosphor::power::regulators::pmbus_utils 215