Index: firmware/App/Controllers/Buttons.c =================================================================== diff -u -rde5a0d43bdef611d963d11855bc958a8d8899a09 -r9a20996b770f446b8c669cba7a49668c1fdadd67 --- firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision de5a0d43bdef611d963d11855bc958a8d8899a09) +++ firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision 9a20996b770f446b8c669cba7a49668c1fdadd67) @@ -16,85 +16,98 @@ ***************************************************************************/ #include "Buttons.h" -#include "CPLD.h" +#include "CPLD.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "SystemCommMessages.h" #include "TaskPriority.h" #include "Timers.h" +/** + * @addtogroup Buttons + * @{ + */ + // ********** private definitions ********** - + +/// Enumeration of button self-test states. typedef enum Button_Self_Test_States { - BUTTON_SELF_TEST_STATE_START = 0, - BUTTON_SELF_TEST_STATE_IN_PROGRESS, - BUTTON_SELF_TEST_STATE_COMPLETE, - NUM_OF_BUTTON_SELF_TEST_STATES + BUTTON_SELF_TEST_STATE_START = 0, ///< Button self-test start state + BUTTON_SELF_TEST_STATE_IN_PROGRESS, ///< Button self-test in progress state + BUTTON_SELF_TEST_STATE_COMPLETE, ///< Button self-test completed state + NUM_OF_BUTTON_SELF_TEST_STATES ///< Number of button self-test states } BUTTON_SELF_TEST_STATE_T; - + +/// Enumeration of hardware buttons. typedef enum Buttons { - BUTTON_OFF = 0, - BUTTON_STOP, - NUM_OF_BUTTONS + BUTTON_OFF = 0, ///< Off button + BUTTON_STOP, ///< Stop button + NUM_OF_BUTTONS ///< Number of hardware buttons } BUTTON_T; - + +/// Enumeration of off button commands to UI. typedef enum OffButtonCmdsToUI { - OFF_BUTTON_CMD_PROMPT_USER_TO_CONFIRM = 0, - OFF_BUTTON_CMD_CANCEL_USER_CONFIRM_PROMPT, - OFF_BUTTON_CMD_REJECT_USER_OFF_REQUEST, - NUM_OF_OFF_BUTTON_CMDS + OFF_BUTTON_CMD_PROMPT_USER_TO_CONFIRM = 0, ///< Prompt user to confirm power off command + OFF_BUTTON_CMD_CANCEL_USER_CONFIRM_PROMPT, ///< Cancel user confirm prompt command + OFF_BUTTON_CMD_REJECT_USER_OFF_REQUEST, ///< Reject user off request command + NUM_OF_OFF_BUTTON_CMDS ///< Number of off button commands to UI } OFF_BUTTON_CMD_T; - + +/// Enumeration of off button responses from UI. typedef enum OffButtonRspsFromUI { - OFF_BUTTON_RSP_USER_REQUESTS_POWER_OFF = 0, - OFF_BUTTON_RSP_USER_CONFIRMS_POWER_OFF, - OFF_BUTTON_RSP_USER_REJECTS_POWER_OFF, - NUM_OF_OFF_BUTTON_RSPS + OFF_BUTTON_RSP_USER_REQUESTS_POWER_OFF = 0, ///< User requests power off response + OFF_BUTTON_RSP_USER_CONFIRMS_POWER_OFF, ///< User confirms power off response + OFF_BUTTON_RSP_USER_REJECTS_POWER_OFF, ///< User rejects power off response + NUM_OF_OFF_BUTTON_RSPS ///< Number of off button responses from UI } OFF_BUTTON_RSP_T; -#define OFF_REQUEST_PULSE_COUNT 4 -#define OFF_REQUEST_PULSE_INTVL 50 // ms -#define STOP_BUTTON_PENDING_TIMEOUT 500 // ms -#define STUCK_BUTTON_TIMEOUT 1000 // ms -#define OFF_REQUEST_EXPIRATION_TIME (1000 * 60) // ms (1 minute) +#define OFF_REQUEST_PULSE_COUNT 4 ///< Number of edges for power off sequence on power off output signal. +#define OFF_REQUEST_PULSE_INTVL_MS 50 ///< Duration (in ms) of power off sequence steps. +#define OFF_REQUEST_DELAY_TIME_MS 2000 ///< Duration (in ms) of delay before power off sequence is initiated to provide sub-systems time to wrap things up. +#define STOP_BUTTON_PENDING_TIMEOUT_MS 500 ///< Timeout period (in ms) for stop button press to be consumed. +#define STUCK_BUTTON_TIMEOUT_MS 1000 ///< Duration (in ms) that a button must be in pressed state before considering it stuck at power up. +#define OFF_REQUEST_EXPIRATION_TIME_MS (1000 * 60) ///< Time (in ms) that the user is given to confirm a power off request before it expires. -#define USER_CONFIRMED 1 -#define USER_REJECTED 0 +#define USER_CONFIRMED 1 ///< User response code to power off confirmation prompt that indicates confirmation. +#define USER_REJECTED 0 ///< User response code to power off confirmation prompt that indicates rejection. // ********** private data ********** + +/// Current off button state (overrideable). +static OVERRIDE_U32_T dataOffButtonState = { BUTTON_STATE_RELEASED, BUTTON_STATE_PRESSED, BUTTON_STATE_PRESSED, 0 }; +static BUTTON_STATE_T prevOffButtonState = BUTTON_STATE_RELEASED; ///< Previous state of off button. +static BOOL offRequestAwaitingUserConfirmation = FALSE; ///< Flag indicates whether a power off request is pending user confirmation. +static U32 offRequestPendingTimer = 0; ///< Timer counter for pending power off request. +static BOOL offButtonPressPending = FALSE; ///< Flag indicates whether a confirmed power off request is pending execution. +static U32 offRequestPulseCount = 0; ///< Power off sequence step counter. +static U32 offRequestPulseTimer = 0; ///< Power off sequence step timer counter. +static U32 offRequestDelayTimer = 0; ///< Power off sequence delay timer counter. -DATA_DECL( BUTTON_STATE_T, OffButtonState, dataOffButtonState, BUTTON_STATE_RELEASED, BUTTON_STATE_PRESSED ); -static BUTTON_STATE_T prevOffButtonState = BUTTON_STATE_RELEASED; -static BOOL offRequestAwaitingUserConfirmation = FALSE; -static U32 offRequestPendingTimer = 0; -static BOOL offButtonPressPending = FALSE; -static U32 offRequestPulseCount = 0; -static U32 offRequestPulseTimer = 0; +/// Current stop button state (overrideable). +static OVERRIDE_U32_T dataStopButtonState = { BUTTON_STATE_RELEASED, BUTTON_STATE_PRESSED, BUTTON_STATE_PRESSED, 0 }; +static BUTTON_STATE_T prevStopButtonState = BUTTON_STATE_RELEASED; ///< Previous state of stop button. +static BOOL stopButtonPressPending = FALSE; ///< Flag indicates a stop button press is pending consumption. +static U32 stopButtonPendingTimer = 0; ///< Timer counter for pending stop button press. -DATA_DECL( BUTTON_STATE_T, StopButtonState, dataStopButtonState, BUTTON_STATE_RELEASED, BUTTON_STATE_PRESSED ); -static BUTTON_STATE_T prevStopButtonState = BUTTON_STATE_RELEASED; -static BOOL stopButtonPressPending = FALSE; -static U32 stopButtonPendingTimer = 0; +static BUTTON_SELF_TEST_STATE_T buttonSelfTestState = BUTTON_SELF_TEST_STATE_START; ///< Current state of button self-test. +static U32 buttonSelfTestTimerCount = 0; ///< Timer counter for button self-test states. -static BUTTON_SELF_TEST_STATE_T buttonSelfTestState = BUTTON_SELF_TEST_STATE_START; -static U32 buttonSelfTestTimerCount = 0; - // ********** private function prototypes ********** static void handleOffButtonProcessing( void ); static void handleStopButtonProcessing( void ); static BOOL isCurrentOpModeOkToTurnOff( void ); -/************************************************************************* - * @brief initButtons +/*********************************************************************//** + * @brief * The initButtons function initializes the Buttons module. * @details * Inputs : none * Outputs : Buttons module initialized. - * @param none * @return none *************************************************************************/ void initButtons( void ) @@ -114,13 +127,12 @@ buttonSelfTestTimerCount = 0; } -/************************************************************************* - * @brief execButtons +/*********************************************************************//** + * @brief * The execButtons function executes the Buttons monitor. * @details * Inputs : none * Outputs : offButtonState, stopButtonState, prevOffButtonState, prevStopButtonState - * @param none * @return none *************************************************************************/ void execButtons( void ) @@ -139,15 +151,14 @@ handleOffButtonProcessing(); } -/************************************************************************* - * @brief isStopButtonPressed - * The isStopButtonPressed function determines whether the stop button has been \n - * pressed. Once the stop button has transitioned from released to pressed, a \n - * press for the stop button will be pending until this function is called. \n +/*********************************************************************//** + * @brief + * The isStopButtonPressed function determines whether the stop button has been + * pressed. Once the stop button has transitioned from released to pressed, a + * press for the stop button will be pending until this function is called. * @details * Inputs : stopButtonPressPending * Outputs : stopButtonPressPending - * @param button * @return true if the stop button is pressed, false if not *************************************************************************/ BOOL isStopButtonPressed( void ) @@ -159,39 +170,56 @@ return result; } -/************************************************************************* - * @brief getOffButtonState - * The getOffButtonState function determines whether the off button is \n +/*********************************************************************//** + * @brief + * The getOffButtonState function determines whether the off button is * currently pressed. * @details * Inputs : dataOffButtonState, prevOffButtonState * Outputs : none - * @param none * @return BUTTON_STATE_PRESSED if off button pressed, BUTTON_STATE_RELEASED if not *************************************************************************/ -DATA_GET( BUTTON_STATE_T, getOffButtonState, dataOffButtonState ) +BUTTON_STATE_T getOffButtonState( void ) +{ + BUTTON_STATE_T result = (BUTTON_STATE_T)dataOffButtonState.data; + + if ( OVERRIDE_KEY == dataOffButtonState.override ) + { + result = (BUTTON_STATE_T)dataOffButtonState.ovData; + } + + return result; +} -/************************************************************************* - * @brief getStopButtonState - * The getStopButtonState function determines whether the stop button is \n +/*********************************************************************//** + * @brief + * The getStopButtonState function determines whether the stop button is * currently pressed. * @details * Inputs : dataStopButtonState, prevStopButtonState * Outputs : none - * @param none * @return BUTTON_STATE_PRESSED if stop button pressed, BUTTON_STATE_RELEASED if not *************************************************************************/ -DATA_GET( BUTTON_STATE_T, getStopButtonState, dataStopButtonState ) +BUTTON_STATE_T getStopButtonState( void ) +{ + BUTTON_STATE_T result = (BUTTON_STATE_T)dataStopButtonState.data; + + if ( OVERRIDE_KEY == dataStopButtonState.override ) + { + result = (BUTTON_STATE_T)dataStopButtonState.ovData; + } + + return result; +} -/************************************************************************* - * @brief execStuckButtonTest - * The execStuckButtonTest function executes the stuck button test. \n - * This function should be called periodically until a pass or fail \n +/*********************************************************************//** + * @brief + * The execStuckButtonTest function executes the stuck button test. + * This function should be called periodically until a pass or fail * result is returned. * @details - * Inputs : - * Outputs : - * @param none + * Inputs : dataOffButtonState + * Outputs : buttonSelfTestState, buttonSelfTestTimerCount * @return in progress, passed, or failed *************************************************************************/ SELF_TEST_STATUS_T execStuckButtonTest( void ) @@ -211,7 +239,7 @@ buttonSelfTestState = BUTTON_SELF_TEST_STATE_COMPLETE; result = SELF_TEST_STATUS_PASSED; } - else if ( TRUE == didTimeout( buttonSelfTestTimerCount, STUCK_BUTTON_TIMEOUT ) ) + else if ( TRUE == didTimeout( buttonSelfTestTimerCount, STUCK_BUTTON_TIMEOUT_MS ) ) { U32 almData = ( dataStopButtonState.data == BUTTON_STATE_PRESSED ? BUTTON_STOP : BUTTON_OFF ); @@ -223,28 +251,28 @@ break; case BUTTON_SELF_TEST_STATE_COMPLETE: - // if we get called in this state, assume we're doing self test again + // if we get called in this state, assume we're doing self-test again buttonSelfTestState = BUTTON_SELF_TEST_STATE_START; break; default: result = SELF_TEST_STATUS_FAILED; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_BUTTONS_INVALID_SELF_TEST_STATE, buttonSelfTestState ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BUTTONS_INVALID_SELF_TEST_STATE, buttonSelfTestState ) break; } return result; } -/************************************************************************* - * @brief userConfirmOffButton - * The userConfirmOffButton function handles user confirmation of the off \n - * button. The off request will be initiated here if confirmed or cancelled \n +/*********************************************************************//** + * @brief + * The userConfirmOffButton function handles user confirmation of the off + * button. The off request will be initiated here if confirmed or cancelled * if rejected by user. * @details * Inputs : current operation mode * Outputs : stopButtonPressPending - * @param response : 1 = confirmed, 0 = rejected + * @param response 1 = confirmed, 0 = rejected * @return none *************************************************************************/ void userConfirmOffButton( U08 response ) @@ -276,8 +304,8 @@ // if we're in a mode that allows power off, initiate power off sequence if ( TRUE == isCurrentOpModeOkToTurnOff() ) { - broadcastPowerOffWarning(); - // TODO - maybe delay a bit before starting power off sequence here to allow sub-systems time to get warning and wrap up critical activities + broadcastPowerOffWarning(); + signalPowerOffWarning(); offButtonPressPending = TRUE; offRequestPulseCount = OFF_REQUEST_PULSE_COUNT; offRequestPulseTimer = 0; @@ -308,14 +336,13 @@ } // end switch } -/************************************************************************* - * @brief isCurrentOpModeOkToTurnOff - * The isCurrentOpModeOkToTurnOff function determines whether the system can \n +/*********************************************************************//** + * @brief + * The isCurrentOpModeOkToTurnOff function determines whether the system can * be turned off in current operation mode. * @details * Inputs : Current operation mode. * Outputs : none - * @param none * @return TRUE if can turn system off in current mode, FALSE if not *************************************************************************/ static BOOL isCurrentOpModeOkToTurnOff( void ) @@ -331,14 +358,13 @@ return result; } -/************************************************************************* - * @brief handleOffButtonProcessing - * The handleOffButtonProcessing function checks for and processes off button \n +/*********************************************************************//** + * @brief + * The handleOffButtonProcessing function checks for and processes off button * activity. * @details * Inputs : offButtonState, prevOffButtonState * Outputs : offButtonPressPending, offRequestPulseCount, offRequestPulseTimer - * @param none * @return none *************************************************************************/ static void handleOffButtonProcessing( void ) @@ -361,7 +387,7 @@ if ( TRUE == offRequestAwaitingUserConfirmation ) { offRequestPendingTimer += TASK_PRIORITY_INTERVAL; - if ( offRequestPendingTimer >= OFF_REQUEST_EXPIRATION_TIME ) + if ( offRequestPendingTimer >= OFF_REQUEST_EXPIRATION_TIME_MS ) { offRequestAwaitingUserConfirmation = FALSE; sendOffButtonMsgToUI( OFF_BUTTON_CMD_CANCEL_USER_CONFIRM_PROMPT ); @@ -370,29 +396,34 @@ // if user confirmed off button press, manage off request sequence if ( TRUE == offButtonPressPending ) - { - offRequestPulseTimer += TASK_PRIORITY_INTERVAL; - if ( offRequestPulseTimer >= OFF_REQUEST_PULSE_INTVL ) - { - offRequestPulseTimer = 0; - offRequestPulseCount--; - if ( offRequestPulseCount == 0 ) - { - offButtonPressPending = false; - } - toggleCPLDOffRequest(); + { + // delay power off to provide sub-systems time to prepare for shutdown + offRequestDelayTimer += TASK_PRIORITY_INTERVAL; + if ( offRequestDelayTimer >= OFF_REQUEST_DELAY_TIME_MS ) + { + // power off sequence is 4 50 ms toggles of the off request output signal + offRequestPulseTimer += TASK_PRIORITY_INTERVAL; + if ( offRequestPulseTimer >= OFF_REQUEST_PULSE_INTVL_MS ) + { + offRequestPulseTimer = 0; + offRequestPulseCount--; + if ( offRequestPulseCount == 0 ) + { + offButtonPressPending = false; + } + toggleCPLDOffRequest(); + } } } } -/************************************************************************* - * @brief handleStopButtonProcessing - * The handleStopButtonProcessing function checks for and processes stop button \n +/*********************************************************************//** + * @brief + * The handleStopButtonProcessing function checks for and processes stop button * activity. * @details * Inputs : stopButtonState, prevStopButtonState * Outputs : stopButtonPressPending - * @param none * @return none *************************************************************************/ static void handleStopButtonProcessing( void ) @@ -412,10 +443,10 @@ if ( TRUE == stopButtonPressPending ) { // if stop button not consumed within a reasonable time, s/w fault - if ( TRUE == didTimeout( stopButtonPendingTimer, STOP_BUTTON_PENDING_TIMEOUT ) ) + if ( TRUE == didTimeout( stopButtonPendingTimer, STOP_BUTTON_PENDING_TIMEOUT_MS ) ) { stopButtonPressPending = FALSE; - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_BUTTONS_STOP_BUTTON_NOT_CONSUMED ) + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_BUTTONS_STOP_BUTTON_NOT_CONSUMED ) } } } @@ -426,31 +457,98 @@ *************************************************************************/ -/************************************************************************* - * @brief testSetOffButtonStateOverride and testResetOffButtonStateOverride - * The testSetOffButtonStateOverride function overrides the state of the \n - * off button with a given state. \n - * The testResetOffButtonStateOverride function resets the override of the \n - * state of the off button. +/*********************************************************************//** + * @brief + * The testSetOffButtonStateOverride function overrides the state of then + * off button with a given state.n * @details * Inputs : none * Outputs : dataOffButtonState - * @param value : override state for the off button + * @param value override state for the off button * @return TRUE if override successful, FALSE if not *************************************************************************/ -DATA_OVERRIDE_FUNC( BUTTON_STATE_T, testSetOffButtonStateOverride, testResetOffButtonStateOverride, dataOffButtonState ) +BOOL testSetOffButtonStateOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataOffButtonState.ovData = value; + dataOffButtonState.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetOffButtonStateOverride function resets the override of then + * state of the off button. + * @details + * Inputs : none + * Outputs : dataOffButtonState + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetOffButtonStateOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataOffButtonState.override = OVERRIDE_RESET; + dataOffButtonState.ovData = dataOffButtonState.ovInitData; + } + + return result; +} -/************************************************************************* - * @brief testSetStopButtonStateOverride and testResetStopButtonStateOverride - * The testSetStopButtonStateOverride function overrides the state of the \n - * stop button with a given state. \n - * The testResetStopButtonStateOverride function resets the override of the \n - * state of the stop button. +/*********************************************************************//** + * @brief + * The testSetStopButtonStateOverride function overrides the state of then + * stop button with a given state. * @details * Inputs : none * Outputs : dataStopButtonState - * @param value : override state for the stop button + * @param value override state for the stop button * @return TRUE if override successful, FALSE if not *************************************************************************/ -DATA_OVERRIDE_FUNC( BUTTON_STATE_T, testSetStopButtonStateOverride, testResetStopButtonStateOverride, dataStopButtonState ) +BOOL testSetStopButtonStateOverride( U32 value ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataStopButtonState.ovData = value; + dataStopButtonState.override = OVERRIDE_KEY; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetStopButtonStateOverride function resets the override of then + * state of the stop button. + * @details + * Inputs : none + * Outputs : dataStopButtonState + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetStopButtonStateOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + result = TRUE; + dataStopButtonState.override = OVERRIDE_RESET; + dataStopButtonState.ovData = dataStopButtonState.ovInitData; + } + + return result; +} +/**@}*/