# HG changeset patch # User Paul Boddie # Date 1363191235 0 # Node ID 491e069640b5ffd664a2ad3e27757f2dcdbd7f0f # Parent 75e240b97a8f2386d38cbfc54858e0c04a45c8a6 Complicated the state machine, adding various reset and wait states, introducing an initial 8 byte retrieval of part of the device descriptor. diff -r 75e240b97a8f -r 491e069640b5 test.c --- a/test.c Wed Mar 13 15:25:27 2013 +0000 +++ b/test.c Wed Mar 13 16:13:55 2013 +0000 @@ -33,9 +33,13 @@ typedef enum { MAX_DEVSTATE_INIT = 0, - MAX_DEVSTATE_CONNECTED = 1, - MAX_DEVSTATE_RESET = 2, - MAX_DEVSTATE_READY = 3 + MAX_DEVSTATE_CONNECTED, + MAX_DEVSTATE_START, + MAX_DEVSTATE_RESET, + MAX_DEVSTATE_INSPECTED, + MAX_DEVSTATE_RESET_AGAIN, + MAX_DEVSTATE_ADDRESSING, + MAX_DEVSTATE_READY } max_devstate; /* Device details. */ @@ -562,9 +566,6 @@ max_write(MAX_REG_MODE, MAX_MODE_HOST_FULLSPEED); } - /* Reset the device. */ - - max_write(MAX_REG_HCTL, MAX_HCTL_BUSRST); return true; } @@ -603,7 +604,7 @@ * Get a descriptor from the device having the given type, value and index. * The descriptor buffer is static and must be copied if it is to be preserved. */ -uint8_t *max_get_descriptor(max_device *device, uint8_t type, uint8_t value, uint8_t index) +uint8_t *max_get_descriptor(max_device *device, uint8_t type, uint8_t value, uint8_t index, bool initial) { static uint8_t data[64]; uint8_t len = 64, setup[8]; @@ -612,7 +613,9 @@ max_write(MAX_REG_PERADDR, device->address); - setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, usb_descriptor_type(type) | value, index, usb_descriptor_size(type)); + setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, usb_descriptor_type(type) | value, index, + initial ? 8 : 64); + max_control(setup); if (!max_control_input(data, &len, device)) { @@ -645,7 +648,32 @@ /* Send a "get descriptor" request for the device descriptor. */ - desc = (struct usb_device_descriptor *) max_get_descriptor(device, USB_DT_DEVICE, 0, 0); + desc = (struct usb_device_descriptor *) max_get_descriptor(device, USB_DT_DEVICE, 0, 0, true); + + if (desc != NULL) + { + device->max_packet_size = device->desc.bMaxPacketSize0; + + /* Reset the device. */ + + max_write(MAX_REG_HCTL, MAX_HCTL_BUSRST); + return true; + } + + return false; +} + +bool max_complete_device(max_device *device) +{ + struct usb_device_descriptor *desc; + + printf("Sending control request to address 0, endpoint 0...\n"); + + device->address = 0; + + /* Send a "get descriptor" request for the device descriptor. */ + + desc = (struct usb_device_descriptor *) max_get_descriptor(device, USB_DT_DEVICE, 0, 0, false); if (desc != NULL) { @@ -670,7 +698,6 @@ printf("iSerialNumber: %d\n", device->desc.iSerialNumber); printf("bNumConfigurations: %d\n", device->desc.bNumConfigurations); - device->max_packet_size = device->desc.bMaxPacketSize0; return true; } @@ -788,7 +815,7 @@ int main(int argc, char *argv[]) { - uint8_t status = 0, revision = 0; + uint8_t status = 0, revision = 0, framecount; uint16_t count; bool bus_event, data_event, suspended_event, connection_event, frame_event; max_device device; @@ -872,6 +899,7 @@ if (devicechanged()) { devstate = MAX_DEVSTATE_CONNECTED; + framecount = 200; } /* Enter the main processing loop. */ @@ -908,30 +936,87 @@ if ((devstate == MAX_DEVSTATE_INIT) && connection_event && devicechanged()) { devstate = MAX_DEVSTATE_CONNECTED; + framecount = 200; printf("CONNECTED\n"); } + /* Handle device connection. */ + + else if ((devstate == MAX_DEVSTATE_CONNECTED) && frame_event) + { + if (framecount) + framecount--; + else + { + /* Reset the device. */ + + max_write(MAX_REG_HCTL, MAX_HCTL_BUSRST); + devstate = MAX_DEVSTATE_START; + printf("START\n"); + } + } + /* Handle device reset initiation. */ - else if ((devstate == MAX_DEVSTATE_CONNECTED) && bus_event) + else if ((devstate == MAX_DEVSTATE_START) && bus_event) { - max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL)); devstate = MAX_DEVSTATE_RESET; + framecount = 200; printf("RESET\n"); } /* Handle device reset completion, getting device details and - initiating a second reset. */ + resetting the device again. */ + + else if ((devstate == MAX_DEVSTATE_RESET) && frame_event) + { + if (framecount) + framecount--; + else if (!max_init_device(&device)) + printf("FAILED: RESET -> INSPECTED\n"); + else + { + devstate = MAX_DEVSTATE_INSPECTED; + printf("INSPECTED\n"); + } + } - else if ((devstate == MAX_DEVSTATE_RESET) && frame_event && max_can_send(&status)) + /* Handle second reset initiation. */ + + else if ((devstate == MAX_DEVSTATE_INSPECTED) && bus_event) { - if (!max_init_device(&device)) - printf("FAILED: RESET -> READY\n"); + devstate = MAX_DEVSTATE_RESET_AGAIN; + framecount = 200; + printf("RESET_AGAIN\n"); + } + + /* Handle second reset completion, setting the address. */ + + else if ((devstate == MAX_DEVSTATE_RESET_AGAIN) && frame_event) + { + if (framecount) + framecount--; + else if (!max_complete_device(&device)) + printf("FAILED: RESET_AGAIN -> ADDRESSING\n"); else { max_set_address(&device); - usb_show_languages(max_get_descriptor(&device, USB_DT_STRING, 0, 0)); - usb_show_configuration(max_get_descriptor(&device, USB_DT_CONFIG, 0, 0)); + devstate = MAX_DEVSTATE_ADDRESSING; + framecount = 30; + printf("ADDRESSING\n"); + } + } + + /* Post-addressing. */ + + else if ((devstate == MAX_DEVSTATE_ADDRESSING) && frame_event) + { + if (framecount) + framecount--; + else + { + usb_show_languages(max_get_descriptor(&device, USB_DT_STRING, 0, 0, false)); + usb_show_configuration(max_get_descriptor(&device, USB_DT_CONFIG, 0, 0, false)); devstate = MAX_DEVSTATE_READY; printf("READY\n"); }