-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgpiokeys.c
136 lines (105 loc) · 2.8 KB
/
gpiokeys.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "fwork.h"
#define GPIOFEATURE (fcache[gpiom])
MNUM gpiom;
void GPIO_onSetup(volatile StenoLog *s, volatile StenoStats *st) {
PASEL1 &= (~PADA_M);
PBSEL1 &= (~PADB_M); // leave the rest
PADIR &= (~PADA_M); // inputs
PBDIR &= (~PADB_M);
// pull high
// PAOUT |= PADA_M;
// PBOUT |= PADB_M;
PAOUT &= (~PADA_M); // pull low
PBOUT &= (~PADB_M);
PAREN |= PADA_M; // enable R
PBREN |= PADB_M;
// PAIES |= PADA_M; // on high->low edge
// PBIES |= PADB_M;
PAIES &= ~PADA_M;
PBIES &= ~PADB_M; // on low->high edge
PAIE |= PADA_M; // enable
PBIE |= PADB_M;
PAIFG &= ~PADA_M; // clear
PBIFG &= ~PADB_M;
}
/*
pragma vector=PORT1_VECTOR
pragma vector=PORT2_VECTOR
pragma vector=PORT3_VECTOR
pragma vector=PORT4_VECTOR
There are 3 potential groups of pins in a chord:
currently pressed (pull 1 low & watch, free float the rest)
past pressed (pull low again, watching is optional)
never pressed (pull low, watch all for going high)
*/
int GPIO_onInterrupt(volatile StenoLog *s, volatile StenoStats *st)
{
unsigned long volatile upd = 0;
upd = (PAIN & PADA_M);
upd = upd<<16;
upd |= (PBIN & PADB_M);
st->rchrd |= upd;
PAREN |= PADA_M; // enable R on allkeys
PBREN |= PADB_M;
PAREN &= ~(PAIN & PADA_M); // disable R on downkeys
PBREN &= ~(PBIN & PADB_M);
PAIE |= PADA_M; // enable I on allkeys
PBIE |= PADB_M;
PAIE &= ~(PAIN & PADA_M); // disable I on downkeys
PBIE &= ~(PBIN & PADB_M);
PAIES = (PADA_M & PAIN) | (PAIES & ~PADA_M); // set edges
PBIES = (PADB_M & PBIN) | (PBIES & ~PADB_M);
PAIFG &= ~PADA_M; // clear flags
PBIFG &= ~PADB_M;
TA0CTL |= TACLR; // reset debounce time
if (upd == 0) {
if(s->log[s->nc] != 0) {
s->nc += 1;
s->flags |= CHREADY;
return 1;
}
} else {
int x;
x = __builtin_ctzl(upd); // get 1 pressedkey
if (x < 16) { // B Pad
x = 1<<x;
PBIE |= x;
PBREN |= x;
// IES already setup
} else { // A PAD
x = 1 << (x-16);
PAIE |= x;
PAREN |= x;
}
s->log[s->nc] |= upd;
s->flags &= ~CHREADY;
}
return 0;
}
int GPIO_onFlagsWake(volatile StenoLog *s, volatile StenoStats *st) {
TA0CCR0 = DEBOUNCE; // reset bounce wait on any key event
TA0CTL = TASSEL_1 + MC_1 + TAIE;
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void GPIO_Timer(void) {
if (s->flags & CHREADY) {
s->flags &= ~CHREADY;
s->nc = (s->nc+1) % LOG_MAX;
s->log[s->nc] = 0;
s->flags |= R2NOTIFY;
}
TA0CTL = 0;
}
int GPIO_onRegister() {
gpiom = gpio;
GPIOFEATURE.id = gpio;
GPIOFEATURE.pins = PADA_M;
GPIOFEATURE.pins = (GPIOFEATURE.pins << 16) | PADB_M;
GPIOFEATURE.onSetup = &GPIO_onSetup;
GPIOFEATURE.onFlagsWake = &GPIO_onFlagsWake;
GPIOFEATURE.onInterrupt = &GPIO_onInterrupt;
GPIOFEATURE.ivectors = (void*)0;
GPIOFEATURE.flags = CHREADY;
GPIOFEATURE.sleep_bits = 0;
GPIOFEATURE.pmm_bits = 0;
}