#ifndef __Buttons #define __Buttons #include #include // Some code borrowed from Peter Dannegger: // http://www.avrfreaks.net/forum/advanced-button-scan-routine // // While his version is optimized well, I found it hard to follow the logic // enough to customize it for my needs, so I went with a less optimized version. // It's good enough for this purpose. // Last reported state #define BSFLastReported _BV(1) // Event flags, cleared when polled #define BSFPressed _BV(2) #define BSFRepeated _BV(3) #define BSFReleased _BV(4) // If not set repeats are disabled while the button is pressed #define BSFRepeatEnabled _BV(5) typedef struct { // Bitmask according to BSF defines above uint8_t flags; // How many ticks the last state has been stable for uint8_t debounceTicks; // How many ticks remaining for the next repeat event uint8_t repeatTicks; } ButtonState; extern ButtonState buttonUp; extern ButtonState buttonDown; extern ButtonState buttonOption; // 8MHz #define XTAL 8e6 #ifndef BUTTON_UP #define BUTTON_UP PB1 #endif #ifndef BUTTON_DOWN #define BUTTON_DOWN PB3 #endif #ifndef BUTTON_OPTION #define BUTTON_OPTION PB4 #endif #define BUTTON_ALL (_BV(BUTTON_UP) | _BV(BUTTON_DOWN) | _BV(BUTTON_OPTION)) // after 20ms (if the timer runs every 10ms, 20ms is the minimum) #define DEBOUNCE_TIME 2 // after 500ms #define REPEAT_START 50 // every 200ms #define REPEAT_NEXT 20 extern void buttons_init(); // Note: these functions act on events, not on the current state. // Calling them will reset the corresponding event and further calls // will return false until the event triggers again. extern uint8_t button_is_pressed(ButtonState* state); extern uint8_t button_is_released(ButtonState* state); extern uint8_t button_is_repeated(ButtonState* state); extern uint8_t button_is_pressed_or_repeated(ButtonState* state); extern uint8_t button_is_released_short(ButtonState* state); extern uint8_t button_is_pressed_long(ButtonState* state); #endif