void hidd_kbd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg) { USB_INTERFACE_DESCRIPTOR* iface; USB_ENDPOINT_DESCRIPTOR* ep; uint8_t in_ep, hid_iface; unsigned in_ep_size; in_ep = in_ep_size = hid_iface = 0; //check control/data ep here for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface)) { if (iface->bInterfaceClass == HID_INTERFACE_CLASS && iface->bInterfaceSubClass == HID_SUBCLASS_BOOT_INTERFACE && iface->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD) { ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep != NULL) { in_ep = USB_EP_NUM(ep->bEndpointAddress); in_ep_size = ep->wMaxPacketSize; hid_iface = iface->bInterfaceNumber; break; } } } //No HID descriptors in interface if (in_ep == 0) return; HIDD_KBD* hidd = (HIDD_KBD*)malloc(sizeof(HIDD_KBD)); if (hidd == NULL) return; hidd->io = io_create(in_ep_size); if (hidd->io == NULL) { hidd_kbd_destroy(hidd); return; } hidd->iface = hid_iface; hidd->in_ep = in_ep; hidd->suspended = false; hidd->over = false; hidd->idle = 0; hidd->boot_protocol = 1; hidd->state = USB_HID_KBD_IDLE; memset(&hidd->kbd, 0x00, sizeof(BOOT_KEYBOARD)); #if (USBD_HID_DEBUG_REQUESTS) printf("Found USB HID device class, EP%d, iface: %d\n", hidd->in_ep, hidd->iface); #endif //USBD_HID_DEBUG_REQUESTS usbd_register_interface(usbd, hidd->iface, &__HIDD_KBD_CLASS, hidd); usbd_register_endpoint(usbd, hidd->iface, hidd->in_ep); usbd_usb_ep_open(usbd, USB_EP_IN | hidd->in_ep, USB_EP_INTERRUPT, in_ep_size); }
void mscd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg) { USB_INTERFACE_DESCRIPTOR* iface; USB_ENDPOINT_DESCRIPTOR* ep; void* config; int i; unsigned int ep_num, ep_size, iface_num, lun_count; ep_num = 0; //check control/data ep here for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface)) { ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep != NULL && iface->bInterfaceClass == MSC_INTERFACE_CLASS) { ep_num = USB_EP_NUM(ep->bEndpointAddress); ep_size = ep->wMaxPacketSize; iface_num = iface->bInterfaceNumber; break; } } //No MSC interface if (ep_num == 0) return; i = usbd_get_cfg(usbd, iface_num); config = usbd_get_cfg_data(usbd, i); lun_count = 0; if (usbd_get_cfg_data_size(usbd, i) > (int)sizeof(uint32_t)) lun_count = MSC_LUN_COUNT(config); if ((config == NULL) || (usbd_get_cfg_data_size(usbd, i) < (int)((sizeof(SCSI_STORAGE_DESCRIPTOR)) * lun_count + sizeof(uint32_t))) || (lun_count == 0)) { #if (USBD_MSC_DEBUG_ERRORS) printf("MSCD: Failed to read user configuration\n"); #endif //USBD_MSC_DEBUG_ERRORS return; } MSCD* mscd = (MSCD*)malloc(sizeof(MSCD) + sizeof(void*) * lun_count); if (mscd == NULL) return; mscd->iface_num = iface_num; mscd->ep_num = ep_num; mscd->ep_size = ep_size; mscd->usbd = usbd; mscd->control = io_create(ep_size); mscd->data = io_create(USBD_MSC_IO_SIZE + sizeof(STORAGE_STACK)); mscd->lun_count = lun_count; mscd->io_busy_mask = 0x00000000; mscd->io_owner = -1; mscd->cbw = io_data(mscd->control); for (i = 0; i < mscd->lun_count; ++i) MSCD_SCSI(mscd)[i] = scsis_create(mscd_host_cb, mscd, i, MSC_LUN_CONFIGURATION(config, i)); if (mscd->control == NULL || mscd->data == NULL || MSCD_SCSI(mscd)[mscd->lun_count - 1] == NULL) { #if (USBD_MSC_DEBUG_ERRORS) printf("MSCD: Out of memory\n"); #endif //USBD_MSC_DEBUG_ERRORS mscd_destroy(mscd); return; } for (i = 0; i < mscd->lun_count; ++i) scsis_init(MSCD_SCSI(mscd)[i]); #if (USBD_MSC_DEBUG_REQUESTS) printf("Found USB MSCD class, EP%d, size: %d, iface: %d\n", ep_num, ep_size, iface_num); #endif //USBD_MSC_DEBUG_REQUESTS usbd_register_interface(usbd, iface_num, &__MSCD_CLASS, mscd); usbd_register_endpoint(usbd, iface_num, ep_num); usbd_usb_ep_open(usbd, USB_EP_IN | ep_num, USB_EP_BULK, ep_size); usbd_usb_ep_open(usbd, ep_num, USB_EP_BULK, ep_size); mscd_read_cbw(usbd, mscd); }
void cdc_acmd_class_configured(USBD* usbd, USB_CONFIGURATION_DESCRIPTOR* cfg) { USB_INTERFACE_DESCRIPTOR* iface; USB_INTERFACE_DESCRIPTOR* diface; CDC_UNION_DESCRIPTOR* u; USB_ENDPOINT_DESCRIPTOR* ep; uint8_t data_ep, data_iface; uint16_t data_ep_size; uint8_t control_ep, control_iface; uint16_t control_ep_size; //check control/data ep here for (iface = usb_get_first_interface(cfg); iface != NULL; iface = usb_get_next_interface(cfg, iface)) { //also skip RNDIS if ((iface->bInterfaceClass != CDC_COMM_INTERFACE_CLASS) || (iface->bInterfaceSubClass != CDC_ACM) || (iface->bInterfaceProtocol == CDC_CP_VENDOR)) continue; #if (USBD_CDC_ACM_DEBUG) printf("Found USB CDC ACM interface: %d\n", iface->bInterfaceNumber); #endif //USBD_CDC_ACM_DEBUG //find union descriptor for (u = usb_interface_get_first_descriptor(cfg, iface, CS_INTERFACE); u != NULL; u = usb_interface_get_next_descriptor(cfg, u, CS_INTERFACE)) { if ((u->bDescriptorSybType == CDC_DESCRIPTOR_UNION) && (u->bControlInterface == iface->bInterfaceNumber) && (u->bFunctionLength > sizeof(CDC_UNION_DESCRIPTOR))) break; } if (u == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning - no UNION descriptor, skipping interface\n"); #endif //USBD_CDC_ACM_DEBUG continue; } data_iface = ((uint8_t*)u)[sizeof(CDC_UNION_DESCRIPTOR)]; diface = usb_find_interface(cfg, data_iface); if (diface == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning no data interface\n"); #endif //USBD_CDC_ACM_DEBUG continue; } #if (USBD_CDC_ACM_DEBUG) printf("Found USB CDC ACM data interface: %d\n", data_iface); #endif //USBD_CDC_ACM_DEBUG ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, diface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning no data EP, skipping interface\n"); #endif //USBD_CDC_ACM_DEBUG continue; } data_ep = USB_EP_NUM(ep->bEndpointAddress); data_ep_size = ep->wMaxPacketSize; control_iface = iface->bInterfaceNumber; control_ep = control_ep_size = 0; ep = (USB_ENDPOINT_DESCRIPTOR*)usb_interface_get_first_descriptor(cfg, iface, USB_ENDPOINT_DESCRIPTOR_TYPE); if (ep != NULL) { control_ep = USB_EP_NUM(ep->bEndpointAddress); control_ep_size = ep->wMaxPacketSize; } //configuration is ok, applying CDC_ACMD* cdc_acmd = (CDC_ACMD*)malloc(sizeof(CDC_ACMD)); if (cdc_acmd == NULL) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Out of memory\n"); #endif //USBD_CDC_ACM_DEBUG return; } cdc_acmd->data_iface = data_iface; cdc_acmd->data_ep = data_ep; cdc_acmd->data_ep_size = data_ep_size; cdc_acmd->tx = cdc_acmd->rx = NULL; cdc_acmd->tx_stream = cdc_acmd->rx_stream = cdc_acmd->tx_stream_handle = cdc_acmd->rx_stream_handle = INVALID_HANDLE; cdc_acmd->suspended = false; cdc_acmd->control_iface = control_iface; cdc_acmd->control_ep = control_ep; cdc_acmd->control_ep_size = control_ep_size; cdc_acmd->notify = NULL; cdc_acmd->notify_busy = cdc_acmd->notify_pending = false; #if (USBD_CDC_ACM_FLOW_CONTROL) cdc_acmd->flow_sending = false; cdc_acmd->flow_changed = false; cdc_acmd->break_count = 0; #endif //USBD_CDC_ACM_FLOW_CONTROL #if (USBD_CDC_ACM_TX_STREAM_SIZE) cdc_acmd->tx = io_create(cdc_acmd->data_ep_size); cdc_acmd->tx_stream = stream_create(USBD_CDC_ACM_RX_STREAM_SIZE); cdc_acmd->tx_stream_handle = stream_open(cdc_acmd->tx_stream); if (cdc_acmd->tx == NULL || cdc_acmd->tx_stream_handle == INVALID_HANDLE) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Out of memory\n"); #endif //USBD_CDC_ACM_DEBUG cdc_acmd_destroy(cdc_acmd); return; } cdc_acmd->tx_size = 0; cdc_acmd->tx_idle = true; usbd_usb_ep_open(usbd, USB_EP_IN | cdc_acmd->data_ep, USB_EP_BULK, cdc_acmd->data_ep_size); stream_listen(cdc_acmd->tx_stream, USBD_IFACE(cdc_acmd->data_iface, 0), HAL_USBD_IFACE); #endif //USBD_CDC_ACM_TX_STREAM_SIZE #if (USBD_CDC_ACM_RX_STREAM_SIZE) cdc_acmd->rx = io_create(cdc_acmd->data_ep_size); cdc_acmd->rx_stream = stream_create(USBD_CDC_ACM_RX_STREAM_SIZE); cdc_acmd->rx_stream_handle = stream_open(cdc_acmd->rx_stream); if (cdc_acmd->rx == NULL || cdc_acmd->rx_stream_handle == INVALID_HANDLE) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Out of memory\n"); #endif //USBD_CDC_ACM_DEBUG cdc_acmd_destroy(cdc_acmd); return; } cdc_acmd->rx_free = 0; usbd_usb_ep_open(usbd, cdc_acmd->data_ep, USB_EP_BULK, cdc_acmd->data_ep_size); usbd_usb_ep_read(usbd, cdc_acmd->data_ep, cdc_acmd->rx, cdc_acmd->data_ep_size); #endif //USBD_CDC_ACM_RX_STREAM_SIZE usbd_register_interface(usbd, cdc_acmd->data_iface, &__CDC_ACMD_CLASS, cdc_acmd); usbd_register_endpoint(usbd, cdc_acmd->data_iface, cdc_acmd->data_ep); if (control_ep_size) { if (cdc_acmd->control_ep_size < 16) { #if (USBD_CDC_ACM_DEBUG) printf("USB CDC ACM: Warning - control endpoint is too small(%d), 16 at least required to fit notify", cdc_acmd->control_ep_size); #endif //USBD_CDC_ACM_DEBUG cdc_acmd->notify = io_create(16); } else cdc_acmd->notify = io_create(cdc_acmd->control_ep_size); if (cdc_acmd->notify == NULL) { cdc_acmd_destroy(cdc_acmd); return; } usbd_usb_ep_open(usbd, USB_EP_IN | cdc_acmd->control_ep, USB_EP_INTERRUPT, cdc_acmd->control_ep_size); usbd_register_interface(usbd, cdc_acmd->control_iface, &__CDC_ACMD_CLASS, cdc_acmd); usbd_register_endpoint(usbd, cdc_acmd->control_iface, cdc_acmd->control_ep); cdc_acmd_notify_serial_state(usbd, cdc_acmd, CDC_SERIAL_STATE_DCD | CDC_SERIAL_STATE_DSR); } cdc_acmd->DTR = cdc_acmd->RTS = false; cdc_acmd->baud.baud = 115200; cdc_acmd->baud.data_bits = 8; cdc_acmd->baud.parity = 'N'; cdc_acmd->baud.stop_bits = 1; } }