uhc_enum_status_t uhi_hid_mouse_install(uhc_device_t* dev) { bool b_iface_supported; uint16_t conf_desc_lgt; usb_iface_desc_t *ptr_iface; if (uhi_hid_mouse_dev.dev != NULL) { return UHC_ENUM_SOFTWARE_LIMIT; // Device already allocated } conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); ptr_iface = (usb_iface_desc_t*)dev->conf_desc; b_iface_supported = false; while(conf_desc_lgt) { switch (ptr_iface->bDescriptorType) { case USB_DT_INTERFACE: if ((ptr_iface->bInterfaceClass == HID_CLASS) && (ptr_iface->bInterfaceProtocol == HID_PROTOCOL_MOUSE) ) { // USB HID Mouse interface found // Start allocation endpoint(s) b_iface_supported = true; } else { // Stop allocation endpoint(s) b_iface_supported = false; } break; case USB_DT_ENDPOINT: // Allocation of the endpoint if (!b_iface_supported) { break; } if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface)) { return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail } Assert(((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN); uhi_hid_mouse_dev.ep_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; uhi_hid_mouse_dev.report_size = le16_to_cpu(((usb_ep_desc_t*)ptr_iface)->wMaxPacketSize); uhi_hid_mouse_dev.report = malloc(uhi_hid_mouse_dev.report_size); if (uhi_hid_mouse_dev.report == NULL) { Assert(false); return UHC_ENUM_MEMORY_LIMIT; // Internal RAM allocation fail } uhi_hid_mouse_dev.dev = dev; // All endpoints of all interfaces supported allocated return UHC_ENUM_SUCCESS; default: // Ignore descriptor break; } Assert(conf_desc_lgt>=ptr_iface->bLength); conf_desc_lgt -= ptr_iface->bLength; ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); } return UHC_ENUM_UNSUPPORTED; // No interface supported }
//----- external (UHC) functions uhc_enum_status_t uhi_hid_install(uhc_device_t* dev) { bool b_iface_supported; uint16_t conf_desc_lgt; usb_iface_desc_t *ptr_iface; if (uhi_hid_dev.dev != NULL) { return UHC_ENUM_SOFTWARE_LIMIT; // Device already allocated } conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); ptr_iface = (usb_iface_desc_t*)dev->conf_desc; b_iface_supported = false; // return UHC_ENUM_UNSUPPORTED; // No interface supported while(conf_desc_lgt) { switch (ptr_iface->bDescriptorType) { case USB_DT_INTERFACE: #if 0 print_dbg("\r\n\r\n"); print_dbg("\r\n iface_desc -> bLength : "); print_dbg_hex(ptr_iface->bLength); print_dbg("\r\n iface_desc -> bDescriptorType : "); print_dbg_hex(ptr_iface->bDescriptorType); print_dbg("\r\n iface_desc -> bInterfaceNumber : "); print_dbg_hex(ptr_iface->bInterfaceNumber); print_dbg("\r\n iface_desc -> bAlternateSetting : "); print_dbg_hex(ptr_iface->bAlternateSetting); print_dbg("\r\n iface_desc -> bNumEndpoints : "); print_dbg_hex(ptr_iface->bNumEndpoints); print_dbg("\r\n iface_desc -> bInterfaceClass : "); print_dbg_hex(ptr_iface->bInterfaceClass); print_dbg("\r\n iface_desc -> bInterfaceSubClass : "); print_dbg_hex(ptr_iface->bInterfaceSubClass); print_dbg("\r\n iface_desc -> bInterfaceProtocol : "); print_dbg_hex(ptr_iface->bInterfaceProtocol); print_dbg("\r\n iface_desc -> iInterface : "); print_dbg_hex(ptr_iface->iInterface); print_dbg("\r\n\r\n"); #endif /* if ((ptr_iface->bInterfaceClass == HID_CLASS) */ /* && (ptr_iface->bInterfaceProtocol == HID_PROTOCOL_GENERIC) ) { */ /// try looking at all HID classes... mostly to test if our system is sane if ((ptr_iface->bInterfaceClass == HID_CLASS)) { // Start allocation endpoint(s) // print_dbg("\r\n HID device: detected interface"); b_iface_supported = true; } else { // Stop allocation endpoint(s) b_iface_supported = false; } break; case USB_DT_ENDPOINT: // Allocation of the endpoint if (!b_iface_supported) { break; } if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface)) { return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail } // print_dbg("\r\n HID device: allocated endpoint"); Assert(((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN); uhi_hid_dev.ep_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; uhi_hid_dev.report_size = le16_to_cpu(((usb_ep_desc_t*)ptr_iface)->wMaxPacketSize); uhi_hid_dev.report = malloc(uhi_hid_dev.report_size); if (uhi_hid_dev.report == NULL) { Assert(false); return UHC_ENUM_MEMORY_LIMIT; // Internal RAM allocation fail } uhi_hid_dev.dev = dev; // All endpoints of all interfaces supported allocated return UHC_ENUM_SUCCESS; default: // Ignore descriptor break; } Assert(conf_desc_lgt>=ptr_iface->bLength); conf_desc_lgt -= ptr_iface->bLength; ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); } return UHC_ENUM_UNSUPPORTED; // No interface supported }
uhc_enum_status_t uhi_cdc_install(uhc_device_t* dev) { bool b_iface_comm, b_iface_data; uint16_t conf_desc_lgt; uint8_t port_num, i; usb_iface_desc_t *ptr_iface; uhi_cdc_port_t *ptr_port = NULL; uhi_cdc_line_t *ptr_line; if (uhi_cdc_dev.dev != NULL) { return UHC_ENUM_SOFTWARE_LIMIT; // Device already allocated } // Compute the number of port conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); ptr_iface = (usb_iface_desc_t*)dev->conf_desc; uhi_cdc_dev.nb_port = 0; while (conf_desc_lgt) { if ((ptr_iface->bDescriptorType == USB_DT_INTERFACE) && (ptr_iface->bInterfaceClass == CDC_CLASS_COMM) && (ptr_iface->bInterfaceSubClass == CDC_SUBCLASS_ACM) && (ptr_iface->bInterfaceProtocol <= CDC_PROTOCOL_V25TER)) { // New COM port has been found uhi_cdc_dev.nb_port++; } Assert(conf_desc_lgt>=ptr_iface->bLength); conf_desc_lgt -= ptr_iface->bLength; ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); } if (uhi_cdc_dev.nb_port == 0) { return UHC_ENUM_UNSUPPORTED; // No interface supported } // Alloc port structures uhi_cdc_dev.port = malloc(uhi_cdc_dev.nb_port * sizeof(uhi_cdc_port_t)); if (uhi_cdc_dev.port == NULL) { Assert(false); return UHC_ENUM_SOFTWARE_LIMIT; } // Initialize structure for (i = 0; i<uhi_cdc_dev.nb_port; i++) { uhi_cdc_dev.port[i].ep_comm_in = 0; uhi_cdc_dev.port[i].iface_data = 0xFF; uhi_cdc_dev.port[i].line_rx.ep_data = 0; uhi_cdc_dev.port[i].line_rx.buffer[0].ptr = NULL; uhi_cdc_dev.port[i].line_rx.buffer[1].ptr = NULL; uhi_cdc_dev.port[i].line_tx.ep_data = 0; uhi_cdc_dev.port[i].line_tx.buffer[0].ptr = NULL; uhi_cdc_dev.port[i].line_tx.buffer[1].ptr = NULL; } // Fill port structures conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); ptr_iface = (usb_iface_desc_t*)dev->conf_desc; b_iface_comm = false; b_iface_data = false; port_num = 0; while (conf_desc_lgt) { switch (ptr_iface->bDescriptorType) { case USB_DT_INTERFACE: if ((ptr_iface->bInterfaceClass == CDC_CLASS_COMM) && (ptr_iface->bInterfaceSubClass == CDC_SUBCLASS_ACM) && (ptr_iface->bInterfaceProtocol <= CDC_PROTOCOL_V25TER) ) { // New Communication Class COM port has been found b_iface_comm = true; ptr_port = &uhi_cdc_dev.port[port_num++]; ptr_port->iface_comm = ptr_iface->bInterfaceNumber; } else { // Stop allocation endpoint(s) b_iface_comm = false; } if ((ptr_iface->bInterfaceClass == CDC_CLASS_DATA) && (ptr_iface->bInterfaceSubClass == 0) && (ptr_iface->bInterfaceProtocol == 0) ) { for (i = 0; i<uhi_cdc_dev.nb_port; i++) { ptr_port = &uhi_cdc_dev.port[i]; if (ptr_port->iface_data == 0xFF) { b_iface_data = true; break; } else if (ptr_port->iface_data == ptr_iface->bInterfaceNumber) { // New CDC DATA Class has been found // and correspond at a CDC COMM Class b_iface_data = true; break; } } } else { // Stop allocation endpoint(s) b_iface_data = false; } break; case CDC_CS_INTERFACE: if (!b_iface_comm) { break; } if (((usb_cdc_call_mgmt_desc_t*)ptr_iface)->bDescriptorSubtype == CDC_SCS_CALL_MGMT) { ptr_port->iface_data = ((usb_cdc_call_mgmt_desc_t*)ptr_iface)->bDataInterface; } break; case USB_DT_ENDPOINT: // Allocation of the endpoint if (b_iface_comm) { Assert ((usb_ep_desc_t*)ptr_iface->bmAttributes == USB_EP_TYPE_INTERRUPT); Assert ((usb_ep_desc_t*)ptr_iface->bEndpointAddress & USB_EP_DIR_IN); if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface)) { uhi_cdc_free_device(); return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail } ptr_port->ep_comm_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; } if (b_iface_data) { Assert (((usb_ep_desc_t*)ptr_iface)->bmAttributes == USB_EP_TYPE_BULK); if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface)) { uhi_cdc_free_device(); return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail } if (((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN) { ptr_line = &ptr_port->line_rx; } else { ptr_line = &ptr_port->line_tx; } ptr_line->ep_data = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; ptr_line->b_trans_ongoing = false; ptr_line->buf_sel = 0; // Allocate and initialize buffers uint16_t buf_size = Max( le16_to_cpu( ((usb_ep_desc_t*)ptr_iface)->wMaxPacketSize), UHI_CDC_BUFFER_SIZE ); ptr_line->buffer_size = buf_size; ptr_line->buffer[0].pos = 0; ptr_line->buffer[0].nb = 0; ptr_line->buffer[0].ptr = malloc(buf_size); if (ptr_line->buffer[0].ptr == NULL) { Assert(false); uhi_cdc_free_device(); return UHC_ENUM_SOFTWARE_LIMIT; } ptr_line->buffer[1].pos = 0; ptr_line->buffer[1].nb = 0; ptr_line->buffer[1].ptr = malloc(buf_size); if (ptr_line->buffer[1].ptr == NULL) { Assert(false); uhi_cdc_free_device(); return UHC_ENUM_SOFTWARE_LIMIT; } } break; } Assert(conf_desc_lgt >= ptr_iface->bLength); conf_desc_lgt -= ptr_iface->bLength; ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); } // Check installed ports for (i = 0; i<uhi_cdc_dev.nb_port; i++) { if ((uhi_cdc_dev.port[i].ep_comm_in == 0) || (uhi_cdc_dev.port[i].line_rx.ep_data == 0) || (uhi_cdc_dev.port[i].line_tx.ep_data == 0)) { // Install is not complete uhi_cdc_free_device(); return UHC_ENUM_UNSUPPORTED; } } uhi_cdc_dev.b_enabled = false; uhi_cdc_dev.dev = dev; return UHC_ENUM_SUCCESS; }
uhc_enum_status_t uhi_vendor_install(uhc_device_t* dev) { bool b_iface_supported; uint16_t conf_desc_lgt, vid, pid; usb_iface_desc_t *ptr_iface; struct { uint16_t vid; uint16_t pid; } vid_pid_supported[] = { UHI_VENDOR_VID_PID_LIST }; if (uhi_vendor_dev.dev != NULL) { return UHC_ENUM_SOFTWARE_LIMIT; // Already allocated } // Check VID/PID (Mandatory for a Vendor Class) vid = le16_to_cpu(dev->dev_desc.idVendor); pid = le16_to_cpu(dev->dev_desc.idProduct); uint8_t i = 0; while(1) { if ((vid_pid_supported[i].vid == vid) && (vid_pid_supported[i].pid == pid)) { // Valid USB device break; } if (++i == (sizeof(vid_pid_supported) / sizeof(vid_pid_supported[0]))) { // Unvalid USB device return UHC_ENUM_UNSUPPORTED; } } // Check that a vendor interface is present conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); ptr_iface = (usb_iface_desc_t*)dev->conf_desc; b_iface_supported = false; while(conf_desc_lgt) { switch (ptr_iface->bDescriptorType) { case USB_DT_INTERFACE: if ((ptr_iface->bInterfaceClass == VENDOR_CLASS) && (ptr_iface->bInterfaceSubClass == VENDOR_SUBCLASS) && (ptr_iface->bInterfaceProtocol == VENDOR_PROTOCOL) && (ptr_iface->bAlternateSetting == 1)) { // USB Vendor interface found // Start allocation endpoint(s) b_iface_supported = true; uhi_vendor_dev.bInterfaceNumber = ptr_iface->bInterfaceNumber; uhi_vendor_dev.ep_bulk_in = 0; uhi_vendor_dev.ep_bulk_out = 0; uhi_vendor_dev.ep_int_in = 0; uhi_vendor_dev.ep_int_out = 0; uhi_vendor_dev.ep_iso_in = 0; uhi_vendor_dev.ep_iso_out = 0; } else { if (b_iface_supported) { // End of Vendor Interface uhi_vendor_dev.dev = dev; return UHC_ENUM_SUCCESS; } } break; case USB_DT_ENDPOINT: // Allocation of the endpoint if (!b_iface_supported) { break; } if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface, dev->speed)) { return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail } switch(((usb_ep_desc_t*)ptr_iface)->bmAttributes & USB_EP_TYPE_MASK) { case USB_EP_TYPE_INTERRUPT: if (((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN) { uhi_vendor_dev.ep_int_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; } else { uhi_vendor_dev.ep_int_out = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; } break; case USB_EP_TYPE_ISOCHRONOUS: if (((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN) { uhi_vendor_dev.ep_iso_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; } else { uhi_vendor_dev.ep_iso_out = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; } break; case USB_EP_TYPE_BULK: if (((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN) { uhi_vendor_dev.ep_bulk_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; } else { uhi_vendor_dev.ep_bulk_out = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; } break; default: return UHC_ENUM_SOFTWARE_LIMIT; } break; default: // Ignore descriptor break; } Assert(conf_desc_lgt>=ptr_iface->bLength); conf_desc_lgt -= ptr_iface->bLength; ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); } if (b_iface_supported) { // End of Vendor Interface uhi_vendor_dev.dev = dev; return UHC_ENUM_SUCCESS; } return UHC_ENUM_UNSUPPORTED; // No interface supported }
uhc_enum_status_t uhi_midi_install(uhc_device_t* dev) { bool b_iface_supported; uint16_t conf_desc_lgt; usb_iface_desc_t *ptr_iface; uhi_midi_line_t *ptr_line; if (uhi_midi_dev.dev != NULL) { return UHC_ENUM_SOFTWARE_LIMIT; // Device already allocated } conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); ptr_iface = (usb_iface_desc_t*)dev->conf_desc; b_iface_supported = false; while(conf_desc_lgt) { switch (ptr_iface->bDescriptorType) { case USB_DT_INTERFACE: if ((ptr_iface->bInterfaceClass == AUDIO_CLASS) && (ptr_iface->bInterfaceProtocol == 0) ) { // USB MIDI interface found // Start allocation endpoint(s) b_iface_supported = true; uhi_midi_dev.iface_num = ptr_iface->bInterfaceNumber; uhi_midi_dev.line_rx.ep_data = 0; uhi_midi_dev.line_tx.ep_data = 0; } else { // Stop allocation endpoint(s) b_iface_supported = false; } break; case USB_DT_ENDPOINT: // Allocation of the endpoint if (!b_iface_supported) { break; } if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface)) { return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail } switch(((usb_ep_desc_t*)ptr_iface)->bmAttributes & USB_EP_TYPE_MASK) { case USB_EP_TYPE_BULK: if(((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN) ptr_line = &uhi_midi_dev.line_rx; else ptr_line = &uhi_midi_dev.line_tx; ptr_line->ep_data = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; ptr_line->b_trans_ongoing = false; ptr_line->buf_sel = 0; // Allocate and initialize buffers uint16_t buf_size = Max( le16_to_cpu( ((usb_ep_desc_t*)ptr_iface)->wMaxPacketSize), UHI_MIDI_BUFFER_SIZE ); ptr_line->buffer_size = buf_size; ptr_line->buffer[0].pos = 0; ptr_line->buffer[0].nb = 0; ptr_line->buffer[0].ptr = calloc(buf_size,sizeof(uint8_t)); if (ptr_line->buffer[0].ptr == NULL) { Assert(false); uhi_midi_free_device(); return UHC_ENUM_SOFTWARE_LIMIT; } ptr_line->buffer[1].pos = 0; ptr_line->buffer[1].nb = 0; ptr_line->buffer[1].ptr = calloc(buf_size,sizeof(uint8_t)); if (ptr_line->buffer[1].ptr == NULL) { Assert(false); uhi_midi_free_device(); return UHC_ENUM_SOFTWARE_LIMIT; } break; default: break; } break; default: // Ignore descriptor break; } Assert(conf_desc_lgt>=ptr_iface->bLength); conf_desc_lgt -= ptr_iface->bLength; ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); } // we added this because sometime USB MIDI devices give garbage in the first transfer firstMessage = 1; // All endpoints of all interfaces supported allocated if(uhi_midi_dev.line_rx.ep_data) { uhi_midi_dev.b_enabled = false; uhi_midi_dev.dev = dev; return UHC_ENUM_SUCCESS; } uhi_midi_free_device(); return UHC_ENUM_UNSUPPORTED; // No interface supported }
uhc_enum_status_t uhi_hid_manta_install(uhc_device_t* dev) { bool b_iface_supported; uint16_t conf_desc_lgt; usb_iface_desc_t *ptr_iface; //char *product = NULL; //product = uhc_dev_get_string(dev,dev->dev_desc.iProduct); //while(product == NULL); //lcd_clear_line(2); //dip204_printf_string("%x",dev->dev_desc.idProduct); Write7Seg(55); if (uhi_hid_manta_dev.dev != NULL) return UHC_ENUM_SOFTWARE_LIMIT; // Device already allocated conf_desc_lgt = le16_to_cpu(dev->conf_desc->wTotalLength); ptr_iface = (usb_iface_desc_t*)dev->conf_desc; b_iface_supported = false; while(conf_desc_lgt) { switch (ptr_iface->bDescriptorType) { case USB_DT_INTERFACE: if ((ptr_iface->bInterfaceClass == HID_CLASS) && (ptr_iface->bInterfaceProtocol == HID_PROTOCOL_GENERIC) && dev->dev_desc.idProduct == 0x2424) { int i; // USB HID Manta interface found // Start allocation endpoint(s) b_iface_supported = true; // initialize button states to 0 for(i=0; i<48; i++) { butt_states[i]=0; pastbutt_states[i]=0; //notestack[i] = -1; } } else { b_iface_supported = false; // Stop allocation endpoint(s) return UHC_ENUM_UNSUPPORTED; // No interface supported } break; case USB_DT_ENDPOINT: // Allocation of the endpoint if (!b_iface_supported) break; if (!uhd_ep_alloc(dev->address, (usb_ep_desc_t*)ptr_iface)) return UHC_ENUM_HARDWARE_LIMIT; // Endpoint allocation fail if(((usb_ep_desc_t*)ptr_iface)->bEndpointAddress & USB_EP_DIR_IN) { uhi_hid_manta_dev.ep_in = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; uhi_hid_manta_dev.report_size = le16_to_cpu(((usb_ep_desc_t*)ptr_iface)->wMaxPacketSize); uhi_hid_manta_dev.report = malloc(uhi_hid_manta_dev.report_size); } else uhi_hid_manta_dev.ep_out = ((usb_ep_desc_t*)ptr_iface)->bEndpointAddress; break; // Ignore descriptor default: break; } Assert(conf_desc_lgt>=ptr_iface->bLength); conf_desc_lgt -= ptr_iface->bLength; ptr_iface = (usb_iface_desc_t*)((uint8_t*)ptr_iface + ptr_iface->bLength); } if (uhi_hid_manta_dev.report == NULL) { Assert(false); return UHC_ENUM_MEMORY_LIMIT; // Internal RAM allocation fail } if(uhi_hid_manta_dev.ep_in != 0 && uhi_hid_manta_dev.ep_out != 0) { uhi_hid_manta_dev.dev = dev; // All endpoints of all interfaces supported allocated return UHC_ENUM_SUCCESS; } return UHC_ENUM_UNSUPPORTED; // No interface supported }