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 21 /** 22 * @namespace pmbus_utils 23 * 24 * Contains utilities for sending PMBus commands over an I2C interface. 25 */ 26 namespace phosphor::power::regulators::pmbus_utils 27 { 28 29 /* 30 * PMBus command codes. 31 * 32 * The constant names are all uppercase to match the PMBus documentation. 33 * 34 * Only the commands that are currently used by this application are defined. 35 * See the PMBus documentation for all valid command codes. 36 */ 37 const uint8_t VOUT_MODE{0x20u}; 38 const uint8_t VOUT_COMMAND{0x21u}; 39 40 /** 41 * Data formats for output voltage. 42 * 43 * These formats are used for commanding and reading output voltage and related 44 * parameters. 45 */ 46 enum class VoutDataFormat 47 { 48 /** 49 * Linear scale that uses a two byte unsigned binary integer with a scaling 50 * factor. 51 */ 52 linear, 53 54 /** 55 * Format that supports transmitting VID codes. 56 */ 57 vid, 58 59 /** 60 * Direct format that uses an equation and device supplied coefficients. 61 */ 62 direct, 63 64 /** 65 * Half-precision floating point format that follows the IEEE-754 standard 66 * for representing magnitudes in 16 bits. 67 */ 68 ieee 69 }; 70 71 /** 72 * Parse the one byte value of the VOUT_MODE command. 73 * 74 * VOUT_MODE contains a 'mode' field that indicates the data format used for 75 * output voltage values. 76 * 77 * VOUT_MODE also contains a 'parameter' field whose value is dependent on the 78 * data format: 79 * - Linear format: value is an exponent 80 * - VID format: value is a VID code 81 * - IEEE and Direct formats: value is not used 82 * 83 * @param voutModeValue one byte value of VOUT_MODE command 84 * @param format data format from the 'mode' field 85 * @param parameter parameter value from the 'parameter' field 86 */ 87 void parseVoutMode(uint8_t voutModeValue, VoutDataFormat& format, 88 int8_t& parameter); 89 90 /** 91 * Converts a volts value to the linear data format for output voltage. 92 * 93 * This data format consists of the following: 94 * - Two byte value 95 * - 16-bit unsigned mantissa value stored in the two bytes 96 * - 5-bit signed exponent value that is not stored in the two bytes 97 * 98 * The exponent value is typically obtained from the PMBus VOUT_MODE command 99 * or from the hardware device documentation (data sheet). 100 * 101 * Note that this format differs from the linear data format for values 102 * unrelated to output voltage. 103 * 104 * @param volts volts value to convert; must not be negative 105 * @param exponent 5-bit signed exponent used to convert value 106 * @return linear data format value 107 */ 108 inline uint16_t convertToVoutLinear(double volts, int8_t exponent) 109 { 110 // Obtain mantissa using equation 'mantissa = volts / 2^exponent' 111 double mantissa = volts / std::pow(2.0, static_cast<double>(exponent)); 112 113 // Return the mantissa value after converting to a rounded uint16_t 114 return static_cast<uint16_t>(std::lround(mantissa)); 115 } 116 117 } // namespace phosphor::power::regulators::pmbus_utils 118