chore(core): clean rgb led driver comments.
What changed, and why it matters
This commit only tidies up comments and documentation for the RGB LED driver in Trezor hardware firmware. It also makes two tiny, safe-looking code-order tweaks: moving a timer unset call earlier and reordering flag/timer operations when stopping an LED effect. There is no security-relevant change and no bug fix.
No action required; this is a non-security documentation and minor cleanup commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff is a comment-only/cosmetic refactor of the RGB LED driver. It adds Doxygen-style comments, renames/clarifies constants (RGBLED_BLUE gains small R/G components), and reorders a few statements in rgb_led_effect_start/stop without changing observable behavior. No vulnerability, hardening, or functional change is introduced.
Changed components
core/embed/io/rgb_led/inc/io/rgb_led.hcore/embed/io/rgb_led/stm32u5/rgb_led_effects.ccore/embed/io/rgb_led/stm32u5/rgb_led_internal.hcore/embed/io/rgb_led/stm32u5/rgb_led_lp.cInspect captured patch +70 / −8
diff --git a/core/embed/io/rgb_led/inc/io/rgb_led.h b/core/embed/io/rgb_led/inc/io/rgb_led.h
index 69753d3f6..6ce710e1f 100644
--- a/core/embed/io/rgb_led/inc/io/rgb_led.h
+++ b/core/embed/io/rgb_led/inc/io/rgb_led.h
@@ -64,14 +64,56 @@ bool rgb_led_get_enabled(void);
#define RGBLED_ORANGE RGB_COMPOSE_COLOR(188, 42, 6)
#define RGBLED_RED RGB_COMPOSE_COLOR(100, 6, 3)
#define RGBLED_YELLOW RGB_COMPOSE_COLOR(22, 16, 0)
-#define RGBLED_BLUE RGB_COMPOSE_COLOR(0, 0, 50)
+#define RGBLED_BLUE RGB_COMPOSE_COLOR(5, 5, 50)
#define RGBLED_OFF 0x000000
+/**
+ * @brief RGB LED effect type
+ */
+typedef enum {
+ RGB_LED_EFFECT_BOOTLOADER_BREATHE = 0,
+ RGB_LED_EFFECT_CHARGING,
+ RGB_LED_NUM_OF_EFFECTS,
+} rgb_led_effect_type_t;
+
+/**
+ * @brief Initialize RGB LED driver
+ */
+void rgb_led_init(void);
+
+/**
+ * @brief Deinitialize RGB LED driver
+ */
+void rgb_led_deinit(void);
+
+#endif // KERNEL_MODE
+
// Set RGB LED color
// color: 24-bit RGB color, 0x00RRGGBB
+
+/**
+ * @brief Set the RGB led color.
+ *
+ * Set the color of the RGB led, if there is ongoing RGB led effect, this
+ * setting will stop the effect and override the color.
+ *
+ * @param color 24-bit RGB color, 0x00RRGGBB
+ */
void rgb_led_set_color(uint32_t color);
+/**
+ * @brief Start an RGB led effect.
+ *
+ * @param effect_type The type of effect to start selected from
+ * `rgb_led_effect_type_t` enum.
+ *
+ * @param requested_cycles The number of cycles to run the effect for, 0 will
+ * run the effect indefinitely.
+ */
void rgb_led_effect_start(rgb_led_effect_type_t effect_type,
uint32_t requested_cycles);
+/**
+ * @brief Stop the currently running RGB led effect and turn off the RGB led
+ */
void rgb_led_effect_stop(void);
diff --git a/core/embed/io/rgb_led/stm32u5/rgb_led_effects.c b/core/embed/io/rgb_led/stm32u5/rgb_led_effects.c
index c9a0013ea..a9d8c29fd 100644
--- a/core/embed/io/rgb_led/stm32u5/rgb_led_effects.c
+++ b/core/embed/io/rgb_led/stm32u5/rgb_led_effects.c
@@ -39,18 +39,21 @@ static uint32_t rgb_led_effect_bootloader_breathe(uint32_t elapsed_ms,
static uint32_t rgb_led_effect_charging(uint32_t elapsed_ms,
rgb_led_effect_data_t *data);
+// Effect callback functions lookup table
static uint32_t (*rgb_led_effects_callbacks[])(uint32_t elapsed_ms,
rgb_led_effect_data_t *data) = {
[RGB_LED_EFFECT_BOOTLOADER_BREATHE] = rgb_led_effect_bootloader_breathe,
[RGB_LED_EFFECT_CHARGING] = rgb_led_effect_charging,
};
+// Single color linear interpolation auxiliary function
static inline uint32_t linear_interpolate(uint32_t y0, uint32_t y1, uint32_t x,
uint32_t x1) {
int32_t diff = (int32_t)y1 - (int32_t)y0;
return (uint32_t)(y0 + (diff * (int32_t)x / (int32_t)x1));
}
+// Linear interpolation between two colors based on elapsed time
static uint32_t rgb_led_linear_effect(uint32_t c_start, uint32_t c_end,
uint32_t elapsed_ms, uint32_t total_ms) {
if (elapsed_ms >= total_ms) {
@@ -72,6 +75,7 @@ static uint32_t rgb_led_linear_effect(uint32_t c_start, uint32_t c_end,
return RGB_COMPOSE_COLOR(r, g, b);
}
+// Assign effect callback from the lookup table
bool rgb_led_assign_effect(rgb_led_effect_t *effect,
rgb_led_effect_type_t effect_type) {
if (effect_type < 0 || effect_type >= RGB_LED_NUM_OF_EFFECTS) {
@@ -87,6 +91,11 @@ bool rgb_led_assign_effect(rgb_led_effect_t *effect,
return true;
}
+/**
+ * Bootloader breathe effect
+ * Slow Linear transition effect from RGBLED_OFF to RGBLED_BLUE and back to
+ * RGBLED_OFF
+ */
static uint32_t rgb_led_effect_bootloader_breathe(uint32_t elapsed_ms,
rgb_led_effect_data_t *data) {
data->cycles = elapsed_ms / EFFECT_BOOTLOADER_BREATHE_CYCLE_MS;
@@ -105,6 +114,11 @@ static uint32_t rgb_led_effect_bootloader_breathe(uint32_t elapsed_ms,
}
}
+/**
+ * Charging effect
+ * Faster linear transition effect from RGBLED_OFF to RGBLED_YELLOW and back to
+ * RGBLED_OFF
+ */
static uint32_t rgb_led_effect_charging(uint32_t elapsed_ms,
rgb_led_effect_data_t *data) {
data->cycles = elapsed_ms / EFFECT_CHARGING_CYCLE_MS;
diff --git a/core/embed/io/rgb_led/stm32u5/rgb_led_internal.h b/core/embed/io/rgb_led/stm32u5/rgb_led_internal.h
index e2651b868..37b40f0bb 100644
--- a/core/embed/io/rgb_led/stm32u5/rgb_led_internal.h
+++ b/core/embed/io/rgb_led/stm32u5/rgb_led_internal.h
@@ -48,5 +48,12 @@ typedef struct {
rgb_led_effect_t effect;
} rgb_led_t;
+/**
+ * @brief Assign effect a callback function according to the effect_type,
+ *
+ * @param effect pointer to the effect handler
+ * @param effect_type the type of effect to assign
+ * @return true on success, false on failure
+ */
bool rgb_led_assign_effect(rgb_led_effect_t *effect,
rgb_led_effect_type_t effect_type);
diff --git a/core/embed/io/rgb_led/stm32u5/rgb_led_lp.c b/core/embed/io/rgb_led/stm32u5/rgb_led_lp.c
index 5ae41c4ed..a82188408 100644
--- a/core/embed/io/rgb_led/stm32u5/rgb_led_lp.c
+++ b/core/embed/io/rgb_led/stm32u5/rgb_led_lp.c
@@ -253,18 +253,17 @@ void rgb_led_effect_start(rgb_led_effect_type_t effect_type,
return;
}
+ systimer_unset();
+
if (!rgb_led_assign_effect(&drv->effect, effect_type)) {
return;
}
drv->effect.data.requested_cycles = requested_cycles;
-
- systimer_set_periodic(drv->effect_timer, RGB_LED_EFFECT_TIMER_PERIOD_MS);
- drv->effect.start_time_ms = systick_ms();
-
drv->ongoing_effect = true;
+ drv->effect.start_time_ms = systick_ms();
- return;
+ systimer_set_periodic(drv->effect_timer, RGB_LED_EFFECT_TIMER_PERIOD_MS);
}
void rgb_led_effect_stop(void) {
@@ -274,8 +273,8 @@ void rgb_led_effect_stop(void) {
return;
}
- drv->ongoing_effect = false;
systimer_unset(drv->effect_timer);
+ drv->ongoing_effect = false;
// Reset the LED to default state
rgb_led_apply_color(drv, RGBLED_OFF); // Turn off the LED
@@ -323,9 +322,9 @@ static void rgb_led_systimer_callback(void* context) {
uint32_t color = drv->effect.callback(elapsed_ms, &drv->effect.data);
rgb_led_apply_color(drv, color);
+ // Stop the effect if the requested cycles have been reached
if (drv->effect.data.requested_cycles &&
drv->effect.data.cycles >= drv->effect.data.requested_cycles) {
- // Stop the effect if the requested cycles have been reached
rgb_led_effect_stop();
}
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.