blob: 5e2e270414a85aa1c28c6674308d8e34621a113a [file] [log] [blame]
Shawn McCarney6663abf2020-02-29 17:25:48 -06001/**
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>
Bob Kingd6820bb2020-04-28 15:37:02 +080020#include <string>
Shawn McCarney6663abf2020-02-29 17:25:48 -060021
22/**
23 * @namespace pmbus_utils
24 *
25 * Contains utilities for sending PMBus commands over an I2C interface.
26 */
27namespace 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 */
38const uint8_t VOUT_MODE{0x20u};
39const uint8_t VOUT_COMMAND{0x21u};
40
41/**
Bob Kingd6820bb2020-04-28 15:37:02 +080042 * Sensor data format.
43 */
44enum 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 */
65enum 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/**
Shawn McCarney6663abf2020-02-29 17:25:48 -0600114 * Data formats for output voltage.
115 *
116 * These formats are used for commanding and reading output voltage and related
117 * parameters.
118 */
119enum 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 */
160void parseVoutMode(uint8_t voutModeValue, VoutDataFormat& format,
161 int8_t& parameter);
162
163/**
Bob Kingd6820bb2020-04-28 15:37:02 +0800164 * Converts the specified SensorDataFormat value to a string.
165 *
166 * @param format SensorDataFormat value
167 * @return string corresponding to the enum value
168 */
169std::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 */
177std::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 */
185std::string toString(VoutDataFormat format);
186
187/**
Shawn McCarney6663abf2020-02-29 17:25:48 -0600188 * 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 */
205inline 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