Added NKRO keyboard
This commit is contained in:
parent
64b89df10c
commit
3008e6d11d
10 changed files with 640 additions and 2 deletions
|
|
@ -5,7 +5,7 @@
|
||||||
Mouse example
|
Mouse example
|
||||||
Press a button to click or move the mouse.
|
Press a button to click or move the mouse.
|
||||||
|
|
||||||
You may also use BootMouse to enable a bios compatible mouse.
|
You may also use BootMouse to enable a bios compatible (single report) mouse.
|
||||||
However this is very unusual and not recommended.
|
However this is very unusual and not recommended.
|
||||||
Bios mice dont support wheels which can cause problems after a reboot.
|
Bios mice dont support wheels which can cause problems after a reboot.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
NKRO can push 113 keys at the same time,
|
NKRO can push 113 keys at the same time,
|
||||||
the other Keyboards only 6 keys + 8 modifiers!
|
the other Keyboards only 6 keys + 8 modifiers!
|
||||||
|
|
||||||
|
You may also use SingleNKROKeyboard to enable a single report NKROKeyboard.
|
||||||
|
|
||||||
See HID Project documentation for more information.
|
See HID Project documentation for more information.
|
||||||
https://github.com/NicoHood/HID/wiki/Keyboard-API
|
https://github.com/NicoHood/HID/wiki/Keyboard-API
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ Gamepad3 KEYWORD1
|
||||||
Gamepad4 KEYWORD1
|
Gamepad4 KEYWORD1
|
||||||
TeensyKeyboard KEYWORD1
|
TeensyKeyboard KEYWORD1
|
||||||
NKROKeyboard KEYWORD1
|
NKROKeyboard KEYWORD1
|
||||||
|
SingleNKROKeyboard KEYWORD1
|
||||||
AbsoluteMouse KEYWORD1
|
AbsoluteMouse KEYWORD1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
|
|
|
||||||
78
src/HID-APIs/NKROKeyboardAPI.h
Normal file
78
src/HID-APIs/NKROKeyboardAPI.h
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Include guard
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "HID-Settings.h"
|
||||||
|
#include "ImprovedKeylayouts.h"
|
||||||
|
#include "HID-Tables.h" //TODO
|
||||||
|
|
||||||
|
// Max value for USB EP_SIZE 16
|
||||||
|
// +1 reportID, +1 modifier, +1 custom key
|
||||||
|
#define NKRO_KEY_COUNT (8*13)
|
||||||
|
|
||||||
|
typedef union{
|
||||||
|
// Modifier + keymap + 1 custom key
|
||||||
|
uint8_t whole8[];
|
||||||
|
uint16_t whole16[];
|
||||||
|
uint32_t whole32[];
|
||||||
|
struct{
|
||||||
|
uint8_t modifiers;
|
||||||
|
uint8_t keys[NKRO_KEY_COUNT / 8];
|
||||||
|
uint8_t key;
|
||||||
|
};
|
||||||
|
} HID_NKROKeyboardReport_Data_t;
|
||||||
|
|
||||||
|
|
||||||
|
class NKROKeyboardAPI : public Print
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline NKROKeyboardAPI(void);
|
||||||
|
inline void begin(void);
|
||||||
|
inline void end(void);
|
||||||
|
inline size_t write(uint8_t k);
|
||||||
|
inline size_t press(uint8_t k);
|
||||||
|
inline size_t release(uint8_t k);
|
||||||
|
inline void releaseAll(void);
|
||||||
|
inline void send_now(void);
|
||||||
|
|
||||||
|
inline size_t writeKeycode(uint8_t k);
|
||||||
|
inline size_t pressKeycode(uint8_t k);
|
||||||
|
inline size_t releaseKeycode(uint8_t k);
|
||||||
|
inline size_t addKeyToReport(uint8_t k);
|
||||||
|
inline size_t addKeycodeToReport(uint8_t k);
|
||||||
|
inline size_t removeKeyFromReport(uint8_t k);
|
||||||
|
inline size_t removeKeycodeFromReport(uint8_t k);
|
||||||
|
|
||||||
|
// Sending is public in the base class for advanced users.
|
||||||
|
virtual void SendReport(void* data, int length) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HID_NKROKeyboardReport_Data_t _keyReport;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation is inline
|
||||||
|
#include "NKROKeyboardAPI.hpp"
|
||||||
|
|
||||||
216
src/HID-APIs/NKROKeyboardAPI.hpp
Normal file
216
src/HID-APIs/NKROKeyboardAPI.hpp
Normal file
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Include guard
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
NKROKeyboardAPI::NKROKeyboardAPI(void)
|
||||||
|
{
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
void NKROKeyboardAPI::begin(void)
|
||||||
|
{
|
||||||
|
releaseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NKROKeyboardAPI::end(void)
|
||||||
|
{
|
||||||
|
releaseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NKROKeyboardAPI::send_now(void){
|
||||||
|
SendReport(&_keyReport, sizeof(_keyReport));
|
||||||
|
}
|
||||||
|
|
||||||
|
// press() adds the specified key (printing, non-printing, or modifier)
|
||||||
|
// 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 NKROKeyboardAPI::press(uint8_t k)
|
||||||
|
{
|
||||||
|
size_t ret = addKeyToReport(k);
|
||||||
|
if(ret){
|
||||||
|
send_now();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 NKROKeyboardAPI::release(uint8_t k)
|
||||||
|
{
|
||||||
|
// it's a non-printing key (not a modifier)
|
||||||
|
if (k >= 136)
|
||||||
|
k = k - 136;
|
||||||
|
|
||||||
|
// it's a modifier key
|
||||||
|
else if (k >= 128)
|
||||||
|
k = k - 128;
|
||||||
|
|
||||||
|
// it's a printing key
|
||||||
|
else {
|
||||||
|
k = pgm_read_byte(_asciimap + k);
|
||||||
|
if (!k)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// it's a capital letter or other character reached with shift
|
||||||
|
if (k & SHIFT) {
|
||||||
|
// the left shift modifier
|
||||||
|
_keyReport.modifiers &= ~(0x02);
|
||||||
|
k = k ^ SHIFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeKeycodeFromReport(k);
|
||||||
|
send_now();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NKROKeyboardAPI::releaseAll(void)
|
||||||
|
{
|
||||||
|
// release all keys
|
||||||
|
memset(&_keyReport, 0x00, sizeof(_keyReport));
|
||||||
|
send_now();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NKROKeyboardAPI::write(uint8_t c)
|
||||||
|
{
|
||||||
|
uint8_t p = press(c); // Keydown
|
||||||
|
release(c); // Keyup
|
||||||
|
return p; // just return the result of press() since release() almost always returns 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pressKeycode() adds the specified key (printing, non-printing, or modifier)
|
||||||
|
// 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 releaseKeycode(), releaseAll(), or otherwise clear the report and resend.
|
||||||
|
size_t NKROKeyboardAPI::pressKeycode(uint8_t k)
|
||||||
|
{
|
||||||
|
if (!addKeycodeToReport(k)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
send_now();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NKROKeyboardAPI::addKeyToReport(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; //TODO return 1??
|
||||||
|
} else { // it's a printing key
|
||||||
|
k = pgm_read_byte(_asciimap + k);
|
||||||
|
if (!k) {
|
||||||
|
setWriteError();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (k & SHIFT) { // it's a capital letter or other character reached with shift
|
||||||
|
_keyReport.modifiers |= 0x02; // the left shift modifier
|
||||||
|
k = k ^ SHIFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return addKeycodeToReport(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NKROKeyboardAPI::addKeycodeToReport(uint8_t k)
|
||||||
|
{
|
||||||
|
// keymap key
|
||||||
|
if (k < NKRO_KEY_COUNT)
|
||||||
|
_keyReport.keys[k / 8] |= 1 << (k % 8);
|
||||||
|
|
||||||
|
// it's a modifier key
|
||||||
|
else if ((k >= HID_KEYBOARD_LEFT_CONTROL) && (k <= HID_KEYBOARD_RIGHT_GUI))
|
||||||
|
_keyReport.modifiers |= (0x01 << (k - HID_KEYBOARD_LEFT_CONTROL));
|
||||||
|
|
||||||
|
// custom key
|
||||||
|
else
|
||||||
|
_keyReport.key = k;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// releaseKeycode() 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.
|
||||||
|
// When send is set to FALSE (= 0) no sendReport() is executed. This comes in
|
||||||
|
// handy when combining key releases (e.g. SHIFT+A).
|
||||||
|
size_t NKROKeyboardAPI::releaseKeycode(uint8_t k)
|
||||||
|
{
|
||||||
|
if (!removeKeycodeFromReport(k)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
send_now();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NKROKeyboardAPI::removeKeyFromReport(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 & SHIFT) { // it's a capital letter or other character reached with shift
|
||||||
|
_keyReport.modifiers &= ~(0x02); // the left shift modifier
|
||||||
|
k = k ^ SHIFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return removeKeycodeFromReport(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t NKROKeyboardAPI::removeKeycodeFromReport(uint8_t k)
|
||||||
|
{
|
||||||
|
// keymap key
|
||||||
|
if (k < NKRO_KEY_COUNT)
|
||||||
|
_keyReport.keys[k / 8] &= ~(1 << (k % 8));
|
||||||
|
|
||||||
|
// it's a modifier key
|
||||||
|
else if ((k >= HID_KEYBOARD_LEFT_CONTROL) && (k <= HID_KEYBOARD_RIGHT_GUI))
|
||||||
|
_keyReport.modifiers &= ~(0x01 << (k - HID_KEYBOARD_LEFT_CONTROL));
|
||||||
|
|
||||||
|
// custom key
|
||||||
|
else
|
||||||
|
_keyReport.key = 0x00;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t NKROKeyboardAPI::writeKeycode(uint8_t c)
|
||||||
|
{
|
||||||
|
uint8_t p = pressKeycode(c); // Keydown
|
||||||
|
releaseKeycode(c); // Keyup
|
||||||
|
return (p); // just return the result of pressKeycode() since release() almost always returns 1
|
||||||
|
}
|
||||||
|
|
@ -53,5 +53,6 @@ THE SOFTWARE.
|
||||||
#else
|
#else
|
||||||
#include "SingleReport/BootKeyboard.h"
|
#include "SingleReport/BootKeyboard.h"
|
||||||
#include "MultiReport/ImprovedKeyboard.h"
|
#include "MultiReport/ImprovedKeyboard.h"
|
||||||
//#include "NKROKeyboard.h"
|
#include "SingleReport/SingleNKROKeyboard.h"
|
||||||
|
#include "MultiReport/NKROKeyboard.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
79
src/MultiReport/NKROKeyboard.cpp
Normal file
79
src/MultiReport/NKROKeyboard.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "NKROKeyboard.h"
|
||||||
|
|
||||||
|
static const uint8_t _hidMultiReportDescriptorNKROKeyboard[] PROGMEM = {
|
||||||
|
// NKRO Keyboard
|
||||||
|
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) 47 */
|
||||||
|
0x09, 0x06, /* USAGE (Keyboard) */
|
||||||
|
0xa1, 0x01, /* COLLECTION (Application) */
|
||||||
|
0x85, HID_REPORTID_NKRO_KEYBOARD, /* REPORT_ID */
|
||||||
|
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) */
|
||||||
|
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||||
|
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||||
|
0x95, 0x08, /* REPORT_COUNT (8) */
|
||||||
|
0x81, 0x02, /* INPUT (Data,Var,Abs) */
|
||||||
|
|
||||||
|
/* 104 Keys as bitmap */
|
||||||
|
0x05, 0x07, /* Usage Page (Key Codes) TODO needed?*/
|
||||||
|
0x19, 0x00, /* Usage Minimum (0) */
|
||||||
|
0x29, NKRO_KEY_COUNT - 1, /* Usage Maximum (103) */
|
||||||
|
0x15, 0x00, /* Logical Minimum (0) */
|
||||||
|
0x25, 0x01, /* Logical Maximum (1) */
|
||||||
|
0x75, 0x01, /* Report Size (1) */
|
||||||
|
0x95, NKRO_KEY_COUNT, /* Report Count (104) */
|
||||||
|
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||||
|
|
||||||
|
/* 1 Custom Keyboard key */
|
||||||
|
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||||
|
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||||
|
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||||
|
0x26, 0xE7, 0x00, /* LOGICAL_MAXIMUM (231) */
|
||||||
|
/*0x05, 0x07, USAGE_PAGE (Keyboard) TODO */
|
||||||
|
0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */
|
||||||
|
0x29, 0xE7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
|
||||||
|
0x81, 0x00, /* INPUT (Data,Ary,Abs) */
|
||||||
|
|
||||||
|
/* End */
|
||||||
|
0xC0 /* End Collection */
|
||||||
|
};
|
||||||
|
|
||||||
|
NKROKeyboard_::NKROKeyboard_(void)
|
||||||
|
{
|
||||||
|
static HIDDescriptorListNode node(_hidMultiReportDescriptorNKROKeyboard, sizeof(_hidMultiReportDescriptorNKROKeyboard));
|
||||||
|
HID().AppendDescriptor(&node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NKROKeyboard_::SendReport(void* data, int length)
|
||||||
|
{
|
||||||
|
HID().SendReport(HID_REPORTID_NKRO_KEYBOARD, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
NKROKeyboard_ NKROKeyboard;
|
||||||
|
|
||||||
43
src/MultiReport/NKROKeyboard.h
Normal file
43
src/MultiReport/NKROKeyboard.h
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Include guard
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "PluggableUSB.h"
|
||||||
|
#include "HID.h"
|
||||||
|
#include "HID-Settings.h"
|
||||||
|
#include "../HID-APIs/NKROKeyboardAPI.h"
|
||||||
|
|
||||||
|
|
||||||
|
class NKROKeyboard_ : public NKROKeyboardAPI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NKROKeyboard_(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual inline void SendReport(void* data, int length) override;
|
||||||
|
};
|
||||||
|
extern NKROKeyboard_ NKROKeyboard;
|
||||||
|
|
||||||
161
src/SingleReport/SingleNKROKeyboard.cpp
Normal file
161
src/SingleReport/SingleNKROKeyboard.cpp
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SingleNKROKeyboard.h"
|
||||||
|
|
||||||
|
static const uint8_t _hidReportDescriptorNKRO[] PROGMEM = {
|
||||||
|
// NKRO Keyboard
|
||||||
|
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) 47 */
|
||||||
|
0x09, 0x06, /* USAGE (Keyboard) */
|
||||||
|
0xa1, 0x01, /* COLLECTION (Application) */
|
||||||
|
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) */
|
||||||
|
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||||
|
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||||
|
0x95, 0x08, /* REPORT_COUNT (8) */
|
||||||
|
0x81, 0x02, /* INPUT (Data,Var,Abs) */
|
||||||
|
|
||||||
|
/* 5 LEDs for num lock etc, 3 left for advanced, custom usage */
|
||||||
|
0x05, 0x08, /* USAGE_PAGE (LEDs) */
|
||||||
|
0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
|
||||||
|
0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
|
||||||
|
0x95, 0x08, /* REPORT_COUNT (8) */
|
||||||
|
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||||
|
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
|
||||||
|
/* Reserved 3 bits */
|
||||||
|
//0x95, 0x01, /* REPORT_COUNT (1) */
|
||||||
|
//0x75, 0x03, /* REPORT_SIZE (3) */
|
||||||
|
//0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */
|
||||||
|
|
||||||
|
/* 104 Keys as bitmap */
|
||||||
|
0x05, 0x07, /* Usage Page (Key Codes) */
|
||||||
|
0x19, 0x00, /* Usage Minimum (0) */
|
||||||
|
0x29, NKRO_KEY_COUNT - 1, /* Usage Maximum (103) */
|
||||||
|
0x15, 0x00, /* Logical Minimum (0) */
|
||||||
|
0x25, 0x01, /* Logical Maximum (1) */
|
||||||
|
0x75, 0x01, /* Report Size (1) */
|
||||||
|
0x95, NKRO_KEY_COUNT, /* Report Count (104) */
|
||||||
|
0x81, 0x02, /* Input (Data, Variable, Absolute) */
|
||||||
|
|
||||||
|
/* 1 Custom Keyboard key */
|
||||||
|
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||||
|
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||||
|
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||||
|
0x26, 0xE7, 0x00, /* LOGICAL_MAXIMUM (231) */
|
||||||
|
/*0x05, 0x07, USAGE_PAGE (Keyboard) */
|
||||||
|
0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */
|
||||||
|
0x29, 0xE7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
|
||||||
|
0x81, 0x00, /* INPUT (Data,Ary,Abs) */
|
||||||
|
|
||||||
|
/* End */
|
||||||
|
0xC0 /* End Collection */
|
||||||
|
};
|
||||||
|
|
||||||
|
SingleNKROKeyboard_::SingleNKROKeyboard_(void) : PUSBListNode(1, 1, epType), protocol(1), idle(1), leds(0)
|
||||||
|
{
|
||||||
|
epType[0] = EP_TYPE_INTERRUPT_IN;
|
||||||
|
PluggableUSB().plug(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SingleNKROKeyboard_::getInterface(uint8_t* interfaceCount)
|
||||||
|
{
|
||||||
|
*interfaceCount += 1; // uses 1
|
||||||
|
HIDDescriptor hidInterface = {
|
||||||
|
D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE),
|
||||||
|
D_HIDREPORT(sizeof(_hidReportDescriptorNKRO)),
|
||||||
|
D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
|
||||||
|
};
|
||||||
|
return USB_SendControl(0, &hidInterface, sizeof(hidInterface));
|
||||||
|
}
|
||||||
|
|
||||||
|
int SingleNKROKeyboard_::getDescriptor(USBSetup& setup)
|
||||||
|
{
|
||||||
|
// Check if this is a HID Class Descriptor request
|
||||||
|
if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
|
||||||
|
if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; }
|
||||||
|
|
||||||
|
// In a HID Class Descriptor wIndex cointains the interface number
|
||||||
|
if (setup.wIndex != pluggedInterface) { return 0; }
|
||||||
|
|
||||||
|
return USB_SendControl(TRANSFER_PGM, _hidReportDescriptorNKRO, sizeof(_hidReportDescriptorNKRO));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SingleNKROKeyboard_::setup(USBSetup& setup)
|
||||||
|
{
|
||||||
|
if (pluggedInterface != setup.wIndex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t request = setup.bRequest;
|
||||||
|
uint8_t requestType = setup.bmRequestType;
|
||||||
|
|
||||||
|
if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
|
||||||
|
{
|
||||||
|
if (request == HID_GET_REPORT) {
|
||||||
|
// TODO: HID_GetReport();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (request == HID_GET_PROTOCOL) {
|
||||||
|
// TODO: Send8(protocol);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
|
||||||
|
{
|
||||||
|
if (request == HID_SET_PROTOCOL) {
|
||||||
|
protocol = setup.wValueL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (request == HID_SET_IDLE) {
|
||||||
|
idle = setup.wValueL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (request == HID_SET_REPORT)
|
||||||
|
{
|
||||||
|
// Check if data has the correct length
|
||||||
|
auto length = setup.wLength;
|
||||||
|
if(length == sizeof(leds)){
|
||||||
|
USB_RecvControl(&leds, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SingleNKROKeyboard_::getLeds(void){
|
||||||
|
return leds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleNKROKeyboard_::SendReport(void* data, int length){
|
||||||
|
USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleNKROKeyboard_ SingleNKROKeyboard;
|
||||||
|
|
||||||
|
|
||||||
57
src/SingleReport/SingleNKROKeyboard.h
Normal file
57
src/SingleReport/SingleNKROKeyboard.h
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 NicoHood
|
||||||
|
See the readme for credit to other people.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Include guard
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "PluggableUSB.h"
|
||||||
|
#include "HID.h"
|
||||||
|
#include "HID-Settings.h"
|
||||||
|
#include "../HID-APIs/NKROKeyboardAPI.h"
|
||||||
|
|
||||||
|
|
||||||
|
class SingleNKROKeyboard_ : public PUSBListNode, public NKROKeyboardAPI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SingleNKROKeyboard_(void);
|
||||||
|
uint8_t getLeds(void);
|
||||||
|
uint8_t getProtocol(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Implementation of the PUSBListNode
|
||||||
|
int getInterface(uint8_t* interfaceCount);
|
||||||
|
int getDescriptor(USBSetup& setup);
|
||||||
|
bool setup(USBSetup& setup);
|
||||||
|
|
||||||
|
uint8_t epType[1];
|
||||||
|
uint8_t protocol;
|
||||||
|
uint8_t idle;
|
||||||
|
|
||||||
|
uint8_t leds;
|
||||||
|
|
||||||
|
virtual void SendReport(void* data, int length) override;
|
||||||
|
};
|
||||||
|
extern SingleNKROKeyboard_ SingleNKROKeyboard;
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in a new issue