diff --git a/core/SConscript.unix b/core/SConscript.unix index 559f14c2a8..7e70f3dea3 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -21,7 +21,7 @@ if BENCHMARK and PYOPT != '0': print("BENCHMARK=1 works only with PYOPT=0.") exit(1) -FEATURES_WANTED = ["input", "sd_card", "dma2d", "optiga"] +FEATURES_WANTED = ["input", "rgb_led", "sd_card", "dma2d", "optiga"] if not models.has_emulator(TREZOR_MODEL): # skip unix build diff --git a/core/embed/io/display/inc/io/display.h b/core/embed/io/display/inc/io/display.h index afb5252f94..9c52cd6018 100644 --- a/core/embed/io/display/inc/io/display.h +++ b/core/embed/io/display/inc/io/display.h @@ -159,4 +159,10 @@ void display_copy_mono1p(const gfx_bitblt_t *bb); // The function is available only on the emulator. const char *display_save(const char *prefix); void display_clear_save(void); + +#ifdef USE_RGB_LED +// Display a color on the LED. +// The function is available only on the emulator. +void display_rgb_led(uint32_t color); +#endif #endif diff --git a/core/embed/io/display/unix/display_driver.c b/core/embed/io/display/unix/display_driver.c index 6b1a8b9ef2..50aafb933f 100644 --- a/core/embed/io/display/unix/display_driver.c +++ b/core/embed/io/display/unix/display_driver.c @@ -74,6 +74,9 @@ typedef struct { // and we have to simulate it uint8_t mono_framebuf[DISPLAY_RESX * DISPLAY_RESY]; #endif +#ifdef USE_RGB_LED + uint32_t led_color; +#endif } display_driver_t; @@ -319,6 +322,46 @@ static void copy_mono_framebuf(display_driver_t *drv) { } #endif +#ifdef USE_RGB_LED +void draw_rgb_led(uint32_t color) { + display_driver_t *drv = &g_display_driver; + + if (!drv->initialized) { + return; + } + // Extract RGB components + uint32_t r = (color >> 16) & 0xFF; + uint32_t g = (color >> 8) & 0xFF; + uint32_t b = color & 0xFF; + + // Define LED circle properties + const int radius = 5; + int center_x = DISPLAY_RESX / 2; + int center_y = 0; + + // Position based on background + if (drv->background) { + center_x += TOUCH_OFFSET_X; + center_y = TOUCH_OFFSET_Y / 2; + } else { + center_x += EMULATOR_BORDER; + center_y = EMULATOR_BORDER / 2; + } + + // Draw the LED + SDL_SetRenderDrawColor(drv->renderer, r, g, b, 255); + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + if (x * x + y * y <= radius * radius) { + SDL_RenderDrawPoint(drv->renderer, center_x + x, center_y + y); + } + } + } + SDL_SetRenderDrawColor(drv->renderer, 0, 0, 0, 255); + SDL_RenderPresent(drv->renderer); +} +#endif + void display_refresh(void) { display_driver_t *drv = &g_display_driver; @@ -353,6 +396,10 @@ void display_refresh(void) { SDL_RenderCopyEx(drv->renderer, drv->texture, NULL, &r, drv->orientation_angle, NULL, 0); } + // Show the LED +#ifdef USE_RGB_LED + draw_rgb_led(drv->led_color); +#endif SDL_RenderPresent(drv->renderer); } @@ -493,3 +540,14 @@ void display_clear_save(void) { SDL_FreeSurface(drv->prev_saved); drv->prev_saved = NULL; } + +#ifdef USE_RGB_LED +void display_rgb_led(uint32_t color) { + display_driver_t *drv = &g_display_driver; + + if (!drv->initialized) { + return; + } + drv->led_color = color; +} +#endif diff --git a/core/embed/io/rgb_led/unix/rgb_led.c b/core/embed/io/rgb_led/unix/rgb_led.c new file mode 100644 index 0000000000..3c245d9cf6 --- /dev/null +++ b/core/embed/io/rgb_led/unix/rgb_led.c @@ -0,0 +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 . + */ + +#include +#include + +void rgb_led_set_color(uint32_t color) { display_rgb_led(color); } diff --git a/core/site_scons/models/T3W1/emulator.py b/core/site_scons/models/T3W1/emulator.py index 0aa1eb5beb..4281c57dcb 100644 --- a/core/site_scons/models/T3W1/emulator.py +++ b/core/site_scons/models/T3W1/emulator.py @@ -45,6 +45,12 @@ def configure( paths += ["embed/io/sbu/inc"] defines += [("USE_SBU", "1")] + if "rgb_led" in features_wanted: + sources += ["embed/io/rgb_led/unix/rgb_led.c"] + paths += ["embed/io/rgb_led/inc"] + features_available.append("rgb_led") + defines += [("USE_RGB_LED", "1")] + if "optiga" in features_wanted: sources += ["embed/sec/optiga/unix/optiga_hal.c"] sources += ["embed/sec/optiga/unix/optiga.c"]