示例#1
0
void usb_handle_StandardDeviceRequest(BDentry *bdp) {
    unsigned char *packet = bdp->BDADDR;
    int i;

    switch (packet[USB_bRequest]) {
        case USB_REQUEST_GET_STATUS:
            rbdp->BDADDR[0] = usb_device_status & 0xFF;
            rbdp->BDADDR[1] = usb_device_status >> 8;

            // JTR I added usb_ack_dat1() simply so that the handling
            // of STANDARD and CLASS requests (in cdc.c) were consistant
            // rather than have the same thing done in two different ways.

            usb_ack_dat1(rbdp, 2); // JTR common addition for STD and CLASS ACK
            break;
        case USB_REQUEST_CLEAR_FEATURE:
            if (0x01u == packet[USB_wValue]) { // TODO: Remove magic (REMOTE_WAKEUP_FEATURE)
                usb_device_status &= ~0x0002;
                usb_ack_dat1(rbdp, 0); // JTR common addition for STD and CLASS ACK
            } else
                usb_RequestError();
            break;
        case USB_REQUEST_SET_FEATURE:
            if (0x01u == packet[USB_wValue]) { // TODO: Remove magic (REMOTE_WAKEUP_FEATURE)
                usb_device_status |= 0x0002;
                usb_ack_dat1(rbdp, 0); // JTR common addition for STD and CLASS ACK
            } else
                usb_RequestError();
            break;
        case USB_REQUEST_SET_ADDRESS:
            if (0x00u == packet[USB_wValueHigh] && 0x7Fu >= packet[USB_wValue]) {
                usb_addr_pending = packet[USB_wValue];
                usb_ack_dat1(rbdp, 0); // JTR common addition for STD and CLASS ACK
                usb_set_in_handler(0, usb_set_address);
            } else
                usb_RequestError();
            break;


        case USB_REQUEST_GET_DESCRIPTOR:
            switch (packet[USB_bDescriptorType]) {
                case USB_DEVICE_DESCRIPTOR_TYPE:
                    usb_desc_ptr = usb_device_descriptor;
                    usb_desc_len = usb_device_descriptor[0];
                    if ((0 == packet[USB_wLengthHigh] && packet[USB_wLength] < usb_desc_ptr[0]))
                        usb_desc_len = packet[USB_wLength];
                    break;
                case USB_CONFIGURATION_DESCRIPTOR_TYPE:
                    if (packet[USB_bDescriptorIndex] >= usb_device_descriptor[17]) // TODO: remove magic
                        usb_RequestError();
                    usb_desc_ptr = usb_config_descriptor;
                    usb_desc_len = usb_desc_ptr[2] + usb_desc_ptr[3] * 256;
                    for (i = 0; i < packet[USB_bDescriptorIndex]; i++) { // Implicit linked list traversal until requested configuration
                        usb_desc_ptr += usb_desc_len;
                        usb_desc_len = usb_desc_ptr[2] + usb_desc_ptr[3] * 256;
                    }
                    if ((packet[USB_wLengthHigh] < usb_desc_ptr[3]) ||
                            (packet[USB_wLengthHigh] == usb_desc_ptr[3] && packet[USB_wLength] < usb_desc_ptr[2]))
                        usb_desc_len = packet[USB_wLength] + packet[USB_wLengthHigh] * 256;
                    break;
                case USB_STRING_DESCRIPTOR_TYPE:
                    // TODO: Handle language request. For now return standard language.
                    if (packet[USB_bDescriptorIndex] >= usb_num_string_descriptors)
                        usb_RequestError();
                    usb_desc_ptr = usb_string_descriptor;
                    usb_desc_len = usb_desc_ptr[0];
                    for (i = 0; i < packet[USB_bDescriptorIndex]; i++) { // Implicit linked list traversal until requested configuration
                        usb_desc_ptr += usb_desc_len;
                        usb_desc_len = usb_desc_ptr[0];
                    }
                    if ((0 == packet[USB_wLengthHigh] && packet[USB_wLength] < usb_desc_ptr[0]))
                        usb_desc_len = packet[USB_wLength];
                    break;
                case USB_INTERFACE_DESCRIPTOR_TYPE:
                case USB_ENDPOINT_DESCRIPTOR_TYPE:
                default:
                    usb_RequestError();
            }
            usb_send_descriptor(); // Send first part of packet right away
            usb_set_in_handler(0, usb_send_descriptor);
            break;
        case USB_REQUEST_GET_CONFIGURATION:
            rbdp->BDADDR[0] = usb_current_cfg;
            usb_ack_dat1(rbdp, 1); // JTR common addition for STD and CLASS ACK
            //		rbdp->BDCNT = 1;
            //		rbdp->BDSTAT = UOWN + DTS + DTSEN;
            break;

        case USB_REQUEST_SET_CONFIGURATION:
            if (USB_NUM_CONFIGURATIONS >= packet[USB_wValue]) {
                // TODO: Support multiple configurations
                /* Configure endpoints (USB_UEPn - registers) */
                usb_current_cfg = packet[USB_wValue];
                if (usb_current_cfg != 0) {

                    // JTR user_configured_init major addition. This is a CALLBACK to the USER when the device is enumerated.
                    // This is when we setup non EP0 endpoints.
                    // TODO: This really could be a function pointer

                    usb_device_state = CONFIGURED_STATE;
                    user_configured_init();
                } else {
                    usb_device_state = ADDRESS_STATE;
                }

                usb_ack_dat1(rbdp, 0); // JTR common addition for STD and CLASS ACK

            } else
                usb_RequestError();
            break;

        case USB_REQUEST_SET_DESCRIPTOR:
        default:
            usb_RequestError();
    }
}
示例#2
0
文件: usb_stack.c 项目: Xykon/pic-dev
void usb_handle_StandardDeviceRequest(BDentry *bdp) {
    BYTE *packet = bdp->BDADDR;
    int i;

    switch (packet[USB_bRequest]) {
        case USB_REQUEST_GET_STATUS:
            EP0_Inbdp->BDADDR[0] = usb_device_status & 0xFF;
            EP0_Inbdp->BDADDR[1] = usb_device_status >> 8;
            usb_ack_dat1(2);
            break;
        case USB_REQUEST_CLEAR_FEATURE:
            if (0x01u == packet[USB_wValue]) { // TODO: Remove magic (REMOTE_WAKEUP_FEATURE)
                usb_device_status &= ~0x0002;
                usb_ack_dat1(0);
            } else
                usb_RequestError();
            break;
        case USB_REQUEST_SET_FEATURE:
            if (0x01u == packet[USB_wValue]) { // TODO: Remove magic (REMOTE_WAKEUP_FEATURE)
                usb_device_status |= 0x0002;
                usb_ack_dat1(0);
            } else
                usb_RequestError();
            break;
        case USB_REQUEST_SET_ADDRESS:
            if (0x00u == packet[USB_wValueHigh] && 0x7Fu >= packet[USB_wValue]) {
                usb_addr_pending = packet[USB_wValue];
                usb_set_in_handler(0, usb_set_address);
                usb_ack_dat1(0);
            } else
                usb_RequestError();
            break;


        case USB_REQUEST_GET_DESCRIPTOR:
            switch (packet[USB_bDescriptorType]) {
                case USB_DEVICE_DESCRIPTOR_TYPE: // There is only every one in pratice.
                    usb_rom_ptr = usb_device_descriptor;
                    usb_rom_len = usb_device_descriptor[0]; // Get BYTE length from descriptor always at byte [0]
                    if ((0 == packet[USB_wLengthHigh] && packet[USB_wLength] < usb_rom_ptr[0]))
                        usb_rom_len = packet[USB_wLength]; // If the HOST asked for LESS then must adjust count to the smaller number
                    break;

                case USB_CONFIGURATION_DESCRIPTOR_TYPE:
                    if (packet[USB_bDescriptorIndex] >= usb_device_descriptor[17]) {
                        flag_usb_RequestError();
                        break;
                    }

                    usb_rom_ptr = usb_config_descriptor;
                    usb_rom_len = usb_rom_ptr[2] + usb_rom_ptr[3] * 256; // Get WORD length from descriptor always at bytes 2&3 (Low-High)
                    for (i = 0; i < packet[USB_bDescriptorIndex]; i++) { // Implicit linked list traversal until requested configuration
                        usb_rom_ptr += usb_rom_len;
                        usb_rom_len = usb_rom_ptr[2] + usb_rom_ptr[3] * 256; // Get (next) WORD length from descriptor always at bytes 2&3 (Low-High)
                    }
                    if ((packet[USB_wLengthHigh] < usb_rom_ptr[3]) ||
                            (packet[USB_wLengthHigh] == usb_rom_ptr[3] && packet[USB_wLength] < usb_rom_ptr[2]))
                        usb_rom_len = packet[USB_wLength] + packet[USB_wLengthHigh] * 256; // If the HOST asked for LESS then must adjust count to the smaller number
                    break;
                case USB_STRING_DESCRIPTOR_TYPE:
                    // TODO: Handle language request. For now return standard language.
                    if (packet[USB_bDescriptorIndex] >= usb_num_string_descriptors) {
                        flag_usb_RequestError();
                        break;
                    }
                    usb_rom_ptr = usb_string_descriptor;
                    usb_rom_len = usb_rom_ptr[0]; // Get BYTE length from descriptor always at byte [0]
                    for (i = 0; i < packet[USB_bDescriptorIndex]; i++) { // Implicit linked list traversal until requested configuration
                        usb_rom_ptr += usb_rom_len;
                        usb_rom_len = usb_rom_ptr[0];
                    }
                    if ((0 == packet[USB_wLengthHigh] && packet[USB_wLength] < usb_rom_ptr[0]))
                        usb_rom_len = packet[USB_wLength];
                    break;
                case USB_INTERFACE_DESCRIPTOR_TYPE:
                case USB_ENDPOINT_DESCRIPTOR_TYPE:
                default:
                    flag_usb_RequestError();
            }
            if (0 == usbrequesterrorflag) {
                usb_send_rom(); // Send first part of packet right away, the rest is handled by the EP0 IN handler.
                usb_set_in_handler(0, usb_send_rom);
            } else {
                usb_RequestError();
            }

            break;
        case USB_REQUEST_GET_CONFIGURATION:
            EP0_Inbdp->BDADDR[0] = usb_current_cfg;
            usb_ack_dat1(1);
            break;

        case USB_REQUEST_SET_CONFIGURATION:
            if (USB_NUM_CONFIGURATIONS >= packet[USB_wValue]) {
                // TODO: Support multiple configurations
                /* Configure endpoints (USB_UEPn - registers) */
                usb_current_cfg = packet[USB_wValue];
                if (usb_current_cfg != 0) {

                    // JTR user_configured_init major addition. This is a CALLBACK to the USER when the device is enumerated.
                    // This is when we setup non EP0 endpoints.
                    // TODO: This really could be a function pointer

                    usb_device_state = CONFIGURED_STATE;
                    user_configured_init();
                } else {
                    usb_device_state = ADDRESS_STATE;
                }

                usb_ack_dat1(0);

            } else
                usb_RequestError();
            break;

        case USB_REQUEST_SET_DESCRIPTOR:
        default:
            usb_RequestError();
    }
}