1#ifndef __INC_CONTROLLER_H
2#define __INC_CONTROLLER_H
13FASTLED_NAMESPACE_BEGIN
21#define RO(X) RGB_BYTE(RGB_ORDER, X)
29#define RGB_BYTE(RO,X) (((RO)>>(3*(2-(X)))) & 0x3)
33#define RGB_BYTE0(RO) ((RO>>6) & 0x3)
36#define RGB_BYTE1(RO) ((RO>>3) & 0x3)
39#define RGB_BYTE2(RO) ((RO) & 0x3)
44#define DISABLE_DITHER 0x00
46#define BINARY_DITHER 0x01
83 virtual void show(
const struct CRGB *data,
int nLeds,
CRGB scale) = 0;
108 void show(
const struct CRGB *data,
int nLeds, uint8_t brightness) {
226 #if defined(NO_CORRECTION) && (NO_CORRECTION==1)
227 return CRGB(scale,scale,scale);
232 for(uint8_t i = 0; i < 3; ++i) {
233 uint8_t cc = colorCorrection.
raw[i];
234 uint8_t ct = colorTemperature.
raw[i];
235 if(cc > 0 && ct > 0) {
236 uint32_t work = (((uint32_t)cc)+1) * (((uint32_t)ct)+1) * scale;
238 adj.
raw[i] = work & 0xFF;
258template<EOrder RGB_ORDER,
int LANES=1, u
int32_t MASK=0xFFFFFFFF>
289 for(
int i = 0; i < LANES; ++i) {
291 if((1<<i) & MASK) { nOffset += (len *
mAdvance); }
332#if !defined(NO_DITHERING) || (NO_DITHERING != 1)
335#define MAX_LIKELY_UPDATE_RATE_HZ 400
338#define MIN_ACCEPTABLE_DITHER_RATE_HZ 50
341#define UPDATES_PER_FULL_DITHER_CYCLE (MAX_LIKELY_UPDATE_RATE_HZ / MIN_ACCEPTABLE_DITHER_RATE_HZ)
356#define RECOMMENDED_VIRTUAL_BITS ((UPDATES_PER_FULL_DITHER_CYCLE>1) + \
357 (UPDATES_PER_FULL_DITHER_CYCLE>2) + \
358 (UPDATES_PER_FULL_DITHER_CYCLE>4) + \
359 (UPDATES_PER_FULL_DITHER_CYCLE>8) + \
360 (UPDATES_PER_FULL_DITHER_CYCLE>16) + \
361 (UPDATES_PER_FULL_DITHER_CYCLE>32) + \
362 (UPDATES_PER_FULL_DITHER_CYCLE>64) + \
363 (UPDATES_PER_FULL_DITHER_CYCLE>128) )
366#define VIRTUAL_BITS RECOMMENDED_VIRTUAL_BITS
373#if !defined(NO_DITHERING) || (NO_DITHERING != 1)
375 static uint8_t R = 0;
381 R &= (0x01 << ditherBits) - 1;
390 if(R & 0x01) { Q |= 0x80; }
391 if(R & 0x02) { Q |= 0x40; }
392 if(R & 0x04) { Q |= 0x20; }
393 if(R & 0x08) { Q |= 0x10; }
394 if(R & 0x10) { Q |= 0x08; }
395 if(R & 0x20) { Q |= 0x04; }
396 if(R & 0x40) { Q |= 0x02; }
397 if(R & 0x80) { Q |= 0x01; }
404 if( ditherBits < 8) {
405 Q += 0x01 << (7 - ditherBits);
413 for(
int i = 0; i < 3; ++i) {
415 e[i] = s ? (256/s) + 1 : 0;
417#if (FASTLED_SCALE8_FIXED == 1)
428 __attribute__((always_inline))
inline bool has(
int n) {
440 default:
d[0]=
d[1]=
d[2]=
e[0]=
e[1]=
e[2]=0;
break;
446 __attribute__((always_inline))
inline int size() {
return mLen; }
450 __attribute__((always_inline))
inline int lanes() {
return LANES; }
493 template<
int SLOT> __attribute__((always_inline))
inline static uint8_t
dither(
PixelController & pc, uint8_t b) {
return b ?
qadd8(b, pc.
d[
RO(SLOT)]) : 0; }
498 template<
int SLOT> __attribute__((always_inline))
inline static uint8_t
dither(
PixelController & , uint8_t b, uint8_t
d) {
return b ?
qadd8(b,
d) : 0; }
510 template<
int SLOT> __attribute__((always_inline))
inline static uint8_t
scale(
PixelController & , uint8_t b, uint8_t scale) {
return scale8(b, scale); }
574 template<
int SLOT> __attribute__((always_inline))
inline static uint8_t
getd(
PixelController & pc) {
return pc.
d[
RO(SLOT)]; }
589 __attribute__((always_inline))
inline uint8_t
loadAndScale0(
int lane, uint8_t scale) {
return loadAndScale<0>(*
this, lane, scale); }
590 __attribute__((always_inline))
inline uint8_t
loadAndScale1(
int lane, uint8_t scale) {
return loadAndScale<1>(*
this, lane, scale); }
591 __attribute__((always_inline))
inline uint8_t
loadAndScale2(
int lane, uint8_t scale) {
return loadAndScale<2>(*
this, lane, scale); }
592 __attribute__((always_inline))
inline uint8_t
advanceAndLoadAndScale0(
int lane, uint8_t scale) {
return advanceAndLoadAndScale<0>(*
this, lane, scale); }
595 __attribute__((always_inline))
inline uint8_t
loadAndScale0(
int lane) {
return loadAndScale<0>(*
this, lane); }
596 __attribute__((always_inline))
inline uint8_t
loadAndScale1(
int lane) {
return loadAndScale<1>(*
this, lane); }
597 __attribute__((always_inline))
inline uint8_t
loadAndScale2(
int lane) {
return loadAndScale<2>(*
this, lane); }
598 __attribute__((always_inline))
inline uint8_t
advanceAndLoadAndScale0(
int lane) {
return advanceAndLoadAndScale<0>(*
this, lane); }
601 __attribute__((always_inline))
inline uint8_t
loadAndScale0() {
return loadAndScale<0>(*
this); }
602 __attribute__((always_inline))
inline uint8_t
loadAndScale1() {
return loadAndScale<1>(*
this); }
603 __attribute__((always_inline))
inline uint8_t
loadAndScale2() {
return loadAndScale<2>(*
this); }
607 __attribute__((always_inline))
inline uint8_t
getScale0() {
return getscale<0>(*
this); }
608 __attribute__((always_inline))
inline uint8_t
getScale1() {
return getscale<1>(*
this); }
609 __attribute__((always_inline))
inline uint8_t
getScale2() {
return getscale<2>(*
this); }
central include file for FastLED, defines the CFastLED class/object
High level controller interface for FastLED.
Base definition for an LED controller.
virtual void showColor(const struct CRGB &data, int nLeds, CRGB scale)=0
Set all the LEDs to a given color.
CLEDController & setTemperature(ColorTemperature temperature)
Set the color temperature, aka white point, for this controller.
CRGB getCorrection()
Get the correction value used by this controller.
CLEDController * next()
Get the next controller in the linked list after this one.
void showColor(const struct CRGB &data, int nLeds, uint8_t brightness)
Set all the LEDs to a given color.
CLEDController & setDither(uint8_t ditherMode=BINARY_DITHER)
Set the dithering mode for this controller to use.
virtual int lanes()
How many Lanes does this controller manage?
static CRGB computeAdjustment(uint8_t scale, const CRGB &colorCorrection, const CRGB &colorTemperature)
Calculates the combined color adjustment to the LEDs at a given scale, color correction,...
virtual uint16_t getMaxRefreshRate() const
Gets the maximum possible refresh rate of the strip.
CRGB * m_Data
pointer to the LED data used by this controller
CRGB & operator[](int x)
Reference to the n'th LED managed by the controller.
void showColor(const struct CRGB &data, uint8_t brightness=255)
Set all the LEDs to a given color.
CRGB m_ColorCorrection
CRGB object representing the color correction to apply to the strip on show()
virtual int size()
How many LEDs does this controller manage?
uint8_t getDither()
Get the dithering option currently set for this controller.
CLEDController & setLeds(CRGB *data, int nLeds)
Set the default array of LEDs to be used by this controller.
void clearLedData()
Zero out the LED data managed by this controller.
CLEDController & setCorrection(CRGB correction)
The color corrction to use for this controller, expressed as a CRGB object.
static CLEDController * head()
Get the first LED controller in the linked list of controllers.
CLEDController()
Create an led controller object, add it to the chain of controllers.
EDitherMode m_DitherMode
the current dither mode of the controller
CLEDController & setTemperature(CRGB temperature)
Set the color temperature, aka white point, for this controller.
void showLeds(uint8_t brightness=255)
Write the data to the LEDs managed by this controller.
CRGB * leds()
Pointer to the CRGB array for this controller.
CLEDController * m_pNext
pointer to the next LED controller in the linked list
int m_nLeds
the number of LEDs in the LED data array
static CLEDController * m_pTail
pointer to the last LED controller in the linked list
virtual void clearLeds(int nLeds)
Clear out/zero out the given number of LEDs.
void show(const struct CRGB *data, int nLeds, uint8_t brightness)
Write the passed in RGB data out to the LEDs managed by this controller.
CLEDController & setCorrection(LEDColorCorrection correction)
The color corrction to use for this controller, expressed as a CRGB object.
CRGB m_ColorTemperature
CRGB object representing the color temperature to apply to the strip on show()
virtual void show(const struct CRGB *data, int nLeds, CRGB scale)=0
Write the passed in RGB data out to the LEDs managed by this controller.
CRGB getAdjustment(uint8_t scale)
Get the combined brightness/color adjustment for this controller.
virtual void init()=0
Initialize the LED controller.
static CLEDController * m_pHead
pointer to the first LED controller in the linked list
CRGB getTemperature()
Get the color temperature, aka whipe point, for this controller.
Template extension of the CLEDController class.
virtual void showPixels(PixelController< RGB_ORDER, LANES, MASK > &pixels)=0
Send the LED data to the strip.
int lanes()
Get the number of lanes of the Controller.
virtual void show(const struct CRGB *data, int nLeds, CRGB scale)
Write the passed in RGB data out to the LEDs managed by this controller.
virtual void showColor(const struct CRGB &data, int nLeds, CRGB scale)
Set all the LEDs on the controller to a given color.
Contains definitions for color correction and temperature.
#define VIRTUAL_BITS
Alias for RECOMMENDED_VIRTUAL_BITS.
uint8_t EDitherMode
The dither setting, either DISABLE_DITHER or BINARY_DITHER.
#define BINARY_DITHER
Enable dithering using binary dithering (only option)
#define RO(X)
Gets the assigned color channel for a byte's position in the output, using the color order (EOrder) t...
ColorTemperature
Color temperature values.
LEDColorCorrection
Color correction starting points.
@ UncorrectedTemperature
Uncorrected temperature (0xFFFFFF)
@ UncorrectedColor
Uncorrected color (0xFFFFFF)
void * memset8(void *ptr, uint8_t value, uint16_t num)
Faster alternative to memset() on AVR.
LIB8STATIC_ALWAYS_INLINE uint8_t qadd8(uint8_t i, uint8_t j)
Add one byte to another, saturating at 0xFF.
LIB8STATIC_ALWAYS_INLINE uint8_t scale8(uint8_t i, fract8 scale)
Scale one byte by a second one, which is treated as the numerator of a fraction whose denominator is ...
Determines which platform system definitions to include.
Definitions for pixel color data structs.
Representation of an RGB pixel (Red, Green, Blue)
uint8_t raw[3]
Access the red, green, and blue data as an array.
int8_t mAdvance
how many bytes to advance the pointer by each time. For CRGB this is 3.
uint8_t getScale1()
non-template alias of getscale<1>()
uint8_t stepAdvanceAndLoadAndScale0(int lane, uint8_t scale)
stepDithering() and advanceAndLoadAndScale0()
uint8_t loadAndScale0()
non-template alias of loadAndScale<0>()
static uint8_t dither(PixelController &pc, uint8_t b)
Calculate a dither value using the per-channel dither data.
uint8_t stepAdvanceAndLoadAndScale0(int lane)
stepDithering() and advanceAndLoadAndScale0()
void init_binary_dithering()
Set up the values for binary dithering.
int mLenRemaining
counter for the number of LEDs left to process
void stepDithering()
Step the dithering forward.
uint8_t loadAndScale0(int lane, uint8_t scale)
non-template alias of loadAndScale<0>()
void initOffsets(int len)
Initialize the PixelController::mOffsets array based on the length of the strip.
static uint8_t advanceAndLoadAndScale(PixelController &pc)
A version of loadAndScale() that advances the output data pointer.
static uint8_t getscale(PixelController &pc)
Gets the scale data for the provided output slot.
static uint8_t scale(PixelController &, uint8_t b, uint8_t scale)
Scale a value.
void preStepFirstByteDithering()
Some chipsets pre-cycle the first byte, which means we want to cycle byte 0's dithering separately.
const uint8_t * mData
pointer to the underlying LED data
PixelController(const CRGB *d, int len, CRGB &s, EDitherMode dither=BINARY_DITHER)
Constructor.
uint8_t d[3]
values for the scaled dither signal
int mOffsets[LANES]
the number of bytes to offset each lane from the starting pointer
void advanceData()
Advance the data pointer forward, adjust position counter.
int size()
Get the length of the LED strip.
static uint8_t loadAndScale(PixelController &pc, int lane, uint8_t d, uint8_t scale)
Loads, dithers, and scales a single byte for a given output slot and lane.
uint8_t loadAndScale1(int lane, uint8_t scale)
non-template alias of loadAndScale<1>()
int mLen
number of LEDs in the data for one lane
uint8_t getScale0()
non-template alias of getscale<0>()
static uint8_t dither(PixelController &, uint8_t b, uint8_t d)
Calculate a dither value.
static uint8_t advanceAndLoadAndScale(PixelController &pc, int lane)
A version of loadAndScale() that advances the output data pointer.
static uint8_t loadAndScale(PixelController &pc, int lane, uint8_t scale)
Loads and scales a single byte for a given output slot and lane.
PixelController(const CRGB &d, int len, CRGB &s, EDitherMode dither=BINARY_DITHER)
Constructor.
PixelController(const uint8_t *d, int len, CRGB &s, EDitherMode dither=BINARY_DITHER, bool advance=true, uint8_t skip=0)
Constructor.
static uint8_t loadAndScale(PixelController &pc)
Loads, dithers, and scales a single byte for a given output slot, using class dither and scale values...
uint8_t stepAdvanceAndLoadAndScale0()
stepDithering() and advanceAndLoadAndScale0()
uint8_t e[3]
values for the scaled dither signal
CRGB mScale
the per-channel scale values, provided by a color correction function such as CLEDController::compute...
void enable_dithering(EDitherMode dither)
Toggle dithering enable If dithering is set to enabled, this will re-init the dithering values (init_...
uint8_t advanceAndLoadAndScale0(int lane)
non-template alias of advanceAndLoadAndScale<0>()
int lanes()
Get the number of lanes of the Controller.
uint8_t loadAndScale1()
non-template alias of loadAndScale<1>()
static uint8_t scale(PixelController &pc, uint8_t b)
Scale a value using the per-channel scale data.
uint8_t loadAndScale2(int lane, uint8_t scale)
non-template alias of loadAndScale<2>()
int advanceBy()
Get the amount to advance the pointer by.
uint8_t loadAndScale0(int lane)
non-template alias of loadAndScale<0>()
uint8_t loadAndScale1(int lane)
non-template alias of loadAndScale<1>()
static uint8_t loadByte(PixelController &pc, int lane)
Read a byte of LED data for parallel output.
uint8_t loadAndScale2()
non-template alias of loadAndScale<2>()
uint8_t advanceAndLoadAndScale0()
non-template alias of advanceAndLoadAndScale<0>()
static uint8_t getd(PixelController &pc)
Gets the dithering data for the provided output slot.
static uint8_t loadAndScale(PixelController &pc, int lane)
Loads, dithers, and scales a single byte for a given output slot and lane, using class dither and sca...
uint8_t getScale2()
non-template alias of getscale<2>()
PixelController(const PixelController &other)
Copy constructor.
bool has(int n)
Do we have n pixels left to process?
uint8_t advanceAndLoadAndScale0(int lane, uint8_t scale)
non-template alias of advanceAndLoadAndScale<0>()
static uint8_t advanceAndLoadAndScale(PixelController &pc, int lane, uint8_t scale)
A version of loadAndScale() that advances the output data pointer without dithering.
static uint8_t loadByte(PixelController &pc)
Read a byte of LED data.
uint8_t loadAndScale2(int lane)
non-template alias of loadAndScale<2>()