mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 22:38:08 +00:00
feat(core): implement RGB LED driver for T3W1
[no changelog]
This commit is contained in:
parent
16e0cf39f1
commit
d9d4fc0187
@ -24,10 +24,16 @@
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
// Initialize RGB LED driver
|
||||
void rgb_led_init(void);
|
||||
|
||||
// Deinitialize RGB LED driver
|
||||
void rgb_led_deinit(void);
|
||||
|
||||
#endif
|
||||
|
||||
// Set RGB LED color
|
||||
// color: 24-bit RGB color, 0x00RRGGBB
|
||||
void rgb_led_set_color(uint32_t color);
|
||||
|
||||
#endif // TREZORHAL_RGB_LED_H
|
||||
|
96
core/embed/io/rgb_led/stm32/rgb_led.c
Normal file
96
core/embed/io/rgb_led/stm32/rgb_led.c
Normal file
@ -0,0 +1,96 @@
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#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 (SystemCoreClock / LED_SWITCHING_FREQUENCY_HZ)
|
||||
|
||||
typedef struct {
|
||||
TIM_HandleTypeDef tim;
|
||||
bool initialized;
|
||||
} rgb_led_t;
|
||||
|
||||
static rgb_led_t g_rgb_led = {0};
|
||||
|
||||
void rgb_led_init(void) {
|
||||
rgb_led_t* drv = &g_rgb_led;
|
||||
if (drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(drv, 0, sizeof(*drv));
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
__HAL_RCC_TIM4_FORCE_RESET();
|
||||
__HAL_RCC_TIM4_RELEASE_RESET();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF2_TIM4;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
drv->tim.State = HAL_TIM_STATE_RESET;
|
||||
drv->tim.Instance = TIM4;
|
||||
drv->tim.Init.Period = TIMER_PERIOD;
|
||||
drv->tim.Init.Prescaler = 0;
|
||||
drv->tim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
drv->tim.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
drv->tim.Init.RepetitionCounter = 0;
|
||||
HAL_TIM_PWM_Init(&drv->tim);
|
||||
|
||||
// OC initialization
|
||||
TIM_OC_InitTypeDef OC_Init = {0};
|
||||
OC_Init.OCMode = TIM_OCMODE_PWM2;
|
||||
OC_Init.Pulse = 0;
|
||||
OC_Init.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
OC_Init.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
HAL_TIM_PWM_ConfigChannel(&drv->tim, &OC_Init, TIM_CHANNEL_1);
|
||||
HAL_TIM_PWM_ConfigChannel(&drv->tim, &OC_Init, TIM_CHANNEL_2);
|
||||
HAL_TIM_PWM_ConfigChannel(&drv->tim, &OC_Init, TIM_CHANNEL_3);
|
||||
|
||||
HAL_TIM_Base_Start(&drv->tim);
|
||||
|
||||
HAL_TIM_PWM_Start(&drv->tim, TIM_CHANNEL_1);
|
||||
HAL_TIM_PWM_Start(&drv->tim, TIM_CHANNEL_2);
|
||||
HAL_TIM_PWM_Start(&drv->tim, TIM_CHANNEL_3);
|
||||
|
||||
drv->initialized = true;
|
||||
}
|
||||
|
||||
void rgb_led_deinit(void) {
|
||||
rgb_led_t* drv = &g_rgb_led;
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_TIM_PWM_Stop(&drv->tim, TIM_CHANNEL_1);
|
||||
HAL_TIM_PWM_Stop(&drv->tim, TIM_CHANNEL_2);
|
||||
HAL_TIM_PWM_Stop(&drv->tim, TIM_CHANNEL_3);
|
||||
|
||||
HAL_TIM_Base_Stop(&drv->tim);
|
||||
|
||||
memset(drv, 0, sizeof(*drv));
|
||||
drv->initialized = false;
|
||||
}
|
||||
|
||||
void rgb_led_set_color(uint32_t color) {
|
||||
rgb_led_t* drv = &g_rgb_led;
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
TIM4->CCR1 = ((color >> 16) & 0xFF) * TIMER_PERIOD / 255;
|
||||
TIM4->CCR2 = ((color >> 8) & 0xFF) * TIMER_PERIOD / 255;
|
||||
TIM4->CCR3 = (color & 0xFF) * TIMER_PERIOD / 255;
|
||||
}
|
||||
|
||||
#endif
|
@ -83,7 +83,6 @@ def configure(
|
||||
|
||||
if "consumption_mask" in features_wanted:
|
||||
sources += ["embed/sec/consumption_mask/stm32u5/consumption_mask.c"]
|
||||
sources += ["vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_tim.c"]
|
||||
paths += ["embed/sec/consumption_mask/inc"]
|
||||
defines += ["USE_CONSUMPTION_MASK=1"]
|
||||
|
||||
|
@ -69,10 +69,6 @@ def configure(
|
||||
sources += [
|
||||
"embed/io/haptic/drv2625/drv2625.c",
|
||||
]
|
||||
sources += [
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_tim.c",
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_tim_ex.c",
|
||||
]
|
||||
paths += ["embed/io/haptic/inc"]
|
||||
features_available.append("haptic")
|
||||
defines += ["USE_HAPTIC=1"]
|
||||
|
@ -80,6 +80,12 @@ def configure(
|
||||
features_available.append("sbu")
|
||||
defines += ["USE_SBU=1"]
|
||||
|
||||
if "rgb_led" in features_wanted:
|
||||
sources += ["embed/io/rgb_led/stm32/rgb_led.c"]
|
||||
paths += ["embed/io/rgb_led/inc"]
|
||||
features_available.append("rgb_led")
|
||||
defines += ["USE_RGB_LED=1"]
|
||||
|
||||
if "usb" in features_wanted:
|
||||
sources += [
|
||||
"embed/io/usb/stm32/usb_class_hid.c",
|
||||
|
@ -68,6 +68,8 @@ def stm32u5_common_files(env, defines, sources, paths):
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_rtc.c",
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_spi.c",
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_sram.c",
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_tim.c",
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_hal_tim_ex.c",
|
||||
"vendor/stm32u5xx_hal_driver/Src/stm32u5xx_ll_fmc.c",
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user