From 1670ec58a706737c4c12efb73f5ed534346636cd Mon Sep 17 00:00:00 2001 From: penfold42 Date: Fri, 2 Dec 2016 02:16:59 +1100 Subject: [PATCH] led device cleanup, bug fix and schemas (#304) * sk6812SPI was buggy cleaned up code - make sk6812spi and ws2812spi more consistent * led device schema updates --- libsrc/leddevice/LedDeviceSchemas.qrc | 2 +- libsrc/leddevice/LedDeviceSk6812SPI.cpp | 11 ++++--- libsrc/leddevice/LedDeviceSk6812SPI.h | 2 ++ libsrc/leddevice/LedDeviceWs2812SPI.cpp | 31 ++++++++--------- libsrc/leddevice/LedDeviceWs2812SPI.h | 2 ++ ...812rgbw-spi.json => schema-sk6812spi.json} | 9 ++++- .../leddevice/schemas/schema-ws2812spi.json | 2 +- libsrc/leddevice/schemas/schema-ws281x.json | 33 +++++++++++++++++++ 8 files changed, 70 insertions(+), 22 deletions(-) rename libsrc/leddevice/schemas/{schema-sk6812rgbw-spi.json => schema-sk6812spi.json} (66%) diff --git a/libsrc/leddevice/LedDeviceSchemas.qrc b/libsrc/leddevice/LedDeviceSchemas.qrc index e9699f6c..ea442fde 100644 --- a/libsrc/leddevice/LedDeviceSchemas.qrc +++ b/libsrc/leddevice/LedDeviceSchemas.qrc @@ -20,7 +20,7 @@ schemas/schema-rawhid.json schemas/schema-sedu.json schemas/schema-dmx.json - schemas/schema-sk6812rgbw-spi.json + schemas/schema-sk6812spi.json schemas/schema-tinkerforge.json schemas/schema-tpm2net.json schemas/schema-tpm2.json diff --git a/libsrc/leddevice/LedDeviceSk6812SPI.cpp b/libsrc/leddevice/LedDeviceSk6812SPI.cpp index 06c9e8f9..5d10bf89 100644 --- a/libsrc/leddevice/LedDeviceSk6812SPI.cpp +++ b/libsrc/leddevice/LedDeviceSk6812SPI.cpp @@ -3,6 +3,7 @@ LedDeviceSk6812SPI::LedDeviceSk6812SPI(const QJsonObject &deviceConfig) : ProviderSpi() , _whiteAlgorithm(RGBW::INVALID) + , SPI_BYTES_PER_COLOUR(4) , bitpair_to_byte { 0b10001000, 0b10001100, @@ -35,8 +36,8 @@ bool LedDeviceSk6812SPI::init(const QJsonObject &deviceConfig) { return false; } - - const int SPI_BYTES_PER_COLOUR = 4; + 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); @@ -46,7 +47,8 @@ bool LedDeviceSk6812SPI::init(const QJsonObject &deviceConfig) int LedDeviceSk6812SPI::write(const std::vector &ledValues) { unsigned spi_ptr = 0; - static const int SPI_BYTES_PER_LED = 4; + const int SPI_BYTES_PER_LED = sizeof(ColorRgbw) * SPI_BYTES_PER_COLOUR; + for (const ColorRgb& color : ledValues) { @@ -57,7 +59,8 @@ int LedDeviceSk6812SPI::write(const std::vector &ledValues) ((uint32_t)_temp_rgbw.blue << 8) + _temp_rgbw.white; - for (int j=SPI_BYTES_PER_LED - 1; j>=0; j--) { + for (int j=SPI_BYTES_PER_LED - 1; j>=0; j--) + { _ledBuffer[spi_ptr+j] = bitpair_to_byte[ colorBits & 0x3 ]; colorBits >>= 2; } diff --git a/libsrc/leddevice/LedDeviceSk6812SPI.h b/libsrc/leddevice/LedDeviceSk6812SPI.h index 1564b6e1..2c35cbb9 100644 --- a/libsrc/leddevice/LedDeviceSk6812SPI.h +++ b/libsrc/leddevice/LedDeviceSk6812SPI.h @@ -37,6 +37,8 @@ private: RGBW::WhiteAlgorithm _whiteAlgorithm; + const int SPI_BYTES_PER_COLOUR; + uint8_t bitpair_to_byte[4]; ColorRgbw _temp_rgbw; diff --git a/libsrc/leddevice/LedDeviceWs2812SPI.cpp b/libsrc/leddevice/LedDeviceWs2812SPI.cpp index 39eafb5c..b211e56d 100644 --- a/libsrc/leddevice/LedDeviceWs2812SPI.cpp +++ b/libsrc/leddevice/LedDeviceWs2812SPI.cpp @@ -2,6 +2,7 @@ LedDeviceWs2812SPI::LedDeviceWs2812SPI(const QJsonObject &deviceConfig) : ProviderSpi() + , SPI_BYTES_PER_COLOUR(4) , bitpair_to_byte { 0b10001000, 0b10001100, @@ -20,29 +21,28 @@ LedDevice* LedDeviceWs2812SPI::construct(const QJsonObject &deviceConfig) bool LedDeviceWs2812SPI::init(const QJsonObject &deviceConfig) { _baudRate_Hz = 3000000; - ProviderSpi::init(deviceConfig); + 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) { - // 3 colours, 4 spi bytes per colour + 3 frame end latch bytes - const int SPI_BYTES_PER_LED = 3 * 4; - unsigned spi_size = _ledCount * SPI_BYTES_PER_LED + 3; - - if(_ledBuffer.size() != spi_size) - { - _ledBuffer.resize(spi_size, 0x00); - } - unsigned spi_ptr = 0; - for (unsigned i=0; i<(unsigned)_ledCount; ++i) + const int SPI_BYTES_PER_LED = sizeof(ColorRgb) * SPI_BYTES_PER_COLOUR; + + for (const ColorRgb& color : ledValues) { - uint32_t colorBits = ((unsigned int)ledValues[i].red << 16) - | ((unsigned int)ledValues[i].green << 8) - | ledValues[i].blue; + 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--) { @@ -51,9 +51,10 @@ int LedDeviceWs2812SPI::write(const std::vector &ledValues) } spi_ptr += SPI_BYTES_PER_LED; } + _ledBuffer[spi_ptr++] = 0; _ledBuffer[spi_ptr++] = 0; _ledBuffer[spi_ptr++] = 0; - return writeBytes(spi_size, _ledBuffer.data()); + return writeBytes(_ledBuffer.size(), _ledBuffer.data()); } diff --git a/libsrc/leddevice/LedDeviceWs2812SPI.h b/libsrc/leddevice/LedDeviceWs2812SPI.h index 88dc3776..b7facf8c 100644 --- a/libsrc/leddevice/LedDeviceWs2812SPI.h +++ b/libsrc/leddevice/LedDeviceWs2812SPI.h @@ -35,5 +35,7 @@ private: /// virtual int write(const std::vector &ledValues); + const int SPI_BYTES_PER_COLOUR; + uint8_t bitpair_to_byte[4]; }; diff --git a/libsrc/leddevice/schemas/schema-sk6812rgbw-spi.json b/libsrc/leddevice/schemas/schema-sk6812spi.json similarity index 66% rename from libsrc/leddevice/schemas/schema-sk6812rgbw-spi.json rename to libsrc/leddevice/schemas/schema-sk6812spi.json index cb5b2298..60582945 100644 --- a/libsrc/leddevice/schemas/schema-sk6812rgbw-spi.json +++ b/libsrc/leddevice/schemas/schema-sk6812spi.json @@ -11,7 +11,7 @@ "rate": { "type": "integer", "title":"Baudrate", - "default": 2666666, + "default": 3000000, "propertyOrder" : 2 }, "invert": { @@ -20,6 +20,13 @@ "title":"Invert signal", "default": false, "propertyOrder" : 3 + }, + "whiteAlgorithm": { + "type": "string", + "title":"White LED algorithm", + "enum" : ["subtract_minimum","sub_min_warm_adjust","white_off"], + "default": "subtract_minimum", + "propertyOrder" : 4 } }, "additionalProperties": true diff --git a/libsrc/leddevice/schemas/schema-ws2812spi.json b/libsrc/leddevice/schemas/schema-ws2812spi.json index 4f36c9a0..641a21a7 100644 --- a/libsrc/leddevice/schemas/schema-ws2812spi.json +++ b/libsrc/leddevice/schemas/schema-ws2812spi.json @@ -11,7 +11,7 @@ "rate": { "type": "integer", "title":"Baudrate", - "default": 1000000, + "default": 3000000, "propertyOrder" : 2 }, "invert": { diff --git a/libsrc/leddevice/schemas/schema-ws281x.json b/libsrc/leddevice/schemas/schema-ws281x.json index 0bce7984..2cf3e1fd 100644 --- a/libsrc/leddevice/schemas/schema-ws281x.json +++ b/libsrc/leddevice/schemas/schema-ws281x.json @@ -2,6 +2,39 @@ "type":"object", "required":true, "properties":{ + "leds": { + "type": "integer", + "title":"maximum led count", + "default": 256, + "propertyOrder" : 1 + }, + "gpio": { + "type": "integer", + "title":"gpio number", + "default": 18, + "propertyOrder" : 2 + }, + "invert": { + "type": "boolean", + "format": "checkbox", + "title":"Invert signal", + "default": false, + "propertyOrder" : 3 + }, + "rgbw": { + "type": "boolean", + "format": "checkbox", + "title":"use rgbw protocol", + "default": false, + "propertyOrder" : 3 + }, + "whiteAlgorithm": { + "type": "string", + "title":"White LED algorithm", + "enum" : ["subtract_minimum","sub_min_warm_adjust","white_off"], + "default": "subtract_minimum", + "propertyOrder" : 4 + } }, "additionalProperties": true }