feat(core): add rgb_led_effect_get_type function.
What changed, and why it matters
This commit adds a new function that lets the firmware ask the RGB LED driver what lighting effect is currently running (for example, pairing or charging). It also adds a special 'none' value returned when no effect is active and tightens a bounds check so invalid negative effect IDs are rejected. There is no security-relevant change here; it is a straightforward feature addition.
No security action required. Review as normal feature code.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces rgb_led_effect_get_type() to expose the currently running RGB LED effect type from the STM32U5 low-power LED driver through the syscall interface to Rust code. It adds RGB_LED_EFFECT_NONE = -1 to the enum, returns it when uninitialized or no effect is running, and updates rgb_led_assign_effect() to reject effect_type < 0. The function is allowlisted in build.rs, assigned a syscall number, dispatched in syscall_dispatch.c, and stubbed in syscall_stubs.c.
Changed components
core/embed/io/rgb_ledcore/embed/sys/syscallcore/embed/rust/build.rsInspect captured patch +39 / −1
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 baeaeb041..f9a588ad8 100644
--- a/core/embed/io/rgb_led/inc/io/rgb_led.h
+++ b/core/embed/io/rgb_led/inc/io/rgb_led.h
@@ -42,6 +42,7 @@
* @brief RGB LED effect type
*/
typedef enum {
+ RGB_LED_EFFECT_NONE = -1,
RGB_LED_EFFECT_PAIRING = 0,
RGB_LED_EFFECT_CHARGING,
RGB_LED_NUM_OF_EFFECTS,
@@ -135,3 +136,13 @@ void rgb_led_effect_stop(void);
* @return true if an effect is currently running, false otherwise
*/
bool rgb_led_effect_ongoing(void);
+
+/**
+ * @brief Get the ongoing RGB led effect type
+ *
+ * Get the ongoing RGB led effect type, return RGB_LED_EFFECT_NONE if no effect
+ * is running.
+ *
+ * @return The type of the currently running RGB led effect
+ */
+rgb_led_effect_type_t rgb_led_effect_get_type(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 9f09c42b2..c3b1c2e24 100644
--- a/core/embed/io/rgb_led/stm32u5/rgb_led_effects.c
+++ b/core/embed/io/rgb_led/stm32u5/rgb_led_effects.c
@@ -105,7 +105,7 @@ static void rgb_led_linear_gc_effect(uint32_t c0, uint32_t c1,
// 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 >= RGB_LED_NUM_OF_EFFECTS) {
+ if (effect_type >= RGB_LED_NUM_OF_EFFECTS || effect_type < 0) {
return false;
}
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 a6b895aa2..bd95a4bbb 100644
--- a/core/embed/io/rgb_led/stm32u5/rgb_led_lp.c
+++ b/core/embed/io/rgb_led/stm32u5/rgb_led_lp.c
@@ -287,6 +287,21 @@ bool rgb_led_effect_ongoing(void) {
return ongoing;
}
+rgb_led_effect_type_t rgb_led_effect_get_type(void) {
+ rgb_led_t* drv = &g_rgb_led;
+
+ if (!drv->initialized || !drv->ongoing_effect) {
+ return RGB_LED_EFFECT_NONE;
+ }
+
+ rgb_led_effect_type_t effect_type;
+ irq_key_t irq_key = irq_lock();
+ effect_type = drv->effect.type;
+ irq_unlock(irq_key);
+
+ return effect_type;
+}
+
static void rgb_led_apply_color(rgb_led_t* drv, rgb_led_color_fs_t* color_fs) {
// Check color settings is in range
if (color_fs->red > RGB_LED_TIMER_PERIOD ||
diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs
index 773f7d7e9..204e52a00 100644
--- a/core/embed/rust/build.rs
+++ b/core/embed/rust/build.rs
@@ -405,6 +405,7 @@ fn generate_trezorhal_bindings() {
.allowlist_function("rgb_led_effect_start")
.allowlist_function("rgb_led_effect_stop")
.allowlist_function("rgb_led_effect_ongoing")
+ .allowlist_function("rgb_led_effect_get_type")
// systick
.allowlist_function("systick_delay_ms")
.allowlist_function("systick_ms")
diff --git a/core/embed/sys/syscall/inc/sys/syscall_numbers.h b/core/embed/sys/syscall/inc/sys/syscall_numbers.h
index 53a0d0486..612ffd821 100644
--- a/core/embed/sys/syscall/inc/sys/syscall_numbers.h
+++ b/core/embed/sys/syscall/inc/sys/syscall_numbers.h
@@ -90,6 +90,7 @@ typedef enum {
SYSCALL_RGB_LED_EFFECT_START,
SYSCALL_RGB_LED_EFFECT_STOP,
SYSCALL_RGB_LED_EFFECT_ONGOING,
+ SYSCALL_RGB_LED_EFFECT_GET_TYPE,
SYSCALL_HAPTIC_SET_ENABLED,
SYSCALL_HAPTIC_GET_ENABLED,
diff --git a/core/embed/sys/syscall/stm32/syscall_dispatch.c b/core/embed/sys/syscall/stm32/syscall_dispatch.c
index 4e1a50725..854ccc682 100644
--- a/core/embed/sys/syscall/stm32/syscall_dispatch.c
+++ b/core/embed/sys/syscall/stm32/syscall_dispatch.c
@@ -351,6 +351,11 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
case SYSCALL_RGB_LED_EFFECT_ONGOING: {
args[0] = rgb_led_effect_ongoing();
} break;
+
+ case SYSCALL_RGB_LED_EFFECT_GET_TYPE: {
+ args[0] = rgb_led_effect_get_type();
+ } break;
+
#endif
#ifdef USE_HAPTIC
diff --git a/core/embed/sys/syscall/stm32/syscall_stubs.c b/core/embed/sys/syscall/stm32/syscall_stubs.c
index aec86aaab..f81d1a691 100644
--- a/core/embed/sys/syscall/stm32/syscall_stubs.c
+++ b/core/embed/sys/syscall/stm32/syscall_stubs.c
@@ -334,6 +334,11 @@ bool rgb_led_effect_ongoing(void) {
return (bool)syscall_invoke0(SYSCALL_RGB_LED_EFFECT_ONGOING);
}
+rgb_led_effect_type_t rgb_led_effect_get_type(void) {
+ return (rgb_led_effect_type_t)syscall_invoke0(
+ SYSCALL_RGB_LED_EFFECT_GET_TYPE);
+}
+
#endif
// =============================================================================
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.