initial commit
This commit is contained in:
29
libraries/FastLED/src/platforms/adafruit/README.md
Normal file
29
libraries/FastLED/src/platforms/adafruit/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# FastLED Platform: adafruit
|
||||
|
||||
Adafruit_NeoPixel integration providing a FastLED‑compatible clockless controller implemented on top of Adafruit’s driver.
|
||||
|
||||
## Files (quick pass)
|
||||
- `clockless.h`: Adapter layer. Exposes a `ClocklessController` template that marshals FastLED pixel data to an `Adafruit_NeoPixel` instance. Requires `Adafruit_NeoPixel.h` to be available; timing (T1/T2/T3) is managed by the Adafruit library.
|
||||
|
||||
## Usage and detection
|
||||
- Controlled by `FASTLED_USE_ADAFRUIT_NEOPIXEL` (defaults to undefined unless building docs). If enabled but `Adafruit_NeoPixel.h` is missing, the adapter disables itself with an error.
|
||||
- Color order: FastLED’s `PixelController` applies RGB ordering; the adapter always feeds RGB into Adafruit’s API.
|
||||
- Timings: `T1/T2/T3` template params are ignored here; Adafruit’s driver handles signal generation and timing per platform.
|
||||
|
||||
## Notes
|
||||
- This path is useful when Adafruit’s platform backends (e.g., some boards/cores) are preferred or more stable for your setup.
|
||||
- Performance characteristics and memory usage follow Adafruit_NeoPixel; expect different throughput vs native FastLED clockless drivers.
|
||||
|
||||
## Optional feature defines
|
||||
|
||||
- **`FASTLED_USE_ADAFRUIT_NEOPIXEL`**: Default undefined (unless building docs via `FASTLED_DOXYGEN`). When defined, enables the Adafruit adapter; requires `Adafruit_NeoPixel.h`.
|
||||
|
||||
Define before including `FastLED.h`.
|
||||
## Compatibility and color order
|
||||
|
||||
Supported color orders: FastLED’s `PixelController` handles byte reordering before passing data to Adafruit_NeoPixel. Typical orders like GRB/RGB/BRG are supported transparently.
|
||||
|
||||
Constraints vs native FastLED timing:
|
||||
|
||||
- Timing is wholly delegated to Adafruit_NeoPixel. The `T1/T2/T3` template parameters are ignored; use Adafruit’s platform timings.
|
||||
- Throughput and CPU usage may differ from FastLED’s native clockless or RMT/I2S backends. If you need multi‑strip parallelism or strict ISR windows, consider native drivers instead.
|
||||
8
libraries/FastLED/src/platforms/adafruit/clockless.cpp
Normal file
8
libraries/FastLED/src/platforms/adafruit/clockless.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
#include "fl/has_include.h"
|
||||
|
||||
#if FL_HAS_INCLUDE(<Adafruit_NeoPixel.h>)
|
||||
#include "platforms/adafruit/clockless_real.hpp"
|
||||
#else
|
||||
#include "platforms/adafruit/clockless_fake.hpp"
|
||||
#endif
|
||||
73
libraries/FastLED/src/platforms/adafruit/clockless.h
Normal file
73
libraries/FastLED/src/platforms/adafruit/clockless.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
/// @file clockless.h
|
||||
/// Adafruit_NeoPixel-based clockless controller implementation
|
||||
///
|
||||
/// This header provides a FastLED-compatible clockless controller that uses
|
||||
/// the Adafruit_NeoPixel library as the underlying driver. This allows users
|
||||
/// to leverage the proven reliability and platform-specific optimizations
|
||||
/// of the Adafruit library within the FastLED ecosystem.
|
||||
///
|
||||
/// Requirements:
|
||||
/// - Adafruit_NeoPixel library must be included before FastLED
|
||||
/// - The controller is only available when Adafruit_NeoPixel.h is detected
|
||||
|
||||
|
||||
#include "fl/memory.h"
|
||||
#include "fl/unique_ptr.h"
|
||||
#include "eorder.h"
|
||||
#include "pixel_controller.h"
|
||||
#include "platforms/adafruit/driver.h"
|
||||
|
||||
|
||||
namespace fl {
|
||||
class PixelIterator;
|
||||
|
||||
/// WS2812/NeoPixel clockless controller using Adafruit_NeoPixel library as the underlying driver
|
||||
///
|
||||
/// This controller provides a simple interface for WS2812/NeoPixel LEDs using the proven
|
||||
/// Adafruit_NeoPixel library for platform-specific optimizations and reliable output.
|
||||
/// Supports RGB color order conversion and handles initialization, pixel conversion,
|
||||
/// and output automatically.
|
||||
///
|
||||
/// @tparam DATA_PIN the data pin for the LED strip
|
||||
/// @tparam RGB_ORDER the RGB ordering for the LEDs (affects input processing, output is always RGB)
|
||||
/// @see https://github.com/adafruit/Adafruit_NeoPixel
|
||||
template <int DATA_PIN, EOrder RGB_ORDER = GRB>
|
||||
class AdafruitWS2812Controller : public CPixelLEDController<RGB_ORDER> {
|
||||
private:
|
||||
fl::unique_ptr<fl::IAdafruitNeoPixelDriver> mDriver;
|
||||
|
||||
public:
|
||||
/// Constructor - creates uninitialized controller
|
||||
AdafruitWS2812Controller(){}
|
||||
|
||||
/// Destructor - automatic cleanup
|
||||
virtual ~AdafruitWS2812Controller() = default;
|
||||
|
||||
/// Initialize the controller
|
||||
virtual void init() override {
|
||||
// Driver will be initialized when showPixels is first called
|
||||
}
|
||||
|
||||
/// Output pixels to the LED strip
|
||||
/// Converts FastLED pixel data to Adafruit format and displays
|
||||
/// @param pixels the pixel controller containing LED data
|
||||
virtual void showPixels(PixelController<RGB_ORDER> &pixels) override {
|
||||
// Initialize driver if needed
|
||||
if (!mDriver) {
|
||||
mDriver = fl::IAdafruitNeoPixelDriver::create();
|
||||
mDriver->init(DATA_PIN);
|
||||
}
|
||||
// Convert to PixelIterator and send to driver
|
||||
auto pixelIterator = pixels.as_iterator(this->getRgbw());
|
||||
mDriver->showPixels(pixelIterator);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Get the driver instance (for derived classes)
|
||||
fl::IAdafruitNeoPixelDriver& getDriver() {
|
||||
return *mDriver;
|
||||
}
|
||||
};
|
||||
} // namespace fl
|
||||
37
libraries/FastLED/src/platforms/adafruit/clockless_fake.hpp
Normal file
37
libraries/FastLED/src/platforms/adafruit/clockless_fake.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/// @file clockless.cpp
|
||||
/// Implementation of IAdafruitNeoPixelDriver
|
||||
///
|
||||
/// This file contains the actual Adafruit_NeoPixel integration, keeping the
|
||||
/// dependency isolated from header files to avoid PlatformIO LDF issues.
|
||||
|
||||
|
||||
#include "platforms/adafruit/driver.h"
|
||||
#include "fl/unused.h"
|
||||
#include "fl/warn.h"
|
||||
|
||||
namespace fl {
|
||||
|
||||
// Concrete implementation of IAdafruitNeoPixelDriver
|
||||
class AdafruitNeoPixelDriverFake : public IAdafruitNeoPixelDriver {
|
||||
public:
|
||||
AdafruitNeoPixelDriverFake() {}
|
||||
|
||||
~AdafruitNeoPixelDriverFake() override = default;
|
||||
|
||||
void init(int dataPin) override {
|
||||
FL_UNUSED(dataPin);
|
||||
FL_WARN("Please install adafruit neopixel package to use this api bridge.");
|
||||
}
|
||||
|
||||
void showPixels(PixelIterator& pixelIterator) override {
|
||||
FL_UNUSED(pixelIterator);
|
||||
FL_WARN("Please install adafruit neopixel package to use this api bridge.");
|
||||
}
|
||||
};
|
||||
|
||||
// Static factory method implementation
|
||||
fl::unique_ptr<IAdafruitNeoPixelDriver> IAdafruitNeoPixelDriver::create() {
|
||||
return fl::unique_ptr<IAdafruitNeoPixelDriver>(new AdafruitNeoPixelDriverFake());
|
||||
}
|
||||
|
||||
} // namespace fl
|
||||
93
libraries/FastLED/src/platforms/adafruit/clockless_real.hpp
Normal file
93
libraries/FastLED/src/platforms/adafruit/clockless_real.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/// @file clockless.cpp
|
||||
/// Implementation of IAdafruitNeoPixelDriver
|
||||
///
|
||||
/// This file contains the actual Adafruit_NeoPixel integration, keeping the
|
||||
/// dependency isolated from header files to avoid PlatformIO LDF issues.
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
|
||||
#include "fl/unique_ptr.h"
|
||||
#include "fl/memory.h"
|
||||
#include "pixel_iterator.h"
|
||||
#include "platforms/adafruit/driver.h"
|
||||
|
||||
namespace fl {
|
||||
|
||||
// Concrete implementation of IAdafruitNeoPixelDriver
|
||||
class AdafruitNeoPixelDriverImpl : public IAdafruitNeoPixelDriver {
|
||||
private:
|
||||
unique_ptr<Adafruit_NeoPixel> mNeoPixel;
|
||||
bool mInitialized;
|
||||
int mDataPin;
|
||||
|
||||
public:
|
||||
AdafruitNeoPixelDriverImpl()
|
||||
: mNeoPixel(nullptr), mInitialized(false), mDataPin(-1) {}
|
||||
|
||||
~AdafruitNeoPixelDriverImpl() override = default;
|
||||
|
||||
void init(int dataPin) override {
|
||||
if (!mInitialized) {
|
||||
mDataPin = dataPin;
|
||||
mInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void showPixels(PixelIterator& pixelIterator) override {
|
||||
if (!mInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get pixel count from iterator
|
||||
int numPixels = pixelIterator.size();
|
||||
auto rgbw = pixelIterator.get_rgbw();
|
||||
|
||||
// Determine the appropriate NeoPixel type based on RGBW mode
|
||||
uint16_t neoPixelType = NEO_KHZ800;
|
||||
if (rgbw.active()) {
|
||||
neoPixelType |= NEO_RGBW; // RGBW mode
|
||||
} else {
|
||||
neoPixelType |= NEO_RGB; // RGB mode
|
||||
}
|
||||
|
||||
// Create or recreate NeoPixel instance if needed
|
||||
if (!mNeoPixel || mNeoPixel->numPixels() != numPixels) {
|
||||
if (mNeoPixel) {
|
||||
mNeoPixel.reset();
|
||||
}
|
||||
mNeoPixel = fl::make_unique<Adafruit_NeoPixel>(
|
||||
numPixels, mDataPin, neoPixelType);
|
||||
mNeoPixel->begin();
|
||||
}
|
||||
|
||||
// Convert pixel data using PixelIterator and send to Adafruit_NeoPixel
|
||||
if (rgbw.active()) {
|
||||
// RGBW mode
|
||||
for (int i = 0; pixelIterator.has(1); ++i) {
|
||||
fl::u8 r, g, b, w;
|
||||
pixelIterator.loadAndScaleRGBW(&r, &g, &b, &w);
|
||||
mNeoPixel->setPixelColor(i, r, g, b, w);
|
||||
pixelIterator.advanceData();
|
||||
}
|
||||
} else {
|
||||
// RGB mode
|
||||
for (int i = 0; pixelIterator.has(1); ++i) {
|
||||
fl::u8 r, g, b;
|
||||
pixelIterator.loadAndScaleRGB(&r, &g, &b);
|
||||
mNeoPixel->setPixelColor(i, r, g, b);
|
||||
pixelIterator.advanceData();
|
||||
}
|
||||
}
|
||||
|
||||
// Output to LEDs
|
||||
mNeoPixel->show();
|
||||
}
|
||||
};
|
||||
|
||||
// Static factory method implementation
|
||||
fl::unique_ptr<IAdafruitNeoPixelDriver> IAdafruitNeoPixelDriver::create() {
|
||||
return fl::make_unique<AdafruitNeoPixelDriverImpl>();
|
||||
}
|
||||
|
||||
} // namespace fl
|
||||
25
libraries/FastLED/src/platforms/adafruit/driver.h
Normal file
25
libraries/FastLED/src/platforms/adafruit/driver.h
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
#include "fl/unique_ptr.h"
|
||||
#include "pixel_iterator.h"
|
||||
|
||||
namespace fl {
|
||||
|
||||
class PixelIterator;
|
||||
|
||||
/// Interface for Adafruit NeoPixel driver - implementation in clockless.cpp
|
||||
class IAdafruitNeoPixelDriver {
|
||||
public:
|
||||
/// Static factory method to create driver implementation
|
||||
static unique_ptr<IAdafruitNeoPixelDriver> create();
|
||||
|
||||
virtual ~IAdafruitNeoPixelDriver() = default;
|
||||
|
||||
/// Initialize the driver with data pin and RGBW mode
|
||||
virtual void init(int dataPin) = 0;
|
||||
|
||||
/// Output pixels to the LED strip
|
||||
virtual void showPixels(PixelIterator& pixelIterator) = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace fl
|
||||
Reference in New Issue
Block a user