@@ -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}, |