Fix overflow in XY transition

main
Martin Böh 2022-04-05 19:24:18 +02:00
parent dd198ef4c1
commit 95b9fe8eea
2 changed files with 12 additions and 3 deletions

View File

@ -327,6 +327,13 @@ void hwLight_colorUpdate_HSV2RGB(u16 hue, u8 saturation, u8 level, bool enhanced
hwLight_colorUpdate_RGB(R, G, B); hwLight_colorUpdate_RGB(R, G, B);
} }
/**
* @brief Updates the PWM channel duty based on RGB colors.
*
* @param R the red component from 0-255
* @param G the green component from 0-255
* @param B the blue component from 0-255
*/
void hwLight_colorUpdate_RGB(u8 R, u8 G, u8 B) void hwLight_colorUpdate_RGB(u8 R, u8 G, u8 B)
{ {
u16 gammaCorrectR = ((u16)R * R) / ZCL_LEVEL_ATTR_MAX_LEVEL; u16 gammaCorrectR = ((u16)R * R) / ZCL_LEVEL_ATTR_MAX_LEVEL;
@ -377,7 +384,8 @@ float _fsqrt(float x, int n) {
float LINEAR_TO_SRGB_GAMMA_CORRECTION(const float part) float LINEAR_TO_SRGB_GAMMA_CORRECTION(const float part)
{ {
// Optimization for embedded devices without math libraries: a ^ (m / n) == nth_root(a) ^ m // Optimization for embedded devices without math libraries: a ^ (m / n) == nth_root(a) ^ m
return part <= 0.0031308f ? 12.92f * part : 1.055f * _fpow(_fsqrt(part, 12), 5) - 0.055f; // This uses a gamma value of 2.2 hence the (5/11)
return part <= 0.0031308f ? 12.92f * part : 1.055f * _fpow(_fsqrt(part, 11), 5) - 0.055f;
} }
#define MAX(x,y) ((x) > (y) ? (x) : (y)) #define MAX(x,y) ((x) > (y) ? (x) : (y))

View File

@ -219,6 +219,7 @@ static s32 sampleLight_colorTimerEvtCb(void *arg)
{ {
zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet();
// It is safe to use the enhanced mode here, because we control it ourselves.
if ((pColor->enhancedColorMode == ZCL_COLOR_MODE_CURRENT_HUE_SATURATION) || if ((pColor->enhancedColorMode == ZCL_COLOR_MODE_CURRENT_HUE_SATURATION) ||
(pColor->enhancedColorMode == ZCL_ENHANCED_COLOR_MODE_CURRENT_HUE_SATURATION)) (pColor->enhancedColorMode == ZCL_ENHANCED_COLOR_MODE_CURRENT_HUE_SATURATION))
{ {
@ -673,8 +674,8 @@ static void sampleLight_moveToColorProcess(zcl_colorCtrlMoveToColorCmd_t *cmd)
pColor->colorMode = ZCL_COLOR_MODE_CURRENT_X_Y; pColor->colorMode = ZCL_COLOR_MODE_CURRENT_X_Y;
pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_X_Y; pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_X_Y;
colorInfo.currentX256 = (u16)(pColor->currentX) << 8; colorInfo.currentX256 = (u32)(pColor->currentX) << 8;
colorInfo.currentY256 = (u16)(pColor->currentY) << 8; colorInfo.currentY256 = (u32)(pColor->currentY) << 8;
u16 remTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL); u16 remTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
colorInfo.xyRemainingTime = remTime; colorInfo.xyRemainingTime = remTime;