Added support for sk6812RGBW leds (ab)using the SPI interface. (#61)

right now it only uses RGB - white is set to zero
This commit is contained in:
penfold42 2016-06-28 06:43:35 +10:00 committed by brindosch
parent 2fff9ae4fc
commit 96037da1cf
5 changed files with 123 additions and 4 deletions

View File

@ -79,6 +79,7 @@ if(ENABLE_SPIDEV)
${CURRENT_SOURCE_DIR}/LedDeviceP9813.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.h
${CURRENT_SOURCE_DIR}/LedDeviceSk6812SPI.h
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.h
)
SET(Leddevice_SOURCES
@ -89,6 +90,7 @@ if(ENABLE_SPIDEV)
${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.cpp
${CURRENT_SOURCE_DIR}/LedDeviceSk6812SPI.cpp
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.cpp
)
endif()

View File

@ -17,6 +17,7 @@
#include "LedDeviceP9813.h"
#include "LedDeviceWs2801.h"
#include "LedDeviceWs2812SPI.h"
#include "LedDeviceSk6812SPI.h"
#include "LedDeviceAPA102.h"
#endif
@ -147,6 +148,16 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = deviceWs2812SPI;
}
else if (type == "sk6812spi")
{
const std::string output = deviceConfig["output"].asString();
const unsigned rate = deviceConfig.get("rate",2857143).asInt();
LedDeviceSk6812SPI* deviceSk6812SPI = new LedDeviceSk6812SPI(output, rate);
deviceSk6812SPI->open();
device = deviceSk6812SPI;
}
#endif
#ifdef ENABLE_TINKERFORGE
else if (type=="tinkerforge")

View File

@ -0,0 +1,67 @@
// STL includes
#include <cstring>
#include <cstdio>
#include <iostream>
// Linux includes
#include <fcntl.h>
#include <sys/ioctl.h>
// hyperion local includes
#include "LedDeviceSk6812SPI.h"
LedDeviceSk6812SPI::LedDeviceSk6812SPI(const std::string& outputDevice, const unsigned baudrate) :
LedSpiDevice(outputDevice, baudrate, 0),
mLedCount(0),
bitpair_to_byte {
0b10001000,
0b10001100,
0b11001000,
0b11001100,
}
{
// empty
}
int LedDeviceSk6812SPI::write(const std::vector<ColorRgb> &ledValues)
{
mLedCount = ledValues.size();
// 4 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) {
uint8_t white = 0;
uint32_t colorBits =
((unsigned int)ledValues[i].red << 24) |
((unsigned int)ledValues[i].green << 16) |
((unsigned int)ledValues[i].blue << 8) |
white;
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 LedDeviceSk6812SPI::switchOff()
{
return write(std::vector<ColorRgb>(mLedCount, ColorRgb{0,0,0}));
}

View File

@ -0,0 +1,43 @@
#pragma once
// STL includes
#include <string>
// hyperion incluse
#include "LedSpiDevice.h"
///
/// Implementation of the LedDevice interface for writing to Sk6801 led device.
///
class LedDeviceSk6812SPI : public LedSpiDevice
{
public:
///
/// Constructs the LedDevice for a string containing leds of the type Sk6812SPI
///
/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
/// @param baudrate The used baudrate for writing to the output device
///
LedDeviceSk6812SPI(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<ColorRgb> &ledValues);
/// Switch the leds off
virtual int switchOff();
private:
/// the number of leds (needed when switching off)
size_t mLedCount;
std::vector<uint8_t> _spiBuffer;
uint8_t bitpair_to_byte[4];
};

View File

@ -21,10 +21,6 @@ public:
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
///