diff --git a/libsrc/leddevice/CMakeLists.txt b/libsrc/leddevice/CMakeLists.txt index 11504e36..63159184 100644 --- a/libsrc/leddevice/CMakeLists.txt +++ b/libsrc/leddevice/CMakeLists.txt @@ -55,6 +55,7 @@ if(ENABLE_SPIDEV) ${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.h ${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.h ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h + ${CURRENT_SOURCE_DIR}/LedDeviceP9813.h ) SET(Leddevice_SOURCES ${Leddevice_SOURCES} @@ -62,6 +63,7 @@ if(ENABLE_SPIDEV) ${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.cpp ${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.cpp ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp ) endif(ENABLE_SPIDEV) diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 2f7b3a6b..3b7ce9fd 100644 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -10,6 +10,7 @@ #include "LedDeviceLpd6803.h" #include "LedDeviceLpd8806.h" #include "LedDeviceWs2801.h" + #include "LedDeviceP9813.h" #endif #include "LedDeviceAdalight.h" @@ -145,6 +146,16 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) device = deviceWs2812b; } + else if (type == "p9813") + { + const std::string output = deviceConfig["output"].asString(); + const unsigned rate = deviceConfig["rate"].asInt(); + + LedDeviceP9813* deviceP9813 = new LedDeviceP9813(output, rate); + deviceP9813->open(); + + device = deviceP9813; + } else { std::cout << "Unable to create device " << type << std::endl; diff --git a/libsrc/leddevice/LedDeviceP9813.cpp b/libsrc/leddevice/LedDeviceP9813.cpp new file mode 100644 index 00000000..6b0654ef --- /dev/null +++ b/libsrc/leddevice/LedDeviceP9813.cpp @@ -0,0 +1,56 @@ + +// STL includes +#include +#include +#include + +// Linux includes +#include +#include + +// hyperion local includes +#include "LedDeviceP9813.h" + +LedDeviceP9813::LedDeviceP9813(const std::string& outputDevice, const unsigned baudrate) : + LedSpiDevice(outputDevice, baudrate, 0), + mLedCount(0) +{ + // empty +} + +int LedDeviceP9813::write(const std::vector &ledValues) +{ + mLedCount = ledValues.size(); + + const unsigned dataLen = ledValues.size() * 4 + 8; + uint8_t data[dataLen]; + + memset(data, 0x00, dataLen); + + int j = 4; + for (unsigned i = 0; i < mLedCount; i++){ + data[j++] = calculateChecksum(ledValues[i]); + data[j++] = ledValues[i].blue; + data[j++] = ledValues[i].green; + data[j++] = ledValues[i].red; + } + + return writeBytes(dataLen, data); +} + +int LedDeviceP9813::switchOff() +{ + return write(std::vector(mLedCount, ColorRgb{0,0,0})); +} + +const uint8_t LedDeviceP9813::calculateChecksum(const ColorRgb color) +{ + uint8_t res = 0; + + res |= (uint8_t)0x03 << 6; + res |= (uint8_t)(~(color.blue >> 6) & 0x03) << 4; + res |= (uint8_t)(~(color.green >> 6) & 0x03) << 2; + res |= (uint8_t)(~(color.red >> 6) & 0x03); + + return res; +} diff --git a/libsrc/leddevice/LedDeviceP9813.h b/libsrc/leddevice/LedDeviceP9813.h new file mode 100644 index 00000000..a76df140 --- /dev/null +++ b/libsrc/leddevice/LedDeviceP9813.h @@ -0,0 +1,40 @@ +#pragma once + +// STL includes +#include + +// hyperion include +#include "LedSpiDevice.h" + +/// +/// Implementation of the LedDevice interface for writing to P9813 led device. +/// +class LedDeviceP9813 : public LedSpiDevice +{ +public: + /// + /// Constructs the LedDevice for a string containing leds of the type P9813 + /// + /// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0') + /// @param baudrate The used baudrate for writing to the output device + /// + LedDeviceP9813(const std::string& outputDevice, + const unsigned baudrate); + + /// + /// 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 + size_t mLedCount; + const uint8_t calculateChecksum(const ColorRgb color); +};