Skip to content

Commit

Permalink
[Infineon] Support Factory reset for all-clusters example apps
Browse files Browse the repository at this point in the history
  • Loading branch information
praveenCY committed Aug 14, 2022
1 parent 1c613ad commit 4362404
Show file tree
Hide file tree
Showing 18 changed files with 412 additions and 133 deletions.
5 changes: 4 additions & 1 deletion examples/all-clusters-app/p6/include/AppConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
#define APP_TASK_NAME "APP"

#define APP_LIGHT_BUTTON_IDX 0
#define APP_FUNCTION_BUTTON_IDX 1

#define APP_LIGHT_BUTTON CYBSP_USER_BTN1
#define APP_BUTTON_DEBOUNCE_PERIOD_MS 50
#define APP_FUNCTION_BUTTON CYBSP_USER_BTN2
#define APP_BUTTON_DEBOUNCE_PERIOD_MS 200

#define APP_BUTTON_PRESSED 0
#define APP_BUTTON_RELEASED 1
Expand Down
14 changes: 14 additions & 0 deletions examples/all-clusters-app/p6/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,22 @@ class AppTask
CHIP_ERROR Init();

static AppTask sAppTask;
void CancelTimer(void);
void DispatchEvent(AppEvent * event);
static void FunctionTimerEventHandler(AppEvent * event);
static void FunctionHandler(AppEvent * event);
static void TimerEventHandler(TimerHandle_t timer);
static void OnOffUpdateClusterState(intptr_t context);
void StartTimer(uint32_t aTimeoutMs);

enum class Function
{
kNoneSelected = 0,
kFactoryReset = 1,
kInvalid
};
Function mFunction = Function::kNoneSelected;
bool mFunctionTimerActive = false;
};

inline AppTask & GetAppTask(void)
Expand Down
1 change: 1 addition & 0 deletions examples/all-clusters-app/p6/include/ButtonHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ class ButtonHandler
private:
static void GpioInit(void);
static void light_button_callback(void * handler_arg, cyhal_gpio_event_t event);
static void func_button_callback(void * handler_arg, cyhal_gpio_event_t event);
static void TimerCallback(TimerHandle_t xTimer);
};
113 changes: 111 additions & 2 deletions examples/all-clusters-app/p6/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ using namespace ::chip::System;
#define APP_EVENT_QUEUE_SIZE 10
#define APP_TASK_STACK_SIZE (4096)
#define APP_WAIT_LOOP 1000
#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 5000

LEDWidget sStatusLED;
LEDWidget sLightLED;
LEDWidget sClusterLED;

namespace {
TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer.

TaskHandle_t sAppTaskHandle;
QueueHandle_t sAppEventQueue;
Expand Down Expand Up @@ -184,6 +186,18 @@ CHIP_ERROR AppTask::Init()
// Initialise WSTK buttons PB0 and PB1 (including debounce).
ButtonHandler::Init();

// Create FreeRTOS sw timer for Function Selection.
sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel
1, // == default timer period (mS)
false, // no timer reload (==one-shot)
(void *) this, // init timer id = app task obj context
TimerEventHandler // timer callback handler
);
if (sFunctionTimer == NULL)
{
P6_LOG("funct timer create failed");
appError(APP_ERROR_CREATE_TIMER_FAILED);
}
NetWorkCommissioningInstInit();
P6_LOG("Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING);

Expand Down Expand Up @@ -234,7 +248,7 @@ void AppTask::LightActionEventHandler(AppEvent * event)

void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction)
{
if (btnIdx != APP_LIGHT_BUTTON_IDX)
if (btnIdx != APP_LIGHT_BUTTON_IDX && btnIdx != APP_FUNCTION_BUTTON_IDX)
{
return;
}
Expand All @@ -244,11 +258,106 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction)
button_event.ButtonEvent.ButtonIdx = btnIdx;
button_event.ButtonEvent.Action = btnAction;

if ((btnIdx == APP_LIGHT_BUTTON_IDX) && (btnAction == APP_BUTTON_RELEASED))
if (btnIdx == APP_LIGHT_BUTTON_IDX)
{
button_event.Handler = LightActionEventHandler;
sAppTask.PostEvent(&button_event);
}
else if (btnIdx == APP_FUNCTION_BUTTON_IDX)
{
button_event.Handler = FunctionHandler;
sAppTask.PostEvent(&button_event);
}
}

void AppTask::TimerEventHandler(TimerHandle_t timer)
{
AppEvent event;
event.Type = AppEvent::kEventType_Timer;
event.TimerEvent.Context = (void *) timer;
event.Handler = FunctionTimerEventHandler;
sAppTask.PostEvent(&event);
}

void AppTask::FunctionTimerEventHandler(AppEvent * event)
{
if (event->Type != AppEvent::kEventType_Timer)
{
return;
}

if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kFactoryReset)
{
// Actually trigger Factory Reset
sAppTask.mFunction = Function::kNoneSelected;
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

void AppTask::FunctionHandler(AppEvent * event)
{
if (event->ButtonEvent.Action == APP_BUTTON_PRESSED)
{
if (!sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kNoneSelected)
{
P6_LOG("Factory Reset Triggered. Press button again within %us to cancel.", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT / 1000);
// Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to
// cancel, if required.
sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT);

sAppTask.mFunction = Function::kFactoryReset;

// Turn off all LEDs before starting blink to make sure blink is
// co-ordinated.
sStatusLED.Set(false);
sLightLED.Set(false);

sStatusLED.Blink(500);
sLightLED.Blink(500);
}
else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == Function::kFactoryReset)
{

sAppTask.CancelTimer();

// Change the function to none selected since factory reset has been
// canceled.
sAppTask.mFunction = Function::kNoneSelected;

P6_LOG("Factory Reset has been Canceled");
}
}
}

void AppTask::CancelTimer()
{
if (xTimerStop(sFunctionTimer, 0) == pdFAIL)
{
P6_LOG("app timer stop() failed");
appError(APP_ERROR_STOP_TIMER_FAILED);
}

mFunctionTimerActive = false;
}

void AppTask::StartTimer(uint32_t aTimeoutInMs)
{
if (xTimerIsTimerActive(sFunctionTimer))
{
P6_LOG("app timer already started!");
CancelTimer();
}

// timer is not active, change its period to required value (== restart).
// FreeRTOS- Block for a maximum of 100 ticks if the change period command
// cannot immediately be sent to the timer command queue.
if (xTimerChangePeriod(sFunctionTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS)
{
P6_LOG("app timer start() failed");
appError(APP_ERROR_START_TIMER_FAILED);
}

mFunctionTimerActive = true;
}

void AppTask::PostEvent(const AppEvent * event)
Expand Down
52 changes: 39 additions & 13 deletions examples/all-clusters-app/p6/src/ButtonHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,28 @@
#include "AppTask.h"

namespace {
constexpr int kButtonCount = 2;

TimerHandle_t buttonTimer; // FreeRTOS timers used for debouncing buttons
TimerHandle_t buttonTimers[kButtonCount]; // FreeRTOS timers used for debouncing
// buttons. Array to hold handles to
// the created timers.

} // namespace

void ButtonHandler::Init(void)
{
GpioInit();

buttonTimer = xTimerCreate("BtnTmr", // Just a text name, not used by the RTOS kernel
APP_BUTTON_DEBOUNCE_PERIOD_MS, // timer period
false, // no timer reload (==one-shot)
(void *) (int) APP_LIGHT_BUTTON_IDX, // init timer id = button index
TimerCallback // timer callback handler (all buttons use
// the same timer cn function)
);
// Create FreeRTOS sw timers for debouncing buttons.
for (uint8_t i = 0; i < kButtonCount; i++)
{
buttonTimers[i] = xTimerCreate("BtnTmr", // Just a text name, not used by the RTOS kernel
APP_BUTTON_DEBOUNCE_PERIOD_MS, // timer period
false, // no timer reload (==one-shot)
(void *) (int) i, // init timer id = button index
TimerCallback // timer callback handler (all buttons use
// the same timer cn function)
);
}
}

void ButtonHandler::GpioInit(void)
Expand All @@ -50,19 +56,34 @@ void ButtonHandler::GpioInit(void)
{
printf(" cyhal_gpio_init failed for APP_LIGHT_BUTTON\r\n");
}

result = cyhal_gpio_init(APP_FUNCTION_BUTTON, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
if (result != CY_RSLT_SUCCESS)
{
printf(" cyhal_gpio_init failed for APP_FUNCTION_BUTTON\r\n");
}
/* Configure GPIO interrupt. */
static cyhal_gpio_callback_data_t light_button_cbdata;
static cyhal_gpio_callback_data_t func_button_cbdata;
light_button_cbdata.callback = light_button_callback;
light_button_cbdata.callback_arg = NULL;
cyhal_gpio_register_callback(APP_LIGHT_BUTTON, &light_button_cbdata);
func_button_cbdata.callback = func_button_callback;
func_button_cbdata.callback_arg = NULL;
cyhal_gpio_register_callback(APP_FUNCTION_BUTTON, &func_button_cbdata);
cyhal_gpio_enable_event(APP_LIGHT_BUTTON, CYHAL_GPIO_IRQ_FALL, GPIO_INTERRUPT_PRIORITY, true);
cyhal_gpio_enable_event(APP_FUNCTION_BUTTON, CYHAL_GPIO_IRQ_FALL, GPIO_INTERRUPT_PRIORITY, true);
}

void ButtonHandler::light_button_callback(void * handler_arg, cyhal_gpio_event_t event)
{
portBASE_TYPE taskWoken = pdFALSE;
xTimerStartFromISR(buttonTimer, &taskWoken);
xTimerStartFromISR(buttonTimers[APP_LIGHT_BUTTON_IDX], &taskWoken);
}

void ButtonHandler::func_button_callback(void * handler_arg, cyhal_gpio_event_t event)
{
portBASE_TYPE taskWoken = pdFALSE;
xTimerStartFromISR(buttonTimers[APP_FUNCTION_BUTTON_IDX], &taskWoken);
}

void ButtonHandler::TimerCallback(TimerHandle_t xTimer)
Expand All @@ -77,11 +98,16 @@ void ButtonHandler::TimerCallback(TimerHandle_t xTimer)
case APP_LIGHT_BUTTON_IDX:
buttonevent = cyhal_gpio_read(APP_LIGHT_BUTTON);
break;

case APP_FUNCTION_BUTTON_IDX:
buttonevent = cyhal_gpio_read(APP_FUNCTION_BUTTON);
break;
default:
P6_LOG("Unhandled TimerID: %d", timerId);
break;
}

GetAppTask().ButtonEventHandler(timerId, (buttonevent) ? APP_BUTTON_PRESSED : APP_BUTTON_RELEASED);
if (buttonevent)
{
GetAppTask().ButtonEventHandler(timerId, APP_BUTTON_PRESSED);
}
}
5 changes: 4 additions & 1 deletion examples/all-clusters-minimal-app/p6/include/AppConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
#define APP_TASK_NAME "APP"

#define APP_LIGHT_BUTTON_IDX 0
#define APP_FUNCTION_BUTTON_IDX 1

#define APP_LIGHT_BUTTON CYBSP_USER_BTN1
#define APP_BUTTON_DEBOUNCE_PERIOD_MS 50
#define APP_FUNCTION_BUTTON CYBSP_USER_BTN2
#define APP_BUTTON_DEBOUNCE_PERIOD_MS 200

#define APP_BUTTON_PRESSED 0
#define APP_BUTTON_RELEASED 1
Expand Down
14 changes: 14 additions & 0 deletions examples/all-clusters-minimal-app/p6/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,22 @@ class AppTask
CHIP_ERROR Init();

static AppTask sAppTask;
void CancelTimer(void);
void DispatchEvent(AppEvent * event);
static void FunctionTimerEventHandler(AppEvent * event);
static void FunctionHandler(AppEvent * event);
static void TimerEventHandler(TimerHandle_t timer);
static void OnOffUpdateClusterState(intptr_t context);
void StartTimer(uint32_t aTimeoutMs);

enum class Function
{
kNoneSelected = 0,
kFactoryReset = 1,
kInvalid
};
Function mFunction = Function::kNoneSelected;
bool mFunctionTimerActive = false;
};

inline AppTask & GetAppTask(void)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ class ButtonHandler
private:
static void GpioInit(void);
static void light_button_callback(void * handler_arg, cyhal_gpio_event_t event);
static void func_button_callback(void * handler_arg, cyhal_gpio_event_t event);
static void TimerCallback(TimerHandle_t xTimer);
};
Loading

0 comments on commit 4362404

Please sign in to comment.