GameCounter/Source/src/buttons.h

90 lines
2.0 KiB
C

#ifndef __Buttons
#define __Buttons
#include <stdint.h>
#include <avr/io.h>
// 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