Browse Source

Speed dependent USB config descriptors

teensy4-core
PaulStoffregen 5 years ago
parent
commit
c48ce955ab
2 changed files with 880 additions and 112 deletions
  1. +29
    -19
      teensy4/usb.c
  2. +851
    -93
      teensy4/usb_desc.c

+ 29
- 19
teensy4/usb.c View File

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

+ 851
- 93
teensy4/usb_desc.c
File diff suppressed because it is too large
View File


Loading…
Cancel
Save