Skip to content

Commit bc82af3

Browse files
committed
Adding leds/[] operators on controllers and LEDS.
1 parent 2b9c17b commit bc82af3

File tree

4 files changed

+85
-62
lines changed

4 files changed

+85
-62
lines changed

FastLED.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ CFastLED::CFastLED() {
2121
}
2222

2323
CLEDController &CFastLED::addLeds(CLEDController *pLed,
24-
const struct CRGB *data,
24+
struct CRGB *data,
2525
int nLedsOrOffset, int nLedsIfOffset) {
2626
int nOffset = (nLedsIfOffset > 0) ? nLedsOrOffset : 0;
2727
int nLeds = (nLedsIfOffset > 0) ? nLedsIfOffset : nLedsOrOffset;
@@ -39,6 +39,18 @@ void CFastLED::show(uint8_t scale) {
3939
}
4040
}
4141

42+
CLEDController & CFastLED::operator[](int x) {
43+
CLEDController *pCur = CLEDController::head();
44+
while(x-- && pCur) {
45+
pCur = pCur->next();
46+
}
47+
if(pCur == NULL) {
48+
return *(CLEDController::head());
49+
} else {
50+
return *pCur;
51+
}
52+
}
53+
4254
void CFastLED::showColor(const struct CRGB & color, uint8_t scale) {
4355
CLEDController *pCur = CLEDController::head();
4456
while(pCur) {

FastLED.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class CFastLED {
8181
public:
8282
CFastLED();
8383

84-
static CLEDController &addLeds(CLEDController *pLed, const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0);
84+
static CLEDController &addLeds(CLEDController *pLed, struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0);
8585

8686
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN > static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
8787
switch(CHIPSET) {
@@ -93,7 +93,7 @@ class CFastLED {
9393
}
9494
}
9595

96-
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER > static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
96+
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER > static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
9797
switch(CHIPSET) {
9898
case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
9999
case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
@@ -103,7 +103,7 @@ class CFastLED {
103103
}
104104
}
105105

106-
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER, uint8_t SPI_DATA_RATE > CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
106+
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER, uint8_t SPI_DATA_RATE > CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
107107
switch(CHIPSET) {
108108
case LPD8806: { static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
109109
case WS2801: { static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> c; return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset); }
@@ -114,50 +114,50 @@ class CFastLED {
114114
}
115115

116116
#ifdef SPI_DATA
117-
template<ESPIChipsets CHIPSET> static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
117+
template<ESPIChipsets CHIPSET> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
118118
return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB>(data, nLedsOrOffset, nLedsIfOffset);
119119
}
120120

121-
template<ESPIChipsets CHIPSET, EOrder RGB_ORDER> static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
121+
template<ESPIChipsets CHIPSET, EOrder RGB_ORDER> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
122122
return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER>(data, nLedsOrOffset, nLedsIfOffset);
123123
}
124124

125-
template<ESPIChipsets CHIPSET, EOrder RGB_ORDER, uint8_t SPI_DATA_RATE> static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
125+
template<ESPIChipsets CHIPSET, EOrder RGB_ORDER, uint8_t SPI_DATA_RATE> static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
126126
return addLeds<CHIPSET, SPI_DATA, SPI_CLOCK, RGB_ORDER, SPI_DATA_RATE>(data, nLedsOrOffset, nLedsIfOffset);
127127
}
128128

129129
#endif
130130

131131
template<template<uint8_t DATA_PIN> class CHIPSET, uint8_t DATA_PIN>
132-
static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
132+
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
133133
static CHIPSET<DATA_PIN> c;
134134
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
135135
}
136136

137137
template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER>
138-
static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
138+
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
139139
static CHIPSET<DATA_PIN, RGB_ORDER> c;
140140
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
141141
}
142142

143143
template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN>
144-
static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
144+
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
145145
static CHIPSET<DATA_PIN, RGB> c;
146146
return addLeds(&c, data, nLedsOrOffset, nLedsIfOffset);
147147
}
148148

149149

150150
#ifdef FASTSPI_USE_DMX_SIMPLE
151151
template<EClocklessChipsets CHIPSET, uint8_t DATA_PIN>
152-
static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
152+
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0)
153153
{
154154
switch(CHIPSET) {
155155
case DMX: { static DMXController<DATA_PIN> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
156156
}
157157
}
158158

159159
template<EClocklessChipsets CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER>
160-
static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
160+
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
161161
switch(CHIPSET) {
162162
case DMX: {static DMXController<DATA_PIN, RGB_ORDER> controller; return addLeds(&controller, data, nLedsOrOffset, nLedsIfOffset); }
163163
}
@@ -166,7 +166,7 @@ class CFastLED {
166166

167167
#ifdef HAS_BLOCKLESS
168168
template<EBlockChipsets CHIPSET, int NUM_LANES>
169-
static CLEDController &addLeds(const struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
169+
static CLEDController &addLeds(struct CRGB *data, int nLedsOrOffset, int nLedsIfOffset = 0) {
170170
switch(CHIPSET) {
171171
case WS2811_PORTC: return addLeds(new BlockClocklessController<NUM_LANES, NS(350), NS(350), NS(550)>(), data, nLedsOrOffset, nLedsIfOffset);
172172
}
@@ -200,6 +200,12 @@ class CFastLED {
200200
// nFrames calls, it will print a summary of FPS info out to the serial port.
201201
// If the serial port isn't opened, this function does nothing.
202202
void countFPS(int nFrames=100);
203+
204+
CLEDController & operator[](int x);
205+
206+
int size() { return (*this)[0].size(); }
207+
208+
CRGB *leds() { return (*this)[0].leds(); }
203209
};
204210

205211
extern CFastLED & FastSPI_LED;

controller.h

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#define RO(X) RGB_BYTE(RGB_ORDER, X)
99
#define RGB_BYTE(RO,X) (((RO)>>(3*(2-(X)))) & 0x3)
1010

11-
#define RGB_BYTE0(RO) ((RO>>6) & 0x3)
12-
#define RGB_BYTE1(RO) ((RO>>3) & 0x3)
11+
#define RGB_BYTE0(RO) ((RO>>6) & 0x3)
12+
#define RGB_BYTE1(RO) ((RO>>3) & 0x3)
1313
#define RGB_BYTE2(RO) ((RO) & 0x3)
1414

1515
// operator byte *(struct CRGB[] arr) { return (byte*)arr; }
@@ -19,20 +19,20 @@
1919
typedef uint8_t EDitherMode;
2020

2121
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22-
//
22+
//
2323
// LED Controller interface definition
2424
//
2525
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2626

27-
/// Base definition for an LED controller. Pretty much the methods that every LED controller object will make available.
27+
/// Base definition for an LED controller. Pretty much the methods that every LED controller object will make available.
2828
/// Note that the showARGB method is not impelemented for all controllers yet. Note also the methods for eventual checking
2929
/// of background writing of data (I'm looking at you, teensy 3.0 DMA controller!). If you want to pass LED controllers around
3030
/// to methods, make them references to this type, keeps your code saner. However, most people won't be seeing/using these objects
3131
/// directly at all
32-
class CLEDController {
32+
class CLEDController {
3333
protected:
3434
friend class CFastLED;
35-
const CRGB *m_Data;
35+
CRGB *m_Data;
3636
CLEDController *m_pNext;
3737
CRGB m_ColorCorrection;
3838
CRGB m_ColorTemperature;
@@ -44,7 +44,7 @@ class CLEDController {
4444
// set all the leds on the controller to a given color
4545
virtual void showColor(const struct CRGB & data, int nLeds, CRGB scale) = 0;
4646

47-
// note that the uint8_ts will be in the order that you want them sent out to the device.
47+
// note that the uint8_ts will be in the order that you want them sent out to the device.
4848
// nLeds is the number of RGB leds being written to
4949
virtual void show(const struct CRGB *data, int nLeds, CRGB scale) = 0;
5050

@@ -77,11 +77,11 @@ class CLEDController {
7777
}
7878

7979
// show function using the "attached to this controller" led data
80-
void showLeds(uint8_t brightness=255) {
80+
void showLeds(uint8_t brightness=255) {
8181
show(m_Data, m_nLeds, getAdjustment(brightness));
8282
}
8383

84-
void showColor(const struct CRGB & data, uint8_t brightness=255) {
84+
void showColor(const struct CRGB & data, uint8_t brightness=255) {
8585
showColor(data, m_nLeds, getAdjustment(brightness));
8686
}
8787

@@ -95,19 +95,28 @@ class CLEDController {
9595
show(data, nLeds, getAdjustment(brightness))
9696
}
9797
#endif
98-
99-
CLEDController & setLeds(const CRGB *data, int nLeds) {
98+
99+
CLEDController & setLeds(CRGB *data, int nLeds) {
100100
m_Data = data;
101101
m_nLeds = nLeds;
102102
return *this;
103103
}
104104

105105
void clearLedData() {
106-
if(m_Data) {
106+
if(m_Data) {
107107
memset8((void*)m_Data, 0, sizeof(struct CRGB) * m_nLeds);
108108
}
109109
}
110110

111+
// How many leds does this controller manage?
112+
int size() { return m_nLeds; }
113+
114+
// Pointer to the CRGB array for this controller
115+
CRGB* leds() { return m_Data; }
116+
117+
// Reference to the n'th item in the controller
118+
CRGB &operator[](int x) { return m_Data[x]; }
119+
111120
inline CLEDController & setDither(uint8_t ditherMode = BINARY_DITHER) { m_DitherMode = ditherMode; return *this; }
112121
inline uint8_t getDither() { return m_DitherMode; }
113122

@@ -119,17 +128,17 @@ class CLEDController {
119128
CLEDController & setTemperature(ColorTemperature temperature) { m_ColorTemperature = temperature; return *this; }
120129
CRGB getTemperature() { return m_ColorTemperature; }
121130

122-
CRGB getAdjustment(uint8_t scale) {
131+
CRGB getAdjustment(uint8_t scale) {
123132
#if defined(NO_CORRECTION) && (NO_CORRECTION==1)
124133
return CRGB(scale,scale,scale);
125134
#else
126135
CRGB adj(0,0,0);
127136

128-
if(scale > 0) {
129-
for(uint8_t i = 0; i < 3; i++) {
137+
if(scale > 0) {
138+
for(uint8_t i = 0; i < 3; i++) {
130139
uint8_t cc = m_ColorCorrection.raw[i];
131140
uint8_t ct = m_ColorTemperature.raw[i];
132-
if(cc > 0 && ct > 0) {
141+
if(cc > 0 && ct > 0) {
133142
uint32_t work = (((uint32_t)cc)+1) * (((uint32_t)ct)+1) * scale;
134143
work /= 0x10000L;
135144
adj.raw[i] = work & 0xFF;
@@ -143,11 +152,11 @@ class CLEDController {
143152
};
144153

145154
// Pixel controller class. This is the class that we use to centralize pixel access in a block of data, including
146-
// support for things like RGB reordering, scaling, dithering, skipping (for ARGB data), and eventually, we will
155+
// support for things like RGB reordering, scaling, dithering, skipping (for ARGB data), and eventually, we will
147156
// centralize 8/12/16 conversions here as well.
148157
template<EOrder RGB_ORDER>
149158
struct PixelController {
150-
const uint8_t *mData;
159+
const uint8_t *mData;
151160
int mLen;
152161
uint8_t d[3];
153162
uint8_t e[3];
@@ -186,7 +195,7 @@ struct PixelController {
186195
#ifdef SUPPORT_ARGB
187196
PixelController(const CARGB &d, int len, CRGB & s, EDitherMode dither = BINARY_DITHER) : mData((const uint8_t*)&d), mLen(len), mScale(s) {
188197
enable_dithering(dither);
189-
// skip the A in CARGB
198+
// skip the A in CARGB
190199
mData += 1;
191200
mAdvance = 0;
192201
}
@@ -195,7 +204,7 @@ struct PixelController {
195204
enable_dithering(dither);
196205
// skip the A in CARGB
197206
mData += 1;
198-
mAdvance = 4;
207+
mAdvance = 4;
199208
}
200209
#endif
201210

@@ -239,7 +248,7 @@ struct PixelController {
239248
// It's initialized to the reversed bits of R.
240249
// If 'ditherBits' is 2, Q here will cycle through (0,128,64,192)
241250
byte Q = 0;
242-
251+
243252
// Reverse bits in a byte
244253
{
245254
if(R & 0x01) { Q |= 0x80; }
@@ -251,21 +260,21 @@ struct PixelController {
251260
if(R & 0x40) { Q |= 0x02; }
252261
if(R & 0x80) { Q |= 0x01; }
253262
}
254-
263+
255264
// Now we adjust Q to fall in the center of each range,
256265
// instead of at the start of the range.
257266
// If ditherBits is 2, Q will be (0, 128, 64, 192) at first,
258267
// and this adjustment makes it (31, 159, 95, 223).
259268
if( ditherBits < 8) {
260269
Q += 0x01 << (7 - ditherBits);
261270
}
262-
271+
263272
// D and E form the "scaled dither signal"
264273
// which is added to pixel values to affect the
265274
// actual dithering.
266-
275+
267276
// Setup the initial D and E values
268-
for(int i = 0; i < 3; i++) {
277+
for(int i = 0; i < 3; i++) {
269278
byte s = mScale.raw[i];
270279
e[i] = s ? (256/s) + 1 : 0;
271280
d[i] = scale8(Q, e[i]);
@@ -275,10 +284,10 @@ struct PixelController {
275284
}
276285

277286
// Do we have n pixels left to process?
278-
__attribute__((always_inline)) inline bool has(int n) {
287+
__attribute__((always_inline)) inline bool has(int n) {
279288
return mLen >= n;
280289
}
281-
290+
282291
// toggle dithering enable
283292
void enable_dithering(EDitherMode dither) {
284293
switch(dither) {
@@ -287,23 +296,23 @@ struct PixelController {
287296
}
288297
}
289298

290-
// get the amount to advance the pointer by
299+
// get the amount to advance the pointer by
291300
__attribute__((always_inline)) inline int advanceBy() { return mAdvance; }
292-
301+
293302
// advance the data pointer forward, adjust position counter
294303
__attribute__((always_inline)) inline void advanceData() { mData += mAdvance; mLen--;}
295304

296-
// step the dithering forward
305+
// step the dithering forward
297306
__attribute__((always_inline)) inline void stepDithering() {
298-
// IF UPDATING HERE, BE SURE TO UPDATE THE ASM VERSION IN
307+
// IF UPDATING HERE, BE SURE TO UPDATE THE ASM VERSION IN
299308
// clockless_trinket.h!
300309
d[0] = e[0] - d[0];
301310
d[1] = e[1] - d[1];
302311
d[2] = e[2] - d[2];
303312
}
304313

305314
// Some chipsets pre-cycle the first byte, which means we want to cycle byte 0's dithering separately
306-
__attribute__((always_inline)) inline void preStepFirstByteDithering() {
315+
__attribute__((always_inline)) inline void preStepFirstByteDithering() {
307316
d[RO(0)] = e[RO(0)] - d[RO(0)];
308317
}
309318

@@ -316,11 +325,11 @@ struct PixelController {
316325
template<int SLOT> __attribute__((always_inline)) inline static uint8_t advanceAndLoadAndScale(PixelController & pc) { pc.advanceData(); return pc.loadAndScale<SLOT>(pc); }
317326

318327
// Helper functions to get around gcc stupidities
319-
__attribute__((always_inline)) inline uint8_t loadAndScale0() { return loadAndScale<0>(*this); }
320-
__attribute__((always_inline)) inline uint8_t loadAndScale1() { return loadAndScale<1>(*this); }
321-
__attribute__((always_inline)) inline uint8_t loadAndScale2() { return loadAndScale<2>(*this); }
322-
__attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0() { return advanceAndLoadAndScale<0>(*this); }
323-
__attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0() { stepDithering(); return advanceAndLoadAndScale<0>(*this); }
328+
__attribute__((always_inline)) inline uint8_t loadAndScale0() { return loadAndScale<0>(*this); }
329+
__attribute__((always_inline)) inline uint8_t loadAndScale1() { return loadAndScale<1>(*this); }
330+
__attribute__((always_inline)) inline uint8_t loadAndScale2() { return loadAndScale<2>(*this); }
331+
__attribute__((always_inline)) inline uint8_t advanceAndLoadAndScale0() { return advanceAndLoadAndScale<0>(*this); }
332+
__attribute__((always_inline)) inline uint8_t stepAdvanceAndLoadAndScale0() { stepDithering(); return advanceAndLoadAndScale<0>(*this); }
324333
};
325334

326-
#endif
335+
#endif

0 commit comments

Comments
 (0)