Switch to just a 16-button gamepad

This commit is contained in:
Justin C. Miller
2025-04-06 14:02:31 -07:00
parent c422864bc2
commit 7b1b4b916a
3 changed files with 25 additions and 52 deletions

View File

@@ -7,7 +7,6 @@
extern "C" {
// TinyUSB Callbacks
void tud_hid_report_complete_cb(uint8_t, uint8_t const*, uint16_t);
uint16_t tud_hid_get_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t*, uint16_t);
void tud_hid_set_report_cb(uint8_t, uint8_t, hid_report_type_t, uint8_t const*, uint16_t);
}
@@ -18,40 +17,6 @@ namespace hid {
static callback set_report_callback = nullptr;
void send_report(descriptor desc, uint32_t btn)
{
// skip if hid is not ready yet
if ( !tud_hid_ready() ) return;
switch(desc)
{
case descriptor::gamepad: {
// use to avoid send multiple consecutive zero report for keyboard
static bool has_gamepad_key = false;
hid_gamepad_report_t report = {
.x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0,
.hat = 0, .buttons = 0
};
if ( btn ) {
report.hat = GAMEPAD_HAT_UP;
report.buttons = GAMEPAD_BUTTON_A;
tud_hid_report(static_cast<uint8_t>(desc), &report, sizeof(report));
has_gamepad_key = true;
} else {
report.hat = GAMEPAD_HAT_CENTERED;
report.buttons = 0;
if (has_gamepad_key) tud_hid_report(static_cast<uint8_t>(desc), &report, sizeof(report));
has_gamepad_key = false;
}
}
break;
default: break;
}
}
void init(callback cb)
{
set_report_callback = cb;
@@ -59,6 +24,9 @@ void init(callback cb)
void task(uint32_t inputs)
{
// skip if hid is not ready yet
if ( !tud_hid_ready() ) return;
// Remote wakeup if host is suspended. Requires host
// to have enabled REMOTE_WAKEUP feature for this device.
if (tud_suspended() && inputs) {
@@ -66,25 +34,12 @@ void task(uint32_t inputs)
return;
}
send_report(descriptor::gamepad, inputs);
uint16_t report = inputs;
tud_hid_report(static_cast<uint8_t>(descriptor::gamepad), &report, sizeof(report));
}
} // namespace hid
// Invoked when sent REPORT successfully to host
// Application can use this to send the next report
// Note: For composite reports, report[0] is report ID
void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len)
{
(void) instance;
(void) len;
auto next_report_id = descriptor(report[0] + 1u);
if (next_report_id < descriptor::_count) {
hid::send_report(next_report_id, board_button_read());
}
}
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request

View File

@@ -57,7 +57,7 @@ void irq_handler(unsigned pin, uint32_t events) {
bool hid_update_callback(repeating_timer *timer) {
uint32_t buttons = 0;
for (unsigned i = 0; i < button_group_count; ++i)
buttons |= uint32_t(button_states[i]) << (i*8);
buttons |= uint32_t(button_states[i]) << (i*buttons_per_group);
blink::task();
hid::task(buttons);

View File

@@ -60,7 +60,25 @@ uint8_t const * tud_descriptor_device_cb(void) {
//--------------------------------------------------------------------+
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(static_cast<uint8_t>(descriptor::gamepad)) )
//TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(static_cast<uint8_t>(descriptor::gamepad)) )
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ),
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ),
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),
HID_REPORT_ID ( uint8_t(descriptor::gamepad) )
/* 16 bit Button Map */
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ),
HID_USAGE_MIN ( 1 ),
HID_USAGE_MAX ( 16 ),
HID_LOGICAL_MIN ( 0 ),
HID_LOGICAL_MAX ( 1 ),
HID_REPORT_COUNT ( 16 ),
HID_REPORT_SIZE ( 1 ),
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),
HID_COLLECTION_END
};
// Invoked when received GET HID REPORT DESCRIPTOR