|
|
|
@ -90,6 +90,7 @@ const u8 _hidReportDescriptor[] = {
|
|
|
|
|
0x85, HID_REPORTID_KEYBOARD, // REPORT_ID (2)
|
|
|
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
|
|
|
|
|
|
|
|
// Keyboard Modifiers (shift, alt, ...)
|
|
|
|
|
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
|
|
|
|
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
|
|
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
|
|
@ -102,14 +103,14 @@ const u8 _hidReportDescriptor[] = {
|
|
|
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
|
|
|
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
|
|
|
|
|
|
|
|
|
// Keyboard keys
|
|
|
|
|
0x95, 0x06, // REPORT_COUNT (6)
|
|
|
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
|
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
|
|
|
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
|
|
|
|
0x26, 0xDF, 0x00, // LOGICAL_MAXIMUM (239)
|
|
|
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
|
|
|
|
|
|
|
|
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
|
|
|
|
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
|
|
|
|
0x29, 0xDF, // USAGE_MAXIMUM (Left Control - 1)
|
|
|
|
|
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
|
|
|
|
0xc0, // END_COLLECTION
|
|
|
|
|
|
|
|
|
@ -571,9 +572,33 @@ uint8_t USBPutChar(uint8_t c);
|
|
|
|
|
// to the persistent key report and sends the report. Because of the way
|
|
|
|
|
// USB HID works, the host acts like the key remains pressed until we
|
|
|
|
|
// call release(), releaseAll(), or otherwise clear the report and resend.
|
|
|
|
|
size_t Keyboard_::press(uint8_t k)
|
|
|
|
|
size_t Keyboard_::pressRaw(uint8_t k)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i;
|
|
|
|
|
// Add k to the key report only if it's not already present
|
|
|
|
|
// and if there is an empty slot.
|
|
|
|
|
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
|
|
|
|
|
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
|
|
|
|
|
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
|
|
|
|
|
|
|
|
|
|
for (i=0; i<6; i++) {
|
|
|
|
|
if (_keyReport.keys[i] == 0x00) {
|
|
|
|
|
_keyReport.keys[i] = k;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (i == 6 || (k >= 0xE0)) {
|
|
|
|
|
setWriteError();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sendReport(&_keyReport);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// translates ASCII characters to usage
|
|
|
|
|
size_t Keyboard_::press(uint8_t k)
|
|
|
|
|
{
|
|
|
|
|
if (k >= 136) { // it's a non-printing key (not a modifier)
|
|
|
|
|
k = k - 136;
|
|
|
|
|
} else if (k >= 128) { // it's a modifier key
|
|
|
|
@ -590,28 +615,48 @@ size_t Keyboard_::press(uint8_t k)
|
|
|
|
|
k &= 0x7F;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return pressRaw(k);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add k to the key report only if it's not already present
|
|
|
|
|
// and if there is an empty slot.
|
|
|
|
|
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
|
|
|
|
|
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
|
|
|
|
|
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
|
|
|
|
|
|
|
|
|
|
for (i=0; i<6; i++) {
|
|
|
|
|
if (_keyReport.keys[i] == 0x00) {
|
|
|
|
|
_keyReport.keys[i] = k;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (i == 6) {
|
|
|
|
|
setWriteError();
|
|
|
|
|
return 0;
|
|
|
|
|
// release() takes the specified key out of the persistent key report and
|
|
|
|
|
// sends the report. This tells the OS the key is no longer pressed and that
|
|
|
|
|
// it shouldn't be repeated any more.
|
|
|
|
|
size_t Keyboard_::releaseRaw(uint8_t k)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i;
|
|
|
|
|
// Test the key report to see if k is present. Clear it if it exists.
|
|
|
|
|
// Check all positions in case the key is present more than once (which it shouldn't be)
|
|
|
|
|
for (i=0; i<6; i++) {
|
|
|
|
|
if (0 != k && _keyReport.keys[i] == k) {
|
|
|
|
|
_keyReport.keys[i] = 0x00;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sendReport(&_keyReport);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// translates ASCII characters to usage
|
|
|
|
|
size_t Keyboard_::release(uint8_t k)
|
|
|
|
|
{
|
|
|
|
|
if (k >= 136) { // it's a non-printing key (not a modifier)
|
|
|
|
|
k = k - 136;
|
|
|
|
|
} else if (k >= 128) { // it's a modifier key
|
|
|
|
|
_keyReport.modifiers &= ~(1<<(k-128));
|
|
|
|
|
k = 0;
|
|
|
|
|
} else { // it's a printing key
|
|
|
|
|
k = pgm_read_byte(_asciimap + k);
|
|
|
|
|
if (!k) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
|
|
|
|
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
|
|
|
|
k &= 0x7F;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return releaseRaw(k);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// System Control
|
|
|
|
|
// k is one of the SYSTEM_CONTROL defines which come from the HID usage table "Generic Desktop Page (0x01)"
|
|
|
|
|
// in "HID Usage Tables" (HUT1_12v2.pdf)
|
|
|
|
@ -644,40 +689,6 @@ size_t Keyboard_::systemControl(uint8_t k)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// release() takes the specified key out of the persistent key report and
|
|
|
|
|
// sends the report. This tells the OS the key is no longer pressed and that
|
|
|
|
|
// it shouldn't be repeated any more.
|
|
|
|
|
size_t Keyboard_::release(uint8_t k)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i;
|
|
|
|
|
if (k >= 136) { // it's a non-printing key (not a modifier)
|
|
|
|
|
k = k - 136;
|
|
|
|
|
} else if (k >= 128) { // it's a modifier key
|
|
|
|
|
_keyReport.modifiers &= ~(1<<(k-128));
|
|
|
|
|
k = 0;
|
|
|
|
|
} else { // it's a printing key
|
|
|
|
|
k = pgm_read_byte(_asciimap + k);
|
|
|
|
|
if (!k) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (k & 0x80) { // it's a capital letter or other character reached with shift
|
|
|
|
|
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
|
|
|
|
k &= 0x7F;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test the key report to see if k is present. Clear it if it exists.
|
|
|
|
|
// Check all positions in case the key is present more than once (which it shouldn't be)
|
|
|
|
|
for (i=0; i<6; i++) {
|
|
|
|
|
if (0 != k && _keyReport.keys[i] == k) {
|
|
|
|
|
_keyReport.keys[i] = 0x00;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sendReport(&_keyReport);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Keyboard_::releaseAll(void)
|
|
|
|
|
{
|
|
|
|
|
_keyReport.keys[0] = 0;
|
|
|
|
@ -690,10 +701,17 @@ void Keyboard_::releaseAll(void)
|
|
|
|
|
sendReport(&_keyReport);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t Keyboard_::writeRaw(uint8_t c)
|
|
|
|
|
{
|
|
|
|
|
uint8_t p = pressRaw(c); // Keydown
|
|
|
|
|
releaseRaw(c); // Keyup
|
|
|
|
|
return (p); // just return the result of press() since release() almost always returns 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t Keyboard_::write(uint8_t c)
|
|
|
|
|
{
|
|
|
|
|
uint8_t p = press(c); // Keydown
|
|
|
|
|
uint8_t r = release(c); // Keyup
|
|
|
|
|
release(c); // Keyup
|
|
|
|
|
return (p); // just return the result of press() since release() almost always returns 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|