Index: firmware/App/Drivers/SafetyShutdown.c =================================================================== diff -u -r8e6488e189349e0f87f2fb21fa8176aced0b5a43 -r7d4711edd7b40cd3e29f43e766f79a8a09586fe9 --- firmware/App/Drivers/SafetyShutdown.c (.../SafetyShutdown.c) (revision 8e6488e189349e0f87f2fb21fa8176aced0b5a43) +++ firmware/App/Drivers/SafetyShutdown.c (.../SafetyShutdown.c) (revision 7d4711edd7b40cd3e29f43e766f79a8a09586fe9) @@ -1,24 +1,26 @@ /************************************************************************** * -* Copyright (c) 2019-2020 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 SafetyShutdown.c +* @file SafetyShutdown.c * -* @author (last) Sean Nash -* @date (last) 04-Jun-2020 +* @author (last) Vinayakam Mani +* @date (last) 03-Oct-2023 * -* @author (original) Dara Navaei -* @date (original) 05-Nov-2019 +* @author (original) Dara Navaei +* @date (original) 05-Nov-2019 * ***************************************************************************/ #include "mibspi.h" +#include "InternalADC.h" #include "SystemCommMessages.h" #include "SafetyShutdown.h" +#include "Timers.h" /** * @addtogroup SafetyShutdown @@ -27,63 +29,174 @@ // ********** private definitions ********** -// pin I/O macros -#define SAFETY_SPI1_PORT_MASK 0x00000010 // (CS[4] - re-purposed as output GPIO) -#define SET_SAFETY_SHUTDOWN() {mibspiREG1->PC3 |= SAFETY_SPI1_PORT_MASK;} -#define CLR_SAFETY_SHUTDOWN() {mibspiREG1->PC3 &= ~SAFETY_SPI1_PORT_MASK;} +#define SAFETY_SPI1_PORT_MASK 0x00000010 ///< Safety shutdown GPIO port mask (CS[4] - re-purposed as output GPIO). +#define SET_SAFETY_SHUTDOWN() {mibspiREG1->PC3 |= SAFETY_SPI1_PORT_MASK;} ///< Set safety shutdown GPIO macro. +#define CLR_SAFETY_SHUTDOWN() {mibspiREG1->PC3 &= ~SAFETY_SPI1_PORT_MASK;} ///< Clear safety shutdown GPIO macro. -// ********** private definitions ********** +#define SAFETY_SHUTDOWN_POST_TIMEOUT_MS 500 ///< Safety shutdown POST test timeout (in ms). +#define SAFETY_SHUTDOWN_RECOVERY_TIME_MS 500 ///< After safety shutdown POST test, wait this long (in ms) to recover before moving on. + +#define MAX_24V_LEVEL_ON_SAFETY_SHUTDOWN 5.0F ///< Maximum voltage on 24V line when safety shutdown asserted. +#define MAX_ISOLATED_24V_LEVEL_ON_SS_EXPIRED 22.6F ///< Maximum voltage on isolated 24V line when watchdog is expired. 10% of 24V. +#define MIN_24V_LEVEL_ON_SAFETY_RECOVER 22.6F ///< Minimum voltage on 24V line when safety shutdown is recovered. + +/// Enumeration of safety shutdown self-test states. +typedef enum Safety_Shutdown_Self_Test_States +{ + SAFETY_SHUTDOWN_SELF_TEST_STATE_START = 0, ///< Safety shutdown self-test start state + SAFETY_SHUTDOWN_SELF_TEST_STATE_IN_PROGRESS, ///< Safety shutdown self-test in progress state + SAFETY_SHUTDOWN_SELF_TEST_STATE_RECOVER, ///< Safety shutdown self-test recovery state + SAFETY_SHUTDOWN_SELF_TEST_STATE_COMPLETE, ///< Safety shutdown self-test completed state + NUM_OF_SAFETY_SHUTDOWN_SELF_TEST_STATES ///< Number of safety shutdown self-test states +} SAFETY_SHUTDOWN_SELF_TEST_STATE_T; + +// ********** private data ********** -static BOOL safetyShutdownActivated = FALSE; ///< Status of safety shutdown signal. -static BOOL safetyShutdownOverrideResetState = FALSE; ///< Natural status of safety shutdown signal. Used to restore state on override reset. +static BOOL safetyShutdownActivated; ///< Status of safety shutdown signal. +static BOOL safetyShutdownOverrideResetState; ///< Natural status of safety shutdown signal. Used to restore state on override reset. +static SAFETY_SHUTDOWN_SELF_TEST_STATE_T safetyShutdownSelfTestState; ///< Current safety shutdown self-test state. +static SELF_TEST_STATUS_T safetyShutdownSelfTestStatus; ///< Safety shutdown self-test preliminary status. +static U32 safetyShutdownSelfTestTimerCount; ///< Safety shutdown self-test state timer counter. /*********************************************************************//** * @brief - * The initSafetyShutdown function initializes the Safety Shutdown module. - * @details - * Inputs : none - * Outputs : Safety Shutdown module signal output set to initial state. + * The initSafetyShutdown function initializes the safety shutdown module. + * @details Inputs: none + * @details Outputs: safetyShutdownActivated, safetyShutdownOverrideResetState, + * safetyShutdownSelfTestState, safetyShutdownSelfTestStatus, + * safetyShutdownSelfTestTimerCount * @return none *************************************************************************/ void initSafetyShutdown( void ) { - CLR_SAFETY_SHUTDOWN(); + safetyShutdownActivated = FALSE; + safetyShutdownOverrideResetState = FALSE; + safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_START; + safetyShutdownSelfTestStatus = SELF_TEST_STATUS_IN_PROGRESS; + safetyShutdownSelfTestTimerCount = 0; + CLR_SAFETY_SHUTDOWN(); } /*********************************************************************//** * @brief * The activateSafetyShutdown function activates the safety shutdown signal. - * @details - * Inputs : none - * Outputs : Safety Shutdown signal output set to active state. + * @details Inputs: none + * @details Outputs: Safety shutdown signal output set to active state. * @return none *************************************************************************/ void activateSafetyShutdown( void ) { - SET_SAFETY_SHUTDOWN(); + SET_SAFETY_SHUTDOWN(); + safetyShutdownActivated = TRUE; } /*********************************************************************//** * @brief - * The isSafetyShutdownActivated function returns whether the safety shutdown \n + * The isSafetyShutdownActivated function returns whether the safety shutdown * signal has been activated. - * @details - * Inputs : none - * Outputs : none + * @details Inputs: none + * @details Outputs: none * @return safetyShutdownActivated *************************************************************************/ BOOL isSafetyShutdownActivated( void ) { return safetyShutdownActivated; } +/*********************************************************************//** + * @brief + * The execSafetyShutdownTest function executes the safety shutdown test. + * This function should be called periodically until a pass or fail + * result is returned. + * @details Inputs: safetyShutdownSelfTestState + * @details Outputs: safetyShutdownSelfTestState + * @return in progress, passed, or failed + *************************************************************************/ +SELF_TEST_STATUS_T execSafetyShutdownTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + + switch ( safetyShutdownSelfTestState ) + { + case SAFETY_SHUTDOWN_SELF_TEST_STATE_START: + safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_IN_PROGRESS; + safetyShutdownSelfTestTimerCount = getMSTimerCount(); + activateSafetyShutdown(); + break; + + case SAFETY_SHUTDOWN_SELF_TEST_STATE_IN_PROGRESS: + if ( TRUE == didTimeout( safetyShutdownSelfTestTimerCount, SAFETY_SHUTDOWN_POST_TIMEOUT_MS ) ) + { + 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_SAFETY_SHUTDOWN ) || ( isolatedV24 > MAX_ISOLATED_24V_LEVEL_ON_SS_EXPIRED ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SAFETY_SHUTDOWN_POST_TEST_FAILED, 1.0, v24 ); + safetyShutdownSelfTestStatus = SELF_TEST_STATUS_FAILED; + } + safetyShutdownSelfTestTimerCount = getMSTimerCount(); + CLR_SAFETY_SHUTDOWN(); + safetyShutdownActivated = FALSE; + safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_RECOVER; + } + break; + + case SAFETY_SHUTDOWN_SELF_TEST_STATE_RECOVER: + if ( TRUE == didTimeout( safetyShutdownSelfTestTimerCount, SAFETY_SHUTDOWN_RECOVERY_TIME_MS ) ) + { + F32 v24 = getIntADCVoltageConverted( INT_ADC_SECONDARY_HEATER_24_VOLTS ); + F32 isolatedV24 = getRawIsolatedPowerSupplyVoltage(); + + // Verify 24V is down when w.d. recovered + if ( ( v24 < MIN_24V_LEVEL_ON_SAFETY_RECOVER ) || ( isolatedV24 < MAX_ISOLATED_24V_LEVEL_ON_SS_EXPIRED ) ) + { + // TODO - If issue persisted talk with systems why 24V does not recover fully. + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SAFETY_SHUTDOWN_POST_TEST_FAILED, 2.0, v24 ); + safetyShutdownSelfTestStatus = SELF_TEST_STATUS_FAILED; + } + else + { + safetyShutdownSelfTestStatus = SELF_TEST_STATUS_PASSED; + } + safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_COMPLETE; + result = safetyShutdownSelfTestStatus; + } + break; + + case SAFETY_SHUTDOWN_SELF_TEST_STATE_COMPLETE: + // If we get called in this state, assume we are doing self-test again + result = SELF_TEST_STATUS_IN_PROGRESS; + safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_START; + break; + + default: + result = SELF_TEST_STATUS_FAILED; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_SAFETY_SHUTDOWN_INVALID_SELF_TEST_STATE, safetyShutdownSelfTestState ) + break; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The resetSafetyShutdownPOSTState function resets the safety shutdown POST state. + * @details Inputs: none + * @details Outputs: safetyShutdownSelfTestState + * @return none + *************************************************************************/ +void resetSafetyShutdownPOSTState( void ) +{ + safetyShutdownSelfTestState = SAFETY_SHUTDOWN_SELF_TEST_STATE_START; +} + /*********************************************************************//** * @brief - * The testSetSafetyShutdownOverride function overrides the HD safety \n - * shutdown. - * @details - * Inputs : none - * Outputs : HD safety shutdown overridden + * The testSetSafetyShutdownOverride function overrides the HD safety shutdown. + * @details Inputs: none + * @details Outputs: HD safety shutdown overridden * @param value TRUE to activate safety shutdown, FALSE to de-activate it * @return TRUE if override successful, FALSE if not *************************************************************************/ @@ -113,11 +226,10 @@ /*********************************************************************//** * @brief - * The testResetSafetyShutdownOverride function resets the override of the \n + * The testResetSafetyShutdownOverride function resets the override of the * HD safety shutdown. - * @details - * Inputs : none - * Outputs : shutdown override reset + * @details Inputs: none + * @details Outputs: shutdown override reset * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetSafetyShutdownOverride( void )