/* * Buttons.c * * Created on: 29 May 2020 * Author: Ralim */ #include "FreeRTOS.h" #include "OperatingModeUtilities.h" #include "settingsGUI.hpp" #include "task.h" #include TickType_t lastButtonTime = 0; ButtonState getButtonState() { /* * Read in the buttons and then determine if a state change needs to occur */ /* * If the previous state was 00 Then we want to latch the new state if * different & update time * If the previous state was !00 Then we want to search if we trigger long * press (buttons still down), or if release we trigger press * (downtime>filter) */ static uint8_t previousState = 0; static bool longPressed = false; static TickType_t previousStateChange = 0; const TickType_t timeout = TICKS_100MS * 4; uint8_t currentState; currentState = (getButtonA()) << 0; currentState |= (getButtonB()) << 1; if (currentState) { lastButtonTime = xTaskGetTickCount(); } if (currentState == previousState) { if (currentState == 0) { return BUTTON_NONE; } if ((xTaskGetTickCount() - previousStateChange) >= timeout) { // User has been holding the button down // We want to send a button is held message longPressed = true; if (currentState == 0x01) { return BUTTON_F_LONG; } else if (currentState == 0x02) { return BUTTON_B_LONG; } else { return BUTTON_BOTH_LONG; // Both being held case } } else { return BUTTON_NONE; } } else { // A change in button state has occurred ButtonState retVal = BUTTON_NONE; if (currentState) { // User has pressed a button down (nothing done on down) // If there is a rising edge on one of the buttons from double press we // want to mask that out As users are having issues with not release // both at once previousState |= currentState; } else { // User has released buttons // If they previously had the buttons down we want to check if they were < // long hold and trigger a press if (!longPressed) { // The user didn't hold the button for long // So we send button press if (previousState == 0x01) { retVal = BUTTON_F_SHORT; } else if (previousState == 0x02) { retVal = BUTTON_B_SHORT; } else { retVal = BUTTON_BOTH; // Both being held case } } previousState = 0; longPressed = false; } previousStateChange = xTaskGetTickCount(); return retVal; } return BUTTON_NONE; } void waitForButtonPress() { // we are just lazy and sleep until user confirms button press // This also eats the button press event! ButtonState buttons = getButtonState(); while (buttons) { buttons = getButtonState(); GUIDelay(); } while (!buttons) { buttons = getButtonState(); GUIDelay(); } } void waitForButtonPressOrTimeout(TickType_t timeout) { timeout += xTaskGetTickCount(); // calculate the exit point ButtonState buttons = getButtonState(); while (buttons) { buttons = getButtonState(); GUIDelay(); if (xTaskGetTickCount() > timeout) { return; } } while (!buttons) { buttons = getButtonState(); GUIDelay(); if (xTaskGetTickCount() > timeout) { return; } } }