Skip to content

Commit b16e083

Browse files
committed
pbio/drv/usb/usb_nxt: Also use usb_ch9.h for descriptors
1 parent c66cf7d commit b16e083

File tree

1 file changed

+83
-72
lines changed

1 file changed

+83
-72
lines changed

lib/pbio/drv/usb/usb_nxt.c

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "nxos/drivers/aic.h"
2828
#include "nxos/util.h"
2929

30+
#include "usb_ch9.h"
31+
3032
/* The USB controller supports up to 4 endpoints. */
3133
#define PBDRV_USB_NXT_N_ENDPOINTS 4
3234

@@ -96,31 +98,33 @@
9698
* don't have a vendor ID to use. Therefore, we are currently
9799
* piggybacking on Lego's device space, using an unused product ID.
98100
*/
99-
static const uint8_t pbdrv_usb_nxt_device_descriptor[] = {
100-
18, USB_DESC_TYPE_DEVICE, /* Packet size and type. */
101-
0x10, 0x02, /* This packet is USB 2.1 (needed for BOS descriptors). */
102-
PBIO_PYBRICKS_USB_DEVICE_CLASS, /* Class code. */
103-
PBIO_PYBRICKS_USB_DEVICE_SUBCLASS, /* Sub class code. */
104-
PBIO_PYBRICKS_USB_DEVICE_PROTOCOL, /* Device protocol. */
105-
MAX_EP0_SIZE, /* Maximum packet size for EP0 (control endpoint). */
106-
0x94, 0x06, /* Vendor ID : LEGO */
107-
0x02, 0x00, /* Product ID : NXT */
108-
0x00, 0x02, /* Product revision: 2.0.0. */
109-
1, /* Index of the vendor string. */
110-
2, /* Index of the product string. */
111-
0, /* Index of the serial number (none for us). */
112-
1, /* The number of possible configurations. */
101+
static const pbdrv_usb_dev_desc_t pbdrv_usb_nxt_device_descriptor = {
102+
.bLength = sizeof(pbdrv_usb_dev_desc_t),
103+
.bDescriptorType = DESC_TYPE_DEVICE,
104+
.bcdUSB = 0x0210, /* This packet is USB 2.1 (needed for BOS descriptors). */
105+
.bDeviceClass = PBIO_PYBRICKS_USB_DEVICE_CLASS,
106+
.bDeviceSubClass = PBIO_PYBRICKS_USB_DEVICE_SUBCLASS,
107+
.bDeviceProtocol = PBIO_PYBRICKS_USB_DEVICE_PROTOCOL,
108+
.bMaxPacketSize0 = MAX_EP0_SIZE,
109+
.idVendor = 0x0694, /* Vendor ID : LEGO */
110+
.idProduct = 0x0002, /* Product ID : NXT */
111+
.bcdDevice = 0x0200, /* Product revision: 2.0.0. */
112+
.iManufacturer = 1,
113+
.iProduct = 2,
114+
.iSerialNumber = 0,
115+
.bNumConfigurations = 1,
113116
};
114117

115-
static const uint8_t pbdrv_usb_nxt_dev_qualifier_desc[] = {
116-
10, USB_DESC_TYPE_DEVICE_QUALIFIER, /* Packet size and type. */
117-
0x10, 0x02, /* This packet is USB 2.1. */
118-
PBIO_PYBRICKS_USB_DEVICE_CLASS, /* Class code */
119-
PBIO_PYBRICKS_USB_DEVICE_SUBCLASS, /* Sub class code */
120-
PBIO_PYBRICKS_USB_DEVICE_PROTOCOL, /* Device protocol */
121-
MAX_EP0_SIZE, /* Maximum packet size for EP0. */
122-
1, /* The number of possible configurations. */
123-
0, /* Reserved for future use, must be zero. */
118+
static const pbdrv_usb_dev_qualifier_desc_t pbdrv_usb_nxt_dev_qualifier_desc = {
119+
.bLength = sizeof(pbdrv_usb_dev_qualifier_desc_t),
120+
.bDescriptorType = DESC_TYPE_DEVICE_QUALIFIER,
121+
.bcdUSB = 0x0210, /* This packet is USB 2.1. */
122+
.bDeviceClass = PBIO_PYBRICKS_USB_DEVICE_CLASS,
123+
.bDeviceSubClass = PBIO_PYBRICKS_USB_DEVICE_SUBCLASS,
124+
.bDeviceProtocol = PBIO_PYBRICKS_USB_DEVICE_PROTOCOL,
125+
.bMaxPacketSize0 = MAX_EP0_SIZE,
126+
.bNumConfigurations = 1,
127+
.bReserved = 0,
124128
};
125129

126130
// These enumerations are specific to the configuration of this device.
@@ -181,54 +185,61 @@ static const uint8_t pbdrv_usb_nxt_bos_desc[] = {
181185
0x00, /* bAltEnumCode = Does not support alternate enumeration */
182186
};
183187

184-
static const uint8_t pbdrv_usb_nxt_full_config[] = {
185-
0x09, USB_DESC_TYPE_CONFIG, /* Descriptor size and type. */
186-
0x20, 0x00, /* Total length of the configuration, interface
187-
* description included.
188-
*/
189-
1, /* The number of interfaces declared by this configuration. */
190-
1, /* The ID for this configuration. */
191-
0, /* Index of the configuration description string (none). */
192-
193-
/* Configuration attributes bitmap. Bit 7 (MSB) must be 1, bit 6 is
194-
* 1 because the NXT is self-powered, bit 5 is 0 because the NXT
195-
* doesn't support remote wakeup, and bits 0-4 are 0 (reserved).
196-
*/
197-
0xC0,
198-
0, /* Device power consumption, for non self-powered devices. */
199-
200-
/*
201-
* This is the descriptor for the interface associated with the
202-
* configuration.
203-
*/
204-
0x09, USB_DESC_TYPE_INT, /* Descriptor size and type. */
205-
0x00, /* Interface index. */
206-
0x00, /* ID for this interface configuration. */
207-
0x02, /* The number of endpoints defined by this interface
208-
* (excluding EP0).
209-
*/
210-
PBIO_PYBRICKS_USB_DEVICE_CLASS, /* Interface class ("Vendor specific"). */
211-
PBIO_PYBRICKS_USB_DEVICE_SUBCLASS, /* Interface subclass (see above). */
212-
PBIO_PYBRICKS_USB_DEVICE_PROTOCOL, /* Interface protocol (see above). */
213-
0x00, /* Index of the string descriptor for this interface (none). */
214-
188+
typedef struct PBDRV_PACKED {
189+
pbdrv_usb_conf_desc_t conf_desc;
190+
pbdrv_usb_iface_desc_t iface_desc;
191+
pbdrv_usb_ep_desc_t ep_out;
192+
pbdrv_usb_ep_desc_t ep_in;
193+
} pbdrv_usb_nxt_conf_t;
194+
195+
static const pbdrv_usb_nxt_conf_t pbdrv_usb_nxt_full_config = {
196+
.conf_desc = {
197+
.bLength = sizeof(pbdrv_usb_conf_desc_t),
198+
.bDescriptorType = DESC_TYPE_CONFIGURATION,
199+
.wTotalLength = sizeof(pbdrv_usb_nxt_conf_t),
200+
.bNumInterfaces = 1,
201+
.bConfigurationValue = 1,
202+
.iConfiguration = 0,
203+
/* Configuration attributes bitmap. Bit 7 (MSB) must be 1, bit 6 is
204+
* 1 because the NXT is self-powered, bit 5 is 0 because the NXT
205+
* doesn't support remote wakeup, and bits 0-4 are 0 (reserved).
206+
*/
207+
.bmAttributes = USB_CONF_DESC_BM_ATTR_MUST_BE_SET | USB_CONF_DESC_BM_ATTR_SELF_POWERED,
208+
.bMaxPower = 0,
209+
},
210+
.iface_desc = {
211+
.bLength = sizeof(pbdrv_usb_iface_desc_t),
212+
.bDescriptorType = DESC_TYPE_INTERFACE,
213+
.bInterfaceNumber = 0,
214+
.bAlternateSetting = 0,
215+
.bNumEndpoints = 2,
216+
.bInterfaceClass = PBIO_PYBRICKS_USB_DEVICE_CLASS,
217+
.bInterfaceSubClass = PBIO_PYBRICKS_USB_DEVICE_SUBCLASS,
218+
.bInterfaceProtocol = PBIO_PYBRICKS_USB_DEVICE_PROTOCOL,
219+
.iInterface = 0,
220+
},
215221
/*
216222
* Descriptor for EP1.
217223
*/
218-
7, USB_DESC_TYPE_ENDPT, /* Descriptor length and type. */
219-
0x1, /* Endpoint number. MSB is zero, meaning this is an OUT EP. */
220-
0x2, /* Endpoint type (bulk). */
221-
MAX_RCV_SIZE, 0x00, /* Maximum packet size (64). */
222-
0, /* EP maximum NAK rate (device never NAKs). */
223-
224+
.ep_out = {
225+
.bLength = sizeof(pbdrv_usb_ep_desc_t),
226+
.bDescriptorType = DESC_TYPE_ENDPOINT,
227+
.bEndpointAddress = 0x01, /* Endpoint number. MSB is zero, meaning this is an OUT EP. */
228+
.bmAttributes = EP_TYPE_BULK,
229+
.wMaxPacketSize = MAX_RCV_SIZE,
230+
.bInterval = 0,
231+
},
224232
/*
225233
* Descriptor for EP2.
226234
*/
227-
7, USB_DESC_TYPE_ENDPT, /* Descriptor length and type. */
228-
0x82, /* Endpoint number. MSB is one, meaning this is an IN EP. */
229-
0x2, /* Endpoint type (bulk). */
230-
MAX_RCV_SIZE, 0x00, /* Maximum packet size (64). */
231-
0, /* EP maximum NAK rate (device never NAKs). */
235+
.ep_in = {
236+
.bLength = sizeof(pbdrv_usb_ep_desc_t),
237+
.bDescriptorType = DESC_TYPE_ENDPOINT,
238+
.bEndpointAddress = 0x82, /* Endpoint number. MSB is one, meaning this is an IN EP. */
239+
.bmAttributes = EP_TYPE_BULK,
240+
.wMaxPacketSize = MAX_SND_SIZE,
241+
.bInterval = 0,
242+
},
232243
};
233244

234245
static const uint8_t pbdrv_usb_nxt_string_desc[] = {
@@ -625,17 +636,17 @@ static void pbdrv_usb_handle_std_request(pbdrv_usb_nxt_setup_packet_t *packet) {
625636
index = (packet->value & USB_WVALUE_INDEX);
626637
switch ((packet->value & USB_WVALUE_TYPE) >> 8) {
627638
case USB_DESC_TYPE_DEVICE: /* Device descriptor */
628-
size = pbdrv_usb_nxt_device_descriptor[0];
629-
pbdrv_usb_nxt_write_data(0, pbdrv_usb_nxt_device_descriptor,
639+
size = pbdrv_usb_nxt_device_descriptor.bLength;
640+
pbdrv_usb_nxt_write_data(0, (const uint8_t *)&pbdrv_usb_nxt_device_descriptor,
630641
MIN(size, packet->length));
631642
break;
632643

633644
case USB_DESC_TYPE_CONFIG: /* Configuration descriptor */
634-
pbdrv_usb_nxt_write_data(0, pbdrv_usb_nxt_full_config,
635-
MIN(pbdrv_usb_nxt_full_config[2], packet->length));
645+
pbdrv_usb_nxt_write_data(0, (const uint8_t *)&pbdrv_usb_nxt_full_config,
646+
MIN(pbdrv_usb_nxt_full_config.conf_desc.wTotalLength, packet->length));
636647

637648
/* TODO: Why? This is not specified in the USB specs. */
638-
if (pbdrv_usb_nxt_full_config[2] < packet->length) {
649+
if (pbdrv_usb_nxt_full_config.conf_desc.wTotalLength < packet->length) {
639650
pbdrv_usb_nxt_send_null();
640651
}
641652
break;
@@ -654,8 +665,8 @@ static void pbdrv_usb_handle_std_request(pbdrv_usb_nxt_setup_packet_t *packet) {
654665
break;
655666

656667
case USB_DESC_TYPE_DEVICE_QUALIFIER: /* Device qualifier descriptor. */
657-
size = pbdrv_usb_nxt_dev_qualifier_desc[0];
658-
pbdrv_usb_nxt_write_data(0, pbdrv_usb_nxt_dev_qualifier_desc,
668+
size = pbdrv_usb_nxt_dev_qualifier_desc.bLength;
669+
pbdrv_usb_nxt_write_data(0, (const uint8_t *)&pbdrv_usb_nxt_dev_qualifier_desc,
659670
MIN(size, packet->length));
660671
break;
661672

0 commit comments

Comments
 (0)