From 72dc8f57e8264bb6caadea23ea73c7070086bc96 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Thu, 24 Aug 2023 11:30:29 +0200 Subject: [PATCH] feat(core): add haptic feedback [no changelog] --- core/SConscript.firmware | 2 +- core/SConscript.prodtest | 2 +- core/embed/firmware/main.c | 7 + core/embed/rust/Cargo.toml | 1 + core/embed/rust/build.rs | 5 +- core/embed/rust/src/trezorhal/haptic.rs | 13 ++ core/embed/rust/src/trezorhal/mod.rs | 2 + .../rust/src/ui/model_tt/component/button.rs | 6 + .../rust/src/ui/model_tt/component/loader.rs | 4 + core/embed/rust/trezorhal.h | 1 + core/embed/trezorhal/boards/trezor_t3t1_v4.h | 3 + core/embed/trezorhal/haptic.h | 20 ++ .../haptic/drv2625/actuators/vg1040003d.h | 6 + .../stm32u5/haptic/drv2625/drv2625.c | 175 ++++++++++++++++++ .../stm32u5/haptic/drv2625/drv2625_lib.h | 130 +++++++++++++ 15 files changed, 374 insertions(+), 3 deletions(-) create mode 100644 core/embed/rust/src/trezorhal/haptic.rs create mode 100644 core/embed/trezorhal/haptic.h create mode 100644 core/embed/trezorhal/stm32u5/haptic/drv2625/actuators/vg1040003d.h create mode 100644 core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c create mode 100644 core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625_lib.h diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 6c66125747..8b3f34f0cd 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -21,7 +21,7 @@ FEATURE_FLAGS = { "SYSTEM_VIEW": False, } -FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga"] +FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic"] if DISABLE_OPTIGA and PYOPT == '0': FEATURES_WANTED.remove("optiga") diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest index 11ec63e5bd..2401f7afe6 100644 --- a/core/SConscript.prodtest +++ b/core/SConscript.prodtest @@ -19,7 +19,7 @@ if TREZOR_MODEL in ('DISC1', 'DISC2'): action=build_prodtest) Return() -FEATURES_WANTED = ["input", "sbu", "sd_card", "rdb_led", "usb", "consumption_mask", "optiga"] +FEATURES_WANTED = ["input", "sbu", "sd_card", "rdb_led", "usb", "consumption_mask", "optiga", "haptic"] CCFLAGS_MOD = '' CPPPATH_MOD = [] diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 71cafccec5..878049408d 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -93,6 +93,9 @@ #ifdef USE_SECP256K1_ZKP #include "zkp_context.h" #endif +#ifdef USE_HAPTIC +#include "haptic.h" +#endif // from util.s extern void shutdown_privileged(void); @@ -183,6 +186,10 @@ int main(void) { sdcard_init(); #endif +#ifdef USE_HAPTIC + haptic_init(); +#endif + #ifdef USE_OPTIGA optiga_init(); optiga_open_application(); diff --git a/core/embed/rust/Cargo.toml b/core/embed/rust/Cargo.toml index bd9ead0b1e..93b23a5c8a 100644 --- a/core/embed/rust/Cargo.toml +++ b/core/embed/rust/Cargo.toml @@ -28,6 +28,7 @@ disp_i8080_8bit_dw = [] # write pixels directly to peripheral disp_i8080_16bit_dw = [] # write pixels directly to peripheral debug = ["ui_debug"] sbu = [] +haptic = [] sd_card = [] rgb_led = [] backlight = [] diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs index 18dd0670b3..4bf8f574bc 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -404,7 +404,10 @@ fn generate_trezorhal_bindings() { // touch .allowlist_function("touch_read") // button - .allowlist_function("button_read"); + .allowlist_function("button_read") + // haptic + .allowlist_type("haptic_effect_t") + .allowlist_function("haptic_play"); // Write the bindings to a file in the OUR_DIR. bindings diff --git a/core/embed/rust/src/trezorhal/haptic.rs b/core/embed/rust/src/trezorhal/haptic.rs new file mode 100644 index 0000000000..d76474c2b3 --- /dev/null +++ b/core/embed/rust/src/trezorhal/haptic.rs @@ -0,0 +1,13 @@ +use super::ffi; + +#[derive(PartialEq, Debug, Eq, FromPrimitive, Clone, Copy)] +pub enum HapticEffect { + ButtonPress = ffi::haptic_effect_t_HAPTIC_BUTTON_PRESS as _, + HoldToConfirm = ffi::haptic_effect_t_HAPTIC_HOLD_TO_CONFIRM as _, +} + +pub fn play(effect: HapticEffect) { + unsafe { + ffi::haptic_play(effect as _); + } +} diff --git a/core/embed/rust/src/trezorhal/mod.rs b/core/embed/rust/src/trezorhal/mod.rs index 1aea7bb35a..39de951510 100644 --- a/core/embed/rust/src/trezorhal/mod.rs +++ b/core/embed/rust/src/trezorhal/mod.rs @@ -7,6 +7,8 @@ pub mod display; #[cfg(feature = "dma2d")] pub mod dma2d; mod ffi; +#[cfg(feature = "haptic")] +pub mod haptic; pub mod io; pub mod model; pub mod random; diff --git a/core/embed/rust/src/ui/model_tt/component/button.rs b/core/embed/rust/src/ui/model_tt/component/button.rs index 4a319070ea..d9e2a558c2 100644 --- a/core/embed/rust/src/ui/model_tt/component/button.rs +++ b/core/embed/rust/src/ui/model_tt/component/button.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "haptic")] +use crate::trezorhal::haptic::{play, HapticEffect}; use crate::{ time::Duration, ui::{ @@ -256,6 +258,8 @@ where _ => { // Touch started in our area, transform to `Pressed` state. if touch_area.contains(pos) { + #[cfg(feature = "haptic")] + play(HapticEffect::ButtonPress); self.set(ctx, State::Pressed); if let Some(duration) = self.long_press { self.long_timer = Some(ctx.request_timer(duration)); @@ -298,6 +302,8 @@ where if self.long_timer == Some(token) { self.long_timer = None; if matches!(self.state, State::Pressed) { + #[cfg(feature = "haptic")] + play(HapticEffect::ButtonPress); self.set(ctx, State::Initial); return Some(ButtonMsg::LongPressed); } diff --git a/core/embed/rust/src/ui/model_tt/component/loader.rs b/core/embed/rust/src/ui/model_tt/component/loader.rs index d661653b71..ebac3b3aac 100644 --- a/core/embed/rust/src/ui/model_tt/component/loader.rs +++ b/core/embed/rust/src/ui/model_tt/component/loader.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "haptic")] +use crate::trezorhal::haptic::{play, HapticEffect}; use crate::{ time::{Duration, Instant}, ui::{ @@ -165,6 +167,8 @@ impl Component for Loader { } if self.is_completely_grown(now) { + #[cfg(feature = "haptic")] + play(HapticEffect::HoldToConfirm); return Some(LoaderMsg::GrownCompletely); } else if self.is_completely_shrunk(now) { return Some(LoaderMsg::ShrunkCompletely); diff --git a/core/embed/rust/trezorhal.h b/core/embed/rust/trezorhal.h index fd64ba5b84..1ee7ac69a7 100644 --- a/core/embed/rust/trezorhal.h +++ b/core/embed/rust/trezorhal.h @@ -7,6 +7,7 @@ #include "dma2d.h" #include "flash.h" #include "fonts/fonts.h" +#include "haptic.h" #include "model.h" #include "rgb_led.h" #include "secbool.h" diff --git a/core/embed/trezorhal/boards/trezor_t3t1_v4.h b/core/embed/trezorhal/boards/trezor_t3t1_v4.h index 8cd2604d1b..4fbf5868f9 100644 --- a/core/embed/trezorhal/boards/trezor_t3t1_v4.h +++ b/core/embed/trezorhal/boards/trezor_t3t1_v4.h @@ -73,6 +73,9 @@ #define TOUCH_ON_PORT GPIOB #define TOUCH_ON_PIN GPIO_PIN_0 +#define DRV2625_I2C_INSTANCE 1 +#define HAPTIC_ACTUATOR "actuators/vg1040003d.h" + #define OPTIGA_I2C_INSTANCE 1 #define SD_DETECT_PORT GPIOC diff --git a/core/embed/trezorhal/haptic.h b/core/embed/trezorhal/haptic.h new file mode 100644 index 0000000000..4bd51f7262 --- /dev/null +++ b/core/embed/trezorhal/haptic.h @@ -0,0 +1,20 @@ + +#ifndef TREZORHAL_HAPTIC_H +#define TREZORHAL_HAPTIC_H + +typedef enum { + HAPTIC_BUTTON_PRESS = 0, + HAPTIC_ALERT = 1, + HAPTIC_HOLD_TO_CONFIRM = 2, +} haptic_effect_t; + +// Initialize haptic driver +void haptic_init(void); + +// Calibrate haptic driver +void haptic_calibrate(void); + +// Play haptic effect +void haptic_play(haptic_effect_t effect); + +#endif diff --git a/core/embed/trezorhal/stm32u5/haptic/drv2625/actuators/vg1040003d.h b/core/embed/trezorhal/stm32u5/haptic/drv2625/actuators/vg1040003d.h new file mode 100644 index 0000000000..e18e836aa1 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/haptic/drv2625/actuators/vg1040003d.h @@ -0,0 +1,6 @@ + +#define ACTUATOR_LRA +#define ACTUATOR_OPEN_LOOP + +#define ACTUATOR_LRA_PERIOD (239) +#define ACTUATOR_OD_CLAMP (126) diff --git a/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c b/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c new file mode 100644 index 0000000000..00e48a7453 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625.c @@ -0,0 +1,175 @@ +#include "drv2625_lib.h" +#include "haptic.h" + +#include STM32_HAL_H + +#include "i2c.h" +#include TREZOR_BOARD +#include HAPTIC_ACTUATOR + +#define DRV2625_I2C_ADDRESS (0x5A << 1) + +#define DRV2625_REG_CHIPID 0x00 +#define DRV2625_REG_STATUS 0x01 +#define DRV2625_REG_MODE 0x07 +#define DRV2625_REG_MODE_RTP 0 +#define DRV2625_REG_MODE_WAVEFORM 0x01 +#define DRV2625_REG_MODE_DIAG 0x02 +#define DRV2625_REG_MODE_AUTOCAL 0x03 +#define DRV2625_REG_MODE_TRGFUNC_PULSE 0x00 +#define DRV2625_REG_MODE_TRGFUNC_ENABLE 0x04 +#define DRV2625_REG_MODE_TRGFUNC_INTERRUPT 0x08 + +#define DRV2625_REG_LRAERM 0x08 +#define DRV2625_REG_LRAERM_LRA 0x80 +#define DRV2625_REG_LRAERM_OPENLOOP 0x40 +#define DRV2625_REG_LRAERM_AUTO_BRK_OL 0x10 +#define DRV2625_REG_LRAERM_AUTO_BRK_STBY 0x08 + +#define DRV2625_REG_LIBRARY 0x0D ///< Waveform library selection register +#define DRV2625_REG_LIBRARY_OPENLOOP 0x40 +#define DRV2625_REG_LIBRARY_GAIN_100 0x00 +#define DRV2625_REG_LIBRARY_GAIN_75 0x01 +#define DRV2625_REG_LIBRARY_GAIN_50 0x02 +#define DRV2625_REG_LIBRARY_GAIN_25 0x03 + +#define DRV2625_REG_RTP 0x0E ///< RTP input register + +#define DRV2625_REG_WAVESEQ1 0x0F ///< Waveform sequence register 1 +#define DRV2625_REG_WAVESEQ2 0x10 ///< Waveform sequence register 2 +#define DRV2625_REG_WAVESEQ3 0x11 ///< Waveform sequence register 3 +#define DRV2625_REG_WAVESEQ4 0x12 ///< Waveform sequence register 4 +#define DRV2625_REG_WAVESEQ5 0x13 ///< Waveform sequence register 5 +#define DRV2625_REG_WAVESEQ6 0x14 ///< Waveform sequence register 6 +#define DRV2625_REG_WAVESEQ7 0x15 ///< Waveform sequence register 7 +#define DRV2625_REG_WAVESEQ8 0x16 ///< Waveform sequence register 8 + +#define DRV2625_REG_GO 0x0C ///< Go register +#define DRV2625_REG_GO_GO 0x01 + +#define DRV2625_REG_OD_CLAMP 0x20 + +#define DRV2625_REG_LRA_WAVE_SHAPE 0x2C +#define DRV2625_REG_LRA_WAVE_SHAPE_SINE 0x01 + +#define DRV2625_REG_OL_LRA_PERIOD_LO 0x2F +#define DRV2625_REG_OL_LRA_PERIOD_HI 0x2E + +#if defined ACTUATOR_CLOSED_LOOP +#define LIB_SEL 0x00 +#define LOOP_SEL 0x00 +#elif defined ACTUATOR_OPEN_LOOP +#define LIB_SEL DRV2625_REG_LIBRARY_OPENLOOP +#define LOOP_SEL DRV2625_REG_LRAERM_OPENLOOP +#else +#error "Must define either CLOSED_LOOP or OPEN_LOOP" +#endif + +#if defined ACTUATOR_LRA +#define LRA_ERM_SEL DRV2625_REG_LRAERM_LRA +#elif defined ACTUATOR_ERM +#define LRA_ERM_SEL 0x00 +#else +#error "Must define either LRA or ERM" +#endif + +#define PRESS_EFFECT_AMPLITUDE 25 +#define PRESS_EFFECT_DURATION 10 + +static void set_reg(uint8_t addr, uint8_t value) { + uint8_t data[] = {addr, value}; + i2c_transmit(DRV2625_I2C_INSTANCE, DRV2625_I2C_ADDRESS, data, sizeof(data), + 1); +} + +void haptic_calibrate(void) { + set_reg(DRV2625_REG_MODE, DRV2625_REG_MODE_AUTOCAL); + HAL_Delay(1); + set_reg(DRV2625_REG_GO, DRV2625_REG_GO_GO); + + HAL_Delay(3000); +} + +void haptic_init(void) { + // select library + set_reg(DRV2625_REG_LIBRARY, LIB_SEL | DRV2625_REG_LIBRARY_GAIN_25); + set_reg(DRV2625_REG_LRAERM, + LRA_ERM_SEL | LOOP_SEL | DRV2625_REG_LRAERM_AUTO_BRK_OL); + + set_reg(DRV2625_REG_OD_CLAMP, ACTUATOR_OD_CLAMP); + + set_reg(DRV2625_REG_LRA_WAVE_SHAPE, DRV2625_REG_LRA_WAVE_SHAPE_SINE); + + set_reg(DRV2625_REG_OL_LRA_PERIOD_LO, ACTUATOR_LRA_PERIOD & 0xFF); + set_reg(DRV2625_REG_OL_LRA_PERIOD_HI, ACTUATOR_LRA_PERIOD >> 8); + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_PULLDOWN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Pin = GPIO_PIN_8; + GPIO_InitStructure.Alternate = GPIO_AF14_TIM16; + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + + TIM_HandleTypeDef TIM_Handle; + __HAL_RCC_TIM16_CLK_ENABLE(); + TIM_Handle.State = HAL_TIM_STATE_RESET; + TIM_Handle.Instance = TIM16; + TIM_Handle.Init.Period = 0; + TIM_Handle.Init.Prescaler = SystemCoreClock / 10000; + 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); + + TIM_OC_InitTypeDef TIM_OC_InitStructure; + 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); + + HAL_TIM_OC_Start(&TIM_Handle, TIM_CHANNEL_1); + + TIM16->CR1 |= TIM_CR1_OPM; + TIM16->BDTR |= TIM_BDTR_MOE; +} + +static void haptic_play_RTP(int8_t amplitude, uint16_t duration_ms) { + set_reg(DRV2625_REG_MODE, + DRV2625_REG_MODE_RTP | DRV2625_REG_MODE_TRGFUNC_ENABLE); + set_reg(DRV2625_REG_RTP, (uint8_t)amplitude); + + if (duration_ms > 6500) { + duration_ms = 6500; + } + + TIM16->CNT = 1; + TIM16->CCR1 = 1; + TIM16->ARR = duration_ms * 10; + TIM16->CR1 |= TIM_CR1_CEN; +} + +static void haptic_play_lib(drv2625_lib_effect_t effect) { + set_reg(DRV2625_REG_MODE, DRV2625_REG_MODE_WAVEFORM); + set_reg(DRV2625_REG_WAVESEQ1, effect); + set_reg(DRV2625_REG_WAVESEQ2, 0); + set_reg(DRV2625_REG_GO, DRV2625_REG_GO_GO); +} + +void haptic_play(haptic_effect_t effect) { + switch (effect) { + case HAPTIC_BUTTON_PRESS: + 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); + break; + default: + break; + } +} diff --git a/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625_lib.h b/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625_lib.h new file mode 100644 index 0000000000..dcf449f443 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/haptic/drv2625/drv2625_lib.h @@ -0,0 +1,130 @@ +#ifndef __DRV_2625_LIB_H__ +#define __DRV_2625_LIB_H__ + +typedef enum { + STRONG_CLICK_100 = 1, + STRONG_CLICK_60 = 2, + STRONG_CLICK_30 = 3, + SHARP_CLICK_100 = 4, + SHARP_CLICK_60 = 5, + SHARP_CLICK_30 = 6, + SOFT_BUMP_100 = 7, + SOFT_BUMP_60 = 8, + SOFT_BUMP_30 = 9, + DOUBLE_CLICK_100 = 10, + DOUBLE_CLICK_60 = 11, + TRIPLE_CLICK_100 = 12, + SOFT_FUZZ_60 = 13, + STRONG_BUZZ_100 = 14, + ALERT_750MS_100 = 15, + ALERT_1000MS_100 = 16, + STRONG_CLICK_1_100 = 17, + STRONG_CLICK_2_80 = 18, + STRONG_CLICK_3_60 = 19, + STRONG_CLICK_4_30 = 20, + MEDIUM_CLICK_1_100 = 21, + MEDIUM_CLICK_2_80 = 22, + MEDIUM_CLICK_3_60 = 23, + SHARP_TICK_1_100 = 24, + SHARP_TICK_2_80 = 25, + SHARP_TICK_3_60 = 26, + SHORT_DOUBLE_CLICK_STRONG_1_100 = 27, + SHORT_DOUBLE_CLICK_STRONG_2_80 = 28, + SHORT_DOUBLE_CLICK_STRONG_3_60 = 29, + SHORT_DOUBLE_CLICK_STRONG_4_30 = 30, + SHORT_DOUBLE_CLICK_MEDIUM_1_100 = 31, + SHORT_DOUBLE_CLICK_MEDIUM_2_80 = 32, + SHORT_DOUBLE_CLICK_MEDIUM_3_60 = 33, + SHORT_DOUBLE_SHARP_TICK_1_100 = 34, + SHORT_DOUBLE_SHARP_TICK_2_80 = 35, + SHORT_DOUBLE_SHARP_TICK_3_60 = 36, + LONG_DOUBLE_SHARP_TICK_STRONG_1_100 = 37, + LONG_DOUBLE_SHARP_TICK_STRONG_2_80 = 38, + LONG_DOUBLE_SHARP_TICK_STRONG_3_60 = 39, + LONG_DOUBLE_SHARP_TICK_STRONG_4_30 = 40, + LONG_DOUBLE_SHARP_TICK_MEDIUM_1_100 = 41, + LONG_DOUBLE_SHARP_TICK_MEDIUM_2_80 = 42, + LONG_DOUBLE_SHARP_TICK_MEDIUM_3_60 = 43, + LONG_DOUBLE_SHARP_TICK_1_100 = 44, + LONG_DOUBLE_SHARP_TICK_2_80 = 45, + LONG_DOUBLE_SHARP_TICK_3_60 = 46, + BUZZ_1_100 = 47, + BUZZ_2_80 = 48, + BUZZ_3_60 = 49, + BUZZ_4_40 = 50, + BUZZ_5_20 = 51, + PULSING_STRONG_1_100 = 52, + PULSING_STRONG_2_60 = 53, + PULSING_MEDIUM_1_100 = 54, + PULSING_MEDIUM_2_60 = 55, + PULSING_SHARP_1_100 = 56, + PULSING_SHARP_2_60 = 57, + TRANSITION_CLICK_1_100 = 58, + TRANSITION_CLICK_2_80 = 59, + TRANSITION_CLICK_3_60 = 60, + TRANSITION_CLICK_4_40 = 61, + TRANSITION_CLICK_5_20 = 62, + TRANSITION_CLICK_6_10 = 63, + TRANSITION_HUM_1_100 = 64, + TRANSITION_HUM_2_80 = 65, + TRANSITION_HUM_3_60 = 66, + TRANSITION_HUM_4_40 = 67, + TRANSITION_HUM_5_20 = 68, + TRANSITION_HUM_6_10 = 69, + TRANSITION_RAMP_DOWN_LONG_SMOOTH_1 = 70, + TRANSITION_RAMP_DOWN_LONG_SMOOTH_2 = 71, + TRANSITION_RAMP_DOWN_MEDIUM_SMOOTH_1 = 72, + TRANSITION_RAMP_DOWN_MEDIUM_SMOOTH_2 = 73, + TRANSITION_RAMP_DOWN_SHORT_SMOOTH_1 = 74, + TRANSITION_RAMP_DOWN_SHORT_SMOOTH_2 = 75, + TRANSITION_RAMP_DOWN_LONG_SHARP_1 = 76, + TRANSITION_RAMP_DOWN_LONG_SHARP_2 = 77, + TRANSITION_RAMP_DOWN_MEDIUM_SHARP_1 = 78, + TRANSITION_RAMP_DOWN_MEDIUM_SHARP_2 = 79, + TRANSITION_RAMP_DOWN_SHORT_SHARP_1 = 80, + TRANSITION_RAMP_DOWN_SHORT_SHARP_2 = 81, + TRANSITION_RAMP_UP_LONG_SMOOTH_1 = 82, + TRANSITION_RAMP_UP_LONG_SMOOTH_2 = 83, + TRANSITION_RAMP_UP_MEDIUM_SMOOTH_1 = 84, + TRANSITION_RAMP_UP_MEDIUM_SMOOTH_2 = 85, + TRANSITION_RAMP_UP_SHORT_SMOOTH_1 = 86, + TRANSITION_RAMP_UP_SHORT_SMOOTH_2 = 87, + TRANSITION_RAMP_UP_LONG_SHARP_1 = 88, + TRANSITION_RAMP_UP_LONG_SHARP_2 = 89, + TRANSITION_RAMP_UP_MEDIUM_SHARP_1 = 90, + TRANSITION_RAMP_UP_MEDIUM_SHARP_2 = 91, + TRANSITION_RAMP_UP_SHORT_SHARP_1 = 92, + TRANSITION_RAMP_UP_SHORT_SHARP_2 = 93, + TRANSITION_RAMP_DOWN_LONG_SMOOTH_1_50 = 94, + TRANSITION_RAMP_DOWN_LONG_SMOOTH_2_50 = 95, + TRANSITION_RAMP_DOWN_MEDIUM_SMOOTH_1_50 = 96, + TRANSITION_RAMP_DOWN_MEDIUM_SMOOTH_2_50 = 97, + TRANSITION_RAMP_DOWN_SHORT_SMOOTH_1_50 = 98, + TRANSITION_RAMP_DOWN_SHORT_SMOOTH_2_50 = 99, + TRANSITION_RAMP_DOWN_LONG_SHARP_1_50 = 100, + TRANSITION_RAMP_DOWN_LONG_SHARP_2_50 = 101, + TRANSITION_RAMP_DOWN_MEDIUM_SHARP_1_50 = 102, + TRANSITION_RAMP_DOWN_MEDIUM_SHARP_2_50 = 103, + TRANSITION_RAMP_DOWN_SHORT_SHARP_1_50 = 104, + TRANSITION_RAMP_DOWN_SHORT_SHARP_2_50 = 105, + TRANSITION_RAMP_UP_LONG_SMOOTH_1_50 = 106, + TRANSITION_RAMP_UP_LONG_SMOOTH_2_50 = 107, + TRANSITION_RAMP_UP_MEDIUM_SMOOTH_1_50 = 108, + TRANSITION_RAMP_UP_MEDIUM_SMOOTH_2_50 = 109, + TRANSITION_RAMP_UP_SHORT_SMOOTH_1_50 = 110, + TRANSITION_RAMP_UP_SHORT_SMOOTH_2_50 = 111, + TRANSITION_RAMP_UP_LONG_SHARP_1_50 = 112, + TRANSITION_RAMP_UP_LONG_SHARP_2_50 = 113, + TRANSITION_RAMP_UP_MEDIUM_SHARP_1_50 = 114, + TRANSITION_RAMP_UP_MEDIUM_SHARP_2_50 = 115, + TRANSITION_RAMP_UP_SHORT_SHARP_1_50 = 116, + TRANSITION_RAMP_UP_SHORT_SHARP_2_50 = 117, + LONG_BUZZ_FROM_PROGRAMMATIC_STOPPING = 118, + SMOOTH_HUM_1_100 = 119, + SMOOTH_HUM_2_80 = 120, + SMOOTH_HUM_3_60 = 121, + SMOOTH_HUM_4_40 = 122, + SMOOTH_HUM_5_20 = 123, +} drv2625_lib_effect_t; + +#endif