| @@ -315,10 +315,12 @@ transfer_t endpoint0_transfer_data __attribute__ ((aligned(32)));; | |||
| transfer_t endpoint0_transfer_ack __attribute__ ((aligned(32)));; | |||
| */ | |||
| static uint8_t reply_buffer[8]; | |||
| static void endpoint0_setup(uint64_t setupdata) | |||
| { | |||
| setup_t setup; | |||
| uint32_t datalen = 0; | |||
| uint32_t endpoint, dir, ctrl, datalen = 0; | |||
| const usb_descriptor_list_t *list; | |||
| setup.bothwords = setupdata; | |||
| @@ -369,10 +371,51 @@ static void endpoint0_setup(uint64_t setupdata) | |||
| #endif | |||
| endpoint0_receive(NULL, 0, 0); | |||
| return; | |||
| case 0x0880: // GET_CONFIGURATION | |||
| reply_buffer[0] = usb_configuration; | |||
| endpoint0_transmit(reply_buffer, 1, 0); | |||
| return; | |||
| case 0x0080: // GET_STATUS (device) | |||
| reply_buffer[0] = 0; | |||
| reply_buffer[1] = 0; | |||
| endpoint0_transmit(reply_buffer, 2, 0); | |||
| return; | |||
| case 0x0082: // GET_STATUS (endpoint) | |||
| endpoint = setup.wIndex & 0x7F; | |||
| if (endpoint > 7) break; | |||
| dir = setup.wIndex & 0x80; | |||
| ctrl = *((uint32_t *)&USB1_ENDPTCTRL0 + endpoint); | |||
| reply_buffer[0] = 0; | |||
| reply_buffer[1] = 0; | |||
| if ((dir && (ctrl & USB_ENDPTCTRL_TXS)) || (!dir && (ctrl & USB_ENDPTCTRL_RXS))) { | |||
| reply_buffer[0] = 1; | |||
| } | |||
| endpoint0_transmit(reply_buffer, 2, 0); | |||
| return; | |||
| case 0x0302: // SET_FEATURE (endpoint) | |||
| endpoint = setup.wIndex & 0x7F; | |||
| if (endpoint > 7) break; | |||
| dir = setup.wIndex & 0x80; | |||
| if (dir) { | |||
| *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) |= USB_ENDPTCTRL_TXS; | |||
| } else { | |||
| *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) |= USB_ENDPTCTRL_RXS; | |||
| } | |||
| endpoint0_receive(NULL, 0, 0); | |||
| return; | |||
| case 0x0102: // CLEAR_FEATURE (endpoint) | |||
| endpoint = setup.wIndex & 0x7F; | |||
| if (endpoint > 7) break; | |||
| dir = setup.wIndex & 0x80; | |||
| if (dir) { | |||
| *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) &= ~USB_ENDPTCTRL_TXS; | |||
| } else { | |||
| *((volatile uint32_t *)&USB1_ENDPTCTRL0 + endpoint) &= ~USB_ENDPTCTRL_RXS; | |||
| } | |||
| endpoint0_receive(NULL, 0, 0); | |||
| return; | |||
| case 0x0680: // GET_DESCRIPTOR | |||
| case 0x0681: | |||
| //printf("desc:\n"); // yay - sending device descriptor now works!!!! | |||
| for (list = usb_descriptor_list; list->addr != NULL; list++) { | |||
| if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) { | |||
| if ((setup.wValue >> 8) == 3) { | |||
| @@ -68,7 +68,7 @@ | |||
| static uint8_t device_descriptor[] = { | |||
| 18, // bLength | |||
| 1, // bDescriptorType | |||
| 0x10, 0x01, // bcdUSB | |||
| 0x00, 0x02, // bcdUSB | |||
| #ifdef DEVICE_CLASS | |||
| DEVICE_CLASS, // bDeviceClass | |||
| #else | |||
| @@ -116,6 +116,30 @@ static uint8_t device_descriptor[] = { | |||
| 1 // bNumConfigurations | |||
| }; | |||
| static uint8_t qualifier_descriptor[] = { // 9.6.2 Device_Qualifier, page 264 | |||
| 10, // bLength | |||
| 6, // bDescriptorType | |||
| 0x00, 0x02, // bcdUSB | |||
| #ifdef DEVICE_CLASS | |||
| DEVICE_CLASS, // bDeviceClass | |||
| #else | |||
| 0, | |||
| #endif | |||
| #ifdef DEVICE_SUBCLASS | |||
| DEVICE_SUBCLASS, // bDeviceSubClass | |||
| #else | |||
| 0, | |||
| #endif | |||
| #ifdef DEVICE_PROTOCOL | |||
| DEVICE_PROTOCOL, // bDeviceProtocol | |||
| #else | |||
| 0, | |||
| #endif | |||
| EP0_SIZE, // bMaxPacketSize0 | |||
| 1, // bNumConfigurations | |||
| 0 // bReserved | |||
| }; | |||
| // These descriptors must NOT be "const", because the USB DMA | |||
| // has trouble accessing flash memory with enough bandwidth | |||
| // while the processor is executing from flash. | |||
| @@ -648,7 +672,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
| CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress | |||
| 0x03, // bmAttributes (0x03=intr) | |||
| CDC_ACM_SIZE, 0, // wMaxPacketSize | |||
| 64, // bInterval | |||
| 16, // bInterval | |||
| // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | |||
| 9, // bLength | |||
| 4, // bDescriptorType | |||
| @@ -1493,7 +1517,9 @@ void usb_init_serialnumber(void) | |||
| const usb_descriptor_list_t usb_descriptor_list[] = { | |||
| //wValue, wIndex, address, length | |||
| {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, | |||
| {0x0600, 0x0000, qualifier_descriptor, sizeof(qualifier_descriptor)}, | |||
| {0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, | |||
| {0x0700, 0x0000, config_descriptor, sizeof(config_descriptor)}, | |||
| #ifdef SEREMU_INTERFACE | |||
| {0x2200, SEREMU_INTERFACE, seremu_report_desc, sizeof(seremu_report_desc)}, | |||
| {0x2100, SEREMU_INTERFACE, config_descriptor+SEREMU_HID_DESC_OFFSET, 9}, | |||