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 #include "pmbus_utils.hpp" 17 18 #include <cstdint> 19 20 #include <gtest/gtest.h> 21 22 using namespace phosphor::power::regulators; 23 24 TEST(PMBusUtilsTests, ParseVoutMode) 25 { 26 uint8_t voutModeValue; 27 pmbus_utils::VoutDataFormat format; 28 int8_t parameter; 29 30 // Linear format: Exponent is negative: 0b1'1111 31 voutModeValue = 0b0001'1111u; 32 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 33 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear); 34 EXPECT_EQ(parameter, -1); 35 36 // Linear format: Exponent is negative: 0b1'0000 37 voutModeValue = 0b1001'0000u; 38 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 39 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear); 40 EXPECT_EQ(parameter, -16); 41 42 // Linear format: Exponent is positive: 0b0'1111 43 voutModeValue = 0b1000'1111u; 44 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 45 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear); 46 EXPECT_EQ(parameter, 15); 47 48 // Linear format: Exponent is positive: 0b0'0001 49 voutModeValue = 0b0000'0001u; 50 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 51 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear); 52 EXPECT_EQ(parameter, 1); 53 54 // Linear format: Exponent is zero: 0b0'0000 55 voutModeValue = 0b0000'0000u; 56 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 57 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear); 58 EXPECT_EQ(parameter, 0); 59 60 // VID format: VID code is 0b1'1111 61 voutModeValue = 0b0011'1111u; 62 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 63 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid); 64 EXPECT_EQ(parameter, 31); 65 66 // VID format: VID code is 0b1'0000 67 voutModeValue = 0b1011'0000u; 68 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 69 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid); 70 EXPECT_EQ(parameter, 16); 71 72 // VID format: VID code is 0b0'1111 73 voutModeValue = 0b1010'1111u; 74 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 75 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid); 76 EXPECT_EQ(parameter, 15); 77 78 // VID format: VID code is 0b0'0001 79 voutModeValue = 0b0010'0001u; 80 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 81 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid); 82 EXPECT_EQ(parameter, 1); 83 84 // VID format: VID code is 0b0'0000 85 voutModeValue = 0b1010'0000u; 86 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 87 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid); 88 EXPECT_EQ(parameter, 0); 89 90 // Direct format 91 voutModeValue = 0b1100'0000u; 92 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 93 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::direct); 94 EXPECT_EQ(parameter, 0); 95 96 // IEEE format 97 voutModeValue = 0b0110'0000u; 98 pmbus_utils::parseVoutMode(voutModeValue, format, parameter); 99 EXPECT_EQ(format, pmbus_utils::VoutDataFormat::ieee); 100 EXPECT_EQ(parameter, 0); 101 } 102 103 TEST(PMBusUtilsTests, ToString) 104 { 105 // Sensor data format: SensorDataFormat::linear_11 106 { 107 pmbus_utils::SensorDataFormat format = 108 pmbus_utils::SensorDataFormat::linear_11; 109 EXPECT_EQ(pmbus_utils::toString(format), "linear_11"); 110 } 111 112 // Sensor data format: SensorDataFormat::linear_16 113 { 114 pmbus_utils::SensorDataFormat format = 115 pmbus_utils::SensorDataFormat::linear_16; 116 EXPECT_EQ(pmbus_utils::toString(format), "linear_16"); 117 } 118 119 // Vout data format: VoutDataFormat::linear 120 { 121 pmbus_utils::VoutDataFormat format = 122 pmbus_utils::VoutDataFormat::linear; 123 EXPECT_EQ(pmbus_utils::toString(format), "linear"); 124 } 125 126 // Vout data format: VoutDataFormat::vid 127 { 128 pmbus_utils::VoutDataFormat format = pmbus_utils::VoutDataFormat::vid; 129 EXPECT_EQ(pmbus_utils::toString(format), "vid"); 130 } 131 132 // Vout data format: VoutDataFormat::direct 133 { 134 pmbus_utils::VoutDataFormat format = 135 pmbus_utils::VoutDataFormat::direct; 136 EXPECT_EQ(pmbus_utils::toString(format), "direct"); 137 } 138 139 // Vout data format: VoutDataFormat::ieee 140 { 141 pmbus_utils::VoutDataFormat format = pmbus_utils::VoutDataFormat::ieee; 142 EXPECT_EQ(pmbus_utils::toString(format), "ieee"); 143 } 144 } 145 146 TEST(PMBusUtilsTests, ConvertFromLinear) 147 { 148 uint16_t value; 149 150 // Minimum possible exponent value: -16 151 // mantissa : 511, exponent : -16, decimal = 511 * 2^-16 = 152 // 0.0077972412109375 153 value = 0x81ff; 154 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0.0077972412109375); 155 156 // Maximum possible exponent value: 15 157 // mantissa : 2, exponent : 15, decimal = 2 * 2^15 = 65536 158 value = 0x7802; 159 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 65536); 160 161 // Minimum possible mantissa value: -1024 162 // mantissa : -1024, exponent : 1, decimal = -1024 * 2^1 = -2048 163 value = 0x0c00; 164 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), -2048); 165 166 // Maximum possible mantissa value: 1023 167 // mantissa : 1023, exponent : -11, decimal = 1023 * 2^-11 = 0.49951171875 168 value = 0xabff; 169 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0.49951171875); 170 171 // Exponent = 0, mantissa > 0 172 // mantissa : 1, exponent : 0, decimal = 1 * 2^0 = 1 173 value = 0x0001; 174 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 1); 175 176 // Exponent > 0, mantissa > 0 177 // mantissa : 2, exponent : 1, decimal = 2 * 2^1 = 4 178 value = 0x0802; 179 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 4); 180 181 // Exponent < 0, mantissa > 0 182 // mantissa : 15, exponent : -1, decimal = 15 * 2^-1 = 7.5 183 value = 0xf80f; 184 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 7.5); 185 186 // Exponent > 0, mantissa = 0 187 // mantissa : 0, exponent : 3, decimal = 0 * 2^3 = 0 188 value = 0x1800; 189 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0); 190 191 // Exponent > 0, mantissa < 0 192 // mantissa : -2, exponent : 3, decimal = -2 * 2^3 = -16 193 value = 0x1ffe; 194 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), -16); 195 } 196 197 TEST(PMBusUtilsTests, ConvertFromVoutLinear) 198 { 199 uint16_t value; 200 int8_t exponent; 201 202 // mantissa : 1, exponent : 2, decimal = 1 * 2^2 = 4 203 value = 0x0001; 204 exponent = 2; 205 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 4); 206 207 // mantissa : 15, exponent : 0, decimal = 15 * 2^0 = 15 208 value = 0x000f; 209 exponent = 0; 210 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 15); 211 212 // mantissa : 255, exponent : -3, decimal = 255 * 2^-3 = 31.875 213 value = 0x00ff; 214 exponent = -3; 215 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 216 31.875); 217 218 // mantissa : 0, exponent : 10, decimal = 0 * 2^10 = 0 219 value = 0x0000; 220 exponent = 10; 221 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 0); 222 } 223 224 TEST(PMBusUtilsTests, ConvertToVoutLinear) 225 { 226 double volts; 227 int8_t exponent; 228 229 // Exponent > 0: Value is not rounded up 230 volts = 13.9; 231 exponent = 2; 232 // 13.9 / 2^2 == 3.475 = 3 233 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 3); 234 235 // Exponent > 0: Value is rounded up 236 volts = 14.0; 237 exponent = 2; 238 // 14.0 / 2^2 == 3.5 = 4 239 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 4); 240 241 // Exponent = 0: Value is not rounded up 242 volts = 2.49; 243 exponent = 0; 244 // 2.49 / 2^0 == 2.49 = 2 245 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 2); 246 247 // Exponent = 0: Value is rounded up 248 volts = 2.51; 249 exponent = 0; 250 // 2.51 / 2^0 == 2.51 = 3 251 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 3); 252 253 // Exponent < 0: Value is not rounded up 254 volts = 1.32613; 255 exponent = -8; 256 // 1.32613 / 2^-8 == 339.48928 == 339 257 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 339); 258 259 // Exponent < 0: Value is rounded up 260 volts = 1.32618; 261 exponent = -8; 262 // 1.32618 / 2^-8 == 339.50208 == 340 263 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 340); 264 } 265