summaryrefslogtreecommitdiff
path: root/hid/src
diff options
context:
space:
mode:
authorDevaev Maxim <[email protected]>2020-11-19 23:28:23 +0300
committerDevaev Maxim <[email protected]>2020-11-20 00:15:18 +0300
commita77db72355c760eb38deb4c46a83fb7d3f2ed008 (patch)
tree208cd060c234fbfd77ef3c1879ed906950660bed /hid/src
parent188de715153100806bc4a95f3888f6f03f1ede2f (diff)
multihid firmware
Diffstat (limited to 'hid/src')
-rw-r--r--hid/src/main.cpp371
-rw-r--r--hid/src/proto.h75
-rw-r--r--hid/src/ps2/hid.h18
-rw-r--r--hid/src/usb/hid.h161
4 files changed, 407 insertions, 218 deletions
diff --git a/hid/src/main.cpp b/hid/src/main.cpp
index 8b48f82a..3117d455 100644
--- a/hid/src/main.cpp
+++ b/hid/src/main.cpp
@@ -29,15 +29,13 @@
#ifdef CMD_SPI
# include <SPI.h>
#endif
+#ifdef HID_DYNAMIC
+# include <avr/eeprom.h>
+#endif
#include "proto.h"
-
-#if defined(HID_USB_KBD) || defined(HID_USB_MOUSE)
-# include "usb/hid.h"
-#endif
-#ifdef HID_PS2_KBD
-# include "ps2/hid.h"
-#endif
+#include "usb/hid.h"
+#include "ps2/hid.h"
// #define CMD_SERIAL Serial1
@@ -48,98 +46,176 @@
// -----------------------------------------------------------------------------
-#ifdef HID_USB_KBD
- UsbHidKeyboard hid_kbd;
-#elif defined(HID_PS2_KBD)
- Ps2HidKeyboard hid_kbd;
-#endif
-#ifdef HID_USB_MOUSE
- UsbHidMouse hid_mouse;
-#endif
+static UsbKeyboard *_usb_kbd = NULL;
+static UsbMouseAbsolute *_usb_mouse_abs = NULL;
+static UsbMouseRelative *_usb_mouse_rel = NULL;
+static Ps2Keyboard *_ps2_kbd = NULL;
-// -----------------------------------------------------------------------------
-uint8_t cmdPong(const uint8_t *_=NULL) { // 0 bytes
- return (
- PROTO::PONG::PREFIX
- | hid_kbd.getLedsAs(PROTO::PONG::CAPS, PROTO::PONG::SCROLL, PROTO::PONG::NUM)
- | (hid_kbd.isOnline() ? 0 : PROTO::PONG::KEYBOARD_OFFLINE)
-# ifdef HID_USB_MOUSE
- | (hid_mouse.isOnline() ? 0 : PROTO::PONG::MOUSE_OFFLINE)
-# endif
- );
+#ifdef HID_DYNAMIC
+static bool _reset_required = false;
+
+static void _setOutputs(uint8_t outputs) {
+ uint8_t data[8] = {0};
+ data[0] = PROTO::MAGIC;
+ data[1] = outputs;
+ PROTO::split16(PROTO::crc16(data, 6), &data[6], &data[7]);
+ eeprom_update_block(data, 0, 8);
}
+#endif
-uint8_t cmdResetHid(const uint8_t *_) { // 0 bytes
-# ifdef HID_USB_KBD
- hid_kbd.reset();
+static void _initOutputs() {
+ uint8_t data[8];
+# ifdef HID_DYNAMIC
+ eeprom_read_block(data, 0, 8);
+ if (
+ PROTO::crc16(data, 6) != PROTO::merge8(data[6], data[7])
+ || data[0] != PROTO::MAGIC
+ ) {
# endif
-# ifdef HID_USB_MOUSE
- hid_mouse.reset();
+ data[1] = 0;
+
+# if defined(HID_WITH_USB) && defined(HID_SET_USB_KBD)
+ data[1] |= PROTO::OUTPUTS::KEYBOARD::USB;
+# elif defined(HID_WITH_PS2) && defined(HID_SET_PS2_KBD)
+ data[1] |= PROTO::OUTPUTS::KEYBOARD::PS2;
+# endif
+# if defined(HID_WITH_USB) && defined(HID_SET_USB_MOUSE_ABS)
+ data[1] |= PROTO::OUTPUTS::MOUSE::USB_ABS;
+# elif defined(HID_WITH_USB) && defined(HID_SET_USB_MOUSE_REL)
+ data[1] |= PROTO::OUTPUTS::MOUSE::USB_REL;
+# elif defined(HID_WITH_PS2) && defined(HID_SET_PS2_MOUSE)
+ data[1] |= PROTO::OUTPUTS::MOUSE::PS2;
+# endif
+
+# ifdef HID_DYNAMIC
+ _setOutputs(data[1]);
+ }
# endif
- return cmdPong();
+
+ uint8_t kbd = data[1] & PROTO::OUTPUTS::KEYBOARD::MASK;
+ switch (kbd) {
+# ifdef HID_WITH_USB
+ case PROTO::OUTPUTS::KEYBOARD::USB: _usb_kbd = new UsbKeyboard(); break;
+# endif
+# ifdef HID_WITH_PS2
+ case PROTO::OUTPUTS::KEYBOARD::PS2: _ps2_kbd = new Ps2Keyboard(); break;
+# endif
+ }
+
+ uint8_t mouse = data[1] & PROTO::OUTPUTS::MOUSE::MASK;
+ switch (mouse) {
+# ifdef HID_WITH_USB
+ case PROTO::OUTPUTS::MOUSE::USB_ABS: _usb_mouse_abs = new UsbMouseAbsolute(); break;
+ case PROTO::OUTPUTS::MOUSE::USB_REL: _usb_mouse_rel = new UsbMouseRelative(); break;
+# endif
+ }
+
+ USBDevice.attach();
+
+ switch (kbd) {
+# ifdef HID_WITH_USB
+ case PROTO::OUTPUTS::KEYBOARD::USB: _usb_kbd->begin(); break;
+# endif
+# ifdef HID_WITH_PS2
+ case PROTO::OUTPUTS::KEYBOARD::PS2: _ps2_kbd->begin(); break;
+# endif
+ }
+
+ switch (mouse) {
+# ifdef HID_WITH_USB
+ case PROTO::OUTPUTS::MOUSE::USB_ABS: _usb_mouse_abs->begin(); break;
+ case PROTO::OUTPUTS::MOUSE::USB_REL: _usb_mouse_rel->begin(); break;
+# endif
+ }
}
-uint8_t cmdKeyEvent(const uint8_t *buffer) { // 2 bytes
- hid_kbd.sendKey(buffer[0], buffer[1]);
- return cmdPong();
+
+// -----------------------------------------------------------------------------
+static void _cmdSetOutputs(const uint8_t *data) { // 1 bytes
+# ifdef HID_DYNAMIC
+ _setOutputs(data[0]);
+ _reset_required = true;
+# endif
}
-uint8_t cmdMouseButtonEvent(const uint8_t *buffer) { // 2 bytes
-# ifdef HID_USB_MOUSE
- uint8_t main_state = buffer[0];
- uint8_t extra_state = buffer[1];
+static void _cmdClearHid(const uint8_t *_) { // 0 bytes
+ if (_usb_kbd) {
+ _usb_kbd->clear();
+ }
+ if (_usb_mouse_abs) {
+ _usb_mouse_abs->clear();
+ } else if (_usb_mouse_rel) {
+ _usb_mouse_rel->clear();
+ }
+}
+
+static void _cmdKeyEvent(const uint8_t *data) { // 2 bytes
+ if (_usb_kbd) {
+ _usb_kbd->sendKey(data[0], data[1]);
+ } else if (_ps2_kbd) {
+ _ps2_kbd->sendKey(data[0], data[1]);
+ }
+}
+static void _cmdMouseButtonEvent(const uint8_t *data) { // 2 bytes
# define MOUSE_PAIR(_state, _button) \
_state & PROTO::CMD::MOUSE::_button::SELECT, \
_state & PROTO::CMD::MOUSE::_button::STATE
- hid_mouse.sendButtons(
- MOUSE_PAIR(main_state, LEFT),
- MOUSE_PAIR(main_state, RIGHT),
- MOUSE_PAIR(main_state, MIDDLE),
- MOUSE_PAIR(extra_state, EXTRA_UP),
- MOUSE_PAIR(extra_state, EXTRA_DOWN)
- );
+# define SEND_BUTTONS(_hid) \
+ _hid->sendButtons( \
+ MOUSE_PAIR(data[0], LEFT), \
+ MOUSE_PAIR(data[0], RIGHT), \
+ MOUSE_PAIR(data[0], MIDDLE), \
+ MOUSE_PAIR(data[1], EXTRA_UP), \
+ MOUSE_PAIR(data[1], EXTRA_DOWN) \
+ );
+ if (_usb_mouse_abs) {
+ SEND_BUTTONS(_usb_mouse_abs);
+ } else if (_usb_mouse_rel) {
+ SEND_BUTTONS(_usb_mouse_rel);
+ }
+# undef SEND_BUTTONS
# undef MOUSE_PAIR
-# endif
- return cmdPong();
}
-uint8_t cmdMouseMoveEvent(const uint8_t *buffer) { // 4 bytes
-# ifdef HID_USB_MOUSE
- int x = (int)buffer[0] << 8;
- x |= (int)buffer[1];
- x = (x + 32768) / 2; // See /kvmd/apps/otg/hid/keyboard.py for details
-
- int y = (int)buffer[2] << 8;
- y |= (int)buffer[3];
- y = (y + 32768) / 2; // See /kvmd/apps/otg/hid/keyboard.py for details
+static void _cmdMouseMoveEvent(const uint8_t *data) { // 4 bytes
+ // See /kvmd/apps/otg/hid/keyboard.py for details
+ if (_usb_mouse_abs) {
+ _usb_mouse_abs->sendMove(
+ (PROTO::merge8_int(data[0], data[1]) + 32768) / 2,
+ (PROTO::merge8_int(data[2], data[3]) + 32768) / 2
+ );
+ }
+}
- hid_mouse.sendMove(x, y);
-# endif
- return cmdPong();
+static void _cmdMouseRelativeEvent(const uint8_t *data) { // 2 bytes
+ if (_usb_mouse_rel) {
+ _usb_mouse_rel->sendRelative(data[0], data[1]);
+ }
}
-uint8_t cmdMouseWheelEvent(const uint8_t *buffer) { // 2 bytes
-# ifdef HID_USB_MOUSE
- hid_mouse.sendWheel(buffer[1]); // Y only, X is not supported
-# endif
- return cmdPong();
+static void _cmdMouseWheelEvent(const uint8_t *data) { // 2 bytes
+ // Y only, X is not supported
+ if (_usb_mouse_abs) {
+ _usb_mouse_abs->sendWheel(data[1]);
+ } else if (_usb_mouse_rel) {
+ _usb_mouse_rel->sendWheel(data[1]);
+ }
}
-uint8_t handleCmdBuffer(const uint8_t *buffer) { // 8 bytes
- uint16_t crc = (uint16_t)buffer[6] << 8;
- crc |= (uint16_t)buffer[7];
-
- if (protoCrc16(buffer, 6) == crc) {
-# define HANDLE(_handler) { return _handler(buffer + 2); }
- switch (buffer[1]) {
- case PROTO::CMD::RESET_HID: HANDLE(cmdResetHid);
- case PROTO::CMD::KEYBOARD::KEY: HANDLE(cmdKeyEvent);
- case PROTO::CMD::MOUSE::BUTTON: HANDLE(cmdMouseButtonEvent);
- case PROTO::CMD::MOUSE::MOVE: HANDLE(cmdMouseMoveEvent);
- case PROTO::CMD::MOUSE::WHEEL: HANDLE(cmdMouseWheelEvent);
- case PROTO::CMD::PING: HANDLE(cmdPong);
+static uint8_t _handleRequest(const uint8_t *data) { // 8 bytes
+ if (PROTO::crc16(data, 6) == PROTO::merge8(data[6], data[7])) {
+# define HANDLE(_handler) { _handler(data + 2); return PROTO::PONG::OK; }
+ switch (data[1]) {
+ case PROTO::CMD::PING: return PROTO::PONG::OK;
+ case PROTO::CMD::SET_OUTPUTS: HANDLE(_cmdSetOutputs);
+ case PROTO::CMD::CLEAR_HID: HANDLE(_cmdClearHid);
+ case PROTO::CMD::KEYBOARD::KEY: HANDLE(_cmdKeyEvent);
+ case PROTO::CMD::MOUSE::BUTTON: HANDLE(_cmdMouseButtonEvent);
+ case PROTO::CMD::MOUSE::MOVE: HANDLE(_cmdMouseMoveEvent);
+ case PROTO::CMD::MOUSE::RELATIVE: HANDLE(_cmdMouseRelativeEvent);
+ case PROTO::CMD::MOUSE::WHEEL: HANDLE(_cmdMouseWheelEvent);
case PROTO::CMD::REPEAT: return 0;
default: return PROTO::RESP::INVALID_ERROR;
}
@@ -151,33 +227,33 @@ uint8_t handleCmdBuffer(const uint8_t *buffer) { // 8 bytes
// -----------------------------------------------------------------------------
#ifdef CMD_SPI
-volatile uint8_t spi_in[8] = {0};
-volatile uint8_t spi_in_index = 0;
+static volatile uint8_t _spi_in[8] = {0};
+static volatile uint8_t _spi_in_index = 0;
-volatile uint8_t spi_out[4] = {0};
-volatile uint8_t spi_out_index = 0;
+static volatile uint8_t _spi_out[8] = {0};
+static volatile uint8_t _spi_out_index = 0;
-bool spiReady() {
- return (!spi_out[0] && spi_in_index == 8);
+static bool _spiReady() {
+ return (!_spi_out[0] && _spi_in_index == 8);
}
-void spiWrite(const uint8_t *buffer) {
- spi_out[3] = buffer[3];
- spi_out[2] = buffer[2];
- spi_out[1] = buffer[1];
- spi_out[0] = buffer[0]; // Меджик разрешает начать ответ
+static void _spiWrite(const uint8_t *data) {
+ // Меджик в нулевом байте разрешает начать ответ
+ for (int index = 7; index >= 0; --index) {
+ _spi_out[index] = data[index];
+ }
}
ISR(SPI_STC_vect) {
uint8_t in = SPDR;
- if (spi_out[0] && spi_out_index < 4) {
- SPDR = spi_out[spi_out_index];
+ if (_spi_out[0] && _spi_out_index < 8) {
+ SPDR = _spi_out[_spi_out_index];
if (!(SPSR & (1 << WCOL))) {
- ++spi_out_index;
- if (spi_out_index == 4) {
- spi_out_index = 0;
- spi_in_index = 0;
- spi_out[0] = 0;
+ ++_spi_out_index;
+ if (_spi_out_index == 8) {
+ _spi_out_index = 0;
+ _spi_in_index = 0;
+ _spi_out[0] = 0;
}
}
} else {
@@ -185,11 +261,11 @@ ISR(SPI_STC_vect) {
if (!receiving && in == PROTO::MAGIC) {
receiving = true;
}
- if (receiving && spi_in_index < 8) {
- spi_in[spi_in_index] = in;
- ++spi_in_index;
+ if (receiving && _spi_in_index < 8) {
+ _spi_in[_spi_in_index] = in;
+ ++_spi_in_index;
}
- if (spi_in_index == 8) {
+ if (_spi_in_index == 8) {
receiving = false;
}
SPDR = 0;
@@ -199,7 +275,7 @@ ISR(SPI_STC_vect) {
// -----------------------------------------------------------------------------
-void sendCmdResponse(uint8_t code) {
+static void _sendResponse(uint8_t code) {
static uint8_t prev_code = PROTO::RESP::NONE;
if (code == 0) {
code = prev_code; // Repeat the last code
@@ -207,51 +283,71 @@ void sendCmdResponse(uint8_t code) {
prev_code = code;
}
- uint8_t buffer[4];
- buffer[0] = PROTO::MAGIC;
- buffer[1] = code;
- uint16_t crc = protoCrc16(buffer, 2);
- buffer[2] = (uint8_t)(crc >> 8);
- buffer[3] = (uint8_t)(crc & 0xFF);
+ uint8_t data[8] = {0};
+ data[0] = PROTO::MAGIC;
+ if (code & PROTO::PONG::OK) {
+ data[1] = PROTO::PONG::OK;
+# ifdef HID_DYNAMIC
+ if (_reset_required) {
+ data[1] |= PROTO::PONG::RESET_REQUIRED;
+ }
+ data[2] = PROTO::OUTPUTS::DYNAMIC;
+# endif
+ if (_usb_kbd) {
+ data[1] |= _usb_kbd->getOfflineAs(PROTO::PONG::KEYBOARD_OFFLINE);
+ data[1] |= _usb_kbd->getLedsAs(PROTO::PONG::CAPS, PROTO::PONG::SCROLL, PROTO::PONG::NUM);
+ data[2] |= PROTO::OUTPUTS::KEYBOARD::USB;
+ } else if (_ps2_kbd) {
+ data[1] |= _ps2_kbd->getOfflineAs(PROTO::PONG::KEYBOARD_OFFLINE);
+ data[1] |= _ps2_kbd->getLedsAs(PROTO::PONG::CAPS, PROTO::PONG::SCROLL, PROTO::PONG::NUM);
+ data[2] |= PROTO::OUTPUTS::KEYBOARD::PS2;
+ }
+ if (_usb_mouse_abs) {
+ data[1] |= _usb_mouse_abs->getOfflineAs(PROTO::PONG::MOUSE_OFFLINE);
+ data[2] |= PROTO::OUTPUTS::MOUSE::USB_ABS;
+ } else if (_usb_mouse_rel) {
+ data[1] |= _usb_mouse_rel->getOfflineAs(PROTO::PONG::MOUSE_OFFLINE);
+ data[2] |= PROTO::OUTPUTS::MOUSE::USB_REL;
+ } // TODO: ps2
+# ifdef HID_WITH_USB
+ data[3] |= PROTO::FEATURES::HAS_USB;
+# endif
+# ifdef HID_WITH_PS2
+ data[3] |= PROTO::FEATURES::HAS_PS2;
+# endif
+ } else {
+ data[1] = code;
+ }
+ PROTO::split16(PROTO::crc16(data, 6), &data[6], &data[7]);
# ifdef CMD_SERIAL
- CMD_SERIAL.write(buffer, 4);
+ CMD_SERIAL.write(data, 8);
# elif defined(CMD_SPI)
- spiWrite(buffer);
+ _spiWrite(data);
# endif
}
-void setup() {
- hid_kbd.begin();
-# ifdef HID_USB_MOUSE
- hid_mouse.begin();
-# endif
+int main() {
+ init(); // Embedded
+ initVariant(); // Arduino
+ _initOutputs();
# ifdef CMD_SERIAL
CMD_SERIAL.begin(CMD_SERIAL_SPEED);
-# elif defined(CMD_SPI)
- pinMode(MISO, OUTPUT);
- SPCR = (1 << SPE) | (1 << SPIE); // Slave, SPI En, IRQ En
-# endif
-}
-
-void loop() {
-# ifdef CMD_SERIAL
unsigned long last = micros();
uint8_t buffer[8];
uint8_t index = 0;
-# endif
while (true) {
-# ifdef HID_PS2_KBD
- hid_kbd.periodic();
+# ifdef HID_WITH_PS2
+ if (_ps2_kbd) {
+ _ps2_kbd->periodic();
+ }
# endif
-
-# ifdef CMD_SERIAL
if (CMD_SERIAL.available() > 0) {
buffer[index] = (uint8_t)CMD_SERIAL.read();
if (index == 7) {
- sendCmdResponse(handleCmdBuffer(buffer));
+ _sendResponse(_handleRequest(buffer));
index = 0;
} else {
last = micros();
@@ -263,14 +359,27 @@ void loop() {
(now >= last && now - last > CMD_SERIAL_TIMEOUT)
|| (now < last && ((unsigned long)-1) - last + now > CMD_SERIAL_TIMEOUT)
) {
- sendCmdResponse(PROTO::RESP::TIMEOUT_ERROR);
+ _sendResponse(PROTO::RESP::TIMEOUT_ERROR);
index = 0;
}
}
-# elif defined(CMD_SPI)
- if (spiReady()) {
- sendCmdResponse(handleCmdBuffer(spi_in));
+ }
+
+# elif defined(CMD_SPI)
+ pinMode(MISO, OUTPUT);
+ SPCR = (1 << SPE) | (1 << SPIE); // Slave, SPI En, IRQ En
+
+ while (true) {
+# ifdef HID_WITH_PS2
+ if (_ps2_kbd) {
+ _ps2_kbd->periodic();
}
# endif
+ if (_spiReady()) {
+ _sendResponse(_handleRequest((const uint8_t *)_spi_in));
+ }
}
+
+# endif
+ return 0;
}
diff --git a/hid/src/proto.h b/hid/src/proto.h
index ca9b4f2c..456ba073 100644
--- a/hid/src/proto.h
+++ b/hid/src/proto.h
@@ -25,7 +25,6 @@
namespace PROTO {
const uint8_t MAGIC = 0x33;
- const uint16_t CRC_POLINOM = 0xA001;
namespace RESP { // Plain responses
// const uint8_t OK = 0x20; // Legacy
@@ -36,27 +35,50 @@ namespace PROTO {
};
namespace PONG { // Complex response
- const uint8_t PREFIX = 0x80;
+ const uint8_t OK = 0x80;
const uint8_t CAPS = 0b00000001;
const uint8_t SCROLL = 0b00000010;
const uint8_t NUM = 0b00000100;
const uint8_t KEYBOARD_OFFLINE = 0b00001000;
const uint8_t MOUSE_OFFLINE = 0b00010000;
+ const uint8_t RESET_REQUIRED = 0b01000000;
};
+ namespace OUTPUTS { // Complex request/responce flags
+ const uint8_t DYNAMIC = 0b10000000;
+ namespace KEYBOARD {
+ const uint8_t MASK = 0b00000111;
+ const uint8_t USB = 0b00000001;
+ const uint8_t PS2 = 0b00000011;
+ };
+ namespace MOUSE {
+ const uint8_t MASK = 0b00111000;
+ const uint8_t USB_ABS = 0b00001000;
+ const uint8_t USB_REL = 0b00010000;
+ const uint8_t PS2 = 0b00011000;
+ };
+ };
+
+ namespace FEATURES {
+ const uint8_t HAS_USB = 0b00000001;
+ const uint8_t HAS_PS2 = 0b00000010;
+ }
+
namespace CMD {
const uint8_t PING = 0x01;
const uint8_t REPEAT = 0x02;
- const uint8_t RESET_HID = 0x10;
+ const uint8_t SET_OUTPUTS = 0x03;
+ const uint8_t CLEAR_HID = 0x10;
namespace KEYBOARD {
const uint8_t KEY = 0x11;
};
namespace MOUSE {
- const uint8_t MOVE = 0x12;
- const uint8_t BUTTON = 0x13;
- const uint8_t WHEEL = 0x14;
+ const uint8_t MOVE = 0x12;
+ const uint8_t BUTTON = 0x13;
+ const uint8_t WHEEL = 0x14;
+ const uint8_t RELATIVE = 0x15;
namespace LEFT {
const uint8_t SELECT = 0b10000000;
const uint8_t STATE = 0b00001000;
@@ -79,22 +101,35 @@ namespace PROTO {
};
};
};
-};
+ uint16_t crc16(const uint8_t *buffer, unsigned length) {
+ const uint16_t polinom = 0xA001;
+ uint16_t crc = 0xFFFF;
-uint16_t protoCrc16(const uint8_t *buffer, unsigned length) {
- uint16_t crc = 0xFFFF;
-
- for (unsigned byte_count = 0; byte_count < length; ++byte_count) {
- crc = crc ^ buffer[byte_count];
- for (unsigned bit_count = 0; bit_count < 8; ++bit_count) {
- if ((crc & 0x0001) == 0) {
- crc = crc >> 1;
- } else {
- crc = crc >> 1;
- crc = crc ^ PROTO::CRC_POLINOM;
+ for (unsigned byte_count = 0; byte_count < length; ++byte_count) {
+ crc = crc ^ buffer[byte_count];
+ for (unsigned bit_count = 0; bit_count < 8; ++bit_count) {
+ if ((crc & 0x0001) == 0) {
+ crc = crc >> 1;
+ } else {
+ crc = crc >> 1;
+ crc = crc ^ polinom;
+ }
}
}
+ return crc;
+ }
+
+ inline int merge8_int(uint8_t from_a, uint8_t from_b) {
+ return (((int)from_a << 8) | (int)from_b);
+ }
+
+ inline uint16_t merge8(uint8_t from_a, uint8_t from_b) {
+ return (((uint16_t)from_a << 8) | (uint16_t)from_b);
+ }
+
+ inline void split16(uint16_t from, uint8_t *to_a, uint8_t *to_b) {
+ *to_a = (uint8_t)(from >> 8);
+ *to_b = (uint8_t)(from & 0xFF);
}
- return crc;
-}
+};
diff --git a/hid/src/ps2/hid.h b/hid/src/ps2/hid.h
index 3f226090..c344625b 100644
--- a/hid/src/ps2/hid.h
+++ b/hid/src/ps2/hid.h
@@ -27,24 +27,20 @@
#include "keymap.h"
-// #define PS2_KBD_CLOCK_PIN 7
-// #define PS2_KBD_DATA_PIN 5
+// #define HID_PS2_KBD_CLOCK_PIN 7
+// #define HID_PS2_KBD_DATA_PIN 5
-class Ps2HidKeyboard {
+class Ps2Keyboard {
// https://wiki.osdev.org/PS/2_Keyboard
public:
- Ps2HidKeyboard() : _dev(PS2_KBD_CLOCK_PIN, PS2_KBD_DATA_PIN) {}
+ Ps2Keyboard() : _dev(HID_PS2_KBD_CLOCK_PIN, HID_PS2_KBD_DATA_PIN) {}
void begin() {
_dev.keyboard_init();
}
- bool isOnline() {
- return true;
- }
-
void periodic() {
_dev.keyboard_handle(&_leds);
}
@@ -57,7 +53,7 @@ class Ps2HidKeyboard {
if (ps2_type != PS2_KEY_TYPE_UNKNOWN) {
// Не отправлялась часть нажатий. Когда clock на нуле, комп не принимает ничего от клавы.
// Этот костыль понижает процент пропущенных нажатий.
- while (digitalRead(PS2_KBD_CLOCK_PIN) == 0) {};
+ while (digitalRead(HID_PS2_KBD_CLOCK_PIN) == 0) {};
if (state) {
switch (ps2_type) {
case PS2_KEY_TYPE_REG: _dev.keyboard_press(ps2_code); break;
@@ -78,6 +74,10 @@ class Ps2HidKeyboard {
}
}
+ uint8_t getOfflineAs(uint8_t offline) {
+ return 0;
+ }
+
uint8_t getLedsAs(uint8_t caps, uint8_t scroll, uint8_t num) {
uint8_t result = 0;
diff --git a/hid/src/usb/hid.h b/hid/src/usb/hid.h
index d48d0fc2..7a102eab 100644
--- a/hid/src/usb/hid.h
+++ b/hid/src/usb/hid.h
@@ -29,113 +29,158 @@
// -----------------------------------------------------------------------------
-#ifdef CHECK_ENDPOINT
-static bool _checkEndpoint(uint8_t ep) {
- // https://github.com/arduino/ArduinoCore-avr/blob/2f67c916f6ab6193c404eebe22efe901e0f9542d/cores/arduino/USBCore.cpp#L249
- // https://sourceforge.net/p/arduinomidilib/svn/41/tree/branch/3.1/Teensy/teensy_core/usb_midi/usb_api.cpp#l103
- uint8_t intr_state = SREG;
- cli();
- UENUM = ep & 7;
- bool rw_allowed = UEINTX & (1 << RWAL);
- SREG = intr_state;
- return rw_allowed;
-}
-# define CHECK_HID_EP { if (!isOnline()) return; }
+#ifdef HID_USB_CHECK_ENDPOINT
+// https://github.com/arduino/ArduinoCore-avr/blob/2f67c916f6ab6193c404eebe22efe901e0f9542d/cores/arduino/USBCore.cpp#L249
+// https://sourceforge.net/p/arduinomidilib/svn/41/tree/branch/3.1/Teensy/teensy_core/usb_midi/usb_api.cpp#l103
+# define CLS_GET_OFFLINE_AS(_hid) \
+ uint8_t getOfflineAs(uint8_t offline) { \
+ uint8_t ep = _hid.getPluggedEndpoint(); \
+ uint8_t intr_state = SREG; \
+ cli(); \
+ UENUM = ep & 7; \
+ bool rw_allowed = UEINTX & (1 << RWAL); \
+ SREG = intr_state; \
+ if (rw_allowed) { \
+ return 0; \
+ } \
+ return offline; \
+ }
+# define CHECK_HID_EP { if (getOfflineAs(1)) return; }
+
#else
+# define CLS_GET_OFFLINE_AS(_hid) \
+ uint8_t getOfflineAs(uint8_t offline) { \
+ return 0; \
+ }
# define CHECK_HID_EP
+
#endif
-class UsbHidKeyboard {
+class UsbKeyboard {
public:
- UsbHidKeyboard() {}
+ UsbKeyboard() {}
void begin() {
- BootKeyboard.begin();
- }
-
- bool isOnline() {
-# ifdef CHECK_ENDPOINT
- return _checkEndpoint(BootKeyboard.getPluggedEndpoint());
-# else
- return true;
-# endif
+ _kbd.begin();
}
- void reset() {
- BootKeyboard.releaseAll();
+ void clear() {
+ _kbd.releaseAll();
}
void sendKey(uint8_t code, bool state) {
CHECK_HID_EP;
KeyboardKeycode usb_code = keymapUsb(code);
if (usb_code != KEY_ERROR_UNDEFINED) {
- if (state) BootKeyboard.press(usb_code);
- else BootKeyboard.release(usb_code);
+ if (state) _kbd.press(usb_code);
+ else _kbd.release(usb_code);
}
}
+ CLS_GET_OFFLINE_AS(_kbd)
+
uint8_t getLedsAs(uint8_t caps, uint8_t scroll, uint8_t num) {
- uint8_t leds = BootKeyboard.getLeds();
+ uint8_t leds = _kbd.getLeds();
uint8_t result = 0;
-
if (leds & LED_CAPS_LOCK) result |= caps;
if (leds & LED_SCROLL_LOCK) result |= scroll;
if (leds & LED_NUM_LOCK) result |= num;
return result;
}
+
+ private:
+ BootKeyboard_ _kbd;
};
-class UsbHidMouse {
+#define CLS_SEND_BUTTONS \
+ void sendButtons( \
+ bool left_select, bool left_state, \
+ bool right_select, bool right_state, \
+ bool middle_select, bool middle_state, \
+ bool up_select, bool up_state, \
+ bool down_select, bool down_state \
+ ) { \
+ if (left_select) _sendButton(MOUSE_LEFT, left_state); \
+ if (right_select) _sendButton(MOUSE_RIGHT, right_state); \
+ if (middle_select) _sendButton(MOUSE_MIDDLE, middle_state); \
+ if (up_select) _sendButton(MOUSE_PREV, up_state); \
+ if (down_select) _sendButton(MOUSE_NEXT, down_state); \
+ }
+
+class UsbMouseAbsolute {
public:
- UsbHidMouse() {}
+ UsbMouseAbsolute() {}
void begin() {
- SingleAbsoluteMouse.begin();
+ _mouse.begin();
}
- bool isOnline() {
-# ifdef CHECK_ENDPOINT
- return _checkEndpoint(SingleAbsoluteMouse.getPluggedEndpoint());
-# else
- return true;
-# endif
+ void clear() {
+ _mouse.releaseAll();
}
- void reset() {
- SingleAbsoluteMouse.releaseAll();
+ CLS_SEND_BUTTONS
+
+ void sendMove(int x, int y) {
+ CHECK_HID_EP;
+ _mouse.moveTo(x, y);
}
- void sendButtons(
- bool left_select, bool left_state,
- bool right_select, bool right_state,
- bool middle_select, bool middle_state,
- bool up_select, bool up_state,
- bool down_select, bool down_state
- ) {
- if (left_select) _sendButton(MOUSE_LEFT, left_state);
- if (right_select) _sendButton(MOUSE_RIGHT, right_state);
- if (middle_select) _sendButton(MOUSE_MIDDLE, middle_state);
- if (up_select) _sendButton(MOUSE_PREV, up_state);
- if (down_select) _sendButton(MOUSE_NEXT, down_state);
+ void sendWheel(int delta_y) {
+ // delta_x is not supported by hid-project now
+ CHECK_HID_EP;
+ _mouse.move(0, 0, delta_y);
}
- void sendMove(int x, int y) {
+ CLS_GET_OFFLINE_AS(_mouse)
+
+ private:
+ SingleAbsoluteMouse_ _mouse;
+
+ void _sendButton(uint8_t button, bool state) {
CHECK_HID_EP;
- SingleAbsoluteMouse.moveTo(x, y);
+ if (state) _mouse.press(button);
+ else _mouse.release(button);
}
+};
- void sendWheel(int delta_y) {
+class UsbMouseRelative {
+ public:
+ UsbMouseRelative() {}
+
+ void begin() {
+ _mouse.begin();
+ }
+
+ void clear() {
+ _mouse.releaseAll();
+ }
+
+ CLS_SEND_BUTTONS
+
+ void sendRelative(int x, int y) {
CHECK_HID_EP;
+ _mouse.move(x, y, 0);
+ }
+
+ void sendWheel(int delta_y) {
// delta_x is not supported by hid-project now
- SingleAbsoluteMouse.move(0, 0, delta_y);
+ CHECK_HID_EP;
+ _mouse.move(0, 0, delta_y);
}
+ CLS_GET_OFFLINE_AS(_mouse)
+
private:
+ BootMouse_ _mouse;
+
void _sendButton(uint8_t button, bool state) {
CHECK_HID_EP;
- if (state) SingleAbsoluteMouse.press(button);
- else SingleAbsoluteMouse.release(button);
+ if (state) _mouse.press(button);
+ else _mouse.release(button);
}
};
+#undef CLS_SEND_BUTTONS
+#undef CLS_GET_OFFLINE_AS
#undef CHECK_HID_EP