Another attempt at the XY conversion
parent
95b9fe8eea
commit
356ae0f04e
|
@ -35,11 +35,12 @@
|
|||
*/
|
||||
#define ZCL_LEVEL_CHANGE_INTERVAL 20 // 50 steps a second, every 20ms
|
||||
#define ZCL_COLOR_CHANGE_INTERVAL 20 // see above
|
||||
#define ZCL_ONOFF_TIMER_INTERVAL 20 // the timer interval to change the offWaitTime/onTime attribute of the ONOFF cluster
|
||||
|
||||
#define ZCL_REMAINING_TIME_INTERVAL 100 // 1/10th of a second according to the zigbee spec
|
||||
|
||||
// Map the required time to our internal steps
|
||||
#define INTERP_STEPS_FROM_REM_TIME(remTime, base) ((remTime * ZCL_REMAINING_TIME_INTERVAL)/base)
|
||||
|
||||
#define INTERP_STEPS_FROM_ONE_TENTH(remTime, base) ((remTime * ZCL_REMAINING_TIME_INTERVAL)/base)
|
||||
|
||||
/**********************************************************************
|
||||
* TYPEDEFS
|
||||
|
|
|
@ -347,11 +347,6 @@ void hwLight_colorUpdate_RGB(u8 R, u8 G, u8 B)
|
|||
pwmSetDuty(WARM_LIGHT_PWM_CHANNEL, 0);
|
||||
}
|
||||
|
||||
static u8 ENFORCE_BOUNDS_U8(u8 lowerBound, s16 num, u8 upperBound)
|
||||
{
|
||||
return num < lowerBound ? lowerBound : num > upperBound ? upperBound : num;
|
||||
}
|
||||
|
||||
/*
|
||||
iLog, pow and root functions, taken from
|
||||
http://rosettacode.org/wiki/Nth_root#C
|
||||
|
@ -381,11 +376,11 @@ float _fsqrt(float x, int n) {
|
|||
return r;
|
||||
}
|
||||
|
||||
float LINEAR_TO_SRGB_GAMMA_CORRECTION(const float part)
|
||||
float LINEAR_TO_SRGB_GAMMA_CORRECTION(float v)
|
||||
{
|
||||
// Optimization for embedded devices without math libraries: a ^ (m / n) == nth_root(a) ^ m
|
||||
// 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;
|
||||
return v <= 0.0031308f ? 12.92f * v : 1.055f * _fpow(_fsqrt(v, 11), 5) - 0.055f;
|
||||
}
|
||||
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
@ -400,21 +395,28 @@ void hwLight_colorUpdate_XY2RGB(u16 xI, u16 yI, u8 level)
|
|||
// This does not locate the closest point in the gamma spectrum of the lamps. possible #todo
|
||||
const float z = 1.f - x - y;
|
||||
|
||||
const float Y = (level / (float)ZCL_LEVEL_ATTR_MAX_LEVEL); // This is luminance, but used as brightness
|
||||
const float X = (Y / y) * x;
|
||||
const float Z = (Y / y) * z;
|
||||
float Y = yI == 0 ? 0.0f : (level / (float)ZCL_LEVEL_ATTR_MAX_LEVEL); // This is luminance, but used as brightness
|
||||
float X = yI == 0 ? 0.0f : (x * Y) / y;
|
||||
float Z = yI == 0 ? 0.0f : (z * Y) / y;
|
||||
|
||||
// SRGB http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
||||
float r = X * 3.2404542f - Y * -1.5371385f - Z * 0.4985314f;
|
||||
float g = -X * 0.9692660f + Y * 1.8760108f + Z * 0.0415560f;
|
||||
float b = X * 0.0556434f - Y * 0.2040259f + Z * 1.0572252f;
|
||||
float r = MAX(X * 3.2404542f + Y * -1.5371385f + Z * -0.4985314f,0);
|
||||
float g = MAX(X * -0.9692660f + Y * 1.8760108f + Z * 0.0415560f,0);
|
||||
float b = MAX(X * 0.0556434f + Y * -0.2040259f + Z * 1.0572252f,0);
|
||||
|
||||
// Apply LINEAR => SRGB Gamma correction
|
||||
r = LINEAR_TO_SRGB_GAMMA_CORRECTION(r);
|
||||
g = LINEAR_TO_SRGB_GAMMA_CORRECTION(g);
|
||||
b = LINEAR_TO_SRGB_GAMMA_CORRECTION(b);
|
||||
|
||||
hwLight_colorUpdate_RGB(ENFORCE_BOUNDS_U8(0, round(r * 255), 255), ENFORCE_BOUNDS_U8(0, round(g * 255), 255), ENFORCE_BOUNDS_U8(0, round(b * 255) , 255));
|
||||
float maxComponent = MAX(MAX(r, g), b);
|
||||
if (maxComponent > 1.0f) {
|
||||
r /= maxComponent;
|
||||
g /= maxComponent;
|
||||
b /= maxComponent;
|
||||
}
|
||||
|
||||
hwLight_colorUpdate_RGB(round(r * 255), round(g * 255), round(b * 255));
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
144
zb_afTestCb.c
144
zb_afTestCb.c
|
@ -1,144 +0,0 @@
|
|||
/********************************************************************************************************
|
||||
* @file zb_afTestCb.c
|
||||
*
|
||||
* @brief This is the source file for zb_afTestCb
|
||||
*
|
||||
* @author Zigbee Group
|
||||
* @date 2021
|
||||
*
|
||||
* @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#if (__PROJECT_TL_DIMMABLE_LIGHT__)
|
||||
|
||||
/**********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "tl_common.h"
|
||||
#include "zb_api.h"
|
||||
#include "zcl_include.h"
|
||||
#include "sampleLight.h"
|
||||
#if ZBHCI_EN
|
||||
#include "zbhci.h"
|
||||
#endif
|
||||
|
||||
#if AF_TEST_ENABLE
|
||||
/**********************************************************************
|
||||
* LOCAL CONSTANTS
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
u16 g_afTest_rcvReqCnt = 0;
|
||||
|
||||
/**********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
static void afTest_testReqPrc(apsdeDataInd_t *pApsdeInd)
|
||||
{
|
||||
epInfo_t dstEp;
|
||||
TL_SETSTRUCTCONTENT(dstEp, 0);
|
||||
|
||||
dstEp.dstEp = pApsdeInd->indInfo.src_ep;
|
||||
dstEp.profileId = pApsdeInd->indInfo.profile_id;
|
||||
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
|
||||
dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr;
|
||||
|
||||
u8 dataLen = 50;
|
||||
u8 *pBuf = (u8 *)ev_buf_allocate(dataLen);
|
||||
if (pBuf)
|
||||
{
|
||||
u8 *pData = pBuf;
|
||||
|
||||
*pData++ = LO_UINT16(g_afTest_rcvReqCnt);
|
||||
*pData++ = HI_UINT16(g_afTest_rcvReqCnt);
|
||||
|
||||
for (u8 i = 0; i < dataLen - 2; i++)
|
||||
{
|
||||
*pData++ = i;
|
||||
}
|
||||
|
||||
u8 apsCnt = 0;
|
||||
#if ZBHCI_EN
|
||||
zbhciTx(ZCL_CLUSTER_TELINK_SDK_TEST_RSP, pApsdeInd->asduLen, (u8 *)pApsdeInd->asdu);
|
||||
#else
|
||||
af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_RSP, dataLen, pBuf, &apsCnt);
|
||||
#endif
|
||||
|
||||
ev_buf_free(pBuf);
|
||||
}
|
||||
}
|
||||
|
||||
static void afTest_testClearReqPrc(apsdeDataInd_t *pApsdeInd)
|
||||
{
|
||||
epInfo_t dstEp;
|
||||
TL_SETSTRUCTCONTENT(dstEp, 0);
|
||||
|
||||
dstEp.dstEp = pApsdeInd->indInfo.src_ep;
|
||||
dstEp.profileId = pApsdeInd->indInfo.profile_id;
|
||||
dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
|
||||
dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr;
|
||||
|
||||
u8 st = SUCCESS;
|
||||
|
||||
u8 apsCnt = 0;
|
||||
af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, 1, &st, &apsCnt);
|
||||
}
|
||||
|
||||
void afTest_rx_handler(void *arg)
|
||||
{
|
||||
apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg;
|
||||
|
||||
switch (pApsdeInd->indInfo.cluster_id)
|
||||
{
|
||||
case ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ:
|
||||
g_afTest_rcvReqCnt = 0;
|
||||
afTest_testClearReqPrc(pApsdeInd);
|
||||
break;
|
||||
case ZCL_CLUSTER_TELINK_SDK_TEST_REQ:
|
||||
g_afTest_rcvReqCnt++;
|
||||
afTest_testReqPrc(pApsdeInd);
|
||||
break;
|
||||
case ZCL_CLUSTER_TELINK_SDK_TEST_RSP:
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Must be free here. */
|
||||
ev_buf_free((u8 *)arg);
|
||||
}
|
||||
|
||||
void afTest_dataSendConfirm(void *arg)
|
||||
{
|
||||
// apsdeDataConf_t *pApsDataCnf = (apsdeDataConf_t *)arg;
|
||||
}
|
||||
|
||||
#endif /* AF_TEST_ENABLE */
|
||||
#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */
|
|
@ -388,7 +388,7 @@ static void sampleLight_moveToHueProcess(zcl_colorCtrlMoveToHueCmd_t *cmd)
|
|||
break;
|
||||
}
|
||||
|
||||
colorInfo.hueRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.hueRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.stepHue256 = ((s32)hueDiff) << 8;
|
||||
colorInfo.stepHue256 /= (s32)colorInfo.hueRemainingTime;
|
||||
|
||||
|
@ -470,7 +470,7 @@ static void sampleLight_stepHueProcess(zcl_colorCtrlStepHueCmd_t *cmd)
|
|||
|
||||
colorInfo.currentHue256 = (u16)(pColor->currentHue) << 8;
|
||||
|
||||
colorInfo.hueRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.hueRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
|
||||
colorInfo.stepHue256 = (((s32)cmd->stepSize) << 8) / colorInfo.hueRemainingTime;
|
||||
|
||||
|
@ -517,7 +517,7 @@ static void sampleLight_moveToSaturationProcess(zcl_colorCtrlMoveToSaturationCmd
|
|||
|
||||
colorInfo.currentSaturation256 = (u16)(pColor->currentSaturation) << 8;
|
||||
|
||||
colorInfo.saturationRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.saturationRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
|
||||
colorInfo.stepSaturation256 = ((s32)(cmd->saturation - pColor->currentSaturation)) << 8;
|
||||
colorInfo.stepSaturation256 /= (s32)colorInfo.saturationRemainingTime;
|
||||
|
@ -600,7 +600,7 @@ static void sampleLight_stepSaturationProcess(zcl_colorCtrlStepSaturationCmd_t *
|
|||
|
||||
colorInfo.currentSaturation256 = (u16)(pColor->currentSaturation) << 8;
|
||||
|
||||
colorInfo.saturationRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.saturationRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
|
||||
colorInfo.stepSaturation256 = (((s32)cmd->stepSize) << 8) / colorInfo.saturationRemainingTime;
|
||||
|
||||
|
@ -677,7 +677,7 @@ static void sampleLight_moveToColorProcess(zcl_colorCtrlMoveToColorCmd_t *cmd)
|
|||
colorInfo.currentX256 = (u32)(pColor->currentX) << 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_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.xyRemainingTime = remTime;
|
||||
|
||||
colorInfo.stepX256 = ((s32)(cmd->colorX - pColor->currentX)) << 8;
|
||||
|
@ -798,7 +798,7 @@ static void sampleLight_enhancedMoveToHueProcess(zcl_colorCtrlEnhancedMoveToHueC
|
|||
break;
|
||||
}
|
||||
|
||||
colorInfo.enhancedHueRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.enhancedHueRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.stepEnhancedHue256 = ((s32)hueDiff) << 8;
|
||||
colorInfo.stepEnhancedHue256 /= (s32)colorInfo.enhancedHueRemainingTime;
|
||||
|
||||
|
@ -964,7 +964,7 @@ static void sampleLight_moveToColorTemperatureProcess(zcl_colorCtrlMoveToColorTe
|
|||
|
||||
colorInfo.currentColorTemp256 = (u32)(pColor->colorTemperatureMireds) << 8;
|
||||
|
||||
colorInfo.colorTempRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.colorTempRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
|
||||
colorInfo.stepColorTemp256 = ((s32)(cmd->colorTemperature - pColor->colorTemperatureMireds)) << 8;
|
||||
colorInfo.stepColorTemp256 /= (s32)colorInfo.colorTempRemainingTime;
|
||||
|
@ -1087,7 +1087,7 @@ static void sampleLight_stepColorTemperatureProcess(zcl_colorCtrlStepColorTemper
|
|||
|
||||
colorInfo.currentColorTemp256 = (u32)(pColor->colorTemperatureMireds) << 8;
|
||||
|
||||
colorInfo.colorTempRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
colorInfo.colorTempRemainingTime = (cmd->transitionTime == 0) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_COLOR_CHANGE_INTERVAL);
|
||||
|
||||
colorInfo.stepColorTemp256 = (((s32)cmd->stepSize) << 8) / colorInfo.colorTempRemainingTime;
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ static void sampleLight_moveToLevelProcess(u8 cmdId, moveToLvl_t *cmd)
|
|||
{
|
||||
zcl_levelAttr_t *pLevel = zcl_levelAttrGet();
|
||||
|
||||
pLevel->remainingTime = ((cmd->transitionTime == 0) || (cmd->transitionTime == 0xFFFF)) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_LEVEL_CHANGE_INTERVAL);
|
||||
pLevel->remainingTime = ((cmd->transitionTime == 0) || (cmd->transitionTime == 0xFFFF)) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_LEVEL_CHANGE_INTERVAL);
|
||||
|
||||
levelInfo.withOnOff = (cmdId == ZCL_CMD_LEVEL_MOVE_TO_LEVEL_WITH_ON_OFF) ? TRUE : FALSE;
|
||||
levelInfo.currentLevel256 = (u16)(pLevel->curLevel) << 8;
|
||||
|
@ -272,7 +272,7 @@ static void sampleLight_stepProcess(u8 cmdId, step_t *cmd)
|
|||
{
|
||||
zcl_levelAttr_t *pLevel = zcl_levelAttrGet();
|
||||
|
||||
pLevel->remainingTime = ((cmd->transitionTime == 0) || (cmd->transitionTime == 0xFFFF)) ? 1 : INTERP_STEPS_FROM_REM_TIME(cmd->transitionTime, ZCL_LEVEL_CHANGE_INTERVAL);
|
||||
pLevel->remainingTime = ((cmd->transitionTime == 0) || (cmd->transitionTime == 0xFFFF)) ? 1 : INTERP_STEPS_FROM_ONE_TENTH(cmd->transitionTime, ZCL_LEVEL_CHANGE_INTERVAL);
|
||||
|
||||
levelInfo.withOnOff = (cmdId == ZCL_CMD_LEVEL_STEP_WITH_ON_OFF) ? TRUE : FALSE;
|
||||
levelInfo.currentLevel256 = (u16)(pLevel->curLevel) << 8;
|
||||
|
|
|
@ -32,11 +32,6 @@
|
|||
#include "sampleLight.h"
|
||||
#include "sampleLightCtrl.h"
|
||||
|
||||
/**********************************************************************
|
||||
* LOCAL CONSTANTS
|
||||
*/
|
||||
#define ZCL_ONOFF_TIMER_INTERVAL 100 // the timer interval to change the offWaitTime/onTime attribute of the ONOFF cluster
|
||||
|
||||
/**********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
|
@ -207,6 +202,7 @@ static void sampleLight_onoff_onWithTimedOffProcess(zcl_onoff_onWithTimeOffCmd_t
|
|||
{
|
||||
zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet();
|
||||
|
||||
// Discard
|
||||
if (cmd->onOffCtrl.bits.acceptOnlyWhenOn && (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF))
|
||||
{
|
||||
return;
|
||||
|
@ -223,7 +219,7 @@ static void sampleLight_onoff_onWithTimedOffProcess(zcl_onoff_onWithTimeOffCmd_t
|
|||
sampleLight_onoff(ZCL_CMD_ONOFF_ON);
|
||||
}
|
||||
|
||||
if ((pOnOff->onTime < 0xFFFF) && (pOnOff->offWaitTime < 0xFFFF))
|
||||
if (pOnOff->onTime < 0xFFFF && pOnOff->offWaitTime < 0xFFFF)
|
||||
{
|
||||
if (pOnOff->onTime || pOnOff->offWaitTime)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue