| static uint32_t endpoint0_notify_mask=0; | static uint32_t endpoint0_notify_mask=0; | ||||
| static uint32_t endpointN_notify_mask=0; | static uint32_t endpointN_notify_mask=0; | ||||
| //static int reset_count=0; | //static int reset_count=0; | ||||
| volatile uint8_t usb_configuration = 0; | |||||
| volatile uint8_t usb_configuration = 0; // non-zero when USB host as configured device | |||||
| volatile uint8_t usb_high_speed = 0; // non-zero if running at 480 Mbit/sec speed | |||||
| static uint8_t endpoint0_buffer[8]; | static uint8_t endpoint0_buffer[8]; | ||||
| static uint8_t usb_reboot_timer = 0; | static uint8_t usb_reboot_timer = 0; | ||||
| extern uint8_t usb_descriptor_buffer[]; // defined in usb_desc.c | |||||
| extern const uint8_t usb_config_descriptor_480[]; | |||||
| extern const uint8_t usb_config_descriptor_12[]; | |||||
| void (*usb_timer0_callback)(void) = NULL; | void (*usb_timer0_callback)(void) = NULL; | ||||
| void (*usb_timer1_callback)(void) = NULL; | void (*usb_timer1_callback)(void) = NULL; | ||||
| if (status & USB_USBSTS_PCI) { | if (status & USB_USBSTS_PCI) { | ||||
| if (USB1_PORTSC1 & USB_PORTSC1_HSP) { | if (USB1_PORTSC1 & USB_PORTSC1_HSP) { | ||||
| //printf("port at 480 Mbit\n"); | //printf("port at 480 Mbit\n"); | ||||
| usb_high_speed = 1; | |||||
| } else { | } else { | ||||
| //printf("port at 12 Mbit\n"); | //printf("port at 12 Mbit\n"); | ||||
| usb_high_speed = 0; | |||||
| } | } | ||||
| } | } | ||||
| if (status & USB_USBSTS_SLI) { // page 3165 | if (status & USB_USBSTS_SLI) { // page 3165 | ||||
| static void endpoint0_setup(uint64_t setupdata) | static void endpoint0_setup(uint64_t setupdata) | ||||
| { | { | ||||
| setup_t setup; | setup_t setup; | ||||
| uint32_t endpoint, dir, ctrl, datalen = 0; | |||||
| uint32_t endpoint, dir, ctrl; | |||||
| const usb_descriptor_list_t *list; | const usb_descriptor_list_t *list; | ||||
| setup.bothwords = setupdata; | setup.bothwords = setupdata; | ||||
| case 0x0900: // SET_CONFIGURATION | case 0x0900: // SET_CONFIGURATION | ||||
| usb_configuration = setup.wValue; | usb_configuration = setup.wValue; | ||||
| // configure all other endpoints | // configure all other endpoints | ||||
| #if 0 | |||||
| volatile uint32_t *reg = &USB1_ENDPTCTRL1; | |||||
| const uint32_t *cfg = usb_endpoint_config_table; | |||||
| int i; | |||||
| for (i=0; i < NUM_ENDPOINTS; i++) { | |||||
| uint32_t n = *cfg++; | |||||
| *reg = n; | |||||
| // TODO: do the TRX & RXR bits self clear?? | |||||
| uint32_t m = n & ~(USB_ENDPTCTRL_TXR | USB_ENDPTCTRL_RXR); | |||||
| *reg = m; | |||||
| //uint32_t p = *reg; | |||||
| //printf(" ep=%d: cfg=%08lX - %08lX - %08lX\n", i + 1, n, m, p); | |||||
| reg++; | |||||
| } | |||||
| #else | |||||
| #if defined(ENDPOINT2_CONFIG) | #if defined(ENDPOINT2_CONFIG) | ||||
| USB1_ENDPTCTRL2 = ENDPOINT2_CONFIG; | USB1_ENDPTCTRL2 = ENDPOINT2_CONFIG; | ||||
| #endif | #endif | ||||
| #if defined(ENDPOINT7_CONFIG) | #if defined(ENDPOINT7_CONFIG) | ||||
| USB1_ENDPTCTRL7 = ENDPOINT7_CONFIG; | USB1_ENDPTCTRL7 = ENDPOINT7_CONFIG; | ||||
| #endif | #endif | ||||
| #endif | |||||
| #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE) | #if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE) | ||||
| usb_serial_configure(); | usb_serial_configure(); | ||||
| #endif | #endif | ||||
| case 0x0681: | case 0x0681: | ||||
| for (list = usb_descriptor_list; list->addr != NULL; list++) { | for (list = usb_descriptor_list; list->addr != NULL; list++) { | ||||
| if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) { | if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) { | ||||
| uint32_t datalen; | |||||
| if ((setup.wValue >> 8) == 3) { | if ((setup.wValue >> 8) == 3) { | ||||
| // for string descriptors, use the descriptor's | // for string descriptors, use the descriptor's | ||||
| // length field, allowing runtime configured length. | // length field, allowing runtime configured length. | ||||
| datalen = list->length; | datalen = list->length; | ||||
| } | } | ||||
| if (datalen > setup.wLength) datalen = setup.wLength; | if (datalen > setup.wLength) datalen = setup.wLength; | ||||
| endpoint0_transmit(list->addr, datalen, 0); | |||||
| // copy the descriptor, from PROGMEM to DMAMEM | |||||
| if (setup.wValue == 0x200) { | |||||
| // config descriptor needs to adapt to speed | |||||
| const uint8_t *src = usb_config_descriptor_12; | |||||
| if (usb_high_speed) src = usb_config_descriptor_480; | |||||
| memcpy(usb_descriptor_buffer, src, datalen); | |||||
| } else if (setup.wValue == 0x700) { | |||||
| // other speed config also needs to adapt | |||||
| const uint8_t *src = usb_config_descriptor_480; | |||||
| if (usb_high_speed) src = usb_config_descriptor_12; | |||||
| memcpy(usb_descriptor_buffer, src, datalen); | |||||
| usb_descriptor_buffer[1] = 7; | |||||
| } else { | |||||
| memcpy(usb_descriptor_buffer, list->addr, datalen); | |||||
| } | |||||
| // prep transmit | |||||
| arm_dcache_flush_delete(usb_descriptor_buffer, datalen); | |||||
| endpoint0_transmit(usb_descriptor_buffer, datalen, 0); | |||||
| return; | return; | ||||
| } | } | ||||
| } | } |