Skip to content

Commit 232fe73

Browse files
authored
version 2.0.0
1 parent d73d545 commit 232fe73

File tree

3 files changed

+424
-0
lines changed

3 files changed

+424
-0
lines changed

ws281x.c

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
2+
#include "ws281x.h"
3+
#include "ws281x_conf.h"
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#if WS281X_FREERTOS == 1
7+
#include "cmsis_os.h"
8+
#define ws281x_delay(x) osDelay(x)
9+
#else
10+
#define ws281x_delay(x) HAL_Delay(x)
11+
#endif
12+
//###########################################################################################################
13+
bool ws281x_init(ws281x_t *ws281x, SPI_HandleTypeDef *spi_handle, uint16_t max_pixel, ws281x_order_t ws281x_order)
14+
{
15+
ws281x->spi_handle = spi_handle;
16+
#if WS281X_FREERTOS == 0
17+
ws281x->pixels = malloc(max_pixel * 3);
18+
ws281x->buffer = malloc(max_pixel * 32);
19+
#else
20+
ws281x->pixels = pvPortMalloc(max_pixel * 3);
21+
ws281x->buffer = pvPortMalloc(max_pixel * 32);
22+
#endif
23+
if (ws281x->pixels != NULL && ws281x->buffer != NULL)
24+
{
25+
ws281x->max_pixel = max_pixel;
26+
ws281x->order = ws281x_order;
27+
memset(ws281x->pixels, 0, max_pixel * 3);
28+
memset(ws281x->buffer, 0, max_pixel * 32);
29+
ws281x_update(ws281x);
30+
return true;
31+
}
32+
else
33+
{
34+
#if WS281X_FREERTOS == 0
35+
if (ws281x->pixels != NULL)
36+
free(ws281x->pixels);
37+
if (ws281x->buffer != NULL)
38+
free(ws281x->buffer);
39+
#else
40+
if (ws281x->pixels != NULL)
41+
vPortFree(ws281x->pixels);
42+
if (ws281x->buffer != NULL)
43+
vPortFree(ws281x->buffer);
44+
#endif
45+
46+
return false;
47+
}
48+
}
49+
//###########################################################################################################
50+
bool ws281x_update(ws281x_t *ws281x)
51+
{
52+
int buff_cnt = 0;
53+
/* reset buffer */
54+
memset(ws281x->buffer, 0, ws281x->max_pixel * 32);
55+
switch (ws281x->order)
56+
{
57+
/* order RGB BEGIN */
58+
case ws281x_order_rgb:
59+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
60+
{
61+
for (int i = 7; i >= 0; i-=2)
62+
{
63+
if (ws281x->pixels[pixel].r & (1 << i))
64+
ws281x->buffer[buff_cnt] |= 0xC0;
65+
else
66+
ws281x->buffer[buff_cnt] |= 0x80;
67+
if (ws281x->pixels[pixel].r & (1 << (i - 1)))
68+
ws281x->buffer[buff_cnt] |= 0x0C;
69+
else
70+
ws281x->buffer[buff_cnt] |= 0x08;
71+
buff_cnt++;
72+
}
73+
for (int i = 7; i >= 0; i-=2)
74+
{
75+
if (ws281x->pixels[pixel].g & (1 << i))
76+
ws281x->buffer[buff_cnt] |= 0xC0;
77+
else
78+
ws281x->buffer[buff_cnt] |= 0x80;
79+
if (ws281x->pixels[pixel].g & (1 << (i - 1)))
80+
ws281x->buffer[buff_cnt] |= 0x0C;
81+
else
82+
ws281x->buffer[buff_cnt] |= 0x08;
83+
buff_cnt++;
84+
}
85+
for (int i = 7; i >= 0; i-=2)
86+
{
87+
if (ws281x->pixels[pixel].b & (1 << i))
88+
ws281x->buffer[buff_cnt] |= 0xC0;
89+
else
90+
ws281x->buffer[buff_cnt] |= 0x80;
91+
if (ws281x->pixels[pixel].b & (1 << (i - 1)))
92+
ws281x->buffer[buff_cnt] |= 0x0C;
93+
else
94+
ws281x->buffer[buff_cnt] |= 0x08;
95+
buff_cnt++;
96+
}
97+
}
98+
break;
99+
/* order RGB END */
100+
101+
/* order GRB BEGIN */
102+
case ws281x_order_grb:
103+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
104+
{
105+
for (int i = 7; i >= 0; i-=2)
106+
{
107+
if (ws281x->pixels[pixel].g & (1 << i))
108+
ws281x->buffer[buff_cnt] |= 0xC0;
109+
else
110+
ws281x->buffer[buff_cnt] |= 0x80;
111+
if (ws281x->pixels[pixel].g & (1 << (i - 1)))
112+
ws281x->buffer[buff_cnt] |= 0x0C;
113+
else
114+
ws281x->buffer[buff_cnt] |= 0x08;
115+
buff_cnt++;
116+
}
117+
for (int i = 7; i >= 0; i-=2)
118+
{
119+
if (ws281x->pixels[pixel].r & (1 << i))
120+
ws281x->buffer[buff_cnt] |= 0xC0;
121+
else
122+
ws281x->buffer[buff_cnt] |= 0x80;
123+
if (ws281x->pixels[pixel].r & (1 << (i - 1)))
124+
ws281x->buffer[buff_cnt] |= 0x0C;
125+
else
126+
ws281x->buffer[buff_cnt] |= 0x08;
127+
buff_cnt++;
128+
}
129+
for (int i = 7; i >= 0; i-=2)
130+
{
131+
if (ws281x->pixels[pixel].b & (1 << i))
132+
ws281x->buffer[buff_cnt] |= 0xC0;
133+
else
134+
ws281x->buffer[buff_cnt] |= 0x80;
135+
if (ws281x->pixels[pixel].b & (1 << (i - 1)))
136+
ws281x->buffer[buff_cnt] |= 0x0C;
137+
else
138+
ws281x->buffer[buff_cnt] |= 0x08;
139+
buff_cnt++;
140+
}
141+
}
142+
break;
143+
/* order GRB END */
144+
}
145+
/* send via SPI */
146+
if (HAL_SPI_Transmit_DMA(ws281x->spi_handle, ws281x->buffer, ws281x->max_pixel * 32) == HAL_OK)
147+
return true;
148+
else
149+
return false;
150+
}
151+
//###########################################################################################################
152+
void ws281x_set_pixel_rgb(ws281x_t *ws281x, uint8_t select_pixel, uint8_t red, uint8_t green, uint8_t blue)
153+
{
154+
if(select_pixel >= ws281x->max_pixel)
155+
return;
156+
ws281x->pixels[select_pixel].r = red;
157+
ws281x->pixels[select_pixel].g = green;
158+
ws281x->pixels[select_pixel].b = blue;
159+
}
160+
//###########################################################################################################
161+
void ws281x_set_pixel_color(ws281x_t *ws281x, uint8_t select_pixel, ws281x_color_t ws281x_color)
162+
{
163+
if(select_pixel >= ws281x->max_pixel)
164+
return;
165+
switch(ws281x_color)
166+
{
167+
case ws281x_color_black:
168+
ws281x->pixels[select_pixel].r = 0;
169+
ws281x->pixels[select_pixel].g = 0;
170+
ws281x->pixels[select_pixel].b = 0;
171+
break;
172+
case ws281x_color_white:
173+
ws281x->pixels[select_pixel].r = 255;
174+
ws281x->pixels[select_pixel].g = 255;
175+
ws281x->pixels[select_pixel].b = 255;
176+
break;
177+
case ws281x_color_red:
178+
ws281x->pixels[select_pixel].r = 255;
179+
ws281x->pixels[select_pixel].g = 0;
180+
ws281x->pixels[select_pixel].b = 0;
181+
break;
182+
case ws281x_color_green:
183+
ws281x->pixels[select_pixel].r = 0;
184+
ws281x->pixels[select_pixel].g = 255;
185+
ws281x->pixels[select_pixel].b = 0;
186+
break;
187+
case ws281x_color_blue:
188+
ws281x->pixels[select_pixel].r = 0;
189+
ws281x->pixels[select_pixel].g = 0;
190+
ws281x->pixels[select_pixel].b = 255;
191+
break;
192+
case ws281x_color_aqua:
193+
ws281x->pixels[select_pixel].r = 0;
194+
ws281x->pixels[select_pixel].g = 255;
195+
ws281x->pixels[select_pixel].b = 255;
196+
break;
197+
case ws281x_color_magenta:
198+
ws281x->pixels[select_pixel].r = 255;
199+
ws281x->pixels[select_pixel].g = 0;
200+
ws281x->pixels[select_pixel].b = 255;
201+
break;
202+
case ws281x_color_yellow:
203+
ws281x->pixels[select_pixel].r = 255;
204+
ws281x->pixels[select_pixel].g = 255;
205+
ws281x->pixels[select_pixel].b = 0;
206+
break;
207+
case ws281x_color_darkBlue:
208+
ws281x->pixels[select_pixel].r = 0;
209+
ws281x->pixels[select_pixel].g = 0;
210+
ws281x->pixels[select_pixel].b = 255;
211+
break;
212+
case ws281x_color_darkGreen:
213+
ws281x->pixels[select_pixel].r = 0;
214+
ws281x->pixels[select_pixel].g = 128;
215+
ws281x->pixels[select_pixel].b = 0;
216+
break;
217+
case ws281x_color_darkRed:
218+
ws281x->pixels[select_pixel].r = 128;
219+
ws281x->pixels[select_pixel].g = 0;
220+
ws281x->pixels[select_pixel].b = 0;
221+
break;
222+
case ws281x_color_gray:
223+
ws281x->pixels[select_pixel].r = 128;
224+
ws281x->pixels[select_pixel].g = 128;
225+
ws281x->pixels[select_pixel].b = 128;
226+
break;
227+
case ws281x_color_olive:
228+
ws281x->pixels[select_pixel].r = 128;
229+
ws281x->pixels[select_pixel].g = 128;
230+
ws281x->pixels[select_pixel].b = 0;
231+
break;
232+
case ws281x_color_pruple:
233+
ws281x->pixels[select_pixel].r = 128;
234+
ws281x->pixels[select_pixel].g = 0;
235+
ws281x->pixels[select_pixel].b = 128;
236+
break;
237+
case ws281x_color_silver:
238+
ws281x->pixels[select_pixel].r = 192;
239+
ws281x->pixels[select_pixel].g = 192;
240+
ws281x->pixels[select_pixel].b = 192;
241+
break;
242+
case ws281x_color_teal:
243+
ws281x->pixels[select_pixel].r = 0;
244+
ws281x->pixels[select_pixel].g = 128;
245+
ws281x->pixels[select_pixel].b = 128;
246+
break;
247+
case ws281x_color_brown:
248+
ws281x->pixels[select_pixel].r = 165;
249+
ws281x->pixels[select_pixel].g = 42;
250+
ws281x->pixels[select_pixel].b = 42;
251+
break;
252+
case ws281x_color_orange:
253+
ws281x->pixels[select_pixel].r = 255;
254+
ws281x->pixels[select_pixel].g = 165;
255+
ws281x->pixels[select_pixel].b = 0;
256+
break;
257+
case ws281x_color_gold:
258+
ws281x->pixels[select_pixel].r = 255;
259+
ws281x->pixels[select_pixel].g = 215;
260+
ws281x->pixels[select_pixel].b = 0;
261+
break;
262+
case ws281x_color_pink:
263+
ws281x->pixels[select_pixel].r = 255;
264+
ws281x->pixels[select_pixel].g = 20;
265+
ws281x->pixels[select_pixel].b = 147;
266+
break;
267+
default:
268+
ws281x->pixels[select_pixel].r = 0;
269+
ws281x->pixels[select_pixel].g = 0;
270+
ws281x->pixels[select_pixel].b = 0;
271+
break;
272+
}
273+
}
274+
//#########################################################################################################
275+
void ws281x_off(ws281x_t *ws281x)
276+
{
277+
ws281x_delay(20);
278+
memset(ws281x->pixels, 0, ws281x->max_pixel * 3);
279+
ws281x_update(ws281x);
280+
}
281+
//#########################################################################################################
282+
void ws281x_test_slow(ws281x_t *ws281x)
283+
{
284+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
285+
{
286+
ws281x_delay(50);
287+
if (pixel > 0)
288+
ws281x_set_pixel_rgb(ws281x, pixel - 1, 0, 0, 0);
289+
ws281x_set_pixel_rgb(ws281x, pixel, 255, 0, 0);
290+
ws281x_update(ws281x);
291+
}
292+
ws281x_set_pixel_rgb(ws281x, ws281x->max_pixel - 1, 0, 0, 0);
293+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
294+
{
295+
ws281x_delay(50);
296+
if (pixel > 0)
297+
ws281x_set_pixel_rgb(ws281x, pixel - 1, 0, 0, 0);
298+
ws281x_set_pixel_rgb(ws281x, pixel, 0, 255, 0);
299+
ws281x_update(ws281x);
300+
}
301+
ws281x_set_pixel_rgb(ws281x, ws281x->max_pixel - 1, 0, 0, 0);
302+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
303+
{
304+
ws281x_delay(50);
305+
if (pixel > 0)
306+
ws281x_set_pixel_rgb(ws281x, pixel - 1, 0, 0, 0);
307+
ws281x_set_pixel_rgb(ws281x, pixel, 0, 0, 255);
308+
ws281x_update(ws281x);
309+
}
310+
ws281x_off(ws281x);
311+
}
312+
//#########################################################################################################
313+
void ws281x_test_fast(ws281x_t *ws281x)
314+
{
315+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
316+
ws281x_set_pixel_rgb(ws281x, pixel, 255, 0, 0);
317+
ws281x_update(ws281x);
318+
ws281x_delay(250);
319+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
320+
ws281x_set_pixel_rgb(ws281x, pixel, 0, 255, 0);
321+
ws281x_update(ws281x);
322+
ws281x_delay(250);
323+
for (int pixel = 0; pixel < ws281x->max_pixel; pixel++)
324+
ws281x_set_pixel_rgb(ws281x, pixel, 0, 0, 255);
325+
ws281x_update(ws281x);
326+
ws281x_delay(250);
327+
ws281x_off(ws281x);
328+
}

0 commit comments

Comments
 (0)