Index: firmware/App/Controllers/Buttons.c =================================================================== diff -u -reff7b1575f008f81b29ef906f6346fac6012d3ab -r52863cba9685f31136ab3f4b4764a17ccf34fc05 --- firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision eff7b1575f008f81b29ef906f6346fac6012d3ab) +++ firmware/App/Controllers/Buttons.c (.../Buttons.c) (revision 52863cba9685f31136ab3f4b4764a17ccf34fc05) @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * Copyright (c) 2019-2020 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. @@ -32,10 +32,34 @@ NUM_OF_BUTTON_SELF_TEST_STATES } BUTTON_SELF_TEST_STATE_T; +typedef enum Buttons +{ + BUTTON_OFF = 0, + BUTTON_STOP, + NUM_OF_BUTTONS +} BUTTON_T; + +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_T; + +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_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 USER_CONFIRMED 1 #define USER_REJECTED 0 @@ -44,16 +68,17 @@ 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; 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 U32 offRequestPulseCount = 0; -static U32 offRequestPulseTimer = 0; - static BUTTON_SELF_TEST_STATE_T buttonSelfTestState = BUTTON_SELF_TEST_STATE_START; static U32 buttonSelfTestTimerCount = 0; @@ -75,15 +100,16 @@ void initButtons( void ) { prevOffButtonState = BUTTON_STATE_RELEASED; + offRequestAwaitingUserConfirmation = FALSE; + offRequestPendingTimer = 0; offButtonPressPending = FALSE; + offRequestPulseCount = 0; + offRequestPulseTimer = 0; prevStopButtonState = BUTTON_STATE_RELEASED; stopButtonPressPending = FALSE; stopButtonPendingTimer = 0; - offRequestPulseCount = 0; - offRequestPulseTimer = 0; - buttonSelfTestState = BUTTON_SELF_TEST_STATE_START; buttonSelfTestTimerCount = 0; } @@ -158,35 +184,6 @@ DATA_GET( BUTTON_STATE_T, getStopButtonState, dataStopButtonState ) /************************************************************************* - * @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 - * if rejected by user. - * @details - * Inputs : current operation mode - * Outputs : stopButtonPressPending - * @param response : 1 = confirmed, 0 = rejected - * @return none - *************************************************************************/ -void userConfirmOffButton( U08 response ) -{ - // did user confirm? - if ( USER_CONFIRMED == response ) - { - if ( TRUE == isCurrentOpModeOkToTurnOff() ) - { - offButtonPressPending = TRUE; - offRequestPulseCount = OFF_REQUEST_PULSE_COUNT; - offRequestPulseTimer = 0; - } - } - else // user did not confirm - { - // for now, don't need to do anything to reject off button press - } -} - -/************************************************************************* * @brief execStuckButtonTest * The execStuckButtonTest function executes the stuck button test. \n * This function should be called periodically until a pass or fail \n @@ -211,14 +208,16 @@ case BUTTON_SELF_TEST_STATE_IN_PROGRESS: if ( ( dataOffButtonState.data == BUTTON_STATE_RELEASED ) && ( dataStopButtonState.data == BUTTON_STATE_RELEASED ) ) { - result = SELF_TEST_STATUS_PASSED; buttonSelfTestState = BUTTON_SELF_TEST_STATE_COMPLETE; + result = SELF_TEST_STATUS_PASSED; } else if ( TRUE == didTimeout( buttonSelfTestTimerCount, STUCK_BUTTON_TIMEOUT ) ) { - result = SELF_TEST_STATUS_FAILED; - // TODO - trigger stuck button POST failure + U32 almData = ( dataStopButtonState.data == BUTTON_STATE_PRESSED ? BUTTON_STOP : BUTTON_OFF ); + + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_STUCK_BUTTON_TEST_FAILED, almData ) buttonSelfTestState = BUTTON_SELF_TEST_STATE_COMPLETE; + result = SELF_TEST_STATUS_FAILED; } // else just stay in progress and wait for next call break; @@ -230,14 +229,74 @@ default: result = SELF_TEST_STATUS_FAILED; - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_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 + * if rejected by user. + * @details + * Inputs : current operation mode + * Outputs : stopButtonPressPending + * @param response : 1 = confirmed, 0 = rejected + * @return none + *************************************************************************/ +void userConfirmOffButton( U08 response ) +{ + switch ( response ) + { + case OFF_BUTTON_RSP_USER_REQUESTS_POWER_OFF: + // if we're in a mode that allows power off, set off pending flag and request user confirmation + if ( TRUE == isCurrentOpModeOkToTurnOff() ) + { + offRequestAwaitingUserConfirmation = TRUE; + offRequestPendingTimer = 0; + sendOffButtonMsgToUI( OFF_BUTTON_CMD_PROMPT_USER_TO_CONFIRM ); + } + else + { // send rejection response to power off request + sendOffButtonMsgToUI( OFF_BUTTON_CMD_REJECT_USER_OFF_REQUEST ); + } + break; + + case OFF_BUTTON_RSP_USER_CONFIRMS_POWER_OFF: + // is an off request pending user confirmation? + if ( TRUE == offRequestAwaitingUserConfirmation ) + { + // reset off request pending flag + offRequestAwaitingUserConfirmation = FALSE; + // if we're in a mode that allows power off, initiate power off sequence + if ( TRUE == isCurrentOpModeOkToTurnOff() ) + { + offButtonPressPending = TRUE; + offRequestPulseCount = OFF_REQUEST_PULSE_COUNT; + offRequestPulseTimer = 0; + } + } + break; + + case OFF_BUTTON_RSP_USER_REJECTS_POWER_OFF: + // is an off request pending user confirmation? + if ( TRUE == offRequestAwaitingUserConfirmation ) + { + // reset off request pending flag + offRequestAwaitingUserConfirmation = FALSE; + } + break; + + default: + // ok - do nothing + break; + } // end switch +} + +/************************************************************************* * @brief isCurrentOpModeOkToTurnOff * The isCurrentOpModeOkToTurnOff function determines whether the system can \n * be turned off in current operation mode. @@ -281,7 +340,9 @@ if ( TRUE == isCurrentOpModeOkToTurnOff() ) { // send off button to UI for user confirmation - sendOffButtonMsgToUI(); + sendOffButtonMsgToUI( OFF_BUTTON_CMD_PROMPT_USER_TO_CONFIRM ); + offRequestAwaitingUserConfirmation = TRUE; + offRequestPendingTimer = 0; #ifdef SIMULATE_UI userConfirmOffButton( USER_CONFIRMED ); #endif @@ -290,6 +351,17 @@ prevOffButtonState = getOffButtonState(); } + // if off request has not been confirmed by user before it expires, cancel it + if ( TRUE == offRequestAwaitingUserConfirmation ) + { + offRequestPendingTimer += TASK_PRIORITY_INTERVAL; + if ( offRequestPendingTimer >= OFF_REQUEST_EXPIRATION_TIME ) + { + offRequestAwaitingUserConfirmation = FALSE; + sendOffButtonMsgToUI( OFF_BUTTON_CMD_CANCEL_USER_CONFIRM_PROMPT ); + } + } + // if user confirmed off button press, manage off request sequence if ( TRUE == offButtonPressPending ) { @@ -336,7 +408,8 @@ // if stop button not consumed within a reasonable time, s/w fault if ( TRUE == didTimeout( stopButtonPendingTimer, STOP_BUTTON_PENDING_TIMEOUT ) ) { - // TODO - s/w fault + stopButtonPressPending = FALSE; + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_SOFTWARE_FAULT, SW_FAULT_ID_BUTTONS_STOP_BUTTON_NOT_CONSUMED ) } } }