Skip to content

Commit

Permalink
[Telink] Add WS2812Device util and update Lighting app for Mars board
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiiSalamakha committed Nov 12, 2023
1 parent a809857 commit fdd0102
Show file tree
Hide file tree
Showing 14 changed files with 300 additions and 77 deletions.
3 changes: 2 additions & 1 deletion examples/air-quality-sensor-app/telink/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ else()
set(DTC_OVERLAY_FILE ${GLOBAL_DTC_OVERLAY_FILE} ${MARS_DTC_OVERLAY_FILE} ${FLASH_DTC_OVERLAY_FILE} ${LOCAL_DTC_OVERLAY_FILE})
endif()

set(CONF_FILE prj.conf ${MARS_CONF_OVERLAY_FILE})
set(CONF_FILE ${MARS_CONF_OVERLAY_FILE} prj.conf)

# Load NCS/Zephyr build system
list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module)
Expand Down Expand Up @@ -100,6 +100,7 @@ target_sources(app PRIVATE
${TELINK_COMMON}/util/src/ButtonManager.cpp
${TELINK_COMMON}/util/src/ThreadUtil.cpp
${TELINK_COMMON}/util/src/PWMDevice.cpp
${TELINK_COMMON}/util/src/WS2812Device.cpp
${CHIP_ROOT}/examples/air-quality-sensor-app/air-quality-sensor-common/src/air-quality-sensor-manager.cpp)

chip_configure_data_model(app
Expand Down
22 changes: 19 additions & 3 deletions examples/lighting-app/telink/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH)

set(ignoreMe "${TLNK_USB_DONGLE}")

if(${TLNK_MARS_BOARD} MATCHES y)
if(EXISTS "${CHIP_ROOT}/src/platform/telink/${BOARD}_mars.overlay")
set(MARS_DTC_OVERLAY_FILE "${CHIP_ROOT}/src/platform/telink/${BOARD}_mars.overlay")
else()
unset(MARS_DTC_OVERLAY_FILE)
endif()
if(EXISTS "${CHIP_ROOT}/src/platform/telink/${BOARD}_mars.conf")
set(MARS_CONF_OVERLAY_FILE "${CHIP_ROOT}/src/platform/telink/${BOARD}_mars.conf")
else()
unset(MARS_CONF_OVERLAY_FILE)
endif()
else()
unset(MARS_CONF_OVERLAY_FILE)
endif()

if(${TLNK_USB_DONGLE} MATCHES y)
if(EXISTS "${CHIP_ROOT}/src/platform/telink/${BOARD}_usb.overlay")
set(USB_DTC_OVERLAY_FILE "${CHIP_ROOT}/src/platform/telink/${BOARD}_usb.overlay")
Expand Down Expand Up @@ -58,14 +73,14 @@ endif()

if(DTC_OVERLAY_FILE)
set(DTC_OVERLAY_FILE
"${DTC_OVERLAY_FILE} ${GLOBAL_DTC_OVERLAY_FILE} ${USB_DTC_OVERLAY_FILE} ${FLASH_DTC_OVERLAY_FILE} ${LOCAL_DTC_OVERLAY_FILE}"
"${DTC_OVERLAY_FILE} ${GLOBAL_DTC_OVERLAY_FILE} ${USB_DTC_OVERLAY_FILE} ${MARS_DTC_OVERLAY_FILE} ${FLASH_DTC_OVERLAY_FILE} ${LOCAL_DTC_OVERLAY_FILE}"
CACHE STRING "" FORCE
)
else()
set(DTC_OVERLAY_FILE ${GLOBAL_DTC_OVERLAY_FILE} ${USB_DTC_OVERLAY_FILE} ${FLASH_DTC_OVERLAY_FILE} ${LOCAL_DTC_OVERLAY_FILE})
set(DTC_OVERLAY_FILE ${GLOBAL_DTC_OVERLAY_FILE} ${USB_DTC_OVERLAY_FILE} ${MARS_DTC_OVERLAY_FILE} ${FLASH_DTC_OVERLAY_FILE} ${LOCAL_DTC_OVERLAY_FILE})
endif()

set(CONF_FILE ${USB_CONF_OVERLAY_FILE} prj.conf)
set(CONF_FILE ${USB_CONF_OVERLAY_FILE} ${MARS_CONF_OVERLAY_FILE} prj.conf)

# Load NCS/Zephyr build system
list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module)
Expand Down Expand Up @@ -99,6 +114,7 @@ target_sources(app PRIVATE
${TELINK_COMMON}/util/src/ButtonManager.cpp
${TELINK_COMMON}/util/src/ThreadUtil.cpp
${TELINK_COMMON}/util/src/PWMDevice.cpp
${TELINK_COMMON}/util/src/WS2812Device.cpp
${TELINK_COMMON}/util/src/ColorFormat.cpp)

chip_configure_data_model(app
Expand Down
12 changes: 11 additions & 1 deletion examples/lighting-app/telink/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ class AppTask : public AppTaskCommon
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */
void SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uint8_t * value);
void UpdateClusterState(void);
PWMDevice & GetPWMDevice(void) { return mPwmRgbBlueLed; }

#ifdef CONFIG_WS2812_STRIP
WS2812Device & GetLightingDevice(void) { return mWS2812Device; }
#else
PWMDevice & GetLightingDevice(void) { return mPwmRgbBlueLed; }
#endif /* CONFIG_WS2812_STRIP */

private:
friend AppTask & GetAppTask(void);
Expand All @@ -47,11 +52,16 @@ class AppTask : public AppTaskCommon
static unsigned int sPowerOnFactoryResetTimerCnt;
static k_timer sPowerOnFactoryResetTimer;
#endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */

#ifdef CONFIG_WS2812_STRIP
WS2812Device mWS2812Device;
#else
PWMDevice mPwmRgbBlueLed;
#if USE_RGB_PWM
PWMDevice mPwmRgbGreenLed;
PWMDevice mPwmRgbRedLed;
#endif
#endif /* CONFIG_WS2812_STRIP */

static AppTask sAppTask;
};
Expand Down
126 changes: 96 additions & 30 deletions examples/lighting-app/telink/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,23 @@
LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);

namespace {
#ifdef CONFIG_WS2812_STRIP
const struct device *const ws2812_dev = DEVICE_DT_GET(DT_ALIAS(led_strip));
#else
const struct pwm_dt_spec sPwmRgbSpecBlueLed = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0));
#if USE_RGB_PWM
const struct pwm_dt_spec sPwmRgbSpecGreenLed = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1));
const struct pwm_dt_spec sPwmRgbSpecRedLed = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led2));
#endif
#endif // CONFIG_WS2812_STRIP

#if defined(CONFIG_WS2812_STRIP) || USE_RGB_PWM
uint8_t sBrightness;
PWMDevice::Action_t sColorAction = PWMDevice::INVALID_ACTION;
XyColor_t sXY;
HsvColor_t sHSV;
CtColor_t sCT;
#endif
#endif // CONFIG_WS2812_STRIP || USE_RGB_PWM
} // namespace

AppTask AppTask::sAppTask;
Expand All @@ -55,14 +61,24 @@ void AppTask::PowerOnFactoryReset(void)

CHIP_ERROR AppTask::Init(void)
{
CHIP_ERROR err;

// Init lighting manager
uint8_t minLightLevel = kDefaultMinLevel;
Clusters::LevelControl::Attributes::MinLevel::Get(kExampleEndpointId, &minLightLevel);

uint8_t maxLightLevel = kDefaultMaxLevel;
Clusters::LevelControl::Attributes::MaxLevel::Get(kExampleEndpointId, &maxLightLevel);

CHIP_ERROR err = sAppTask.mPwmRgbBlueLed.Init(&sPwmRgbSpecBlueLed, minLightLevel, maxLightLevel, maxLightLevel);
#ifdef CONFIG_WS2812_STRIP
err = sAppTask.mWS2812Device.Init(ws2812_dev, STRIP_NUM_PIXELS(led_strip));
if (err != CHIP_NO_ERROR)
{
LOG_ERR("WS2812 Device Init fail");
return err;
}
#else
err = sAppTask.mPwmRgbBlueLed.Init(&sPwmRgbSpecBlueLed, minLightLevel, maxLightLevel, maxLightLevel);
if (err != CHIP_NO_ERROR)
{
LOG_ERR("Blue RGB PWM Device Init fail");
Expand All @@ -84,6 +100,7 @@ CHIP_ERROR AppTask::Init(void)
}
#endif
sAppTask.mPwmRgbBlueLed.SetCallbacks(ActionInitiated, ActionCompleted, nullptr);
#endif // CONFIG_WS2812_STRIP

#if APP_USE_EXAMPLE_START_BUTTON
SetExampleButtonCallbacks(LightingActionEventHandler);
Expand All @@ -95,6 +112,21 @@ CHIP_ERROR AppTask::Init(void)

void AppTask::LightingActionEventHandler(AppEvent * aEvent)
{
#ifdef CONFIG_WS2812_STRIP
if (aEvent->Type == AppEvent::kEventType_Button)
{
if (sAppTask.mWS2812Device.IsTurnedOn())
{
sAppTask.mWS2812Device.Set(SET_RGB_TURN_OFF);
}
else
{
sAppTask.mWS2812Device.Set(SET_RGB_TURN_ON);
}

sAppTask.UpdateClusterState();
}
#else
PWMDevice::Action_t action = PWMDevice::INVALID_ACTION;
int32_t actor = 0;

Expand All @@ -120,8 +152,7 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent)
actor = AppEvent::kEventType_Button;
}

if (action != PWMDevice::INVALID_ACTION &&
(
if (action != PWMDevice::INVALID_ACTION && (
#if USE_RGB_PWM
!sAppTask.mPwmRgbRedLed.InitiateAction(action, actor, NULL) ||
!sAppTask.mPwmRgbGreenLed.InitiateAction(action, actor, NULL) ||
Expand All @@ -130,6 +161,7 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent)
{
LOG_INF("Action is in progress or active");
}
#endif // CONFIG_WS2812_STRIP
}

void AppTask::ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor)
Expand Down Expand Up @@ -171,34 +203,48 @@ void AppTask::ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor)

void AppTask::UpdateClusterState(void)
{
#if USE_RGB_PWM
bool isTurnedOn =
sAppTask.mPwmRgbRedLed.IsTurnedOn() || sAppTask.mPwmRgbGreenLed.IsTurnedOn() || sAppTask.mPwmRgbBlueLed.IsTurnedOn();
#else
bool isTurnedOn = sAppTask.mPwmRgbBlueLed.IsTurnedOn();
#endif
// write the new on/off value
EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(kExampleEndpointId, isTurnedOn);
EmberAfStatus status;
bool isTurnedOn;
uint8_t setLevel;

if (status != EMBER_ZCL_STATUS_SUCCESS)
{
LOG_ERR("Update OnOff fail: %x", status);
}
#if defined(CONFIG_WS2812_STRIP) || USE_RGB_PWM
#ifdef CONFIG_WS2812_STRIP
isTurnedOn = sAppTask.mWS2812Device.IsTurnedOn();
#else
isTurnedOn = sAppTask.mPwmRgbRedLed.IsTurnedOn()
|| sAppTask.mPwmRgbGreenLed.IsTurnedOn()
|| sAppTask.mPwmRgbBlueLed.IsTurnedOn();
#endif // CONFIG_WS2812_STRIP

#if USE_RGB_PWM
uint8_t setLevel;
if (sColorAction == PWMDevice::COLOR_ACTION_XY || sColorAction == PWMDevice::COLOR_ACTION_HSV ||
sColorAction == PWMDevice::COLOR_ACTION_CT)
{
setLevel = sBrightness;
}
else
{
#ifdef CONFIG_WS2812_STRIP
setLevel = sAppTask.mWS2812Device.GetBlueLevel();
if (setLevel > kDefaultMaxLevel)
{
setLevel = kDefaultMaxLevel;
}
#else
setLevel = sAppTask.mPwmRgbBlueLed.GetLevel();
#endif // CONFIG_WS2812_STRIP
}
#else
uint8_t setLevel = sAppTask.mPwmRgbBlueLed.GetLevel();
#endif
isTurnedOn = sAppTask.mPwmRgbBlueLed.IsTurnedOn();
setLevel = sAppTask.mPwmRgbBlueLed.GetLevel();
#endif // CONFIG_WS2812_STRIP || USE_RGB_PWM

// write the new on/off value
status = Clusters::OnOff::Attributes::OnOff::Set(kExampleEndpointId, isTurnedOn);
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
LOG_ERR("Update OnOff fail: %x", status);
}

status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kExampleEndpointId, setLevel);
if (status != EMBER_ZCL_STATUS_SUCCESS)
{
Expand All @@ -208,22 +254,33 @@ void AppTask::UpdateClusterState(void)

void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uint8_t * value)
{
#if USE_RGB_PWM
#if defined(CONFIG_WS2812_STRIP) || USE_RGB_PWM
bool setRgbAction = false;
RgbColor_t rgb;
#endif
#endif // CONFIG_WS2812_STRIP || USE_RGB_PWM

if (aAction == PWMDevice::ON_ACTION || aAction == PWMDevice::OFF_ACTION)
{
#ifdef CONFIG_WS2812_STRIP
if (aAction == PWMDevice::ON_ACTION)
{
sAppTask.mWS2812Device.Set(SET_RGB_TURN_ON);
}
else if (aAction == PWMDevice::OFF_ACTION)
{
sAppTask.mWS2812Device.Set(SET_RGB_TURN_OFF);
}
#else
sAppTask.mPwmRgbBlueLed.InitiateAction(aAction, aActor, value);
#if USE_RGB_PWM
sAppTask.mPwmRgbRedLed.InitiateAction(aAction, aActor, value);
sAppTask.mPwmRgbGreenLed.InitiateAction(aAction, aActor, value);
#endif
#endif // CONFIG_WS2812_STRIP
}
else if (aAction == PWMDevice::LEVEL_ACTION)
{
#if USE_RGB_PWM
#if defined(CONFIG_WS2812_STRIP) || USE_RGB_PWM
// Save a new brightness for ColorControl
sBrightness = *value;

Expand All @@ -238,19 +295,16 @@ void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uin
}
else
{
rgb.r = sBrightness;
rgb.g = sBrightness;
rgb.b = sBrightness;
memset(&rgb, sBrightness, sizeof(RgbColor_t));
}

ChipLogProgress(Zcl, "New brightness: %u | R: %u, G: %u, B: %u", sBrightness, rgb.r, rgb.g, rgb.b);
setRgbAction = true;
#else
sAppTask.mPwmRgbBlueLed.InitiateAction(aAction, aActor, value);
#endif
#endif // CONFIG_WS2812_STRIP || USE_RGB_PWM
}

#if USE_RGB_PWM
#if defined(CONFIG_WS2812_STRIP) || USE_RGB_PWM
else if (aAction == PWMDevice::COLOR_ACTION_XY)
{
sXY = *reinterpret_cast<XyColor_t *>(value);
Expand Down Expand Up @@ -283,11 +337,15 @@ void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uin

if (setRgbAction)
{
#ifdef CONFIG_WS2812_STRIP
sAppTask.mWS2812Device.SetLevel(&rgb);
#else
sAppTask.mPwmRgbRedLed.InitiateAction(aAction, aActor, &rgb.r);
sAppTask.mPwmRgbGreenLed.InitiateAction(aAction, aActor, &rgb.g);
sAppTask.mPwmRgbBlueLed.InitiateAction(aAction, aActor, &rgb.b);
#endif // CONFIG_WS2812_STRIP
}
#endif
#endif // CONFIG_WS2812_STRIP || USE_RGB_PWM
}

#ifdef CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET
Expand All @@ -301,11 +359,15 @@ void AppTask::PowerOnFactoryResetEventHandler(AppEvent * aEvent)
{
LOG_INF("Lighting App Power On Factory Reset Handler");
sPowerOnFactoryResetTimerCnt = 1;
#ifdef CONFIG_WS2812_STRIP
sAppTask.mWS2812Device.Set(sPowerOnFactoryResetTimerCnt % 2);
#else
sAppTask.mPwmRgbBlueLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#if USE_RGB_PWM
sAppTask.mPwmRgbRedLed.Set(sPowerOnFactoryResetTimerCnt % 2);
sAppTask.mPwmRgbGreenLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#endif
#endif // CONFIG_WS2812_STRIP
k_timer_init(&sPowerOnFactoryResetTimer, PowerOnFactoryResetTimerEvent, nullptr);
k_timer_start(&sPowerOnFactoryResetTimer, K_MSEC(kPowerOnFactoryResetIndicationTimeMs),
K_MSEC(kPowerOnFactoryResetIndicationTimeMs));
Expand All @@ -315,11 +377,15 @@ void AppTask::PowerOnFactoryResetTimerEvent(struct k_timer * timer)
{
sPowerOnFactoryResetTimerCnt++;
LOG_INF("Lighting App Power On Factory Reset Handler %u", sPowerOnFactoryResetTimerCnt);
#ifdef CONFIG_WS2812_STRIP
sAppTask.mWS2812Device.Set(sPowerOnFactoryResetTimerCnt % 2);
#else
sAppTask.mPwmRgbBlueLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#if USE_RGB_PWM
sAppTask.mPwmRgbRedLed.Set(sPowerOnFactoryResetTimerCnt % 2);
sAppTask.mPwmRgbGreenLed.Set(sPowerOnFactoryResetTimerCnt % 2);
#endif
#endif // CONFIG_WS2812_STRIP
if (sPowerOnFactoryResetTimerCnt > kPowerOnFactoryResetIndicationMax)
{
k_timer_stop(timer);
Expand Down
4 changes: 2 additions & 2 deletions examples/lighting-app/telink/src/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &
}
else if (clusterId == LevelControl::Id && attributeId == LevelControl::Attributes::CurrentLevel::Id)
{
if (GetAppTask().GetPWMDevice().IsTurnedOn())
if (GetAppTask().GetLightingDevice().IsTurnedOn())
{
ChipLogDetail(Zcl, "Cluster LevelControl: attribute CurrentLevel set to %u", *value);
GetAppTask().SetInitiateAction(PWMDevice::LEVEL_ACTION, static_cast<int32_t>(AppEvent::kEventType_Lighting), value);
Expand Down Expand Up @@ -138,7 +138,7 @@ void emberAfOnOffClusterInitCallback(EndpointId endpoint)
if (status == EMBER_ZCL_STATUS_SUCCESS)
{
// Set actual state to stored before reboot
GetAppTask().GetPWMDevice().Set(storedValue);
GetAppTask().GetLightingDevice().Set(storedValue);
}

GetAppTask().UpdateClusterState();
Expand Down
4 changes: 4 additions & 0 deletions examples/platform/telink/common/include/AppTaskCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include "PWMDevice.h"
#endif

#ifdef CONFIG_WS2812_STRIP
#include "WS2812Device.h"
#endif

#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
Expand Down
Loading

0 comments on commit fdd0102

Please sign in to comment.