vendor
rpi_ws281x
main.c
Go to the documentation of this file.
1
/*
2
* newtest.c
3
*
4
* Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
5
*
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without modification, are permitted
9
* provided that the following conditions are met:
10
*
11
* 1. Redistributions of source code must retain the above copyright notice, this list of
12
* conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
14
* of conditions and the following disclaimer in the documentation and/or other materials
15
* provided with the distribution.
16
* 3. Neither the name of the owner nor the names of its contributors may be used to endorse
17
* or promote products derived from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
22
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
*
28
*/
29
30
31
static
char
VERSION
[] =
"XX.YY.ZZ"
;
32
33
#include <stdint.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <unistd.h>
38
#include <sys/types.h>
39
#include <sys/stat.h>
40
#include <fcntl.h>
41
#include <sys/mman.h>
42
#include <signal.h>
43
#include <stdarg.h>
44
#include <getopt.h>
45
46
47
#include "
clk.h
"
48
#include "
gpio.h
"
49
#include "
dma.h
"
50
#include "
pwm.h
"
51
#include "version.h"
52
53
#include "
ws2811.h
"
54
55
56
#define ARRAY_SIZE(stuff) (sizeof(stuff) / sizeof(stuff[0]))
57
58
// defaults for cmdline options
59
#define TARGET_FREQ WS2811_TARGET_FREQ
60
#define GPIO_PIN 18
61
#define DMA 10
62
//#define STRIP_TYPE WS2811_STRIP_RGB // WS2812/SK6812RGB integrated chip+leds
63
#define STRIP_TYPE WS2811_STRIP_GBR // WS2812/SK6812RGB integrated chip+leds
64
//#define STRIP_TYPE SK6812_STRIP_RGBW // SK6812RGBW (NOT SK6812RGB)
65
66
#define WIDTH 8
67
#define HEIGHT 8
68
#define LED_COUNT (WIDTH * HEIGHT)
69
70
int
width
=
WIDTH
;
71
int
height
=
HEIGHT
;
72
int
led_count
=
LED_COUNT
;
73
74
int
clear_on_exit
= 0;
75
76
ws2811_t
ledstring
=
77
{
78
.
freq
=
TARGET_FREQ
,
79
.dmanum =
DMA
,
80
.channel =
81
{
82
[0] =
83
{
84
.gpionum =
GPIO_PIN
,
85
.count =
LED_COUNT
,
86
.invert = 0,
87
.brightness = 255,
88
.strip_type =
STRIP_TYPE
,
89
},
90
[1] =
91
{
92
.gpionum = 0,
93
.count = 0,
94
.invert = 0,
95
.brightness = 0,
96
},
97
},
98
};
99
100
ws2811_led_t
*
matrix
;
101
102
static
uint8_t
running
= 1;
103
104
void
matrix_render
(
void
)
105
{
106
int
x, y;
107
108
for
(x = 0; x <
width
; x++)
109
{
110
for
(y = 0; y <
height
; y++)
111
{
112
ledstring
.
channel
[0].
leds
[(y *
width
) + x] =
matrix
[y *
width
+ x];
113
}
114
}
115
}
116
117
void
matrix_raise
(
void
)
118
{
119
int
x, y;
120
121
for
(y = 0; y < (
height
- 1); y++)
122
{
123
for
(x = 0; x <
width
; x++)
124
{
125
// This is for the 8x8 Pimoroni Unicorn-HAT where the LEDS in subsequent
126
// rows are arranged in opposite directions
127
matrix
[y *
width
+ x] =
matrix
[(y + 1)*
width
+
width
- x - 1];
128
}
129
}
130
}
131
132
void
matrix_clear
(
void
)
133
{
134
int
x, y;
135
136
for
(y = 0; y < (
height
); y++)
137
{
138
for
(x = 0; x <
width
; x++)
139
{
140
matrix
[y *
width
+ x] = 0;
141
}
142
}
143
}
144
145
int
dotspos
[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
146
ws2811_led_t
dotcolors
[] =
147
{
148
0x00200000,
// red
149
0x00201000,
// orange
150
0x00202000,
// yellow
151
0x00002000,
// green
152
0x00002020,
// lightblue
153
0x00000020,
// blue
154
0x00100010,
// purple
155
0x00200010,
// pink
156
};
157
158
ws2811_led_t
dotcolors_rgbw
[] =
159
{
160
0x00200000,
// red
161
0x10200000,
// red + W
162
0x00002000,
// green
163
0x10002000,
// green + W
164
0x00000020,
// blue
165
0x10000020,
// blue + W
166
0x00101010,
// white
167
0x10101010,
// white + W
168
169
};
170
171
void
matrix_bottom
(
void
)
172
{
173
int
i;
174
175
for
(i = 0; i < (int)(
ARRAY_SIZE
(
dotspos
)); i++)
176
{
177
dotspos
[i]++;
178
if
(
dotspos
[i] > (
width
- 1))
179
{
180
dotspos
[i] = 0;
181
}
182
183
if
(
ledstring
.
channel
[0].
strip_type
==
SK6812_STRIP_RGBW
) {
184
matrix
[
dotspos
[i] + (
height
- 1) *
width
] =
dotcolors_rgbw
[i];
185
}
else
{
186
matrix
[
dotspos
[i] + (
height
- 1) *
width
] =
dotcolors
[i];
187
}
188
}
189
}
190
191
static
void
ctrl_c_handler
(
int
signum)
192
{
193
(void)(signum);
194
running
= 0;
195
}
196
197
static
void
setup_handlers
(
void
)
198
{
199
struct
sigaction sa =
200
{
201
.sa_handler =
ctrl_c_handler
,
202
};
203
204
sigaction(SIGINT, &sa, NULL);
205
sigaction(SIGTERM, &sa, NULL);
206
}
207
208
209
void
parseargs
(
int
argc,
char
**argv,
ws2811_t
*ws2811)
210
{
211
int
index;
212
int
c;
213
214
static
struct
option longopts[] =
215
{
216
{
"help"
, no_argument, 0,
'h'
},
217
{
"dma"
, required_argument, 0,
'd'
},
218
{
"gpio"
, required_argument, 0,
'g'
},
219
{
"invert"
, no_argument, 0,
'i'
},
220
{
"clear"
, no_argument, 0,
'c'
},
221
{
"strip"
, required_argument, 0,
's'
},
222
{
"height"
, required_argument, 0,
'y'
},
223
{
"width"
, required_argument, 0,
'x'
},
224
{
"version"
, no_argument, 0,
'v'
},
225
{0, 0, 0, 0}
226
};
227
228
while
(1)
229
{
230
231
index = 0;
232
c = getopt_long(argc, argv,
"cd:g:his:vx:y:"
, longopts, &index);
233
234
if
(c == -1)
235
break
;
236
237
switch
(c)
238
{
239
case
0:
240
/* handle flag options (array's 3rd field non-0) */
241
break
;
242
243
case
'h'
:
244
fprintf(stderr,
"%s version %s\n"
, argv[0],
VERSION
);
245
fprintf(stderr,
"Usage: %s \n"
246
"-h (--help) - this information\n"
247
"-s (--strip) - strip type - rgb, grb, gbr, rgbw\n"
248
"-x (--width) - matrix width (default 8)\n"
249
"-y (--height) - matrix height (default 8)\n"
250
"-d (--dma) - dma channel to use (default 10)\n"
251
"-g (--gpio) - GPIO to use\n"
252
" If omitted, default is 18 (PWM0)\n"
253
"-i (--invert) - invert pin output (pulse LOW)\n"
254
"-c (--clear) - clear matrix on exit.\n"
255
"-v (--version) - version information\n"
256
, argv[0]);
257
exit(-1);
258
259
case
'D'
:
260
break
;
261
262
case
'g'
:
263
if
(optarg) {
264
int
gpio = atoi(optarg);
265
/*
266
PWM0, which can be set to use GPIOs 12, 18, 40, and 52.
267
Only 12 (pin 32) and 18 (pin 12) are available on the B+/2B/3B
268
PWM1 which can be set to use GPIOs 13, 19, 41, 45 and 53.
269
Only 13 is available on the B+/2B/PiZero/3B, on pin 33
270
PCM_DOUT, which can be set to use GPIOs 21 and 31.
271
Only 21 is available on the B+/2B/PiZero/3B, on pin 40.
272
SPI0-MOSI is available on GPIOs 10 and 38.
273
Only GPIO 10 is available on all models.
274
275
The library checks if the specified gpio is available
276
on the specific model (from model B rev 1 till 3B)
277
278
*/
279
ws2811->
channel
[0].
gpionum
= gpio;
280
}
281
break
;
282
283
case
'i'
:
284
ws2811->
channel
[0].
invert
=1;
285
break
;
286
287
case
'c'
:
288
clear_on_exit
=1;
289
break
;
290
291
case
'd'
:
292
if
(optarg) {
293
int
dma = atoi(optarg);
294
if
(dma < 14) {
295
ws2811->
dmanum
= dma;
296
}
else
{
297
printf (
"invalid dma %d\n"
, dma);
298
exit (-1);
299
}
300
}
301
break
;
302
303
case
'y'
:
304
if
(optarg) {
305
height
= atoi(optarg);
306
if
(
height
> 0) {
307
ws2811->
channel
[0].
count
=
height
*
width
;
308
}
else
{
309
printf (
"invalid height %d\n"
,
height
);
310
exit (-1);
311
}
312
}
313
break
;
314
315
case
'x'
:
316
if
(optarg) {
317
width
= atoi(optarg);
318
if
(
width
> 0) {
319
ws2811->
channel
[0].
count
=
height
*
width
;
320
}
else
{
321
printf (
"invalid width %d\n"
,
width
);
322
exit (-1);
323
}
324
}
325
break
;
326
327
case
's'
:
328
if
(optarg) {
329
if
(!strncasecmp(
"rgb"
, optarg, 4)) {
330
ws2811->
channel
[0].
strip_type
=
WS2811_STRIP_RGB
;
331
}
332
else
if
(!strncasecmp(
"rbg"
, optarg, 4)) {
333
ws2811->
channel
[0].
strip_type
=
WS2811_STRIP_RBG
;
334
}
335
else
if
(!strncasecmp(
"grb"
, optarg, 4)) {
336
ws2811->
channel
[0].
strip_type
=
WS2811_STRIP_GRB
;
337
}
338
else
if
(!strncasecmp(
"gbr"
, optarg, 4)) {
339
ws2811->
channel
[0].
strip_type
=
WS2811_STRIP_GBR
;
340
}
341
else
if
(!strncasecmp(
"brg"
, optarg, 4)) {
342
ws2811->
channel
[0].
strip_type
=
WS2811_STRIP_BRG
;
343
}
344
else
if
(!strncasecmp(
"bgr"
, optarg, 4)) {
345
ws2811->
channel
[0].
strip_type
=
WS2811_STRIP_BGR
;
346
}
347
else
if
(!strncasecmp(
"rgbw"
, optarg, 4)) {
348
ws2811->
channel
[0].
strip_type
=
SK6812_STRIP_RGBW
;
349
}
350
else
if
(!strncasecmp(
"grbw"
, optarg, 4)) {
351
ws2811->
channel
[0].
strip_type
=
SK6812_STRIP_GRBW
;
352
}
353
else
{
354
printf (
"invalid strip %s\n"
, optarg);
355
exit (-1);
356
}
357
}
358
break
;
359
360
case
'v'
:
361
fprintf(stderr,
"%s version %s\n"
, argv[0],
VERSION
);
362
exit(-1);
363
364
case
'?'
:
365
/* getopt_long already reported error? */
366
exit(-1);
367
368
default
:
369
exit(-1);
370
}
371
}
372
}
373
374
375
int
main
(
int
argc,
char
*argv[])
376
{
377
ws2811_return_t
ret;
378
379
sprintf(
VERSION
,
"%d.%d.%d"
, VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO);
380
381
parseargs
(argc, argv, &
ledstring
);
382
383
matrix
= malloc(
sizeof
(
ws2811_led_t
) *
width
*
height
);
384
385
setup_handlers
();
386
387
if
((ret =
ws2811_init
(&
ledstring
)) != WS2811_SUCCESS)
388
{
389
fprintf(stderr,
"ws2811_init failed: %s\n"
,
ws2811_get_return_t_str
(ret));
390
return
ret;
391
}
392
393
while
(
running
)
394
{
395
matrix_raise
();
396
matrix_bottom
();
397
matrix_render
();
398
399
if
((ret =
ws2811_render
(&
ledstring
)) != WS2811_SUCCESS)
400
{
401
fprintf(stderr,
"ws2811_render failed: %s\n"
,
ws2811_get_return_t_str
(ret));
402
break
;
403
}
404
405
// 15 frames /sec
406
usleep(1000000 / 15);
407
}
408
409
if
(
clear_on_exit
) {
410
matrix_clear
();
411
matrix_render
();
412
ws2811_render
(&
ledstring
);
413
}
414
415
ws2811_fini
(&
ledstring
);
416
417
printf (
"\n"
);
418
return
ret;
419
}
dotcolors_rgbw
ws2811_led_t dotcolors_rgbw[]
Definition:
main.c:158
matrix_render
void matrix_render(void)
Definition:
main.c:104
ws2811_t::freq
uint32_t freq
Definition:
ws2811.h:91
WS2811_STRIP_BGR
#define WS2811_STRIP_BGR
Definition:
ws2811.h:61
LED_COUNT
#define LED_COUNT
Definition:
main.c:68
ws2811_channel_t::strip_type
int strip_type
Definition:
ws2811.h:76
ws2811_init
ws2811_return_t ws2811_init(ws2811_t *ws2811)
Definition:
ws2811.c:894
ws2811_channel_t::leds
ws2811_led_t * leds
Definition:
ws2811.h:77
setup_handlers
static void setup_handlers(void)
Definition:
main.c:197
WS2811_STRIP_GRB
#define WS2811_STRIP_GRB
Definition:
ws2811.h:58
ws2811_led_t
uint32_t ws2811_led_t
Definition:
ws2811.h:68
matrix_raise
void matrix_raise(void)
Definition:
main.c:117
ws2811_channel_t::gpionum
int gpionum
Definition:
ws2811.h:73
WS2811_STRIP_RBG
#define WS2811_STRIP_RBG
Definition:
ws2811.h:57
VERSION
static char VERSION[]
Definition:
main.c:31
SK6812_STRIP_GRBW
#define SK6812_STRIP_GRBW
Definition:
ws2811.h:49
height
int height
Definition:
main.c:71
clear_on_exit
int clear_on_exit
Definition:
main.c:74
clk.h
ARRAY_SIZE
#define ARRAY_SIZE(stuff)
Definition:
main.c:56
ws2811_t::channel
ws2811_channel_t channel[RPI_PWM_CHANNELS]
Definition:
ws2811.h:93
matrix
ws2811_led_t * matrix
Definition:
main.c:100
ws2811_t::dmanum
int dmanum
Definition:
ws2811.h:92
ws2811_return_t
ws2811_return_t
Definition:
ws2811.h:116
matrix_bottom
void matrix_bottom(void)
Definition:
main.c:171
WIDTH
#define WIDTH
Definition:
main.c:66
running
static uint8_t running
Definition:
main.c:102
GPIO_PIN
#define GPIO_PIN
Definition:
main.c:60
ws2811.h
ws2811_get_return_t_str
const char * ws2811_get_return_t_str(const ws2811_return_t state)
Definition:
ws2811.c:1273
main
int main(int argc, char *argv[])
Definition:
main.c:375
parseargs
void parseargs(int argc, char **argv, ws2811_t *ws2811)
Definition:
main.c:209
TARGET_FREQ
#define TARGET_FREQ
Definition:
main.c:59
ws2811_t
Definition:
ws2811.h:86
width
int width
Definition:
main.c:70
STRIP_TYPE
#define STRIP_TYPE
Definition:
main.c:63
ws2811_render
ws2811_return_t ws2811_render(ws2811_t *ws2811)
Definition:
ws2811.c:1138
gpio.h
SK6812_STRIP_RGBW
#define SK6812_STRIP_RGBW
Definition:
ws2811.h:47
ctrl_c_handler
static void ctrl_c_handler(int signum)
Definition:
main.c:191
ws2811_channel_t::count
int count
Definition:
ws2811.h:75
dotspos
int dotspos[]
Definition:
main.c:145
DMA
#define DMA
Definition:
main.c:61
HEIGHT
#define HEIGHT
Definition:
main.c:67
led_count
int led_count
Definition:
main.c:72
pwm.h
matrix_clear
void matrix_clear(void)
Definition:
main.c:132
WS2811_STRIP_GBR
#define WS2811_STRIP_GBR
Definition:
ws2811.h:59
WS2811_STRIP_BRG
#define WS2811_STRIP_BRG
Definition:
ws2811.h:60
ws2811_fini
void ws2811_fini(ws2811_t *ws2811)
Definition:
ws2811.c:1079
WS2811_STRIP_RGB
#define WS2811_STRIP_RGB
Definition:
ws2811.h:56
dotcolors
ws2811_led_t dotcolors[]
Definition:
main.c:146
ws2811_channel_t::invert
int invert
Definition:
ws2811.h:74
ledstring
ws2811_t ledstring
Definition:
main.c:76
dma.h
ws281x
Author(s): Alexey Rogachevskiy
, Oleg Kalachev
autogenerated on Wed Jun 15 2022 02:21:36