# HG changeset patch # User Paul Boddie # Date 1361668693 0 # Node ID d64ec78641fc4f380abd424aff6b96eea7452a11 # Parent 34eb855a91a5ff3c61241c145511a40339abdb43 Added clearing of the handshake/timeout interrupt. Fixed previously erroneous/deficient communication by moving address register setting out of individual functions and making sure it only gets set once per transaction, adding initialisation of the data toggle for the inbound control transfer associated with the device descriptor, testing for the HRSLT status and not inadvertently exiting the loop waiting for received data. Added a timeout for waiting for received data. Fixed the display of descriptor information. Fixed the data receiving function to be capable of being called more than once. diff -r 34eb855a91a5 -r d64ec78641fc Makefile --- a/Makefile Sat Feb 23 21:58:24 2013 +0000 +++ b/Makefile Sun Feb 24 01:18:13 2013 +0000 @@ -13,7 +13,7 @@ ARCH = mipsel-openwrt-linux CC = $(ARCH)-gcc -CFLAGS = -g -Wall -fPIC -march=mips32 -I$(LIBUBB)/include +CFLAGS = -g -Wall -fPIC -march=mips32 -I$(LIBUBB)/include # -DDEBUG=1 LDFLAGS = -lubb -L$(LIBUBB) #-static #-L$(SYSLIBS) TARGET = test diff -r 34eb855a91a5 -r d64ec78641fc test.c --- a/test.c Sat Feb 23 21:58:24 2013 +0000 +++ b/test.c Sun Feb 24 01:18:13 2013 +0000 @@ -20,6 +20,7 @@ #include #include #include +#include /* Found in Python's asdl.h. */ @@ -291,7 +292,8 @@ status = max_read(MAX_REG_HIRQ, NULL); } - return status; + max_write(MAX_REG_HIRQ, MAX_HIRQ_HXFRDNIRQ); + return max_read(MAX_REG_HIRQ, NULL); } /** @@ -313,32 +315,28 @@ /** * Read the data from the FIFO. */ -void max_read_fifo(uint8_t *data, uint8_t *len, uint8_t *datalimit) +void max_read_fifo(uint8_t **data, uint8_t *len, uint8_t *datalimit) { uint8_t count, received = max_read(MAX_REG_RCVBC, NULL); + printf("Received %d bytes.\n", received); *len += received; - for (count = 0; (count < received) && (data < datalimit); count++) + for (count = 0; (count < received) && (*data < datalimit); count++) { - *data++ = max_read(MAX_REG_RCVFIFO, NULL); + *((*data)++) = max_read(MAX_REG_RCVFIFO, NULL); } } /** - * Send a control request to the given address consisting of the given setup - * data. + * Send a control request consisting of the given setup data. */ -uint8_t max_control(uint8_t address, uint8_t *setup) +uint8_t max_control(uint8_t *setup) { uint8_t status, hrsl; max_write_fifo(0, setup, 8); - /* Set the address. */ - - max_write(MAX_REG_PERADDR, address); - /* Initiate the transfer. */ do @@ -373,22 +371,17 @@ } /** - * Send a request to the given address and endpoint, using the supplied data - * payload with the given length, indicating the preserved toggle state of the - * endpoint (which will be updated). + * Send a request to the given endpoint, using the supplied data payload with + * the given length, indicating the preserved toggle state of the endpoint + * (which will be updated). */ -uint8_t max_send(uint8_t address, uint8_t endpoint, uint8_t *data, uint8_t len, bool *toggle) +uint8_t max_send(uint8_t endpoint, uint8_t *data, uint8_t len, bool *toggle) { uint8_t status, hrsl = 0; max_write_fifo(endpoint, data, len); - if (endpoint) - max_set_send_toggle(*toggle); - - /* Set the address. */ - - max_write(MAX_REG_PERADDR, address); + max_set_send_toggle(*toggle); /* Initiate the transfer. */ @@ -399,36 +392,34 @@ /* Test for usable data. */ - if (!(status & MAX_HIRQ_SNDBAVIRQ)) - continue; + if (status & MAX_HIRQ_SNDBAVIRQ) + { + hrsl = max_read(MAX_REG_HRSL, &status); - hrsl = max_read(MAX_REG_HRSL, &status); + if (!(hrsl & MAX_HRSL_HRSLT)) + break; + } } - while (hrsl & MAX_HRSL_HRSLT); + while (true); - if (endpoint) - *toggle = max_get_send_toggle(); + *toggle = max_get_send_toggle(); return status; } /** - * Make a request for data from the given address and endpoint, collecting it in - * the supplied buffer with the given length, indicating the preserved toggle - * state of the endpoint (which will be updated) The length will be updated to + * Make a request for data from the given endpoint, collecting it in the + * supplied buffer with the given length, indicating the preserved toggle state + * of the endpoint (which will be updated). The length will be updated to * indicate the total length of the received data. */ -uint8_t max_recv(uint8_t address, uint8_t endpoint, uint8_t *data, uint8_t *len, bool *toggle) +bool max_recv(uint8_t endpoint, uint8_t *data, uint8_t *len, bool *toggle) { uint8_t *datalimit = data + *len; uint8_t status, hrsl = 0; - - if (endpoint) - max_set_send_toggle(*toggle); + uint16_t attempt = 1024; - /* Set the address. */ - - max_write(MAX_REG_PERADDR, address); + max_set_recv_toggle(*toggle); /* Initiate the transfer. */ @@ -439,27 +430,31 @@ /* Test for usable data. */ - if (!(status & MAX_HIRQ_RCVDAVIRQ)) - continue; + hrsl = max_read(MAX_REG_HRSL, &status); - hrsl = max_read(MAX_REG_HRSL, &status); + attempt--; } - while (hrsl & MAX_HRSL_HRSLT); + while ((hrsl & MAX_HRSL_HRSLT) && attempt); - do + if (!attempt) { - max_read_fifo(data, len, datalimit); + printf("HRSL is %x\n", hrsl); + return false; + } + + while (status & MAX_HIRQ_RCVDAVIRQ) + { + max_read_fifo(&data, len, datalimit); /* Indicate that all data has been read. */ - status = max_write(MAX_REG_HIRQ, MAX_HIRQ_RCVDAVIRQ); + max_write(MAX_REG_HIRQ, MAX_HIRQ_RCVDAVIRQ); + status = max_read(MAX_REG_HIRQ, NULL); } - while (status & MAX_HIRQ_RCVDAVIRQ); - if (endpoint) - *toggle = max_get_send_toggle(); + *toggle = max_get_recv_toggle(); - return status; + return true; } void chipreset() @@ -582,24 +577,33 @@ uint8_t data[64], len = 64, setup[8]; printf("Sending control request to address 0, endpoint 0...\n"); - setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE); - max_control(0, setup); - max_recv(0, 0, data, &len, &device->in_toggle); + + max_write(MAX_REG_PERADDR, 0); + setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE << 8, 0, USB_DT_DEVICE_SIZE); + max_control(setup); + device->in_toggle = true; + if (!max_recv(0, data, &len, &device->in_toggle)) + return false; max_control_status(true); if (len >= sizeof(struct usb_device_descriptor)) { memcpy(&device->desc, data, sizeof(struct usb_device_descriptor)); + device->desc.bcdUSB = le16toh(device->desc.bcdUSB); + device->desc.idVendor = le16toh(device->desc.idVendor); + device->desc.idProduct = le16toh(device->desc.idProduct); + device->desc.bcdDevice = le16toh(device->desc.bcdDevice); + printf("bLength: %d\n", device->desc.bLength); printf("bDescriptorType: %d\n", device->desc.bDescriptorType); - printf("bcdUSB: %d\n", device->desc.bcdUSB); + printf("bcdUSB: %04x\n", device->desc.bcdUSB); printf("bDeviceClass: %d\n", device->desc.bDeviceClass); printf("bDeviceSubClass: %d\n", device->desc.bDeviceSubClass); printf("bDeviceProtocol: %d\n", device->desc.bDeviceProtocol); printf("bMaxPacketSize0: %d\n", device->desc.bMaxPacketSize0); - printf("idVendor: %x\n", device->desc.idVendor); - printf("idProduct: %x\n", device->desc.idProduct); - printf("bcdDevice: %d\n", device->desc.bcdDevice); + printf("idVendor: %04x\n", device->desc.idVendor); + printf("idProduct: %04x\n", device->desc.idProduct); + printf("bcdDevice: %04x\n", device->desc.bcdDevice); printf("iManufacturer: %d\n", device->desc.iManufacturer); printf("iProduct: %d\n", device->desc.iProduct); printf("iSerialNumber: %d\n", device->desc.iSerialNumber); @@ -759,9 +763,13 @@ else if ((devstate == MAX_DEVSTATE_RESET) && frame_event && max_can_send(&status)) { - max_init_device(&device); - devstate = MAX_DEVSTATE_INSPECTED; - printf("INSPECTED\n"); + if (max_init_device(&device)) + { + devstate = MAX_DEVSTATE_INSPECTED; + printf("INSPECTED\n"); + } + else + printf("FAILED: RESET -> INSPECTED\n"); } /* Handle the second device reset initiation. */