From dc6688351c57c3128bf2ae037b066055fdb6ef80 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Tue, 1 Oct 2024 10:46:07 +0200 Subject: [PATCH] feat(core): add power button to button driver [no changelog] --- core/embed/bootloader/bootui.c | 4 +- core/embed/bootloader/main.c | 2 +- core/embed/rust/build.rs | 1 + core/embed/rust/src/trezorhal/io.rs | 11 +++ core/embed/rust/src/ui/event/button.rs | 19 ++-- .../rust/src/ui/model_tr/component/button.rs | 1 + .../model_tr/component/button_controller.rs | 3 + core/embed/trezorhal/button.h | 16 ++-- core/embed/trezorhal/stm32f4/button.c | 91 +++++++++++++++---- 9 files changed, 107 insertions(+), 41 deletions(-) diff --git a/core/embed/bootloader/bootui.c b/core/embed/bootloader/bootui.c index 594202f083..9980272d6c 100644 --- a/core/embed/bootloader/bootui.c +++ b/core/embed/bootloader/bootui.c @@ -169,13 +169,13 @@ void ui_click(void) { void ui_click(void) { for (;;) { button_read(); - if (button_state_left() != 0 && button_state_right() != 0) { + if (button_state(BTN_LEFT) != 0 && button_state(BTN_RIGHT) != 0) { break; } } for (;;) { button_read(); - if (button_state_left() != 1 && button_state_right() != 1) { + if (button_state(BTN_LEFT) != 1 && button_state(BTN_RIGHT) != 1) { break; } } diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index 553df46a47..c237752bb4 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -524,7 +524,7 @@ int bootloader_main(void) { } #elif defined USE_BUTTON button_read(); - if (button_state_left() == 1) { + if (button_state(BTN_LEFT) == 1) { touched = 1; } #endif diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs index 47f4724eba..8a62626ca6 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -450,6 +450,7 @@ fn generate_trezorhal_bindings() { // touch .allowlist_function("touch_get_event") // button + .allowlist_type("button_t") .allowlist_function("button_read") // haptic .allowlist_type("haptic_effect_t") diff --git a/core/embed/rust/src/trezorhal/io.rs b/core/embed/rust/src/trezorhal/io.rs index 6ece57df9f..ae1fdd8952 100644 --- a/core/embed/rust/src/trezorhal/io.rs +++ b/core/embed/rust/src/trezorhal/io.rs @@ -9,3 +9,14 @@ pub fn io_touch_get_event() -> u32 { pub fn io_button_read() -> u32 { unsafe { ffi::button_read() } } + +//#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] + +#[cfg(feature = "button")] +#[derive(Copy, Clone, PartialEq, Eq, FromPrimitive)] +#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] +pub enum PhysicalButton { + Left = ffi::button_t_BTN_LEFT as _, + Right = ffi::button_t_BTN_RIGHT as _, + Power = ffi::button_t_BTN_POWER as _, +} diff --git a/core/embed/rust/src/ui/event/button.rs b/core/embed/rust/src/ui/event/button.rs index d7bae42a7a..cb0f934356 100644 --- a/core/embed/rust/src/ui/event/button.rs +++ b/core/embed/rust/src/ui/event/button.rs @@ -1,11 +1,7 @@ use crate::error::Error; +use num_traits::FromPrimitive; -#[derive(Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] -pub enum PhysicalButton { - Left, - Right, -} +pub use crate::trezorhal::io::PhysicalButton; #[derive(Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "debug", derive(ufmt::derive::uDebug))] @@ -22,12 +18,11 @@ pub enum ButtonEvent { impl ButtonEvent { pub fn new(event: u32, button: u32) -> Result { - let button = match button { - 0 => PhysicalButton::Left, - 1 => PhysicalButton::Right, - _ => return Err(Error::OutOfRange), - }; - let result = match event { + let button = PhysicalButton::from_u32(button); + + let button = button.ok_or(Error::OutOfRange)?; + + let result = match event & 0xFF { 1 => Self::ButtonPressed(button), 2 => Self::ButtonReleased(button), _ => return Err(Error::OutOfRange), diff --git a/core/embed/rust/src/ui/model_tr/component/button.rs b/core/embed/rust/src/ui/model_tr/component/button.rs index 7e630d5d21..33ecbed4ff 100644 --- a/core/embed/rust/src/ui/model_tr/component/button.rs +++ b/core/embed/rust/src/ui/model_tr/component/button.rs @@ -28,6 +28,7 @@ impl From for ButtonPos { match btn { PhysicalButton::Left => ButtonPos::Left, PhysicalButton::Right => ButtonPos::Right, + _ => fatal_error!("unsupported button"), } } } diff --git a/core/embed/rust/src/ui/model_tr/component/button_controller.rs b/core/embed/rust/src/ui/model_tr/component/button_controller.rs index 2809388790..242712fd67 100644 --- a/core/embed/rust/src/ui/model_tr/component/button_controller.rs +++ b/core/embed/rust/src/ui/model_tr/component/button_controller.rs @@ -439,6 +439,7 @@ impl Component for ButtonController { self.right_btn.hold_started(ctx); Some(ButtonControllerMsg::Pressed(ButtonPos::Right)) } + _ => None, }, ) } @@ -465,6 +466,7 @@ impl Component for ButtonController { // _ _ (ButtonState::Nothing, self.right_btn.maybe_trigger(ctx)) } + _ => (ButtonState::Nothing, None), }, // * ▼ | ▼ * ButtonEvent::ButtonPressed(b) if b != which_down => { @@ -562,6 +564,7 @@ impl Component for ButtonController { PhysicalButton::Right => { self.set_pressed(ctx, false, false, true); } + _ => {} }, ButtonState::BothDown | ButtonState::OneReleased(_) => { self.set_pressed(ctx, false, true, false); diff --git a/core/embed/trezorhal/button.h b/core/embed/trezorhal/button.h index 0f77b436ba..91c43d0488 100644 --- a/core/embed/trezorhal/button.h +++ b/core/embed/trezorhal/button.h @@ -25,17 +25,15 @@ #define BTN_EVT_DOWN (1U << 24) #define BTN_EVT_UP (1U << 25) -#define BTN_LEFT 0 -#define BTN_RIGHT 1 - -#ifdef KERNEL_MODE +typedef enum { + BTN_LEFT = 0, + BTN_RIGHT = 1, + BTN_POWER = 2, +} button_t; void button_init(void); - -#endif - uint32_t button_read(void); -char button_state_left(void); -char button_state_right(void); + +bool button_state(button_t button); #endif diff --git a/core/embed/trezorhal/stm32f4/button.c b/core/embed/trezorhal/stm32f4/button.c index 66676aa465..697f755a5d 100644 --- a/core/embed/trezorhal/stm32f4/button.c +++ b/core/embed/trezorhal/stm32f4/button.c @@ -6,27 +6,51 @@ #ifdef KERNEL_MODE -static char last_left = 0, last_right = 0; - -void button_init(void) { - BTN_LEFT_CLK_ENA(); - BTN_RIGHT_CLK_ENA(); - - GPIO_InitTypeDef GPIO_InitStructure = {0}; +static void init_btn(GPIO_TypeDef *port, uint16_t pin) { + GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = BTN_LEFT_PIN; - HAL_GPIO_Init(BTN_LEFT_PORT, &GPIO_InitStructure); - GPIO_InitStructure.Pin = BTN_RIGHT_PIN; - HAL_GPIO_Init(BTN_RIGHT_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = pin; + HAL_GPIO_Init(port, &GPIO_InitStructure); +} + +#ifdef BTN_LEFT_CLK_ENA +static bool last_left = 0; +bool button_state_left(void) { return last_left; } +#endif + +#ifdef BTN_RIGHT_CLK_ENA +static bool last_right = 0; +bool button_state_right(void) { return last_right; } +#endif + +#ifdef BTN_POWER_CLK_ENA +static bool last_power = 0; +bool button_state_power(void) { return last_power; } +#endif + +void button_init(void) { +#ifdef BTN_LEFT_CLK_ENA + BTN_LEFT_CLK_ENA(); + init_btn(BTN_LEFT_PORT, BTN_LEFT_PIN); +#endif + +#ifdef BTN_RIGHT_CLK_ENA + BTN_RIGHT_CLK_ENA(); + init_btn(BTN_RIGHT_PORT, BTN_RIGHT_PIN); +#endif + +#ifdef BTN_POWER_CLK_ENA + BTN_POWER_CLK_ENA(); + init_btn(BTN_POWER_PORT, BTN_POWER_PIN); +#endif } uint32_t button_read(void) { - char left = (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_LEFT_PORT, BTN_LEFT_PIN)); - char right = - (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_RIGHT_PORT, BTN_RIGHT_PIN)); +#ifdef BTN_LEFT_CLK_ENA + bool left = (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_LEFT_PORT, BTN_LEFT_PIN)); if (last_left != left) { last_left = left; if (left) { @@ -35,6 +59,10 @@ uint32_t button_read(void) { return BTN_EVT_UP | BTN_LEFT; } } +#endif +#ifdef BTN_RIGHT_CLK_ENA + bool right = + (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_RIGHT_PORT, BTN_RIGHT_PIN)); if (last_right != right) { last_right = right; if (right) { @@ -43,11 +71,40 @@ uint32_t button_read(void) { return BTN_EVT_UP | BTN_RIGHT; } } +#endif +#ifdef BTN_POWER_CLK_ENA + bool power = + (GPIO_PIN_RESET == HAL_GPIO_ReadPin(BTN_POWER_PORT, BTN_POWER_PIN)); + if (last_power != power) { + last_power = power; + if (power) { + return BTN_EVT_DOWN | BTN_POWER; + } else { + return BTN_EVT_UP | BTN_POWER; + } + } +#endif + return 0; } -char button_state_left(void) { return last_left; } - -char button_state_right(void) { return last_right; } +bool button_state(button_t button) { + switch (button) { +#ifdef BTN_LEFT_CLK_ENA + case BTN_LEFT: + return button_state_left(); +#endif +#ifdef BTN_RIGHT_CLK_ENA + case BTN_RIGHT: + return button_state_right(); +#endif +#ifdef BTN_POWER_CLK_ENA + case BTN_POWER: + return button_state_power(); +#endif + default: + return false; + } +} #endif // KERNEL_MODE