Skip to content

Commit

Permalink
feat(front-leds): diamond: use update_channels to set brightness
Browse files Browse the repository at this point in the history
apa102 driver with led_strip api doesn't allow to set the brightness
byte, only the three RGB values. Use `update_channels` instead to set
LED raw values.
apa102 receives color in that order: ABGR, B and R have to be swapped in
 the struct before updating the channels.

Signed-off-by: Cyril Fougeray <[email protected]>
  • Loading branch information
fouge committed Jan 15, 2025
1 parent c5c4aa4 commit 3cc89eb
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
30 changes: 28 additions & 2 deletions main_board/src/ui/rgb_leds/front_leds/front_leds.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,19 @@ static const struct device *const led_strip_w =
static const struct device *led_strip = led_strip_w;

#define NUM_LEDS DT_PROP(DT_NODELABEL(front_unit_rgb_leds_w), num_leds)

#if defined(CONFIG_BOARD_PEARL_MAIN)

static const struct device *const led_strip_apa = NULL;

#define NUM_CENTER_LEDS 9
#define INDEX_RING_ZERO \
((NUM_RING_LEDS * 3 / 4)) // 0º is at the 3 o'clock position
// Maximum amount of time for LED strip update
// It's also the minimum amount of time we need to trigger
// an LED strip update until the next IR LED pulse
#define LED_STRIP_MAXIMUM_UPDATE_TIME_US 10000

#elif defined(CONFIG_BOARD_DIAMOND_MAIN)

// NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init)
Expand All @@ -45,12 +50,13 @@ static const struct device *const led_strip_apa =
// 0º (3 o'clock position) is at 53rd LED on Front Unit 6.2
#define INDEX_RING_ZERO 53
#endif

#define NUM_RING_LEDS (NUM_LEDS - NUM_CENTER_LEDS)

// for rainbow pattern
#define SHADES_PER_COLOR 4 // 4^3 = 64 different colors

struct center_ring_leds {
__PACKED struct center_ring_leds {
#if defined(CONFIG_BOARD_PEARL_MAIN)
struct led_rgb center_leds[NUM_CENTER_LEDS];
struct led_rgb ring_leds[NUM_RING_LEDS];
Expand Down Expand Up @@ -82,6 +88,8 @@ typedef union {
} user_leds_t;
static user_leds_t leds;

BUILD_ASSERT(sizeof(leds.part) == sizeof(leds.all), "leds union size mismatch");

/// Mutex used to protect the LEDs array update from multiple threads
static K_SEM_DEFINE(leds_update_sem, 1, 1);
#if defined(CONFIG_BOARD_PEARL_MAIN)
Expand Down Expand Up @@ -369,7 +377,25 @@ front_leds_thread()
k_sem_take(&leds_wait_for_trigger, K_FOREVER);
}
#endif
led_strip_update_rgb(led_strip, leds.all, ARRAY_SIZE(leds.all));
// use update_channels for APA102 LEDs, to be able to set the
// brightness byte, not encoded in `struct led_rgb`
const struct led_strip_driver_api *api =
(const struct led_strip_driver_api *)led_strip->api;
if (led_strip == led_strip_apa && api->update_channels != NULL) {
// apa102 channels in that order: A (brightness), B, G, R
for (size_t i = 0; i < ARRAY_SIZE(leds.all); i++) {
const uint8_t red = leds.all[i].r;
leds.all[i].r = leds.all[i].b;
leds.all[i].b = red;
}
const int ret = led_strip_update_channels(
led_strip, (uint8_t *)leds.all, sizeof(leds.all));
ASSERT_SOFT(ret);
} else {
const int ret = led_strip_update_rgb(led_strip, leds.all,
ARRAY_SIZE(leds.all));
ASSERT_SOFT(ret);
}
atomic_set(&leds_dirty, ALL_LEDS_DIRTY);
k_sem_give(&leds_update_sem);
}
Expand Down
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ manifest:
remote: worldcoin
projects:
- name: zephyr
revision: f07063db20c993b1d1e0a1f514b1e6c266a18602
revision: afc8bc561bce67fb992cf84cd53bc69606d9f3f6
import:
name-allowlist:
- cmsis
Expand Down

0 comments on commit 3cc89eb

Please sign in to comment.