16663abf3SShawn McCarney /**
26663abf3SShawn McCarney * Copyright © 2020 IBM Corporation
36663abf3SShawn McCarney *
46663abf3SShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License");
56663abf3SShawn McCarney * you may not use this file except in compliance with the License.
66663abf3SShawn McCarney * You may obtain a copy of the License at
76663abf3SShawn McCarney *
86663abf3SShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0
96663abf3SShawn McCarney *
106663abf3SShawn McCarney * Unless required by applicable law or agreed to in writing, software
116663abf3SShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS,
126663abf3SShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136663abf3SShawn McCarney * See the License for the specific language governing permissions and
146663abf3SShawn McCarney * limitations under the License.
156663abf3SShawn McCarney */
166663abf3SShawn McCarney #include "pmbus_utils.hpp"
176663abf3SShawn McCarney
186663abf3SShawn McCarney #include <cstdint>
196663abf3SShawn McCarney
206663abf3SShawn McCarney #include <gtest/gtest.h>
216663abf3SShawn McCarney
226663abf3SShawn McCarney using namespace phosphor::power::regulators;
236663abf3SShawn McCarney
TEST(PMBusUtilsTests,ParseVoutMode)246663abf3SShawn McCarney TEST(PMBusUtilsTests, ParseVoutMode)
256663abf3SShawn McCarney {
266663abf3SShawn McCarney uint8_t voutModeValue;
276663abf3SShawn McCarney pmbus_utils::VoutDataFormat format;
286663abf3SShawn McCarney int8_t parameter;
296663abf3SShawn McCarney
306663abf3SShawn McCarney // Linear format: Exponent is negative: 0b1'1111
316663abf3SShawn McCarney voutModeValue = 0b0001'1111u;
326663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
336663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear);
346663abf3SShawn McCarney EXPECT_EQ(parameter, -1);
356663abf3SShawn McCarney
366663abf3SShawn McCarney // Linear format: Exponent is negative: 0b1'0000
376663abf3SShawn McCarney voutModeValue = 0b1001'0000u;
386663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
396663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear);
406663abf3SShawn McCarney EXPECT_EQ(parameter, -16);
416663abf3SShawn McCarney
426663abf3SShawn McCarney // Linear format: Exponent is positive: 0b0'1111
436663abf3SShawn McCarney voutModeValue = 0b1000'1111u;
446663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
456663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear);
466663abf3SShawn McCarney EXPECT_EQ(parameter, 15);
476663abf3SShawn McCarney
486663abf3SShawn McCarney // Linear format: Exponent is positive: 0b0'0001
496663abf3SShawn McCarney voutModeValue = 0b0000'0001u;
506663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
516663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear);
526663abf3SShawn McCarney EXPECT_EQ(parameter, 1);
536663abf3SShawn McCarney
546663abf3SShawn McCarney // Linear format: Exponent is zero: 0b0'0000
556663abf3SShawn McCarney voutModeValue = 0b0000'0000u;
566663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
576663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::linear);
586663abf3SShawn McCarney EXPECT_EQ(parameter, 0);
596663abf3SShawn McCarney
606663abf3SShawn McCarney // VID format: VID code is 0b1'1111
616663abf3SShawn McCarney voutModeValue = 0b0011'1111u;
626663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
636663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid);
646663abf3SShawn McCarney EXPECT_EQ(parameter, 31);
656663abf3SShawn McCarney
666663abf3SShawn McCarney // VID format: VID code is 0b1'0000
676663abf3SShawn McCarney voutModeValue = 0b1011'0000u;
686663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
696663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid);
706663abf3SShawn McCarney EXPECT_EQ(parameter, 16);
716663abf3SShawn McCarney
726663abf3SShawn McCarney // VID format: VID code is 0b0'1111
736663abf3SShawn McCarney voutModeValue = 0b1010'1111u;
746663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
756663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid);
766663abf3SShawn McCarney EXPECT_EQ(parameter, 15);
776663abf3SShawn McCarney
786663abf3SShawn McCarney // VID format: VID code is 0b0'0001
796663abf3SShawn McCarney voutModeValue = 0b0010'0001u;
806663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
816663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid);
826663abf3SShawn McCarney EXPECT_EQ(parameter, 1);
836663abf3SShawn McCarney
846663abf3SShawn McCarney // VID format: VID code is 0b0'0000
856663abf3SShawn McCarney voutModeValue = 0b1010'0000u;
866663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
876663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::vid);
886663abf3SShawn McCarney EXPECT_EQ(parameter, 0);
896663abf3SShawn McCarney
906663abf3SShawn McCarney // Direct format
916663abf3SShawn McCarney voutModeValue = 0b1100'0000u;
926663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
936663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::direct);
946663abf3SShawn McCarney EXPECT_EQ(parameter, 0);
956663abf3SShawn McCarney
966663abf3SShawn McCarney // IEEE format
976663abf3SShawn McCarney voutModeValue = 0b0110'0000u;
986663abf3SShawn McCarney pmbus_utils::parseVoutMode(voutModeValue, format, parameter);
996663abf3SShawn McCarney EXPECT_EQ(format, pmbus_utils::VoutDataFormat::ieee);
1006663abf3SShawn McCarney EXPECT_EQ(parameter, 0);
1016663abf3SShawn McCarney }
1026663abf3SShawn McCarney
TEST(PMBusUtilsTests,ToString)103d6820bb8SBob King TEST(PMBusUtilsTests, ToString)
104d6820bb8SBob King {
105d6820bb8SBob King // Sensor data format: SensorDataFormat::linear_11
106d6820bb8SBob King {
107d6820bb8SBob King pmbus_utils::SensorDataFormat format =
108d6820bb8SBob King pmbus_utils::SensorDataFormat::linear_11;
109d6820bb8SBob King EXPECT_EQ(pmbus_utils::toString(format), "linear_11");
110d6820bb8SBob King }
111d6820bb8SBob King
112d6820bb8SBob King // Sensor data format: SensorDataFormat::linear_16
113d6820bb8SBob King {
114d6820bb8SBob King pmbus_utils::SensorDataFormat format =
115d6820bb8SBob King pmbus_utils::SensorDataFormat::linear_16;
116d6820bb8SBob King EXPECT_EQ(pmbus_utils::toString(format), "linear_16");
117d6820bb8SBob King }
118d6820bb8SBob King
119d6820bb8SBob King // Vout data format: VoutDataFormat::linear
120d6820bb8SBob King {
121d6820bb8SBob King pmbus_utils::VoutDataFormat format =
122d6820bb8SBob King pmbus_utils::VoutDataFormat::linear;
123d6820bb8SBob King EXPECT_EQ(pmbus_utils::toString(format), "linear");
124d6820bb8SBob King }
125d6820bb8SBob King
126d6820bb8SBob King // Vout data format: VoutDataFormat::vid
127d6820bb8SBob King {
128d6820bb8SBob King pmbus_utils::VoutDataFormat format = pmbus_utils::VoutDataFormat::vid;
129d6820bb8SBob King EXPECT_EQ(pmbus_utils::toString(format), "vid");
130d6820bb8SBob King }
131d6820bb8SBob King
132d6820bb8SBob King // Vout data format: VoutDataFormat::direct
133d6820bb8SBob King {
134d6820bb8SBob King pmbus_utils::VoutDataFormat format =
135d6820bb8SBob King pmbus_utils::VoutDataFormat::direct;
136d6820bb8SBob King EXPECT_EQ(pmbus_utils::toString(format), "direct");
137d6820bb8SBob King }
138d6820bb8SBob King
139d6820bb8SBob King // Vout data format: VoutDataFormat::ieee
140d6820bb8SBob King {
141d6820bb8SBob King pmbus_utils::VoutDataFormat format = pmbus_utils::VoutDataFormat::ieee;
142d6820bb8SBob King EXPECT_EQ(pmbus_utils::toString(format), "ieee");
143d6820bb8SBob King }
144d6820bb8SBob King }
145d6820bb8SBob King
TEST(PMBusUtilsTests,ConvertFromLinear)14619523dd6SBob King TEST(PMBusUtilsTests, ConvertFromLinear)
14719523dd6SBob King {
14819523dd6SBob King uint16_t value;
14919523dd6SBob King
15019523dd6SBob King // Minimum possible exponent value: -16
15119523dd6SBob King // mantissa : 511, exponent : -16, decimal = 511 * 2^-16 =
15219523dd6SBob King // 0.0077972412109375
15319523dd6SBob King value = 0x81ff;
15419523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0.0077972412109375);
15519523dd6SBob King
15619523dd6SBob King // Maximum possible exponent value: 15
15719523dd6SBob King // mantissa : 2, exponent : 15, decimal = 2 * 2^15 = 65536
15819523dd6SBob King value = 0x7802;
15919523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 65536);
16019523dd6SBob King
16119523dd6SBob King // Minimum possible mantissa value: -1024
16219523dd6SBob King // mantissa : -1024, exponent : 1, decimal = -1024 * 2^1 = -2048
16319523dd6SBob King value = 0x0c00;
16419523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), -2048);
16519523dd6SBob King
16619523dd6SBob King // Maximum possible mantissa value: 1023
16719523dd6SBob King // mantissa : 1023, exponent : -11, decimal = 1023 * 2^-11 = 0.49951171875
16819523dd6SBob King value = 0xabff;
16919523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0.49951171875);
17019523dd6SBob King
17119523dd6SBob King // Exponent = 0, mantissa > 0
17219523dd6SBob King // mantissa : 1, exponent : 0, decimal = 1 * 2^0 = 1
17319523dd6SBob King value = 0x0001;
17419523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 1);
17519523dd6SBob King
17619523dd6SBob King // Exponent > 0, mantissa > 0
17719523dd6SBob King // mantissa : 2, exponent : 1, decimal = 2 * 2^1 = 4
17819523dd6SBob King value = 0x0802;
17919523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 4);
18019523dd6SBob King
18119523dd6SBob King // Exponent < 0, mantissa > 0
18219523dd6SBob King // mantissa : 15, exponent : -1, decimal = 15 * 2^-1 = 7.5
18319523dd6SBob King value = 0xf80f;
18419523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 7.5);
18519523dd6SBob King
18619523dd6SBob King // Exponent > 0, mantissa = 0
18719523dd6SBob King // mantissa : 0, exponent : 3, decimal = 0 * 2^3 = 0
18819523dd6SBob King value = 0x1800;
18919523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), 0);
19019523dd6SBob King
19119523dd6SBob King // Exponent > 0, mantissa < 0
19219523dd6SBob King // mantissa : -2, exponent : 3, decimal = -2 * 2^3 = -16
19319523dd6SBob King value = 0x1ffe;
19419523dd6SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromLinear(value), -16);
19519523dd6SBob King }
19619523dd6SBob King
TEST(PMBusUtilsTests,ConvertFromVoutLinear)197*8d0b3ce2SBob King TEST(PMBusUtilsTests, ConvertFromVoutLinear)
198*8d0b3ce2SBob King {
199*8d0b3ce2SBob King uint16_t value;
200*8d0b3ce2SBob King int8_t exponent;
201*8d0b3ce2SBob King
202*8d0b3ce2SBob King // mantissa : 1, exponent : 2, decimal = 1 * 2^2 = 4
203*8d0b3ce2SBob King value = 0x0001;
204*8d0b3ce2SBob King exponent = 2;
205*8d0b3ce2SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 4);
206*8d0b3ce2SBob King
207*8d0b3ce2SBob King // mantissa : 15, exponent : 0, decimal = 15 * 2^0 = 15
208*8d0b3ce2SBob King value = 0x000f;
209*8d0b3ce2SBob King exponent = 0;
210*8d0b3ce2SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 15);
211*8d0b3ce2SBob King
212*8d0b3ce2SBob King // mantissa : 255, exponent : -3, decimal = 255 * 2^-3 = 31.875
213*8d0b3ce2SBob King value = 0x00ff;
214*8d0b3ce2SBob King exponent = -3;
215*8d0b3ce2SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent),
216*8d0b3ce2SBob King 31.875);
217*8d0b3ce2SBob King
218*8d0b3ce2SBob King // mantissa : 0, exponent : 10, decimal = 0 * 2^10 = 0
219*8d0b3ce2SBob King value = 0x0000;
220*8d0b3ce2SBob King exponent = 10;
221*8d0b3ce2SBob King EXPECT_DOUBLE_EQ(pmbus_utils::convertFromVoutLinear(value, exponent), 0);
222*8d0b3ce2SBob King }
223*8d0b3ce2SBob King
TEST(PMBusUtilsTests,ConvertToVoutLinear)2246663abf3SShawn McCarney TEST(PMBusUtilsTests, ConvertToVoutLinear)
2256663abf3SShawn McCarney {
2266663abf3SShawn McCarney double volts;
2276663abf3SShawn McCarney int8_t exponent;
2286663abf3SShawn McCarney
2296663abf3SShawn McCarney // Exponent > 0: Value is not rounded up
2306663abf3SShawn McCarney volts = 13.9;
2316663abf3SShawn McCarney exponent = 2;
2326663abf3SShawn McCarney // 13.9 / 2^2 == 3.475 = 3
2336663abf3SShawn McCarney EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 3);
2346663abf3SShawn McCarney
2356663abf3SShawn McCarney // Exponent > 0: Value is rounded up
2366663abf3SShawn McCarney volts = 14.0;
2376663abf3SShawn McCarney exponent = 2;
2386663abf3SShawn McCarney // 14.0 / 2^2 == 3.5 = 4
2396663abf3SShawn McCarney EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 4);
2406663abf3SShawn McCarney
2416663abf3SShawn McCarney // Exponent = 0: Value is not rounded up
2426663abf3SShawn McCarney volts = 2.49;
2436663abf3SShawn McCarney exponent = 0;
2446663abf3SShawn McCarney // 2.49 / 2^0 == 2.49 = 2
2456663abf3SShawn McCarney EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 2);
2466663abf3SShawn McCarney
2476663abf3SShawn McCarney // Exponent = 0: Value is rounded up
2486663abf3SShawn McCarney volts = 2.51;
2496663abf3SShawn McCarney exponent = 0;
2506663abf3SShawn McCarney // 2.51 / 2^0 == 2.51 = 3
2516663abf3SShawn McCarney EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 3);
2526663abf3SShawn McCarney
2536663abf3SShawn McCarney // Exponent < 0: Value is not rounded up
2546663abf3SShawn McCarney volts = 1.32613;
2556663abf3SShawn McCarney exponent = -8;
2566663abf3SShawn McCarney // 1.32613 / 2^-8 == 339.48928 == 339
2576663abf3SShawn McCarney EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 339);
2586663abf3SShawn McCarney
2596663abf3SShawn McCarney // Exponent < 0: Value is rounded up
2606663abf3SShawn McCarney volts = 1.32618;
2616663abf3SShawn McCarney exponent = -8;
2626663abf3SShawn McCarney // 1.32618 / 2^-8 == 339.50208 == 340
2636663abf3SShawn McCarney EXPECT_EQ(pmbus_utils::convertToVoutLinear(volts, exponent), 340);
2646663abf3SShawn McCarney }
265