-
Notifications
You must be signed in to change notification settings - Fork 1
/
ZeroPhone_Keypad_FW.ino
132 lines (120 loc) · 3.71 KB
/
ZeroPhone_Keypad_FW.ino
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
#include <Keypad.h>
#include <Wire.h>
#define version 0x05
#define address 0x12
#define int_pin A3
#define vibromotor_pin 11
#define tftbl_pin 10
#define kpbl_pin 9
#define usrgp1_pin 5
//#define debug
const byte ROWS = 6;
const byte COLS = 5;
uint8_t keys[COLS][ROWS] = {
//{'VOL_DW','ANSWER', '1', '4', 'PROG1', 'F5'},
{ 27, 20, 6, 9, 28, 24},
//{'VOL_UP','LEFT', 'F3', '8', '*', '0'},
{ 26, 1, 22, 13, 15, 16},
//{'F1', 'ENTER', 'DOWN', '2', '7' '#'},
{ 18, 5, 3, 7, 12, 17 },
//{'UP', 'RIGHT', 'F4', '5', '9' 'F6'},
{ 2, 4, 23, 10, 14, 25},
//{'F2', 'HANGUP', '3', '6', 'CAMERA', 'PROG2'},
{ 19, 21, 8, 11, 30, 29}
};
const byte BUFFER_SIZE = 3*15;
uint8_t key_buffer[BUFFER_SIZE] = {};
uint8_t key_pointer = 1; // pointer to next position in buffer to put the key state value
uint8_t i2c_pointer = 1; // pointer to next position in buffer to read the key state value from
// (to then send it over I2C)
byte rowPins[ROWS] = {8, 7, 6, 4, 3, 2};
byte colPins[COLS] = {12, 13, A0, A1, A2};
Keypad keypad = Keypad( makeKeymap(keys), colPins, rowPins, COLS, ROWS );
void sendKey() {
if (i2c_pointer == BUFFER_SIZE) i2c_pointer = 0;
if (i2c_pointer == key_pointer) {
Wire.write(0);
digitalWrite(int_pin, HIGH);
return;
}
Wire.write(key_buffer[i2c_pointer]);
i2c_pointer++;
if (i2c_pointer == key_pointer) {
digitalWrite(int_pin, HIGH);
}
}
bool pointer_overflow() {
// Tells whether the key pointer is about to overtake i2c pointer.
// Used by the key read function to know when to block.
// As a result, there's an assumption that the pointer is about to be incremented
// (and, if necessary, clamped) after calling this function.
if (i2c_pointer == 0){
return key_pointer == BUFFER_SIZE-1;
}
return key_pointer == i2c_pointer - 1;
}
void keypad_ev_listener_i2c(char key) {
uint8_t key_value = (uint8_t) key;
byte state = keypad.getState();
if (state == 0)
return;
state--;
uint8_t i2c_value = state << 5 | key_value;
while (pointer_overflow()) {
delay(1);
}
key_buffer[key_pointer] = i2c_value;
key_pointer++;
if (key_pointer == BUFFER_SIZE) key_pointer = 0;
digitalWrite(int_pin, LOW);
}
void processWrite(int len){
// res-res-res-res-gpo-kpbl-tftbl-vib
for (int i=0; i<len; i++)
{
uint8_t data = Wire.read();
digitalWrite(vibromotor_pin, bitRead( data, 0 ));
analogWrite(tftbl_pin, bitRead( data, 1 ) ? 0 : 500);
analogWrite(kpbl_pin, bitRead( data, 2 ) ? 0 : 500);
digitalWrite(usrgp1_pin, bitRead( data, 3 ));
}
}
void setup(){
#ifdef debug
Serial.begin(115200);
Serial.write('a'); //TXD testing
#endif
// Interrupt pin
pinMode(int_pin, OUTPUT);
digitalWrite(int_pin, HIGH);
// Vibromotor pin
pinMode(vibromotor_pin, OUTPUT);
digitalWrite(vibromotor_pin, LOW);
// TFT backlight pin
pinMode(tftbl_pin, OUTPUT);
digitalWrite(tftbl_pin, LOW);
// Keypad backlight pin
pinMode(kpbl_pin, OUTPUT);
digitalWrite(kpbl_pin, LOW);
// User-controlled GPIO (in this FW version, it's OUT-only)
pinMode(usrgp1_pin, OUTPUT);
digitalWrite(usrgp1_pin, LOW);
// I2C setup
Wire.begin(address);
Wire.onRequest(sendKey);
Wire.onReceive(processWrite);
// Enable the vibromotor for a short while on bootup
digitalWrite(vibromotor_pin, HIGH);
delay(300);
digitalWrite(vibromotor_pin, LOW);
keypad.addEventListener(keypad_ev_listener_i2c);
keypad.setHoldTime(500);
}
void loop(){
keypad.getKey();
#ifdef debug
Serial.print(key_pointer);
Serial.print(" ");
Serial.println(i2c_pointer);
#endif
}