blob: 551b97d39414fdde6b3f074ce993bb95afb1567c [file] [log] [blame]
/*
*
* Copyright (c) 2019 Google LLC.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ButtonHandler.h"
#include "AppConfig.h"
#include "AppTask.h"
namespace {
constexpr int kButtonCount = 2;
TimerHandle_t buttonTimers[kButtonCount]; // FreeRTOS timers used for debouncing
// buttons. Array to hold handles to
// the created timers.
} // namespace
void ButtonHandler::Init(void)
{
GpioInit();
// 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_MIN_ASSERT_TIME_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)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
static cyhal_gpio_callback_data_t lockButtonCbData;
static cyhal_gpio_callback_data_t funcButtonCbData;
// Set up button GPIOs to input with pullups.
result = cyhal_gpio_init(APP_LOCK_BUTTON, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
if (result != CY_RSLT_SUCCESS)
{
printf(" cyhal_gpio_init failed for APP_LOCK_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. */
lockButtonCbData.callback = LockButtonCallback;
lockButtonCbData.callback_arg = NULL;
cyhal_gpio_register_callback(APP_LOCK_BUTTON, &lockButtonCbData);
funcButtonCbData.callback = FuncButtonCallback;
funcButtonCbData.callback_arg = NULL;
cyhal_gpio_register_callback(APP_FUNCTION_BUTTON, &funcButtonCbData);
cyhal_gpio_enable_event(APP_LOCK_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::LockButtonCallback(void * handler_arg, cyhal_gpio_event_t event)
{
portBASE_TYPE taskWoken = pdFALSE;
xTimerStartFromISR(buttonTimers[APP_LOCK_BUTTON_IDX], &taskWoken);
}
void ButtonHandler::FuncButtonCallback(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)
{
uint32_t timerId = 0;
uint8_t buttonevent = 0;
/* Get the button index of the expired timer and call button event helper. */
timerId = (uint32_t) pvTimerGetTimerID(xTimer);
if (timerId)
{
GetAppTask().ButtonEventHandler(timerId, APP_BUTTON_PRESSED);
}
else
{
buttonevent = cyhal_gpio_read(APP_LOCK_BUTTON);
if (!buttonevent)
{
GetAppTask().ButtonEventHandler(timerId, APP_BUTTON_LONG_PRESS);
}
else
{
GetAppTask().ButtonEventHandler(timerId, APP_BUTTON_PRESSED);
}
}
}