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 // Sensor value type: SensorValueType::iout 120 { 121 pmbus_utils::SensorValueType type = pmbus_utils::SensorValueType::iout; 122 EXPECT_EQ(pmbus_utils::toString(type), "iout"); 123 } 124 125 // Sensor value type: SensorValueType::iout_peak 126 { 127 pmbus_utils::SensorValueType type = 128 pmbus_utils::SensorValueType::iout_peak; 129 EXPECT_EQ(pmbus_utils::toString(type), "iout_peak"); 130 } 131 132 // Sensor value type: SensorValueType::iout_valley 133 { 134 pmbus_utils::SensorValueType type = 135 pmbus_utils::SensorValueType::iout_valley; 136 EXPECT_EQ(pmbus_utils::toString(type), "iout_valley"); 137 } 138 139 // Sensor value type: SensorValueType::pout 140 { 141 pmbus_utils::SensorValueType type = pmbus_utils::SensorValueType::pout; 142 EXPECT_EQ(pmbus_utils::toString(type), "pout"); 143 } 144 145 // Sensor value type: SensorValueType::temperature 146 { 147 pmbus_utils::SensorValueType type = 148 pmbus_utils::SensorValueType::temperature; 149 EXPECT_EQ(pmbus_utils::toString(type), "temperature"); 150 } 151 152 // Sensor value type: SensorValueType::temperature_peak 153 { 154 pmbus_utils::SensorValueType type = 155 pmbus_utils::SensorValueType::temperature_peak; 156 EXPECT_EQ(pmbus_utils::toString(type), "temperature_peak"); 157 } 158 159 // Sensor value type: SensorValueType::vout 160 { 161 pmbus_utils::SensorValueType type = pmbus_utils::SensorValueType::vout; 162 EXPECT_EQ(pmbus_utils::toString(type), "vout"); 163 } 164 165 // Sensor value type: SensorValueType::vout_peak 166 { 167 pmbus_utils::SensorValueType type = 168 pmbus_utils::SensorValueType::vout_peak; 169 EXPECT_EQ(pmbus_utils::toString(type), "vout_peak"); 170 } 171 172 // Sensor value type: SensorValueType::vout_valley 173 { 174 pmbus_utils::SensorValueType type = 175 pmbus_utils::SensorValueType::vout_valley; 176 EXPECT_EQ(pmbus_utils::toString(type), "vout_valley"); 177 } 178 179 // Vout data format: VoutDataFormat::linear 180 { 181 pmbus_utils::VoutDataFormat format = 182 pmbus_utils::VoutDataFormat::linear; 183 EXPECT_EQ(pmbus_utils::toString(format), "linear"); 184 } 185 186 // Vout data format: VoutDataFormat::vid 187 { 188 pmbus_utils::VoutDataFormat format = pmbus_utils::VoutDataFormat::vid; 189 EXPECT_EQ(pmbus_utils::toString(format), "vid"); 190 } 191 192 // Vout data format: VoutDataFormat::direct 193 { 194 pmbus_utils::VoutDataFormat format = 195 pmbus_utils::VoutDataFormat::direct; 196 EXPECT_EQ(pmbus_utils::toString(format), "direct"); 197 } 198 199 // Vout data format: VoutDataFormat::ieee 200 { 201 pmbus_utils::VoutDataFormat format = pmbus_utils::VoutDataFormat::ieee; 202 EXPECT_EQ(pmbus_utils::toString(format), "ieee"); 203 } 204 } 205 206 TEST(PMBusUtilsTests, ConvertFromLinear) 207 { 208 uint16_t value; 209 210 // Minimum possible exponent value: -16 211 // mantissa : 511, exponent : -16, decimal = 511 * 2^-16 = 212 // 0.0077972412109375 213 value = 0x81ff; 214 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0.0077972412109375); 215 216 // Maximum possible exponent value: 15 217 // mantissa : 2, exponent : 15, decimal = 2 * 2^15 = 65536 218 value = 0x7802; 219 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 65536); 220 221 // Minimum possible mantissa value: -1024 222 // mantissa : -1024, exponent : 1, decimal = -1024 * 2^1 = -2048 223 value = 0x0c00; 224 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), -2048); 225 226 // Maximum possible mantissa value: 1023 227 // mantissa : 1023, exponent : -11, decimal = 1023 * 2^-11 = 0.49951171875 228 value = 0xabff; 229 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0.49951171875); 230 231 // Exponent = 0, mantissa > 0 232 // mantissa : 1, exponent : 0, decimal = 1 * 2^0 = 1 233 value = 0x0001; 234 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 1); 235 236 // Exponent > 0, mantissa > 0 237 // mantissa : 2, exponent : 1, decimal = 2 * 2^1 = 4 238 value = 0x0802; 239 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 4); 240 241 // Exponent < 0, mantissa > 0 242 // mantissa : 15, exponent : -1, decimal = 15 * 2^-1 = 7.5 243 value = 0xf80f; 244 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 7.5); 245 246 // Exponent > 0, mantissa = 0 247 // mantissa : 0, exponent : 3, decimal = 0 * 2^3 = 0 248 value = 0x1800; 249 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0); 250 251 // Exponent > 0, mantissa < 0 252 // mantissa : -2, exponent : 3, decimal = -2 * 2^3 = -16 253 value = 0x1ffe; 254 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), -16); 255 } 256 257 TEST(PMBusUtilsTests, ConvertFromVoutLinear) 258 { 259 uint16_t value; 260 int8_t exponent; 261 262 // mantissa : 1, exponent : 2, decimal = 1 * 2^2 = 4 263 value = 0x0001; 264 exponent = 2; 265 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 4); 266 267 // mantissa : 15, exponent : 0, decimal = 15 * 2^0 = 15 268 value = 0x000f; 269 exponent = 0; 270 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 15); 271 272 // mantissa : 255, exponent : -3, decimal = 255 * 2^-3 = 31.875 273 value = 0x00ff; 274 exponent = -3; 275 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 276 31.875); 277 278 // mantissa : 0, exponent : 10, decimal = 0 * 2^10 = 0 279 value = 0x0000; 280 exponent = 10; 281 EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 0); 282 } 283 284 TEST(PMBusUtilsTests, ConvertToVoutLinear) 285 { 286 double volts; 287 int8_t exponent; 288 289 // Exponent > 0: Value is not rounded up 290 volts = 13.9; 291 exponent = 2; 292 // 13.9 / 2^2 == 3.475 = 3 293 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 3); 294 295 // Exponent > 0: Value is rounded up 296 volts = 14.0; 297 exponent = 2; 298 // 14.0 / 2^2 == 3.5 = 4 299 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 4); 300 301 // Exponent = 0: Value is not rounded up 302 volts = 2.49; 303 exponent = 0; 304 // 2.49 / 2^0 == 2.49 = 2 305 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 2); 306 307 // Exponent = 0: Value is rounded up 308 volts = 2.51; 309 exponent = 0; 310 // 2.51 / 2^0 == 2.51 = 3 311 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 3); 312 313 // Exponent < 0: Value is not rounded up 314 volts = 1.32613; 315 exponent = -8; 316 // 1.32613 / 2^-8 == 339.48928 == 339 317 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 339); 318 319 // Exponent < 0: Value is rounded up 320 volts = 1.32618; 321 exponent = -8; 322 // 1.32618 / 2^-8 == 339.50208 == 340 323 EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 340); 324 } 325