Skip to content

Commit f1e6ad8

Browse files
committed
[RPi] a test of driver for WS281X RGB LED (NeoPixel) ring in use by Standalone Edition [skip ci]
1 parent f612048 commit f1e6ad8

2 files changed

Lines changed: 205 additions & 1 deletion

File tree

software/firmware/source/SoftRF/Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ ifeq ($(LGPIO), yes)
3232
endif
3333

3434
BRIDGE ?= no
35+
NEOPIXEL ?= no
3536

3637
CC = gcc
3738
CXX = g++
@@ -108,6 +109,7 @@ LGPIO_PATH = $(LIB_PATH)/lg-0.1
108109
RADIOLIB_PATH = $(LIB_PATH)/RadioLib/src
109110
BRIDGE_PATH = $(LIB_PATH)/Bridge/src
110111
BMP280_PATH = $(LIB_PATH)/Adafruit_BMP280_Library
112+
WS281X_PATH = $(LIB_PATH)/rpi_ws281x-1.0.0
111113

112114
ifeq ($(BASICMAC), yes)
113115
RADIO_PATH = $(BASICMAC_PATH)
@@ -124,7 +126,7 @@ INCLUDE = -I$(PRODAT_PATH) -I$(PRORAD_PATH) -I$(PLATFORM_PATH) \
124126
-I$(GFX_PATH) -I$(U8G2_AF_PATH) -I$(EPD2_PATH) \
125127
-I$(MODES_PATH) -I$(APRS_PATH) -I$(RADIOLIB_PATH) \
126128
-I$(LGPIO_PATH) -I$(BRIDGE_PATH) -I$(BMP280_PATH) \
127-
-I$(U8G2_PATH)
129+
-I$(U8G2_PATH) -I$(WS281X_PATH)
128130

129131
SRC_CPPS := $(SRC_PATH)/TrafficHelper.cpp \
130132
$(SRC_PATH)/Library.cpp
@@ -284,6 +286,13 @@ ifeq ($(BRIDGE), yes)
284286
CFLAGS += -DUSE_BRIDGE
285287
endif
286288

289+
ifeq ($(NEOPIXEL), yes)
290+
OBJS += $(WS281X_PATH)/mailbox.o $(WS281X_PATH)/ws2811.o \
291+
$(WS281X_PATH)/pwm.o $(WS281X_PATH)/pcm.o \
292+
$(WS281X_PATH)/dma.o $(WS281X_PATH)/rpihw.o
293+
CFLAGS += -DUSE_NEOPIXEL
294+
endif
295+
287296
ifeq ($(NOMAVLINK), no)
288297
OBJS += $(MAVLINK_PATH)/mavlink.o
289298
else

software/firmware/source/SoftRF/src/platform/RPi.cpp

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,187 @@ void notFound(Request &req, Response &res) {
360360
}
361361
#endif /* USE_BRIDGE */
362362

363+
#if defined(USE_NEOPIXEL)
364+
#include "clk.h"
365+
#include "gpio.h"
366+
#include "dma.h"
367+
#include "pwm.h"
368+
369+
#include "ws2811.h"
370+
371+
#define ARRAY_SIZE(stuff) (sizeof(stuff) / sizeof(stuff[0]))
372+
373+
#define TARGET_FREQ WS2811_TARGET_FREQ
374+
#define GPIO_PIN 18
375+
#define DMA 10
376+
//#define STRIP_TYPE WS2811_STRIP_RGB // WS2812/SK6812RGB integrated chip+leds
377+
#define STRIP_TYPE WS2811_STRIP_GBR // WS2812/SK6812RGB integrated chip+leds
378+
//#define STRIP_TYPE SK6812_STRIP_RGBW // SK6812RGBW (NOT SK6812RGB)
379+
380+
#define WIDTH 8
381+
#define HEIGHT 8
382+
#define LED_COUNT (WIDTH * HEIGHT)
383+
384+
static int width = WIDTH;
385+
static int height = HEIGHT;
386+
static int led_count = LED_COUNT;
387+
388+
ws2811_t ledstring =
389+
{
390+
.freq = TARGET_FREQ,
391+
.dmanum = DMA,
392+
.channel =
393+
{
394+
[0] =
395+
{
396+
.gpionum = GPIO_PIN,
397+
.invert = 0,
398+
.count = LED_COUNT,
399+
.strip_type = STRIP_TYPE,
400+
.brightness = 255,
401+
},
402+
[1] =
403+
{
404+
.gpionum = 0,
405+
.invert = 0,
406+
.count = 0,
407+
.brightness = 0,
408+
},
409+
},
410+
};
411+
412+
ws2811_led_t *matrix;
413+
414+
void matrix_render(void)
415+
{
416+
int x, y;
417+
418+
for (x = 0; x < width; x++)
419+
{
420+
for (y = 0; y < height; y++)
421+
{
422+
ledstring.channel[0].leds[(y * width) + x] = matrix[y * width + x];
423+
}
424+
}
425+
}
426+
427+
void matrix_raise(void)
428+
{
429+
int x, y;
430+
431+
for (y = 0; y < (height - 1); y++)
432+
{
433+
for (x = 0; x < width; x++)
434+
{
435+
// This is for the 8x8 Pimoroni Unicorn-HAT where the LEDS in subsequent
436+
// rows are arranged in opposite directions
437+
matrix[y * width + x] = matrix[(y + 1)*width + width - x - 1];
438+
}
439+
}
440+
}
441+
442+
void matrix_clear(void)
443+
{
444+
int x, y;
445+
446+
for (y = 0; y < (height ); y++)
447+
{
448+
for (x = 0; x < width; x++)
449+
{
450+
matrix[y * width + x] = 0;
451+
}
452+
}
453+
}
454+
455+
int dotspos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
456+
457+
ws2811_led_t dotcolors[] =
458+
{
459+
0x00200000, // red
460+
0x00201000, // orange
461+
0x00202000, // yellow
462+
0x00002000, // green
463+
0x00002020, // lightblue
464+
0x00000020, // blue
465+
0x00100010, // purple
466+
0x00200010, // pink
467+
};
468+
469+
ws2811_led_t dotcolors_rgbw[] =
470+
{
471+
0x00200000, // red
472+
0x10200000, // red + W
473+
0x00002000, // green
474+
0x10002000, // green + W
475+
0x00000020, // blue
476+
0x10000020, // blue + W
477+
0x00101010, // white
478+
0x10101010, // white + W
479+
480+
};
481+
482+
void matrix_bottom(void)
483+
{
484+
int i;
485+
486+
for (i = 0; i < (int)(ARRAY_SIZE(dotspos)); i++)
487+
{
488+
dotspos[i]++;
489+
if (dotspos[i] > (width - 1))
490+
{
491+
dotspos[i] = 0;
492+
}
493+
494+
if (ledstring.channel[0].strip_type == SK6812_STRIP_RGBW) {
495+
matrix[dotspos[i] + (height - 1) * width] = dotcolors_rgbw[i];
496+
} else {
497+
matrix[dotspos[i] + (height - 1) * width] = dotcolors[i];
498+
}
499+
}
500+
}
501+
502+
int ws2811_init(void)
503+
{
504+
ws2811_return_t ret;
505+
506+
matrix = (ws2811_led_t *) malloc(sizeof(ws2811_led_t) * width * height);
507+
508+
if ((ret = ws2811_init(&ledstring)) != WS2811_SUCCESS)
509+
{
510+
fprintf(stderr, "ws2811_init failed: %s\n", ws2811_get_return_t_str(ret));
511+
return ret;
512+
}
513+
514+
return ret;
515+
}
516+
517+
void ws2811_test(void)
518+
{
519+
ws2811_return_t ret;
520+
521+
for (int i=0; i < 75; i++)
522+
{
523+
matrix_raise();
524+
matrix_bottom();
525+
matrix_render();
526+
527+
if ((ret = ws2811_render(&ledstring)) != WS2811_SUCCESS)
528+
{
529+
fprintf(stderr, "ws2811_render failed: %s\n", ws2811_get_return_t_str(ret));
530+
break;
531+
}
532+
533+
// 15 frames /sec
534+
usleep(1000000 / 15);
535+
}
536+
537+
matrix_clear();
538+
matrix_render();
539+
ws2811_render(&ledstring);
540+
}
541+
542+
#endif /* USE_NEOPIXEL */
543+
363544
//-------------------------------------------------------------------------
364545
//
365546
// The MIT License (MIT)
@@ -1446,6 +1627,13 @@ int main()
14461627
// hw_info.gnss = GNSS_setup();
14471628

14481629
Traffic_setup();
1630+
1631+
#if defined(USE_NEOPIXEL)
1632+
// LED_setup();
1633+
1634+
ws2811_init();
1635+
#endif /* USE_NEOPIXEL */
1636+
14491637
NMEA_setup();
14501638

14511639
Traffic_TCP_Server.setup(JSON_SRV_TCP_PORT);
@@ -1486,6 +1674,13 @@ int main()
14861674
Serial.println((unsigned long) RELAY_SRC_PORT);
14871675
#endif /* USE_BRIDGE */
14881676

1677+
#if defined(USE_NEOPIXEL)
1678+
// LED_test();
1679+
1680+
ws2811_test();
1681+
ws2811_fini(&ledstring);
1682+
#endif /* USE_NEOPIXEL */
1683+
14891684
Sound_setup();
14901685
SoC->Sound_test(reset_info.reason);
14911686

0 commit comments

Comments
 (0)