1
0
mirror of https://github.com/mist-devel/mist-firmware.git synced 2026-01-13 07:09:44 +00:00

USB: vid and pid belong to the device, not interface

This commit is contained in:
Gyorgy Szombathelyi 2021-11-21 20:54:48 +01:00
parent 2345eb6626
commit 491d467a97
7 changed files with 74 additions and 97 deletions

View File

@ -291,13 +291,6 @@ static uint8_t usb_hid_init(usb_device_t *dev) {
usb_configuration_descriptor_t conf_desc;
} buf;
union {
usb_string0_descriptor_t str0_desc;
usb_string_descriptor_t str_desc;
uint8_t buf[255];
} str;
uint8_t s[128+1];
// reset status
info->bPollEnable = false;
info->bNumIfaces = 0;
@ -313,9 +306,6 @@ static uint8_t usb_hid_init(usb_device_t *dev) {
// try to re-read full device descriptor from newly assigned address
if(rcode = usb_get_dev_descr( dev, sizeof(usb_device_descriptor_t), &buf.dev_desc ))
return rcode;
usb_dump_device_descriptor(&buf.dev_desc);
iprintf("USB vendor ID: %04X, product ID: %04X\n", buf.dev_desc.idVendor, buf.dev_desc.idProduct);
// save vid/pid for automatic hack later
vid = buf.dev_desc.idVendor;
@ -339,41 +329,6 @@ static uint8_t usb_hid_init(usb_device_t *dev) {
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
}
// The Retroflag Classic USB Gamepad doesn't report movement until the string descriptors are read,
// so read all of them here (and show them on the console)
if (!usb_get_string_descr(dev, sizeof(str), 0, 0, &str.str_desc)) { // supported languages descriptor
uint16_t wLangId = str.str0_desc.wLANGID[0];
hid_debugf("wLangId: %04X", wLangId);
// Some gamepads (Retrobit) breaks if its strings are queried like below, so don't do it until it can be done safely.
#if 0
if (buf.dev_desc.iManufacturer &&
!usb_get_string_descr(dev, sizeof(str), buf.dev_desc.iManufacturer, wLangId, &str.str_desc)) {
for (i=0; i<((str.str_desc.bLength-2)/2); i++) {
s[i] = ff_uni2oem(str.str_desc.bString[i], FF_CODE_PAGE);
}
s[i] = 0;
iprintf("Manufacturer: %s\n", s);
}
if (buf.dev_desc.iProduct &&
!usb_get_string_descr(dev, sizeof(str), buf.dev_desc.iProduct, wLangId, &str.str_desc)) {
for (i=0; i<((str.str_desc.bLength-2)/2); i++) {
s[i] = ff_uni2oem(str.str_desc.bString[i], FF_CODE_PAGE);
}
s[i] = 0;
iprintf("Product: %s\n", s);
}
if (buf.dev_desc.iSerialNumber &&
!usb_get_string_descr(dev, sizeof(str), buf.dev_desc.iSerialNumber, wLangId, &str.str_desc)) {
for (i=0; i<((str.str_desc.bLength-2)/2); i++) {
s[i] = ff_uni2oem(str.str_desc.bString[i], FF_CODE_PAGE);
}
s[i] = 0;
iprintf("Serial no.: %s\n", s);
}
#endif
}
// Set Configuration Value
rcode = usb_set_conf(dev, buf.conf_desc.bConfigurationValue);
if (rcode) hid_debugf("hid_set_conf error: %d", rcode);
@ -381,9 +336,6 @@ static uint8_t usb_hid_init(usb_device_t *dev) {
// process all supported interfaces
for(i=0; i<info->bNumIfaces; i++) {
info->iface[i].conf.pid = pid;
info->iface[i].conf.vid = vid;
// no boot mode, try to parse HID report descriptor
// when running archie core force the usage of the HID descriptor as
// boot mode only supports two buttons and the archie wants three
@ -537,7 +489,7 @@ static uint8_t usb_hid_release(usb_device_t *dev) {
}
// special 5200daptor button processing
static void handle_5200daptor(usb_hid_iface_info_t *iface, uint8_t *buf) {
static void handle_5200daptor(usb_device_t *dev, usb_hid_iface_info_t *iface, uint8_t *buf) {
// list of buttons that are reported as keys
static const struct {
@ -588,7 +540,7 @@ static void handle_5200daptor(usb_hid_iface_info_t *iface, uint8_t *buf) {
// iprintf("5200: %d %d %d %d %d %d\n", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
// generate key events
user_io_kbd(0x00, buf, UIO_PRIORITY_GAMEPAD, iface->conf.vid, iface->conf.pid);
user_io_kbd(0x00, buf, UIO_PRIORITY_GAMEPAD, dev->vid, dev->pid);
// save current state of keys
iface->key_state = keys;
@ -646,9 +598,10 @@ static uint16_t collect_bits(uint8_t *p, uint16_t offset, uint8_t size, bool is_
static usb_hid_iface_info_t *virt_joy_kbd_iface = NULL;
/* processes a single USB interface */
static void usb_process_iface (usb_hid_iface_info_t *iface,
uint16_t read,
uint8_t *buf) {
static void usb_process_iface (usb_device_t *dev,
usb_hid_iface_info_t *iface,
uint16_t read,
uint8_t *buf) {
// successfully received some bytes
if(iface->has_boot_mode && !iface->ignore_boot_mode) {
@ -663,9 +616,9 @@ static void usb_process_iface (usb_hid_iface_info_t *iface,
// boot kbd needs at least eight bytes
if(read >= 8) {
if (iface->conf.report_id)
user_io_kbd(buf[1], buf+3, UIO_PRIORITY_KEYBOARD, iface->conf.vid, iface->conf.pid);
user_io_kbd(buf[1], buf+3, UIO_PRIORITY_KEYBOARD, dev->vid, dev->pid);
else
user_io_kbd(buf[0], buf+2, UIO_PRIORITY_KEYBOARD, iface->conf.vid, iface->conf.pid);
user_io_kbd(buf[0], buf+2, UIO_PRIORITY_KEYBOARD, dev->vid, dev->pid);
}
}
}
@ -836,13 +789,13 @@ static void usb_process_iface (usb_hid_iface_info_t *iface,
// report joystick 1 to OSD
idx = joystick_index(iface->jindex);
StateUsbIdSet( conf->vid, conf->pid, conf->joystick_mouse.button_count, idx);
StateUsbIdSet( dev->vid, dev->pid, conf->joystick_mouse.button_count, idx);
StateUsbJoySet( jmap, btn_extra, idx);
// map virtual joypad
uint16_t vjoy = jmap;
vjoy |= btn_extra << 8;
vjoy = virtual_joystick_mapping( conf->vid, conf->pid, vjoy );
vjoy = virtual_joystick_mapping( dev->vid, dev->pid, vjoy );
//iprintf("VIRTUAL JOY:%d\n", vjoy);
//if (jmap != 0) iprintf("JMAP pre map:%d\n", jmap);
@ -880,7 +833,7 @@ static void usb_process_iface (usb_hid_iface_info_t *iface,
// do special 5200daptor treatment
if(iface->is_5200daptor)
handle_5200daptor(iface, buf);
handle_5200daptor(dev, iface, buf);
// apply keyboard mappings
if ((!virt_joy_kbd_iface) || (virt_joy_kbd_iface == iface)) {
@ -917,7 +870,7 @@ static uint8_t usb_hid_poll(usb_device_t *dev) {
if (rcode != hrNAK)
hid_debugf("%s() error: %d", __FUNCTION__, rcode);
} else {
usb_process_iface ( iface, read, buf);
usb_process_iface (dev, iface, read, buf);
}
iface->qNextPollTime = timer_get_msec() + iface->interval; // poll at requested rate
}

View File

@ -12,10 +12,6 @@ typedef struct {
uint8_t report_id;
uint8_t report_size;
// for downstream mapping
uint16_t vid;
uint16_t pid;
union {
struct {
struct {

View File

@ -62,7 +62,7 @@ uint8_t joystick_release(uint8_t c_jindex) {
iprintf("decreasing joystick index of dev #%d from %d to %d\n", j,
jindex, jindex-1);
dev[j].hid_info.iface[k].jindex--;
StateUsbIdSet( dev[j].hid_info.iface[k].conf.vid, dev[j].hid_info.iface[k].conf.pid, dev[j].hid_info.iface[k].conf.joystick_mouse.button_count, dev[j].hid_info.iface[k].jindex);
StateUsbIdSet( dev[j].vid, dev[j].pid, dev[j].hid_info.iface[k].conf.joystick_mouse.button_count, dev[j].hid_info.iface[k].jindex);
}
}
}
@ -72,7 +72,7 @@ uint8_t joystick_release(uint8_t c_jindex) {
if(jindex > c_jindex) {
iprintf("Decreasing xbox index of dev #%d from %d to %d\n", j, jindex, jindex-1);
dev[j].xbox_info.jindex--;
StateUsbIdSet( dev[j].xbox_info.vid, dev[j].xbox_info.pid, 8/*button_count*/, dev[j].xbox_info.jindex);
StateUsbIdSet( dev[j].vid, dev[j].pid, 8/*button_count*/, dev[j].xbox_info.jindex);
}
}

View File

@ -354,6 +354,13 @@ uint8_t usb_configure(uint8_t parent, uint8_t port, bool lowspeed) {
// find an empty device entry
uint8_t i;
usb_device_descriptor_t dev_desc;
union {
usb_string0_descriptor_t str0_desc;
usb_string_descriptor_t str_desc;
uint8_t buf[255];
} str;
for(i=0; i<USB_NUMDEVICES && dev[i].bAddress; i++);
if(i < USB_NUMDEVICES) {
@ -375,6 +382,49 @@ uint8_t usb_configure(uint8_t parent, uint8_t port, bool lowspeed) {
d->ep0.bmNakPower = USB_NAK_MAX_POWER;
// --- enumerate device ---
if(rcode = usb_get_dev_descr( d, sizeof(usb_device_descriptor_t), &dev_desc ))
return rcode;
usb_dump_device_descriptor(&dev_desc);
iprintf("USB vendor ID: %04X, product ID: %04X\n", dev_desc.idVendor, dev_desc.idProduct);
// save vid/pid
d->vid = dev_desc.idVendor;
d->pid = dev_desc.idProduct;
// The Retroflag Classic USB Gamepad doesn't report movement until the string descriptors are read,
// so read all of them here (and show them on the console)
if (!usb_get_string_descr(d, sizeof(str), 0, 0, &str.str_desc)) { // supported languages descriptor
uint16_t wLangId = str.str0_desc.wLANGID[0];
iprintf("wLangId: %04X\n", wLangId);
// Some gamepads (Retrobit) breaks if its strings are queried like below, so don't do it until it can be done safely.
#if 0
if (dev_desc.iManufacturer &&
!usb_get_string_descr(d, sizeof(str), dev_desc.iManufacturer, wLangId, &str.str_desc)) {
for (i=0; i<((str.str_desc.bLength-2)/2); i++) {
s[i] = ff_uni2oem(str.str_desc.bString[i], FF_CODE_PAGE);
}
s[i] = 0;
iprintf("Manufacturer: %s\n", s);
}
if (dev_desc.iProduct &&
!usb_get_string_descr(d, sizeof(str), dev_desc.iProduct, wLangId, &str.str_desc)) {
for (i=0; i<((str.str_desc.bLength-2)/2); i++) {
s[i] = ff_uni2oem(str.str_desc.bString[i], FF_CODE_PAGE);
}
s[i] = 0;
iprintf("Product: %s\n", s);
}
if (dev_desc.iSerialNumber &&
!usb_get_string_descr(d, sizeof(str), dev_desc.iSerialNumber, wLangId, &str.str_desc)) {
for (i=0; i<((str.str_desc.bLength-2)/2); i++) {
s[i] = ff_uni2oem(str.str_desc.bString[i], FF_CODE_PAGE);
}
s[i] = 0;
iprintf("Serial no.: %s\n", s);
}
#endif
}
// Assign new address to the device
// (address is simply the number of the free slot + 1)

View File

@ -113,6 +113,8 @@ typedef struct usb_device_entry {
uint8_t bAddress; // device address
uint8_t parent; // parent device address
uint8_t port;
uint16_t vid;
uint16_t pid;
bool lowspeed;
union {

View File

@ -89,26 +89,12 @@ uint8_t usb_xbox_init(usb_device_t *dev) {
uint16_t pid;
uint16_t vid;
union {
usb_device_descriptor_t dev_desc;
usb_configuration_descriptor_t conf_desc;
} buf;
union {
usb_string0_descriptor_t str0_desc;
usb_string_descriptor_t str_desc;
uint8_t buf[255];
} str;
usb_configuration_descriptor_t conf_desc;
dev->xbox_info.bPollEnable = false;
usb_debugf("%s(%x)", __FUNCTION__, dev->bAddress);
if(rcode = usb_get_dev_descr( dev, sizeof(usb_device_descriptor_t), &buf.dev_desc ))
return rcode;
usb_dump_device_descriptor(&buf.dev_desc);
vid = buf.dev_desc.idVendor;
pid = buf.dev_desc.idProduct;
vid = dev->vid;
pid = dev->pid;
if(vid != XBOX_VID && vid != MADCATZ_VID && vid != JOYTECH_VID && vid != GAMESTOP_VID) {// Check VID
usb_debugf("Not a XBOX VID (%04x)", vid);
@ -127,16 +113,10 @@ uint8_t usb_xbox_init(usb_device_t *dev) {
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
}
// get the language descriptor 0, Retroflag classic USB joystick doesn't work without querying it
if (!usb_get_string_descr(dev, sizeof(str), 0, 0, &str.str_desc)) { // supported languages descriptor
uint16_t wLangId = str.str0_desc.wLANGID[0];
iprintf("XBOX: wLangId: %04X\n", wLangId);
}
if(rcode = usb_get_conf_descr(dev, sizeof(usb_configuration_descriptor_t), 0, &buf.conf_desc))
if(rcode = usb_get_conf_descr(dev, sizeof(usb_configuration_descriptor_t), 0, &conf_desc))
return rcode;
usb_dump_conf_descriptor(&buf.conf_desc);
usb_dump_conf_descriptor(&conf_desc);
// Skip parsing the interface and endpoint descriptors, and use known values */
//usb_xbox_parse_conf(dev, 0, buf.conf_desc.wTotalLength);
@ -149,12 +129,10 @@ uint8_t usb_xbox_init(usb_device_t *dev) {
dev->xbox_info.qNextPollTime = 0;
// Set Configuration Value
if(rcode = usb_set_conf(dev, buf.conf_desc.bConfigurationValue)) {
if(rcode = usb_set_conf(dev, conf_desc.bConfigurationValue)) {
iprintf("XBOX: error setting conf value (%d)\n", rcode);
return rcode;
}
dev->xbox_info.vid = vid;
dev->xbox_info.pid = pid;
dev->xbox_info.jindex = joystick_add();
dev->xbox_info.bPollEnable = true;
return 0;
@ -175,7 +153,7 @@ static void usb_xbox_read_report(usb_device_t *dev, uint16_t len, uint8_t *buf)
uint16_t buttons = (swp2(buf[2], 0xc) >> 2) | (swp2(buf[2], 0x3) << 2) | swp2(buf[3], 0x30) | (swp2(buf[2], 0x30) << 2) | ((buf[3] & 0x03) << 10) | (swp2(buf[3], 0xc0) << 2);
uint8_t idx = dev->xbox_info.jindex;
StateUsbIdSet(dev->xbox_info.vid, dev->xbox_info.pid, 8, idx);
StateUsbIdSet(dev->vid, dev->pid, 8, idx);
/*
TODO: handle analogue parts
@ -189,7 +167,7 @@ static void usb_xbox_read_report(usb_device_t *dev, uint16_t len, uint8_t *buf)
if(buttons != dev->xbox_info.oldButtons) {
StateUsbJoySet(buttons, buttons>>8, idx);
uint16_t vjoy = virtual_joystick_mapping(dev->xbox_info.vid, dev->xbox_info.pid, buttons);
uint16_t vjoy = virtual_joystick_mapping(dev->vid, dev->pid, buttons);
StateJoySet(vjoy, idx);
StateJoySetExtra( vjoy>>8, idx);

View File

@ -53,8 +53,6 @@
typedef struct {
bool bPollEnable; // poll enable flag
uint16_t vid;
uint16_t pid;
uint8_t interval;
uint32_t oldButtons;
uint32_t qNextPollTime; // next poll time