X-Git-Url: http://git.kpe.io/?p=avr_bc100.git;a=blobdiff_plain;f=BaseMegaFirmware%2FGCC%2Fkey_io.h;fp=BaseMegaFirmware%2FGCC%2Fkey_io.h;h=8c0891f6c70eeba0026a865ff85ae350b74ec576;hp=0000000000000000000000000000000000000000;hb=89173ec9cd6f33843bf27c45be0f2f9be3f5f0ce;hpb=7997f136b12114035265bd082c854bff95fd73dc diff --git a/BaseMegaFirmware/GCC/key_io.h b/BaseMegaFirmware/GCC/key_io.h new file mode 100644 index 0000000..8c0891f --- /dev/null +++ b/BaseMegaFirmware/GCC/key_io.h @@ -0,0 +1,101 @@ +/* Copyright (c)2007, 2008 Martin Thomas, BSD license */ + +#ifndef KEY_IO_H_ +#define KEY_IO_H_ + +#include +#include + +#include "timebase.h" /* for TIMEBASE_DELTAT_MS */ + +#define KEY_IO_KEYSA_DDR DDRC +#define KEY_IO_KEYSA_PORT PORTC +#define KEY_IO_KEYSA_PIN PINC +#define KEY_IO_KEYA1_BIT PC0 /* SW0 */ +#define KEY_IO_KEYA2_BIT PC1 /* SW1 */ +#define KEY_IO_KEYA3_BIT PC6 /* SW2 */ +#define KEY_IO_KEYA4_BIT PC7 /* SW3 */ +#define KEY_IO_KEYSB_DDR DDRD +#define KEY_IO_KEYSB_PORT PORTD +#define KEY_IO_KEYSB_PIN PIND +#define KEY_IO_KEYB1_BIT PD5 /* Power button */ + +#define KEY_IO_KEY_SW0 (1<<0) +#define KEY_IO_KEY_SW1 (1<<1) +#define KEY_IO_KEY_SW2 (1<<2) +#define KEY_IO_KEY_SW3 (1<<3) +#define KEY_IO_KEY_POWER (1<<4) +#define KEY_IO_KEY_ALL \ + ( KEY_IO_KEY_SW0 | \ + KEY_IO_KEY_SW1 | \ + KEY_IO_KEY_SW2 | \ + KEY_IO_KEY_SW3 | \ + KEY_IO_KEY_POWER ) + + +static inline uint8_t key_io_state_hardware(void) +{ + uint8_t tmp1, tmp2, tmp3; + tmp1 = KEY_IO_KEYSA_PIN & ( (1<>= 4; + tmp3 = KEY_IO_KEYSB_PIN & (1<>= 1; + return ( tmp1 | tmp2 | tmp3 ); +} + +/* debounce/repeat code based on an example from Peter Dannegger, + modified for better integration and volatiles added */ + +//#define KEY_IO_REPEAT_MASK ( KEY_IO_KEY_DOWN | KEY_IO_KEY_UP ) +#define KEY_IO_REPEAT_MASK ( KEY_IO_KEY_ALL ) +#define KEY_IO_REPEAT_START ( 500/*ms*/ / TIMEBASE_DELTAT_MS ) +#define KEY_IO_REPEAT_NEXT ( 100/*ms*/ / TIMEBASE_DELTAT_MS ) + +// debounced and inverted key state, bit = 1: key pressed +extern volatile uint8_t key_io_state; +// key press detect +extern volatile uint8_t key_io_press; +// key long press and repeat +extern volatile uint8_t key_io_rpt; + +/* The following callback-function has to be + called frequently from timer-ISR. Implemented + in this header-file as static inline to + indicate to the compiler that the function + should be inlined into the ISR-code. Tested with + avr-gcc 4.2.1: inlined - o.k. */ +static inline void key_io_callback(void) +{ + static uint8_t ct0, ct1, rpt; + uint8_t i, mystate; + + mystate = key_io_state; + + i = mystate ^ ~( key_io_state_hardware() ); // keys changed ? + ct0 = ~(ct0 & i); // reset or count ct0 + ct1 = ct0 ^ (ct1 & i); // reset or count ct1 + i &= ct0 & ct1; // count until roll over ? + mystate ^= i; // then toggle debounced state + key_io_press |= mystate & i; // 0->1: key press detect + + if( (mystate & KEY_IO_REPEAT_MASK) == 0 ) { // check repeat function + rpt = KEY_IO_REPEAT_START; // start delay + } + if( --rpt == 0 ) { + rpt = KEY_IO_REPEAT_NEXT; // repeat delay + key_io_rpt |= mystate & KEY_IO_REPEAT_MASK; + } + + key_io_state = mystate; +} + +void key_io_init(void); + +uint8_t key_io_get_press( uint8_t key_mask ); +uint8_t key_io_get_rpt( uint8_t key_mask ); +uint8_t key_io_get_longpress( uint8_t key_mask ); +/* only returns "true" after key has been released: */ +uint8_t key_io_get_was_short( uint8_t key_mask ); + +#endif