Skip to content

Commit

Permalink
[Telink] Introduce power management (project-chip#24787)
Browse files Browse the repository at this point in the history
* [Telink] Introduce power management (#72)

* [Telink] Moved LightingManager into PWMDevice

* [Telink] Enabled PM for Light Switch example

* [Telink] Added OpenThread power management support

* [Telink] Configured project for the lowest power consumption

* [Telink] Restyle

* [Telink] Adapt system status LED and buttons with Power Mode usage

* [Telink] Fixed factory reset in pool mode of button manager

* [Telink] Updated Factory Reset trigger

* Restyled by clang-format

* [Telink] Adding lighting color feature (#59)

* [Telink] Added lighting color feature

* [Telink] Added tlsr9518adk80d.overlay to lighting-app

* [Telink] Updated RGB functionality

* [Telink] Updated RGB PWM pins

Co-authored-by: Alex Tsitsiura <[email protected]>

* Restyled by whitespace

* Restyled by clang-format

* [Telink] Minor changes

* [Telink] Add 'telink reboot' shell CLI command (#63)

* [Telink] Restyled

* [Telink] Enable CHIP SED support

* [Telink] Update new configs name/location

* [Telink] restyle

* [Telink] Add PM to all apps

* [Telink] set default configs

* [Telink] Revert EOL

* [Telink] Revert EOL

---------

Co-authored-by: Serhii Salamakha <[email protected]>
Co-authored-by: Misha.Tkachenko <[email protected]>
Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: Dmytro Huz <[email protected]>

* [Telink] Copyright update

* [Telink] Fix builds after merge of master

* [Telink] Review fixes

* [Telink] Custom RF power values example

* [Telink] Remove Level Control cluster from binding

* [Telink] Add CONFIG_MATTER_LOG_LEVEL

---------

Co-authored-by: Serhii Salamakha <[email protected]>
Co-authored-by: Misha.Tkachenko <[email protected]>
Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: Dmytro Huz <[email protected]>
  • Loading branch information
5 people authored Feb 7, 2023
1 parent 4982399 commit 062b770
Show file tree
Hide file tree
Showing 36 changed files with 666 additions and 290 deletions.
7 changes: 6 additions & 1 deletion config/telink/chip-module/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2022 Project CHIP Authors
# Copyright (c) 2022-2023 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -191,6 +191,7 @@ chip_gn_arg_string("zephyr_ar" ${CMAKE_AR})
chip_gn_arg_string("zephyr_cc" ${CMAKE_C_COMPILER})
chip_gn_arg_string("zephyr_cxx" ${CMAKE_CXX_COMPILER})
chip_gn_arg_bool ("is_debug" CONFIG_DEBUG)
chip_gn_arg_bool ("chip_logging" CONFIG_LOG)
chip_gn_arg_bool ("chip_enable_openthread" CONFIG_NET_L2_OPENTHREAD)
chip_gn_arg_bool ("chip_openthread_ftd" CONFIG_OPENTHREAD_FTD)
chip_gn_arg_bool ("chip_config_network_layer_ble" CONFIG_BT)
Expand All @@ -199,6 +200,10 @@ chip_gn_arg_bool ("chip_enable_ota_requestor" CONFIG_CHIP_OTA_REQU
chip_gn_arg_bool ("chip_build_tests" CONFIG_CHIP_BUILD_TESTS)
chip_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS)
chip_gn_arg_bool ("chip_build_libshell" CONFIG_CHIP_LIB_SHELL)
chip_gn_arg_bool ("chip_error_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 1)
chip_gn_arg_bool ("chip_progress_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 3)
chip_gn_arg_bool ("chip_detail_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 4)
chip_gn_arg_bool ("chip_automation_logging" FALSE)

if (CONFIG_CHIP_FACTORY_DATA)
chip_gn_arg_bool ("chip_use_transitional_commissionable_data_provider" "false")
Expand Down
13 changes: 13 additions & 0 deletions config/telink/chip-module/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,16 @@ config CHIP_LOG_SIZE_OPTIMIZATION
information that is too detailed to be used in most cases. You can find
full configuration enabled by this option in the
platform/telink/CHIPPlatformConfig.h file.

config CHIP_BUTTON_MANAGER_IRQ_MODE
bool "Use GPIO in an IRQ mode instead of polling the GPIO"
default n
help
Use GPIO in an IRQ mode to avoid button polling loop and extend the battery lifetime by waking up by GPIO event.
GPIO events are working only with GPIO IRQ. This option changes button matrix configuration.

config CHIP_ENABLE_APPLICATION_STATUS_LED
bool "Enable application status LED"
default y
help
Enable application status LED.
19 changes: 16 additions & 3 deletions examples/all-clusters-app/telink/include/AppTask.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* Copyright (c) 2022-2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -19,13 +19,19 @@
#pragma once

#include "AppEvent.h"
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
#include "LEDWidget.h"
#endif
#include "PWMDevice.h"

#include <zephyr/drivers/gpio.h>

#include <platform/CHIPDeviceLayer.h>

#if CONFIG_CHIP_FACTORY_DATA
#include <platform/telink/FactoryDataProvider.h>
#endif

#include <cstdint>

struct k_timer;
Expand All @@ -41,14 +47,18 @@ class AppTask

private:
friend AppTask & GetAppTask(void);

CHIP_ERROR Init(void);

static void ActionIdentifyStateUpdateHandler(k_timer * timer);

void DispatchEvent(AppEvent * event);

static void UpdateStatusLED(void);
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
static void UpdateLedStateEventHandler(AppEvent * aEvent);
static void LEDStateUpdateHandler(LEDWidget * ledWidget);
static void UpdateStatusLED();
#endif
static void FactoryResetButtonEventHandler(void);
static void StartThreadButtonEventHandler(void);
static void StartBleAdvButtonEventHandler(void);
Expand All @@ -61,7 +71,6 @@ class AppTask
static void FactoryResetHandler(AppEvent * aEvent);
static void StartThreadHandler(AppEvent * aEvent);
static void StartBleAdvHandler(AppEvent * aEvent);
static void UpdateLedStateEventHandler(AppEvent * aEvent);
static void UpdateIdentifyStateEventHandler(AppEvent * aEvent);

static void InitButtons(void);
Expand All @@ -70,6 +79,10 @@ class AppTask

static AppTask sAppTask;
PWMDevice mPwmIdentifyLed;

#if CONFIG_CHIP_FACTORY_DATA
chip::DeviceLayer::FactoryDataProvider<chip::DeviceLayer::ExternalFlashFactoryData> mFactoryDataProvider;
#endif
};

inline AppTask & GetAppTask(void)
Expand Down
22 changes: 20 additions & 2 deletions examples/all-clusters-app/telink/prj.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2022 Project CHIP Authors
# Copyright (c) 2022-2023 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,6 +27,9 @@ CONFIG_PWM=y
# OpenThread configs
CONFIG_OPENTHREAD_MTD=y
CONFIG_OPENTHREAD_FTD=n
CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT=n
CONFIG_CHIP_SED_IDLE_INTERVAL=200
CONFIG_CHIP_THREAD_SSED=n

# Default OpenThread network settings
CONFIG_OPENTHREAD_PANID=4660
Expand All @@ -53,4 +56,19 @@ CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING="2022"
CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y

# CHIP shell
CONFIG_CHIP_LIB_SHELL=n
CONFIG_CHIP_LIB_SHELL=n

# Disable factory data support.
CONFIG_CHIP_FACTORY_DATA=n
CONFIG_CHIP_FACTORY_DATA_BUILD=n
CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n

# Enable Button IRQ mode. The poling mode is used by default.
CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE=n

# Disable Status LED.
CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED=y

# Enable Power Management
CONFIG_PM=n
CONFIG_PM_DEVICE=n
109 changes: 71 additions & 38 deletions examples/all-clusters-app/telink/src/AppTask.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* Copyright (c) 2022-2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -22,16 +22,14 @@
#include "AppEvent.h"
#include "ButtonManager.h"
#include "binding-handler.h"
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>

#include <DeviceInfoProviderImpl.h>

#include "ThreadUtil.h"

#include <DeviceInfoProviderImpl.h>
#include <app/clusters/identify-server/identify-server.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <app/util/attribute-storage.h>

#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>

Expand Down Expand Up @@ -67,7 +65,8 @@ using namespace ::chip::Credentials;
using namespace ::chip::DeviceLayer;

namespace {
constexpr int kFactoryResetTriggerTimeout = 2000;
constexpr int kFactoryResetCalcTimeout = 3000;
constexpr int kFactoryResetTriggerCntr = 3;
constexpr int kAppEventQueueSize = 10;
constexpr uint8_t kButtonPushEvent = 1;
constexpr uint8_t kButtonReleaseEvent = 0;
Expand All @@ -84,20 +83,28 @@ constexpr uint32_t kIdentifyBreatheRateMs = 1000;

const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN;

#if CONFIG_CHIP_FACTORY_DATA
// NOTE! This key is for test/certification only and should not be available in production devices!
uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
#endif

K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent));
k_timer sFactoryResetTimer;
uint8_t sFactoryResetCntr = 0;

#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
LEDWidget sStatusLED;
#endif

Button sFactoryResetButton;
Button sThreadStartButton;
Button sBleAdvStartButton;

bool sIsThreadProvisioned = false;
bool sIsThreadEnabled = false;
bool sIsThreadAttached = false;
bool sHaveBLEConnections = false;
bool sIsFactoryResetTimerActive = false;
bool sIsThreadProvisioned = false;
bool sIsThreadEnabled = false;
bool sIsThreadAttached = false;
bool sHaveBLEConnections = false;

chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;

Expand Down Expand Up @@ -135,24 +142,21 @@ CHIP_ERROR AppTask::Init(void)
{
LOG_INF("SW Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);

// Initialize status LED
// Initialize LEDs
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
LEDWidget::InitGpio(LEDS_PORT);
LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler);
sStatusLED.Init(SYSTEM_STATE_LED);

UpdateStatusLED();
#endif

InitButtons();

// Initialize function button timer
k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr);
k_timer_user_data_set(&sFactoryResetTimer, this);

// Init ZCL Data Model and start server
static chip::CommonCaseDeviceServerInitParams initParams;
(void) initParams.InitializeStaticResourcesBeforeServerInit();
chip::Server::GetInstance().Init(initParams);

// Initialize PWM Identify led
CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel);
if (err != CHIP_NO_ERROR)
Expand All @@ -163,10 +167,28 @@ CHIP_ERROR AppTask::Init(void)

sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler);

// Initialize device attestation config
// Initialize CHIP server
#if CONFIG_CHIP_FACTORY_DATA
ReturnErrorOnFailure(mFactoryDataProvider.Init());
SetDeviceInstanceInfoProvider(&mFactoryDataProvider);
SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider);
SetCommissionableDataProvider(&mFactoryDataProvider);
// Read EnableKey from the factory data.
MutableByteSpan enableKey(sTestEventTriggerEnableKey);
err = mFactoryDataProvider.GetEnableKey(enableKey);
if (err != CHIP_NO_ERROR)
{
LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger");
memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey));
}
#else
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage());
static CommonCaseDeviceServerInitParams initParams;
(void) initParams.InitializeStaticResourcesBeforeServerInit();
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));
gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);

#if CONFIG_CHIP_OTA_REQUESTOR
Expand Down Expand Up @@ -226,13 +248,8 @@ CHIP_ERROR AppTask::StartApp(void)

while (true)
{
int ret = k_msgq_get(&sAppEventQueue, &event, K_MSEC(10));

while (!ret)
{
DispatchEvent(&event);
ret = k_msgq_get(&sAppEventQueue, &event, K_NO_WAIT);
}
k_msgq_get(&sAppEventQueue, &event, K_FOREVER);
DispatchEvent(&event);
}
}

Expand Down Expand Up @@ -298,15 +315,20 @@ void AppTask::FactoryResetButtonEventHandler(void)

void AppTask::FactoryResetHandler(AppEvent * aEvent)
{
if (!sIsFactoryResetTimerActive)
if (sFactoryResetCntr == 0)
{
k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetTriggerTimeout), K_NO_WAIT);
sIsFactoryResetTimerActive = true;
k_timer_start(&sFactoryResetTimer, K_MSEC(kFactoryResetCalcTimeout), K_NO_WAIT);
}
else

sFactoryResetCntr++;
LOG_INF("Factory Reset Trigger Counter: %d/%d", sFactoryResetCntr, kFactoryResetTriggerCntr);

if (sFactoryResetCntr == kFactoryResetTriggerCntr)
{
k_timer_stop(&sFactoryResetTimer);
sIsFactoryResetTimerActive = false;
sFactoryResetCntr = 0;

chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down Expand Up @@ -369,6 +391,7 @@ void AppTask::StartBleAdvHandler(AppEvent * aEvent)
}
}

#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent)
{
if (aEvent->Type == AppEvent::kEventType_UpdateLedState)
Expand Down Expand Up @@ -404,20 +427,25 @@ void AppTask::UpdateStatusLED(void)
sStatusLED.Blink(50, 950);
}
}
#endif

void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */)
{
switch (event->Type)
{
case DeviceEventType::kCHIPoBLEAdvertisingChange:
sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0;
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
UpdateStatusLED();
#endif
break;
case DeviceEventType::kThreadStateChange:
sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned();
sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled();
sIsThreadAttached = ConnectivityMgr().IsThreadAttached();
#if CONFIG_CHIP_ENABLE_APPLICATION_STATUS_LED
UpdateStatusLED();
#endif
break;
case DeviceEventType::kThreadConnectivityChange:
#if CONFIG_CHIP_OTA_REQUESTOR
Expand Down Expand Up @@ -485,16 +513,21 @@ void AppTask::FactoryResetTimerEventHandler(AppEvent * aEvent)
return;
}

sIsFactoryResetTimerActive = false;
LOG_INF("FactoryResetHandler");
chip::Server::GetInstance().ScheduleFactoryReset();
sFactoryResetCntr = 0;
LOG_INF("Factory Reset Trigger Counter is cleared");
}

void AppTask::InitButtons(void)
{
sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, true, FactoryResetButtonEventHandler);
sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, false, StartThreadButtonEventHandler);
sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, false, StartBleAdvButtonEventHandler);
#if CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE
sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_1, FactoryResetButtonEventHandler);
sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, StartThreadButtonEventHandler);
sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, StartBleAdvButtonEventHandler);
#else
sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler);
sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler);
sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler);
#endif

ButtonManagerInst().AddButton(sFactoryResetButton);
ButtonManagerInst().AddButton(sThreadStartButton);
Expand Down
Loading

0 comments on commit 062b770

Please sign in to comment.