diff --git a/hyperiond.test-binary.REMOVED.git-id b/hyperiond.test-binary.REMOVED.git-id index dc9b6471..007dd52b 100644 --- a/hyperiond.test-binary.REMOVED.git-id +++ b/hyperiond.test-binary.REMOVED.git-id @@ -1 +1 @@ -5d75f380f2bd74d3cd6b574f0a7d05850786216b \ No newline at end of file +23f1b917ec588d71521aa698edf446a2e8c0ea5d \ No newline at end of file diff --git a/libsrc/leddevice/CMakeLists.txt b/libsrc/leddevice/CMakeLists.txt index 6d89205a..2d2ceba5 100755 --- a/libsrc/leddevice/CMakeLists.txt +++ b/libsrc/leddevice/CMakeLists.txt @@ -75,6 +75,7 @@ if(ENABLE_SPIDEV) ${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.h ${CURRENT_SOURCE_DIR}/LedDeviceP9813.h ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h + ${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.h ${CURRENT_SOURCE_DIR}/LedDeviceAPA102.h ) SET(Leddevice_SOURCES @@ -84,6 +85,7 @@ if(ENABLE_SPIDEV) ${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.cpp ${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.cpp ${CURRENT_SOURCE_DIR}/LedDeviceAPA102.cpp ) endif(ENABLE_SPIDEV) diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 7cf2385b..689ef91f 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -14,6 +14,7 @@ #include "LedDeviceLpd8806.h" #include "LedDeviceP9813.h" #include "LedDeviceWs2801.h" + #include "LedDeviceWs2812SPI.h" #include "LedDeviceAPA102.h" #endif @@ -142,6 +143,16 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) device = deviceWs2801; } + else if (type == "ws2812spi") + { + const std::string output = deviceConfig["output"].asString(); + const unsigned rate = deviceConfig.get("rate",2857143).asInt(); + + LedDeviceWs2812SPI* deviceWs2812SPI = new LedDeviceWs2812SPI(output, rate); + deviceWs2812SPI->open(); + + device = deviceWs2812SPI; + } #endif #ifdef ENABLE_TINKERFORGE else if (type=="tinkerforge") diff --git a/libsrc/leddevice/LedDeviceWs2812SPI.cpp b/libsrc/leddevice/LedDeviceWs2812SPI.cpp new file mode 100644 index 00000000..7b915595 --- /dev/null +++ b/libsrc/leddevice/LedDeviceWs2812SPI.cpp @@ -0,0 +1,57 @@ + +// STL includes +#include +#include +#include + +// Linux includes +#include +#include + +// hyperion local includes +#include "LedDeviceWs2812SPI.h" + +LedDeviceWs2812SPI::LedDeviceWs2812SPI(const std::string& outputDevice, const unsigned baudrate) : + LedSpiDevice(outputDevice, baudrate, 0), + mLedCount(0) +{ + // empty +} + +int LedDeviceWs2812SPI::write(const std::vector &ledValues) +{ + mLedCount = ledValues.size(); + +// 3 colours, 4 spi bytes per colour + 3 frame end latch bytes +#define COLOURS_PER_LED 3 +#define SPI_BYTES_PER_COLOUR 4 +#define SPI_BYTES_PER_LED COLOURS_PER_LED * SPI_BYTES_PER_COLOUR + + unsigned spi_size = mLedCount * SPI_BYTES_PER_LED + 3; + if(_spiBuffer.size() != spi_size){ + _spiBuffer.resize(spi_size, 0x00); + } + + unsigned spi_ptr = 0; + for (unsigned i=0; i< mLedCount; ++i) { + uint32_t colorBits = ((unsigned int)ledValues[i].red << 16) + | ((unsigned int)ledValues[i].green << 8) + | ledValues[i].blue; + + for (int j=SPI_BYTES_PER_LED - 1; j>=0; j--) { + _spiBuffer[spi_ptr+j] = bitpair_to_byte[ colorBits & 0x3 ]; + colorBits >>= 2; + } + spi_ptr += SPI_BYTES_PER_LED; + } + _spiBuffer[spi_ptr++] = 0; + _spiBuffer[spi_ptr++] = 0; + _spiBuffer[spi_ptr++] = 0; + + return writeBytes(spi_size, _spiBuffer.data()); +} + +int LedDeviceWs2812SPI::switchOff() +{ + return write(std::vector(mLedCount, ColorRgb{0,0,0})); +} diff --git a/libsrc/leddevice/LedDeviceWs2812SPI.h b/libsrc/leddevice/LedDeviceWs2812SPI.h new file mode 100644 index 00000000..e82d9134 --- /dev/null +++ b/libsrc/leddevice/LedDeviceWs2812SPI.h @@ -0,0 +1,52 @@ +#pragma once + +// STL includes +#include + +// hyperion incluse +#include "LedSpiDevice.h" + +/// +/// Implementation of the LedDevice interface for writing to Ws2801 led device. +/// +class LedDeviceWs2812SPI : public LedSpiDevice +{ +public: + /// + /// Constructs the LedDevice for a string containing leds of the type Ws2812SPI + /// + /// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0') + /// @param baudrate The used baudrate for writing to the output device + /// + LedDeviceWs2812SPI(const std::string& outputDevice, + const unsigned baudrate); + + LedDeviceWs2812SPI(const std::string& outputDevice, + const unsigned baudrate, + const unsigned latchTime); + + /// + /// 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 &ledValues); + + /// Switch the leds off + virtual int switchOff(); + +private: + + /// the number of leds (needed when switching off) + size_t mLedCount; + std::vector _spiBuffer; + + uint8_t bitpair_to_byte[4] = { + 0b10001000, + 0b10001100, + 0b11001000, + 0b11001100, + }; + +};