mirror of
https://github.com/ravinrabbid/DonCon2040.git
synced 2024-11-20 03:37:07 +01:00
Refactor USB drivers
This commit is contained in:
parent
fc15457cbf
commit
55c9966b88
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,5 @@
|
|||||||
.vscode/
|
.vscode/
|
||||||
build/
|
build/
|
||||||
|
research/
|
||||||
research
|
|
||||||
|
|
||||||
*.pio.h
|
*.pio.h
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef _PERIPHERALS_DISPLAY_H_
|
#ifndef _PERIPHERALS_DISPLAY_H_
|
||||||
#define _PERIPHERALS_DISPLAY_H_
|
#define _PERIPHERALS_DISPLAY_H_
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
#include "utils/InputState.h"
|
#include "utils/InputState.h"
|
||||||
#include "utils/Menu.h"
|
#include "utils/Menu.h"
|
||||||
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#ifndef _USB_DEBUG_DRIVER_H_
|
|
||||||
#define _USB_DEBUG_DRIVER_H_
|
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define USBD_DEBUG_CDC_NAME "Serial Debug"
|
|
||||||
#define USBD_DEBUG_RESET_NAME "Picotool Reset"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool send_debug_report(usb_report_t report);
|
|
||||||
|
|
||||||
extern const tusb_desc_device_t debug_desc_device;
|
|
||||||
extern const uint8_t debug_desc_cfg[];
|
|
||||||
extern const usbd_class_driver_t debug_app_driver;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _USB_DEBUG_DRIVER_H_
|
|
16
include/usb/device/hid/common.h
Normal file
16
include/usb/device/hid/common.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _USB_DEVICE_HID_COMMON_H_
|
||||||
|
#define _USB_DEVICE_HID_COMMON_H_
|
||||||
|
|
||||||
|
#include "device/usbd_pvt.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const usbd_class_driver_t hid_app_driver;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _USB_DEVICE_HID_COMMON_H_
|
@ -1,14 +1,12 @@
|
|||||||
#ifndef _USB_HID_KEYBOARD_DRIVER_H_
|
#ifndef _USB_DEVICE_HID_KEYBOARD_DRIVER_H_
|
||||||
#define _USB_HID_KEYBOARD_DRIVER_H_
|
#define _USB_DEVICE_HID_KEYBOARD_DRIVER_H_
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define USBD_KEYBOARD_NAME "Keyboard Mode"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -17,11 +15,10 @@ typedef struct __attribute((packed, aligned(1))) {
|
|||||||
uint8_t keycodes[32];
|
uint8_t keycodes[32];
|
||||||
} hid_nkro_keyboard_report_t;
|
} hid_nkro_keyboard_report_t;
|
||||||
|
|
||||||
extern const tusb_desc_device_t keyboard_desc_device;
|
extern const usbd_driver_t hid_keyboard_device_driver;
|
||||||
extern const uint8_t keyboard_desc_cfg[];
|
|
||||||
extern const uint8_t keyboard_desc_hid_report[];
|
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 hid_keyboard_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
||||||
uint16_t reqlen);
|
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,
|
void hid_keyboard_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
||||||
@ -31,4 +28,4 @@ void hid_keyboard_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _USB_HID_KEYBOARD_DRIVER_H_
|
#endif // _USB_DEVICE_HID_KEYBOARD_DRIVER_H_
|
@ -1,14 +1,12 @@
|
|||||||
#ifndef _USB_HID_PS3_DRIVER_H_
|
#ifndef _USB_DEVICE_HID_PS3_DRIVER_H_
|
||||||
#define _USB_HID_PS3_DRIVER_H_
|
#define _USB_DEVICE_HID_PS3_DRIVER_H_
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define USBD_PS3_NAME "Dualshock3 Emulation"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -40,11 +38,10 @@ typedef struct __attribute((packed, aligned(1))) {
|
|||||||
uint8_t unknown_0x02_2;
|
uint8_t unknown_0x02_2;
|
||||||
} hid_ps3_report_t;
|
} hid_ps3_report_t;
|
||||||
|
|
||||||
extern const tusb_desc_device_t ds3_desc_device;
|
extern const usbd_driver_t hid_ds3_device_driver;
|
||||||
extern const uint8_t ps3_desc_cfg[];
|
|
||||||
extern const uint8_t ps3_desc_hid_report[];
|
extern const uint8_t ps3_desc_hid_report[];
|
||||||
|
|
||||||
bool send_hid_ps3_report(usb_report_t report);
|
|
||||||
uint16_t hid_ps3_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
uint16_t hid_ps3_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
||||||
uint16_t reqlen);
|
uint16_t reqlen);
|
||||||
void hid_ps3_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
void hid_ps3_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
||||||
@ -54,4 +51,4 @@ void hid_ps3_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _USB_HID_PS3_DRIVER_H_
|
#endif // _USB_DEVICE_HID_PS3_DRIVER_H_
|
@ -1,14 +1,12 @@
|
|||||||
#ifndef _USB_HID_PS4_DRIVER_H_
|
#ifndef _USB_DEVICE_HID_PS4_DRIVER_H_
|
||||||
#define _USB_HID_PS4_DRIVER_H_
|
#define _USB_DEVICE_HID_PS4_DRIVER_H_
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define USBD_PS4_NAME "Dualshock4 Emulation"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -44,12 +42,11 @@ typedef struct __attribute((packed, aligned(1))) {
|
|||||||
uint8_t _reserved3[3];
|
uint8_t _reserved3[3];
|
||||||
} hid_ps4_report_t;
|
} hid_ps4_report_t;
|
||||||
|
|
||||||
extern const tusb_desc_device_t ps4_tatacon_desc_device;
|
extern const usbd_driver_t hid_ds4_device_driver;
|
||||||
extern const tusb_desc_device_t ds4_desc_device;
|
extern const usbd_driver_t hid_ps4_tatacon_device_driver;
|
||||||
extern const uint8_t ps4_desc_cfg[];
|
|
||||||
extern const uint8_t ps4_desc_hid_report[];
|
extern const uint8_t ps4_desc_hid_report[];
|
||||||
|
|
||||||
bool send_hid_ps4_report(usb_report_t report);
|
|
||||||
uint16_t hid_ps4_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
uint16_t hid_ps4_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
||||||
uint16_t reqlen);
|
uint16_t reqlen);
|
||||||
void hid_ps4_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
void hid_ps4_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
||||||
@ -59,4 +56,4 @@ void hid_ps4_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _USB_HID_PS4_DRIVER_H_
|
#endif // _USB_DEVICE_HID_PS4_DRIVER_H_
|
@ -1,14 +1,12 @@
|
|||||||
#ifndef _USB_HID_SWITCH_DRIVER_H_
|
#ifndef _USB_DEVICE_HID_SWITCH_DRIVER_H_
|
||||||
#define _USB_HID_SWITCH_DRIVER_H_
|
#define _USB_DEVICE_HID_SWITCH_DRIVER_H_
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define USBD_SWITCH_NAME "Switch Horipad Emulation"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -23,12 +21,11 @@ typedef struct __attribute((packed, aligned(1))) {
|
|||||||
uint8_t vendor;
|
uint8_t vendor;
|
||||||
} hid_switch_report_t;
|
} hid_switch_report_t;
|
||||||
|
|
||||||
extern const tusb_desc_device_t switch_tatacon_desc_device;
|
extern const usbd_driver_t hid_switch_horipad_device_driver;
|
||||||
extern const tusb_desc_device_t switch_horipad_desc_device;
|
extern const usbd_driver_t hid_switch_tatacon_device_driver;
|
||||||
extern const uint8_t switch_desc_cfg[];
|
|
||||||
extern const uint8_t switch_desc_hid_report[];
|
extern const uint8_t switch_desc_hid_report[];
|
||||||
|
|
||||||
bool send_hid_switch_report(usb_report_t report);
|
|
||||||
uint16_t hid_switch_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
uint16_t hid_switch_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
||||||
uint16_t reqlen);
|
uint16_t reqlen);
|
||||||
void hid_switch_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
void hid_switch_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
||||||
@ -38,4 +35,4 @@ void hid_switch_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _USB_HID_SWITCH_DRIVER_H_
|
#endif // _USB_DEVICE_HID_SWITCH_DRIVER_H_
|
@ -1,14 +1,10 @@
|
|||||||
#ifndef _USB_MIDI_DRIVER_H_
|
#ifndef _USB_DEVICE_MIDI_DRIVER_H_
|
||||||
#define _USB_MIDI_DRIVER_H_
|
#define _USB_DEVICE_MIDI_DRIVER_H_
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define USBD_MIDI_NAME "MIDI Controller"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -29,15 +25,10 @@ typedef struct __attribute((packed, aligned(1))) {
|
|||||||
} velocity;
|
} velocity;
|
||||||
} midi_report_t;
|
} midi_report_t;
|
||||||
|
|
||||||
bool receive_midi_report(void);
|
extern const usbd_driver_t midi_device_driver;
|
||||||
bool send_midi_report(usb_report_t report);
|
|
||||||
|
|
||||||
extern const tusb_desc_device_t midi_desc_device;
|
|
||||||
extern const uint8_t midi_desc_cfg[];
|
|
||||||
extern const usbd_class_driver_t midi_app_driver;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _USB_MIDI_DRIVER_H_
|
#endif // _USB_DEVICE_MIDI_DRIVER_H_
|
12
include/usb/device/vendor/common.h
vendored
Normal file
12
include/usb/device/vendor/common.h
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _USB_DEVICE_VENDOR_COMMON_H_
|
||||||
|
#define _USB_DEVICE_VENDOR_COMMON_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _USB_DEVICE_VENDOR_COMMON_H_
|
20
include/usb/device/vendor/debug_driver.h
vendored
Normal file
20
include/usb/device/vendor/debug_driver.h
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _USB_DEVICE_VENDOR_DEBUG_DRIVER_H_
|
||||||
|
#define _USB_DEVICE_VENDOR_DEBUG_DRIVER_H_
|
||||||
|
|
||||||
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const usbd_driver_t debug_device_driver;
|
||||||
|
|
||||||
|
bool debug_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _USB_DEVICE_VENDOR_DEBUG_DRIVER_H_
|
36
include/usb/device/vendor/xinput_driver.h
vendored
Normal file
36
include/usb/device/vendor/xinput_driver.h
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _USB_DEVICE_VENDOR_XINPUT_DRIVER_H_
|
||||||
|
#define _USB_DEVICE_VENDOR_XINPUT_DRIVER_H_
|
||||||
|
|
||||||
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct __attribute((packed, aligned(1))) {
|
||||||
|
uint8_t report_id;
|
||||||
|
uint8_t report_size;
|
||||||
|
uint8_t buttons1;
|
||||||
|
uint8_t buttons2;
|
||||||
|
uint8_t lt;
|
||||||
|
uint8_t rt;
|
||||||
|
int16_t lx;
|
||||||
|
int16_t ly;
|
||||||
|
int16_t rx;
|
||||||
|
int16_t ry;
|
||||||
|
uint8_t _reserved[6];
|
||||||
|
} xinput_report_t;
|
||||||
|
|
||||||
|
extern const usbd_driver_t xinput_device_driver;
|
||||||
|
|
||||||
|
bool xinput_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _USB_DEVICE_VENDOR_XINPUT_DRIVER_H_
|
@ -1,12 +1,12 @@
|
|||||||
#ifndef _USB_USB_DRIVER_H_
|
#ifndef _USB_DEVICE_DRIVER_H_
|
||||||
#define _USB_USB_DRIVER_H_
|
#define _USB_DEVICE_DRIVER_H_
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "device/usbd_pvt.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define USBD_MANUFACTURER "DonCon"
|
#define USBD_MANUFACTURER "DonCon2040"
|
||||||
#define USBD_PRODUCT "DonCon rev1"
|
#define USBD_PRODUCT_BASE "Taiko Controller"
|
||||||
|
|
||||||
#define USBD_MAX_POWER_MAX (500)
|
#define USBD_MAX_POWER_MAX (500)
|
||||||
|
|
||||||
@ -34,14 +34,6 @@ enum {
|
|||||||
USBD_STR_MANUFACTURER,
|
USBD_STR_MANUFACTURER,
|
||||||
USBD_STR_PRODUCT,
|
USBD_STR_PRODUCT,
|
||||||
USBD_STR_SERIAL,
|
USBD_STR_SERIAL,
|
||||||
USBD_STR_CDC,
|
|
||||||
USBD_STR_SWITCH,
|
|
||||||
USBD_STR_PS3,
|
|
||||||
USBD_STR_PS4,
|
|
||||||
USBD_STR_KEYBOARD,
|
|
||||||
USBD_STR_XINPUT,
|
|
||||||
USBD_STR_MIDI,
|
|
||||||
USBD_STR_RPI_RESET,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -49,6 +41,18 @@ typedef struct {
|
|||||||
uint16_t size;
|
uint16_t size;
|
||||||
} usb_report_t;
|
} usb_report_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
const usbd_class_driver_t *app_driver;
|
||||||
|
// Descriptors
|
||||||
|
const tusb_desc_device_t *desc_device;
|
||||||
|
const uint8_t *desc_cfg;
|
||||||
|
const uint8_t *desc_hid_report;
|
||||||
|
const uint8_t *desc_bos;
|
||||||
|
// Callbacks
|
||||||
|
bool (*send_report)(usb_report_t report);
|
||||||
|
} usbd_driver_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
USB_PLAYER_LED_ID,
|
USB_PLAYER_LED_ID,
|
||||||
USB_PLAYER_LED_COLOR,
|
USB_PLAYER_LED_COLOR,
|
||||||
@ -70,18 +74,18 @@ extern char *const usbd_desc_str[];
|
|||||||
|
|
||||||
typedef void (*usbd_player_led_cb_t)(usb_player_led_t);
|
typedef void (*usbd_player_led_cb_t)(usb_player_led_t);
|
||||||
|
|
||||||
void usb_driver_init(usb_mode_t mode);
|
void usbd_driver_init(usb_mode_t mode);
|
||||||
void usb_driver_task();
|
void usbd_driver_task();
|
||||||
|
|
||||||
usb_mode_t usb_driver_get_mode();
|
usb_mode_t usbd_driver_get_mode();
|
||||||
|
|
||||||
void usb_driver_send_and_receive_report(usb_report_t report);
|
void usbd_driver_send_report(usb_report_t report);
|
||||||
|
|
||||||
void usb_driver_set_player_led_cb(usbd_player_led_cb_t cb);
|
void usbd_driver_set_player_led_cb(usbd_player_led_cb_t cb);
|
||||||
usbd_player_led_cb_t usb_driver_get_player_led_cb();
|
usbd_player_led_cb_t usbd_driver_get_player_led_cb();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _USB_USB_DRIVER_H_
|
#endif // _USB_DEVICE_DRIVER_H_
|
@ -1,22 +0,0 @@
|
|||||||
#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"
|
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const usbd_class_driver_t hid_app_driver;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _USB_HID_DRIVER_H_
|
|
@ -1,41 +0,0 @@
|
|||||||
#ifndef _USB_XINPUT_DRIVER_H_
|
|
||||||
#define _USB_XINPUT_DRIVER_H_
|
|
||||||
|
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define USBD_XINPUT_NAME "XInput Gamepad"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct __attribute((packed, aligned(1))) {
|
|
||||||
uint8_t report_id;
|
|
||||||
uint8_t report_size;
|
|
||||||
uint8_t buttons1;
|
|
||||||
uint8_t buttons2;
|
|
||||||
uint8_t lt;
|
|
||||||
uint8_t rt;
|
|
||||||
int16_t lx;
|
|
||||||
int16_t ly;
|
|
||||||
int16_t rx;
|
|
||||||
int16_t ry;
|
|
||||||
uint8_t _reserved[6];
|
|
||||||
} xinput_report_t;
|
|
||||||
|
|
||||||
bool receive_xinput_report(void);
|
|
||||||
bool send_xinput_report(usb_report_t report);
|
|
||||||
|
|
||||||
extern const tusb_desc_device_t xinput_desc_device;
|
|
||||||
extern const uint8_t xinput_desc_cfg[];
|
|
||||||
extern const usbd_class_driver_t xinput_app_driver;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _USB_XINPUT_DRIVER_H_
|
|
@ -1,10 +1,13 @@
|
|||||||
#ifndef _UTILS_INPUTSTATE_H_
|
#ifndef _UTILS_INPUTSTATE_H_
|
||||||
#define _UTILS_INPUTSTATE_H_
|
#define _UTILS_INPUTSTATE_H_
|
||||||
|
|
||||||
#include "usb/hid_driver.h"
|
#include "usb/device/hid/keyboard_driver.h"
|
||||||
#include "usb/midi_driver.h"
|
#include "usb/device/hid/ps3_driver.h"
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device/hid/ps4_driver.h"
|
||||||
#include "usb/xinput_driver.h"
|
#include "usb/device/hid/switch_driver.h"
|
||||||
|
#include "usb/device/midi_driver.h"
|
||||||
|
#include "usb/device/vendor/xinput_driver.h"
|
||||||
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define _UTILS_SETTINGSSTORE_H_
|
#define _UTILS_SETTINGSSTORE_H_
|
||||||
|
|
||||||
#include "peripherals/Drum.h"
|
#include "peripherals/Drum.h"
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include "hardware/flash.h"
|
#include "hardware/flash.h"
|
||||||
|
|
||||||
|
30
src/main.cpp
30
src/main.cpp
@ -2,7 +2,7 @@
|
|||||||
#include "peripherals/Display.h"
|
#include "peripherals/Display.h"
|
||||||
#include "peripherals/Drum.h"
|
#include "peripherals/Drum.h"
|
||||||
#include "peripherals/StatusLed.h"
|
#include "peripherals/StatusLed.h"
|
||||||
#include "usb/usb_driver.h"
|
#include "usb/device_driver.h"
|
||||||
#include "utils/Menu.h"
|
#include "utils/Menu.h"
|
||||||
#include "utils/SettingsStore.h"
|
#include "utils/SettingsStore.h"
|
||||||
|
|
||||||
@ -34,13 +34,15 @@ struct ControlMessage {
|
|||||||
union {
|
union {
|
||||||
usb_mode_t usb_mode;
|
usb_mode_t usb_mode;
|
||||||
usb_player_led_t player_led;
|
usb_player_led_t player_led;
|
||||||
uint8_t brightness;
|
uint8_t led_brightness;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
void core1_task() {
|
void core1_task() {
|
||||||
multicore_lockout_victim_init();
|
multicore_lockout_victim_init();
|
||||||
|
|
||||||
|
// Init i2c port here because Controller and Display share it and
|
||||||
|
// therefore can't init it themself.
|
||||||
gpio_set_function(Config::Default::i2c_config.sda_pin, GPIO_FUNC_I2C);
|
gpio_set_function(Config::Default::i2c_config.sda_pin, GPIO_FUNC_I2C);
|
||||||
gpio_set_function(Config::Default::i2c_config.scl_pin, GPIO_FUNC_I2C);
|
gpio_set_function(Config::Default::i2c_config.scl_pin, GPIO_FUNC_I2C);
|
||||||
gpio_pull_up(Config::Default::i2c_config.sda_pin);
|
gpio_pull_up(Config::Default::i2c_config.sda_pin);
|
||||||
@ -77,7 +79,7 @@ void core1_task() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ControlCommand::SetLedBrightness:
|
case ControlCommand::SetLedBrightness:
|
||||||
led.setBrightness(control_msg.data.brightness);
|
led.setBrightness(control_msg.data.led_brightness);
|
||||||
break;
|
break;
|
||||||
case ControlCommand::EnterMenu:
|
case ControlCommand::EnterMenu:
|
||||||
display.showMenu();
|
display.showMenu();
|
||||||
@ -104,18 +106,20 @@ int main() {
|
|||||||
queue_init(&menu_display_queue, sizeof(Utils::Menu::State), 1);
|
queue_init(&menu_display_queue, sizeof(Utils::Menu::State), 1);
|
||||||
queue_init(&drum_input_queue, sizeof(Utils::InputState::Drum), 1);
|
queue_init(&drum_input_queue, sizeof(Utils::InputState::Drum), 1);
|
||||||
queue_init(&controller_input_queue, sizeof(Utils::InputState::Controller), 1);
|
queue_init(&controller_input_queue, sizeof(Utils::InputState::Controller), 1);
|
||||||
multicore_launch_core1(core1_task);
|
|
||||||
|
|
||||||
Utils::InputState input_state;
|
Utils::InputState input_state;
|
||||||
|
|
||||||
auto settings_store = std::make_shared<Utils::SettingsStore>();
|
auto settings_store = std::make_shared<Utils::SettingsStore>();
|
||||||
Utils::Menu menu(settings_store);
|
Utils::Menu menu(settings_store);
|
||||||
|
|
||||||
|
auto mode = settings_store->getUsbMode();
|
||||||
|
|
||||||
Peripherals::Drum drum(Config::Default::drum_config);
|
Peripherals::Drum drum(Config::Default::drum_config);
|
||||||
|
|
||||||
auto mode = settings_store->getUsbMode();
|
multicore_launch_core1(core1_task);
|
||||||
usb_driver_init(mode);
|
|
||||||
usb_driver_set_player_led_cb([](usb_player_led_t player_led) {
|
usbd_driver_init(mode);
|
||||||
|
usbd_driver_set_player_led_cb([](usb_player_led_t player_led) {
|
||||||
auto ctrl_message = ControlMessage{ControlCommand::SetPlayerLed, {.player_led = player_led}};
|
auto ctrl_message = ControlMessage{ControlCommand::SetPlayerLed, {.player_led = player_led}};
|
||||||
queue_add_blocking(&control_queue, &ctrl_message);
|
queue_add_blocking(&control_queue, &ctrl_message);
|
||||||
});
|
});
|
||||||
@ -128,7 +132,7 @@ int main() {
|
|||||||
ctrl_message = {ControlCommand::SetUsbMode, {.usb_mode = mode}};
|
ctrl_message = {ControlCommand::SetUsbMode, {.usb_mode = mode}};
|
||||||
queue_add_blocking(&control_queue, &ctrl_message);
|
queue_add_blocking(&control_queue, &ctrl_message);
|
||||||
|
|
||||||
ctrl_message = {ControlCommand::SetLedBrightness, {.brightness = settings_store->getLedBrightness()}};
|
ctrl_message = {ControlCommand::SetLedBrightness, {.led_brightness = settings_store->getLedBrightness()}};
|
||||||
queue_add_blocking(&control_queue, &ctrl_message);
|
queue_add_blocking(&control_queue, &ctrl_message);
|
||||||
|
|
||||||
drum.setDebounceDelay(settings_store->getDebounceDelay());
|
drum.setDebounceDelay(settings_store->getDebounceDelay());
|
||||||
@ -154,21 +158,19 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readSettings();
|
readSettings();
|
||||||
|
input_state.releaseAll();
|
||||||
|
|
||||||
} else if (input_state.checkHotkey()) {
|
} else if (input_state.checkHotkey()) {
|
||||||
menu.activate();
|
menu.activate();
|
||||||
|
|
||||||
input_state.releaseAll();
|
|
||||||
usb_driver_send_and_receive_report(input_state.getReport(mode));
|
|
||||||
|
|
||||||
ControlMessage ctrl_message{ControlCommand::EnterMenu, {}};
|
ControlMessage ctrl_message{ControlCommand::EnterMenu, {}};
|
||||||
queue_add_blocking(&control_queue, &ctrl_message);
|
queue_add_blocking(&control_queue, &ctrl_message);
|
||||||
} else {
|
|
||||||
usb_driver_send_and_receive_report(input_state.getReport(mode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_driver_task();
|
usbd_driver_send_report(input_state.getReport(mode));
|
||||||
|
usbd_driver_task();
|
||||||
|
|
||||||
|
// TODO don't send whole input_state
|
||||||
queue_try_add(&drum_input_queue, &input_state);
|
queue_try_add(&drum_input_queue, &input_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
#include "usb/hid_driver.h"
|
#include "usb/device/hid/common.h"
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
#include "usb/device/hid/keyboard_driver.h"
|
||||||
|
#include "usb/device/hid/ps3_driver.h"
|
||||||
|
#include "usb/device/hid/ps4_driver.h"
|
||||||
|
#include "usb/device/hid/switch_driver.h"
|
||||||
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
#include "class/hid/hid_device.h"
|
#include "class/hid/hid_device.h"
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer,
|
||||||
uint16_t reqlen) {
|
uint16_t reqlen) {
|
||||||
switch (usb_driver_get_mode()) {
|
switch (usbd_driver_get_mode()) {
|
||||||
case USB_MODE_SWITCH_TATACON:
|
case USB_MODE_SWITCH_TATACON:
|
||||||
case USB_MODE_SWITCH_HORIPAD:
|
case USB_MODE_SWITCH_HORIPAD:
|
||||||
return hid_switch_get_report_cb(itf, report_id, report_type, buffer, reqlen);
|
return hid_switch_get_report_cb(itf, report_id, report_type, buffer, reqlen);
|
||||||
@ -27,7 +31,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
|
|||||||
|
|
||||||
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer,
|
||||||
uint16_t bufsize) {
|
uint16_t bufsize) {
|
||||||
switch (usb_driver_get_mode()) {
|
switch (usbd_driver_get_mode()) {
|
||||||
case USB_MODE_SWITCH_TATACON:
|
case USB_MODE_SWITCH_TATACON:
|
||||||
case USB_MODE_SWITCH_HORIPAD:
|
case USB_MODE_SWITCH_HORIPAD:
|
||||||
hid_switch_set_report_cb(itf, report_id, report_type, buffer, bufsize);
|
hid_switch_set_report_cb(itf, report_id, report_type, buffer, bufsize);
|
||||||
@ -59,6 +63,27 @@ bool hid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
|
||||||
|
(void)itf;
|
||||||
|
|
||||||
|
switch (usbd_driver_get_mode()) {
|
||||||
|
case USB_MODE_SWITCH_TATACON:
|
||||||
|
case USB_MODE_SWITCH_HORIPAD:
|
||||||
|
return switch_desc_hid_report;
|
||||||
|
case USB_MODE_DUALSHOCK3:
|
||||||
|
return ps3_desc_hid_report;
|
||||||
|
case USB_MODE_PS4_TATACON:
|
||||||
|
case USB_MODE_DUALSHOCK4:
|
||||||
|
return ps4_desc_hid_report;
|
||||||
|
case USB_MODE_KEYBOARD_P1:
|
||||||
|
case USB_MODE_KEYBOARD_P2:
|
||||||
|
return keyboard_desc_hid_report;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const usbd_class_driver_t hid_app_driver = {
|
const usbd_class_driver_t hid_app_driver = {
|
||||||
#if CFG_TUSB_DEBUG >= 2
|
#if CFG_TUSB_DEBUG >= 2
|
||||||
.name = "HID",
|
.name = "HID",
|
@ -1,8 +1,6 @@
|
|||||||
#include "usb/hid_keyboard_driver.h"
|
#include "usb/device/hid/keyboard_driver.h"
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
|
||||||
#include "class/hid/hid_device.h"
|
#include "usb/device/hid/common.h"
|
||||||
#include "pico/unique_id.h"
|
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
@ -48,8 +46,8 @@ const uint8_t keyboard_desc_hid_report[] = {
|
|||||||
uint8_t const keyboard_desc_cfg[] = {
|
uint8_t const keyboard_desc_cfg[] = {
|
||||||
TUD_CONFIG_DESCRIPTOR(0x01, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_KEYBOARD_DESC_LEN,
|
TUD_CONFIG_DESCRIPTOR(0x01, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_KEYBOARD_DESC_LEN,
|
||||||
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MAX),
|
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),
|
TUD_HID_DESCRIPTOR(USBD_ITF_HID, 0, HID_ITF_PROTOCOL_KEYBOARD, sizeof(keyboard_desc_hid_report), 0x81,
|
||||||
0x81, CFG_TUD_HID_EP_BUFSIZE, 1),
|
CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
static hid_keyboard_report_t last_report = {};
|
static hid_keyboard_report_t last_report = {};
|
||||||
@ -87,3 +85,12 @@ void hid_keyboard_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_
|
|||||||
(void)buffer;
|
(void)buffer;
|
||||||
(void)bufsize;
|
(void)bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const usbd_driver_t hid_keyboard_device_driver = {
|
||||||
|
.name = "Keyboard",
|
||||||
|
.app_driver = &hid_app_driver,
|
||||||
|
.desc_device = &keyboard_desc_device,
|
||||||
|
.desc_cfg = keyboard_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_hid_keyboard_report,
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
#include "usb/hid_ps3_driver.h"
|
#include "usb/device/hid/ps3_driver.h"
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
#include "usb/device/hid/common.h"
|
||||||
|
|
||||||
#include "class/hid/hid_device.h"
|
|
||||||
#include "pico/unique_id.h"
|
#include "pico/unique_id.h"
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
@ -28,12 +28,6 @@ enum {
|
|||||||
USBD_ITF_MAX,
|
USBD_ITF_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USBD_PS3_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
|
|
||||||
const uint8_t ps3_desc_cfg[] = {
|
|
||||||
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_PS3_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
|
||||||
TUD_HID_INOUT_DESCRIPTOR(USBD_ITF_HID, USBD_STR_PS3, 0, 148, 0x02, 0x81, CFG_TUD_HID_EP_BUFSIZE, 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t ps3_desc_hid_report[] = {
|
const uint8_t ps3_desc_hid_report[] = {
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||||
0x09, 0x04, // Usage (Joystick)
|
0x09, 0x04, // Usage (Joystick)
|
||||||
@ -112,6 +106,12 @@ const uint8_t ps3_desc_hid_report[] = {
|
|||||||
0xC0, // End Collection
|
0xC0, // End Collection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define USBD_PS3_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
|
||||||
|
const uint8_t ps3_desc_cfg[] = {
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_PS3_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
||||||
|
TUD_HID_INOUT_DESCRIPTOR(USBD_ITF_HID, 0, 0, sizeof(ps3_desc_hid_report), 0x02, 0x81, CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||||
|
};
|
||||||
|
|
||||||
static hid_ps3_report_t last_report = {};
|
static hid_ps3_report_t last_report = {};
|
||||||
|
|
||||||
bool send_hid_ps3_report(usb_report_t report) {
|
bool send_hid_ps3_report(usb_report_t report) {
|
||||||
@ -201,9 +201,18 @@ void hid_ps3_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
|
|||||||
| ((report->leds_bitmap & 0x08) ? (1 << 2) : 0) //
|
| ((report->leds_bitmap & 0x08) ? (1 << 2) : 0) //
|
||||||
| ((report->leds_bitmap & 0x10) ? (1 << 3) : 0);
|
| ((report->leds_bitmap & 0x10) ? (1 << 3) : 0);
|
||||||
|
|
||||||
usb_driver_get_player_led_cb()(player_led);
|
usbd_driver_get_player_led_cb()(player_led);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const usbd_driver_t hid_ds3_device_driver = {
|
||||||
|
.name = "DS3",
|
||||||
|
.app_driver = &hid_app_driver,
|
||||||
|
.desc_device = &ds3_desc_device,
|
||||||
|
.desc_cfg = ps3_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_hid_ps3_report,
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
#include "usb/hid_ps4_driver.h"
|
#include "usb/device/hid/ps4_driver.h"
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
#include "usb/device/hid/common.h"
|
||||||
|
|
||||||
#include "class/hid/hid_device.h"
|
|
||||||
#include "pico/unique_id.h"
|
#include "pico/unique_id.h"
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
@ -45,12 +45,6 @@ enum {
|
|||||||
USBD_ITF_MAX,
|
USBD_ITF_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USBD_PS4_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
|
|
||||||
const uint8_t ps4_desc_cfg[] = {
|
|
||||||
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_PS4_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
|
||||||
TUD_HID_INOUT_DESCRIPTOR(USBD_ITF_HID, USBD_STR_PS4, 0, 483, 0x03, 0x84, CFG_TUD_HID_EP_BUFSIZE, 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t ps4_desc_hid_report[] = {
|
const uint8_t ps4_desc_hid_report[] = {
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||||
0x09, 0x05, // Usage (Game Pad)
|
0x09, 0x05, // Usage (Game Pad)
|
||||||
@ -292,6 +286,12 @@ const uint8_t ps4_desc_hid_report[] = {
|
|||||||
0xC0, // End Collection
|
0xC0, // End Collection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define USBD_PS4_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
|
||||||
|
const uint8_t ps4_desc_cfg[] = {
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_PS4_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
||||||
|
TUD_HID_INOUT_DESCRIPTOR(USBD_ITF_HID, 0, 0, sizeof(ps4_desc_hid_report), 0x03, 0x84, CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||||
|
};
|
||||||
|
|
||||||
// MAC Address
|
// MAC Address
|
||||||
static uint8_t ps4_0x81_report[] = {0x39, 0x39, 0x39, 0x68, 0x22, 0x00};
|
static uint8_t ps4_0x81_report[] = {0x39, 0x39, 0x39, 0x68, 0x22, 0x00};
|
||||||
|
|
||||||
@ -404,10 +404,28 @@ void hid_ps4_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
|
|||||||
.red = report->led_red,
|
.red = report->led_red,
|
||||||
.green = report->led_green,
|
.green = report->led_green,
|
||||||
.blue = report->led_blue};
|
.blue = report->led_blue};
|
||||||
usb_driver_get_player_led_cb()(player_led);
|
usbd_driver_get_player_led_cb()(player_led);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const usbd_driver_t hid_ds4_device_driver = {
|
||||||
|
.name = "DS4",
|
||||||
|
.app_driver = &hid_app_driver,
|
||||||
|
.desc_device = &ds4_desc_device,
|
||||||
|
.desc_cfg = ps4_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_hid_ps4_report,
|
||||||
|
};
|
||||||
|
|
||||||
|
const usbd_driver_t hid_ps4_tatacon_device_driver = {
|
||||||
|
.name = "PS4 Tatacon",
|
||||||
|
.app_driver = &hid_app_driver,
|
||||||
|
.desc_device = &ps4_tatacon_desc_device,
|
||||||
|
.desc_cfg = ps4_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_hid_ps4_report,
|
||||||
|
};
|
@ -1,7 +1,6 @@
|
|||||||
#include "usb/hid_switch_driver.h"
|
#include "usb/device/hid/switch_driver.h"
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
|
||||||
#include "class/hid/hid_device.h"
|
#include "usb/device/hid/common.h"
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
@ -44,12 +43,6 @@ enum {
|
|||||||
USBD_ITF_MAX,
|
USBD_ITF_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USBD_SWITCH_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
|
|
||||||
const uint8_t switch_desc_cfg[] = {
|
|
||||||
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_SWITCH_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
|
||||||
TUD_HID_INOUT_DESCRIPTOR(USBD_ITF_HID, USBD_STR_SWITCH, 0, 86, 0x02, 0x81, CFG_TUD_HID_EP_BUFSIZE, 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t switch_desc_hid_report[] = {
|
const uint8_t switch_desc_hid_report[] = {
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||||
0x09, 0x05, // Usage (Game Pad)
|
0x09, 0x05, // Usage (Game Pad)
|
||||||
@ -94,6 +87,12 @@ const uint8_t switch_desc_hid_report[] = {
|
|||||||
0xC0, // End Collection
|
0xC0, // End Collection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define USBD_SWITCH_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
|
||||||
|
const uint8_t switch_desc_cfg[] = {
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_SWITCH_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
||||||
|
TUD_HID_INOUT_DESCRIPTOR(USBD_ITF_HID, 0, 0, sizeof(switch_desc_hid_report), 0x02, 0x81, CFG_TUD_HID_EP_BUFSIZE, 1),
|
||||||
|
};
|
||||||
|
|
||||||
static hid_switch_report_t last_report = {};
|
static hid_switch_report_t last_report = {};
|
||||||
|
|
||||||
bool send_hid_switch_report(usb_report_t report) {
|
bool send_hid_switch_report(usb_report_t report) {
|
||||||
@ -128,3 +127,21 @@ void hid_switch_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
|
|||||||
(void)bufsize;
|
(void)bufsize;
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const usbd_driver_t hid_switch_horipad_device_driver = {
|
||||||
|
.name = "Switch",
|
||||||
|
.app_driver = &hid_app_driver,
|
||||||
|
.desc_device = &switch_horipad_desc_device,
|
||||||
|
.desc_cfg = switch_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_hid_switch_report,
|
||||||
|
};
|
||||||
|
|
||||||
|
const usbd_driver_t hid_switch_tatacon_device_driver = {
|
||||||
|
.name = "Switch Tatacon",
|
||||||
|
.app_driver = &hid_app_driver,
|
||||||
|
.desc_device = &switch_tatacon_desc_device,
|
||||||
|
.desc_cfg = switch_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_hid_switch_report,
|
||||||
|
};
|
@ -1,5 +1,4 @@
|
|||||||
#include "usb/midi_driver.h"
|
#include "usb/device/midi_driver.h"
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
|
||||||
#include "class/midi/midi_device.h"
|
#include "class/midi/midi_device.h"
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ const tusb_desc_device_t midi_desc_device = {
|
|||||||
.bDeviceProtocol = 0x00,
|
.bDeviceProtocol = 0x00,
|
||||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
.idVendor = 0x1209,
|
.idVendor = 0x1209,
|
||||||
.idProduct = 0x3939,
|
.idProduct = 0x3902,
|
||||||
.bcdDevice = 0x0100,
|
.bcdDevice = 0x0100,
|
||||||
.iManufacturer = USBD_STR_MANUFACTURER,
|
.iManufacturer = USBD_STR_MANUFACTURER,
|
||||||
.iProduct = USBD_STR_PRODUCT,
|
.iProduct = USBD_STR_PRODUCT,
|
||||||
@ -40,16 +39,6 @@ const uint8_t midi_desc_cfg[USBD_DESC_LEN] = {
|
|||||||
|
|
||||||
static midi_report_t last_report = {};
|
static midi_report_t last_report = {};
|
||||||
|
|
||||||
bool receive_midi_report(void) {
|
|
||||||
// Read and discard incoming data to avoid blocking the sender
|
|
||||||
uint8_t packet[4];
|
|
||||||
while (tud_midi_available()) {
|
|
||||||
tud_midi_packet_read(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_midi_message(uint8_t status, uint8_t byte1, uint8_t byte2) {
|
static void write_midi_message(uint8_t status, uint8_t byte1, uint8_t byte2) {
|
||||||
uint8_t midi_message[3] = {status, byte1, byte2};
|
uint8_t midi_message[3] = {status, byte1, byte2};
|
||||||
tud_midi_stream_write(0, midi_message, sizeof(midi_message));
|
tud_midi_stream_write(0, midi_message, sizeof(midi_message));
|
||||||
@ -86,7 +75,17 @@ bool send_midi_report(usb_report_t report) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usbd_class_driver_t midi_app_driver = {
|
void tud_midi_rx_cb(uint8_t itf) {
|
||||||
|
(void)itf;
|
||||||
|
|
||||||
|
// Read and discard incoming data to avoid blocking the sender
|
||||||
|
uint8_t packet[4];
|
||||||
|
while (tud_midi_available()) {
|
||||||
|
tud_midi_packet_read(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const usbd_class_driver_t midi_app_driver = {
|
||||||
#if CFG_TUSB_DEBUG >= 2
|
#if CFG_TUSB_DEBUG >= 2
|
||||||
.name = "MIDI",
|
.name = "MIDI",
|
||||||
#endif
|
#endif
|
||||||
@ -96,3 +95,12 @@ const usbd_class_driver_t midi_app_driver = {
|
|||||||
.control_xfer_cb = midid_control_xfer_cb,
|
.control_xfer_cb = midid_control_xfer_cb,
|
||||||
.xfer_cb = midid_xfer_cb,
|
.xfer_cb = midid_xfer_cb,
|
||||||
.sof = NULL};
|
.sof = NULL};
|
||||||
|
|
||||||
|
const usbd_driver_t midi_device_driver = {
|
||||||
|
.name = "MIDI",
|
||||||
|
.app_driver = &midi_app_driver,
|
||||||
|
.desc_device = &midi_desc_device,
|
||||||
|
.desc_cfg = midi_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_midi_report,
|
||||||
|
};
|
22
src/usb/device/vendor/common.c
vendored
Normal file
22
src/usb/device/vendor/common.c
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "usb/device/vendor/common.h"
|
||||||
|
|
||||||
|
#include "usb/device/vendor/debug_driver.h"
|
||||||
|
#include "usb/device/vendor/xinput_driver.h"
|
||||||
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
// Implement TinyUSB internal callback since vendor control requests are not forwarded to custom drivers.
|
||||||
|
bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) {
|
||||||
|
switch (usbd_driver_get_mode()) {
|
||||||
|
case USB_MODE_XBOX360:
|
||||||
|
case USB_MODE_XBOX360_ANALOG_P1:
|
||||||
|
case USB_MODE_XBOX360_ANALOG_P2:
|
||||||
|
return xinput_control_xfer_cb(rhport, stage, request);
|
||||||
|
case USB_MODE_DEBUG:
|
||||||
|
return debug_control_xfer_cb(rhport, stage, request);
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
#include "usb/debug_driver.h"
|
#include "usb/device/vendor/debug_driver.h"
|
||||||
|
|
||||||
#include "device/usbd_pvt.h"
|
#include "device/usbd_pvt.h"
|
||||||
#include "hardware/watchdog.h"
|
#include "hardware/watchdog.h"
|
||||||
@ -45,9 +45,9 @@ enum {
|
|||||||
|
|
||||||
const uint8_t debug_desc_cfg[USBD_DESC_LEN] = {
|
const uint8_t debug_desc_cfg[USBD_DESC_LEN] = {
|
||||||
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
||||||
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD, USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT,
|
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, 0, USBD_CDC_EP_CMD, USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN,
|
||||||
USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
|
USBD_CDC_IN_OUT_MAX_SIZE),
|
||||||
TUD_RPI_RESET_DESCRIPTOR(USBD_ITF_RPI_RESET, USBD_STR_RPI_RESET),
|
TUD_RPI_RESET_DESCRIPTOR(USBD_ITF_RPI_RESET, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TUD_DEBUG_MS_OS_20_DESC_LEN 166
|
#define TUD_DEBUG_MS_OS_20_DESC_LEN 166
|
||||||
@ -147,7 +147,7 @@ static bool debug_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usbd_class_driver_t debug_app_driver = {
|
static usbd_class_driver_t const debug_app_driver = {
|
||||||
#if CFG_TUSB_DEBUG >= 2
|
#if CFG_TUSB_DEBUG >= 2
|
||||||
.name = "DEBUG",
|
.name = "DEBUG",
|
||||||
#endif
|
#endif
|
||||||
@ -158,6 +158,15 @@ const usbd_class_driver_t debug_app_driver = {
|
|||||||
.xfer_cb = debug_xfer_cb,
|
.xfer_cb = debug_xfer_cb,
|
||||||
.sof = NULL};
|
.sof = NULL};
|
||||||
|
|
||||||
|
const usbd_driver_t debug_device_driver = {
|
||||||
|
.name = "Debug",
|
||||||
|
.app_driver = &debug_app_driver,
|
||||||
|
.desc_device = &debug_desc_device,
|
||||||
|
.desc_cfg = debug_desc_cfg,
|
||||||
|
.desc_bos = debug_desc_bos,
|
||||||
|
.send_report = send_debug_report,
|
||||||
|
};
|
||||||
|
|
||||||
// Support for default BOOTSEL reset by changing baud rate
|
// Support for default BOOTSEL reset by changing baud rate
|
||||||
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *p_line_coding) {
|
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *p_line_coding) {
|
||||||
(void)itf;
|
(void)itf;
|
256
src/usb/device/vendor/xinput_driver.c
vendored
Normal file
256
src/usb/device/vendor/xinput_driver.c
vendored
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
#include "usb/device/vendor/xinput_driver.h"
|
||||||
|
|
||||||
|
#include "device/usbd_pvt.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
const tusb_desc_device_t xinput_desc_device = {
|
||||||
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
|
.bcdUSB = 0x0200,
|
||||||
|
.bDeviceClass = TUSB_CLASS_VENDOR_SPECIFIC,
|
||||||
|
.bDeviceSubClass = 0xFF,
|
||||||
|
.bDeviceProtocol = 0xFF,
|
||||||
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
.idVendor = 0x045E,
|
||||||
|
.idProduct = 0x028E,
|
||||||
|
.bcdDevice = 0x0114,
|
||||||
|
.iManufacturer = USBD_STR_MANUFACTURER,
|
||||||
|
.iProduct = USBD_STR_PRODUCT,
|
||||||
|
.iSerialNumber = USBD_STR_SERIAL,
|
||||||
|
.bNumConfigurations = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
USBD_ITF_XINPUT,
|
||||||
|
USBD_ITF_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define XINPUT_INTERFACE_SUBCLASS 0x5D
|
||||||
|
#define XINPUT_INTERFACE_PROTOCOL 0x01
|
||||||
|
#define XINPUT_DESC_VENDOR 0x21
|
||||||
|
|
||||||
|
#define TUD_XINPUT_EP_BUFSIZE 32
|
||||||
|
#define TUD_XINPUT_EP_OUT 0x01
|
||||||
|
#define TUD_XINPUT_EP_IN 0x81
|
||||||
|
|
||||||
|
#define TUD_XINPUT_DESC_LEN (9 + 16 + 7 + 7)
|
||||||
|
|
||||||
|
#define TUD_XINPUT_DESCRIPTOR(_itfnum, _stridx, _epout, _epin, _epsize) \
|
||||||
|
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_VENDOR_SPECIFIC, XINPUT_INTERFACE_SUBCLASS, \
|
||||||
|
XINPUT_INTERFACE_PROTOCOL, _stridx, 16, XINPUT_DESC_VENDOR, 0x10, 0x01, 0x01, 0x24, 0x81, 0x14, 0x03, 0x00, \
|
||||||
|
0x03, 0x13, 0x01, 0x00, 0x03, 0x00, 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), \
|
||||||
|
1, 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), 8
|
||||||
|
|
||||||
|
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_XINPUT_DESC_LEN)
|
||||||
|
|
||||||
|
const uint8_t xinput_desc_cfg[USBD_DESC_LEN] = {
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
||||||
|
TUD_XINPUT_DESCRIPTOR(USBD_ITF_XINPUT, 0, TUD_XINPUT_EP_OUT, TUD_XINPUT_EP_IN, TUD_XINPUT_EP_BUFSIZE),
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct __attribute((packed, aligned(1))) {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t led;
|
||||||
|
uint8_t rumble_strong;
|
||||||
|
uint8_t rumble_light;
|
||||||
|
uint8_t _reserved[3];
|
||||||
|
} hid_xinput_ouput_report_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t itf_num;
|
||||||
|
uint8_t ep_in;
|
||||||
|
uint8_t ep_out;
|
||||||
|
|
||||||
|
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[TUD_XINPUT_EP_BUFSIZE];
|
||||||
|
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[TUD_XINPUT_EP_BUFSIZE];
|
||||||
|
} xinput_interface_t;
|
||||||
|
|
||||||
|
CFG_TUSB_MEM_SECTION static xinput_interface_t _xinput_itf;
|
||||||
|
|
||||||
|
static bool xinput_ready() {
|
||||||
|
uint8_t const ep_in = _xinput_itf.ep_in;
|
||||||
|
|
||||||
|
return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(0, ep_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool send_xinput_report(usb_report_t report) {
|
||||||
|
if (!xinput_ready()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TU_VERIFY(usbd_edpt_claim(0, _xinput_itf.ep_in));
|
||||||
|
|
||||||
|
uint16_t size = tu_min16(report.size, TUD_XINPUT_EP_BUFSIZE);
|
||||||
|
memcpy(_xinput_itf.epin_buf, report.data, size);
|
||||||
|
|
||||||
|
return usbd_edpt_xfer(0, _xinput_itf.ep_in, _xinput_itf.epin_buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool receive_xinput_report(uint8_t const *buf, uint32_t size) {
|
||||||
|
enum {
|
||||||
|
REPORT_RUMBLE = 0x00,
|
||||||
|
REPORT_LED = 0x01,
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
ALL_OFF = 0x00,
|
||||||
|
ALL_BLINK = 0x01,
|
||||||
|
P1_FLASH_ON = 0x02,
|
||||||
|
P2_FLASH_ON = 0x03,
|
||||||
|
P3_FLASH_ON = 0x04,
|
||||||
|
P4_FLASH_ON = 0x05,
|
||||||
|
P1_ON = 0x06,
|
||||||
|
P2_ON = 0x07,
|
||||||
|
P3_ON = 0x08,
|
||||||
|
P4_ON = 0x09,
|
||||||
|
ALL_ROTATE = 0x0A,
|
||||||
|
CURRENT_BLINK = 0x0B,
|
||||||
|
CURRENT_BLINK_SLOW = 0x0C,
|
||||||
|
ALL_ALTERNATE = 0x0D,
|
||||||
|
ALL_SLOW_BLINK = 0x0E,
|
||||||
|
ALL_BLINK_ONCE = 0x0F,
|
||||||
|
};
|
||||||
|
|
||||||
|
hid_xinput_ouput_report_t *report = (hid_xinput_ouput_report_t *)buf;
|
||||||
|
|
||||||
|
switch (report->type) {
|
||||||
|
case REPORT_RUMBLE:
|
||||||
|
// Ignore, we ain't doing that
|
||||||
|
return true;
|
||||||
|
case REPORT_LED: {
|
||||||
|
TU_ASSERT(size >= 3);
|
||||||
|
|
||||||
|
usb_player_led_t player_led = {.type = USB_PLAYER_LED_ID, .id = 0};
|
||||||
|
|
||||||
|
switch (report->led) {
|
||||||
|
case ALL_OFF:
|
||||||
|
player_led.id = 0x00;
|
||||||
|
break;
|
||||||
|
case ALL_ROTATE:
|
||||||
|
case ALL_ALTERNATE:
|
||||||
|
player_led.id = 0x0F;
|
||||||
|
break;
|
||||||
|
case P1_FLASH_ON:
|
||||||
|
case P1_ON:
|
||||||
|
player_led.id = 0x01;
|
||||||
|
break;
|
||||||
|
case P2_FLASH_ON:
|
||||||
|
case P2_ON:
|
||||||
|
player_led.id = 0x02;
|
||||||
|
break;
|
||||||
|
case P3_FLASH_ON:
|
||||||
|
case P3_ON:
|
||||||
|
player_led.id = 0x04;
|
||||||
|
break;
|
||||||
|
case P4_FLASH_ON:
|
||||||
|
case P4_ON:
|
||||||
|
player_led.id = 0x08;
|
||||||
|
break;
|
||||||
|
case ALL_SLOW_BLINK:
|
||||||
|
player_led.id = 0x0F;
|
||||||
|
break;
|
||||||
|
case ALL_BLINK:
|
||||||
|
case CURRENT_BLINK:
|
||||||
|
case CURRENT_BLINK_SLOW:
|
||||||
|
case ALL_BLINK_ONCE:
|
||||||
|
default:
|
||||||
|
player_led.id = 0x00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
usbd_driver_get_player_led_cb()(player_led);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xinput_reset(uint8_t rhport) {
|
||||||
|
(void)rhport;
|
||||||
|
|
||||||
|
tu_memclr(&_xinput_itf, sizeof(_xinput_itf));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xinput_init(void) { xinput_reset(0); }
|
||||||
|
|
||||||
|
static uint16_t xinput_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) {
|
||||||
|
TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0);
|
||||||
|
|
||||||
|
uint16_t const drv_len =
|
||||||
|
(uint16_t)(sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t) + 16);
|
||||||
|
TU_ASSERT(max_len >= drv_len, 0);
|
||||||
|
|
||||||
|
_xinput_itf.itf_num = desc_itf->bInterfaceNumber;
|
||||||
|
|
||||||
|
// Unknown vendor specific descriptor
|
||||||
|
uint8_t const *p_desc = tu_desc_next(desc_itf);
|
||||||
|
TU_ASSERT(p_desc[1] == XINPUT_DESC_VENDOR, 0);
|
||||||
|
|
||||||
|
// Endpoint descriptors
|
||||||
|
p_desc = tu_desc_next(p_desc);
|
||||||
|
TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &_xinput_itf.ep_out,
|
||||||
|
&_xinput_itf.ep_in),
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (_xinput_itf.ep_out) {
|
||||||
|
TU_ASSERT(usbd_edpt_xfer(rhport, _xinput_itf.ep_out, _xinput_itf.epout_buf, sizeof(_xinput_itf.epout_buf)), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return drv_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool xinput_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) {
|
||||||
|
(void)rhport;
|
||||||
|
|
||||||
|
if (stage != CONTROL_STAGE_SETUP)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// This is mainly to suppress a warning from the linux kernel:
|
||||||
|
// https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c#L1756
|
||||||
|
//
|
||||||
|
// Hopefully nobody expects actual data here.
|
||||||
|
if (!(request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR && request->bRequest == 0x01 &&
|
||||||
|
request->wIndex == 0x00)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *dummy_data = calloc(request->wLength, sizeof(uint8_t));
|
||||||
|
bool success = tud_control_xfer(rhport, request, (void *)(uintptr_t)dummy_data, request->wLength);
|
||||||
|
free(dummy_data);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool xinput_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
|
||||||
|
TU_ASSERT(result == XFER_RESULT_SUCCESS);
|
||||||
|
|
||||||
|
if (ep_addr == _xinput_itf.ep_out) {
|
||||||
|
receive_xinput_report(_xinput_itf.epout_buf, xferred_bytes);
|
||||||
|
TU_ASSERT(usbd_edpt_xfer(rhport, _xinput_itf.ep_out, _xinput_itf.epout_buf, sizeof(_xinput_itf.epout_buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const usbd_class_driver_t xinput_app_driver = {
|
||||||
|
#if CFG_TUSB_DEBUG >= 2
|
||||||
|
.name = "XINPUT",
|
||||||
|
#endif
|
||||||
|
.init = xinput_init,
|
||||||
|
.reset = xinput_reset,
|
||||||
|
.open = xinput_open,
|
||||||
|
.control_xfer_cb = xinput_control_xfer_cb,
|
||||||
|
.xfer_cb = xinput_xfer_cb,
|
||||||
|
.sof = NULL};
|
||||||
|
|
||||||
|
const usbd_driver_t xinput_device_driver = {
|
||||||
|
.name = "XInput",
|
||||||
|
.app_driver = &xinput_app_driver,
|
||||||
|
.desc_device = &xinput_desc_device,
|
||||||
|
.desc_cfg = xinput_desc_cfg,
|
||||||
|
.desc_bos = NULL,
|
||||||
|
.send_report = send_xinput_report,
|
||||||
|
};
|
152
src/usb/device_driver.c
Normal file
152
src/usb/device_driver.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include "usb/device_driver.h"
|
||||||
|
|
||||||
|
#include "usb/device/hid/keyboard_driver.h"
|
||||||
|
#include "usb/device/hid/ps3_driver.h"
|
||||||
|
#include "usb/device/hid/ps4_driver.h"
|
||||||
|
#include "usb/device/hid/switch_driver.h"
|
||||||
|
#include "usb/device/midi_driver.h"
|
||||||
|
#include "usb/device/vendor/debug_driver.h"
|
||||||
|
#include "usb/device/vendor/xinput_driver.h"
|
||||||
|
|
||||||
|
#include "bsp/board.h"
|
||||||
|
#include "pico/unique_id.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define DESC_STR_MAX (127)
|
||||||
|
|
||||||
|
static usb_mode_t usbd_mode = USB_MODE_DEBUG;
|
||||||
|
static usbd_driver_t usbd_driver = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||||
|
static usbd_player_led_cb_t usbd_player_led_cb = NULL;
|
||||||
|
|
||||||
|
#define USBD_SERIAL_STR_SIZE (PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1 + 3)
|
||||||
|
static char usbd_serial_str[USBD_SERIAL_STR_SIZE] = {};
|
||||||
|
static char usbd_product_str[DESC_STR_MAX] = {};
|
||||||
|
|
||||||
|
char *const usbd_desc_str[] = {
|
||||||
|
[USBD_STR_MANUFACTURER] = USBD_MANUFACTURER, //
|
||||||
|
[USBD_STR_PRODUCT] = usbd_product_str, //
|
||||||
|
[USBD_STR_SERIAL] = usbd_serial_str, //
|
||||||
|
};
|
||||||
|
|
||||||
|
void usbd_driver_init(usb_mode_t mode) {
|
||||||
|
usbd_mode = mode;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case USB_MODE_SWITCH_TATACON:
|
||||||
|
usbd_driver = hid_switch_tatacon_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_SWITCH_HORIPAD:
|
||||||
|
usbd_driver = hid_switch_horipad_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_DUALSHOCK3:
|
||||||
|
usbd_driver = hid_ds3_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_PS4_TATACON:
|
||||||
|
usbd_driver = hid_ps4_tatacon_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_DUALSHOCK4:
|
||||||
|
usbd_driver = hid_ds4_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_KEYBOARD_P1:
|
||||||
|
case USB_MODE_KEYBOARD_P2:
|
||||||
|
usbd_driver = hid_keyboard_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_XBOX360_ANALOG_P1:
|
||||||
|
case USB_MODE_XBOX360_ANALOG_P2:
|
||||||
|
case USB_MODE_XBOX360:
|
||||||
|
usbd_driver = xinput_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_MIDI:
|
||||||
|
usbd_driver = midi_device_driver;
|
||||||
|
break;
|
||||||
|
case USB_MODE_DEBUG:
|
||||||
|
usbd_driver = debug_device_driver;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tud_init(BOARD_TUD_RHPORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usbd_driver_task() { tud_task(); }
|
||||||
|
|
||||||
|
usb_mode_t usbd_driver_get_mode() { return usbd_mode; }
|
||||||
|
|
||||||
|
void usbd_driver_send_report(usb_report_t report) {
|
||||||
|
static const uint64_t interval_us = 900;
|
||||||
|
static uint64_t start_us = 0;
|
||||||
|
|
||||||
|
if (to_us_since_boot(get_absolute_time()) - start_us <= interval_us) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
start_us += interval_us;
|
||||||
|
|
||||||
|
if (tud_suspended()) {
|
||||||
|
tud_remote_wakeup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usbd_driver.send_report) {
|
||||||
|
usbd_driver.send_report(report);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void usbd_driver_set_player_led_cb(usbd_player_led_cb_t cb) { usbd_player_led_cb = cb; };
|
||||||
|
usbd_player_led_cb_t usbd_driver_get_player_led_cb() { return usbd_player_led_cb; };
|
||||||
|
|
||||||
|
const uint8_t *tud_descriptor_device_cb(void) { return (const uint8_t *)usbd_driver.desc_device; }
|
||||||
|
|
||||||
|
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
|
||||||
|
(void)index;
|
||||||
|
|
||||||
|
return usbd_driver.desc_cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||||
|
(void)langid;
|
||||||
|
|
||||||
|
static uint16_t desc_str[DESC_STR_MAX];
|
||||||
|
|
||||||
|
// Assign the SN using the unique flash id
|
||||||
|
if (!usbd_serial_str[0]) {
|
||||||
|
pico_get_unique_board_id_string(usbd_serial_str, sizeof(usbd_serial_str));
|
||||||
|
usbd_serial_str[USBD_SERIAL_STR_SIZE - 4] = '-';
|
||||||
|
usbd_serial_str[USBD_SERIAL_STR_SIZE - 3] = '0' + ((usbd_mode / 10) % 10);
|
||||||
|
usbd_serial_str[USBD_SERIAL_STR_SIZE - 2] = '0' + (usbd_mode % 10);
|
||||||
|
usbd_serial_str[USBD_SERIAL_STR_SIZE - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usbd_product_str[0]) {
|
||||||
|
strcpy(usbd_product_str, USBD_PRODUCT_BASE);
|
||||||
|
strcat(usbd_product_str, " (");
|
||||||
|
strcat(usbd_product_str, usbd_driver.name);
|
||||||
|
strcat(usbd_product_str, ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t len;
|
||||||
|
if (index == USBD_STR_LANGUAGE) {
|
||||||
|
desc_str[1] = 0x0409; // Supported language is English
|
||||||
|
len = 1;
|
||||||
|
} else {
|
||||||
|
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
const char *str = usbd_desc_str[index];
|
||||||
|
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
|
||||||
|
desc_str[1 + len] = str[len];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// first byte is length (including header), second byte is string type
|
||||||
|
desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * len + 2));
|
||||||
|
|
||||||
|
return desc_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t const *tud_descriptor_bos_cb(void) { return usbd_driver.desc_bos; }
|
||||||
|
|
||||||
|
// Implement callback to add our custom driver
|
||||||
|
const usbd_class_driver_t *usbd_app_driver_get_cb(uint8_t *driver_count) {
|
||||||
|
*driver_count = 1;
|
||||||
|
return usbd_driver.app_driver;
|
||||||
|
}
|
@ -1,196 +0,0 @@
|
|||||||
#include "usb/usb_driver.h"
|
|
||||||
#include "usb/debug_driver.h"
|
|
||||||
#include "usb/hid_driver.h"
|
|
||||||
#include "usb/midi_driver.h"
|
|
||||||
#include "usb/xinput_driver.h"
|
|
||||||
|
|
||||||
#include "bsp/board.h"
|
|
||||||
#include "pico/unique_id.h"
|
|
||||||
|
|
||||||
static usb_mode_t usbd_mode = USB_MODE_DEBUG;
|
|
||||||
static usbd_player_led_cb_t usbd_player_led_cb = NULL;
|
|
||||||
static const tusb_desc_device_t *usbd_desc_device = NULL;
|
|
||||||
static const uint8_t *usbd_desc_cfg = NULL;
|
|
||||||
static const uint8_t *usbd_desc_hid_report = NULL;
|
|
||||||
static const usbd_class_driver_t *usbd_app_driver = NULL;
|
|
||||||
static bool (*usbd_send_report)(usb_report_t report) = NULL;
|
|
||||||
static bool (*usbd_receive_report)() = NULL;
|
|
||||||
|
|
||||||
#define USBD_SERIAL_STR_SIZE (PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1 + 3)
|
|
||||||
static char usbd_serial_str[USBD_SERIAL_STR_SIZE] = {};
|
|
||||||
|
|
||||||
char *const usbd_desc_str[] = {
|
|
||||||
[USBD_STR_MANUFACTURER] = USBD_MANUFACTURER, //
|
|
||||||
[USBD_STR_PRODUCT] = USBD_PRODUCT, //
|
|
||||||
[USBD_STR_SERIAL] = usbd_serial_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, //
|
|
||||||
[USBD_STR_RPI_RESET] = USBD_DEBUG_RESET_NAME, //
|
|
||||||
};
|
|
||||||
|
|
||||||
void usb_driver_init(usb_mode_t mode) {
|
|
||||||
usbd_mode = mode;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case USB_MODE_SWITCH_TATACON:
|
|
||||||
usbd_desc_device = &switch_tatacon_desc_device;
|
|
||||||
usbd_desc_cfg = switch_desc_cfg;
|
|
||||||
usbd_desc_hid_report = switch_desc_hid_report;
|
|
||||||
usbd_app_driver = &hid_app_driver;
|
|
||||||
usbd_send_report = send_hid_switch_report;
|
|
||||||
usbd_receive_report = NULL;
|
|
||||||
break;
|
|
||||||
case USB_MODE_SWITCH_HORIPAD:
|
|
||||||
usbd_desc_device = &switch_horipad_desc_device;
|
|
||||||
usbd_desc_cfg = switch_desc_cfg;
|
|
||||||
usbd_desc_hid_report = switch_desc_hid_report;
|
|
||||||
usbd_app_driver = &hid_app_driver;
|
|
||||||
usbd_send_report = send_hid_switch_report;
|
|
||||||
usbd_receive_report = NULL;
|
|
||||||
break;
|
|
||||||
case USB_MODE_DUALSHOCK3:
|
|
||||||
usbd_desc_device = &ds3_desc_device;
|
|
||||||
usbd_desc_cfg = ps3_desc_cfg;
|
|
||||||
usbd_desc_hid_report = ps3_desc_hid_report;
|
|
||||||
usbd_app_driver = &hid_app_driver;
|
|
||||||
usbd_send_report = send_hid_ps3_report;
|
|
||||||
usbd_receive_report = NULL;
|
|
||||||
break;
|
|
||||||
case USB_MODE_PS4_TATACON:
|
|
||||||
usbd_desc_device = &ps4_tatacon_desc_device;
|
|
||||||
usbd_desc_cfg = ps4_desc_cfg;
|
|
||||||
usbd_desc_hid_report = ps4_desc_hid_report;
|
|
||||||
usbd_app_driver = &hid_app_driver;
|
|
||||||
usbd_send_report = send_hid_ps4_report;
|
|
||||||
usbd_receive_report = NULL;
|
|
||||||
break;
|
|
||||||
case USB_MODE_DUALSHOCK4:
|
|
||||||
usbd_desc_device = &ds4_desc_device;
|
|
||||||
usbd_desc_cfg = ps4_desc_cfg;
|
|
||||||
usbd_desc_hid_report = ps4_desc_hid_report;
|
|
||||||
usbd_app_driver = &hid_app_driver;
|
|
||||||
usbd_send_report = send_hid_ps4_report;
|
|
||||||
usbd_receive_report = NULL;
|
|
||||||
break;
|
|
||||||
case USB_MODE_KEYBOARD_P1:
|
|
||||||
case USB_MODE_KEYBOARD_P2:
|
|
||||||
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_ANALOG_P1:
|
|
||||||
case USB_MODE_XBOX360_ANALOG_P2:
|
|
||||||
case USB_MODE_XBOX360:
|
|
||||||
usbd_desc_device = &xinput_desc_device;
|
|
||||||
usbd_desc_cfg = xinput_desc_cfg;
|
|
||||||
usbd_app_driver = &xinput_app_driver;
|
|
||||||
usbd_send_report = send_xinput_report;
|
|
||||||
usbd_receive_report = receive_xinput_report;
|
|
||||||
break;
|
|
||||||
case USB_MODE_MIDI:
|
|
||||||
usbd_desc_device = &midi_desc_device;
|
|
||||||
usbd_desc_cfg = midi_desc_cfg;
|
|
||||||
usbd_app_driver = &midi_app_driver;
|
|
||||||
usbd_send_report = send_midi_report;
|
|
||||||
usbd_receive_report = receive_midi_report;
|
|
||||||
break;
|
|
||||||
case USB_MODE_DEBUG:
|
|
||||||
usbd_desc_device = &debug_desc_device;
|
|
||||||
usbd_desc_cfg = debug_desc_cfg;
|
|
||||||
usbd_app_driver = &debug_app_driver;
|
|
||||||
usbd_send_report = send_debug_report;
|
|
||||||
usbd_receive_report = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tusb_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void usb_driver_task() { tud_task(); }
|
|
||||||
|
|
||||||
usb_mode_t usb_driver_get_mode() { return usbd_mode; }
|
|
||||||
|
|
||||||
void usb_driver_send_and_receive_report(usb_report_t report) {
|
|
||||||
static const uint32_t interval_ms = 1;
|
|
||||||
static uint32_t start_ms = 0;
|
|
||||||
|
|
||||||
if (board_millis() - start_ms < interval_ms) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
start_ms += interval_ms;
|
|
||||||
|
|
||||||
if (tud_suspended()) {
|
|
||||||
tud_remote_wakeup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usbd_send_report) {
|
|
||||||
usbd_send_report(report);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usbd_receive_report) {
|
|
||||||
usbd_receive_report();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void usb_driver_set_player_led_cb(usbd_player_led_cb_t cb) { usbd_player_led_cb = cb; };
|
|
||||||
|
|
||||||
usbd_player_led_cb_t usb_driver_get_player_led_cb() { return usbd_player_led_cb; };
|
|
||||||
|
|
||||||
const uint8_t *tud_descriptor_device_cb(void) { return (const uint8_t *)usbd_desc_device; }
|
|
||||||
|
|
||||||
const uint8_t *tud_descriptor_configuration_cb(uint8_t __unused index) { return usbd_desc_cfg; }
|
|
||||||
|
|
||||||
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
|
||||||
#define DESC_STR_MAX (20)
|
|
||||||
(void)langid;
|
|
||||||
|
|
||||||
static uint16_t desc_str[DESC_STR_MAX];
|
|
||||||
|
|
||||||
// Assign the SN using the unique flash id
|
|
||||||
if (!usbd_serial_str[0]) {
|
|
||||||
pico_get_unique_board_id_string(usbd_serial_str, sizeof(usbd_serial_str));
|
|
||||||
usbd_serial_str[USBD_SERIAL_STR_SIZE - 4] = '-';
|
|
||||||
usbd_serial_str[USBD_SERIAL_STR_SIZE - 3] = '0' + ((usbd_mode / 10) % 10);
|
|
||||||
usbd_serial_str[USBD_SERIAL_STR_SIZE - 2] = '0' + (usbd_mode % 10);
|
|
||||||
usbd_serial_str[USBD_SERIAL_STR_SIZE - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t len;
|
|
||||||
if (index == USBD_STR_LANGUAGE) {
|
|
||||||
desc_str[1] = 0x0409; // Supported language is English
|
|
||||||
len = 1;
|
|
||||||
} else {
|
|
||||||
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
const char *str = usbd_desc_str[index];
|
|
||||||
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
|
|
||||||
desc_str[1 + len] = str[len];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// first byte is length (including header), second byte is string type
|
|
||||||
desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * len + 2));
|
|
||||||
|
|
||||||
return desc_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
|
|
||||||
(void)itf;
|
|
||||||
|
|
||||||
return usbd_desc_hid_report;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implement callback to add our custom driver
|
|
||||||
const usbd_class_driver_t *usbd_app_driver_get_cb(uint8_t *driver_count) {
|
|
||||||
*driver_count = 1;
|
|
||||||
return usbd_app_driver;
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
#include "usb/xinput_driver.h"
|
|
||||||
#include "usb/usb_driver.h"
|
|
||||||
|
|
||||||
#include "tusb.h"
|
|
||||||
|
|
||||||
#define XINPUT_OUT_SIZE 32
|
|
||||||
#define XINPUT_INTERFACE_SUBCLASS (0x5D)
|
|
||||||
#define XINPUT_INTERFACE_PROTOCOL (0x01)
|
|
||||||
#define TUD_XINPUT_DESC_LEN (39)
|
|
||||||
|
|
||||||
const tusb_desc_device_t xinput_desc_device = {
|
|
||||||
.bLength = sizeof(tusb_desc_device_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
|
||||||
.bcdUSB = 0x0200,
|
|
||||||
.bDeviceClass = TUSB_CLASS_VENDOR_SPECIFIC,
|
|
||||||
.bDeviceSubClass = 0xFF,
|
|
||||||
.bDeviceProtocol = 0xFF,
|
|
||||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
|
||||||
.idVendor = 0x045E,
|
|
||||||
.idProduct = 0x028E,
|
|
||||||
.bcdDevice = 0x0114,
|
|
||||||
.iManufacturer = USBD_STR_MANUFACTURER,
|
|
||||||
.iProduct = USBD_STR_PRODUCT,
|
|
||||||
.iSerialNumber = USBD_STR_SERIAL,
|
|
||||||
.bNumConfigurations = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
USBD_ITF_XINPUT,
|
|
||||||
USBD_ITF_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TUD_XINPUT_DESCRIPTOR(_itfnum, _stridx) \
|
|
||||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_VENDOR_SPECIFIC, XINPUT_INTERFACE_SUBCLASS, \
|
|
||||||
XINPUT_INTERFACE_PROTOCOL, _stridx, 0x10, 0x21, 0x10, 0x01, 0x01, 0x24, 0x81, 0x14, 0x03, 0x00, 0x03, 0x13, \
|
|
||||||
0x01, 0x00, 0x03, 0x00, 0x07, 0x05, 0x81, 0x03, 0x20, 0x00, 0x01, 0x07, 0x05, 0x01, 0x03, 0x20, 0x00, 0x08
|
|
||||||
|
|
||||||
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_XINPUT_DESC_LEN)
|
|
||||||
|
|
||||||
const uint8_t xinput_desc_cfg[USBD_DESC_LEN] = {
|
|
||||||
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_LANGUAGE, USBD_DESC_LEN, 0, USBD_MAX_POWER_MAX),
|
|
||||||
TUD_XINPUT_DESCRIPTOR(USBD_ITF_XINPUT, USBD_STR_XINPUT),
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t endpoint_in = 0;
|
|
||||||
static uint8_t endpoint_out = 0;
|
|
||||||
static uint8_t xinput_out_buffer[XINPUT_OUT_SIZE] = {};
|
|
||||||
|
|
||||||
bool receive_xinput_report(void) {
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
if (tud_ready() && (endpoint_out != 0) && (!usbd_edpt_busy(0, endpoint_out))) {
|
|
||||||
usbd_edpt_claim(0, endpoint_out); // Take control of OUT endpoint
|
|
||||||
success = usbd_edpt_xfer(0, endpoint_out, xinput_out_buffer, XINPUT_OUT_SIZE); // Retrieve report buffer
|
|
||||||
usbd_edpt_release(0, endpoint_out); // Release control of OUT endpoint
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool send_xinput_report(usb_report_t report) {
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
if (tud_ready() && // Is the device ready?
|
|
||||||
(endpoint_in != 0) && (!usbd_edpt_busy(0, endpoint_in)) // Is the IN endpoint available?
|
|
||||||
) {
|
|
||||||
usbd_edpt_claim(0, endpoint_in); // Take control of IN endpoint
|
|
||||||
success = usbd_edpt_xfer(0, endpoint_in, report.data, report.size); // Send report buffer
|
|
||||||
usbd_edpt_release(0, endpoint_in); // Release control of IN endpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xinput_init(void) {}
|
|
||||||
|
|
||||||
static void xinput_reset(uint8_t rhport) { (void)rhport; }
|
|
||||||
|
|
||||||
static uint16_t xinput_open(uint8_t rhport, tusb_desc_interface_t const *itf_descriptor, uint16_t max_length) {
|
|
||||||
uint16_t driver_length =
|
|
||||||
sizeof(tusb_desc_interface_t) + (itf_descriptor->bNumEndpoints * sizeof(tusb_desc_endpoint_t)) + 16;
|
|
||||||
|
|
||||||
TU_VERIFY(max_length >= driver_length, 0);
|
|
||||||
|
|
||||||
uint8_t const *current_descriptor = tu_desc_next(itf_descriptor);
|
|
||||||
uint8_t found_endpoints = 0;
|
|
||||||
while ((found_endpoints < itf_descriptor->bNumEndpoints) && (driver_length <= max_length)) {
|
|
||||||
tusb_desc_endpoint_t const *endpoint_descriptor = (tusb_desc_endpoint_t const *)current_descriptor;
|
|
||||||
if (TUSB_DESC_ENDPOINT == tu_desc_type(endpoint_descriptor)) {
|
|
||||||
TU_ASSERT(usbd_edpt_open(rhport, endpoint_descriptor));
|
|
||||||
|
|
||||||
if (tu_edpt_dir(endpoint_descriptor->bEndpointAddress) == TUSB_DIR_IN)
|
|
||||||
endpoint_in = endpoint_descriptor->bEndpointAddress;
|
|
||||||
else
|
|
||||||
endpoint_out = endpoint_descriptor->bEndpointAddress;
|
|
||||||
|
|
||||||
++found_endpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_descriptor = tu_desc_next(current_descriptor);
|
|
||||||
}
|
|
||||||
return driver_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool xinput_control_xfer_callback(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) {
|
|
||||||
(void)rhport;
|
|
||||||
(void)stage;
|
|
||||||
(void)request;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool xinput_xfer_callback(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
|
|
||||||
(void)rhport;
|
|
||||||
(void)xferred_bytes;
|
|
||||||
|
|
||||||
if (result == XFER_RESULT_SUCCESS && ep_addr == endpoint_out) {
|
|
||||||
if (xinput_out_buffer[0] == 0x01) { // 0x00 is rumble, 0x01 is led
|
|
||||||
usb_player_led_t player_led = {.type = USB_PLAYER_LED_ID, .id = 0};
|
|
||||||
|
|
||||||
switch (xinput_out_buffer[2]) {
|
|
||||||
case 0x02:
|
|
||||||
case 0x06:
|
|
||||||
player_led.id = 0x01;
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
case 0x07:
|
|
||||||
player_led.id = 0x02;
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
case 0x08:
|
|
||||||
player_led.id = 0x04;
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
case 0x09:
|
|
||||||
player_led.id = 0x08;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
usb_driver_get_player_led_cb()(player_led);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const usbd_class_driver_t xinput_app_driver = {
|
|
||||||
#if CFG_TUSB_DEBUG >= 2
|
|
||||||
.name = "XINPUT",
|
|
||||||
#endif
|
|
||||||
.init = xinput_init,
|
|
||||||
.reset = xinput_reset,
|
|
||||||
.open = xinput_open,
|
|
||||||
.control_xfer_cb = xinput_control_xfer_callback,
|
|
||||||
.xfer_cb = xinput_xfer_callback,
|
|
||||||
.sof = NULL};
|
|
Loading…
Reference in New Issue
Block a user