Parcourir la source

USB compliance (work in progress)

teensy4-core
PaulStoffregen il y a 5 ans
Parent
révision
c378195d1f
2 fichiers modifiés avec 74 ajouts et 5 suppressions
  1. +46
    -3
      teensy4/usb.c
  2. +28
    -2
      teensy4/usb_desc.c

+ 46
- 3
teensy4/usb.c Voir le fichier

@@ -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) {

+ 28
- 2
teensy4/usb_desc.c Voir le fichier

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

Chargement…
Annuler
Enregistrer