1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-24 08:45:36 +03:00

Optimize ledstrip DMA buffer update to reduce task processing time

Previous logic was updating updating the DMA buffer for all possible LED positions (32) regardless of how many were used. Since there are 24 bytes per LED, this performed a lot of unnecessary processing in cases where the user had less than 32 LEDs configured.

Also includes a bug fix in that if the LED count was decreased (like making changed using the Configurator LED tab), the now unused LEDs at the end of the string would remain on at the last color applied. Now they will be properly turned off. The bug was minor as it was resolved by a reboot, but made setup using the Configurator confusing since changes made are reflected when the user clicked the "Save" button (which does not reboot).
This commit is contained in:
Bruce Luckcuck 2019-09-05 11:58:54 -04:00
parent 62f0eb7ed3
commit e1f10b0430
4 changed files with 25 additions and 4 deletions

View file

@ -57,6 +57,8 @@ uint32_t ledStripDMABuffer[WS2811_DMA_BUFFER_SIZE];
static ioTag_t ledStripIoTag;
static bool ws2811Initialised = false;
volatile bool ws2811LedDataTransferInProgress = false;
static unsigned usedLedCount = 0;
static bool needsFullRefresh = true;
uint16_t BIT_COMPARE_1 = 0;
uint16_t BIT_COMPARE_0 = 0;
@ -87,18 +89,27 @@ void scaleLedValue(uint16_t index, const uint8_t scalePercent)
void setStripColor(const hsvColor_t *color)
{
for (unsigned index = 0; index < WS2811_DATA_BUFFER_SIZE; index++) {
for (unsigned index = 0; index < usedLedCount; index++) {
ledColorBuffer[index] = *color;
}
}
void setStripColors(const hsvColor_t *colors)
{
for (unsigned index = 0; index < WS2811_DATA_BUFFER_SIZE; index++) {
for (unsigned index = 0; index < usedLedCount; index++) {
setLedHsv(index, colors++);
}
}
void setUsedLedCount(unsigned ledCount)
{
usedLedCount = (ledCount < WS2811_DATA_BUFFER_SIZE) ? ledCount : WS2811_DATA_BUFFER_SIZE;
// Update all possible positions on the next update in case the count
// decreased otherwise LEDs on the end could be left in their previous state
needsFullRefresh = true;
}
void ws2811LedStripInit(ioTag_t ioTag)
{
memset(ledStripDMABuffer, 0, sizeof(ledStripDMABuffer));
@ -129,6 +140,7 @@ bool isWS2811LedStripReady(void)
STATIC_UNIT_TESTED void updateLEDDMABuffer(ledStripFormatRGB_e ledFormat, rgbColor24bpp_t *color, unsigned ledIndex)
{
uint32_t packed_colour;
switch (ledFormat) {
@ -163,11 +175,14 @@ void ws2811UpdateStrip(ledStripFormatRGB_e ledFormat)
// fill transmit buffer with correct compare values to achieve
// correct pulse widths according to color values
while (ledIndex < WS2811_DATA_BUFFER_SIZE) {
rgbColor24bpp_t *rgb24 = hsvToRgb24(&ledColorBuffer[ledIndex]);
const unsigned ledUpdateCount = needsFullRefresh ? WS2811_DATA_BUFFER_SIZE : usedLedCount;
const hsvColor_t hsvBlack = { 0, 0, 0 };
while (ledIndex < ledUpdateCount) {
rgbColor24bpp_t *rgb24 = hsvToRgb24(ledIndex < usedLedCount ? &ledColorBuffer[ledIndex] : &hsvBlack);
updateLEDDMABuffer(ledFormat, rgb24, ledIndex++);
}
needsFullRefresh = false;
ws2811LedDataTransferInProgress = true;
ws2811LedStripDMAEnable();

View file

@ -67,6 +67,8 @@ void setLedValue(uint16_t index, const uint8_t value);
void setStripColor(const hsvColor_t *color);
void setStripColors(const hsvColor_t *colors);
void setUsedLedCount(unsigned ledCount);
bool isWS2811LedStripReady(void);
#if defined(STM32F1) || defined(STM32F3)

View file

@ -269,6 +269,7 @@ STATIC_UNIT_TESTED void updateLedCount(void)
ledCounts.count = count;
ledCounts.ring = countRing;
ledCounts.larson = countScanner;
setUsedLedCount(ledCounts.count);
}
void reevaluateLedConfig(void)

View file

@ -394,4 +394,7 @@ uint8_t getRssiPercent(void) { return 0; }
bool isFlipOverAfterCrashActive(void) { return false; }
void ws2811LedStripEnable(void) { }
void setUsedLedCount(unsigned) { };
}