FastLED 3.10.8
Loading...
Searching...
No Matches
lpd880x.h
Go to the documentation of this file.
1#pragma once
2
3#include "pixeltypes.h"
5#include "pixel_iterator.h"
6#include "crgb.h"
7#include "eorder.h"
8// IWYU pragma: begin_keep
9#include "platforms/shared/spi_pixel_writer.h" // ok platform headers
10// IWYU pragma: end_keep
11#include "platforms/spi_output_template.h"
12#include "fl/stl/noexcept.h"
13
16
18//
19// LPD8806 controller class - takes data/clock/select pin values (N.B. should take an SPI definition?)
20//
22
28template <int DATA_PIN, fl::u8 CLOCK_PIN, EOrder RGB_ORDER = RGB, fl::u32 SPI_SPEED = DATA_RATE_MHZ(12) >
29class LPD8806Controller : public CPixelLEDController<RGB_ORDER> {
30 typedef fl::SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
31
33 public:
34 // LPD8806 spec wants the high bit of every rgb data byte sent out to be set.
35 FASTLED_FORCE_INLINE static fl::u8 adjust(FASTLED_REGISTER fl::u8 data) FL_NO_EXCEPT { return ((data>>1) | 0x80) + ((data && (data<254)) & 0x01); }
36 FASTLED_FORCE_INLINE static void postBlock(int len, void* context = nullptr) FL_NO_EXCEPT {
37 SPI* pSPI = static_cast<SPI*>(context);
38 pSPI->writeBytesValueRaw(0, ((len*3+63)>>6));
39 }
40
41 };
42
44
45public:
47 #if defined(FL_IS_ESP32)
49 mSPI.setBus(bus);
50 return *this;
51 }
52 #endif
53 virtual void init() FL_NO_EXCEPT {
54 mSPI.init();
55 }
56
57protected:
58
61 fl::writePixelsToSPI<0, LPD8806_ADJUST, RGB_ORDER>(pixels, mSPI, &mSPI);
62 }
63
64public:
68 static constexpr fl::u8 getPaddingByte() FL_NO_EXCEPT { return 0x00; }
69
73 static fl::span<const fl::u8> getPaddingLEDFrame() FL_NO_EXCEPT { // okay static in header
74 static const fl::u8 frame[] = { // okay static in header
75 0x80, // Green = 0 (with MSB=1)
76 0x80, // Red = 0 (with MSB=1)
77 0x80 // Blue = 0 (with MSB=1)
78 };
79 return fl::span<const fl::u8>(frame, 3);
80 }
81
84 static constexpr size_t getPaddingLEDFrameSize() FL_NO_EXCEPT {
85 return 3;
86 }
87
92 static constexpr size_t calculateBytes(size_t num_leds) FL_NO_EXCEPT {
93 // LPD8806 protocol:
94 // - LED data: 3 bytes per LED (GRB with high bit set)
95 // - Latch: ((num_leds * 3 + 63) / 64) bytes of 0x00
96 return (num_leds * 3) + ((num_leds * 3 + 63) / 64);
97 }
98};
99
108template <int DATA_PIN, fl::u8 CLOCK_PIN, EOrder RGB_ORDER = RGB, fl::u32 SPI_SPEED = DATA_RATE_MHZ(12)>
109class LPD6803Controller : public CPixelLEDController<RGB_ORDER> {
110 typedef fl::SPIOutput<DATA_PIN, CLOCK_PIN, SPI_SPEED> SPI;
112
113 void startBoundary() FL_NO_EXCEPT { mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); mSPI.writeByte(0); }
114 void endBoundary(int nLeds) FL_NO_EXCEPT { int nDWords = (nLeds/32); do { mSPI.writeByte(0xFF); mSPI.writeByte(0x00); mSPI.writeByte(0x00); mSPI.writeByte(0x00); } while(nDWords--); }
115
116public:
118 #if defined(FL_IS_ESP32)
120 mSPI.setBus(bus);
121 return *this;
122 }
123 #endif
124
125 virtual void init() FL_NO_EXCEPT {
126 mSPI.init();
127 }
128
129protected:
132 mSPI.select();
133
135 while(pixels.has(1)) {
136 FASTLED_REGISTER fl::u16 command;
137 command = 0x8000;
138 command |= (pixels.loadAndScale0() & 0xF8) << 7; // red is the high 5 bits
139 command |= (pixels.loadAndScale1() & 0xF8) << 2; // green is the middle 5 bits
140 mSPI.writeByte((command >> 8) & 0xFF);
141 command |= pixels.loadAndScale2() >> 3 ; // blue is the low 5 bits
142 mSPI.writeByte(command & 0xFF);
143
144 pixels.stepDithering();
145 pixels.advanceData();
146 }
147 endBoundary(pixels.size());
148 mSPI.endTransaction();
149 }
150
151};
152
CPixelLEDController(RegistrationMode mode) FL_NO_EXCEPT
fl::SPIOutput< DATA_PIN, CLOCK_PIN, SPI_SPEED > SPI
Definition lpd880x.h:110
void startBoundary() FL_NO_EXCEPT
Definition lpd880x.h:113
LPD6803Controller() FL_NO_EXCEPT
Definition lpd880x.h:117
void endBoundary(int nLeds) FL_NO_EXCEPT
Definition lpd880x.h:114
virtual void init() FL_NO_EXCEPT
Initialize the LED controller.
Definition lpd880x.h:125
virtual void showPixels(PixelController< RGB_ORDER > &pixels) FL_NO_EXCEPT
Send the LED data to the strip.
Definition lpd880x.h:131
static FASTLED_FORCE_INLINE fl::u8 adjust(FASTLED_REGISTER fl::u8 data) FL_NO_EXCEPT
Definition lpd880x.h:35
static FASTLED_FORCE_INLINE void postBlock(int len, void *context=nullptr) FL_NO_EXCEPT
Definition lpd880x.h:36
virtual void showPixels(PixelController< RGB_ORDER > &pixels) FL_NO_EXCEPT
Send the LED data to the strip.
Definition lpd880x.h:60
static constexpr fl::u8 getPaddingByte() FL_NO_EXCEPT
Get the protocol-safe padding byte for LPD8806 Used for quad-SPI lane padding when strips have differ...
Definition lpd880x.h:68
LPD8806Controller() FL_NO_EXCEPT
Definition lpd880x.h:46
static constexpr size_t getPaddingLEDFrameSize() FL_NO_EXCEPT
Get the size of the padding LED frame in bytes.
Definition lpd880x.h:84
static fl::span< const fl::u8 > getPaddingLEDFrame() FL_NO_EXCEPT
Get a black LED frame for synchronized latching Used for quad-SPI lane padding to ensure all strips l...
Definition lpd880x.h:73
fl::SPIOutput< DATA_PIN, CLOCK_PIN, SPI_SPEED > SPI
Definition lpd880x.h:30
static constexpr size_t calculateBytes(size_t num_leds) FL_NO_EXCEPT
Calculate total byte count for LPD8806 protocol Used for quad-SPI buffer pre-allocation.
Definition lpd880x.h:92
virtual void init() FL_NO_EXCEPT
Initialize the LED controller.
Definition lpd880x.h:53
CLEDController & setSpiBus(Esp32SpiBus bus) FL_NO_EXCEPT
Select an ESP-IDF SPI host for this clocked controller before init().
fl::CLEDController CLEDController
#define FASTLED_REGISTER
Helper macro to replace the deprecated 'register' keyword if we're using modern C++ where it's been r...
#define FASTLED_FORCE_INLINE
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
#define FL_DISABLE_WARNING_DEPRECATED_REGISTER
unsigned char u8
Definition stdint.h:131
Esp32SpiBus
ESP-IDF SPI host selection for an individual clocked LED controller.
Definition spi_bus.h:18
Includes defintions for RGB and HSV pixels.
#define FL_NO_EXCEPT
Pixel controller class.