Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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;
    }
}