diff --git a/utils/imxtools/hwemul/dev/main.c b/utils/imxtools/hwemul/dev/main.c
index 09bb6c7..328dd2c 100644
--- a/utils/imxtools/hwemul/dev/main.c
+++ b/utils/imxtools/hwemul/dev/main.c
@@ -154,8 +154,8 @@ static inline void imx233_enable_pin_pullup_mask(unsigned bank, uint32_t pin_msk
*/
#define USB_BASE 0x80080000
-#define USB_NUM_ENDPOINTS 2
-#define MAX_PKT_SIZE 1024
+#define USB_NUM_ENDPOINTS 3
+#define MAX_PKT_SIZE_DFLT 64
#define MAX_PKT_SIZE_EP0 64
/* USB device mode registers (Little Endian) */
@@ -427,6 +427,19 @@ static int usb_drv_port_speed(void)
return (REG_PORTSC1 & 0x08000000) ? 1 : 0;
}
+static int usb_drv_max_packet_size(bool hs, int type)
+{
+ switch(type)
+ {
+ case USB_ENDPOINT_XFER_BULK:
+ return hs ? 512 : 64;
+ case USB_ENDPOINT_XFER_INT:
+ return hs ? 1024 : 64;
+ default:
+ return 0;
+ }
+}
+
static void usb_drv_stall(int endpoint, bool stall, bool in)
{
int ep_num = EP_NUM(endpoint);
@@ -1018,17 +1031,18 @@ static void handle_std_dev_desc(struct usb_ctrlrequest *req)
case USB_DT_OTHER_SPEED_CONFIG:
case USB_DT_CONFIG:
{
- int max_packet_size;
-
+ int bulk_max_packet_size, int_max_packet_size;
/* config desc */
- if((req->wValue >> 8) ==USB_DT_CONFIG)
+ if((req->wValue >> 8) == USB_DT_CONFIG)
{
- max_packet_size = (usb_drv_port_speed() ? 512 : 64);
+ bulk_max_packet_size = usb_drv_max_packet_size(usb_drv_port_speed(), USB_ENDPOINT_XFER_BULK);
+ int_max_packet_size = usb_drv_max_packet_size(usb_drv_port_speed(), USB_ENDPOINT_XFER_INT);
config_descriptor.bDescriptorType = USB_DT_CONFIG;
}
else
{
- max_packet_size=(usb_drv_port_speed() ? 64 : 512);
+ bulk_max_packet_size = usb_drv_max_packet_size(!usb_drv_port_speed(), USB_ENDPOINT_XFER_BULK);
+ int_max_packet_size = usb_drv_max_packet_size(!usb_drv_port_speed(), USB_ENDPOINT_XFER_INT);
config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
}
size = sizeof(struct usb_config_descriptor);
@@ -1040,21 +1054,22 @@ static void handle_std_dev_desc(struct usb_ctrlrequest *req)
/* endpoint 1: bulk out */
endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT;
endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
- endpoint_descriptor.wMaxPacketSize = 512;
+ endpoint_descriptor.wMaxPacketSize = bulk_max_packet_size;
memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
sizeof(endpoint_descriptor));
size += sizeof(endpoint_descriptor);
/* endpoint 2: bulk in */
endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN;
endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
- endpoint_descriptor.wMaxPacketSize = 512;
+ endpoint_descriptor.wMaxPacketSize = bulk_max_packet_size;
memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
sizeof(endpoint_descriptor));
size += sizeof(endpoint_descriptor);
/* endpoint 3: int in */
endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN;
endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT;
- endpoint_descriptor.wMaxPacketSize = 1024;
+ endpoint_descriptor.wMaxPacketSize = int_max_packet_size;
+ endpoint_descriptor.bInterval = 32;
memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
sizeof(endpoint_descriptor));
size += sizeof(endpoint_descriptor);
@@ -1367,6 +1382,7 @@ void main(uint32_t arg)
/* reset the controller */
REG_USBCMD |= USBCMD_CTRL_RESET;
while (REG_USBCMD & USBCMD_CTRL_RESET);
+ //REG_PORTSC1 |= PORTSCX_PORT_FORCE_FULL_SPEED;
/* put it in device mode */
REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
/* reset address */
@@ -1374,17 +1390,33 @@ void main(uint32_t arg)
/* prepare qh array */
qh_array[0].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
qh_array[1].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
- qh_array[2].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
- qh_array[3].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
+ qh_array[2].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_DFLT << 16;
+ qh_array[3].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_DFLT << 16;
+ qh_array[4].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_DFLT << 16;
+ qh_array[5].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_DFLT << 16;
/* setup qh */
REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
/* clear setup status */
REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
/* run! */
REG_USBCMD |= USBCMD_RUN;
-
+
+ int speed = -1;
while(1)
{
+ if(speed != usb_drv_port_speed())
+ {
+ speed = usb_drv_port_speed();
+ qh_array[2].max_pkt_length = 1 << 29 |
+ usb_drv_max_packet_size(speed, USB_ENDPOINT_XFER_BULK) << 16;
+ qh_array[3].max_pkt_length = 1 << 29 |
+ usb_drv_max_packet_size(speed, USB_ENDPOINT_XFER_BULK) << 16;
+ qh_array[4].max_pkt_length = 1 << 29 |
+ usb_drv_max_packet_size(speed, USB_ENDPOINT_XFER_INT) << 16;
+ qh_array[5].max_pkt_length = 1 << 29 |
+ usb_drv_max_packet_size(speed, USB_ENDPOINT_XFER_INT) << 16;
+ logf("connected in %s speed mode\n", speed ? "high" : "full");
+ }
/* wait for setup */
while(!(REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0))
;