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:
parent
2345eb6626
commit
491d467a97
71
usb/hid.c
71
usb/hid.c
@ -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
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
50
usb/usb.c
50
usb/usb.c
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user