mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Implemented the Ldp6803 device.
Former-commit-id: e38f7d697fbf137d89bfefb1503848a771f51dad
This commit is contained in:
parent
f158236910
commit
518ca910b7
@ -10,8 +10,9 @@
|
|||||||
#include <hyperion/LedDevice.h>
|
#include <hyperion/LedDevice.h>
|
||||||
#include <hyperion/ImageProcessorFactory.h>
|
#include <hyperion/ImageProcessorFactory.h>
|
||||||
|
|
||||||
#include "LedDeviceWs2801.h"
|
#include "LedDeviceLdp6803.h"
|
||||||
#include "LedDeviceTest.h"
|
#include "LedDeviceTest.h"
|
||||||
|
#include "LedDeviceWs2801.h"
|
||||||
|
|
||||||
#include "LinearColorSmoothing.h"
|
#include "LinearColorSmoothing.h"
|
||||||
|
|
||||||
@ -36,9 +37,20 @@ LedDevice* Hyperion::createDevice(const Json::Value& deviceConfig)
|
|||||||
|
|
||||||
device = deviceWs2801;
|
device = deviceWs2801;
|
||||||
}
|
}
|
||||||
|
else if (type == "ldp6803")
|
||||||
|
{
|
||||||
|
const std::string output = deviceConfig["output"].asString();
|
||||||
|
const unsigned rate = deviceConfig["rate"].asInt();
|
||||||
|
|
||||||
|
LedDeviceLdp6803* deviceLdp6803 = new LedDeviceLdp6803(output, rate);
|
||||||
|
deviceLdp6803->open();
|
||||||
|
|
||||||
|
device = deviceLdp6803;
|
||||||
|
}
|
||||||
else if (type == "test")
|
else if (type == "test")
|
||||||
{
|
{
|
||||||
device = new LedDeviceTest();
|
const std::string output = deviceConfig["output"].asString();
|
||||||
|
device = new LedDeviceTest(output);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -10,80 +10,48 @@
|
|||||||
// hyperion local includes
|
// hyperion local includes
|
||||||
#include "LedDeviceLdp6803.h"
|
#include "LedDeviceLdp6803.h"
|
||||||
|
|
||||||
LedDeviceLDP6803::LedDeviceLDP6803(const std::string& outputDevice, const unsigned baudrate) :
|
LedDeviceLdp6803::LedDeviceLdp6803(const std::string& outputDevice, const unsigned baudrate) :
|
||||||
LedSpiDevice(outputDevice, baudrate),
|
LedSpiDevice(outputDevice, baudrate),
|
||||||
mLedCount(0)
|
_ledBuffer(0)
|
||||||
{
|
{
|
||||||
latchTime.tv_sec = 0;
|
// empty
|
||||||
latchTime.tv_nsec = 500000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceLDP6803::write(const std::vector<RgbColor> &ledValues)
|
int LedDeviceLdp6803::write(const std::vector<RgbColor> &ledValues)
|
||||||
{
|
{
|
||||||
mLedCount = ledValues.size();
|
// Reconfigure if the current connfiguration does not match the required configuration
|
||||||
|
if (ledValues.size() != _ledBuffer.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;
|
// Initialise the buffer with all 'black' values
|
||||||
return -1;
|
_ledBuffer.resize(ledValues.size() + 2, 0x80);
|
||||||
|
_ledBuffer[0] = 0;
|
||||||
|
_ledBuffer[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_buff = reinterpret_cast<const uint8_t*>(ledValues.data());
|
// Copy the colors from the RgbColor vector to the Ldp6803Rgb vector
|
||||||
|
for (unsigned iLed=0; iLed<ledValues.size(); ++iLed)
|
||||||
// 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)
|
const RgbColor& rgb = ledValues[iLed];
|
||||||
nanosleep(&latchTime, NULL);
|
|
||||||
|
const char packedRed = rgb.red & 0xf8;
|
||||||
|
const char packedGreen = rgb.green & 0xf8;
|
||||||
|
const char packedBlue = rgb.blue & 0xf8;
|
||||||
|
const unsigned short packedRgb = 0x80 | (packedRed << 7) | (packedGreen << 2) | (packedBlue >> 3);
|
||||||
|
|
||||||
|
_ledBuffer[iLed + 2] = packedRgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
// Write the data
|
||||||
|
const unsigned bufCnt = _ledBuffer.size() * sizeof(short);
|
||||||
|
const char * bufPtr = reinterpret_cast<const char *>(_ledBuffer.data());
|
||||||
|
if (latch(bufCnt, bufPtr, 0) < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceLDP6803::switchOff()
|
int LedDeviceLdp6803::switchOff()
|
||||||
{
|
{
|
||||||
return write(std::vector<RgbColor>(mLedCount, RgbColor::BLACK));
|
return write(std::vector<RgbColor>(_ledBuffer.size(), RgbColor::BLACK));
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,15 @@
|
|||||||
///
|
///
|
||||||
/// Implementation of the LedDevice interface for writing to LDP6803 led device.
|
/// Implementation of the LedDevice interface for writing to LDP6803 led device.
|
||||||
///
|
///
|
||||||
class LedDeviceLDP6803 : public LedSpiDevice
|
/// 00000000 00000000 00000000 00000000 1XXXXXYY YYYZZZZZ 1XXXXXYY YYYZZZZZ ...
|
||||||
|
/// |---------------------------------| |---------------| |---------------|
|
||||||
|
/// 32 zeros to start the frame Led1 Led2 ...
|
||||||
|
///
|
||||||
|
/// For each led, the first bit is always 1, and then you have 5 bits each for red, green and blue
|
||||||
|
/// (X, Y and Z in the above illustration) making 16 bits per led. Total bits = 32 + (16 x number of
|
||||||
|
/// leds)
|
||||||
|
///
|
||||||
|
class LedDeviceLdp6803 : public LedSpiDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
@ -15,7 +23,7 @@ public:
|
|||||||
/// @param[in] outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
|
/// @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
|
/// @param[in] baudrate The used baudrate for writing to the output device
|
||||||
///
|
///
|
||||||
LedDeviceLDP6803(const std::string& outputDevice, const unsigned baudrate);
|
LedDeviceLdp6803(const std::string& outputDevice, const unsigned baudrate);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes the led color values to the led-device
|
/// Writes the led color values to the led-device
|
||||||
@ -29,9 +37,5 @@ public:
|
|||||||
virtual int switchOff();
|
virtual int switchOff();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The 'latch' time for latching the shifted-value into the leds
|
std::vector<unsigned short> _ledBuffer;
|
||||||
timespec latchTime;
|
|
||||||
|
|
||||||
/// the number of leds (needed when switching off)
|
|
||||||
size_t mLedCount;
|
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// Local-Hyperion includes
|
// Local-Hyperion includes
|
||||||
#include "LedDeviceTest.h"
|
#include "LedDeviceTest.h"
|
||||||
|
|
||||||
LedDeviceTest::LedDeviceTest() :
|
LedDeviceTest::LedDeviceTest(const std::string& output) :
|
||||||
_ofs("/home/pi/LedDevice.out")
|
_ofs(output.empty()?"/home/pi/LedDevice.out":output.c_str())
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// Constructs the test-device, which opens an output stream to the file
|
/// Constructs the test-device, which opens an output stream to the file
|
||||||
///
|
///
|
||||||
LedDeviceTest();
|
LedDeviceTest(const std::string& output);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destructor of this test-device
|
/// Destructor of this test-device
|
||||||
|
@ -15,31 +15,17 @@ LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, const unsigned
|
|||||||
LedSpiDevice(outputDevice, baudrate),
|
LedSpiDevice(outputDevice, baudrate),
|
||||||
mLedCount(0)
|
mLedCount(0)
|
||||||
{
|
{
|
||||||
latchTime.tv_sec = 0;
|
// empty
|
||||||
latchTime.tv_nsec = 500000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceWs2801::write(const std::vector<RgbColor> &ledValues)
|
int LedDeviceWs2801::write(const std::vector<RgbColor> &ledValues)
|
||||||
{
|
{
|
||||||
mLedCount = ledValues.size();
|
mLedCount = ledValues.size();
|
||||||
|
|
||||||
if (mFid < 0)
|
const unsigned dataLen = ledValues.size() * sizeof(RgbColor);
|
||||||
{
|
const char * dataPtr = reinterpret_cast<const char *>(ledValues.data());
|
||||||
std::cerr << "Can not write to device which is open." << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
spi.tx_buf = (__u64)ledValues.data();
|
|
||||||
spi.len = ledValues.size() * sizeof(RgbColor);
|
|
||||||
|
|
||||||
int retVal = ioctl(mFid, SPI_IOC_MESSAGE(1), &spi);
|
|
||||||
|
|
||||||
if (retVal == 0)
|
|
||||||
{
|
|
||||||
// Sleep to latch the leds (only if write succesfull)
|
|
||||||
nanosleep(&latchTime, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const int retVal = latch(dataLen, dataPtr, 500000);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,6 @@ public:
|
|||||||
virtual int switchOff();
|
virtual int switchOff();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The 'latch' time for latching the shifted-value into the leds
|
|
||||||
timespec latchTime;
|
|
||||||
|
|
||||||
/// the number of leds (needed when switching off)
|
/// the number of leds (needed when switching off)
|
||||||
size_t mLedCount;
|
size_t mLedCount;
|
||||||
|
@ -55,3 +55,31 @@ int LedSpiDevice::open()
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LedSpiDevice::latch(const unsigned len, const char * vec, const int latchTime_ns)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mFid < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi.tx_buf = __u64(vec);
|
||||||
|
spi.len = __u32(len);
|
||||||
|
|
||||||
|
int retVal = ioctl(mFid, SPI_IOC_MESSAGE(1), &spi);
|
||||||
|
|
||||||
|
if (retVal == 0 && latchTime_ns > 0)
|
||||||
|
{
|
||||||
|
// The 'latch' time for latching the shifted-value into the leds
|
||||||
|
timespec latchTime;
|
||||||
|
latchTime.tv_sec = 0;
|
||||||
|
latchTime.tv_nsec = latchTime_ns;
|
||||||
|
|
||||||
|
// Sleep to latch the leds (only if write succesfull)
|
||||||
|
nanosleep(&latchTime, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -32,13 +32,26 @@ public:
|
|||||||
///
|
///
|
||||||
int open();
|
int open();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Writes the given bytes/bits to the SPI-device and sleeps the latch time to ensure that the
|
||||||
|
* values are latched.
|
||||||
|
*
|
||||||
|
* @param[in[ len The length of the data
|
||||||
|
* @param[in] vec The data
|
||||||
|
* @param[in] latchTime_ns The latch-time to latch in the values across the SPI-device (negative
|
||||||
|
* means no latch required) [ns]
|
||||||
|
*
|
||||||
|
* @return Zero on succes else negative
|
||||||
|
*/
|
||||||
|
int latch(const unsigned len, const char * vec, const int latchTime_ns);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The name of the output device
|
/// The name of the output device
|
||||||
const std::string mDeviceName;
|
const std::string mDeviceName;
|
||||||
/// The used baudrate of the output device
|
/// The used baudrate of the output device
|
||||||
const int mBaudRate_Hz;
|
const int mBaudRate_Hz;
|
||||||
|
|
||||||
protected:
|
|
||||||
/// The File Identifier of the opened output device (or -1 if not opened)
|
/// The File Identifier of the opened output device (or -1 if not opened)
|
||||||
int mFid;
|
int mFid;
|
||||||
/// The transfer structure for writing to the spi-device
|
/// The transfer structure for writing to the spi-device
|
||||||
|
Loading…
Reference in New Issue
Block a user