blob: 599c23637bfa28abad362ba5d18af839c53c5900 [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>
20
21/**
22 * @namespace pmbus_utils
23 *
24 * Contains utilities for sending PMBus commands over an I2C interface.
25 */
26namespace 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 */
37const uint8_t VOUT_MODE{0x20u};
38const 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 */
46enum 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 */
87void 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 */
108inline 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