1 | #ifndef F_CPU
|
2 | #define F_CPU 1000000 // processor clock frequency
|
3 | #warning no F_CPU defined
|
4 | #endif
|
5 |
|
6 | #include <stdint.h>
|
7 | #include <avr/io.h>
|
8 | #include <avr/interrupt.h>
|
9 | #include "key-routines.h"
|
10 |
|
11 | /************************************************************************/
|
12 |
|
13 | volatile uint8_t key_state; // debounced and inverted key state:
|
14 | // bit = 1: key pressed
|
15 | volatile uint8_t key_press; // key press detect
|
16 |
|
17 | volatile uint8_t key_rpt; // key long press and repeat
|
18 |
|
19 | /************************************************************************/
|
20 |
|
21 | ISR( TIMER0_OVF_vect ) // every 10ms
|
22 | {
|
23 | static uint8_t ct0 = 0xFF, ct1 = 0xFF, rpt;
|
24 | uint8_t i;
|
25 |
|
26 | TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms
|
27 |
|
28 | i = key_state ^ ~KEY_PIN; // key changed ?
|
29 | ct0 = ~( ct0 & i ); // reset or count ct0
|
30 | ct1 = ct0 ^ (ct1 & i); // reset or count ct1
|
31 | i &= ct0 & ct1; // count until roll over ?
|
32 | key_state ^= i; // then toggle debounced state
|
33 | key_press |= key_state & i; // 0->1: key press detect
|
34 |
|
35 | if( (key_state & REPEAT_MASK) == 0 ) // check repeat function
|
36 | rpt = REPEAT_START; // start delay
|
37 | if( --rpt == 0 ){
|
38 | rpt = REPEAT_NEXT; // repeat delay
|
39 | key_rpt |= key_state & REPEAT_MASK;
|
40 | }
|
41 | }
|
42 |
|
43 | /************************************************************************/
|
44 |
|
45 | uint8_t get_key_press( uint8_t key_mask )
|
46 | {
|
47 | cli(); // read and clear atomic !
|
48 | key_mask &= key_press; // read key(s)
|
49 | key_press ^= key_mask; // clear key(s)
|
50 | sei();
|
51 | return key_mask;
|
52 | }
|
53 |
|
54 | /************************************************************************/
|
55 |
|
56 | uint8_t get_key_rpt( uint8_t key_mask )
|
57 | {
|
58 | cli(); // read and clear atomic !
|
59 | key_mask &= key_rpt; // read key(s)
|
60 | key_rpt ^= key_mask; // clear key(s)
|
61 | sei();
|
62 | return key_mask;
|
63 | }
|
64 |
|
65 | /************************************************************************/
|
66 |
|
67 | uint8_t get_key_state( uint8_t key_mask )
|
68 | {
|
69 | key_mask &= key_state;
|
70 | return key_mask;
|
71 | }
|
72 |
|
73 | /************************************************************************/
|
74 |
|
75 | uint8_t get_key_short( uint8_t key_mask )
|
76 | {
|
77 | cli(); // read key state and key press atomic !
|
78 | return get_key_press( ~key_state & key_mask );
|
79 | }
|
80 |
|
81 | /************************************************************************/
|
82 |
|
83 | uint8_t get_key_long( uint8_t key_mask )
|
84 | {
|
85 | return get_key_press( get_key_rpt( key_mask ));
|
86 | }
|