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