Skip to content

Commit

Permalink
[QPG] LED handling switched from polling to event-based (#23526)
Browse files Browse the repository at this point in the history
* Switched to callbacks

* LEDs are behaving the same

* Cleanup

* BLE is now also handled by events

* Better variable name

* Logs removed

* switch-case is more elegant here

* Moved LED handling to separate func

* AppTask stack reduced to 2kB

* Restyled by clang-format

* Updating LEDs only on connectivity change

Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
2 people authored and pull[bot] committed Jan 30, 2024
1 parent cd4812e commit 1173131
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 43 deletions.
3 changes: 3 additions & 0 deletions examples/lighting-app/qpg/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class AppTask
static void LightingActionEventHandler(AppEvent * aEvent);
static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState);

static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
static void UpdateLEDs(void);

void StartTimer(uint32_t aTimeoutMs);
void CancelTimer(void);

Expand Down
106 changes: 63 additions & 43 deletions examples/lighting-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ using namespace ::chip::DeviceLayer;

#define FACTORY_RESET_TRIGGER_TIMEOUT 3000
#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000
#define APP_TASK_STACK_SIZE (3 * 1024)
#define APP_TASK_STACK_SIZE (2 * 1024)
#define APP_TASK_PRIORITY 2
#define APP_EVENT_QUEUE_SIZE 10
#define QPG_LIGHT_ENDPOINT_ID (1)
Expand Down Expand Up @@ -260,6 +260,8 @@ CHIP_ERROR AppTask::Init()
{
CHIP_ERROR err = CHIP_NO_ERROR;

PlatformMgr().AddEventHandler(MatterEventHandler, 0);

ChipLogProgress(NotSpecified, "Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);

// Init ZCL Data Model and start server
Expand Down Expand Up @@ -303,53 +305,12 @@ void AppTask::AppTaskMain(void * pvParameter)

while (true)
{
BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10));
BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY);
while (eventReceived == pdTRUE)
{
sAppTask.DispatchEvent(&event);
eventReceived = xQueueReceive(sAppEventQueue, &event, 0);
}

// Collect connectivity and configuration state from the CHIP stack. Because
// the CHIP event loop is being run in a separate task, the stack must be
// locked while these values are queried. However we use a non-blocking
// lock request (TryLockCHIPStack()) to avoid blocking other UI activities
// when the CHIP task is busy (e.g. with a long crypto operation).
if (PlatformMgr().TryLockChipStack())
{
sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned();
sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled();
sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0);
PlatformMgr().UnlockChipStack();
}

// Update the status LED if factory reset has not been initiated.
//
// If system has "full connectivity", keep the LED On constantly.
//
// If thread and service provisioned, but not attached to the thread network
// yet OR no connectivity to the service OR subscriptions are not fully
// established THEN blink the LED Off for a short period of time.
//
// If the system has ble connection(s) uptill the stage above, THEN blink
// the LEDs at an even rate of 100ms.
//
// Otherwise, blink the LED ON for a very short time.
if (sAppTask.mFunction != kFunction_FactoryReset)
{
if (sIsThreadProvisioned && sIsThreadEnabled)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
}
else if (sHaveBLEConnections)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
}
else
{
qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
}
}
}
}

Expand Down Expand Up @@ -621,3 +582,62 @@ void AppTask::UpdateClusterState(void)
ChipLogError(NotSpecified, "ERR: updating level %x", status);
}
}

void AppTask::UpdateLEDs(void)
{
// If system has "full connectivity", keep the LED On constantly.
//
// If thread and service provisioned, but not attached to the thread network
// yet OR no connectivity to the service OR subscriptions are not fully
// established THEN blink the LED Off for a short period of time.
//
// If the system has ble connection(s) uptill the stage above, THEN blink
// the LEDs at an even rate of 100ms.
//
// Otherwise, blink the LED ON for a very short time.
if (sIsThreadProvisioned && sIsThreadEnabled)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
}
else if (sHaveBLEConnections)
{
qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
}
else
{
qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
}
}

void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t)
{
switch (event->Type)
{
case DeviceEventType::kServiceProvisioningChange: {
sIsThreadProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned;
UpdateLEDs();
break;
}

case DeviceEventType::kThreadConnectivityChange: {
sIsThreadEnabled = (event->ThreadConnectivityChange.Result == kConnectivity_Established);
UpdateLEDs();
break;
}

case DeviceEventType::kCHIPoBLEConnectionEstablished: {
sHaveBLEConnections = true;
UpdateLEDs();
break;
}

case DeviceEventType::kCHIPoBLEConnectionClosed: {
sHaveBLEConnections = false;
UpdateLEDs();
break;
}

default:
break;
}
}
4 changes: 4 additions & 0 deletions src/platform/qpg/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,12 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event)
break;

case DeviceEventType::kCHIPoBLEUnsubscribe: {
ChipDeviceEvent connClosedEvent;

ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe");
HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
connClosedEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed;
PlatformMgr().PostEventOrDie(&connClosedEvent);
}
break;

Expand Down

0 comments on commit 1173131

Please sign in to comment.