1.1 --- a/test.c Sun Feb 24 01:18:13 2013 +0000
1.2 +++ b/test.c Fri Mar 01 23:38:54 2013 +0000
1.3 @@ -46,8 +46,11 @@
1.4 {
1.5 bool in_toggle, out_toggle;
1.6 struct usb_device_descriptor desc;
1.7 + uint8_t address;
1.8 } max_device;
1.9
1.10 +static uint16_t next_address = 1;
1.11 +
1.12 /* Pin assignments:
1.13 *
1.14 * Sniffer UBB Shield
1.15 @@ -157,6 +160,8 @@
1.16 #define max_reg_read(n) (max_reg(n) | MAX_REG_READ)
1.17 #define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE)
1.18
1.19 +#define usb_descriptor_type(n) ((uint16_t) (n << 8))
1.20 +
1.21 void spi_begin()
1.22 {
1.23 CLR(MAX_SS);
1.24 @@ -329,48 +334,6 @@
1.25 }
1.26
1.27 /**
1.28 - * Send a control request consisting of the given setup data.
1.29 - */
1.30 -uint8_t max_control(uint8_t *setup)
1.31 -{
1.32 - uint8_t status, hrsl;
1.33 -
1.34 - max_write_fifo(0, setup, 8);
1.35 -
1.36 - /* Initiate the transfer. */
1.37 -
1.38 - do
1.39 - {
1.40 - status = max_write(MAX_REG_HXFR, MAX_HXFR_SETUP);
1.41 - status = max_wait_transfer(status);
1.42 - hrsl = max_read(MAX_REG_HRSL, &status);
1.43 - }
1.44 - while (hrsl & MAX_HRSL_HRSLT);
1.45 -
1.46 - return status;
1.47 -}
1.48 -
1.49 -/**
1.50 - * Perform a status transaction as part of a larger control transaction.
1.51 - * The out parameter is used to indicate the kind of status transfer to be
1.52 - * performed and should be the inverse of the control transfer direction.
1.53 - */
1.54 -uint8_t max_control_status(bool out)
1.55 -{
1.56 - uint8_t status, hrsl;
1.57 -
1.58 - do
1.59 - {
1.60 - status = max_write(MAX_REG_HXFR, MAX_HXFR_HS | (out ? MAX_HXFR_OUTNIN : 0));
1.61 - status = max_wait_transfer(status);
1.62 - hrsl = max_read(MAX_REG_HRSL, &status);
1.63 - }
1.64 - while (hrsl & MAX_HRSL_HRSLT);
1.65 -
1.66 - return status;
1.67 -}
1.68 -
1.69 -/**
1.70 * Send a request to the given endpoint, using the supplied data payload with
1.71 * the given length, indicating the preserved toggle state of the endpoint
1.72 * (which will be updated).
1.73 @@ -457,6 +420,54 @@
1.74 return true;
1.75 }
1.76
1.77 +/**
1.78 + * Send a control request consisting of the given setup data.
1.79 + */
1.80 +uint8_t max_control(uint8_t *setup)
1.81 +{
1.82 + uint8_t status, hrsl;
1.83 +
1.84 + max_write_fifo(0, setup, 8);
1.85 +
1.86 + /* Initiate the transfer. */
1.87 +
1.88 + do
1.89 + {
1.90 + status = max_write(MAX_REG_HXFR, MAX_HXFR_SETUP);
1.91 + status = max_wait_transfer(status);
1.92 + hrsl = max_read(MAX_REG_HRSL, &status);
1.93 + }
1.94 + while (hrsl & MAX_HRSL_HRSLT);
1.95 +
1.96 + return status;
1.97 +}
1.98 +
1.99 +bool max_control_input(uint8_t *data, uint8_t *len, max_device *device)
1.100 +{
1.101 + device->in_toggle = true;
1.102 + return max_recv(0, data, len, &device->in_toggle);
1.103 +}
1.104 +
1.105 +/**
1.106 + * Perform a status transaction as part of a larger control transaction.
1.107 + * The out parameter is used to indicate the kind of status transfer to be
1.108 + * performed and should be the inverse of the control transfer direction.
1.109 + */
1.110 +uint8_t max_control_status(bool out)
1.111 +{
1.112 + uint8_t status, hrsl;
1.113 +
1.114 + do
1.115 + {
1.116 + status = max_write(MAX_REG_HXFR, MAX_HXFR_HS | (out ? MAX_HXFR_OUTNIN : 0));
1.117 + status = max_wait_transfer(status);
1.118 + hrsl = max_read(MAX_REG_HRSL, &status);
1.119 + }
1.120 + while (hrsl & MAX_HRSL_HRSLT);
1.121 +
1.122 + return status;
1.123 +}
1.124 +
1.125 void chipreset()
1.126 {
1.127 printf("Resetting...\n");
1.128 @@ -560,6 +571,9 @@
1.129 return false;
1.130 }
1.131
1.132 +/**
1.133 + * Initialise a USB control request setup payload.
1.134 + */
1.135 void setup_packet(uint8_t *setup, uint8_t request_type, uint8_t request, uint16_t value, uint16_t index, uint16_t length)
1.136 {
1.137 setup[0] = request_type;
1.138 @@ -572,6 +586,11 @@
1.139 setup[7] = length >> 8;
1.140 }
1.141
1.142 +/**
1.143 + * Perform initialisation on a device, obtaining the device details and storing
1.144 + * this information in the device structure, returning true if successful and
1.145 + * false otherwise.
1.146 + */
1.147 bool max_init_device(max_device *device)
1.148 {
1.149 uint8_t data[64], len = 64, setup[8];
1.150 @@ -579,10 +598,12 @@
1.151 printf("Sending control request to address 0, endpoint 0...\n");
1.152
1.153 max_write(MAX_REG_PERADDR, 0);
1.154 - setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE << 8, 0, USB_DT_DEVICE_SIZE);
1.155 +
1.156 + /* Send a "get descriptor" request for the device descriptor. */
1.157 +
1.158 + setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, usb_descriptor_type(USB_DT_DEVICE), 0, USB_DT_DEVICE_SIZE);
1.159 max_control(setup);
1.160 - device->in_toggle = true;
1.161 - if (!max_recv(0, data, &len, &device->in_toggle))
1.162 + if (!max_control_input(data, &len, device))
1.163 return false;
1.164 max_control_status(true);
1.165
1.166 @@ -618,6 +639,61 @@
1.167 return false;
1.168 }
1.169
1.170 +/**
1.171 + * Assign a new address to the given device.
1.172 + */
1.173 +void max_set_address(max_device *device)
1.174 +{
1.175 + uint8_t setup[8];
1.176 +
1.177 + max_write(MAX_REG_PERADDR, 0);
1.178 +
1.179 + device->address = next_address++;
1.180 +
1.181 + printf("Setting device address to %d...\n", device->address);
1.182 +
1.183 + setup_packet(setup, USB_ENDPOINT_OUT, USB_REQ_SET_ADDRESS, device->address, 0, 0);
1.184 + max_control(setup);
1.185 + max_control_status(false);
1.186 +}
1.187 +
1.188 +
1.189 +void max_get_descriptor(max_device *device)
1.190 +{
1.191 + uint8_t data[64], len = 64, setup[8];
1.192 + struct usb_string_descriptor *desc;
1.193 + uint16_t *lang;
1.194 +
1.195 + printf("Sending descriptor request to address %d, endpoint 0...\n", device->address);
1.196 +
1.197 + max_write(MAX_REG_PERADDR, device->address);
1.198 +
1.199 + setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, usb_descriptor_type(USB_DT_STRING), 0, 64);
1.200 + max_control(setup);
1.201 + if (!max_control_input(data, &len, device))
1.202 + {
1.203 + printf("Failed.\n");
1.204 + return;
1.205 + }
1.206 + max_control_status(true);
1.207 +
1.208 + if (len >= sizeof(struct usb_string_descriptor))
1.209 + {
1.210 + desc = (struct usb_string_descriptor *) data;
1.211 +
1.212 + printf("bLength: %d\n", desc->bLength);
1.213 + printf("bDescriptorType: %d\n", desc->bDescriptorType);
1.214 +
1.215 + for (lang = desc->wData; lang < (uint16_t *) (data + desc->bLength); lang++)
1.216 + {
1.217 + printf("wLangId: %04x\n", le16toh(*lang));
1.218 + }
1.219 + }
1.220 +}
1.221 +
1.222 +/**
1.223 + * Handle termination of the process.
1.224 + */
1.225 void shutdown(int signum)
1.226 {
1.227 printf("Closing...\n");
1.228 @@ -772,7 +848,10 @@
1.229 printf("FAILED: RESET -> INSPECTED\n");
1.230 }
1.231
1.232 - /* Handle the second device reset initiation. */
1.233 + /* Handle the second device reset initiation. This is arguably
1.234 + superfluous, since the second reset is typically done because
1.235 + Windows aborts the device descriptor acquisition after 8 bytes
1.236 + because it was only interested in the maximum packet size. */
1.237
1.238 else if ((devstate == MAX_DEVSTATE_INSPECTED) && bus_event)
1.239 {
1.240 @@ -785,7 +864,9 @@
1.241 else if ((devstate == MAX_DEVSTATE_RESET_AGAIN) && frame_event && max_can_send(&status))
1.242 {
1.243 max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL) & ~MAX_MODE_SOFKAENAB);
1.244 + max_set_address(&device);
1.245 devstate = MAX_DEVSTATE_READY;
1.246 + max_get_descriptor(&device);
1.247 printf("READY\n");
1.248 }
1.249