add keyboard interface (#95)

This commit is contained in:
tomaszduda23 2022-07-10 04:43:54 +09:00 committed by GitHub
parent 793edf8203
commit 38fae01cc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 75 deletions

View File

@ -25,18 +25,21 @@
namespace DRIVERS {
enum type {
USB_MOUSE_ABSOLUTE,
USB_MOUSE_RELATIVE,
USB_MOUSE_ABSOLUTE_WIN98,
};
enum type {
DUMMY = 0,
USB_MOUSE_ABSOLUTE,
USB_MOUSE_RELATIVE,
USB_MOUSE_ABSOLUTE_WIN98,
USB_KEYBOARD,
PS2_KEYBOARD,
};
class Driver {
public:
Driver(type _type) : _type(_type) {}
uint8_t getType() { return _type; }
class Driver {
public:
Driver(type _type) : _type(_type) {}
uint8_t getType() { return _type; }
private:
type _type;
};
private:
type _type;
};
}

View File

@ -26,9 +26,41 @@
namespace DRIVERS {
typedef struct {
bool caps;
bool scroll;
bool num;
} KeyboardLedsState;
typedef struct {
bool caps;
bool scroll;
bool num;
} KeyboardLedsState;
struct Keyboard : public Driver {
using Driver::Driver;
virtual void begin() {}
/**
* Release all keys
*/
virtual void clear() {}
/**
* Sends key
* @param code ???
* @param state true pressed, false released
*/
virtual void sendKey(uint8_t code, bool state) {}
virtual void periodic() {}
/**
* False if online or unknown. Otherwise true.
*/
virtual bool isOffline() { return false; }
virtual KeyboardLedsState getLeds() {
KeyboardLedsState result = {};
return result;
}
};
}

View File

@ -26,7 +26,7 @@
namespace DRIVERS {
class Mouse : public Driver {
using Driver::Driver;
};
class Mouse : public Driver {
using Driver::Driver;
};
}

View File

@ -49,11 +49,10 @@
// -----------------------------------------------------------------------------
static UsbKeyboard *_usb_kbd = NULL;
static UsbMouseAbsolute *_usb_mouse_abs = NULL;
static UsbMouseRelative *_usb_mouse_rel = NULL;
static Ps2Keyboard *_ps2_kbd = NULL;
static DRIVERS::Keyboard *_kbd = nullptr;
#ifdef HID_DYNAMIC
static bool _reset_required = false;
@ -114,11 +113,12 @@ static void _initOutputs() {
uint8_t kbd = outputs & PROTO::OUTPUTS1::KEYBOARD::MASK;
switch (kbd) {
# ifdef HID_WITH_USB
case PROTO::OUTPUTS1::KEYBOARD::USB: _usb_kbd = new UsbKeyboard(); break;
case PROTO::OUTPUTS1::KEYBOARD::USB: _kbd = new UsbKeyboard(); break;
# endif
# ifdef HID_WITH_PS2
case PROTO::OUTPUTS1::KEYBOARD::PS2: _ps2_kbd = new Ps2Keyboard(); break;
case PROTO::OUTPUTS1::KEYBOARD::PS2: _kbd = new Ps2Keyboard(); break;
# endif
default: _kbd = new DRIVERS::Keyboard(DRIVERS::DUMMY); break;
}
uint8_t mouse = outputs & PROTO::OUTPUTS1::MOUSE::MASK;
@ -136,14 +136,7 @@ static void _initOutputs() {
USBDevice.attach();
switch (kbd) {
# ifdef HID_WITH_USB
case PROTO::OUTPUTS1::KEYBOARD::USB: _usb_kbd->begin(); break;
# endif
# ifdef HID_WITH_PS2
case PROTO::OUTPUTS1::KEYBOARD::PS2: _ps2_kbd->begin(); break;
# endif
}
_kbd->begin();
switch (mouse) {
# ifdef HID_WITH_USB
@ -181,9 +174,7 @@ static void _cmdSetConnected(const uint8_t *data) { // 1 byte
}
static void _cmdClearHid(const uint8_t *_) { // 0 bytes
if (_usb_kbd) {
_usb_kbd->clear();
}
_kbd->clear();
if (_usb_mouse_abs) {
_usb_mouse_abs->clear();
} else if (_usb_mouse_rel) {
@ -192,11 +183,7 @@ static void _cmdClearHid(const uint8_t *_) { // 0 bytes
}
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]);
}
_kbd->sendKey(data[0], data[1]);
}
static void _cmdMouseButtonEvent(const uint8_t *data) { // 2 bytes
@ -287,20 +274,21 @@ static void _sendResponse(uint8_t code) {
}
response[2] = PROTO::OUTPUTS1::DYNAMIC;
# endif
if (_usb_kbd) {
response[1] |= (_usb_kbd->isOffline() ? PROTO::PONG::KEYBOARD_OFFLINE : 0);
KeyboardLedsState leds = _usb_kbd->getLeds();
if (DRIVERS::DUMMY != _kbd->getType()) {
response[1] |= (_kbd->isOffline() ? PROTO::PONG::KEYBOARD_OFFLINE : 0);
KeyboardLedsState leds = _kbd->getLeds();
response[1] |= (leds.caps ? PROTO::PONG::CAPS : 0);
response[1] |= (leds.num ? PROTO::PONG::NUM : 0);
response[1] |= (leds.scroll ? PROTO::PONG::SCROLL : 0);
response[2] |= PROTO::OUTPUTS1::KEYBOARD::USB;
} else if (_ps2_kbd) {
response[1] |= (_ps2_kbd->isOffline() ? PROTO::PONG::KEYBOARD_OFFLINE : 0);
KeyboardLedsState leds = _usb_kbd->getLeds();
response[1] |= (leds.caps ? PROTO::PONG::CAPS : 0);
response[1] |= (leds.num ? PROTO::PONG::NUM : 0);
response[1] |= (leds.scroll ? PROTO::PONG::SCROLL : 0);
response[2] |= PROTO::OUTPUTS1::KEYBOARD::PS2;
switch (_kbd->getType())
{
case DRIVERS::USB_KEYBOARD:
response[2] |= PROTO::OUTPUTS1::KEYBOARD::USB;
break;
case DRIVERS::PS2_KEYBOARD:
response[2] |= PROTO::OUTPUTS1::KEYBOARD::PS2;
break;
}
}
if (_usb_mouse_abs) {
response[1] |= _usb_mouse_abs->isOffline() ? PROTO::PONG::MOUSE_OFFLINE : 0;
@ -363,16 +351,7 @@ int main() {
aumProxyUsbVbus();
# endif
# ifdef HID_WITH_USB
if (_usb_kbd) {
_usb_kbd->periodic();
}
# endif
# ifdef HID_WITH_PS2
if (_ps2_kbd) {
_ps2_kbd->periodic();
}
# endif
_kbd->periodic();
# ifdef CMD_SERIAL
if (CMD_SERIAL.available() > 0) {

View File

@ -32,21 +32,21 @@
// #define HID_PS2_KBD_DATA_PIN 5
class Ps2Keyboard {
class Ps2Keyboard : public DRIVERS::Keyboard {
// https://wiki.osdev.org/PS/2_Keyboard
public:
Ps2Keyboard() : _dev(HID_PS2_KBD_CLOCK_PIN, HID_PS2_KBD_DATA_PIN) {}
Ps2Keyboard() : DRIVERS::Keyboard(DRIVERS::PS2_KEYBOARD), _dev(HID_PS2_KBD_CLOCK_PIN, HID_PS2_KBD_DATA_PIN) {}
void begin() {
void begin() override {
_dev.keyboard_init();
}
void periodic() {
void periodic() override {
_dev.keyboard_handle(&_leds);
}
void sendKey(uint8_t code, bool state) {
void sendKey(uint8_t code, bool state) override {
Ps2KeyType ps2_type;
uint8_t ps2_code;
@ -75,11 +75,11 @@ class Ps2Keyboard {
}
}
bool isOffline() {
bool isOffline() override {
return false;
}
KeyboardLedsState getLeds() {
KeyboardLedsState getLeds() override {
periodic();
KeyboardLedsState result = {
.caps = _leds & 0b00000100,

View File

@ -69,15 +69,15 @@ using namespace DRIVERS;
#endif
class UsbKeyboard {
class UsbKeyboard : public DRIVERS::Keyboard {
public:
UsbKeyboard() {}
UsbKeyboard() : DRIVERS::Keyboard(DRIVERS::USB_KEYBOARD) {}
void begin() {
void begin() override {
_kbd.begin();
}
void periodic() {
void periodic() override {
# ifdef HID_USB_CHECK_ENDPOINT
static unsigned long prev_ts = 0;
if (is_micros_timed_out(prev_ts, 50000)) {
@ -92,11 +92,11 @@ class UsbKeyboard {
# endif
}
void clear() {
void clear() override {
_kbd.releaseAll();
}
void sendKey(uint8_t code, bool state) {
void sendKey(uint8_t code, bool state) override {
KeyboardKeycode usb_code = keymapUsb(code);
if (usb_code != KEY_ERROR_UNDEFINED) {
if (state ? _kbd.add(usb_code) : _kbd.remove(usb_code)) {
@ -107,7 +107,7 @@ class UsbKeyboard {
CLS_IS_OFFLINE(_kbd)
KeyboardLedsState getLeds() {
KeyboardLedsState getLeds() override {
uint8_t leds = _kbd.getLeds();
KeyboardLedsState result = {
.caps = leds & LED_CAPS_LOCK,