forked from leaflabs/libmaple
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcaptouch.cpp
309 lines (254 loc) · 8.04 KB
/
captouch.cpp
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// Sample main.cpp file. Blinks the built-in LED, sends a message out
// USART1.
#include "wirish.h"
#include "mpr121.h"
#include "i2c.h"
#define CAPTOUCH_ADDR 0x5A
#define CAPTOUCH_I2C I2C1
#define CAPTOUCH_GPIO 30
// "WASD" cluster as defined by physical arrangement of touch switches
#define W_KEY (1 << 3)
#define A_KEY (1 << 6)
#define S_KEY (1 << 4)
#define D_KEY (1 << 2)
#define Q_KEY (1 << 8)
#define E_KEY (1 << 0)
#define FIRMWARE_VERSION "Safecast firmware v0.1 Jan 28 2012"
static struct i2c_dev *i2c;
static uint8 touchInit = 0;
static uint8 touchService = 0;
static uint16 touchList = 1 << 9 | 1 << 8 | 1 << 6 | 1 << 4 | 1 << 3 | 1 << 2 | 1 << 0;
static void
mpr121Write(uint8 addr, uint8 value)
{
struct i2c_msg msg;
uint8 bytes[2];
int result;
bytes[0] = addr;
bytes[1] = value;
msg.addr = CAPTOUCH_ADDR;
msg.flags = 0;
msg.length = sizeof(bytes);
msg.xferred = 0;
msg.data = bytes;
result = i2c_master_xfer(i2c, &msg, 1, 100);
if (!result) {
Serial1.print(addr, 16); Serial1.print(" -> "); Serial1.print(value); Serial1.print("\r\n");
}
else {
Serial1.print(addr, 16); Serial1.print(" err "); Serial1.print(result); Serial1.print("\r\n");
}
return;
}
static uint8
mpr121Read(uint8 addr)
{
struct i2c_msg msgs[2];
uint8 byte;
byte = addr;
msgs[0].addr = msgs[1].addr = CAPTOUCH_ADDR;
msgs[0].length = msgs[1].length = sizeof(byte);
msgs[0].data = msgs[1].data = &byte;
msgs[0].flags = 0;
msgs[1].flags = I2C_MSG_READ;
i2c_master_xfer(i2c, msgs, 2, 100);
return byte;
}
static void
cap_change(void)
{
int board_state;
/*
if( digitalRead(MANUAL_WAKEUP_GPIO) == LOW ) {
touchInit = 0;
return; // don't initiate service if the unit is powered down
}
*/
if(touchInit) {
touchService = 1; // flag that we're ready to be serviced
toggleLED();
}
board_state = mpr121Read(TCH_STATL);
board_state |= mpr121Read(TCH_STATH) << 8;
touchService = 0;
return;
}
void
cap_init(void)
{
i2c = CAPTOUCH_I2C;
i2c_init(i2c);
i2c_master_enable(i2c, 0);
Serial1.print(".");
mpr121Write(ELE_CFG, 0x00); // disable electrodes for config
delay(100);
// Section A
// This group controls filtering when data is > baseline.
mpr121Write(MHD_R, 0x01);
mpr121Write(NHD_R, 0x01);
// mpr121Write(NCL_R, 0x50);
// mpr121Write(FDL_R, 0x50);
mpr121Write(NCL_R, 0x00);
mpr121Write(FDL_R, 0x00);
// Section B
// This group controls filtering when data is < baseline.
mpr121Write(MHD_F, 0x01);
mpr121Write(NHD_F, 0x01);
mpr121Write(NCL_F, 0xFF);
// mpr121Write(FDL_F, 0x52);
mpr121Write(FDL_F, 0x02);
// Section C
// This group sets touch and release thresholds for each electrode
mpr121Write(ELE0_T, TOU_THRESH);
mpr121Write(ELE0_R, REL_THRESH);
mpr121Write(ELE1_T, TOU_THRESH);
mpr121Write(ELE1_R, REL_THRESH);
mpr121Write(ELE2_T, TOU_THRESH);
mpr121Write(ELE2_R, REL_THRESH);
mpr121Write(ELE3_T, TOU_THRESH);
mpr121Write(ELE3_R, REL_THRESH);
mpr121Write(ELE4_T, TOU_THRESH);
mpr121Write(ELE4_R, REL_THRESH);
mpr121Write(ELE5_T, TOU_THRESH);
mpr121Write(ELE5_R, REL_THRESH);
mpr121Write(ELE6_T, TOU_THRESH);
mpr121Write(ELE6_R, REL_THRESH);
mpr121Write(ELE7_T, TOU_THRESH);
mpr121Write(ELE7_R, REL_THRESH);
mpr121Write(ELE8_T, TOU_THRESH);
mpr121Write(ELE8_R, REL_THRESH);
mpr121Write(ELE9_T, TOU_THRESH);
mpr121Write(ELE9_R, REL_THRESH);
mpr121Write(ELE10_T, TOU_THRESH);
mpr121Write(ELE10_R, REL_THRESH);
mpr121Write(ELE11_T, TOU_THRESH);
mpr121Write(ELE11_R, REL_THRESH);
// Section D
// Set the Filter Configuration
// Set ESI2
mpr121Write(FIL_CFG, 0x03); // set CDT to 32us, ESI (sampling interval) to 8 ms
mpr121Write(AFE_CONF, 0x3F); // 6 samples, 63uA <-- will be overridden by auto-config i think
// Section F
mpr121Write(ATO_CFGU, 0xC9); // USL = (Vdd-0.7)/vdd*256 = 0xC9 @3.3V
mpr121Write(ATO_CFGL, 0x82); // LSL = 0.65*USL = 0x82 @3.3V
mpr121Write(ATO_CFGT, 0xB5); // Target = 0.9*USL = 0xB5 @3.3V
// mpr121Write(ATO_CFGU, 0xC0); // VSL = (Vdd-0.7)/vdd*256 = 0xC0 @2.8V
// mpr121Write(ATO_CFGL, 0x7D); // LSL = 0.65*USL = 0x7D @2.8V
// mpr121Write(ATO_CFGT, 0xB2); // Target = 0.9*USL = 0xB2 @2.8V
// mpr121Write(ATO_CFGU, 0x9C); // USL = (Vdd-0.7)/vdd*256 = 0xC9 @1.8V
// mpr121Write(ATO_CFGL, 0x65); // LSL = 0.65*USL = 0x82 @1.8V
// mpr121Write(ATO_CFGT, 0x8C); // Target = 0.9*USL = 0xB5 @1.8V
// Enable Auto Config and auto Reconfig
mpr121Write(ATO_CFG0, 0x3B); // must match AFE_CONF setting of 6 samples, retry enabled
delay(100);
// Section E
// Electrode Configuration
// Enable 6 Electrodes and set to run mode
// Set ELE_CFG to 0x00 to return to standby mode
mpr121Write(ELE_CFG, 0x0C); // Enables all 12 Electrodes
//mpr121Write(ELE_CFG, 0x06); // Enable first 6 electrodes
delay(100);
pinMode(CAPTOUCH_GPIO, INPUT);
attachInterrupt(CAPTOUCH_GPIO, cap_change, FALLING);
attachInterrupt(CAPTOUCH_GPIO, cap_change, RISING);
touchInit = 1;
return;
}
void
cap_deinit(void)
{
detachInterrupt(CAPTOUCH_GPIO);
// Disable MPR121 scanning, in case the chip is on
mpr121Write(ELE_CFG, 0x00);
return;
}
int
cap_setkeydown(void (*new_keydown)(int key))
{
return 0;
}
int
cap_setkeyup(void (*new_keyup)(int key))
{
return 0;
}
void
cap_debug(void)
{
uint8 bytes[2];
uint16 temp;
int i;
bytes[0] = mpr121Read(TCH_STATL);
bytes[1] = mpr121Read(TCH_STATH);
Serial1.print("Values: [");
Serial1.print(bytes[0]&(1<<0)?"1":"0");
Serial1.print(" ");
Serial1.print(bytes[0]&(1<<2)?"1":"0");
Serial1.print(" ");
Serial1.print(bytes[0]&(1<<3)?"1":"0");
Serial1.print(" ");
Serial1.print(bytes[0]&(1<<4)?"1":"0");
Serial1.print(" ");
Serial1.print(bytes[0]&(1<<6)?"1":"0");
Serial1.print(" ");
Serial1.print(bytes[1]&(1<<0)?"1":"0");
Serial1.print(" ");
Serial1.print(bytes[1]&(1<<1)?"1":"0"); // 9, a dummy electrode
// Serial1.print("]\r");
Serial1.println("]\r");
Serial1.print("OOR: ");
temp = mpr121Read(TCH_OORL);
temp |= mpr121Read(TCH_OORH) << 8;
Serial1.print( temp, 16 );
Serial1.println( "\r" );
Serial1.print("FIL_CFG: ");
temp = mpr121Read(FIL_CFG);
Serial1.print( temp, 16 );
Serial1.println( "\r" );
Serial1.print("AFE_CONF: ");
temp = mpr121Read(AFE_CONF);
Serial1.print( temp, 16 );
Serial1.println( "\r" );
for( i = 0; i < 13; i++ ) {
temp = 0;
if( touchList & (1 << i) ) {
temp = mpr121Read(ELE0_T + i * 2);
Serial1.print( " TT" );
Serial1.print( i );
Serial1.print( " " );
Serial1.print( temp, 16 );
temp = mpr121Read(ELE0_R + i * 2);
Serial1.print( " RT" );
Serial1.print( i );
Serial1.print( " " );
Serial1.print( temp, 16 );
temp = mpr121Read(0x5F + i);
Serial1.print( " CUR" );
Serial1.print( i );
Serial1.print( " " );
Serial1.print( temp, 16 );
temp = mpr121Read(0x1e + i);
Serial1.print( " ELEBASE" );
Serial1.print( i );
Serial1.print( " " );
Serial1.print( temp << 2, 16 );
temp |= mpr121Read(0x4 + i);
temp |= (mpr121Read(0x5 + i) & 0x3) << 8;
Serial1.print( " ELEFILT" );
Serial1.print( i );
Serial1.print( " " );
Serial1.print( temp, 16 );
Serial1.println( "\r" );
temp = 0;
}
}
Serial1.print( "CHG TIME: ");
for( i = 0; i < 5; i++ ) {
temp = mpr121Read(0x6c + i);
Serial1.print( temp, 16 );
Serial1.print( " " );
}
Serial1.println( "\r" );
Serial1.println( "\r" );
delay(500);
}