2014-12-03 09:35:10 +01:00
|
|
|
// STL includes
|
|
|
|
#include <cstring>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
// Linux includes
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
|
|
|
// hyperion local includes
|
|
|
|
#include "LedDeviceAPA102.h"
|
|
|
|
|
|
|
|
LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate) :
|
|
|
|
LedSpiDevice(outputDevice, baudrate, 500000),
|
2014-12-11 13:48:14 +01:00
|
|
|
_ledBuffer(0)
|
2014-12-03 09:35:10 +01:00
|
|
|
{
|
|
|
|
// empty
|
|
|
|
}
|
|
|
|
|
2015-08-09 16:15:25 +02:00
|
|
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
|
|
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
|
|
|
|
|
|
|
#define APA102_START_FRAME_BYTES 4
|
|
|
|
#define APA102_LED_BYTES 4
|
|
|
|
#define APA102_END_FRAME_BITS_MIN 32
|
|
|
|
#define APA102_END_FRAME_BITS(leds) MAX((((leds-1)/2)+1),APA102_END_FRAME_BITS_MIN)
|
|
|
|
#define APA102_END_FRAME_BYTES(leds) (((APA102_END_FRAME_BITS(leds)-1)/8)+1)
|
|
|
|
#define APA102_LED_HEADER 0xe0
|
|
|
|
#define APA102_LED_MAX_INTENSITY 0x1f
|
|
|
|
|
2014-12-03 09:35:10 +01:00
|
|
|
int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
|
|
|
|
{
|
2015-08-09 16:15:25 +02:00
|
|
|
const unsigned int startFrameSize = APA102_START_FRAME_BYTES;
|
2016-02-07 17:40:24 +01:00
|
|
|
const unsigned int ledsCount = ledValues.size() ;
|
|
|
|
const unsigned int ledsSize = ledsCount * APA102_LED_BYTES ;
|
|
|
|
const unsigned int endFrameBits = APA102_END_FRAME_BITS(ledsCount) ;
|
|
|
|
const unsigned int endFrameSize = APA102_END_FRAME_BYTES(ledsCount) ;
|
|
|
|
const unsigned int transferSize = startFrameSize + ledsSize + endFrameSize ;
|
2015-08-09 16:15:25 +02:00
|
|
|
|
|
|
|
if(_ledBuffer.size() != transferSize){
|
|
|
|
_ledBuffer.resize(transferSize, 0x00);
|
2016-02-07 17:40:24 +01:00
|
|
|
}
|
2015-08-09 16:15:25 +02:00
|
|
|
|
|
|
|
unsigned idx = 0, i;
|
|
|
|
for (i=0; i<APA102_START_FRAME_BYTES; i++) {
|
|
|
|
_ledBuffer[idx++] = 0x00 ;
|
2015-11-04 14:05:09 +01:00
|
|
|
}
|
2014-12-03 09:35:10 +01:00
|
|
|
|
2015-08-09 16:15:25 +02:00
|
|
|
for (i=0; i<ledsCount; i++) {
|
|
|
|
const ColorRgb& rgb = ledValues[i];
|
|
|
|
|
|
|
|
_ledBuffer[idx++] = APA102_LED_HEADER + APA102_LED_MAX_INTENSITY;
|
|
|
|
_ledBuffer[idx++] = rgb.red;
|
|
|
|
_ledBuffer[idx++] = rgb.green;
|
|
|
|
_ledBuffer[idx++] = rgb.blue;
|
2014-12-11 13:48:14 +01:00
|
|
|
}
|
2015-08-09 16:15:25 +02:00
|
|
|
for(i=0; i<endFrameSize; i++)
|
2016-02-07 17:40:24 +01:00
|
|
|
_ledBuffer[idx++] = 0x00 ;
|
2014-12-03 09:35:10 +01:00
|
|
|
|
2014-12-11 13:48:14 +01:00
|
|
|
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
|
2014-12-03 09:35:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int LedDeviceAPA102::switchOff()
|
|
|
|
{
|
2014-12-11 13:48:14 +01:00
|
|
|
return write(std::vector<ColorRgb>(_ledBuffer.size(), ColorRgb{0,0,0}));
|
2016-02-07 17:40:24 +01:00
|
|
|
}
|