Correct line-endings
This commit is contained in:
parent
b93f73a458
commit
5c0ac6abbc
|
@ -1,222 +1,222 @@
|
|||
#include "LedDeviceAdalight.h"
|
||||
|
||||
#include <QtEndian>
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
|
||||
// Configuration settings
|
||||
const char CONFIG_STREAM_PROTOCOL[] = "streamProtocol";
|
||||
|
||||
const char CONFIG_WHITE_CHANNEL_CALLIBRATION[] = "white_channel_calibration";
|
||||
const char CONFIG_WHITE_CHANNEL_LIMIT[] = "white_channel_limit";
|
||||
const char CONFIG_WHITE_CHANNEL_RED[] = "white_channel_red";
|
||||
const char CONFIG_WHITE_CHANNEL_GREEN[] = "white_channel_green";
|
||||
const char CONFIG_WHITE_CHANNEL_BLUE[] = "white_channel_blue";
|
||||
constexpr int HEADER_SIZE {6};
|
||||
|
||||
} //End of constants
|
||||
|
||||
LedDeviceAdalight::LedDeviceAdalight(const QJsonObject &deviceConfig)
|
||||
: ProviderRs232(deviceConfig)
|
||||
{
|
||||
}
|
||||
|
||||
LedDevice* LedDeviceAdalight::construct(const QJsonObject &deviceConfig)
|
||||
{
|
||||
return new LedDeviceAdalight(deviceConfig);
|
||||
}
|
||||
|
||||
bool LedDeviceAdalight::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
bool isInitOK = false;
|
||||
|
||||
// Initialise sub-class
|
||||
if ( ProviderRs232::init(deviceConfig) )
|
||||
{
|
||||
_streamProtocol = static_cast<Adalight::PROTOCOLTYPE>(deviceConfig[CONFIG_STREAM_PROTOCOL].toString().toInt());
|
||||
switch (_streamProtocol) {
|
||||
|
||||
case Adalight::AWA:
|
||||
{
|
||||
Debug( _log, "Adalight driver uses Hyperserial protocol");
|
||||
_white_channel_calibration = deviceConfig[CONFIG_WHITE_CHANNEL_CALLIBRATION].toBool(false);
|
||||
double _white_channel_limit_percent = deviceConfig[CONFIG_WHITE_CHANNEL_LIMIT].toDouble(1);
|
||||
_white_channel_limit = static_cast<uint8_t>(qMin(qRound(_white_channel_limit_percent * 255.0 / 100.0), 255));
|
||||
_white_channel_red = static_cast<uint8_t>(qMin(deviceConfig[CONFIG_WHITE_CHANNEL_RED].toInt(255), 255));
|
||||
_white_channel_green = static_cast<uint8_t>(qMin(deviceConfig[CONFIG_WHITE_CHANNEL_GREEN].toInt(255), 255));
|
||||
_white_channel_blue = static_cast<uint8_t>(qMin(deviceConfig[CONFIG_WHITE_CHANNEL_BLUE].toInt(255), 255));
|
||||
|
||||
DebugIf(_white_channel_calibration, _log, "White channel limit: %i (%.2f%), red: %i, green: %i, blue: %i", _white_channel_limit, _white_channel_limit_percent, _white_channel_red, _white_channel_green, _white_channel_blue);
|
||||
}
|
||||
break;
|
||||
|
||||
case Adalight::LBAPA:
|
||||
Debug( _log, "Adalight driver uses LightBerry APA102 protocol");
|
||||
break;
|
||||
|
||||
case Adalight::ADA:
|
||||
Debug( _log, "Adalight driver uses standard Adalight protocol");
|
||||
break;
|
||||
default:
|
||||
Error( _log, "Adalight driver - unsupported protocol");
|
||||
return false;
|
||||
}
|
||||
|
||||
prepareHeader();
|
||||
isInitOK = true;
|
||||
}
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
void LedDeviceAdalight::prepareHeader()
|
||||
{
|
||||
// create ledBuffer
|
||||
uint totalLedCount = _ledCount;
|
||||
_bufferLength = static_cast<qint64>(HEADER_SIZE + _ledRGBCount);
|
||||
|
||||
switch (_streamProtocol) {
|
||||
case Adalight::LBAPA:
|
||||
{
|
||||
const unsigned int startFrameSize = 4;
|
||||
const unsigned int bytesPerRGBLed = 4;
|
||||
const unsigned int endFrameSize = qMax<unsigned int>(((_ledCount + 15) / 16), bytesPerRGBLed);
|
||||
_bufferLength = HEADER_SIZE + (_ledCount * bytesPerRGBLed) + startFrameSize + endFrameSize;
|
||||
|
||||
_ledBuffer.resize(static_cast<size_t>(_bufferLength), 0x00);
|
||||
|
||||
// init constant data values
|
||||
for (uint iLed=1; iLed <= _ledCount; iLed++)
|
||||
{
|
||||
_ledBuffer[iLed*4+HEADER_SIZE] = 0xFF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Adalight::AWA:
|
||||
_bufferLength += 8;
|
||||
[[fallthrough]];
|
||||
case Adalight::ADA:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
totalLedCount -= 1;
|
||||
_ledBuffer.resize(static_cast<size_t>(_bufferLength), 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
_ledBuffer[0] = 'A';
|
||||
if (_streamProtocol == Adalight::AWA )
|
||||
{
|
||||
_ledBuffer[1] = 'w';
|
||||
_ledBuffer[2] = _white_channel_calibration ? 'A' : 'a';
|
||||
}
|
||||
else
|
||||
{
|
||||
_ledBuffer[1] = 'd';
|
||||
_ledBuffer[2] = 'a';
|
||||
}
|
||||
|
||||
qToBigEndian<quint16>(static_cast<quint16>(totalLedCount), &_ledBuffer[3]);
|
||||
_ledBuffer[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum
|
||||
|
||||
Debug( _log, "Adalight header for %d leds (size: %d): %c%c%c 0x%02x 0x%02x 0x%02x", _ledCount, _ledBuffer.size(),
|
||||
_ledBuffer[0], _ledBuffer[1], _ledBuffer[2], _ledBuffer[3], _ledBuffer[4], _ledBuffer[5] );
|
||||
}
|
||||
|
||||
|
||||
int LedDeviceAdalight::write(const std::vector<ColorRgb> & ledValues)
|
||||
{
|
||||
if (_ledCount != ledValues.size())
|
||||
{
|
||||
Warning(_log, "Adalight LED count has changed (old: %d, new: %d). Rebuilding header.", _ledCount, ledValues.size());
|
||||
_ledCount = static_cast<uint>(ledValues.size());
|
||||
_ledRGBCount = _ledCount * 3;
|
||||
prepareHeader();
|
||||
}
|
||||
|
||||
if (_bufferLength > static_cast<qint64>(_ledBuffer.size()))
|
||||
{
|
||||
Warning(_log, "Adalight buffer's size has changed. Skipping refresh.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_streamProtocol == Adalight::LBAPA )
|
||||
{
|
||||
for (signed iLed=1; iLed<=static_cast<int>( _ledCount); iLed++)
|
||||
{
|
||||
const ColorRgb& rgb = ledValues[static_cast<size_t>(iLed-1)];
|
||||
_ledBuffer[static_cast<size_t>(iLed*4+7)] = rgb.red;
|
||||
_ledBuffer[static_cast<size_t>(iLed*4+8)] = rgb.green;
|
||||
_ledBuffer[static_cast<size_t>(iLed*4+9)] = rgb.blue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* writer = _ledBuffer.data() + HEADER_SIZE;
|
||||
uint8_t* hasher = writer;
|
||||
|
||||
memcpy(writer, ledValues.data(), ledValues.size() * sizeof(ColorRgb));
|
||||
writer += ledValues.size() * sizeof(ColorRgb);
|
||||
|
||||
if (_streamProtocol == Adalight::AWA)
|
||||
{
|
||||
whiteChannelExtension(writer);
|
||||
|
||||
uint16_t fletcher1 = 0;
|
||||
uint16_t fletcher2 = 0;
|
||||
uint16_t fletcherExt = 0;
|
||||
uint8_t position = 0;
|
||||
|
||||
while (hasher < writer)
|
||||
{
|
||||
fletcherExt = (fletcherExt + (*(hasher) ^ (position++))) % 255;
|
||||
fletcher1 = (fletcher1 + *(hasher++)) % 255;
|
||||
fletcher2 = (fletcher2 + fletcher1) % 255;
|
||||
}
|
||||
*(writer++) = static_cast<uint8_t>(fletcher1);
|
||||
*(writer++) = static_cast<uint8_t>(fletcher2);
|
||||
*(writer++) = static_cast<uint8_t>((fletcherExt != 0x41) ? fletcherExt : 0xaa);
|
||||
}
|
||||
_bufferLength = writer - _ledBuffer.data();
|
||||
}
|
||||
|
||||
int rc = writeBytes(_bufferLength, _ledBuffer.data());
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void LedDeviceAdalight::readFeedback()
|
||||
{
|
||||
if (_streamProtocol == Adalight::AWA)
|
||||
{
|
||||
bool continuousLines {true};
|
||||
while ( _rs232Port.canReadLine() )
|
||||
{
|
||||
QByteArray record = _rs232Port.readLine();
|
||||
if (record.startsWith("FPS:"))
|
||||
{
|
||||
if (continuousLines)
|
||||
{
|
||||
continuousLines = false;
|
||||
}
|
||||
Debug(_log, "Statistics %s", record.trimmed().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << record.toStdString() << std::flush;
|
||||
continuousLines = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LedDeviceAdalight::whiteChannelExtension(uint8_t*& writer)
|
||||
{
|
||||
if (_streamProtocol == Adalight::AWA && _white_channel_calibration)
|
||||
{
|
||||
*(writer++) = _white_channel_limit;
|
||||
*(writer++) = _white_channel_red;
|
||||
*(writer++) = _white_channel_green;
|
||||
*(writer++) = _white_channel_blue;
|
||||
}
|
||||
}
|
||||
#include "LedDeviceAdalight.h"
|
||||
|
||||
#include <QtEndian>
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
|
||||
// Configuration settings
|
||||
const char CONFIG_STREAM_PROTOCOL[] = "streamProtocol";
|
||||
|
||||
const char CONFIG_WHITE_CHANNEL_CALLIBRATION[] = "white_channel_calibration";
|
||||
const char CONFIG_WHITE_CHANNEL_LIMIT[] = "white_channel_limit";
|
||||
const char CONFIG_WHITE_CHANNEL_RED[] = "white_channel_red";
|
||||
const char CONFIG_WHITE_CHANNEL_GREEN[] = "white_channel_green";
|
||||
const char CONFIG_WHITE_CHANNEL_BLUE[] = "white_channel_blue";
|
||||
constexpr int HEADER_SIZE {6};
|
||||
|
||||
} //End of constants
|
||||
|
||||
LedDeviceAdalight::LedDeviceAdalight(const QJsonObject &deviceConfig)
|
||||
: ProviderRs232(deviceConfig)
|
||||
{
|
||||
}
|
||||
|
||||
LedDevice* LedDeviceAdalight::construct(const QJsonObject &deviceConfig)
|
||||
{
|
||||
return new LedDeviceAdalight(deviceConfig);
|
||||
}
|
||||
|
||||
bool LedDeviceAdalight::init(const QJsonObject &deviceConfig)
|
||||
{
|
||||
bool isInitOK = false;
|
||||
|
||||
// Initialise sub-class
|
||||
if ( ProviderRs232::init(deviceConfig) )
|
||||
{
|
||||
_streamProtocol = static_cast<Adalight::PROTOCOLTYPE>(deviceConfig[CONFIG_STREAM_PROTOCOL].toString().toInt());
|
||||
switch (_streamProtocol) {
|
||||
|
||||
case Adalight::AWA:
|
||||
{
|
||||
Debug( _log, "Adalight driver uses Hyperserial protocol");
|
||||
_white_channel_calibration = deviceConfig[CONFIG_WHITE_CHANNEL_CALLIBRATION].toBool(false);
|
||||
double _white_channel_limit_percent = deviceConfig[CONFIG_WHITE_CHANNEL_LIMIT].toDouble(1);
|
||||
_white_channel_limit = static_cast<uint8_t>(qMin(qRound(_white_channel_limit_percent * 255.0 / 100.0), 255));
|
||||
_white_channel_red = static_cast<uint8_t>(qMin(deviceConfig[CONFIG_WHITE_CHANNEL_RED].toInt(255), 255));
|
||||
_white_channel_green = static_cast<uint8_t>(qMin(deviceConfig[CONFIG_WHITE_CHANNEL_GREEN].toInt(255), 255));
|
||||
_white_channel_blue = static_cast<uint8_t>(qMin(deviceConfig[CONFIG_WHITE_CHANNEL_BLUE].toInt(255), 255));
|
||||
|
||||
DebugIf(_white_channel_calibration, _log, "White channel limit: %i (%.2f%), red: %i, green: %i, blue: %i", _white_channel_limit, _white_channel_limit_percent, _white_channel_red, _white_channel_green, _white_channel_blue);
|
||||
}
|
||||
break;
|
||||
|
||||
case Adalight::LBAPA:
|
||||
Debug( _log, "Adalight driver uses LightBerry APA102 protocol");
|
||||
break;
|
||||
|
||||
case Adalight::ADA:
|
||||
Debug( _log, "Adalight driver uses standard Adalight protocol");
|
||||
break;
|
||||
default:
|
||||
Error( _log, "Adalight driver - unsupported protocol");
|
||||
return false;
|
||||
}
|
||||
|
||||
prepareHeader();
|
||||
isInitOK = true;
|
||||
}
|
||||
return isInitOK;
|
||||
}
|
||||
|
||||
void LedDeviceAdalight::prepareHeader()
|
||||
{
|
||||
// create ledBuffer
|
||||
uint totalLedCount = _ledCount;
|
||||
_bufferLength = static_cast<qint64>(HEADER_SIZE + _ledRGBCount);
|
||||
|
||||
switch (_streamProtocol) {
|
||||
case Adalight::LBAPA:
|
||||
{
|
||||
const unsigned int startFrameSize = 4;
|
||||
const unsigned int bytesPerRGBLed = 4;
|
||||
const unsigned int endFrameSize = qMax<unsigned int>(((_ledCount + 15) / 16), bytesPerRGBLed);
|
||||
_bufferLength = HEADER_SIZE + (_ledCount * bytesPerRGBLed) + startFrameSize + endFrameSize;
|
||||
|
||||
_ledBuffer.resize(static_cast<size_t>(_bufferLength), 0x00);
|
||||
|
||||
// init constant data values
|
||||
for (uint iLed=1; iLed <= _ledCount; iLed++)
|
||||
{
|
||||
_ledBuffer[iLed*4+HEADER_SIZE] = 0xFF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Adalight::AWA:
|
||||
_bufferLength += 8;
|
||||
[[fallthrough]];
|
||||
case Adalight::ADA:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
totalLedCount -= 1;
|
||||
_ledBuffer.resize(static_cast<size_t>(_bufferLength), 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
_ledBuffer[0] = 'A';
|
||||
if (_streamProtocol == Adalight::AWA )
|
||||
{
|
||||
_ledBuffer[1] = 'w';
|
||||
_ledBuffer[2] = _white_channel_calibration ? 'A' : 'a';
|
||||
}
|
||||
else
|
||||
{
|
||||
_ledBuffer[1] = 'd';
|
||||
_ledBuffer[2] = 'a';
|
||||
}
|
||||
|
||||
qToBigEndian<quint16>(static_cast<quint16>(totalLedCount), &_ledBuffer[3]);
|
||||
_ledBuffer[5] = _ledBuffer[3] ^ _ledBuffer[4] ^ 0x55; // Checksum
|
||||
|
||||
Debug( _log, "Adalight header for %d leds (size: %d): %c%c%c 0x%02x 0x%02x 0x%02x", _ledCount, _ledBuffer.size(),
|
||||
_ledBuffer[0], _ledBuffer[1], _ledBuffer[2], _ledBuffer[3], _ledBuffer[4], _ledBuffer[5] );
|
||||
}
|
||||
|
||||
|
||||
int LedDeviceAdalight::write(const std::vector<ColorRgb> & ledValues)
|
||||
{
|
||||
if (_ledCount != ledValues.size())
|
||||
{
|
||||
Warning(_log, "Adalight LED count has changed (old: %d, new: %d). Rebuilding header.", _ledCount, ledValues.size());
|
||||
_ledCount = static_cast<uint>(ledValues.size());
|
||||
_ledRGBCount = _ledCount * 3;
|
||||
prepareHeader();
|
||||
}
|
||||
|
||||
if (_bufferLength > static_cast<qint64>(_ledBuffer.size()))
|
||||
{
|
||||
Warning(_log, "Adalight buffer's size has changed. Skipping refresh.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_streamProtocol == Adalight::LBAPA )
|
||||
{
|
||||
for (signed iLed=1; iLed<=static_cast<int>( _ledCount); iLed++)
|
||||
{
|
||||
const ColorRgb& rgb = ledValues[static_cast<size_t>(iLed-1)];
|
||||
_ledBuffer[static_cast<size_t>(iLed*4+7)] = rgb.red;
|
||||
_ledBuffer[static_cast<size_t>(iLed*4+8)] = rgb.green;
|
||||
_ledBuffer[static_cast<size_t>(iLed*4+9)] = rgb.blue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* writer = _ledBuffer.data() + HEADER_SIZE;
|
||||
uint8_t* hasher = writer;
|
||||
|
||||
memcpy(writer, ledValues.data(), ledValues.size() * sizeof(ColorRgb));
|
||||
writer += ledValues.size() * sizeof(ColorRgb);
|
||||
|
||||
if (_streamProtocol == Adalight::AWA)
|
||||
{
|
||||
whiteChannelExtension(writer);
|
||||
|
||||
uint16_t fletcher1 = 0;
|
||||
uint16_t fletcher2 = 0;
|
||||
uint16_t fletcherExt = 0;
|
||||
uint8_t position = 0;
|
||||
|
||||
while (hasher < writer)
|
||||
{
|
||||
fletcherExt = (fletcherExt + (*(hasher) ^ (position++))) % 255;
|
||||
fletcher1 = (fletcher1 + *(hasher++)) % 255;
|
||||
fletcher2 = (fletcher2 + fletcher1) % 255;
|
||||
}
|
||||
*(writer++) = static_cast<uint8_t>(fletcher1);
|
||||
*(writer++) = static_cast<uint8_t>(fletcher2);
|
||||
*(writer++) = static_cast<uint8_t>((fletcherExt != 0x41) ? fletcherExt : 0xaa);
|
||||
}
|
||||
_bufferLength = writer - _ledBuffer.data();
|
||||
}
|
||||
|
||||
int rc = writeBytes(_bufferLength, _ledBuffer.data());
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void LedDeviceAdalight::readFeedback()
|
||||
{
|
||||
if (_streamProtocol == Adalight::AWA)
|
||||
{
|
||||
bool continuousLines {true};
|
||||
while ( _rs232Port.canReadLine() )
|
||||
{
|
||||
QByteArray record = _rs232Port.readLine();
|
||||
if (record.startsWith("FPS:"))
|
||||
{
|
||||
if (continuousLines)
|
||||
{
|
||||
continuousLines = false;
|
||||
}
|
||||
Debug(_log, "Statistics %s", record.trimmed().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << record.toStdString() << std::flush;
|
||||
continuousLines = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LedDeviceAdalight::whiteChannelExtension(uint8_t*& writer)
|
||||
{
|
||||
if (_streamProtocol == Adalight::AWA && _white_channel_calibration)
|
||||
{
|
||||
*(writer++) = _white_channel_limit;
|
||||
*(writer++) = _white_channel_red;
|
||||
*(writer++) = _white_channel_green;
|
||||
*(writer++) = _white_channel_blue;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue