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