Skip to content

Commit fe825c8

Browse files
facchinmcmaglie
authored andcommitted
standalone Keyboard library
1 parent c2a083b commit fe825c8

File tree

2 files changed

+412
-0
lines changed

2 files changed

+412
-0
lines changed

libraries/Keyboard/Keyboard.cpp

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
/*
2+
Keyboard.cpp
3+
4+
Copyright (c) 2015, Arduino LLC
5+
Original code (pre-library): Copyright (c) 2011, Peter Barrett
6+
7+
This library is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
22+
#if defined(USBCON)
23+
24+
#include "HID.h"
25+
#include "Keyboard.h"
26+
27+
//================================================================================
28+
//================================================================================
29+
// Keyboard
30+
31+
Keyboard_ Keyboard;
32+
33+
Keyboard_::Keyboard_(void)
34+
{
35+
}
36+
37+
void Keyboard_::begin(void)
38+
{
39+
}
40+
41+
void Keyboard_::end(void)
42+
{
43+
}
44+
45+
void Keyboard_::sendReport(KeyReport* keys)
46+
{
47+
HID_SendReport(2,keys,sizeof(KeyReport));
48+
}
49+
50+
extern
51+
const uint8_t _asciimap[128] PROGMEM;
52+
53+
#define SHIFT 0x80
54+
const uint8_t _asciimap[128] =
55+
{
56+
0x00, // NUL
57+
0x00, // SOH
58+
0x00, // STX
59+
0x00, // ETX
60+
0x00, // EOT
61+
0x00, // ENQ
62+
0x00, // ACK
63+
0x00, // BEL
64+
0x2a, // BS Backspace
65+
0x2b, // TAB Tab
66+
0x28, // LF Enter
67+
0x00, // VT
68+
0x00, // FF
69+
0x00, // CR
70+
0x00, // SO
71+
0x00, // SI
72+
0x00, // DEL
73+
0x00, // DC1
74+
0x00, // DC2
75+
0x00, // DC3
76+
0x00, // DC4
77+
0x00, // NAK
78+
0x00, // SYN
79+
0x00, // ETB
80+
0x00, // CAN
81+
0x00, // EM
82+
0x00, // SUB
83+
0x00, // ESC
84+
0x00, // FS
85+
0x00, // GS
86+
0x00, // RS
87+
0x00, // US
88+
89+
0x2c, // ' '
90+
0x1e|SHIFT, // !
91+
0x34|SHIFT, // "
92+
0x20|SHIFT, // #
93+
0x21|SHIFT, // $
94+
0x22|SHIFT, // %
95+
0x24|SHIFT, // &
96+
0x34, // '
97+
0x26|SHIFT, // (
98+
0x27|SHIFT, // )
99+
0x25|SHIFT, // *
100+
0x2e|SHIFT, // +
101+
0x36, // ,
102+
0x2d, // -
103+
0x37, // .
104+
0x38, // /
105+
0x27, // 0
106+
0x1e, // 1
107+
0x1f, // 2
108+
0x20, // 3
109+
0x21, // 4
110+
0x22, // 5
111+
0x23, // 6
112+
0x24, // 7
113+
0x25, // 8
114+
0x26, // 9
115+
0x33|SHIFT, // :
116+
0x33, // ;
117+
0x36|SHIFT, // <
118+
0x2e, // =
119+
0x37|SHIFT, // >
120+
0x38|SHIFT, // ?
121+
0x1f|SHIFT, // @
122+
0x04|SHIFT, // A
123+
0x05|SHIFT, // B
124+
0x06|SHIFT, // C
125+
0x07|SHIFT, // D
126+
0x08|SHIFT, // E
127+
0x09|SHIFT, // F
128+
0x0a|SHIFT, // G
129+
0x0b|SHIFT, // H
130+
0x0c|SHIFT, // I
131+
0x0d|SHIFT, // J
132+
0x0e|SHIFT, // K
133+
0x0f|SHIFT, // L
134+
0x10|SHIFT, // M
135+
0x11|SHIFT, // N
136+
0x12|SHIFT, // O
137+
0x13|SHIFT, // P
138+
0x14|SHIFT, // Q
139+
0x15|SHIFT, // R
140+
0x16|SHIFT, // S
141+
0x17|SHIFT, // T
142+
0x18|SHIFT, // U
143+
0x19|SHIFT, // V
144+
0x1a|SHIFT, // W
145+
0x1b|SHIFT, // X
146+
0x1c|SHIFT, // Y
147+
0x1d|SHIFT, // Z
148+
0x2f, // [
149+
0x31, // bslash
150+
0x30, // ]
151+
0x23|SHIFT, // ^
152+
0x2d|SHIFT, // _
153+
0x35, // `
154+
0x04, // a
155+
0x05, // b
156+
0x06, // c
157+
0x07, // d
158+
0x08, // e
159+
0x09, // f
160+
0x0a, // g
161+
0x0b, // h
162+
0x0c, // i
163+
0x0d, // j
164+
0x0e, // k
165+
0x0f, // l
166+
0x10, // m
167+
0x11, // n
168+
0x12, // o
169+
0x13, // p
170+
0x14, // q
171+
0x15, // r
172+
0x16, // s
173+
0x17, // t
174+
0x18, // u
175+
0x19, // v
176+
0x1a, // w
177+
0x1b, // x
178+
0x1c, // y
179+
0x1d, // z
180+
0x2f|SHIFT, //
181+
0x31|SHIFT, // |
182+
0x30|SHIFT, // }
183+
0x35|SHIFT, // ~
184+
0 // DEL
185+
};
186+
187+
uint8_t USBPutChar(uint8_t c);
188+
189+
// press() adds the specified key (printing, non-printing, or modifier)
190+
// to the persistent key report and sends the report. Because of the way
191+
// USB HID works, the host acts like the key remains pressed until we
192+
// call release(), releaseAll(), or otherwise clear the report and resend.
193+
size_t Keyboard_::press(uint8_t k)
194+
{
195+
uint8_t i;
196+
if (k >= 136) { // it's a non-printing key (not a modifier)
197+
k = k - 136;
198+
} else if (k >= 128) { // it's a modifier key
199+
_keyReport.modifiers |= (1<<(k-128));
200+
k = 0;
201+
} else { // it's a printing key
202+
k = pgm_read_byte(_asciimap + k);
203+
if (!k) {
204+
setWriteError();
205+
return 0;
206+
}
207+
if (k & 0x80) { // it's a capital letter or other character reached with shift
208+
_keyReport.modifiers |= 0x02; // the left shift modifier
209+
k &= 0x7F;
210+
}
211+
}
212+
213+
// Add k to the key report only if it's not already present
214+
// and if there is an empty slot.
215+
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
216+
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
217+
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
218+
219+
for (i=0; i<6; i++) {
220+
if (_keyReport.keys[i] == 0x00) {
221+
_keyReport.keys[i] = k;
222+
break;
223+
}
224+
}
225+
if (i == 6) {
226+
setWriteError();
227+
return 0;
228+
}
229+
}
230+
sendReport(&_keyReport);
231+
return 1;
232+
}
233+
234+
// release() takes the specified key out of the persistent key report and
235+
// sends the report. This tells the OS the key is no longer pressed and that
236+
// it shouldn't be repeated any more.
237+
size_t Keyboard_::release(uint8_t k)
238+
{
239+
uint8_t i;
240+
if (k >= 136) { // it's a non-printing key (not a modifier)
241+
k = k - 136;
242+
} else if (k >= 128) { // it's a modifier key
243+
_keyReport.modifiers &= ~(1<<(k-128));
244+
k = 0;
245+
} else { // it's a printing key
246+
k = pgm_read_byte(_asciimap + k);
247+
if (!k) {
248+
return 0;
249+
}
250+
if (k & 0x80) { // it's a capital letter or other character reached with shift
251+
_keyReport.modifiers &= ~(0x02); // the left shift modifier
252+
k &= 0x7F;
253+
}
254+
}
255+
256+
// Test the key report to see if k is present. Clear it if it exists.
257+
// Check all positions in case the key is present more than once (which it shouldn't be)
258+
for (i=0; i<6; i++) {
259+
if (0 != k && _keyReport.keys[i] == k) {
260+
_keyReport.keys[i] = 0x00;
261+
}
262+
}
263+
264+
sendReport(&_keyReport);
265+
return 1;
266+
}
267+
268+
void Keyboard_::releaseAll(void)
269+
{
270+
_keyReport.keys[0] = 0;
271+
_keyReport.keys[1] = 0;
272+
_keyReport.keys[2] = 0;
273+
_keyReport.keys[3] = 0;
274+
_keyReport.keys[4] = 0;
275+
_keyReport.keys[5] = 0;
276+
_keyReport.modifiers = 0;
277+
sendReport(&_keyReport);
278+
}
279+
280+
size_t Keyboard_::write(uint8_t c)
281+
{
282+
uint8_t p = press(c); // Keydown
283+
release(c); // Keyup
284+
return p; // just return the result of press() since release() almost always returns 1
285+
}
286+
287+
Keyboard_ Keyboard;
288+
289+
#endif

0 commit comments

Comments
 (0)