#include "LedDeviceWs2812SPI.h" LedDeviceWs2812SPI::LedDeviceWs2812SPI(const QJsonObject &deviceConfig) : ProviderSpi() , SPI_BYTES_PER_COLOUR(4) , bitpair_to_byte { 0b10001000, 0b10001100, 0b11001000, 0b11001100, } { _deviceReady = init(deviceConfig); } LedDevice* LedDeviceWs2812SPI::construct(const QJsonObject &deviceConfig) { return new LedDeviceWs2812SPI(deviceConfig); } bool LedDeviceWs2812SPI::init(const QJsonObject &deviceConfig) { _baudRate_Hz = 3000000; if ( !ProviderSpi::init(deviceConfig) ) { return false; } 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(_ledRGBCount * SPI_BYTES_PER_COLOUR + SPI_FRAME_END_LATCH_BYTES, 0x00); return true; } int LedDeviceWs2812SPI::write(const std::vector &ledValues) { unsigned spi_ptr = 0; const int SPI_BYTES_PER_LED = sizeof(ColorRgb) * SPI_BYTES_PER_COLOUR; for (const ColorRgb& color : ledValues) { uint32_t colorBits = ((unsigned int)color.red << 16) | ((unsigned int)color.green << 8) | color.blue; 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()); }