Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for T3W1 rev B #4539

Merged
merged 3 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions core/embed/io/haptic/drv2625/actuators/ld0625bc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#define ACTUATOR_LRA
#define ACTUATOR_CLOSED_LOOP

#define ACTUATOR_FREQUENCY (260)
#define ACTUATOR_VOLTAGE (0.7)

#define ACTUATOR_LRA_PERIOD ((int)((1000000 / ACTUATOR_FREQUENCY) / 24.615))

// open-loop mode
// V = 21.32 * 10^(-3) * OD_CLAMP * sqrt(1 - fLRA * 800 * 10^(-6))
#define ACTUATOR_OD_CLAMP (37)

// closed-loop mode
// V = (20.58 * 10^(-3) * RATED_VOLTAGE) / sqrt (1 - (4 * tSAMPLE_TIME + 300 *
// 10^(-6)) * fLRA) where tSAMPLE_TIME = 300us, by default
#define ACTUATOR_RATED_VOLTAGE (27)
20 changes: 20 additions & 0 deletions core/embed/io/haptic/drv2625/actuators/vg1040003d.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#define ACTUATOR_LRA
#define ACTUATOR_OPEN_LOOP
Expand Down
7 changes: 7 additions & 0 deletions core/embed/io/haptic/drv2625/drv2625.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,17 @@ bool haptic_init(void) {
goto cleanup;
}

#ifdef ACTUATOR_OPEN_LOOP
if (!drv2625_set_reg(driver->i2c_bus, DRV2625_REG_OD_CLAMP,
ACTUATOR_OD_CLAMP)) {
goto cleanup;
}
#elif defined ACTUATOR_CLOSED_LOOP
if (!drv2625_set_reg(driver->i2c_bus, DRV2625_REG_RATED_VOLTAGE,
ACTUATOR_RATED_VOLTAGE)) {
goto cleanup;
}
#endif

if (!drv2625_set_reg(driver->i2c_bus, DRV2625_REG_LRA_WAVE_SHAPE,
DRV2625_REG_LRA_WAVE_SHAPE_SINE)) {
Expand Down
25 changes: 21 additions & 4 deletions core/embed/io/haptic/drv2625/drv2625.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
#ifndef TREZOR_HAL_DRV_2625_H
#define TREZOR_HAL_DRV_2625_H
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

// I2C address of the DRV2625 on the I2C bus.
#define DRV2625_I2C_ADDRESS 0x5A
Expand Down Expand Up @@ -47,6 +65,7 @@
#define DRV2625_REG_GO_GO 0x01

#define DRV2625_REG_OD_CLAMP 0x20
#define DRV2625_REG_RATED_VOLTAGE 0x20

#define DRV2625_REG_LRA_WAVE_SHAPE 0x2C
#define DRV2625_REG_LRA_WAVE_SHAPE_SINE 0x01
Expand Down Expand Up @@ -183,5 +202,3 @@ typedef enum {
SMOOTH_HUM_4_40 = 122,
SMOOTH_HUM_5_20 = 123,
} drv2625_lib_effect_t;

#endif // TREZOR_HAL_DRV_2625_H
7 changes: 2 additions & 5 deletions core/embed/io/haptic/inc/io/haptic.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TREZORHAL_HAPTIC_H
#define TREZORHAL_HAPTIC_H
#pragma once

#include <trezor_types.h>

typedef enum {
// Effect at the start of a button press
HAPTIC_BUTTON_PRESS = 0,
// Effect at the and of hold-to-confirm action
// Effect at the end of hold-to-confirm action
HAPTIC_HOLD_TO_CONFIRM = 1,
} haptic_effect_t;

Expand Down Expand Up @@ -86,5 +85,3 @@ bool haptic_play(haptic_effect_t effect);
//
// Returns `true` if the effect was successfully started.
bool haptic_play_custom(int8_t amplitude_pct, uint16_t duration_ms);

#endif // TREZORHAL_HAPTIC_H
231 changes: 231 additions & 0 deletions core/embed/io/rgb_led/stm32u5/rgb_led_lp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifdef KERNEL_MODE
cepetr marked this conversation as resolved.
Show resolved Hide resolved

#include <trezor_bsp.h>
#include <trezor_model.h>
#include <trezor_rtl.h>

#include <io/rgb_led.h>

#define LED_SWITCHING_FREQUENCY_HZ 20000
#define TIMER_PERIOD (16000000 / LED_SWITCHING_FREQUENCY_HZ)

#define RGB_LED_RED_PIN GPIO_PIN_2
#define RGB_LED_RED_PORT GPIOB
#define RGB_LED_RED_CLK_ENA __HAL_RCC_GPIOB_CLK_ENABLE

#define RGB_LED_GREEN_PIN GPIO_PIN_2
#define RGB_LED_GREEN_PORT GPIOF
#define RGB_LED_GREEN_CLK_ENA __HAL_RCC_GPIOF_CLK_ENABLE

#define RGB_LED_BLUE_PIN GPIO_PIN_0
#define RGB_LED_BLUE_PORT GPIOB
#define RGB_LED_BLUE_CLK_ENA __HAL_RCC_GPIOB_CLK_ENABLE

typedef struct {
LPTIM_HandleTypeDef tim_1;
LPTIM_HandleTypeDef tim_3;
bool initialized;
} rgb_led_t;

static rgb_led_t g_rgb_led = {0};

static void rgb_led_set_default_pin_state(void) {
GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStructure.Pin = RGB_LED_RED_PIN;
HAL_GPIO_Init(RGB_LED_RED_PORT, &GPIO_InitStructure);

GPIO_InitStructure.Pin = RGB_LED_GREEN_PIN;
HAL_GPIO_Init(RGB_LED_GREEN_PORT, &GPIO_InitStructure);

GPIO_InitStructure.Pin = RGB_LED_BLUE_PIN;
HAL_GPIO_Init(RGB_LED_BLUE_PORT, &GPIO_InitStructure);
}

void rgb_led_init(void) {
rgb_led_t* drv = &g_rgb_led;
if (drv->initialized) {
return;
}

memset(drv, 0, sizeof(*drv));

rgb_led_set_default_pin_state();

// enable LSE clock
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

// select LSE as LPTIM clock source
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection =
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM34;
PeriphClkInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_HSI;
PeriphClkInitStruct.Lptim34ClockSelection = RCC_LPTIM34CLKSOURCE_HSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);

__HAL_RCC_LPTIM1_CLK_ENABLE();
__HAL_RCC_LPTIM1_FORCE_RESET();
__HAL_RCC_LPTIM1_RELEASE_RESET();

__HAL_RCC_LPTIM3_CLK_ENABLE();
__HAL_RCC_LPTIM3_FORCE_RESET();
__HAL_RCC_LPTIM3_RELEASE_RESET();

drv->tim_1.State = HAL_LPTIM_STATE_RESET;
drv->tim_1.Instance = LPTIM1;
drv->tim_1.Init.Period = TIMER_PERIOD;
drv->tim_1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
drv->tim_1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
drv->tim_1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
drv->tim_1.Init.UltraLowPowerClock.SampleTime =
LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
drv->tim_1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
HAL_LPTIM_Init(&drv->tim_1);

drv->tim_3.State = HAL_LPTIM_STATE_RESET;
drv->tim_3.Instance = LPTIM3;
drv->tim_3.Init.Period = TIMER_PERIOD;
drv->tim_3.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
drv->tim_3.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
drv->tim_3.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
drv->tim_3.Init.UltraLowPowerClock.SampleTime =
LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
drv->tim_3.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
HAL_LPTIM_Init(&drv->tim_3);

// OC initialization
LPTIM_OC_ConfigTypeDef OC_Init = {0};
OC_Init.Pulse = 0;
OC_Init.OCPolarity = LPTIM_OCPOLARITY_LOW;

HAL_LPTIM_OC_ConfigChannel(&drv->tim_1, &OC_Init, LPTIM_CHANNEL_1);
HAL_LPTIM_OC_ConfigChannel(&drv->tim_3, &OC_Init, LPTIM_CHANNEL_1);
HAL_LPTIM_OC_ConfigChannel(&drv->tim_3, &OC_Init, LPTIM_CHANNEL_2);

HAL_LPTIM_Counter_Start(&drv->tim_1);
HAL_LPTIM_Counter_Start(&drv->tim_3);

__HAL_LPTIM_COMPARE_SET(&drv->tim_1, LPTIM_CHANNEL_1, TIMER_PERIOD);
__HAL_LPTIM_COMPARE_SET(&drv->tim_3, LPTIM_CHANNEL_1, TIMER_PERIOD);
__HAL_LPTIM_COMPARE_SET(&drv->tim_3, LPTIM_CHANNEL_2, TIMER_PERIOD);

// Enable the Peripheral
__HAL_LPTIM_ENABLE(&drv->tim_1);
__HAL_LPTIM_ENABLE(&drv->tim_3);

// Start timer in continuous mode
__HAL_LPTIM_START_CONTINUOUS(&drv->tim_1);
__HAL_LPTIM_START_CONTINUOUS(&drv->tim_3);

// Wait for reload before configuring the pins
__HAL_LPTIM_CLEAR_FLAG(&drv->tim_1, LPTIM_FLAG_UPDATE);
__HAL_LPTIM_CLEAR_FLAG(&drv->tim_3, LPTIM_FLAG_UPDATE);
while (__HAL_LPTIM_GET_FLAG(&drv->tim_1, LPTIM_FLAG_UPDATE) != true) {
}
while (__HAL_LPTIM_GET_FLAG(&drv->tim_3, LPTIM_FLAG_UPDATE) != true) {
}

GPIO_InitTypeDef GPIO_InitStructure = {0};
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;

RGB_LED_RED_CLK_ENA();
GPIO_InitStructure.Pin = RGB_LED_RED_PIN;
GPIO_InitStructure.Alternate = GPIO_AF1_LPTIM1;
HAL_GPIO_Init(RGB_LED_RED_PORT, &GPIO_InitStructure);

RGB_LED_GREEN_CLK_ENA();
GPIO_InitStructure.Pin = RGB_LED_GREEN_PIN;
GPIO_InitStructure.Alternate = GPIO_AF2_LPTIM3;
HAL_GPIO_Init(RGB_LED_GREEN_PORT, &GPIO_InitStructure);

RGB_LED_BLUE_CLK_ENA();
GPIO_InitStructure.Pin = RGB_LED_BLUE_PIN;
GPIO_InitStructure.Alternate = GPIO_AF4_LPTIM3;
HAL_GPIO_Init(RGB_LED_BLUE_PORT, &GPIO_InitStructure);

drv->initialized = true;
}

void rgb_led_deinit(void) {
rgb_led_t* drv = &g_rgb_led;
if (!drv->initialized) {
return;
}

rgb_led_set_default_pin_state();

HAL_LPTIM_PWM_Stop(&drv->tim_1, LPTIM_CHANNEL_1);
HAL_LPTIM_PWM_Stop(&drv->tim_3, LPTIM_CHANNEL_1);
HAL_LPTIM_PWM_Stop(&drv->tim_3, LPTIM_CHANNEL_2);

HAL_LPTIM_Counter_Stop(&drv->tim_1);
HAL_LPTIM_Counter_Stop(&drv->tim_3);

memset(drv, 0, sizeof(*drv));
}

void rgb_led_set_color(uint32_t color) {
rgb_led_t* drv = &g_rgb_led;
if (!drv->initialized) {
return;
}

uint32_t red = (color >> 16) & 0xFF;
uint32_t green = (color >> 8) & 0xFF;
uint32_t blue = color & 0xFF;

if (red != 0) {
__HAL_LPTIM_CAPTURE_COMPARE_ENABLE(&drv->tim_1, LPTIM_CHANNEL_1);
} else {
__HAL_LPTIM_CAPTURE_COMPARE_DISABLE(&drv->tim_1, LPTIM_CHANNEL_1);
}

if (green != 0) {
__HAL_LPTIM_CAPTURE_COMPARE_ENABLE(&drv->tim_3, LPTIM_CHANNEL_2);
} else {
__HAL_LPTIM_CAPTURE_COMPARE_DISABLE(&drv->tim_3, LPTIM_CHANNEL_2);
}

if (blue != 0) {
__HAL_LPTIM_CAPTURE_COMPARE_ENABLE(&drv->tim_3, LPTIM_CHANNEL_1);
} else {
__HAL_LPTIM_CAPTURE_COMPARE_DISABLE(&drv->tim_3, LPTIM_CHANNEL_1);
}

__HAL_LPTIM_COMPARE_SET(&drv->tim_1, LPTIM_CHANNEL_1,
TIMER_PERIOD - (red * (TIMER_PERIOD) / 255));
__HAL_LPTIM_COMPARE_SET(&drv->tim_3, LPTIM_CHANNEL_2,
TIMER_PERIOD - (green * (TIMER_PERIOD) / 255));
__HAL_LPTIM_COMPARE_SET(&drv->tim_3, LPTIM_CHANNEL_1,
TIMER_PERIOD - (blue * (TIMER_PERIOD) / 255));
}

#endif
2 changes: 1 addition & 1 deletion core/embed/models/T3W1/boards/trezor_t3w1_revA.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
#define TOUCH_INT_PIN GPIO_PIN_3

#define DRV2625_I2C_INSTANCE 2
#define HAPTIC_ACTUATOR "actuators/vg1040003d.h"
#define HAPTIC_ACTUATOR "actuators/ld0625bc.h"
#define DRV2625_TRIG_PIN GPIO_PIN_2
#define DRV2625_TRIG_PORT GPIOA
#define DRV2625_TRIG_CLK_ENA __HAL_RCC_GPIOA_CLK_ENABLE
Expand Down
2 changes: 1 addition & 1 deletion core/embed/models/T3W1/boards/trezor_t3w1_revA0.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
#define TOUCH_INT_PIN GPIO_PIN_3

#define DRV2625_I2C_INSTANCE 2
#define HAPTIC_ACTUATOR "actuators/vg1040003d.h"
#define HAPTIC_ACTUATOR "actuators/ld0625bc.h"
#define DRV2625_TRIG_PIN GPIO_PIN_2
#define DRV2625_TRIG_PORT GPIOA
#define DRV2625_TRIG_CLK_ENA __HAL_RCC_GPIOA_CLK_ENABLE
Expand Down
Loading
Loading