[Silabs]Fixes and cleanup for our window app (#30693)
* Fix WindowApp Provision state check. Fix some button release logic. Add trace. Start some cleanup old elements
* Reuse BaseApplication factory reset sequence. more cleanup
* add option to link App led to baseApplication to sync leds animations. More cleanup of duplicated or unused stuff
diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp
index eefddb7..c8a99b4 100644
--- a/examples/platform/silabs/BaseApplication.cpp
+++ b/examples/platform/silabs/BaseApplication.cpp
@@ -27,10 +27,6 @@
#include <app/server/Server.h>
-#if (defined(ENABLE_WSTK_LEDS) && (defined(SL_CATALOG_SIMPLE_LED_LED1_PRESENT) || defined(SIWX_917)))
-#include "LEDWidget.h"
-#endif // ENABLE_WSTK_LEDS
-
#ifdef DISPLAY_ENABLED
#include "lcd.h"
#ifdef QR_CODE_ENABLED
@@ -129,9 +125,6 @@
StackType_t appStack[APP_TASK_STACK_SIZE / sizeof(StackType_t)];
StaticTask_t appTaskStruct;
-BaseApplication::Function_t mFunction;
-bool mFunctionTimerActive;
-
#ifdef DISPLAY_ENABLED
SilabsLCD slLCD;
#endif
@@ -149,7 +142,10 @@
#endif // EMBER_AF_PLUGIN_IDENTIFY_SERVER
} // namespace
-bool BaseApplication::sIsProvisioned = false;
+
+bool BaseApplication::sIsProvisioned = false;
+bool BaseApplication::sIsFactoryResetTriggered = false;
+LEDWidget * BaseApplication::sAppActionLed = nullptr;
#ifdef DIC_ENABLE
namespace {
@@ -280,39 +276,16 @@
void BaseApplication::FunctionEventHandler(AppEvent * aEvent)
{
- if (aEvent->Type != AppEvent::kEventType_Timer)
- {
- return;
- }
-
+ VerifyOrReturn(aEvent->Type == AppEvent::kEventType_Timer);
// If we reached here, the button was held past FACTORY_RESET_TRIGGER_TIMEOUT,
- // initiate factory reset
- if (mFunctionTimerActive && mFunction == kFunction_StartBleAdv)
+ if (!sIsFactoryResetTriggered)
{
- SILABS_LOG("Factory Reset Triggered. Release button within %ums to cancel.", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
-
- // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to
- // cancel, if required.
- StartFunctionTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
-
-#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1
- StartStatusLEDTimer();
-#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
-
- mFunction = kFunction_FactoryReset;
-
-#if (defined(ENABLE_WSTK_LEDS) && (defined(SL_CATALOG_SIMPLE_LED_LED1_PRESENT) || defined(SIWX_917)))
- // Turn off all LEDs before starting blink to make sure blink is
- // co-ordinated.
- sStatusLED.Set(false);
- sStatusLED.Blink(500);
-#endif // ENABLE_WSTK_LEDS
+ StartFactoryResetSequence();
}
- else if (mFunctionTimerActive && mFunction == kFunction_FactoryReset)
+ else
{
- // Actually trigger Factory Reset
- mFunction = kFunction_NoneSelected;
-
+ // The factory reset sequence was in motion. The cancellation window expired.
+ // Factory Reset the device now.
#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1
StopStatusLEDTimer();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
@@ -436,7 +409,8 @@
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
-#if (defined(ENABLE_WSTK_LEDS) && (defined(SL_CATALOG_SIMPLE_LED_LED1_PRESENT) || defined(SIWX_917)))
+#if defined(ENABLE_WSTK_LEDS)
+#if (defined(SL_CATALOG_SIMPLE_LED_LED1_PRESENT) || defined(SIWX_917))
// Update the status LED if factory reset has not been initiated.
//
// If system has "full connectivity", keep the LED On constantly.
@@ -449,13 +423,18 @@
// the LEDs at an even rate of 100ms.
//
// Otherwise, blink the LED ON for a very short time.
- if (mFunction != kFunction_FactoryReset)
+ if (!sIsFactoryResetTriggered)
{
ActivateStatusLedPatterns();
}
sStatusLED.Animate();
-#endif // ENABLE_WSTK_LEDS && SL_CATALOG_SIMPLE_LED_LED1_PRESENT
+#endif // SL_CATALOG_SIMPLE_LED_LED1_PRESENT
+ if (sAppActionLed)
+ {
+ sAppActionLed->Animate();
+ }
+#endif // ENABLE_WSTK_LEDS
}
void BaseApplication::ButtonHandler(AppEvent * aEvent)
@@ -469,20 +448,22 @@
// start blinking within the FACTORY_RESET_CANCEL_WINDOW_TIMEOUT
if (aEvent->ButtonEvent.Action == static_cast<uint8_t>(SilabsPlatform::ButtonAction::ButtonPressed))
{
- if (!mFunctionTimerActive && mFunction == kFunction_NoneSelected)
- {
- StartFunctionTimer(FACTORY_RESET_TRIGGER_TIMEOUT);
- mFunction = kFunction_StartBleAdv;
- }
+ StartFunctionTimer(FACTORY_RESET_TRIGGER_TIMEOUT);
}
else
{
- // If the button was released before factory reset got initiated, open the commissioning window and start BLE advertissement
- // in fast mode
- if (mFunctionTimerActive && mFunction == kFunction_StartBleAdv)
+ if (sIsFactoryResetTriggered)
{
+ CancelFactoryResetSequence();
+ }
+ else
+ {
+ // The factory reset sequence was not initiated,
+ // Press and Release:
+ // - Open the commissioning window and start BLE advertissement in fast mode when not commissioned
+ // - Output qr code in logs
+ // - Cycle LCD screen
CancelFunctionTimer();
- mFunction = kFunction_NoneSelected;
OutputQrCode(false);
#ifdef DISPLAY_ENABLED
@@ -515,19 +496,6 @@
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
}
}
- else if (mFunctionTimerActive && mFunction == kFunction_FactoryReset)
- {
- CancelFunctionTimer();
-
-#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1
- StopStatusLEDTimer();
-#endif
-
- // Change the function to none selected since factory reset has been
- // canceled.
- mFunction = kFunction_NoneSelected;
- SILABS_LOG("Factory Reset has been Canceled");
- }
}
}
@@ -538,8 +506,6 @@
SILABS_LOG("app timer stop() failed");
appError(APP_ERROR_STOP_TIMER_FAILED);
}
-
- mFunctionTimerActive = false;
}
void BaseApplication::StartFunctionTimer(uint32_t aTimeoutInMs)
@@ -558,8 +524,42 @@
SILABS_LOG("app timer start() failed");
appError(APP_ERROR_START_TIMER_FAILED);
}
+}
- mFunctionTimerActive = true;
+void BaseApplication::StartFactoryResetSequence()
+{
+ // Initiate the factory reset sequence
+ SILABS_LOG("Factory Reset Triggered. Release button within %ums to cancel.", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+
+ // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to
+ // cancel, if required.
+ StartFunctionTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);
+
+ sIsFactoryResetTriggered = true;
+#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1
+ StartStatusLEDTimer();
+#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
+
+#if (defined(ENABLE_WSTK_LEDS) && (defined(SL_CATALOG_SIMPLE_LED_LED1_PRESENT) || defined(SIWX_917)))
+ // Turn off all LEDs before starting blink to make sure blink is
+ // co-ordinated.
+ sStatusLED.Set(false);
+ sStatusLED.Blink(500);
+#endif // ENABLE_WSTK_LEDS
+}
+
+void BaseApplication::CancelFactoryResetSequence()
+{
+ CancelFunctionTimer();
+
+#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1
+ StopStatusLEDTimer();
+#endif
+ if (sIsFactoryResetTriggered)
+ {
+ sIsFactoryResetTriggered = false;
+ SILABS_LOG("Factory Reset has been Canceled");
+ }
}
void BaseApplication::StartStatusLEDTimer()
@@ -754,7 +754,7 @@
}
}
-bool BaseApplication::getWifiProvisionStatus()
+bool BaseApplication::GetProvisionStatus()
{
return BaseApplication::sIsProvisioned;
}
diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h
index 8bf6783..7b31f23 100644
--- a/examples/platform/silabs/BaseApplication.h
+++ b/examples/platform/silabs/BaseApplication.h
@@ -36,6 +36,10 @@
#include <platform/CHIPDeviceEvent.h>
#include <platform/CHIPDeviceLayer.h>
+#if defined(ENABLE_WSTK_LEDS)
+#include "LEDWidget.h"
+#endif // ENABLE_WSTK_LEDS
+
#ifdef EMBER_AF_PLUGIN_IDENTIFY_SERVER
#include <app/clusters/identify-server/identify-server.h>
#endif
@@ -71,6 +75,8 @@
BaseApplication() = default;
virtual ~BaseApplication(){};
static bool sIsProvisioned;
+ static bool sIsFactoryResetTriggered;
+ static LEDWidget * sAppActionLed;
/**
* @brief Create AppTask task and Event Queue
@@ -81,6 +87,20 @@
CHIP_ERROR StartAppTask(TaskFunction_t taskFunction);
/**
+ * @brief Links the application specific led to the baseApplication context
+ * in order to synchronize both LED animations.
+ * Some apps may not have an application led or no animation patterns.
+ *
+ * @param appLed Pointer to the configure LEDWidget for the application defined LED
+ */
+ void LinkAppLed(LEDWidget * appLed) { sAppActionLed = appLed; }
+
+ /**
+ * @brief Remove the app Led linkage form the baseApplication context
+ */
+ void UnlinkAppLed() { sAppActionLed = nullptr; }
+
+ /**
* @brief PostEvent function that add event to AppTask queue for processing
*
* @param event AppEvent to post
@@ -104,7 +124,10 @@
* Turns off Status LED before stopping timer
*/
static void StopStatusLEDTimer(void);
- static bool getWifiProvisionStatus(void);
+ static bool GetProvisionStatus(void);
+
+ static void StartFactoryResetSequence(void);
+ static void CancelFactoryResetSequence(void);
#ifdef EMBER_AF_PLUGIN_IDENTIFY_SERVER
// Idenfiy server command callbacks.
@@ -114,16 +137,6 @@
static void OnTriggerIdentifyEffect(Identify * identify);
#endif
- enum Function_t
- {
- kFunction_NoneSelected = 0,
- kFunction_SoftwareUpdate = 0,
- kFunction_StartBleAdv = 1,
- kFunction_FactoryReset = 2,
-
- kFunction_Invalid
- } Function;
-
protected:
CHIP_ERROR Init();
diff --git a/examples/window-app/silabs/include/AppEvent.h b/examples/window-app/silabs/include/AppEvent.h
index 6ed767d..f343a10 100644
--- a/examples/window-app/silabs/include/AppEvent.h
+++ b/examples/window-app/silabs/include/AppEvent.h
@@ -32,14 +32,6 @@
{
kEventType_Button = 0,
kEventType_Timer,
- kEventType_Light,
- kEventType_Install,
- kEventType_ButtonDown,
- kEventType_ButtonUp,
-
- kEventType_None,
- kEventType_Reset,
- kEventType_ResetPressed,
kEventType_ResetWarning,
kEventType_ResetCanceled,
// Button events
@@ -54,13 +46,6 @@
// Cover Attribute update events
kEventType_AttributeChange,
-
- // Provisioning events
- kEventType_ProvisionedStateChanged,
- kEventType_ConnectivityStateChanged,
- kEventType_BLEConnectionsChanged,
- kEventType_WinkOff,
- kEventType_WinkOn,
};
uint16_t Type;
diff --git a/examples/window-app/silabs/include/WindowManager.h b/examples/window-app/silabs/include/WindowManager.h
index 3312111..bed448d 100644
--- a/examples/window-app/silabs/include/WindowManager.h
+++ b/examples/window-app/silabs/include/WindowManager.h
@@ -116,7 +116,7 @@
void PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId);
static void ButtonEventHandler(uint8_t button, uint8_t btnAction);
- void UpdateLEDs();
+ void UpdateLED();
void UpdateLCD();
static void GeneralEventHandler(AppEvent * aEvent);
@@ -124,32 +124,18 @@
static void OnIconTimeout(WindowManager::Timer & timer);
protected:
- struct StateFlags
- {
-#if CHIP_ENABLE_OPENTHREAD
- bool isThreadProvisioned = false;
- bool isThreadEnabled = false;
-#else
- bool isWiFiProvisioned = false;
- bool isWiFiEnabled = false;
-#endif
- bool haveBLEConnections = false;
- bool isWinking = false;
- };
-
Cover & GetCover();
Cover * GetCover(chip::EndpointId endpoint);
static void OnLongPressTimeout(Timer & timer);
Timer * mLongPressTimer = nullptr;
- StateFlags mState;
- bool mTiltMode = false;
- bool mUpPressed = false;
- bool mDownPressed = false;
- bool mUpSuppressed = false;
- bool mDownSuppressed = false;
- bool mResetWarning = false;
+ bool mTiltMode = false;
+ bool mUpPressed = false;
+ bool mDownPressed = false;
+ bool mUpSuppressed = false;
+ bool mDownSuppressed = false;
+ bool mResetWarning = false;
private:
void HandleLongPress();
@@ -158,7 +144,6 @@
Cover mCoverList[WINDOW_COVER_COUNT];
uint8_t mCurrentCover = 0;
- LEDWidget mStatusLED;
LEDWidget mActionLED;
#ifdef DISPLAY_ENABLED
Timer mIconTimer;
diff --git a/examples/window-app/silabs/src/AppTask.cpp b/examples/window-app/silabs/src/AppTask.cpp
index 92c8053..e8b5cc3 100644
--- a/examples/window-app/silabs/src/AppTask.cpp
+++ b/examples/window-app/silabs/src/AppTask.cpp
@@ -23,8 +23,6 @@
#include "WindowManager.h"
-#include "LEDWidget.h"
-
#include <app/clusters/on-off-server/on-off-server.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
@@ -39,20 +37,10 @@
#include <lib/support/CodeUtils.h>
-#if !defined(BRD2704A)
-#define LIGHT_LED 1
-#else
-#define LIGHT_LED 0
-#endif
-
using namespace chip;
using namespace ::chip::DeviceLayer;
using namespace ::chip::DeviceLayer::Silabs;
-namespace {
-LEDWidget sLightLED;
-}
-
using namespace chip::TLV;
using namespace ::chip::DeviceLayer;
@@ -82,23 +70,6 @@
appError(err);
}
- sLightLED.Init(LIGHT_LED);
-
-// Update the LCD with the Stored value. Show QR Code if not provisioned
-#ifdef DISPLAY_ENABLED
-
-#ifdef QR_CODE_ENABLED
-#ifdef SL_WIFI
- if (!ConnectivityMgr().IsWiFiStationProvisioned())
-#else
- if (!ConnectivityMgr().IsThreadProvisioned())
-#endif /* !SL_WIFI */
- {
- GetLCD().ShowQRCode(true);
- }
-#endif // QR_CODE_ENABLED
-#endif
-
return err;
}
@@ -126,7 +97,7 @@
SILABS_LOG("App Task started");
- WindowManager::sWindow.UpdateLEDs();
+ WindowManager::sWindow.UpdateLED();
WindowManager::sWindow.UpdateLCD();
while (true)
diff --git a/examples/window-app/silabs/src/WindowManager.cpp b/examples/window-app/silabs/src/WindowManager.cpp
index 46e883a..309fb39 100644
--- a/examples/window-app/silabs/src/WindowManager.cpp
+++ b/examples/window-app/silabs/src/WindowManager.cpp
@@ -42,7 +42,6 @@
#ifdef DISPLAY_ENABLED
#include <LcdPainter.h>
-SilabsLCD slLCD;
#endif
#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
@@ -53,7 +52,6 @@
using namespace chip;
using namespace ::chip::DeviceLayer;
using namespace ::chip::DeviceLayer::Silabs;
-#define APP_STATE_LED 0
#define APP_ACTION_LED 1
#ifdef DIC_ENABLE
@@ -78,12 +76,6 @@
return aEvent;
}
-inline void OnTriggerEffectCompleted(chip::System::Layer * systemLayer, void * appState)
-{
- AppEvent event = CreateNewEvent(AppEvent::kEventType_WinkOff);
- AppTask::GetAppTask().PostEvent(&event);
-}
-
void WindowManager::Timer::Start()
{
if (xTimerIsTimerActive(mHandler))
@@ -156,7 +148,7 @@
opStatus = OperationalStatusGet(endpoint);
OperationalStatusPrint(opStatus);
chip::DeviceLayer::PlatformMgr().UnlockChipStack();
- UpdateLEDs();
+ UpdateLED();
break;
/* RW Mode */
case Attributes::Mode::Id:
@@ -183,7 +175,7 @@
/* ============= Positions for Position Aware ============= */
case Attributes::CurrentPositionLiftPercent100ths::Id:
case Attributes::CurrentPositionTiltPercent100ths::Id:
- UpdateLEDs();
+ UpdateLED();
UpdateLCD();
break;
default:
@@ -206,17 +198,12 @@
mCurrentCover = mCurrentCover < WINDOW_COVER_COUNT - 1 ? mCurrentCover + 1 : 0;
event.Type = AppEvent::kEventType_CoverChange;
AppTask::GetAppTask().PostEvent(&event);
+ ChipLogDetail(AppServer, "App controls set to cover %d", mCurrentCover + 1);
}
else if (mUpPressed)
{
mUpSuppressed = true;
- if (mResetWarning)
- {
- // Double long press button up: Reset now, you were warned!
- event.Type = AppEvent::kEventType_Reset;
- AppTask::GetAppTask().PostEvent(&event);
- }
- else
+ if (!mResetWarning)
{
// Long press button up: Reset warning!
event.Type = AppEvent::kEventType_ResetWarning;
@@ -229,6 +216,7 @@
mDownSuppressed = true;
Type type = GetCover().CycleType();
mTiltMode = mTiltMode && (Type::kTiltBlindLiftAndTilt == type);
+ ChipLogDetail(AppServer, "Cover type changed to %d", to_underlying(type));
}
}
@@ -613,8 +601,6 @@
{
chip::DeviceLayer::PlatformMgr().LockChipStack();
- ConfigurationMgr().LogDeviceConfig();
-
// Timers
mLongPressTimer = new Timer(LONG_PRESS_TIMEOUT, OnLongPressTimeout, this);
@@ -624,12 +610,8 @@
// Initialize LEDs
LEDWidget::InitGpio();
- mStatusLED.Init(APP_STATE_LED);
mActionLED.Init(APP_ACTION_LED);
-
-#ifdef DISPLAY_ENABLED
- slLCD.Init();
-#endif
+ AppTask::GetAppTask().LinkAppLed(&mActionLED);
chip::DeviceLayer::PlatformMgr().UnlockChipStack();
@@ -644,14 +626,11 @@
AppTask::GetAppTask().PostEvent(&event);
}
-void WindowManager::UpdateLEDs()
+void WindowManager::UpdateLED()
{
Cover & cover = GetCover();
if (mResetWarning)
{
- mStatusLED.Set(false);
- mStatusLED.Blink(500);
-
mActionLED.Set(false);
mActionLED.Blink(500);
}
@@ -673,22 +652,18 @@
if (OperationalState::Stall != cover.mLiftOpState)
{
-
mActionLED.Blink(100);
}
else if (LimitStatus::IsUpOrOpen == liftLimit)
{
-
mActionLED.Set(true);
}
else if (LimitStatus::IsDownOrClose == liftLimit)
{
-
mActionLED.Set(false);
}
else
{
-
mActionLED.Blink(1000);
}
}
@@ -698,11 +673,7 @@
{
// Update LCD
#ifdef DISPLAY_ENABLED
-#if CHIP_ENABLE_OPENTHREAD
- if (mState.isThreadProvisioned)
-#else
- if (BaseApplication::getWifiProvisionStatus())
-#endif // CHIP_ENABLE_OPENTHREAD
+ if (BaseApplication::GetProvisionStatus())
{
Cover & cover = GetCover();
chip::app::DataModel::Nullable<uint16_t> lift;
@@ -717,7 +688,7 @@
if (!tilt.IsNull() && !lift.IsNull())
{
- LcdPainter::Paint(slLCD, type, lift.Value(), tilt.Value(), mIcon);
+ LcdPainter::Paint(AppTask::GetAppTask().GetLCD(), type, lift.Value(), tilt.Value(), mIcon);
}
}
#endif // DISPLAY_ENABLED
@@ -748,24 +719,14 @@
{
case AppEvent::kEventType_ResetWarning:
window->mResetWarning = true;
- if (window->mLongPressTimer)
- {
- window->mLongPressTimer->Start();
- }
- SILABS_LOG("Factory Reset Triggered. Release button within %ums to cancel.", LONG_PRESS_TIMEOUT);
- // Turn off all LEDs before starting blink to make sure blink is
- // co-ordinated.
- window->UpdateLEDs();
+ AppTask::GetAppTask().StartFactoryResetSequence();
+ window->UpdateLED();
break;
case AppEvent::kEventType_ResetCanceled:
window->mResetWarning = false;
- SILABS_LOG("Factory Reset has been Canceled");
- window->UpdateLEDs();
- break;
-
- case AppEvent::kEventType_Reset:
- chip::Server::GetInstance().ScheduleFactoryReset();
+ AppTask::GetAppTask().CancelFactoryResetSequence();
+ window->UpdateLED();
break;
case AppEvent::kEventType_UpPressed:
@@ -793,9 +754,9 @@
}
else if (window->mDownPressed)
{
- window->mTiltMode = !(window->mTiltMode);
- window->mUpSuppressed = window->mDownSuppressed = true;
- aEvent->Type = AppEvent::kEventType_TiltModeChange;
+ window->mTiltMode = !(window->mTiltMode);
+ window->mDownSuppressed = true;
+ aEvent->Type = AppEvent::kEventType_TiltModeChange;
AppTask::GetAppTask().PostEvent(aEvent);
}
else
@@ -830,34 +791,20 @@
else if (window->mUpPressed)
{
window->mTiltMode = !(window->mTiltMode);
- window->mUpSuppressed = window->mDownSuppressed = true;
- aEvent->Type = AppEvent::kEventType_TiltModeChange;
+ window->mUpSuppressed = true;
+ aEvent->Type = AppEvent::kEventType_TiltModeChange;
+ AppTask::GetAppTask().PostEvent(aEvent);
}
else
{
window->GetCover().UpdateTargetPosition(OperationalState::MovingDownOrClose, window->mTiltMode);
}
break;
+
case AppEvent::kEventType_AttributeChange:
window->DispatchEventAttributeChange(aEvent->mEndpoint, aEvent->mAttributeId);
break;
- case AppEvent::kEventType_ProvisionedStateChanged:
- window->UpdateLEDs();
- window->UpdateLCD();
- break;
-
- case AppEvent::kEventType_WinkOn:
- case AppEvent::kEventType_WinkOff:
- window->mState.isWinking = (AppEvent::kEventType_WinkOn == aEvent->Type);
- window->UpdateLEDs();
- break;
-
- case AppEvent::kEventType_ConnectivityStateChanged:
- case AppEvent::kEventType_BLEConnectionsChanged:
- window->UpdateLEDs();
- break;
-
#ifdef DISPLAY_ENABLED
case AppEvent::kEventType_CoverTypeChange:
window->UpdateLCD();
@@ -868,6 +815,7 @@
window->UpdateLCD();
break;
case AppEvent::kEventType_TiltModeChange:
+ ChipLogDetail(AppServer, "App control mode changed to %s", window->mTiltMode ? "Tilt" : "Lift");
window->mIconTimer.Start();
window->mIcon = window->mTiltMode ? LcdIcon::Tilt : LcdIcon::Lift;
window->UpdateLCD();