mirror of
https://github.com/ravinrabbid/DonCon2040.git
synced 2024-11-20 03:37:07 +01:00
Add Keyboard Mode
This commit is contained in:
parent
75bcf4dd96
commit
c1b410d120
@ -17,6 +17,7 @@ The firmware is pretty much tailored to this specific use case, if you are looki
|
||||
- Dualshock 3
|
||||
- Switch Pro Controller
|
||||
- XInput
|
||||
- Keyboard
|
||||
- MIDI
|
||||
- Debug mode (will output current state via USB serial)
|
||||
- Additional buttons via external i2c GPIO expander
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef _USB_HID_DRIVER_H_
|
||||
#define _USB_HID_DRIVER_H_
|
||||
|
||||
#include "usb/hid_keyboard_driver.h"
|
||||
#include "usb/hid_ps3_driver.h"
|
||||
#include "usb/hid_ps4_driver.h"
|
||||
#include "usb/hid_switch_driver.h"
|
||||
|
34
include/usb/hid_keyboard_driver.h
Normal file
34
include/usb/hid_keyboard_driver.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef _USB_HID_KEYBOARD_DRIVER_H_
|
||||
#define _USB_HID_KEYBOARD_DRIVER_H_
|
||||
|
||||
#include "usb/usb_driver.h"
|
||||
|
||||
#include "device/usbd_pvt.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define USBD_KEYBOARD_NAME "Keyboard Mode"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct __attribute((packed, aligned(1))) {
|
||||
uint8_t keycodes[32];
|
||||
} hid_nkro_keyboard_report_t;
|
||||
|
||||
extern const tusb_desc_device_t keyboard_desc_device;
|
||||
extern const uint8_t keyboard_desc_cfg[];
|
||||
extern const uint8_t keyboard_desc_hid_report[];
|
||||
|
||||
bool send_hid_keyboard_report(usb_report_t report);
|
||||
uint16_t hid_keyboard_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
||||
uint16_t reqlen);
|
||||
void hid_keyboard_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
||||
uint16_t bufsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _USB_HID_KEYBOARD_DRIVER_H_
|
@ -20,6 +20,7 @@ typedef enum {
|
||||
USB_MODE_DUALSHOCK3,
|
||||
USB_MODE_PS4_TATACON,
|
||||
USB_MODE_DUALSHOCK4,
|
||||
USB_MODE_KEYBOARD,
|
||||
USB_MODE_XBOX360,
|
||||
USB_MODE_MIDI,
|
||||
USB_MODE_DEBUG,
|
||||
@ -34,6 +35,7 @@ enum {
|
||||
USBD_STR_SWITCH,
|
||||
USBD_STR_PS3,
|
||||
USBD_STR_PS4,
|
||||
USBD_STR_KEYBOARD,
|
||||
USBD_STR_XINPUT,
|
||||
USBD_STR_MIDI,
|
||||
USBD_STR_RPI_RESET,
|
||||
|
@ -45,6 +45,7 @@ struct InputState {
|
||||
hid_switch_report_t m_switch_report;
|
||||
hid_ps3_report_t m_ps3_report;
|
||||
hid_ps4_report_t m_ps4_report;
|
||||
hid_nkro_keyboard_report_t m_keyboard_report;
|
||||
xinput_report_t m_xinput_report;
|
||||
midi_report_t m_midi_report;
|
||||
std::string m_debug_report;
|
||||
@ -52,6 +53,7 @@ struct InputState {
|
||||
usb_report_t getSwitchReport();
|
||||
usb_report_t getPS3InputReport();
|
||||
usb_report_t getPS4InputReport();
|
||||
usb_report_t getKeyboardReport();
|
||||
usb_report_t getXinputReport();
|
||||
usb_report_t getMidiReport();
|
||||
usb_report_t getDebugReport();
|
||||
|
@ -65,6 +65,7 @@ class Menu {
|
||||
ChangeUsbModeDS3,
|
||||
ChangeUsbModePS4Tatacon,
|
||||
ChangeUsbModeDS4,
|
||||
ChangeUsbModeKeyboard,
|
||||
ChangeUsbModeXbox360,
|
||||
ChangeUsbModeMidi,
|
||||
ChangeUsbModeDebug,
|
||||
|
@ -40,6 +40,8 @@ static std::string modeToString(usb_mode_t mode) {
|
||||
return "PS4 Tatacon";
|
||||
case USB_MODE_DUALSHOCK4:
|
||||
return "Dualshock 4";
|
||||
case USB_MODE_KEYBOARD:
|
||||
return "Keyboard";
|
||||
case USB_MODE_XBOX360:
|
||||
return "Xbox 360";
|
||||
case USB_MODE_MIDI:
|
||||
|
@ -16,6 +16,8 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
|
||||
case USB_MODE_PS4_TATACON:
|
||||
case USB_MODE_DUALSHOCK4:
|
||||
return hid_ps4_get_report_cb(itf, report_id, report_type, buffer, reqlen);
|
||||
case USB_MODE_KEYBOARD:
|
||||
return hid_keyboard_get_report_cb(itf, report_id, report_type, buffer, reqlen);
|
||||
default:
|
||||
}
|
||||
|
||||
@ -36,6 +38,9 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
|
||||
case USB_MODE_DUALSHOCK4:
|
||||
hid_ps4_set_report_cb(itf, report_id, report_type, buffer, bufsize);
|
||||
break;
|
||||
case USB_MODE_KEYBOARD:
|
||||
hid_keyboard_set_report_cb(itf, report_id, report_type, buffer, bufsize);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
89
src/usb/hid_keyboard_driver.c
Normal file
89
src/usb/hid_keyboard_driver.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include "usb/hid_keyboard_driver.h"
|
||||
#include "usb/usb_driver.h"
|
||||
|
||||
#include "class/hid/hid_device.h"
|
||||
#include "pico/unique_id.h"
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
const tusb_desc_device_t keyboard_desc_device = {
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = 0x0200,
|
||||
.bDeviceClass = TUSB_CLASS_UNSPECIFIED,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
.idVendor = 0x1209,
|
||||
.idProduct = 0x3901,
|
||||
.bcdDevice = 0x0100,
|
||||
.iManufacturer = USBD_STR_MANUFACTURER,
|
||||
.iProduct = USBD_STR_PRODUCT,
|
||||
.iSerialNumber = USBD_STR_SERIAL,
|
||||
.bNumConfigurations = 0x01,
|
||||
};
|
||||
|
||||
enum {
|
||||
USBD_ITF_HID,
|
||||
USBD_ITF_MAX,
|
||||
};
|
||||
|
||||
const uint8_t keyboard_desc_hid_report[] = {
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x06, // Usage (Keyboard)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x01, // Report ID (1)
|
||||
0x05, 0x07, // Usage Page (Kbrd/Keypad)
|
||||
0x19, 0x00, // Usage Minimum (0x00)
|
||||
0x2A, 0xFF, 0x00, // Usage Maximum (0xFF)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x96, 0x00, 0x01, // Report Count (256)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
};
|
||||
|
||||
#define USBD_KEYBOARD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN)
|
||||
uint8_t const keyboard_desc_cfg[] = {
|
||||
TUD_CONFIG_DESCRIPTOR(0x01, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_KEYBOARD_DESC_LEN,
|
||||
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MAX),
|
||||
TUD_HID_DESCRIPTOR(USBD_ITF_HID, USBD_STR_KEYBOARD, HID_ITF_PROTOCOL_KEYBOARD, sizeof(keyboard_desc_hid_report),
|
||||
0x81, CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||
};
|
||||
|
||||
static hid_keyboard_report_t last_report = {};
|
||||
|
||||
bool send_hid_keyboard_report(usb_report_t report) {
|
||||
bool result = false;
|
||||
|
||||
if (tud_hid_ready()) {
|
||||
result = tud_hid_report(0x01, report.data, report.size);
|
||||
}
|
||||
|
||||
memcpy(&last_report, report.data, tu_min16(report.size, sizeof(hid_nkro_keyboard_report_t)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t hid_keyboard_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
||||
uint16_t reqlen) {
|
||||
(void)itf;
|
||||
(void)report_id;
|
||||
(void)reqlen;
|
||||
|
||||
if (report_type == HID_REPORT_TYPE_INPUT) {
|
||||
memcpy(buffer, &last_report, sizeof(hid_keyboard_report_t));
|
||||
return sizeof(hid_keyboard_report_t);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hid_keyboard_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
||||
uint16_t bufsize) {
|
||||
(void)itf;
|
||||
(void)report_id;
|
||||
(void)report_type;
|
||||
(void)buffer;
|
||||
(void)bufsize;
|
||||
}
|
@ -26,6 +26,7 @@ char *const usbd_desc_str[] = {
|
||||
[USBD_STR_SWITCH] = USBD_SWITCH_NAME, //
|
||||
[USBD_STR_PS3] = USBD_PS3_NAME, //
|
||||
[USBD_STR_PS4] = USBD_PS4_NAME, //
|
||||
[USBD_STR_KEYBOARD] = USBD_KEYBOARD_NAME, //
|
||||
[USBD_STR_XINPUT] = USBD_XINPUT_NAME, //
|
||||
[USBD_STR_MIDI] = USBD_MIDI_NAME, //
|
||||
[USBD_STR_CDC] = USBD_DEBUG_CDC_NAME, //
|
||||
@ -76,6 +77,14 @@ void usb_driver_init(usb_mode_t mode) {
|
||||
usbd_send_report = send_hid_ps4_report;
|
||||
usbd_receive_report = NULL;
|
||||
break;
|
||||
case USB_MODE_KEYBOARD:
|
||||
usbd_desc_device = &keyboard_desc_device;
|
||||
usbd_desc_cfg = keyboard_desc_cfg;
|
||||
usbd_desc_hid_report = keyboard_desc_hid_report;
|
||||
usbd_app_driver = &hid_app_driver;
|
||||
usbd_send_report = send_hid_keyboard_report;
|
||||
usbd_receive_report = NULL;
|
||||
break;
|
||||
case USB_MODE_XBOX360:
|
||||
usbd_desc_device = &xinput_desc_device;
|
||||
usbd_desc_cfg = xinput_desc_cfg;
|
||||
|
@ -9,7 +9,7 @@ InputState::InputState()
|
||||
: drum({{false, 0}, {false, 0}, {false, 0}, {false, 0}}),
|
||||
controller(
|
||||
{{false, false, false, false}, {false, false, false, false, false, false, false, false, false, false}}),
|
||||
m_switch_report({}), m_ps3_report({}), m_ps4_report({}),
|
||||
m_switch_report({}), m_ps3_report({}), m_ps4_report({}), m_keyboard_report({}),
|
||||
m_xinput_report({0x00, sizeof(xinput_report_t), 0, 0, 0, 0, 0, 0, 0, 0, {}}),
|
||||
m_midi_report({{false, false, false, false}, {0, 0, 0, 0}}) {}
|
||||
|
||||
@ -23,6 +23,8 @@ usb_report_t InputState::getReport(usb_mode_t mode) {
|
||||
case USB_MODE_PS4_TATACON:
|
||||
case USB_MODE_DUALSHOCK4:
|
||||
return getPS4InputReport();
|
||||
case USB_MODE_KEYBOARD:
|
||||
return getKeyboardReport();
|
||||
case USB_MODE_XBOX360:
|
||||
return getXinputReport();
|
||||
case USB_MODE_MIDI:
|
||||
@ -173,7 +175,7 @@ usb_report_t InputState::getPS4InputReport() {
|
||||
m_ps4_report.battery = 0 | (1 << 4) | 11; // Cable connected and fully charged
|
||||
m_ps4_report.peripheral = 0x01;
|
||||
m_ps4_report.touch_report_count = 0;
|
||||
|
||||
|
||||
// This method actually gets called more often than the report is sent,
|
||||
// so counters are not consecutive ... let's see if this turns out to
|
||||
// be a problem.
|
||||
@ -185,6 +187,41 @@ usb_report_t InputState::getPS4InputReport() {
|
||||
return {(uint8_t *)&m_ps4_report, sizeof(hid_ps4_report_t)};
|
||||
}
|
||||
|
||||
usb_report_t InputState::getKeyboardReport() {
|
||||
m_keyboard_report = {.keycodes = {0}};
|
||||
|
||||
auto set_key = [&](const bool input, const uint8_t keycode) {
|
||||
if (input) {
|
||||
m_keyboard_report.keycodes[keycode / 8] |= 1 << (keycode % 8);
|
||||
}
|
||||
};
|
||||
|
||||
set_key(drum.ka_left.triggered, HID_KEY_D);
|
||||
set_key(drum.don_left.triggered, HID_KEY_F);
|
||||
set_key(drum.don_right.triggered, HID_KEY_J);
|
||||
set_key(drum.ka_right.triggered, HID_KEY_K);
|
||||
|
||||
set_key(controller.dpad.up, HID_KEY_ARROW_UP);
|
||||
set_key(controller.dpad.down, HID_KEY_ARROW_DOWN);
|
||||
set_key(controller.dpad.left, HID_KEY_ARROW_LEFT);
|
||||
set_key(controller.dpad.right, HID_KEY_ARROW_RIGHT);
|
||||
|
||||
set_key(controller.buttons.north, HID_KEY_L);
|
||||
set_key(controller.buttons.east, HID_KEY_BACKSPACE);
|
||||
set_key(controller.buttons.south, HID_KEY_ENTER);
|
||||
set_key(controller.buttons.west, HID_KEY_P);
|
||||
|
||||
set_key(controller.buttons.l, HID_KEY_Q);
|
||||
set_key(controller.buttons.r, HID_KEY_E);
|
||||
|
||||
set_key(controller.buttons.start, HID_KEY_ESCAPE);
|
||||
set_key(controller.buttons.select, HID_KEY_TAB);
|
||||
// set_key(controller.buttons.home, );
|
||||
// set_key(controller.buttons.share, );
|
||||
|
||||
return {(uint8_t *)&m_keyboard_report, sizeof(hid_nkro_keyboard_report_t)};
|
||||
}
|
||||
|
||||
usb_report_t InputState::getXinputReport() {
|
||||
m_xinput_report.buttons1 = 0 //
|
||||
| (controller.dpad.up ? (1 << 0) : 0) // Dpad Up
|
||||
|
@ -9,7 +9,7 @@ const std::map<Menu::Page, const Menu::Descriptor> Menu::descriptors = {
|
||||
{{"Mode", Menu::Descriptor::Action::GotoPageDeviceMode}, //
|
||||
{"Brightness", Menu::Descriptor::Action::GotoPageLedBrightness}, //
|
||||
{"Sensitvty", Menu::Descriptor::Action::GotoPageTriggerThreshold}, //
|
||||
{"DebnceDly", Menu::Descriptor::Action::GotoPageDebounceDelay}, //
|
||||
{"DebnceDly", Menu::Descriptor::Action::GotoPageDebounceDelay}, //
|
||||
{"Reset", Menu::Descriptor::Action::GotoPageReset}, //
|
||||
{"BOOTSEL", Menu::Descriptor::Action::GotoPageBootsel}}, //
|
||||
0}}, //
|
||||
@ -22,6 +22,7 @@ const std::map<Menu::Page, const Menu::Descriptor> Menu::descriptors = {
|
||||
{"Dualshock3", Menu::Descriptor::Action::ChangeUsbModeDS3}, //
|
||||
{"PS4 Tata", Menu::Descriptor::Action::ChangeUsbModePS4Tatacon}, //
|
||||
{"Dualshock4", Menu::Descriptor::Action::ChangeUsbModeDS4}, //
|
||||
{"Keyboard", Menu::Descriptor::Action::ChangeUsbModeKeyboard}, //
|
||||
{"Xbox 360", Menu::Descriptor::Action::ChangeUsbModeXbox360}, //
|
||||
{"MIDI", Menu::Descriptor::Action::ChangeUsbModeMidi}, //
|
||||
{"Debug", Menu::Descriptor::Action::ChangeUsbModeDebug}}, //
|
||||
@ -286,6 +287,10 @@ void Menu::performSelectionAction(Menu::Descriptor::Action action) {
|
||||
m_store->setUsbMode(USB_MODE_DUALSHOCK4);
|
||||
gotoParent();
|
||||
break;
|
||||
case Descriptor::Action::ChangeUsbModeKeyboard:
|
||||
m_store->setUsbMode(USB_MODE_KEYBOARD);
|
||||
gotoParent();
|
||||
break;
|
||||
case Descriptor::Action::ChangeUsbModeXbox360:
|
||||
m_store->setUsbMode(USB_MODE_XBOX360);
|
||||
gotoParent();
|
||||
|
Loading…
Reference in New Issue
Block a user