11#include " LedDeviceAPA102.h"
22
3+ // Constants
4+ namespace {
5+
6+ // / The value that determines the higher bits of the APA102 brightness control field
7+ const int APA102_LEDFRAME_UPPER_BITS = 0xE0 ;
8+
9+ } // End of constants
10+
11+
312LedDeviceAPA102::LedDeviceAPA102 (const QJsonObject &deviceConfig)
413 : ProviderSpi(deviceConfig)
514{
15+ // Overwrite non supported/required features
16+ _latchTime_ms = 0 ;
617}
718
819LedDevice* LedDeviceAPA102::construct (const QJsonObject &deviceConfig)
@@ -17,32 +28,44 @@ bool LedDeviceAPA102::init(const QJsonObject &deviceConfig)
1728 // Initialise sub-class
1829 if ( ProviderSpi::init (deviceConfig) )
1930 {
31+ _brightnessControlMaxLevel = deviceConfig[" brightnessControlMaxLevel" ].toInt (APA102_BRIGHTNESS_MAX_LEVEL);
32+ Info (_log, " [%s] Setting maximum brightness to [%d] = %d%%" , QSTRING_CSTR (_activeDeviceType), _brightnessControlMaxLevel, _brightnessControlMaxLevel * 100 / APA102_BRIGHTNESS_MAX_LEVEL);
2033
2134 const unsigned int startFrameSize = 4 ;
22- const unsigned int endFrameSize = qMax<unsigned int >(((_ledCount + 15 ) / 16 ), 4 );
35+ // Endframe, add additional 4 bytes to cover SK9922 Reset frame (in case SK9922 were sold as AP102) - has no effect on APA102
36+ const unsigned int endFrameSize = (_ledCount/32 ) * 4 + 4 ;
2337 const unsigned int APAbufferSize = (_ledCount * 4 ) + startFrameSize + endFrameSize;
2438
25- _ledBuffer.resize (APAbufferSize, 0xFF );
26- _ledBuffer[0 ] = 0x00 ;
27- _ledBuffer[1 ] = 0x00 ;
28- _ledBuffer[2 ] = 0x00 ;
29- _ledBuffer[3 ] = 0x00 ;
39+ _ledBuffer.resize (APAbufferSize, 0x00 );
3040
3141 isInitOK = true ;
32-
3342 }
3443 return isInitOK;
3544}
3645
46+ void LedDeviceAPA102::bufferWithBrightness (std::vector<uint8_t > &txBuf, const std::vector<ColorRgb> & ledValues, const int brightness) {
47+ const int ledCount = static_cast <int >(_ledCount);
48+
49+ for (int iLed = 0 ; iLed < ledCount; ++iLed)
50+ {
51+ const ColorRgb &rgb = ledValues[iLed];
52+ const uint8_t red = rgb.red ;
53+ const uint8_t green = rgb.green ;
54+ const uint8_t blue = rgb.blue ;
55+
56+ // / The LED index in the buffer
57+ const int b = 4 + iLed * 4 ;
58+
59+ txBuf[b + 0 ] = brightness | APA102_LEDFRAME_UPPER_BITS;
60+ txBuf[b + 1 ] = blue;
61+ txBuf[b + 2 ] = green;
62+ txBuf[b + 3 ] = red;
63+ }
64+ }
65+
3766int LedDeviceAPA102::write (const std::vector<ColorRgb> &ledValues)
3867{
39- for (signed iLed=0 ; iLed < static_cast <int >( _ledCount); ++iLed) {
40- const ColorRgb& rgb = ledValues[iLed];
41- _ledBuffer[4 +iLed*4 ] = 0xFF ;
42- _ledBuffer[4 +iLed*4 +1 ] = rgb.red ;
43- _ledBuffer[4 +iLed*4 +2 ] = rgb.green ;
44- _ledBuffer[4 +iLed*4 +3 ] = rgb.blue ;
45- }
68+ this ->bufferWithBrightness (_ledBuffer, ledValues, _brightnessControlMaxLevel);
4669
4770 return writeBytes (_ledBuffer.size (), _ledBuffer.data ());
4871}
0 commit comments