hyperion.ng/libsrc/leddevice/dev_spi/LedDeviceSk6812SPI.cpp
LordGrey 7389068a66
LED Device Features, Fixes and Refactoring (Resubmit PR855) (#875)
* Refactor LedDevices - Initial version
* Small renamings
* Add WLED as own device
* Lpd8806 Remove open() method
* remove dependency on Qt 5.10
* Lpd8806 Remove open() method
* Update WS281x
* Update WS2812SPI
* Add writeBlack for WLED powerOff
* WLED remove extra bracket
* Allow different Nanoleaf panel numbering sequence (Feature req.#827)
* build(deps): bump websocket-extensions from 0.1.3 to 0.1.4 in /docs (#826)
* Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
  - [Release notes](https://github.com/faye/websocket-extensions-node/releases)
  - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
  - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)
* Fix typos
* Nanoleaf clean-up
* Yeelight support, generalize wizard elements
* Update Yeelight to handle quota in music mode
* Yeelight extend rage for extraTimeDarkness for testing
* Clean-up - Add commentary, Remove development debug statements
* Fix brightnessSwitchOffOnMinimum typo and default value
* Yeelight support restoreOriginalState, additional Fixes
* WLED - Remove UDP-Port, as it is not configurable
* Fix merging issue
* Remove QHostAddress::operator=(const QString&)' is deprecated
* Windows compile errors and (Qt 5.15 deprecation) warnings
* Fix order includes
* LedDeviceFile Support Qt5.7 and greater
* Windows compatibility and other Fixes
* Fix Qt Version compatability
* Rs232 - Resolve portname from unix /dev/ style, fix DMX sub-type support
* Disable WLED Wizard Button (until Wizard is available)
* Yeelight updates
* Add wrong log-type as per #505
* Fixes and Clean-up after clang-tidy report
* Fix udpe131 not enabled for generated CID
* Change timer into dynamic for Qt Thread-Affinity
* Hue clean-up and diyHue workaround
* Updates after review feedback by m-seker
* Add "chrono" includes
2020-07-12 20:27:56 +02:00

87 lines
2.2 KiB
C++

#include "LedDeviceSk6812SPI.h"
LedDeviceSk6812SPI::LedDeviceSk6812SPI(const QJsonObject &deviceConfig)
: ProviderSpi()
, _whiteAlgorithm(RGBW::WhiteAlgorithm::INVALID)
, SPI_BYTES_PER_COLOUR(4)
, bitpair_to_byte {
0b10001000,
0b10001100,
0b11001000,
0b11001100,
}
{
_devConfig = deviceConfig;
_isDeviceReady = false;
_activeDeviceType = deviceConfig["type"].toString("UNSPECIFIED").toLower();
}
LedDevice* LedDeviceSk6812SPI::construct(const QJsonObject &deviceConfig)
{
return new LedDeviceSk6812SPI(deviceConfig);
}
bool LedDeviceSk6812SPI::init(const QJsonObject &deviceConfig)
{
_baudRate_Hz = 3000000;
bool isInitOK = false;
// Initialise sub-class
if ( ProviderSpi::init(deviceConfig) )
{
QString whiteAlgorithm = deviceConfig["whiteAlgorithm"].toString("white_off");
_whiteAlgorithm = RGBW::stringToWhiteAlgorithm(whiteAlgorithm);
if (_whiteAlgorithm == RGBW::WhiteAlgorithm::INVALID)
{
QString errortext = QString ("unknown whiteAlgorithm: %1").arg(whiteAlgorithm);
this->setInError(errortext);
isInitOK = false;
}
else
{
Debug( _log, "whiteAlgorithm : %s", QSTRING_CSTR(whiteAlgorithm));
WarningIf(( _baudRate_Hz < 2050000 || _baudRate_Hz > 4000000 ), _log, "SPI rate %d outside recommended range (2050000 -> 4000000)", _baudRate_Hz);
const int SPI_FRAME_END_LATCH_BYTES = 3;
_ledBuffer.resize(_ledRGBWCount * SPI_BYTES_PER_COLOUR + SPI_FRAME_END_LATCH_BYTES, 0x00);
isInitOK = true;
}
}
return isInitOK;
}
int LedDeviceSk6812SPI::write(const std::vector<ColorRgb> &ledValues)
{
unsigned spi_ptr = 0;
const int SPI_BYTES_PER_LED = sizeof(ColorRgbw) * SPI_BYTES_PER_COLOUR;
for (const ColorRgb& color : ledValues)
{
RGBW::Rgb_to_Rgbw(color, &_temp_rgbw, _whiteAlgorithm);
uint32_t colorBits =
((uint32_t)_temp_rgbw.red << 24) +
((uint32_t)_temp_rgbw.green << 16) +
((uint32_t)_temp_rgbw.blue << 8) +
_temp_rgbw.white;
for (int j=SPI_BYTES_PER_LED - 1; j>=0; j--)
{
_ledBuffer[spi_ptr+j] = bitpair_to_byte[ colorBits & 0x3 ];
colorBits >>= 2;
}
spi_ptr += SPI_BYTES_PER_LED;
}
_ledBuffer[spi_ptr++] = 0;
_ledBuffer[spi_ptr++] = 0;
_ledBuffer[spi_ptr++] = 0;
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}