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(); } }
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(); } }