diff --git a/libsrc/hyperion/CMakeLists.txt b/libsrc/hyperion/CMakeLists.txt index f881e8b8..8f52d048 100644 --- a/libsrc/hyperion/CMakeLists.txt +++ b/libsrc/hyperion/CMakeLists.txt @@ -20,8 +20,10 @@ SET(Hyperion_HEADERS ${CURRENT_SOURCE_DIR}/BlackBorderDetector.h ${CURRENT_SOURCE_DIR}/BlackBorderProcessor.h ${CURRENT_SOURCE_DIR}/ImageToLedsMap.h + ${CURRENT_SOURCE_DIR}/LedSpiDevice.h ${CURRENT_SOURCE_DIR}/LedDeviceTest.h ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h + ${CURRENT_SOURCE_DIR}/LedDeviceLdp6803.h ) SET(Hyperion_SOURCES @@ -34,8 +36,10 @@ SET(Hyperion_SOURCES ${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp ${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp ${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp - ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp + ${CURRENT_SOURCE_DIR}/LedSpiDevice.cpp ${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceLdp6803.cpp ${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp ) diff --git a/libsrc/hyperion/LedDeviceLdp6803.cpp b/libsrc/hyperion/LedDeviceLdp6803.cpp new file mode 100644 index 00000000..df476c23 --- /dev/null +++ b/libsrc/hyperion/LedDeviceLdp6803.cpp @@ -0,0 +1,89 @@ +// STL includes +#include +#include +#include + +// Linux includes +#include +#include + +// hyperion local includes +#include "LedDeviceLdp6803.h" + +LedDeviceLDP6803::LedDeviceLDP6803(const std::string& outputDevice, const unsigned baudrate) : + LedSpiDevice(outputDevice, baudrate), + mLedCount(0) +{ + latchTime.tv_sec = 0; + latchTime.tv_nsec = 500000; +} + +int LedDeviceLDP6803::write(const std::vector &ledValues) +{ + mLedCount = ledValues.size(); + + // Define buffer sizes based on number of leds + // buffsize for actual buffer to be sent via SPI pins + // tempbuffsize for RGB data processing. + // buffsize = 4 zero bytes + 2 bytes per LED + // tempbuffsize will hold RGB values, so 3 bytes per LED + + int buffsize = (mLedCount * 2) + 4; + int tempbuffsize = mLedCount *3; + int i,r,g,b,d,count; + + uint8_t m_buff[buffsize]; + const uint8_t *temp_buff;//[tempbuffsize]; + + if (mFid < 0) + { + std::cerr << "Can not write to device which is open." << std::endl; + return -1; + } + + temp_buff = reinterpret_cast(ledValues.data()); + + // set first 4 bytes to zero + m_buff[0]=0; + m_buff[1]=0; + m_buff[2]=0; + m_buff[3]=0; + + // Set counter + count=4; + + // Now process RGB values: 0-255 to be + // converted to 0-31, with bits combined + // to match hardware protocol + + for (i=0 ; i < tempbuffsize ; i+=3) { + r = temp_buff[i] >> 3; + g = temp_buff[i+1] >> 3; + b = temp_buff[i+2] >> 3; + + d = (r * 1024) + (g * 32) + b + 32768; + + m_buff[count] = d >> 8; + m_buff[count+1] = d & 0x00FF; + + count += 2; + } + + spi.tx_buf = __u64(m_buff); + spi.len = buffsize; + + int retVal = ioctl(mFid, SPI_IOC_MESSAGE(1), &spi); + + if (retVal == 0) + { + // Sleep to latch the leds (only if write succesfull) + nanosleep(&latchTime, NULL); + } + + return retVal; +} + +int LedDeviceLDP6803::switchOff() +{ + return write(std::vector(mLedCount, RgbColor::BLACK)); +} diff --git a/libsrc/hyperion/LedDeviceLdp6803.h b/libsrc/hyperion/LedDeviceLdp6803.h new file mode 100644 index 00000000..b785d5f4 --- /dev/null +++ b/libsrc/hyperion/LedDeviceLdp6803.h @@ -0,0 +1,37 @@ +#pragma once + +// Local hyperion incluse +#include "LedSpiDevice.h" + +/// +/// Implementation of the LedDevice interface for writing to LDP6803 led device. +/// +class LedDeviceLDP6803 : public LedSpiDevice +{ +public: + /// + /// Constructs the LedDevice for a string containing leds of the type LDP6803 + /// + /// @param[in] outputDevice The name of the output device (eg '/etc/SpiDev.0.0') + /// @param[in] baudrate The used baudrate for writing to the output device + /// + LedDeviceLDP6803(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 'latch' time for latching the shifted-value into the leds + timespec latchTime; + + /// the number of leds (needed when switching off) + size_t mLedCount; +}; diff --git a/libsrc/hyperion/LedDeviceWs2801.cpp b/libsrc/hyperion/LedDeviceWs2801.cpp index b4d60013..2bcf0e18 100644 --- a/libsrc/hyperion/LedDeviceWs2801.cpp +++ b/libsrc/hyperion/LedDeviceWs2801.cpp @@ -11,54 +11,12 @@ // hyperion local includes #include "LedDeviceWs2801.h" -LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, - const unsigned baudrate) : - mDeviceName(outputDevice), - mBaudRate_Hz(baudrate), - mFid(-1), +LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, const unsigned baudrate) : + LedSpiDevice(outputDevice, baudrate), mLedCount(0) { - memset(&spi, 0, sizeof(spi)); - latchTime.tv_sec = 0; latchTime.tv_nsec = 500000; - -} - -LedDeviceWs2801::~LedDeviceWs2801() -{ -// close(mFid); -} - -int LedDeviceWs2801::open() -{ - const int bitsPerWord = 8; - - mFid = ::open(mDeviceName.c_str(), O_RDWR); - - if (mFid < 0) - { - std::cerr << "Failed to open device('" << mDeviceName << "') " << std::endl; - return -1; - } - - int mode = SPI_MODE_0; - if (ioctl(mFid, SPI_IOC_WR_MODE, &mode) == -1 || ioctl(mFid, SPI_IOC_RD_MODE, &mode) == -1) - { - return -2; - } - - if (ioctl(mFid, SPI_IOC_WR_BITS_PER_WORD, &bitsPerWord) == -1 || ioctl(mFid, SPI_IOC_RD_BITS_PER_WORD, &bitsPerWord) == -1) - { - return -4; - } - - if (ioctl(mFid, SPI_IOC_WR_MAX_SPEED_HZ, &mBaudRate_Hz) == -1 || ioctl(mFid, SPI_IOC_RD_MAX_SPEED_HZ, &mBaudRate_Hz) == -1) - { - return -6; - } - - return 0; } int LedDeviceWs2801::write(const std::vector &ledValues) diff --git a/libsrc/hyperion/LedDeviceWs2801.h b/libsrc/hyperion/LedDeviceWs2801.h index 2aed1b4b..2a2dd365 100644 --- a/libsrc/hyperion/LedDeviceWs2801.h +++ b/libsrc/hyperion/LedDeviceWs2801.h @@ -3,16 +3,13 @@ // STL includes #include -// Linux-SPI includes -#include - // hyperion incluse -#include +#include "LedSpiDevice.h" /// /// Implementation of the LedDevice interface for writing to Ws2801 led device. /// -class LedDeviceWs2801 : public LedDevice +class LedDeviceWs2801 : public LedSpiDevice { public: /// @@ -24,18 +21,6 @@ public: LedDeviceWs2801(const std::string& outputDevice, const unsigned baudrate); - /// - /// Destructor of the LedDevice; closes the output device if it is open - /// - virtual ~LedDeviceWs2801(); - - /// - /// Opens and configures the output device - /// - /// @return Zero on succes else negative - /// - int open(); - /// /// Writes the led color values to the led-device /// @@ -48,15 +33,6 @@ public: virtual int switchOff(); private: - /// The name of the output device - const std::string mDeviceName; - /// The used baudrate of the output device - const int mBaudRate_Hz; - - /// The File Identifier of the opened output device (or -1 if not opened) - int mFid; - /// The transfer structure for writing to the spi-device - spi_ioc_transfer spi; /// The 'latch' time for latching the shifted-value into the leds timespec latchTime; diff --git a/libsrc/hyperion/LedSpiDevice.cpp b/libsrc/hyperion/LedSpiDevice.cpp new file mode 100644 index 00000000..b5c80fbb --- /dev/null +++ b/libsrc/hyperion/LedSpiDevice.cpp @@ -0,0 +1,57 @@ + +// STL includes +#include +#include +#include + +// Linux includes +#include +#include + +// Local Hyperion includes +#include "LedSpiDevice.h" + + +LedSpiDevice::LedSpiDevice(const std::string& outputDevice, const unsigned baudrate) : + mDeviceName(outputDevice), + mBaudRate_Hz(baudrate), + mFid(-1) +{ + memset(&spi, 0, sizeof(spi)); +} + +LedSpiDevice::~LedSpiDevice() +{ +// close(mFid); +} + +int LedSpiDevice::open() +{ + const int bitsPerWord = 8; + + mFid = ::open(mDeviceName.c_str(), O_RDWR); + + if (mFid < 0) + { + std::cerr << "Failed to open device('" << mDeviceName << "') " << std::endl; + return -1; + } + + int mode = SPI_MODE_0; + if (ioctl(mFid, SPI_IOC_WR_MODE, &mode) == -1 || ioctl(mFid, SPI_IOC_RD_MODE, &mode) == -1) + { + return -2; + } + + if (ioctl(mFid, SPI_IOC_WR_BITS_PER_WORD, &bitsPerWord) == -1 || ioctl(mFid, SPI_IOC_RD_BITS_PER_WORD, &bitsPerWord) == -1) + { + return -4; + } + + if (ioctl(mFid, SPI_IOC_WR_MAX_SPEED_HZ, &mBaudRate_Hz) == -1 || ioctl(mFid, SPI_IOC_RD_MAX_SPEED_HZ, &mBaudRate_Hz) == -1) + { + return -6; + } + + return 0; +} diff --git a/libsrc/hyperion/LedSpiDevice.h b/libsrc/hyperion/LedSpiDevice.h new file mode 100644 index 00000000..b22b5856 --- /dev/null +++ b/libsrc/hyperion/LedSpiDevice.h @@ -0,0 +1,46 @@ +#pragma once + +// Linux-SPI includes +#include + +// Hyperion includes +#include + +/// +/// The LedSpiDevice implements an abstract base-class for LedDevices using the SPI-device. +/// +class LedSpiDevice : public LedDevice +{ +public: + /// + /// Constructs the LedDevice attached to a SPI-device + /// + /// @param[in] outputDevice The name of the output device (eg '/etc/SpiDev.0.0') + /// @param[in] baudrate The used baudrate for writing to the output device + /// + LedSpiDevice(const std::string& outputDevice, const unsigned baudrate); + + /// + /// Destructor of the LedDevice; closes the output device if it is open + /// + virtual ~LedSpiDevice(); + + /// + /// Opens and configures the output device + /// + /// @return Zero on succes else negative + /// + int open(); + +private: + /// The name of the output device + const std::string mDeviceName; + /// The used baudrate of the output device + const int mBaudRate_Hz; + +protected: + /// The File Identifier of the opened output device (or -1 if not opened) + int mFid; + /// The transfer structure for writing to the spi-device + spi_ioc_transfer spi; +};