32
32
(
33
33
'`' , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 , F10 , F11 , F12 , DEL ,
34
34
___ , ___ , UP , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ ,
35
- ___ ,LEFT ,DOWN ,RIGHT ,___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ ,
35
+ ___ , LEFT , DOWN , RIGHT , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ ,
36
36
___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ ,
37
37
___ , ___ , ___ , ___ , ___ , ___ , ___ , ___
38
38
),
39
-
39
+
40
40
# layer 2
41
41
(
42
42
'`' , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 , F10 , F11 , F12 , DEL ,
43
43
___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ ,
44
- ___ , ___ , ___ , ___ , ___ , ___ ,LEFT , UP ,DOWN ,RIGHT , ___ , ___ , ___ ,
44
+ ___ , ___ , ___ , ___ , ___ , ___ , LEFT , UP , DOWN , RIGHT , ___ , ___ , ___ ,
45
45
___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ , ___ ,
46
46
___ , ___ , ___ , ___ , ___ , ___ , ___ , ___
47
47
),
48
48
)
49
49
50
50
51
-
52
51
ROWS = (P27 , P13 , P30 , P20 , P3 )
53
52
COLS = (P26 , P31 , P29 , P28 , P5 , P4 , P24 , P25 , P23 , P22 , P14 , P15 , P16 , P17 )
54
53
55
54
56
55
COORDS = bytearray ((
57
- 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 ,
58
- 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 ,
59
- 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 0 , 40 ,
60
- 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 0 , 52 , 0 ,
61
- 53 , 55 , 54 , 0 , 0 , 56 , 0 , 0 , 57 , 58 , 59 , 60 , 0 , 0
62
- ))
56
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 ,
57
+ 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 ,
58
+ 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 0 , 40 ,
59
+ 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 0 , 52 , 0 ,
60
+ 53 , 55 , 54 , 0 , 0 , 56 , 0 , 0 , 57 , 58 , 59 , 60 , 0 , 0
61
+ ))
63
62
64
63
65
64
class Queue :
66
65
def __init__ (self , size ):
67
66
self .size = size
68
67
self .queue = bytearray (size )
69
-
68
+
70
69
self .head = 0
71
70
self .tail = 0
72
-
71
+
73
72
def put (self , data ):
74
73
self .queue [self .head ] = data
75
74
self .head += 1
76
75
if self .head >= self .size :
77
76
self .head = 0
78
-
77
+
79
78
def get (self ):
80
79
data = self .queue [self .tail ]
81
80
self .tail += 1
82
81
if self .tail >= self .size :
83
82
self .tail = 0
84
-
83
+
85
84
return data
86
-
85
+
87
86
def preview (self , n = 0 ):
88
87
return self .queue [(self .tail + n ) % self .size ]
89
-
88
+
90
89
def __len__ (self ):
91
90
length = self .head - self .tail
92
91
return length if length >= 0 else length + self .size
@@ -99,39 +98,42 @@ def __init__(self, keymap=KEYMAP, rows=ROWS, cols=COLS, coords=COORDS, row2col=T
99
98
self .cols = cols
100
99
self .coords = coords
101
100
self .row2col = row2col
102
- self .pressed_keys = []
103
101
self .layers = 1
102
+ self .scan_time = 0
103
+ self .pair_keys = {}
104
104
self .pressed_mask = 0
105
+ self .pressed_count = 0
105
106
self .queue = Queue (128 )
106
- self .t = 0
107
- self .pair_keys = {}
108
107
109
108
def setup (self ):
110
109
n = len (self .rows ) * len (self .cols )
111
- self .t_keydown = [0 ] * n
110
+ self .pressed_time = [0 ] * n
112
111
self .keys = [0 ] * n
113
-
114
- def f (x ):
112
+
113
+ # convert pykey to pycode (unicode string)
114
+ def pykeycode (x ):
115
115
if type (x ) is int :
116
116
return chr (x ) if x > 9 else ASCII_TO_KEYCODE [ord (str (x ))]
117
117
if type (x ) is str and len (x ) == 1 :
118
118
return ASCII_TO_KEYCODE [ord (str (x ))]
119
119
raise ValueError ('Invalid keycode or keyname {}' .format (x ))
120
120
121
- convert = lambda * args : '' .join ((f (x ) for x in args ))
121
+ concat = lambda * a : '' .join ((pykeycode (x ) for x in a ))
122
+
123
+ self ._keymap = tuple (concat (* layer ) for layer in self .keymap )
124
+
125
+ self .pair_keys_code = tuple (
126
+ map (lambda x : ord (pykeycode (x )), self .pair_keys .keys ()))
127
+
128
+ def get_coord (x ): return self .coords [self .keymap [0 ].index (x )]
122
129
123
- self ._keymap = tuple (convert (* layer ) for layer in self .keymap )
124
-
125
- self .pair_keys_code = list (map (lambda x : ord (f (x )), self .pair_keys .keys ()))
126
-
127
- get_coord = lambda x : self .coords [self .keymap [0 ].index (x )]
128
130
def get_mask (x ):
129
131
keys = self .pair_keys [x ]
130
132
return 1 << get_coord (keys [0 ]) | 1 << get_coord (keys [1 ])
131
133
132
- self .pair_keys_mask = list (map (get_mask , self .pair_keys ))
134
+ self .pair_keys_mask = tuple (map (get_mask , self .pair_keys ))
133
135
# print([hex(x) for x in self.pair_keys_mask])
134
-
136
+
135
137
self .ro = [] # row as output
136
138
for pin in self .rows :
137
139
io = digitalio .DigitalInOut (pin )
@@ -151,26 +153,36 @@ def get_mask(x):
151
153
self .selected_value = bool (self .row2col )
152
154
153
155
def scan (self ):
154
- self .t = time .monotonic_ns ()
156
+ self .scan_time = time .monotonic_ns ()
155
157
pressed_mask = 0
156
- n_pressed_keys = 0
158
+ n_pressed = 0
157
159
for r , o in enumerate (self .ro ):
158
160
o .value = self .selected_value # select row
159
161
for c , i in enumerate (self .ci ):
160
162
key_index = r * len (self .ci ) + c
161
163
key_mask = 1 << key_index
162
164
if i .value == self .selected_value :
163
165
pressed_mask |= key_mask
164
- n_pressed_keys += 1
166
+ n_pressed += 1
165
167
if not (self .pressed_mask & (1 << key_index )):
166
- self .t_keydown [key_index ] = self .t
168
+ self .pressed_time [key_index ] = self .scan_time
167
169
self .queue .put (key_index )
168
170
elif self .pressed_mask & (1 << key_index ):
169
171
self .queue .put (0x80 | key_index )
170
-
172
+
171
173
o .value = not self .selected_value
172
174
self .pressed_mask = pressed_mask
173
- return n_pressed_keys
175
+ self .pressed_count = n_pressed
176
+
177
+ return len (self .queue )
178
+
179
+ def wait (self , n_events = 1 , until = None ):
180
+ while True :
181
+ n = len (self .queue )
182
+ if n >= n_events or (until and self .scan_time > until ):
183
+ return n
184
+
185
+ self .scan ()
174
186
175
187
def keycode (self , position ):
176
188
position = self .coords [position ]
@@ -195,66 +207,58 @@ def run(self):
195
207
ble .advertising = True
196
208
ble_keyboard = _Keyboard (hid .devices )
197
209
usb_keyboard = _Keyboard (usb_hid .devices )
198
-
210
+
199
211
def send (code ):
200
212
usb_keyboard .press (code )
201
213
usb_keyboard .release (code )
202
214
if ble .connected :
203
215
ble .advertising = False
204
216
ble_keyboard .press (code )
205
217
ble_keyboard .release (code )
206
-
218
+
207
219
def press (code ):
208
220
usb_keyboard .press (code )
209
221
if ble .connected :
210
222
ble .advertising = False
211
223
ble_keyboard .press (code )
212
-
224
+
213
225
def release (code ):
214
226
usb_keyboard .release (code )
215
227
if ble .connected :
216
228
ble .advertising = False
217
229
ble_keyboard .release (code )
218
230
219
231
self .setup ()
220
-
221
- pair_keys_state = 0
222
- # pending_key = 0xFF
223
232
while True :
224
- n_pressed_keys = self .scan ()
225
- n_events = len (self .queue )
226
- if not n_events :
233
+ n_events = self .scan ()
234
+ if n_events == 0 :
227
235
continue
228
236
229
237
# detecting pair keys
230
- if n_pressed_keys == 1 and n_events == 1 :
231
- if pair_keys_state == 0 :
232
- for mask in self .pair_keys_mask :
233
- if self .pressed_mask & mask == self .pressed_mask :
234
- pair_keys_state = 1
235
- break
236
- else :
237
- pair_keys_state = - 1
238
-
239
-
240
- if pair_keys_state > 0 :
241
- event = self .queue .preview ()
242
- dt = time .monotonic_ns () - self .t_keydown [event & 0x7F ]
243
- if dt < 25000000 :
244
- # wait for a more event
245
- continue
246
- elif n_pressed_keys == 2 and n_events == 2 :
247
- if self .pressed_mask in self .pair_keys_mask :
248
- multi_hit_index = self .pair_keys_mask .index (self .pressed_mask )
249
- keycode = self .pair_keys_code [multi_hit_index ]
250
- print ('multi hit {}' .format (multi_hit_index ))
251
- key = self .queue .get ()
252
- self .keys [key ] = keycode
253
-
238
+ if n_events == 1 and self .pressed_count == 1 :
239
+ for mask in self .pair_keys_mask :
240
+ if self .pressed_mask & mask == self .pressed_mask :
241
+ n_events = self .wait (2 , self .scan_time + 25000000 )
242
+ break
243
+
244
+ if n_events >= 2 :
245
+ mask = 1 << self .queue .preview (0 ) | 1 << self .queue .preview (1 )
246
+ if mask in self .pair_keys_mask :
247
+ pair_keys_index = self .pair_keys_mask .index (mask )
248
+ keycode = self .pair_keys_code [pair_keys_index ]
249
+ key1 = self .queue .get ()
250
+ key2 = self .queue .get ()
251
+ dt = self .pressed_time [key2 ] - self .pressed_time [key1 ]
252
+ print ('pair keys {} ({}, {}), dt = {}' .format (
253
+ pair_keys_index ,
254
+ key1 ,
255
+ key2 ,
256
+ dt // 1000000 ))
257
+
254
258
# only one action
255
- key = self . queue . get ()
256
- self .keys [key ] = 0
257
-
259
+ self . keys [ key1 ] = keycode
260
+ self .keys [key2 ] = 0
261
+
258
262
if keycode < 2 :
259
263
pass
260
264
elif keycode < 0xFF :
@@ -268,44 +272,41 @@ def release(code):
268
272
elif kind == ACT_LAYER_TAP :
269
273
self .layers |= 1 << layer
270
274
print ('layers {}' .format (self .layers ))
271
-
272
- pair_keys_state = 0
275
+
273
276
while len (self .queue ):
274
277
event = self .queue .get ()
275
278
key = event & 0x7F
276
- if event & 0x80 :
277
- print ('{} \\ ' .format (key ))
278
- keycode = self .keys [key ]
279
- dt = (self .t - self .t_keydown [key ]) // 1000000
280
- print ('dt({}) = {}' .format (key , dt ))
279
+ if event & 0x80 == 0 :
280
+ keycode = self .keycode (key )
281
+ self .keys [key ] = keycode
282
+ print ('{} / keycode = {}' .format (key , keycode ))
281
283
if keycode < 2 :
282
284
pass
283
- if keycode < 0xFF :
284
- release (keycode )
285
+ elif keycode < 0xFF :
286
+ press (keycode )
285
287
else :
286
288
kind = keycode >> 12
287
289
layer = ((keycode >> 8 ) & 0xF )
288
290
if kind == ACT_LAYER_TAP :
289
- self .layers &= ~ ( 1 << layer )
291
+ self .layers |= 1 << layer
290
292
print ('layers {}' .format (self .layers ))
291
- code = keycode & 0xFF
292
- if dt < 500 and code :
293
- send (code )
294
293
else :
295
- print ('/ {}' .format (key ))
296
- keycode = self .keycode (key )
297
- self .keys [key ] = keycode
298
- print ('keycode {}' .format (keycode ))
294
+ keycode = self .keys [key ]
295
+ dt = (self .scan_time - self .pressed_time [key ]) // 1000000
296
+ print ('{} \\ keycode = {}, dt = {}' .format (key , keycode , dt ))
299
297
if keycode < 2 :
300
298
pass
301
- elif keycode < 0xFF :
302
- press (keycode )
299
+ if keycode < 0xFF :
300
+ release (keycode )
303
301
else :
304
302
kind = keycode >> 12
305
303
layer = ((keycode >> 8 ) & 0xF )
306
304
if kind == ACT_LAYER_TAP :
307
- self .layers |= 1 << layer
305
+ self .layers &= ~ ( 1 << layer )
308
306
print ('layers {}' .format (self .layers ))
307
+ code = keycode & 0xFF
308
+ if dt < 500 and code :
309
+ send (code )
309
310
310
311
if not ble .connected and not ble .advertising :
311
312
ble .start_advertising (advertisement )
@@ -316,7 +317,7 @@ def release(code):
316
317
317
318
def main ():
318
319
kbd = Keyboard ()
319
- kbd .pair_keys = { L2 : (S , D ), L1 : (J , K ) }
320
+ kbd .pair_keys = {L2 : (S , D ), L1 : (J , K )}
320
321
kbd .run ()
321
322
322
323
0 commit comments