hyperion.ng/libsrc/leddevice/dev_ftdi/LedDeviceAPA102_ftdi.cpp
2023-03-25 23:32:14 +00:00

62 lines
1.9 KiB
C++

#include "LedDeviceAPA102_ftdi.h"
#define LED_HEADER 0b11100000
#define LED_BRIGHTNESS_FULL 31
LedDeviceAPA102_ftdi::LedDeviceAPA102_ftdi(const QJsonObject &deviceConfig) : ProviderFtdi(deviceConfig)
{
}
LedDevice *LedDeviceAPA102_ftdi::construct(const QJsonObject &deviceConfig)
{
return new LedDeviceAPA102_ftdi(deviceConfig);
}
bool LedDeviceAPA102_ftdi::init(const QJsonObject &deviceConfig)
{
bool isInitOK = false;
_brightnessControlMaxLevel = deviceConfig["brightnessControlMaxLevel"].toInt(LED_BRIGHTNESS_FULL);
Info(_log, "[%s] Setting maximum brightness to [%d] = %d%%", QSTRING_CSTR(_activeDeviceType), _brightnessControlMaxLevel, _brightnessControlMaxLevel * 100 / LED_BRIGHTNESS_FULL);
// Initialise sub-class
if (ProviderFtdi::init(deviceConfig))
{
CreateHeader();
isInitOK = true;
}
return isInitOK;
}
void LedDeviceAPA102_ftdi::CreateHeader()
{
const unsigned int startFrameSize = 4;
// Endframe, add additional 4 bytes to cover SK9922 Reset frame (in case SK9922 were sold as AP102) - has no effect on APA102
const unsigned int endFrameSize = (_ledCount / 32) * 4 + 4;
const unsigned int APAbufferSize = (_ledCount * 4) + startFrameSize + endFrameSize;
_ledBuffer.resize(APAbufferSize, 0);
Debug(_log, "APA102 buffer created. Led's number: %d", _ledCount);
}
int LedDeviceAPA102_ftdi::write(const std::vector<ColorRgb> &ledValues)
{
if (_ledCount != ledValues.size())
{
Warning(_log, "APA102 led's number has changed (old: %d, new: %d). Rebuilding buffer.", _ledCount, ledValues.size());
_ledCount = ledValues.size();
CreateHeader();
}
for (signed iLed = 0; iLed < static_cast<int>(_ledCount); ++iLed)
{
const ColorRgb &rgb = ledValues[iLed];
_ledBuffer[4 + iLed * 4 + 0] = LED_HEADER | _brightnessControlMaxLevel;
_ledBuffer[4 + iLed * 4 + 1] = rgb.red;
_ledBuffer[4 + iLed * 4 + 2] = rgb.green;
_ledBuffer[4 + iLed * 4 + 3] = rgb.blue;
}
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}