-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFastLED_RGBW.h
159 lines (140 loc) · 3.55 KB
/
FastLED_RGBW.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* FastLED_RGBW
*
* Hack to enable SK6812 RGBW strips to work with FastLED.
*
* Original code by Jim Bumgardner (http://krazydad.com).
* Modified by David Madison (http://partsnotincluded.com).
* Extended by Christoph Wempe
*
*/
#ifndef FastLED_RGBW_h
#define FastLED_RGBW_h
/// scale four one byte values by a fith one, which is treated as
/// the numerator of a fraction whose demominator is 256
/// In other words, it computes r,g,b,w * (scale / 256)
///
/// THIS FUNCTION ALWAYS MODIFIES ITS ARGUMENTS IN PLACE
LIB8STATIC void nscale8x4( uint8_t& r, uint8_t& g, uint8_t& b, uint8_t& w, fract8 scale)
{
#if SCALE8_C == 1
#if (FASTLED_SCALE8_FIXED == 1)
uint16_t scale_fixed = scale + 1;
r = (((uint16_t)r) * scale_fixed) >> 8;
g = (((uint16_t)g) * scale_fixed) >> 8;
b = (((uint16_t)b) * scale_fixed) >> 8;
w = (((uint16_t)w) * scale_fixed) >> 8;
#else
r = ((int)r * (int)(scale) ) >> 8;
g = ((int)g * (int)(scale) ) >> 8;
b = ((int)b * (int)(scale) ) >> 8;
w = ((int)w * (int)(scale) ) >> 8;
#endif
#elif SCALE8_AVRASM == 1
r = scale8_LEAVING_R1_DIRTY(r, scale);
g = scale8_LEAVING_R1_DIRTY(g, scale);
b = scale8_LEAVING_R1_DIRTY(b, scale);
w = scale8_LEAVING_R1_DIRTY(w, scale);
cleanup_R1();
#else
#error "No implementation for nscale8x3 available."
#endif
}
struct CRGBW {
union {
struct {
union {
uint8_t g;
uint8_t green;
};
union {
uint8_t r;
uint8_t red;
};
union {
uint8_t b;
uint8_t blue;
};
union {
uint8_t w;
uint8_t white;
};
};
uint8_t raw[4];
};
CRGBW(){}
CRGBW(uint8_t rd, uint8_t grn, uint8_t blu, uint8_t wht){
r = rd;
g = grn;
b = blu;
w = wht;
}
inline void operator = (const CRGB c) __attribute__((always_inline)){
this->r = c.r;
this->g = c.g;
this->b = c.b;
this->white = 0;
}
/// add one RGBW to another, saturating at 0xFF for each channel
inline CRGBW& operator+= (const CRGB& rhs )
{
r = qadd8( r, rhs.r);
g = qadd8( g, rhs.g);
b = qadd8( b, rhs.b);
w = 0;
return *this;
}
/// scale down a RGBW to N 256ths of it's current brightness, using
/// 'plain math' dimming rules, which means that if the low light levels
/// may dim all the way to 100% black.
inline CRGBW& nscale8 (uint8_t scaledown )
{
nscale8x4( r, g, b, w, scaledown);
return *this;
}
/// scale down a RGBW to N 256ths of it's current brightness, using
/// 'plain math' dimming rules, which means that if the low light levels
/// may dim all the way to 100% black.
inline CRGBW& nscale8 (const CRGBW & scaledown )
{
r = ::scale8(r, scaledown.r);
g = ::scale8(g, scaledown.g);
b = ::scale8(b, scaledown.b);
w = 0;
return *this;
}
};
inline uint16_t getRGBWsize(uint16_t nleds){
uint16_t nbytes = nleds * 4;
if(nbytes % 3 > 0) return nbytes / 3 + 1;
else return nbytes / 3;
}
void fill_solid( struct CRGBW * leds, int numToFill, CRGB color)
{
for( int i = 0; i < numToFill; i++) {
leds[i] = color;
}
}
void nscale8( CRGBW* leds, uint16_t num_leds, uint8_t scale)
{
for( uint16_t i = 0; i < num_leds; i++) {
leds[i].nscale8( scale);
}
}
void fadeToBlackBy( CRGBW* leds, uint16_t num_leds, uint8_t fadeBy)
{
nscale8( leds, num_leds, 255 - fadeBy);
}
void fill_rainbow( struct CRGBW * pFirstLED, int numToFill,
uint8_t initialhue,
uint8_t deltahue )
{
CHSV hsv;
hsv.hue = initialhue;
hsv.val = 255;
hsv.sat = 240;
for( int i = 0; i < numToFill; i++) {
pFirstLED[i] = hsv;
hsv.hue += deltahue;
}
}
#endif