Index: firmware/App/Services/WatchdogMgmt.c =================================================================== diff -u -r256d5cb05f1ef09e19e2f2733a111f600c73a7ee -r7d4711edd7b40cd3e29f43e766f79a8a09586fe9 --- firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 256d5cb05f1ef09e19e2f2733a111f600c73a7ee) +++ firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 7d4711edd7b40cd3e29f43e766f79a8a09586fe9) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file WatchdogMgmt.c * -* @author (last) Darren Cox -* @date (last) 11-Aug-2022 +* @author (last) Sean Nash +* @date (last) 04-Oct-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -17,7 +17,8 @@ #include "CPLD.h" #include "InternalADC.h" -#include "OperationModes.h" +#include "OperationModes.h" +#include "SafetyShutdown.h" #include "SystemCommMessages.h" #include "Timers.h" #include "WatchdogMgmt.h" @@ -29,14 +30,17 @@ // ********** private definitions ********** -#define MIN_WATCHDOG_PET_INTERVAL_MS 45 ///< Minimum watchdog pet interval. +#define MIN_WATCHDOG_PET_INTERVAL_MS 45 ///< Minimum watchdog pet interval. -#define WATCHDOG_POST_TIMEOUT_MS 500 ///< Watchdog POST timeout in ms. -#define WATCHDOG_RECOVERY_TIME_MS 750 ///< Watchdog recovery time in ms. +#define WATCHDOG_POST_TIMEOUT_MS ( 0.5 * MS_PER_SECOND ) ///< Watchdog POST timeout in ms. +#define WATCHDOG_RECOVERY_TIME_MS 750 ///< Watchdog recovery time in ms. -#define MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED 5.0F ///< Maximum voltage on 24V line when watchdog is expired. // TODO - check w/ Systems. Takes time for V to bleed off. Had to raise to 5V. -#define MIN_24V_LEVEL_ON_WATCHDOG_RECOVER 22.6F ///< Minimum voltage on 24V line when watchdog is recovered. +#define MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED 5.0F ///< Maximum voltage on 24V line when watchdog is expired. // TODO - check w/ Systems. Takes time for V to bleed off. Had to raise to 5V. +#define MAX_ISOLATED_24V_LEVEL_ON_WD_EXPIRED 22.6F ///< Maximum voltage on isolated 24V line when watchdog is expired. 10% of 24V. +#define MIN_24V_LEVEL_ON_WATCHDOG_RECOVER 22.6F ///< Minimum voltage on 24V line when watchdog is recovered. +#define MAX_SAFETY_SHUTDOWN_MISMATCH_MS 100 ///< Maximum time (in ms) that safety shutdown cmd vs. feedback can be mismatched. + /// List of watchdog states. typedef enum Button_Self_Test_States { @@ -49,13 +53,12 @@ // ********** private data ********** -static U32 lastWatchdogPetTime = 0; ///< Previous watchdog pet timestamp (in ms). - +static U32 lastWatchdogPetTime; ///< Previous watchdog pet timestamp (in ms). static OVERRIDE_U32_T watchdogTaskCheckedIn[ NUM_OF_TASKS ]; ///< Array of flags indicating whether individual tasks have checked in with watchdog manager. - static WATCHDOG_SELF_TEST_STATE_T watchdogSelfTestState; ///< Watchdog self-test current state. static SELF_TEST_STATUS_T watchdogSelfTestStatus; ///< Watchdog self-test status. -static U32 watchdogSelfTestTimerCount = 0; ///< Watchdog self-test timer count. +static U32 watchdogSelfTestTimerCount; ///< Watchdog self-test timer count. +static U32 safetyShutdownFeedbackMismatchTS; ///< Persistence timestamp for safety shutdown cmd vs. feedback mismatch. // ********** private function prototypes ********** @@ -75,17 +78,19 @@ { U32 i; - lastWatchdogPetTime = 0; - watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; - watchdogSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; - watchdogSelfTestTimerCount = 0; + lastWatchdogPetTime = 0; + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; + watchdogSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; + watchdogSelfTestTimerCount = 0; + safetyShutdownFeedbackMismatchTS = getMSTimerCount(); + // initialize task check-ins to false for ( i = 0; i < NUM_OF_TASKS; i++ ) { - watchdogTaskCheckedIn[ i ].data = FALSE; - watchdogTaskCheckedIn[ i ].ovData = FALSE; + watchdogTaskCheckedIn[ i ].data = FALSE; + watchdogTaskCheckedIn[ i ].ovData = FALSE; watchdogTaskCheckedIn[ i ].ovInitData = FALSE; - watchdogTaskCheckedIn[ i ].override = OVERRIDE_RESET; + watchdogTaskCheckedIn[ i ].override = OVERRIDE_RESET; } } @@ -98,7 +103,9 @@ *************************************************************************/ void execWatchdogMgmt( void ) { - BOOL allTasksCheckedIn; + BOOL allTasksCheckedIn; + PIN_SIGNAL_STATE_T safetyShutdownFeedbackSignal = getCPLDWatchdogExpired(); + PIN_SIGNAL_STATE_T safetyShutdownSoftwareCmd = ( TRUE == isSafetyShutdownActivated() ? PIN_SIGNAL_LOW : PIN_SIGNAL_HIGH ); // called by background task, so give bg task credit for checking in checkInWithWatchdogMgmt( TASK_BG ); @@ -107,24 +114,29 @@ allTasksCheckedIn = haveAllTasksCheckedIn(); // if all monitored tasks checked in, pet watchdog and clear the slate - if ( ( TRUE == allTasksCheckedIn ) && ( didTimeout( lastWatchdogPetTime, MIN_WATCHDOG_PET_INTERVAL_MS ) ) ) + if ( ( TRUE == allTasksCheckedIn ) && ( TRUE == didTimeout( lastWatchdogPetTime, MIN_WATCHDOG_PET_INTERVAL_MS ) ) ) { petWatchdog(); resetWDTaskCheckIns(); } - // check to see if watchdog has expired - if ( PIN_SIGNAL_LOW == getCPLDWatchdogExpired() ) - { - // ignore expired watchdog until after watchdog POST - if ( ( WATCHDOG_SELF_TEST_STATE_COMPLETE == watchdogSelfTestState ) || - ( getCurrentOperationMode() != DG_MODE_INIT ) ) - { -#ifndef DEBUG_ENABLED - activateAlarmNoData( ALARM_ID_DG_WATCHDOG_EXPIRED ); -#endif - } - } + // Check to see if watchdog has expired or safety shutdown feedback does not match s/w command (only after POST completed) + if ( ( safetyShutdownSoftwareCmd != safetyShutdownFeedbackSignal ) && ( getCurrentOperationMode() != MODE_INIT ) ) + { + if ( ( PIN_SIGNAL_LOW == safetyShutdownFeedbackSignal ) || ( TRUE == didTimeout( safetyShutdownFeedbackMismatchTS, MAX_SAFETY_SHUTDOWN_MISMATCH_MS ) ) ) + { + /* DEBUG WARNING + * It may be necessary to comment out the following + * line to prevent the alarm from occurring while + * debugging. + */ + activateAlarmNoData( ALARM_ID_DG_WATCHDOG_EXPIRED ); + } + } + else + { + safetyShutdownFeedbackMismatchTS = getMSTimerCount(); + } } /*********************************************************************//** @@ -159,7 +171,7 @@ switch ( watchdogSelfTestState ) { case WATCHDOG_SELF_TEST_STATE_START: - watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_IN_PROGRESS; + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_IN_PROGRESS; watchdogSelfTestTimerCount = getMSTimerCount(); // no break here so we pass through directly to in progress processing @@ -170,12 +182,13 @@ } if ( PIN_SIGNAL_LOW == getCPLDWatchdogExpired() ) { - F32 v24 = getIntADCVoltageConverted( INT_ADC_SECONDARY_HEATER_24_VOLTS ); + F32 v24 = getIntADCVoltageConverted( INT_ADC_SECONDARY_HEATER_24_VOLTS ); + F32 isolatedV24 = getRawIsolatedPowerSupplyVoltage(); // Verify 24V is down when w.d. expired - if ( v24 > MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED ) + if ( ( v24 > MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED ) || ( isolatedV24 > MAX_ISOLATED_24V_LEVEL_ON_WD_EXPIRED ) ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 2.0, v24 ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 2.0F, v24 ); watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } } @@ -185,27 +198,34 @@ watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; } watchdogSelfTestTimerCount = getMSTimerCount(); - watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_RECOVER; + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_RECOVER; break; case WATCHDOG_SELF_TEST_STATE_RECOVER: - if ( TRUE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_RECOVERY_TIME_MS ) ) - { + if ( TRUE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_RECOVERY_TIME_MS ) ) + { if ( PIN_SIGNAL_HIGH == getCPLDWatchdogExpired() ) { - F32 v24 = getIntADCVoltageConverted( INT_ADC_SECONDARY_HEATER_24_VOLTS ); + F32 v24 = getIntADCVoltageConverted( INT_ADC_SECONDARY_HEATER_24_VOLTS ); + F32 isolatedV24 = getRawIsolatedPowerSupplyVoltage(); - // Verify 24V is down when w.d. recovered TODO - ask EE team why 24V does not quite recover all the way to 22.6V even after 750 ms. How long should it take? -// if ( v24 < MIN_24V_LEVEL_ON_WATCHDOG_RECOVER ) -// { -// SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 3.0, v24 ); -// watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; -// } -// else + // Verify 24V is down when w.d. recovered TODO - If issue persisted + // ask EE team why 24V does not quite recover all the way to 22.6V even after 750 ms. How long should it take? + if ( ( v24 < MIN_24V_LEVEL_ON_WATCHDOG_RECOVER ) || ( isolatedV24 < MIN_24V_LEVEL_ON_WATCHDOG_RECOVER ) ) { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 3.0F, v24 ); + watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; + } + else + { watchdogSelfTestStatus = SELF_TEST_STATUS_PASSED; } } + else + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 4 ); + watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED; + } result = watchdogSelfTestStatus; watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_COMPLETE; } @@ -224,6 +244,18 @@ } return result; +} + +/*********************************************************************//** + * @brief + * The resetWatchdogPOSTState function resets the watchdog POST state. + * @details Inputs: none + * @details Outputs: watchdogSelfTestState + * @return none + *************************************************************************/ +void resetWatchdogPOSTState( void ) +{ + watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_START; } /*********************************************************************//**