1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 12:28:09 +00:00

feat(core): improve loader haptic effect

[no changelog]
This commit is contained in:
cepetr 2024-04-29 10:37:00 +02:00 committed by TychoVrahe
parent 2e58a4959f
commit 04d5017228
5 changed files with 47 additions and 18 deletions

View File

@ -358,7 +358,8 @@ fn generate_trezorhal_bindings() {
.allowlist_function("button_read")
// haptic
.allowlist_type("haptic_effect_t")
.allowlist_function("haptic_play");
.allowlist_function("haptic_play")
.allowlist_function("haptic_play_rtp");
// Write the bindings to a file in the OUR_DIR.
bindings

View File

@ -11,3 +11,9 @@ pub fn play(effect: HapticEffect) {
ffi::haptic_play(effect as _);
}
}
pub fn play_rtp(amplitude: i8, duration: u16) {
unsafe {
ffi::haptic_play_rtp(amplitude, duration);
}
}

View File

@ -1,5 +1,5 @@
#[cfg(feature = "haptic")]
use crate::trezorhal::haptic::{play, HapticEffect};
use crate::trezorhal::haptic::{self, play, HapticEffect};
use crate::{
time::{Duration, Instant},
ui::{
@ -7,6 +7,7 @@ use crate::{
component::{Component, Event, EventCtx, Pad},
display::{self, toif::Icon, Color},
geometry::{Offset, Rect},
lerp::Lerp,
model_tt::constant,
util::animation_disabled,
},
@ -173,6 +174,10 @@ impl Component for Loader {
} else if self.is_completely_shrunk(now) {
return Some(LoaderMsg::ShrunkCompletely);
} else {
let progress = self.progress(now).unwrap() as f32 / 1000.0;
let ampl = i16::lerp(0, 76, progress);
haptic::play_rtp(ampl as i8, 100);
// There is further progress in the animation, request an animation frame event.
ctx.request_anim_frame();
}

View File

@ -23,4 +23,11 @@ bool haptic_test(uint16_t duration_ms);
// Play haptic effect
void haptic_play(haptic_effect_t effect);
// Starts the haptic motor with a specified amplitude and period
//
// The function can be invoked repeatedly during the specified duration
// (`duration_ms`) to modify the amplitude dynamically, allowing
// the creation of customized haptic effects.
bool haptic_play_rtp(int8_t amplitude, uint16_t duration_ms);
#endif

View File

@ -94,6 +94,11 @@ void haptic_calibrate(void) {
HAL_Delay(3000);
}
// Set to `true` if real-time playing is activated. to
// This prevents the repeated set of `DRV2625_REG_MODE` register
// which would otherwise stop all playback.
static bool playing_rtp = false;
void haptic_init(void) {
// select library
set_reg(DRV2625_REG_LIBRARY, LIB_SEL | DRV2625_REG_LIBRARY_GAIN_25);
@ -124,26 +129,29 @@ void haptic_init(void) {
TIM_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
TIM_Handle.Init.RepetitionCounter = 0;
HAL_TIM_PWM_Init(&TIM_Handle);
HAL_TIM_OnePulse_Init(&TIM_Handle, TIM_OPMODE_SINGLE);
TIM_OC_InitTypeDef TIM_OC_InitStructure = {0};
TIM_OC_InitStructure.OCMode = TIM_OCMODE_PWM2;
TIM_OC_InitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
TIM_OC_InitStructure.Pulse = 1;
TIM_OC_InitStructure.OCNPolarity = TIM_OCNPOLARITY_HIGH;
TIM_OC_InitStructure.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&TIM_Handle, &TIM_OC_InitStructure, TIM_CHANNEL_1);
TIM_OnePulse_InitTypeDef TIM_OP_InitStructure = {0};
TIM_OP_InitStructure.OCMode = TIM_OCMODE_PWM2;
TIM_OP_InitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
TIM_OP_InitStructure.Pulse = 1;
TIM_OP_InitStructure.OCNPolarity = TIM_OCNPOLARITY_HIGH;
HAL_TIM_OnePulse_ConfigChannel(&TIM_Handle, &TIM_OP_InitStructure,
TIM_CHANNEL_1, TIM_CHANNEL_2);
HAL_TIM_OC_Start(&TIM_Handle, TIM_CHANNEL_1);
TIM16->CR1 |= TIM_CR1_OPM;
TIM16->BDTR |= TIM_BDTR_MOE;
}
static bool haptic_play_RTP(int8_t amplitude, uint16_t duration_ms) {
if (!set_reg(DRV2625_REG_MODE,
DRV2625_REG_MODE_RTP | DRV2625_REG_MODE_TRGFUNC_ENABLE)) {
return false;
bool haptic_play_rtp(int8_t amplitude, uint16_t duration_ms) {
if (!playing_rtp) {
if (!set_reg(DRV2625_REG_MODE,
DRV2625_REG_MODE_RTP | DRV2625_REG_MODE_TRGFUNC_ENABLE)) {
return false;
}
playing_rtp = true;
}
if (!set_reg(DRV2625_REG_RTP, (uint8_t)amplitude)) {
@ -166,6 +174,8 @@ static bool haptic_play_RTP(int8_t amplitude, uint16_t duration_ms) {
}
static void haptic_play_lib(drv2625_lib_effect_t effect) {
playing_rtp = false;
set_reg(DRV2625_REG_MODE, DRV2625_REG_MODE_WAVEFORM);
set_reg(DRV2625_REG_WAVESEQ1, effect);
set_reg(DRV2625_REG_WAVESEQ2, 0);
@ -175,13 +185,13 @@ static void haptic_play_lib(drv2625_lib_effect_t effect) {
void haptic_play(haptic_effect_t effect) {
switch (effect) {
case HAPTIC_BUTTON_PRESS:
haptic_play_RTP(PRESS_EFFECT_AMPLITUDE, PRESS_EFFECT_DURATION);
haptic_play_rtp(PRESS_EFFECT_AMPLITUDE, PRESS_EFFECT_DURATION);
break;
case HAPTIC_ALERT:
haptic_play_lib(ALERT_750MS_100);
break;
case HAPTIC_HOLD_TO_CONFIRM:
haptic_play_lib(TRANSITION_RAMP_UP_SHORT_SMOOTH_1);
haptic_play_lib(DOUBLE_CLICK_60);
break;
default:
break;
@ -189,5 +199,5 @@ void haptic_play(haptic_effect_t effect) {
}
bool haptic_test(uint16_t duration_ms) {
return haptic_play_RTP(PRODTEST_EFFECT_AMPLITUDE, duration_ms);
return haptic_play_rtp(PRODTEST_EFFECT_AMPLITUDE, duration_ms);
}