mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Merge pull request #533 from markwal/rpi_ws281x
Add new WS281x driver Former-commit-id: 1264edf7f5e0bc29f091e72989ab7116b78056bf
This commit is contained in:
commit
e82643ff50
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "dependencies/external/protobuf"]
|
||||
path = dependencies/external/protobuf
|
||||
url = https://github.com/tvdzwan/protobuf.git
|
||||
[submodule "dependencies/external/rpi_ws281x"]
|
||||
path = dependencies/external/rpi_ws281x
|
||||
url = https://github.com/jgarff/rpi_ws281x
|
||||
|
@ -34,6 +34,9 @@ message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2})
|
||||
option(ENABLE_WS2812BPWM "Enable the WS2812b-PWM device" OFF)
|
||||
message(STATUS "ENABLE_WS2812BPWM = " ${ENABLE_WS2812BPWM})
|
||||
|
||||
option(ENABLE_WS281XPWM "Enable the WS281x-PWM device" OFF)
|
||||
message(STATUS "ENABLE_WS281XPWM = " ${ENABLE_WS281XPWM})
|
||||
|
||||
option(ENABLE_X11 "Enable the X11 grabber" OFF)
|
||||
message(STATUS "ENABLE_X11 = " ${ENABLE_X11})
|
||||
|
||||
|
@ -12,6 +12,9 @@
|
||||
// Define to enable the ws2812b-pwm-device
|
||||
#cmakedefine ENABLE_WS2812BPWM
|
||||
|
||||
// Define to enable the ws281x-pwm-via-dma-device using jgarff's library
|
||||
#cmakedefine ENABLE_WS281XPWM
|
||||
|
||||
// Define to enable the spi-device
|
||||
#cmakedefine ENABLE_TINKERFORGE
|
||||
|
||||
|
7
dependencies/CMakeLists.txt
vendored
7
dependencies/CMakeLists.txt
vendored
@ -4,6 +4,13 @@ add_subdirectory(build/jsoncpp)
|
||||
add_subdirectory(build/serial)
|
||||
add_subdirectory(build/tinkerforge)
|
||||
|
||||
if(ENABLE_WS281XPWM)
|
||||
add_library(ws281x
|
||||
external/rpi_ws281x/mailbox.c external/rpi_ws281x/ws2811.c
|
||||
external/rpi_ws281x/pwm.c external/rpi_ws281x/dma.c
|
||||
external/rpi_ws281x/rpihw.c)
|
||||
endif(ENABLE_WS281XPWM)
|
||||
|
||||
if(ENABLE_PROTOBUF)
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library")
|
||||
add_subdirectory(external/protobuf)
|
||||
|
1
dependencies/external/rpi_ws281x
vendored
Submodule
1
dependencies/external/rpi_ws281x
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 34c917e25044a7aca4f6dc9326c48c1474b8f28c
|
@ -97,6 +97,18 @@ SET(Leddevice_SOURCES
|
||||
)
|
||||
endif(ENABLE_WS2812BPWM)
|
||||
|
||||
if(ENABLE_WS281XPWM)
|
||||
include_directories(../../dependencies/external/rpi_ws281x)
|
||||
SET(Leddevice_HEADERS
|
||||
${Leddevice_HEADERS}
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWS281x.h
|
||||
)
|
||||
SET(Leddevice_SOURCES
|
||||
${Leddevice_SOURCES}
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWS281x.cpp
|
||||
)
|
||||
endif(ENABLE_WS281XPWM)
|
||||
|
||||
if(ENABLE_TINKERFORGE)
|
||||
SET(Leddevice_HEADERS
|
||||
${Leddevice_HEADERS}
|
||||
@ -138,6 +150,10 @@ if(ENABLE_TINKERFORGE)
|
||||
target_link_libraries(leddevice tinkerforge)
|
||||
endif()
|
||||
|
||||
if(ENABLE_WS281XPWM)
|
||||
target_link_libraries(leddevice ws281x)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(leddevice hidapi-mac)
|
||||
else()
|
||||
|
@ -42,6 +42,10 @@
|
||||
#include "LedDeviceWS2812b.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_WS281XPWM
|
||||
#include "LedDeviceWS281x.h"
|
||||
#endif
|
||||
|
||||
LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
||||
{
|
||||
std::cout << "Device configuration: " << deviceConfig << std::endl;
|
||||
@ -285,6 +289,18 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
|
||||
LedDeviceWS2812b * ledDeviceWS2812b = new LedDeviceWS2812b();
|
||||
device = ledDeviceWS2812b;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_WS281XPWM
|
||||
else if (type == "ws281x")
|
||||
{
|
||||
const int gpio = deviceConfig.get("gpio", 18).asInt();
|
||||
const int leds = deviceConfig.get("leds", 12).asInt();
|
||||
const uint32_t freq = deviceConfig.get("freq", (Json::UInt)800000ul).asInt();
|
||||
const int dmanum = deviceConfig.get("dmanum", 5).asInt();
|
||||
|
||||
LedDeviceWS281x * ledDeviceWS281x = new LedDeviceWS281x(gpio, leds, freq, dmanum);
|
||||
device = ledDeviceWS281x;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
|
78
libsrc/leddevice/LedDeviceWS281x.cpp
Normal file
78
libsrc/leddevice/LedDeviceWS281x.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "LedDeviceWS281x.h"
|
||||
|
||||
// Constructor
|
||||
LedDeviceWS281x::LedDeviceWS281x(const int gpio, const int leds, const uint32_t freq, const int dmanum)
|
||||
{
|
||||
initialized = false;
|
||||
led_string.freq = freq;
|
||||
led_string.dmanum = dmanum;
|
||||
led_string.channel[0].gpionum = gpio;
|
||||
led_string.channel[0].invert = 0;
|
||||
led_string.channel[0].count = leds;
|
||||
led_string.channel[0].brightness = 255;
|
||||
led_string.channel[0].strip_type = WS2811_STRIP_RGB;
|
||||
|
||||
led_string.channel[1].gpionum = 0;
|
||||
led_string.channel[1].invert = 0;
|
||||
led_string.channel[1].count = 0;
|
||||
led_string.channel[1].brightness = 0;
|
||||
led_string.channel[0].strip_type = WS2811_STRIP_RGB;
|
||||
if (ws2811_init(&led_string) < 0) {
|
||||
std::cout << "Unable to initialize ws281x library." << std::endl;
|
||||
throw -1;
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
// Send new values down the LED chain
|
||||
int LedDeviceWS281x::write(const std::vector<ColorRgb> &ledValues)
|
||||
{
|
||||
if (!initialized)
|
||||
return -1;
|
||||
|
||||
int idx = 0;
|
||||
for (const ColorRgb& color : ledValues)
|
||||
{
|
||||
if (idx >= led_string.channel[0].count)
|
||||
break;
|
||||
led_string.channel[0].leds[idx++] = ((uint32_t)color.red << 16) + ((uint32_t)color.green << 8) + color.blue;
|
||||
}
|
||||
while (idx < led_string.channel[0].count)
|
||||
led_string.channel[0].leds[idx++] = 0;
|
||||
|
||||
if (ws2811_render(&led_string))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Turn off the LEDs by sending 000000's
|
||||
// TODO Allow optional power switch out another gpio, if this code handles it can
|
||||
// make it more likely we don't accidentally drive data into an off strip
|
||||
int LedDeviceWS281x::switchOff()
|
||||
{
|
||||
if (!initialized)
|
||||
return -1;
|
||||
|
||||
int idx = 0;
|
||||
while (idx < led_string.channel[0].count)
|
||||
led_string.channel[0].leds[idx++] = 0;
|
||||
|
||||
if (ws2811_render(&led_string))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
LedDeviceWS281x::~LedDeviceWS281x()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
std::cout << "Shutdown WS281x PWM and DMA channel" << std::endl;
|
||||
ws2811_fini(&led_string);
|
||||
}
|
||||
initialized = false;
|
||||
}
|
43
libsrc/leddevice/LedDeviceWS281x.h
Normal file
43
libsrc/leddevice/LedDeviceWS281x.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef LEDDEVICEWS281X_H_
|
||||
#define LEDDEVICEWS281X_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <leddevice/LedDevice.h>
|
||||
#include <ws2811.h>
|
||||
|
||||
class LedDeviceWS281x : public LedDevice
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs the LedDevice for WS281x (one wire 800kHz)
|
||||
///
|
||||
/// @param gpio The gpio pin to use (BCM chip counting, default is 18)
|
||||
/// @param leds The number of leds attached to the gpio pin
|
||||
/// @param freq The target frequency for the data line, default is 800000
|
||||
/// @param dmanum The DMA channel to use, default is 5
|
||||
///
|
||||
LedDeviceWS281x(const int gpio, const int leds, const uint32_t freq, int dmanum);
|
||||
|
||||
///
|
||||
/// Destructor of the LedDevice, waits for DMA to complete and then cleans up
|
||||
///
|
||||
~LedDeviceWS281x();
|
||||
|
||||
///
|
||||
/// Writes the led color values to the led-device
|
||||
///
|
||||
/// @param ledValues The color-value per led
|
||||
/// @return Zero on succes else negative
|
||||
///
|
||||
virtual int write(const std::vector<ColorRgb> &ledValues);
|
||||
|
||||
/// Switch the leds off
|
||||
virtual int switchOff();
|
||||
|
||||
private:
|
||||
ws2811_t led_string;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
#endif /* LEDDEVICEWS281X_H_ */
|
Loading…
Reference in New Issue
Block a user