Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 42 additions & 42 deletions radio/src/boards/generic_stm32/rgb_leds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

#if defined(LED_STRIP_GPIO)

#include "stm32_ws2812.h"
#include "stm32_rgbleds.h"
#include "stm32_dma.h"
#include "stm32_gpio.h"
#include "hal/gpio.h"
Expand All @@ -37,11 +37,11 @@

// Front buffer: read by the WS2812 DMA ISR. Mutated only inside
// _flush_and_update() and only when DMA is idle.
static uint8_t _led_colors[WS2812_BYTES_PER_LED * LED_STRIP_LENGTH];
static uint8_t _led_colors[RGBLEDS_BYTES_PER_LED * LED_STRIP_LENGTH];

// Back buffer: written by rgbSetLedColor (menu task / pre-OS, single writer).
// Read only inside _flush_and_update() when a new frame has been published.
static uint8_t _back_colors[WS2812_BYTES_PER_LED * LED_STRIP_LENGTH];
static uint8_t _back_colors[RGBLEDS_BYTES_PER_LED * LED_STRIP_LENGTH];

// Seqlock-style publish using a single counter:
// - LSB set (odd) → menu task is mid-batch, back buffer not consistent
Expand Down Expand Up @@ -77,50 +77,15 @@ static timer_handle_t _refresh_timer = TIMER_INITIALIZER;

static void _flush_and_update()
{
if (!ws2812_is_busy(&_led_timer)) {
if (!rgbleds_is_busy(&_led_timer)) {
uint32_t seq = _commit_seq;
// Skip if mid-batch (odd) or already consumed.
if ((seq & 1u) == 0u && seq != _consumed_seq) {
memcpy(_led_colors, _back_colors, sizeof(_led_colors));
_consumed_seq = seq;
Comment thread
pfeerick marked this conversation as resolved.
}
rgbleds_update(&_led_timer);
}
ws2812_update(&_led_timer);
}

void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
_begin_batch();
ws2812_set_color_in_buf(_back_colors, led, r, g, b);
}

uint32_t rgbGetLedColor(uint8_t led)
{
return ws2812_get_color_in_buf(_back_colors, led);
}

bool rgbGetState(uint8_t led)
{
return ws2812_get_state_in_buf(_back_colors, led);
}

void rgbLedColorApply()
{
// Publish: ensure the back-buffer write is complete, then advance to
// the next even value. (seq | 1) + 1 == round up to next even.
_compiler_barrier();
_commit_seq = (_commit_seq | 1u) + 1u;
if (!scheduler_is_running()) {
// Pre-OS: timer task isn't running, drive the flush synchronously.
_flush_and_update();
}
}

void rgbLedClearAll()
{
_begin_batch();
memset(_back_colors, 0, sizeof(_back_colors));
rgbLedColorApply();
}

__attribute__((weak)) void rgbLedOnUpdate() {}
Expand Down Expand Up @@ -168,7 +133,7 @@ static bool _hw_initialised = false;
void rgbLedHwInit()
{
if (_hw_initialised) return;
ws2812_init(&_led_timer, _led_colors, LED_STRIP_LENGTH, WS2812_GRB);
rgbleds_init(&_led_timer, _led_colors, LED_STRIP_LENGTH, RGBLEDS_GRB);
_hw_initialised = true;
rgbLedClearAll();
}
Expand All @@ -179,6 +144,41 @@ void rgbLedInit()
rgbLedStart();
}

void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
_begin_batch();
rgbleds_set_color_in_buf(_back_colors, led, r, g, b);
}

uint32_t rgbGetLedColor(uint8_t led)
{
return rgbleds_get_color_in_buf(_back_colors, led);
}

bool rgbGetState(uint8_t led)
{
return rgbleds_get_state_in_buf(_back_colors, led);
}

void rgbLedColorApply()
{
// Publish: ensure the back-buffer write is complete, then advance to
// the next even value. (seq | 1) + 1 == round up to next even.
_compiler_barrier();
_commit_seq = (_commit_seq | 1u) + 1u;
if (!scheduler_is_running()) {
// Pre-OS: timer task isn't running, drive the flush synchronously.
_flush_and_update();
}
}

void rgbLedClearAll()
{
_begin_batch();
memset(_back_colors, 0, sizeof(_back_colors));
rgbLedColorApply();
}

// Make sure the timer channel is supported
static_assert(__STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(LED_STRIP_TIMER_CHANNEL),
"Unsupported timer channel");
Expand All @@ -193,7 +193,7 @@ static_assert(__STM32_DMA_IS_STREAM_SUPPORTED(LED_STRIP_TIMER_DMA_STREAM),

extern "C" void LED_STRIP_TIMER_DMA_IRQHandler()
{
ws2812_dma_isr(&_led_timer);
rgbleds_dma_isr(&_led_timer);
}

#endif
2 changes: 1 addition & 1 deletion radio/src/boards/rm-h750/bsp_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

#include "bsp_io.h"

#include "stm32_ws2812.h"
#include "stm32_rgbleds.h"
#include "stm32_switch_driver.h"
#include "stm32_i2c_driver.h"
#include "hal/switch_driver.h"
Expand Down
2 changes: 1 addition & 1 deletion radio/src/edgetx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "os/sleep.h"
#include "os/time.h"
#if !defined(SIMU)
#include "stm32_ws2812.h"
#include "stm32_rgbleds.h"
#include "boards/generic_stm32/rgb_leds.h"
#include "stm32_hal.h"
#include "stm32_hal_ll.h"
Expand Down
Loading