psu-ng: Clear faults when voltage back in range
If the last read voltage (via READ_VIN) was below the minimum and
now it is back in a valid range (100 or 200 volt range valid), clear all
the faults to allow for re-detection of faults and logging of new errors.
Trace if INPUT_FAULT_WARN or VIN_UV clear. We should not expect to see
that without sending a CLEAR_FAULTS command (or a power cycle).
Tested:
Rainier 2S2U real hardware.
ePDU outlet off/on allows re-detection of injected CML fault.
- input fault, vin_uv fault, pgood/off fault.
- repeat shows faults cleared, and new faults logged.
Simulator pgood fault, then low voltage followed by good voltage.
Verify simulator can re-detect faults after voltage back in range.
Simulator fake input fault/warn on, then off and other fault on.
- verified tracing input going off without clear faults sent.
Simulator fake input fault/warn on, then no faults.
- verified tracing input going off without clear faults sent.
Change-Id: Ic8022cf137978ff660680e9680f778853cbecf0d
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/phosphor-power-supply/test/power_supply_tests.cpp b/phosphor-power-supply/test/power_supply_tests.cpp
index 539f2fb..1eec2a0 100644
--- a/phosphor-power-supply/test/power_supply_tests.cpp
+++ b/phosphor-power-supply/test/power_supply_tests.cpp
@@ -103,9 +103,15 @@
EXPECT_CALL(pmbus, writeBinary(ON_OFF_CONFIG, _, _));
// Presence change from missing to present will trigger in1_input read
// in an attempt to get CLEAR_FAULTS called.
- EXPECT_CALL(pmbus, read(READ_VIN, _)).Times(1).WillOnce(Return(1));
+ // The voltage defaults to 0, the first call to analyze should update the
+ // voltage to the current reading, triggering another clearing of faults
+ // due to below minimum to within range voltage.
+ // This READ_VIN for CLEAR_FAULTS does not check the returned value.
+ EXPECT_CALL(pmbus, read(READ_VIN, _))
+ .Times(2)
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
// Missing/present call will update Presence in inventory.
- // EXPECT_CALL(mockedUtil, setPresence(_, _, true, _));
EXPECT_CALL(util, setPresence(_, _, true, _));
}
@@ -253,6 +259,10 @@
// Set expectations for a no fault
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // After reading STATUS_WORD, etc., there will be a READ_VIN check.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("206000"));
psu2.analyze();
EXPECT_EQ(psu2.isPresent(), true);
EXPECT_EQ(psu2.isFaulted(), false);
@@ -275,6 +285,9 @@
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);
@@ -298,6 +311,9 @@
// First need it to return good status, then the fault
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("208000"));
psu2.analyze();
// Now set fault bits in STATUS_WORD
expectations.statusWordValue =
@@ -305,6 +321,10 @@
// 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);
@@ -321,6 +341,24 @@
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;
+ setPMBusExpectations(mockPMBus, expectations);
+ // The call to read the voltage
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209000"));
+ // The call for CLEAR_FAULTS command
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
+ psu2.analyze();
+ // Should remain present, no longer be faulted, no input fault, no
+ // VIN_UV fault. Nothing else should change.
+ EXPECT_EQ(psu2.isPresent(), true);
+ EXPECT_EQ(psu2.isFaulted(), false);
+ EXPECT_EQ(psu2.hasInputFault(), false);
+ EXPECT_EQ(psu2.hasVINUVFault(), false);
}
// STATUS_WORD MFR fault.
@@ -328,12 +366,18 @@
// First need it to return good status, then the fault
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("210000"));
psu2.analyze();
// Now STATUS_WORD with MFR fault bit on.
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);
@@ -357,12 +401,18 @@
// First STATUS_WORD with no bits set, then with temperature fault.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("212000"));
psu2.analyze();
// STATUS_WORD with temperature fault bit on.
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);
@@ -386,12 +436,18 @@
// First STATUS_WORD wit no bits set, then with CML fault.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("214000"));
psu2.analyze();
// STATUS_WORD with CML fault bit on.
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);
@@ -415,6 +471,9 @@
// First STATUS_WORD with no bits set, then with VOUT/VOUT_OV fault.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("216000"));
psu2.analyze();
// STATUS_WORD with VOUT/VOUT_OV fault.
expectations.statusWordValue =
@@ -423,6 +482,9 @@
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);
@@ -446,12 +508,18 @@
// First STATUS_WORD with no bits set, then with IOUT_OC fault.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("218000"));
psu2.analyze();
// STATUS_WORD with IOUT_OC fault.
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);
@@ -475,12 +543,18 @@
// First STATUS_WORD with no bits set, then with VOUT fault.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("220000"));
psu2.analyze();
// Change STATUS_WORD to indicate VOUT fault.
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);
@@ -504,11 +578,17 @@
// First STATUS_WORD with no bits set, then with fan fault.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("222000"));
psu2.analyze();
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);
@@ -532,6 +612,9 @@
// First STATUS_WORD with no bits set.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("123000"));
psu2.analyze();
EXPECT_EQ(psu2.isFaulted(), false);
// POWER_GOOD# inactive, and OFF bit on.
@@ -542,6 +625,9 @@
// STATUS_INPUT, STATUS_MFR, STATUS_CML, STATUS_VOUT, and
// STATUS_TEMPERATURE: Don't care if bits set or not (defaults).
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("124000"));
psu2.analyze();
EXPECT_EQ(psu2.isPresent(), true);
if (x < DEGLITCH_LIMIT)
@@ -614,6 +700,9 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("205000"));
psu.analyze();
// I definitely should be writting ON_OFF_CONFIG if I call the function
EXPECT_CALL(mockPMBus, writeBinary(ON_OFF_CONFIG, ElementsAre(0x15),
@@ -639,6 +728,9 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("207000"));
psu.analyze();
EXPECT_EQ(psu.isPresent(), true);
EXPECT_EQ(psu.isFaulted(), false);
@@ -673,6 +765,9 @@
// 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);
@@ -690,17 +785,23 @@
// 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);
-
- EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(207000));
+ // This is the CLEAR_FAULTS read that does not check the return value.
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
psu.clearFaults();
EXPECT_EQ(psu.isPresent(), true);
EXPECT_EQ(psu.isFaulted(), false);
@@ -718,6 +819,75 @@
EXPECT_EQ(psu.hasPS12VcsFault(), false);
EXPECT_EQ(psu.hasPSCS12VFault(), false);
+ // Faults clear on READ_VIN 0 -> !0
+ // STATUS_WORD with fault bits galore!
+ expectations.statusWordValue = 0xFFFF;
+ // STATUS_INPUT with fault bits on.
+ expectations.statusInputValue = 0xFF;
+ // STATUS_MFR_SPEFIC with bits on.
+ expectations.statusMFRValue = 0xFF;
+ // STATUS_CML with bits on.
+ expectations.statusCMLValue = 0xFF;
+ // STATUS_VOUT with bits on.
+ expectations.statusVOUTValue = 0xFF;
+ // STATUS_IOUT with bits on.
+ expectations.statusIOUTValue = 0xFF;
+ // STATUS_FANS_1_2 with bits on.
+ 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();
+ 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);
+ // True due to CML fault bits on
+ 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);
+ // PGOOD fault is deglitched before hasPgoodFault() returns true.
+ EXPECT_EQ(psu.hasPgoodFault(), false);
+ EXPECT_EQ(psu.hasPSKillFault(), true);
+ EXPECT_EQ(psu.hasPS12VcsFault(), true);
+ EXPECT_EQ(psu.hasPSCS12VFault(), true);
+ // STATUS_WORD with INPUT/VIN_UV fault bits off.
+ expectations.statusWordValue = 0xDFF7;
+ // STATUS_INPUT with VIN_UV_WARNING, VIN_UV_FAULT, and Unit Off For
+ // Insufficient Input Voltage bits off.
+ expectations.statusInputValue = 0xC7;
+ setPMBusExpectations(mockPMBus, expectations);
+ // READ_VIN back in range.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("206000"));
+ psu.analyze();
+ EXPECT_EQ(psu.isPresent(), true);
+ EXPECT_EQ(psu.isFaulted(), false);
+ EXPECT_EQ(psu.hasInputFault(), false);
+ EXPECT_EQ(psu.hasMFRFault(), false);
+ EXPECT_EQ(psu.hasVINUVFault(), false);
+ EXPECT_EQ(psu.hasCommFault(), false);
+ EXPECT_EQ(psu.hasVoutOVFault(), false);
+ EXPECT_EQ(psu.hasIoutOCFault(), false);
+ EXPECT_EQ(psu.hasVoutUVFault(), false);
+ EXPECT_EQ(psu.hasFanFault(), false);
+ EXPECT_EQ(psu.hasTempFault(), false);
+ EXPECT_EQ(psu.hasPgoodFault(), false);
+ EXPECT_EQ(psu.hasPSKillFault(), false);
+ EXPECT_EQ(psu.hasPS12VcsFault(), false);
+ EXPECT_EQ(psu.hasPSCS12VFault(), false);
+
// TODO: Faults clear on missing/present?
}
@@ -750,7 +920,11 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
- // Need analyze call to update power supply from missing to present.
+ // Call to analyze will read voltage, trigger clear faults for 0 to
+ // within range.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("123456"));
psu.analyze();
EXPECT_CALL(mockPMBus, readString(_, _)).WillRepeatedly(Return(""));
psu.updateInventory();
@@ -792,6 +966,10 @@
// Default expectations will be on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Give it an input voltage in the 100-volt range.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("123456"));
psu.analyze();
EXPECT_EQ(psu.isPresent(), true);
}
@@ -811,6 +989,10 @@
// Default expectations will be on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Give it an input voltage in the 100-volt range.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("124680"));
psu.analyze();
EXPECT_EQ(psu.isFaulted(), false);
// STATUS_WORD with fault bits on.
@@ -830,6 +1012,10 @@
// 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);
}
@@ -848,6 +1034,10 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Analyze call will also need good READ_VIN value to check.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("201100"));
psu.analyze();
EXPECT_EQ(psu.hasInputFault(), false);
// STATUS_WORD with input fault/warn on.
@@ -855,11 +1045,19 @@
// 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);
// STATUS_WORD with no bits on.
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ // Analyze call will also need good READ_VIN value to check.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("201300"));
psu.analyze();
EXPECT_EQ(psu.hasInputFault(), false);
}
@@ -879,6 +1077,10 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Analyze call will also need good READ_VIN value to check.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("202100"));
psu.analyze();
EXPECT_EQ(psu.hasMFRFault(), false);
// Next return STATUS_WORD with MFR fault bit on.
@@ -886,11 +1088,17 @@
// 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);
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("202300"));
psu.analyze();
EXPECT_EQ(psu.hasMFRFault(), false);
}
@@ -906,9 +1114,21 @@
EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
setMissingToPresentExpects(mockPMBus, mockedUtil);
+
+ // Presence change from missing to present will trigger in1_input read in
+ // an attempt to get CLEAR_FAULTS called. Return value ignored.
+ // Zero to non-zero voltage, for missing/present change, triggers clear
+ // faults call again. Return value ignored.
+ // Fault (low voltage) to not faulted (voltage in range) triggers clear
+ // faults call a third time.
+
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Analyze call will also need good READ_VIN value to check.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("201100"));
psu.analyze();
EXPECT_EQ(psu.hasVINUVFault(), false);
// Turn fault on.
@@ -917,11 +1137,22 @@
// 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);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ // Updates now result in clearing faults if read voltage goes from below the
+ // minimum, to within a valid range.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("201300"));
+ // Went from below minimum to within range, expect CLEAR_FAULTS.
+ EXPECT_CALL(mockPMBus, read(READ_VIN, _)).Times(1).WillOnce(Return(3));
psu.analyze();
EXPECT_EQ(psu.hasVINUVFault(), false);
}
@@ -940,6 +1171,11 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ // Initial value would be 0, so this read updates it to non-zero.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("202100"));
psu.analyze();
EXPECT_EQ(psu.hasVoutOVFault(), false);
// Turn fault on.
@@ -948,11 +1184,17 @@
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);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("202300"));
psu.analyze();
EXPECT_EQ(psu.hasVoutOVFault(), false);
}
@@ -971,6 +1213,11 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ // Initial value would be 0, so this read updates it to non-zero.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("203100"));
psu.analyze();
EXPECT_EQ(psu.hasIoutOCFault(), false);
// Turn fault on.
@@ -978,11 +1225,17 @@
// 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);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("203300"));
psu.analyze();
EXPECT_EQ(psu.hasIoutOCFault(), false);
}
@@ -1001,6 +1254,11 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ // Initial value would be 0, so this read updates it to non-zero.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("204100"));
psu.analyze();
EXPECT_EQ(psu.hasVoutUVFault(), false);
// Turn fault on.
@@ -1008,11 +1266,17 @@
// 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);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("204300"));
psu.analyze();
EXPECT_EQ(psu.hasVoutUVFault(), false);
}
@@ -1031,6 +1295,11 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ // Initial value would be 0, so this read updates it to non-zero.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("205100"));
psu.analyze();
EXPECT_EQ(psu.hasFanFault(), false);
// Turn fault on.
@@ -1038,11 +1307,19 @@
// 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);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
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("205300"));
psu.analyze();
EXPECT_EQ(psu.hasFanFault(), false);
}
@@ -1061,6 +1338,11 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ // Initial value would be 0, so this read updates it to non-zero.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("206100"));
psu.analyze();
EXPECT_EQ(psu.hasTempFault(), false);
// Turn fault on.
@@ -1068,11 +1350,19 @@
// 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);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
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("206300"));
psu.analyze();
EXPECT_EQ(psu.hasTempFault(), false);
}
@@ -1091,45 +1381,91 @@
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ // Initial value would be 0, so this read updates it to non-zero.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("207100"));
psu.analyze();
EXPECT_EQ(psu.hasPgoodFault(), false);
// Setup another expectation of no faults.
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("207200"));
+ psu.analyze();
+ EXPECT_EQ(psu.hasPgoodFault(), false);
+ // Setup another expectation of no faults.
+ 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("207300"));
psu.analyze();
EXPECT_EQ(psu.hasPgoodFault(), false);
// Turn PGOOD# off (fault on).
expectations.statusWordValue = (status_word::POWER_GOOD_NEGATED);
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("207400"));
psu.analyze();
// Expect false until reaches DEGLITCH_LIMIT
EXPECT_EQ(psu.hasPgoodFault(), false);
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("207500"));
psu.analyze();
// Expect false until reaches DEGLITCH_LIMIT
EXPECT_EQ(psu.hasPgoodFault(), false);
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("207600"));
psu.analyze();
// DEGLITCH_LIMIT reached, expect true.
EXPECT_EQ(psu.hasPgoodFault(), true);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
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("207700"));
psu.analyze();
EXPECT_EQ(psu.hasPgoodFault(), false);
+
// Turn OFF bit on
expectations.statusWordValue = (status_word::UNIT_IS_OFF);
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("208100"));
psu.analyze();
EXPECT_EQ(psu.hasPgoodFault(), false);
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("208200"));
psu.analyze();
EXPECT_EQ(psu.hasPgoodFault(), false);
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("208300"));
psu.analyze();
EXPECT_EQ(psu.hasPgoodFault(), true);
// Back to no fault bits on in STATUS_WORD
expectations.statusWordValue = 0;
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.hasPgoodFault(), false);
}
@@ -1142,12 +1478,16 @@
static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
// Always return 1 to indicate present.
EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
- psu.analyze();
- EXPECT_EQ(psu.hasPSKillFault(), false);
MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
+ setMissingToPresentExpects(mockPMBus, mockedUtil);
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ // Call to analyze will trigger read of "in1_input" to check voltage.
+ // Initial value would be 0, so this read updates it to non-zero.
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("208100"));
psu.analyze();
EXPECT_EQ(psu.hasPSKillFault(), false);
// Next return STATUS_WORD with MFR fault bit on.
@@ -1155,11 +1495,19 @@
// 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);
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
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("208300"));
psu.analyze();
EXPECT_EQ(psu.hasPSKillFault(), false);
// Next return STATUS_WORD with MFR fault bit on.
@@ -1167,11 +1515,19 @@
// 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);
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
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("208500"));
psu.analyze();
EXPECT_EQ(psu.hasPSKillFault(), false);
}
@@ -1184,12 +1540,15 @@
static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
// Always return 1 to indicate present.
EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
- psu.analyze();
- EXPECT_EQ(psu.hasPS12VcsFault(), false);
MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
+ setMissingToPresentExpects(mockPMBus, mockedUtil);
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
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("209100"));
psu.analyze();
EXPECT_EQ(psu.hasPS12VcsFault(), false);
// Next return STATUS_WORD with MFR fault bit on.
@@ -1197,11 +1556,17 @@
// 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);
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209300"));
psu.analyze();
EXPECT_EQ(psu.hasPS12VcsFault(), false);
// Next return STATUS_WORD with MFR fault bit on.
@@ -1209,11 +1574,17 @@
// 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);
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209500"));
psu.analyze();
EXPECT_EQ(psu.hasPS12VcsFault(), false);
}
@@ -1226,12 +1597,14 @@
static_cast<MockedGPIOInterface*>(psu.getPresenceGPIO());
// Always return 1 to indicate present.
EXPECT_CALL(*mockPresenceGPIO, read()).WillRepeatedly(Return(1));
- psu.analyze();
- EXPECT_EQ(psu.hasPSCS12VFault(), false);
MockedPMBus& mockPMBus = static_cast<MockedPMBus&>(psu.getPMBus());
+ setMissingToPresentExpects(mockPMBus, mockedUtil);
// STATUS_WORD 0x0000 is powered on, no faults.
PMBusExpectations expectations;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209100"));
psu.analyze();
EXPECT_EQ(psu.hasPSCS12VFault(), false);
// Next return STATUS_WORD with MFR fault bit on.
@@ -1239,11 +1612,17 @@
// 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);
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209300"));
psu.analyze();
EXPECT_EQ(psu.hasPSCS12VFault(), false);
// Next return STATUS_WORD with MFR fault bit on.
@@ -1251,11 +1630,17 @@
// 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);
// Back to no bits on in STATUS_WORD
expectations.statusWordValue = 0;
setPMBusExpectations(mockPMBus, expectations);
+ EXPECT_CALL(mockPMBus, readString(READ_VIN, _))
+ .Times(1)
+ .WillOnce(Return("209500"));
psu.analyze();
EXPECT_EQ(psu.hasPSCS12VFault(), false);
}