APA102 protocol fix (#1352) (#1361)

* Fix APA102 protocoll

* Minor clean-ups

* Revert updates
This commit is contained in:
LordGrey 2021-10-28 18:54:54 +01:00 committed by GitHub
parent ba32b875ab
commit 954112a88e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 28 deletions

View File

@ -16,9 +16,11 @@ make_release()
mkdir -p deploy/${RELEASE} mkdir -p deploy/${RELEASE}
cd build-${RELEASE} cd build-${RELEASE}
cmake -DCMAKE_INSTALL_PREFIX=/usr -DPLATFORM=${PLATFORM} $@ -DCMAKE_BUILD_TYPE=Release -Wno-dev .. || exit 1 cmake -DCMAKE_INSTALL_PREFIX=/usr -DPLATFORM=${PLATFORM} $@ -DCMAKE_BUILD_TYPE=Release -Wno-dev .. || exit 1
#cmake -DCMAKE_INSTALL_PREFIX=/usr -DPLATFORM=${PLATFORM} $@ -DCMAKE_BUILD_TYPE=Debug .. || exit 1
make -j $(nproc) || exit 1 make -j $(nproc) || exit 1
#strip bin/* strip bin/*
make package -j $(nproc) make package -j $(nproc)
mv Hyperion-* ../deploy/${RELEASE} mv Hyperion-* ../deploy/${RELEASE}
cd .. cd ..
@ -30,7 +32,7 @@ CMAKE_FLATC_FLAG="-DIMPORT_FLATC=../build-x86x64/flatc_export.cmake"
make_release x86x64 x11 make_release x86x64 x11
#make_release x32 x11 -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-x32.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG} #make_release x32 x11 -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-x32.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG}
make_release rpi rpi -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-rpi.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG} #make_release rpi rpi -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-rpi.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG}
#make_release wetek wetek -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-rpi.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG} #make_release wetek wetek -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-rpi.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG}
#make_release imx6 imx6 -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-imx6.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG} #make_release imx6 imx6 -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-imx6.cmake" ${CMAKE_PROTOC_FLAG} ${CMAKE_FLATC_FLAG}

View File

@ -275,6 +275,7 @@ bool LedDevice::switchOn()
if ( powerOn() ) if ( powerOn() )
{ {
_isOn = true; _isOn = true;
_isInSwitchOff = false;
rc = true; rc = true;
} }
} }

View File

@ -1,8 +1,19 @@
#include "LedDeviceAPA102.h" #include "LedDeviceAPA102.h"
// 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
LedDeviceAPA102::LedDeviceAPA102(const QJsonObject &deviceConfig) LedDeviceAPA102::LedDeviceAPA102(const QJsonObject &deviceConfig)
: ProviderSpi(deviceConfig) : ProviderSpi(deviceConfig)
{ {
// Overwrite non supported/required features
_latchTime_ms = 0;
} }
LedDevice* LedDeviceAPA102::construct(const QJsonObject &deviceConfig) LedDevice* LedDeviceAPA102::construct(const QJsonObject &deviceConfig)
@ -17,32 +28,44 @@ bool LedDeviceAPA102::init(const QJsonObject &deviceConfig)
// Initialise sub-class // Initialise sub-class
if ( ProviderSpi::init(deviceConfig) ) if ( ProviderSpi::init(deviceConfig) )
{ {
_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);
const unsigned int startFrameSize = 4; const unsigned int startFrameSize = 4;
const unsigned int endFrameSize = qMax<unsigned int>(((_ledCount + 15) / 16), 4); //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;
const unsigned int APAbufferSize = (_ledCount * 4) + startFrameSize + endFrameSize; const unsigned int APAbufferSize = (_ledCount * 4) + startFrameSize + endFrameSize;
_ledBuffer.resize(APAbufferSize, 0xFF); _ledBuffer.resize(APAbufferSize, 0x00);
_ledBuffer[0] = 0x00;
_ledBuffer[1] = 0x00;
_ledBuffer[2] = 0x00;
_ledBuffer[3] = 0x00;
isInitOK = true; isInitOK = true;
} }
return isInitOK; return isInitOK;
} }
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;
}
}
int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues) int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
{ {
for (signed iLed=0; iLed < static_cast<int>( _ledCount); ++iLed) { this->bufferWithBrightness(_ledBuffer, ledValues, _brightnessControlMaxLevel);
const ColorRgb& rgb = ledValues[iLed];
_ledBuffer[4+iLed*4] = 0xFF;
_ledBuffer[4+iLed*4+1] = rgb.red;
_ledBuffer[4+iLed*4+2] = rgb.green;
_ledBuffer[4+iLed*4+3] = rgb.blue;
}
return writeBytes(_ledBuffer.size(), _ledBuffer.data()); return writeBytes(_ledBuffer.size(), _ledBuffer.data());
} }

View File

@ -4,6 +4,9 @@
// hyperion includes // hyperion includes
#include "ProviderSpi.h" #include "ProviderSpi.h"
/// The maximal level supported by the APA brightness control field, 31
const int APA102_BRIGHTNESS_MAX_LEVEL = 31;
/// ///
/// Implementation of the LedDevice interface for writing to APA102 led device. /// Implementation of the LedDevice interface for writing to APA102 led device.
/// ///
@ -43,6 +46,18 @@ private:
/// @return Zero on success, else negative /// @return Zero on success, else negative
/// ///
int write(const std::vector<ColorRgb> & ledValues) override; int write(const std::vector<ColorRgb> & ledValues) override;
///
/// @brief Writes the RGB-Color values to the SPI Tx buffer setting considering a given brightness level
///
/// @param[in,out] txBuf The packed spi transfer buffer of the LED's color values
/// @param[in] ledValues The RGB-color per LED
/// @param[in] brightness The current brightness level 1 .. 31
///
void bufferWithBrightness(std::vector<uint8_t> &txBuf, const std::vector<ColorRgb> & ledValues, const int brightness = APA102_BRIGHTNESS_MAX_LEVEL);
/// The brighness level. Possibile values 1 .. 31.
int _brightnessControlMaxLevel;
}; };
#endif // LEDEVICEAPA102_H #endif // LEDEVICEAPA102_H

View File

@ -39,10 +39,6 @@ bool LedDeviceSK9822::init(const QJsonObject &deviceConfig)
_ledBuffer.resize(0, 0x00); _ledBuffer.resize(0, 0x00);
_ledBuffer.resize(bufferSize, 0x00); _ledBuffer.resize(bufferSize, 0x00);
//_ledBuffer[0] = 0x00;
//_ledBuffer[1] = 0x00;
//_ledBuffer[2] = 0x00;
//_ledBuffer[3] = 0x00;
isInitOK = true; isInitOK = true;
} }

View File

@ -37,6 +37,7 @@ ProviderSpi::ProviderSpi(const QJsonObject &deviceConfig)
{ {
memset(&_spi, 0, sizeof(_spi)); memset(&_spi, 0, sizeof(_spi));
_latchTime_ms = 1; _latchTime_ms = 1;
_isInSwitchOff = false;
} }
ProviderSpi::~ProviderSpi() ProviderSpi::~ProviderSpi()
@ -68,6 +69,7 @@ int ProviderSpi::open()
int retval = -1; int retval = -1;
QString errortext; QString errortext;
_isDeviceReady = false; _isDeviceReady = false;
_isInSwitchOff = false;
const int bitsPerWord = 8; const int bitsPerWord = 8;

View File

@ -19,20 +19,18 @@
"default": false, "default": false,
"propertyOrder" : 3 "propertyOrder" : 3
}, },
"latchTime": { "brightnessControlMaxLevel": {
"type": "integer", "type": "integer",
"title":"edt_dev_spec_latchtime_title", "title":"edt_conf_color_brightness_title",
"default": 0, "default": 31,
"append" : "edt_append_ms", "minimum": 1,
"minimum": 0, "maximum": 31,
"maximum": 1000,
"access" : "expert",
"propertyOrder" : 4 "propertyOrder" : 4
}, },
"rewriteTime": { "rewriteTime": {
"type": "integer", "type": "integer",
"title":"edt_dev_general_rewriteTime_title", "title":"edt_dev_general_rewriteTime_title",
"default": 1000, "default": 0,
"append" : "edt_append_ms", "append" : "edt_append_ms",
"minimum": 0, "minimum": 0,
"access" : "expert", "access" : "expert",