Fix interaction of SO92, VirtualCT, and RGBWWTable (#18768)

* remove unused variable

* Relocate SO92 implementation
This way, SO92 does not ignore SO106

* Relocate RGBWWTable implementation
This fixes a bug related to RGBWWTable and SO92.
Also, the code is tidier this way

* Cleanup: Reduce code duplication

* more consistent behaviour for SO92 and free_cw

---------

Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
jonschz 2023-06-01 22:12:57 +02:00 committed by GitHub
parent b9d855ef79
commit 9d57a19be3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1911,21 +1911,14 @@ void LightAnimate(void)
cur_col_10[i] = change8to10(Light.new_color[i]);
}
bool rgbwwtable_applied_white = false; // did we already applied RGBWWTable to white channels (ex: in white_blend_mode or virtual_ct)
if (Light.pwm_multi_channels) {
calcGammaMultiChannels(cur_col_10);
} else {
// AddLog(LOG_LEVEL_INFO, PSTR(">>> calcGammaBulbs In %03X,%03X,%03X,%03X,%03X"), cur_col_10[0], cur_col_10[1], cur_col_10[2], cur_col_10[3], cur_col_10[4]);
rgbwwtable_applied_white = calcGammaBulbs(cur_col_10); // true means that one PWM channel is used for CT
calcGammaBulbs(cur_col_10);
// AddLog(LOG_LEVEL_INFO, PSTR(">>> calcGammaBulbs Out %03X,%03X,%03X,%03X,%03X"), cur_col_10[0], cur_col_10[1], cur_col_10[2], cur_col_10[3], cur_col_10[4]);
}
// Apply RGBWWTable only if not Settings->flag4.white_blend_mode
for (uint32_t i = 0; i < (rgbwwtable_applied_white ? 3 : Light.subtype); i++) {
uint32_t adjust = change8to10(Settings->rgbwwTable[i]);
cur_col_10[i] = changeUIntScale(cur_col_10[i], 0, 1023, 0, adjust);
}
// final adjusments for PMW ranges, post-gamma correction
for (uint32_t i = 0; i < LST_MAX; i++) {
// scale from 0..1023 to 0..pwm_range, but keep any non-zero value to at least 1
@ -2320,9 +2313,8 @@ void calcGammaBulb5Channels_8(uint8_t in8[LST_MAX], uint16_t col10[LST_MAX]) {
calcGammaBulb5Channels(col10, nullptr, nullptr);
}
bool calcGammaBulbs(uint16_t cur_col_10[5]) {
void calcGammaBulbs(uint16_t cur_col_10[5]) {
bool rgbwwtable_applied_white = false;
bool pwm_ct = false;
bool white_free_cw = false; // true if White channels are uncorrelated. Happens when CW+WW>255, i.e. manually setting white channels to exceed to total power of a single channel (may harm the power supply)
// Various values needed for accurate White calculation
// CT value streteched to 0..1023 (from within CT range, so not necessarily from 153 to 500). 0=Cold, 1023=Warm
@ -2340,24 +2332,7 @@ bool calcGammaBulbs(uint16_t cur_col_10[5]) {
calcGammaBulbCW(cur_col_10, &white_bri10, &white_free_cw);
}
// Now we know ct_10 and white_bri10 (gamma corrected if needed)
if ((LST_COLDWARM == Light.subtype) || (LST_RGBCW == Light.subtype)) {
#ifdef ESP8266
if ((PHILIPS == TasmotaGlobal.module_type) || (Settings->flag4.pwm_ct_mode)) { // channel 1 is the color tone, mapped to cold channel (0..255)
#else
if (Settings->flag4.pwm_ct_mode) { // channel 1 is the color tone, mapped to cold channel (0..255)
#endif // ESP8266
pwm_ct = true;
// Xiaomi Philips bulbs follow a different scheme:
// channel 0=intensity, channel1=temperature
cur_col_10[cw0] = white_bri10;
cur_col_10[cw0+1] = ct_10;
return false; // avoid any interference
}
}
// Now see if we need to mix RGB and White
// Now see if we need to mix RGB and White
// Valid only for LST_RGBW, LST_RGBCW, SetOption105 1, and white is zero (see doc)
if ((LST_RGBW <= Light.subtype) && (Settings->flag4.white_blend_mode) && (0 == cur_col_10[3]+cur_col_10[4])) {
uint32_t min_rgb_10 = min3(cur_col_10[0], cur_col_10[1], cur_col_10[2]);
@ -2421,7 +2396,28 @@ bool calcGammaBulbs(uint16_t cur_col_10[5]) {
cur_col_10[cw0] = white_bri10 - cur_col_10[cw0+1];
}
}
return rgbwwtable_applied_white;
// Apply RGBWWTable (RGB: always, CW: only if white_blend_mode is not engaged)
for (uint32_t i = 0; i < (rgbwwtable_applied_white ? 3 : Light.subtype); i++) {
uint32_t adjust = change8to10(Settings->rgbwwTable[i]);
cur_col_10[i] = changeUIntScale(cur_col_10[i], 0, 1023, 0, adjust);
}
// Implement SO92: Some lights like Xiaomi Philips bulbs follow the scheme
// cw0=intensity, cw0+1=temperature
if (ChannelCT() >= 0) {
// Need to compute white_bri10 and ct_10 from cur_col_10[] for compatibility with VirtualCT
white_bri10 = cur_col_10[cw0] + cur_col_10[cw0+1];
ct_10 = changeUIntScale(cur_col_10[cw0+1], 0, white_bri10, 0, 1023);
if (white_bri10 > 1023) {
// In white_free_cw mode, the combined brightness of cw and ww may be larger than 1023.
// This cannot be represented in pwm_ct_mode, so we set the maximum brightness instead.
white_bri10 = 1023;
}
cur_col_10[cw0] = white_bri10;
cur_col_10[cw0+1] = ct_10;
}
}
#ifdef USE_DEVICE_GROUPS