diff options
Diffstat (limited to 'board/cr50/recovery_button.c')
-rw-r--r-- | board/cr50/recovery_button.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/board/cr50/recovery_button.c b/board/cr50/recovery_button.c index af4d4d7c87..0ed4b78508 100644 --- a/board/cr50/recovery_button.c +++ b/board/cr50/recovery_button.c @@ -9,6 +9,8 @@ #include "console.h" #include "extension.h" #include "registers.h" +#include "timer.h" +#include "u2f_impl.h" #include "util.h" /* @@ -20,12 +22,53 @@ */ static uint8_t rec_btn_force_pressed; +/* + * Timestamp of the most recent recovery button press + */ +static timestamp_t last_press; + +/* How long do we latch the last recovery button press */ +#define RECOVERY_BUTTON_TIMEOUT (10 * SECOND) + +void recovery_button_record(void) +{ + last_press = get_time(); +} + +/* + * Read the recovery button latched state and unconditionally clear the state. + * + * Returns 1 iff the recovery button key combination was recorded within the + * last RECOVERY_BUTTON_TIMEOUT microseconds. Note that deep sleep also + * clears the recovery button state. + */ +static int pop_recovery_button_state(void) +{ + int latched_state = 0; + + if (last_press.val && + ((get_time().val - last_press.val) < RECOVERY_BUTTON_TIMEOUT)) + latched_state = 1; + + last_press.val = 0; + + /* Latched recovery button state */ + return latched_state; +} + static uint8_t is_rec_btn_pressed(void) { if (rec_btn_force_pressed) return 1; /* + * Platform has a defined recovery button combination and it + * the combination was pressed within a timeout + */ + if (board_uses_closed_source_set1() && pop_recovery_button_state()) + return 1; + + /* * If not force pressed, check the actual state of button. Note, * the value is inverted because the button is active low. */ @@ -68,6 +111,8 @@ static enum vendor_cmd_rc vc_get_rec_btn(enum vendor_cmd_cc code, *(uint8_t *)buf = is_rec_btn_pressed(); *response_size = 1; + ccprints("%s: state=%d", __func__, *(uint8_t *)buf); + return VENDOR_RC_SUCCESS; } DECLARE_VENDOR_COMMAND(VENDOR_CC_GET_REC_BTN, vc_get_rec_btn); |