psu-ng: De-glitch all faults
Use DEGLITCH_LIMIT to determine all the faults. If a fault bit is on, do
not consider that a fault until it is seen at least DEGLITCH_LIMIT
times. With DEGLITCH_LIMIT set to 3, the monitor would need to see a
fault bit on 3 times in a row before indicating that the power supply
has that fault.
This was done earlier for the PGOOD fault detection.
Change-Id: I918c2fcdd1d90ae253ab268bd04aa7a0da0208b8
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/phosphor-power-supply/power_supply.cpp b/phosphor-power-supply/power_supply.cpp
index c2dccfb..cc846ac 100644
--- a/phosphor-power-supply/power_supply.cpp
+++ b/phosphor-power-supply/power_supply.cpp
@@ -193,15 +193,19 @@
{
if (statusWord & phosphor::pmbus::status_word::CML_FAULT)
{
- if (!cmlFault)
+ if (cmlFault < DEGLITCH_LIMIT)
{
log<level::ERR>(fmt::format("CML fault: STATUS_WORD = {:#04x}, "
"STATUS_CML = {:#02x}",
statusWord, statusCML)
.c_str());
- }
- cmlFault = true;
+ cmlFault++;
+ }
+ }
+ else
+ {
+ cmlFault = 0;
}
}
@@ -209,16 +213,16 @@
{
if (statusWord & phosphor::pmbus::status_word::INPUT_FAULT_WARN)
{
- if (!inputFault)
+ if (inputFault < DEGLITCH_LIMIT)
{
log<level::ERR>(fmt::format("INPUT fault: STATUS_WORD = {:#04x}, "
"STATUS_MFR_SPECIFIC = {:#02x}, "
"STATUS_INPUT = {:#02x}",
statusWord, statusMFR, statusInput)
.c_str());
- }
- inputFault = true;
+ inputFault++;
+ }
}
// If had INPUT/VIN_UV fault, and now off.
@@ -232,7 +236,7 @@
"STATUS_INPUT = {:#02x}",
statusWord, statusMFR, statusInput)
.c_str());
- inputFault = false;
+ inputFault = 0;
}
}
@@ -240,7 +244,7 @@
{
if (statusWord & phosphor::pmbus::status_word::VOUT_OV_FAULT)
{
- if (!voutOVFault)
+ if (voutOVFault < DEGLITCH_LIMIT)
{
log<level::ERR>(
fmt::format("VOUT_OV_FAULT fault: STATUS_WORD = {:#04x}, "
@@ -248,9 +252,13 @@
"STATUS_VOUT = {:#02x}",
statusWord, statusMFR, statusVout)
.c_str());
- }
- voutOVFault = true;
+ voutOVFault++;
+ }
+ }
+ else
+ {
+ voutOVFault = 0;
}
}
@@ -258,16 +266,20 @@
{
if (statusWord & phosphor::pmbus::status_word::IOUT_OC_FAULT)
{
- if (!ioutOCFault)
+ if (ioutOCFault < DEGLITCH_LIMIT)
{
log<level::ERR>(fmt::format("IOUT fault: STATUS_WORD = {:#04x}, "
"STATUS_MFR_SPECIFIC = {:#02x}, "
"STATUS_IOUT = {:#02x}",
statusWord, statusMFR, statusIout)
.c_str());
- }
- ioutOCFault = true;
+ ioutOCFault++;
+ }
+ }
+ else
+ {
+ ioutOCFault = 0;
}
}
@@ -276,7 +288,7 @@
if ((statusWord & phosphor::pmbus::status_word::VOUT_FAULT) &&
!(statusWord & phosphor::pmbus::status_word::VOUT_OV_FAULT))
{
- if (!voutUVFault)
+ if (voutUVFault < DEGLITCH_LIMIT)
{
log<level::ERR>(
fmt::format("VOUT_UV_FAULT fault: STATUS_WORD = {:#04x}, "
@@ -284,9 +296,13 @@
"STATUS_VOUT = {:#02x}",
statusWord, statusMFR, statusVout)
.c_str());
- }
- voutUVFault = true;
+ voutUVFault++;
+ }
+ }
+ else
+ {
+ voutUVFault = 0;
}
}
@@ -294,7 +310,7 @@
{
if (statusWord & phosphor::pmbus::status_word::FAN_FAULT)
{
- if (!fanFault)
+ if (fanFault < DEGLITCH_LIMIT)
{
log<level::ERR>(fmt::format("FANS fault/warning: "
"STATUS_WORD = {:#04x}, "
@@ -302,9 +318,13 @@
"STATUS_FANS_1_2 = {:#02x}",
statusWord, statusMFR, statusFans12)
.c_str());
- }
- fanFault = true;
+ fanFault++;
+ }
+ }
+ else
+ {
+ fanFault = 0;
}
}
@@ -312,7 +332,7 @@
{
if (statusWord & phosphor::pmbus::status_word::TEMPERATURE_FAULT_WARN)
{
- if (!tempFault)
+ if (tempFault < DEGLITCH_LIMIT)
{
log<level::ERR>(fmt::format("TEMPERATURE fault/warning: "
"STATUS_WORD = {:#04x}, "
@@ -321,9 +341,13 @@
statusWord, statusMFR,
statusTemperature)
.c_str());
- }
- tempFault = true;
+ tempFault++;
+ }
+ }
+ else
+ {
+ tempFault = 0;
}
}
@@ -356,17 +380,38 @@
// IBM MFR_SPECIFIC[4] is PS_Kill fault
if (statusMFR & 0x10)
{
- psKillFault = true;
+ if (psKillFault < DEGLITCH_LIMIT)
+ {
+ psKillFault++;
+ }
+ }
+ else
+ {
+ psKillFault = 0;
}
// IBM MFR_SPECIFIC[6] is 12Vcs fault.
if (statusMFR & 0x40)
{
- ps12VcsFault = true;
+ if (ps12VcsFault < DEGLITCH_LIMIT)
+ {
+ ps12VcsFault++;
+ }
+ }
+ else
+ {
+ ps12VcsFault = 0;
}
// IBM MFR_SPECIFIC[7] is 12V Current-Share fault.
if (statusMFR & 0x80)
{
- psCS12VFault = true;
+ if (psCS12VFault < DEGLITCH_LIMIT)
+ {
+ psCS12VFault++;
+ }
+ }
+ else
+ {
+ psCS12VFault = 0;
}
}
}
@@ -375,34 +420,37 @@
{
if (statusWord & phosphor::pmbus::status_word::MFR_SPECIFIC_FAULT)
{
- if (!mfrFault)
+ if (mfrFault < DEGLITCH_LIMIT)
{
log<level::ERR>(fmt::format("MFR fault: "
"STATUS_WORD = {:#04x} "
"STATUS_MFR_SPECIFIC = {:#02x}",
statusWord, statusMFR)
.c_str());
+ mfrFault++;
}
- mfrFault = true;
determineMFRFault();
}
+ else
+ {
+ mfrFault = 0;
+ }
}
void PowerSupply::analyzeVinUVFault()
{
if (statusWord & phosphor::pmbus::status_word::VIN_UV_FAULT)
{
- if (!vinUVFault)
+ if (vinUVFault < DEGLITCH_LIMIT)
{
log<level::ERR>(fmt::format("VIN_UV fault: STATUS_WORD = {:#04x}, "
"STATUS_MFR_SPECIFIC = {:#02x}, "
"STATUS_INPUT = {:#02x}",
statusWord, statusMFR, statusInput)
.c_str());
+ vinUVFault++;
}
-
- vinUVFault = true;
}
if (vinUVFault &&
@@ -414,7 +462,7 @@
"STATUS_INPUT = {:#02x}",
statusWord, statusMFR, statusInput)
.c_str());
- vinUVFault = false;
+ vinUVFault = 0;
}
}
diff --git a/phosphor-power-supply/power_supply.hpp b/phosphor-power-supply/power_supply.hpp
index eb53c14..b7459f5 100644
--- a/phosphor-power-supply/power_supply.hpp
+++ b/phosphor-power-supply/power_supply.hpp
@@ -109,20 +109,20 @@
*/
void clearFaultFlags()
{
- inputFault = false;
- mfrFault = false;
+ inputFault = 0;
+ mfrFault = 0;
statusMFR = 0;
- vinUVFault = false;
- cmlFault = false;
- voutOVFault = false;
- ioutOCFault = false;
- voutUVFault = false;
- fanFault = false;
- tempFault = false;
+ vinUVFault = 0;
+ cmlFault = 0;
+ voutOVFault = 0;
+ ioutOCFault = 0;
+ voutUVFault = 0;
+ fanFault = 0;
+ tempFault = 0;
pgoodFault = 0;
- psKillFault = false;
- ps12VcsFault = false;
- psCS12VFault = false;
+ psKillFault = 0;
+ ps12VcsFault = 0;
+ psCS12VFault = 0;
}
/**
@@ -229,9 +229,13 @@
*/
bool isFaulted() const
{
- return (hasCommFault() || vinUVFault || inputFault || voutOVFault ||
- ioutOCFault || voutUVFault || fanFault || tempFault ||
- (pgoodFault >= DEGLITCH_LIMIT) || mfrFault);
+ return (hasCommFault() || (vinUVFault >= DEGLITCH_LIMIT) ||
+ (inputFault >= DEGLITCH_LIMIT) ||
+ (voutOVFault >= DEGLITCH_LIMIT) ||
+ (ioutOCFault >= DEGLITCH_LIMIT) ||
+ (voutUVFault >= DEGLITCH_LIMIT) ||
+ (fanFault >= DEGLITCH_LIMIT) || (tempFault >= DEGLITCH_LIMIT) ||
+ (pgoodFault >= DEGLITCH_LIMIT) || (mfrFault >= DEGLITCH_LIMIT));
}
/**
@@ -255,7 +259,7 @@
*/
bool hasInputFault() const
{
- return inputFault;
+ return (inputFault >= DEGLITCH_LIMIT);
}
/**
@@ -263,7 +267,7 @@
*/
bool hasMFRFault() const
{
- return mfrFault;
+ return (mfrFault >= DEGLITCH_LIMIT);
}
/**
@@ -271,7 +275,7 @@
*/
bool hasVINUVFault() const
{
- return vinUVFault;
+ return (vinUVFault >= DEGLITCH_LIMIT);
}
/**
@@ -279,7 +283,7 @@
*/
bool hasVoutOVFault() const
{
- return voutOVFault;
+ return (voutOVFault >= DEGLITCH_LIMIT);
}
/**
@@ -287,7 +291,7 @@
*/
bool hasIoutOCFault() const
{
- return ioutOCFault;
+ return (ioutOCFault >= DEGLITCH_LIMIT);
}
/**
@@ -295,7 +299,7 @@
*/
bool hasVoutUVFault() const
{
- return voutUVFault;
+ return (voutUVFault >= DEGLITCH_LIMIT);
}
/**
@@ -303,7 +307,7 @@
*/
bool hasFanFault() const
{
- return fanFault;
+ return (fanFault >= DEGLITCH_LIMIT);
}
/**
@@ -311,7 +315,7 @@
*/
bool hasTempFault() const
{
- return tempFault;
+ return (tempFault >= DEGLITCH_LIMIT);
}
/**
@@ -328,7 +332,7 @@
*/
bool hasPSKillFault() const
{
- return psKillFault;
+ return (psKillFault >= DEGLITCH_LIMIT);
}
/**
@@ -336,7 +340,7 @@
*/
bool hasPS12VcsFault() const
{
- return ps12VcsFault;
+ return (ps12VcsFault >= DEGLITCH_LIMIT);
}
/**
@@ -344,7 +348,7 @@
*/
bool hasPSCS12VFault() const
{
- return psCS12VFault;
+ return (psCS12VFault >= DEGLITCH_LIMIT);
}
/**
@@ -391,7 +395,7 @@
*/
bool hasCommFault() const
{
- return ((readFail >= LOG_LIMIT) || (cmlFault));
+ return ((readFail >= LOG_LIMIT) || (cmlFault >= DEGLITCH_LIMIT));
}
/**
@@ -439,33 +443,59 @@
/** @brief True if an error for a fault has already been logged. */
bool faultLogged = false;
- /** @brief True if bit 1 of STATUS_WORD low byte is on. */
- bool cmlFault = false;
+ /** @brief Incremented if bit 1 of STATUS_WORD low byte is on.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t cmlFault = 0;
- /** @brief True if bit 5 of STATUS_WORD high byte is on. */
- bool inputFault = false;
+ /** @brief Incremented if bit 5 of STATUS_WORD high byte is on.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t inputFault = 0;
- /** @brief True if bit 4 of STATUS_WORD high byte is on. */
- bool mfrFault = false;
+ /** @brief Incremented if bit 4 of STATUS_WORD high byte is on.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t mfrFault = 0;
- /** @brief True if bit 3 of STATUS_WORD low byte is on. */
- bool vinUVFault = false;
+ /** @brief Incremented if bit 3 of STATUS_WORD low byte is on.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t vinUVFault = 0;
- /** @brief True if bit 5 of STATUS_WORD low byte is on. */
- bool voutOVFault = false;
+ /** @brief Incremented if bit 5 of STATUS_WORD low byte is on.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t voutOVFault = 0;
- /** @brief True if bit 4 of STATUS_WORD low byte is on. */
- bool ioutOCFault = false;
+ /** @brief Incremented if bit 4 of STATUS_WORD low byte is on.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t ioutOCFault = 0;
- /** @brief True if bit 7 of STATUS_WORD high byte is on and bit 5 (VOUT_OV)
- * of low byte is off. */
- bool voutUVFault = false;
+ /** @brief Incremented if bit 7 of STATUS_WORD high byte is on and bit 5
+ * (VOUT_OV) of low byte is off.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t voutUVFault = 0;
- /** @brief True if FANS fault/warn bit on in STATUS_WORD. */
- bool fanFault = false;
+ /** @brief Incremented if FANS fault/warn bit on in STATUS_WORD.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT.
+ */
+ size_t fanFault = 0;
- /** @brief True if bit 2 of STATUS_WORD low byte is on. */
- bool tempFault = false;
+ /** @brief Incremented if bit 2 of STATUS_WORD low byte is on.
+ *
+ * Considered faulted if reaches DEGLITCH_LIMIT. */
+ size_t tempFault = 0;
/**
* @brief Incremented if bit 11 or 6 of STATUS_WORD is on. PGOOD# is
@@ -477,18 +507,30 @@
/**
* @brief Power Supply Kill fault.
+ *
+ * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
+ * bit 4 to indicate this fault. Considered faulted if it reaches
+ * DEGLITCH_LIMIT.
*/
- bool psKillFault = false;
+ size_t psKillFault = 0;
/**
* @brief Power Supply 12Vcs fault (standby power).
+ *
+ * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
+ * bit 6 to indicate this fault. Considered faulted if it reaches
+ * DEGLITCH_LIMIT.
*/
- bool ps12VcsFault = false;
+ size_t ps12VcsFault = 0;
/**
* @brief Power Supply Current-Share fault in 12V domain.
+ *
+ * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use
+ * bit 7 to indicate this fault. Considered faulted if it reaches
+ * DEGLITCH_LIMIT.
*/
- bool psCS12VFault = false;
+ size_t psCS12VFault = 0;
/** @brief Count of the number of read failures. */
size_t readFail = 0;
diff --git a/phosphor-power-supply/test/power_supply_tests.cpp b/phosphor-power-supply/test/power_supply_tests.cpp
index 1eec2a0..22c15e2 100644
--- a/phosphor-power-supply/test/power_supply_tests.cpp
+++ b/phosphor-power-supply/test/power_supply_tests.cpp
@@ -284,28 +284,36 @@
// STATUS_INPUT fault bits ... on.
expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
expectations.statusInputValue = 0x38;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("207000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), true);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("207000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ // Should not be faulted until it reaches the deglitch limit.
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
}
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
+ psu2.clearFaults();
+
// STATUS_WORD INPUT/UV fault.
{
// First need it to return good status, then the fault
@@ -315,33 +323,38 @@
.Times(1)
.WillOnce(Return("208000"));
psu2.analyze();
+ EXPECT_EQ(psu2.isFaulted(), false);
+ EXPECT_EQ(psu2.hasInputFault(), false);
// Now set fault bits in STATUS_WORD
expectations.statusWordValue =
(status_word::INPUT_FAULT_WARN | status_word::VIN_UV_FAULT);
// STATUS_INPUT fault bits ... on.
expectations.statusInputValue = 0x38;
- setPMBusExpectations(mockPMBus, expectations);
- // Input/UV fault, so voltage should read back low.
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("19123"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), true);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), true);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
-
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // Input/UV fault, so voltage should read back low.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("19123"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ // Only faulted if hit deglitch limit
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasVINUVFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
// Turning VIN_UV fault off causes clearing of faults, causing read of
// in1_input as an attempt to get CLEAR_FAULTS called.
expectations.statusWordValue = 0;
@@ -361,6 +374,9 @@
EXPECT_EQ(psu2.hasVINUVFault(), false);
}
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
+ psu2.clearFaults();
+
// STATUS_WORD MFR fault.
{
// First need it to return good status, then the fault
@@ -374,28 +390,34 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR bits on.
expectations.statusMFRValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("211000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), false);
- EXPECT_EQ(psu2.hasMFRFault(), true);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), true);
- EXPECT_EQ(psu2.hasPS12VcsFault(), true);
- EXPECT_EQ(psu2.hasPSCS12VFault(), true);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("211000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasMFRFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasPSKillFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ }
}
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
+ psu2.clearFaults();
// Temperature fault.
{
// First STATUS_WORD with no bits set, then with temperature fault.
@@ -409,28 +431,33 @@
expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
// STATUS_TEMPERATURE with fault bit(s) on.
expectations.statusTempValue = 0x10;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("213000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), false);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), true);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("213000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
}
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
+ psu2.clearFaults();
// CML fault
{
// First STATUS_WORD wit no bits set, then with CML fault.
@@ -444,28 +471,33 @@
expectations.statusWordValue = (status_word::CML_FAULT);
// Turn on STATUS_CML fault bit(s)
expectations.statusCMLValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("215000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), false);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), true);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("215000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasCommFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
}
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
+ psu2.clearFaults();
// VOUT_OV_FAULT fault
{
// First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
@@ -480,27 +512,30 @@
((status_word::VOUT_FAULT) | (status_word::VOUT_OV_FAULT));
// Turn on STATUS_VOUT fault bit(s)
expectations.statusVOUTValue = 0xA0;
- // STATUS_TEMPERATURE don't care (default)
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("217000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), false);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), true);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ // STATUS_TEMPERATURE don't care (default)
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("217000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
}
// IOUT_OC_FAULT fault
@@ -516,26 +551,29 @@
expectations.statusWordValue = status_word::IOUT_OC_FAULT;
// Turn on STATUS_IOUT fault bit(s)
expectations.statusIOUTValue = 0x88;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("219000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), false);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), true);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("219000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
}
// VOUT_UV_FAULT
@@ -551,26 +589,29 @@
expectations.statusWordValue = (status_word::VOUT_FAULT);
// Turn on STATUS_VOUT fault bit(s)
expectations.statusVOUTValue = 0x30;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("221000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), false);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasVoutUVFault(), true);
- EXPECT_EQ(psu2.hasFanFault(), false);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("221000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasFanFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
}
// Fan fault
@@ -585,26 +626,30 @@
expectations.statusWordValue = (status_word::FAN_FAULT);
// STATUS_FANS_1_2 with fan 1 warning & fault bits on.
expectations.statusFans12Value = 0xA0;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("223000"));
- psu2.analyze();
- EXPECT_EQ(psu2.isPresent(), true);
- EXPECT_EQ(psu2.isFaulted(), true);
- EXPECT_EQ(psu2.hasInputFault(), false);
- EXPECT_EQ(psu2.hasMFRFault(), false);
- EXPECT_EQ(psu2.hasVINUVFault(), false);
- EXPECT_EQ(psu2.hasCommFault(), false);
- EXPECT_EQ(psu2.hasVoutOVFault(), false);
- EXPECT_EQ(psu2.hasIoutOCFault(), false);
- EXPECT_EQ(psu2.hasVoutUVFault(), false);
- EXPECT_EQ(psu2.hasFanFault(), true);
- EXPECT_EQ(psu2.hasTempFault(), false);
- EXPECT_EQ(psu2.hasPgoodFault(), false);
- EXPECT_EQ(psu2.hasPSKillFault(), false);
- EXPECT_EQ(psu2.hasPS12VcsFault(), false);
- EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("223000"));
+ psu2.analyze();
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasFanFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasMFRFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
+ EXPECT_EQ(psu2.hasCommFault(), false);
+ EXPECT_EQ(psu2.hasVoutOVFault(), false);
+ EXPECT_EQ(psu2.hasIoutOCFault(), false);
+ EXPECT_EQ(psu2.hasVoutUVFault(), false);
+ EXPECT_EQ(psu2.hasTempFault(), false);
+ EXPECT_EQ(psu2.hasPgoodFault(), false);
+ EXPECT_EQ(psu2.hasPSKillFault(), false);
+ EXPECT_EQ(psu2.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu2.hasPSCS12VFault(), false);
+ }
}
// PGOOD/OFF fault. Deglitched, needs to reach DEGLITCH_LIMIT.
@@ -630,14 +675,7 @@
.WillOnce(Return("124000"));
psu2.analyze();
EXPECT_EQ(psu2.isPresent(), true);
- if (x < DEGLITCH_LIMIT)
- {
- EXPECT_EQ(psu2.isFaulted(), false);
- }
- else
- {
- EXPECT_EQ(psu2.isFaulted(), true);
- }
+ EXPECT_EQ(psu2.isFaulted(), x >= DEGLITCH_LIMIT);
EXPECT_EQ(psu2.hasInputFault(), false);
EXPECT_EQ(psu2.hasMFRFault(), false);
EXPECT_EQ(psu2.hasVINUVFault(), false);
@@ -764,44 +802,35 @@
expectations.statusFans12Value = 0xFF;
// STATUS_TEMPERATURE with bits on.
expectations.statusTempValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("0"));
- psu.analyze();
- EXPECT_EQ(psu.isPresent(), true);
- EXPECT_EQ(psu.isFaulted(), true);
- EXPECT_EQ(psu.hasInputFault(), true);
- EXPECT_EQ(psu.hasMFRFault(), true);
- EXPECT_EQ(psu.hasVINUVFault(), true);
- EXPECT_EQ(psu.hasCommFault(), true);
- EXPECT_EQ(psu.hasVoutOVFault(), true);
- EXPECT_EQ(psu.hasIoutOCFault(), true);
- // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
- // Rely on HasVoutUVFault() to verify this sets and clears.
- EXPECT_EQ(psu.hasVoutUVFault(), false);
- EXPECT_EQ(psu.hasFanFault(), true);
- EXPECT_EQ(psu.hasTempFault(), true);
- // pgoodFault is deglitched up to DEGLITCH_LIMIT
- EXPECT_EQ(psu.hasPgoodFault(), false);
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("0"));
- psu.analyze();
- EXPECT_EQ(psu.hasPgoodFault(), false);
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("0"));
- psu.analyze();
- // DEGLITCH_LIMIT reached for pgoodFault
- EXPECT_EQ(psu.hasPgoodFault(), true);
- EXPECT_EQ(psu.hasPSKillFault(), true);
- EXPECT_EQ(psu.hasPS12VcsFault(), true);
- EXPECT_EQ(psu.hasPSCS12VFault(), true);
- // This is the CLEAR_FAULTS read that does not check the return value.
- EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("0"));
+ psu.analyze();
+ EXPECT_EQ(psu.isPresent(), true);
+ // Cannot have VOUT_OV_FAULT and VOUT_UV_FAULT.
+ // Rely on HasVoutUVFault() to verify this sets and clears.
+ EXPECT_EQ(psu.hasVoutUVFault(), false);
+ // All faults are deglitched up to DEGLITCH_LIMIT
+ EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasCommFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasPgoodFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
+ EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
+ }
+
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(207000));
psu.clearFaults();
EXPECT_EQ(psu.isPresent(), true);
EXPECT_EQ(psu.isFaulted(), false);
@@ -836,12 +865,17 @@
expectations.statusFans12Value = 0xFF;
// STATUS_TEMPERATURE with bits on.
expectations.statusTempValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(0));
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("0"));
- psu.analyze();
+
+ // All faults degltiched now. Check for false before limit above.
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("0"));
+ psu.analyze();
+ }
+
EXPECT_EQ(psu.isPresent(), true);
EXPECT_EQ(psu.isFaulted(), true);
EXPECT_EQ(psu.hasInputFault(), true);
@@ -856,8 +890,7 @@
EXPECT_EQ(psu.hasVoutUVFault(), false);
EXPECT_EQ(psu.hasFanFault(), true);
EXPECT_EQ(psu.hasTempFault(), true);
- // PGOOD fault is deglitched before hasPgoodFault() returns true.
- EXPECT_EQ(psu.hasPgoodFault(), false);
+ EXPECT_EQ(psu.hasPgoodFault(), true);
EXPECT_EQ(psu.hasPSKillFault(), true);
EXPECT_EQ(psu.hasPS12VcsFault(), true);
EXPECT_EQ(psu.hasPSCS12VFault(), true);
@@ -871,6 +904,7 @@
EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
.Times(1)
.WillOnce(Return("206000"));
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(0));
psu.analyze();
EXPECT_EQ(psu.isPresent(), true);
EXPECT_EQ(psu.isFaulted(), false);
@@ -1011,13 +1045,16 @@
expectations.statusFans12Value = 0xFF;
// STATUS_TEMPERATURE with fault bits on.
expectations.statusTempValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- // Also get another read of READ_VIN.
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("125790"));
- psu.analyze();
- EXPECT_EQ(psu.isFaulted(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // Also get another read of READ_VIN.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("125790"));
+ psu.analyze();
+ EXPECT_EQ(psu.isFaulted(), x >= DEGLITCH_LIMIT);
+ }
}
TEST_F(PowerSupplyTests, HasInputFault)
@@ -1044,13 +1081,16 @@
expectations.statusWordValue = (status_word::INPUT_FAULT_WARN);
// STATUS_INPUT with an input fault bit on.
expectations.statusInputValue = 0x80;
- setPMBusExpectations(mockPMBus, expectations);
- // Analyze call will also need good READ_VIN value to check.
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("201200"));
- psu.analyze();
- EXPECT_EQ(psu.hasInputFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // Analyze call will also need good READ_VIN value to check.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("201200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasInputFault(), x >= DEGLITCH_LIMIT);
+ }
// STATUS_WORD with no bits on.
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1087,12 +1127,15 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR_SPEFIC with bit(s) on.
expectations.statusMFRValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("202200"));
- psu.analyze();
- EXPECT_EQ(psu.hasMFRFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("202200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasMFRFault(), x >= DEGLITCH_LIMIT);
+ }
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1136,13 +1179,16 @@
// Curious disagreement between PMBus Spec. Part II Figure 16 and 33. Go by
// Figure 16, and assume bits on in STATUS_INPUT.
expectations.statusInputValue = 0x18;
- setPMBusExpectations(mockPMBus, expectations);
- // If there is a VIN_UV fault, fake reading voltage of less than 20V
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("19876"));
- psu.analyze();
- EXPECT_EQ(psu.hasVINUVFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // If there is a VIN_UV fault, fake reading voltage of less than 20V
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("19876"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasVINUVFault(), x >= DEGLITCH_LIMIT);
+ }
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1182,13 +1228,15 @@
expectations.statusWordValue = (status_word::VOUT_OV_FAULT);
// STATUS_VOUT fault bit(s)
expectations.statusVOUTValue = 0x80;
- // STATUS_TEMPERATURE default.
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("202200"));
- psu.analyze();
- EXPECT_EQ(psu.hasVoutOVFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("202200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasVoutOVFault(), x >= DEGLITCH_LIMIT);
+ }
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1224,12 +1272,15 @@
expectations.statusWordValue = status_word::IOUT_OC_FAULT;
// STATUS_IOUT fault bit(s)
expectations.statusIOUTValue = 0x88;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("203200"));
- psu.analyze();
- EXPECT_EQ(psu.hasIoutOCFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("203200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasIoutOCFault(), x >= DEGLITCH_LIMIT);
+ }
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1265,12 +1316,15 @@
expectations.statusWordValue = (status_word::VOUT_FAULT);
// STATUS_VOUT fault bit(s)
expectations.statusVOUTValue = 0x30;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("204200"));
- psu.analyze();
- EXPECT_EQ(psu.hasVoutUVFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("204200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasVoutUVFault(), x >= DEGLITCH_LIMIT);
+ }
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1306,13 +1360,16 @@
expectations.statusWordValue = (status_word::FAN_FAULT);
// STATUS_FANS_1_2 fault bit on (Fan 1 Fault)
expectations.statusFans12Value = 0x80;
- setPMBusExpectations(mockPMBus, expectations);
- // Call to analyze will trigger read of "in1_input" to check voltage.
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("205200"));
- psu.analyze();
- EXPECT_EQ(psu.hasFanFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("205200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasFanFault(), x >= DEGLITCH_LIMIT);
+ }
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1349,13 +1406,16 @@
expectations.statusWordValue = (status_word::TEMPERATURE_FAULT_WARN);
// STATUS_TEMPERATURE fault bit on (OT Fault)
expectations.statusTempValue = 0x80;
- setPMBusExpectations(mockPMBus, expectations);
- // Call to analyze will trigger read of "in1_input" to check voltage.
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("206200"));
- psu.analyze();
- EXPECT_EQ(psu.hasTempFault(), true);
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("206200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasTempFault(), x >= DEGLITCH_LIMIT);
+ }
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1494,13 +1554,19 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR_SPEFIC with bit(s) on.
expectations.statusMFRValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- // Call to analyze will trigger read of "in1_input" to check voltage.
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("208200"));
- psu.analyze();
- EXPECT_EQ(psu.hasPSKillFault(), true);
+
+ // Deglitching faults, false until read the fault bits on up to the limit.
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("208200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
+ }
+
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1514,13 +1580,18 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR_SPEFIC with bit 4 on.
expectations.statusMFRValue = 0x10;
- setPMBusExpectations(mockPMBus, expectations);
- // Call to analyze will trigger read of "in1_input" to check voltage.
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("208400"));
- psu.analyze();
- EXPECT_EQ(psu.hasPSKillFault(), true);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("208400"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasPSKillFault(), x >= DEGLITCH_LIMIT);
+ }
+
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1555,12 +1626,17 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR_SPEFIC with bit(s) on.
expectations.statusMFRValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("209200"));
- psu.analyze();
- EXPECT_EQ(psu.hasPS12VcsFault(), true);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
+ }
+
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1573,12 +1649,17 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR_SPEFIC with bit 6 on.
expectations.statusMFRValue = 0x40;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("209400"));
- psu.analyze();
- EXPECT_EQ(psu.hasPS12VcsFault(), true);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209400"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasPS12VcsFault(), x >= DEGLITCH_LIMIT);
+ }
+
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1611,12 +1692,17 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR_SPEFIC with bit(s) on.
expectations.statusMFRValue = 0xFF;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("209200"));
- psu.analyze();
- EXPECT_EQ(psu.hasPSCS12VFault(), true);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
+ }
+
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
@@ -1629,12 +1715,17 @@
expectations.statusWordValue = (status_word::MFR_SPECIFIC_FAULT);
// STATUS_MFR_SPEFIC with bit 7 on.
expectations.statusMFRValue = 0x80;
- setPMBusExpectations(mockPMBus, expectations);
- EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
- .Times(1)
- .WillOnce(Return("209400"));
- psu.analyze();
- EXPECT_EQ(psu.hasPSCS12VFault(), true);
+
+ for (auto x = 1; x <= DEGLITCH_LIMIT; x++)
+ {
+ setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209400"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasPSCS12VFault(), x >= DEGLITCH_LIMIT);
+ }
+
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);