90 lines
2.0 KiB
C
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 |