2014-12-03 09:35:10 +01:00
# include "LedDeviceAPA102.h"
2021-10-28 19:54:54 +02:00
// Constants
namespace {
/// The value that determines the higher bits of the APA102 brightness control field
const int APA102_LEDFRAME_UPPER_BITS = 0xE0 ;
} //End of constants
2016-10-13 21:59:58 +02:00
LedDeviceAPA102 : : LedDeviceAPA102 ( const QJsonObject & deviceConfig )
2020-08-08 00:21:19 +02:00
: ProviderSpi ( deviceConfig )
2014-12-03 09:35:10 +01:00
{
2021-10-28 19:54:54 +02:00
// Overwrite non supported/required features
_latchTime_ms = 0 ;
2016-08-23 20:07:12 +02:00
}
2016-10-13 21:59:58 +02:00
LedDevice * LedDeviceAPA102 : : construct ( const QJsonObject & deviceConfig )
2016-08-23 20:07:12 +02:00
{
return new LedDeviceAPA102 ( deviceConfig ) ;
2014-12-03 09:35:10 +01:00
}
2016-10-13 21:59:58 +02:00
bool LedDeviceAPA102 : : init ( const QJsonObject & deviceConfig )
2014-12-03 09:35:10 +01:00
{
2020-07-12 20:27:56 +02:00
bool isInitOK = false ;
2016-10-08 08:14:36 +02:00
2020-07-12 20:27:56 +02:00
// Initialise sub-class
if ( ProviderSpi : : init ( deviceConfig ) )
2020-02-10 15:21:58 +01:00
{
2021-10-28 19:54:54 +02:00
_brightnessControlMaxLevel = deviceConfig [ " brightnessControlMaxLevel " ] . toInt ( APA102_BRIGHTNESS_MAX_LEVEL ) ;
Info ( _log , " [%s] Setting maximum brightness to [%d] = %d%% " , QSTRING_CSTR ( _activeDeviceType ) , _brightnessControlMaxLevel , _brightnessControlMaxLevel * 100 / APA102_BRIGHTNESS_MAX_LEVEL ) ;
2020-07-12 20:27:56 +02:00
2020-02-10 15:21:58 +01:00
const unsigned int startFrameSize = 4 ;
2021-10-28 19:54:54 +02:00
//Endframe, add additional 4 bytes to cover SK9922 Reset frame (in case SK9922 were sold as AP102) - has no effect on APA102
const unsigned int endFrameSize = ( _ledCount / 32 ) * 4 + 4 ;
2020-02-10 15:21:58 +01:00
const unsigned int APAbufferSize = ( _ledCount * 4 ) + startFrameSize + endFrameSize ;
2016-05-10 12:16:19 +02:00
2021-10-28 19:54:54 +02:00
_ledBuffer . resize ( APAbufferSize , 0x00 ) ;
2020-07-12 20:27:56 +02:00
isInitOK = true ;
2020-02-10 15:21:58 +01:00
}
return isInitOK ;
2016-10-08 08:14:36 +02:00
}
2021-10-28 19:54:54 +02:00
void LedDeviceAPA102 : : bufferWithBrightness ( std : : vector < uint8_t > & txBuf , const std : : vector < ColorRgb > & ledValues , const int brightness ) {
const int ledCount = static_cast < int > ( _ledCount ) ;
for ( int iLed = 0 ; iLed < ledCount ; + + iLed )
{
const ColorRgb & rgb = ledValues [ iLed ] ;
const uint8_t red = rgb . red ;
const uint8_t green = rgb . green ;
const uint8_t blue = rgb . blue ;
/// The LED index in the buffer
const int b = 4 + iLed * 4 ;
txBuf [ b + 0 ] = brightness | APA102_LEDFRAME_UPPER_BITS ;
txBuf [ b + 1 ] = blue ;
txBuf [ b + 2 ] = green ;
txBuf [ b + 3 ] = red ;
}
}
2016-10-08 08:14:36 +02:00
int LedDeviceAPA102 : : write ( const std : : vector < ColorRgb > & ledValues )
{
2021-10-28 19:54:54 +02:00
this - > bufferWithBrightness ( _ledBuffer , ledValues , _brightnessControlMaxLevel ) ;
2014-12-03 09:35:10 +01:00
2014-12-11 13:48:14 +01:00
return writeBytes ( _ledBuffer . size ( ) , _ledBuffer . data ( ) ) ;
2014-12-03 09:35:10 +01:00
}