| /* |
| * |
| * 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); |
| } |
| } |
| } |