# HG changeset patch # User Paul Boddie # Date 1361061943 0 # Node ID d1bbe7a9319ee4e6231c9325544c21754acc0a63 # Parent 2da6d7a3fe1b19a3b4d0d1d8d2750ddf0a76d279 Added the necessary bus reset sequence before device communication can occur. Added retrieval of a connected device's descriptor. diff -r 2da6d7a3fe1b -r d1bbe7a9319e test.c --- a/test.c Wed Feb 13 00:29:18 2013 +0000 +++ b/test.c Sun Feb 17 00:45:43 2013 +0000 @@ -18,6 +18,7 @@ #include #include #include +#include /* Found in Python's asdl.h. */ @@ -25,6 +26,16 @@ typedef enum {false, true} bool; #endif +/* Initialisation states. */ + +typedef enum +{ + MAX_DEVSTATE_INIT = 0, + MAX_DEVSTATE_CONNECTED = 1, + MAX_DEVSTATE_RESET = 2, + MAX_DEVSTATE_READY = 3 +} max_devstate; + /* Pin assignments: * * Sniffer UBB Shield @@ -96,7 +107,9 @@ #define MAX_HIRQ_FRAMEIRQ 64 #define MAX_HIRQ_HXFRDNIRQ 128 +#define MAX_HIEN_BUSEVENTIE 1 #define MAX_HIEN_CONDETIE 32 +#define MAX_HIEN_FRAMEIE 64 #define MAX_MODE_PERIPHERAL 0 #define MAX_MODE_HOST 1 @@ -111,6 +124,7 @@ #define MAX_MODE_HOST_FULLSPEED MAX_MODE_HOST_ENABLED #define MAX_MODE_HOST_LOWSPEED MAX_MODE_HOST_ENABLED | MAX_MODE_LOWSPEED +#define MAX_HCTL_BUSRST 1 #define MAX_HCTL_SAMPLEBUS 4 #define MAX_HCTL_RCVTOG0 16 #define MAX_HCTL_RCVTOG1 32 @@ -216,11 +230,12 @@ /** * Return whether data can be sent. */ -bool max_can_send() +bool max_can_send(uint8_t *status) { - uint8_t status = max_read(MAX_REG_HIRQ, NULL); - - return !(status & MAX_HIRQ_SNDBAVIRQ); + if (status == NULL) + return max_read(MAX_REG_HIRQ, NULL) & MAX_HIRQ_SNDBAVIRQ; + else + return *status & MAX_HIRQ_SNDBAVIRQ; } /** @@ -316,6 +331,7 @@ { uint8_t status, hrsl = 0; + printf("Writing FIFO with setup...\n"); max_write_fifo(0, setup, 8); /* Set the address. */ @@ -326,11 +342,14 @@ do { + printf("Initiating transfer...\n"); status = max_write(MAX_REG_HXFR, MAX_HXFR_SETUP); status = max_wait_transfer(status); hrsl = max_read(MAX_REG_HRSL, &status); + printf("HRSL = %x\n", hrsl); + sleep(1); } - while ((hrsl & MAX_HRSL_HRSLT) != 0); + while (hrsl & MAX_HRSL_HRSLT); return status; } @@ -367,7 +386,7 @@ hrsl = max_read(MAX_REG_HRSL, &status); } - while ((hrsl & MAX_HRSL_HRSLT) != 0); + while (hrsl & MAX_HRSL_HRSLT); if (endpoint) *toggle = max_get_send_toggle(); @@ -407,7 +426,7 @@ hrsl = max_read(MAX_REG_HRSL, &status); } - while ((hrsl & MAX_HRSL_HRSLT) != 0); + while (hrsl & MAX_HRSL_HRSLT); do { @@ -515,6 +534,9 @@ max_write(MAX_REG_MODE, MAX_MODE_HOST_FULLSPEED); } + /* Reset the device. */ + + max_write(MAX_REG_HCTL, MAX_HCTL_BUSRST); return true; } @@ -533,6 +555,39 @@ setup[7] = length >> 8; } +bool max_init_device(bool *in_toggle) +{ + uint8_t data[64], len = 64, setup[8]; + struct usb_device_descriptor *desc; + + 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, in_toggle); + + if (len >= sizeof(struct usb_device_descriptor)) + { + desc = (struct usb_device_descriptor *) data; + printf("bLength: %d\n", desc->bLength); + printf("bDescriptorType: %d\n", desc->bDescriptorType); + printf("bcdUSB: %d\n", desc->bcdUSB); + printf("bDeviceClass: %d\n", desc->bDeviceClass); + printf("bDeviceSubClass: %d\n", desc->bDeviceSubClass); + printf("bDeviceProtocol: %d\n", desc->bDeviceProtocol); + printf("bMaxPacketSize0: %d\n", desc->bMaxPacketSize0); + printf("idVendor: %x\n", desc->idVendor); + printf("idProduct: %x\n", desc->idProduct); + printf("bcdDevice: %d\n", desc->bcdDevice); + printf("iManufacturer: %d\n", desc->iManufacturer); + printf("iProduct: %d\n", desc->iProduct); + printf("iSerialNumber: %d\n", desc->iSerialNumber); + printf("bNumConfigurations: %d\n", desc->bNumConfigurations); + return true; + } + + return false; +} + void shutdown(int signum) { printf("Closing...\n"); @@ -545,7 +600,7 @@ uint8_t status = 0, revision = 0; uint16_t count; bool in_toggle = 0; - uint8_t data[64], len = 64, setup[8]; + max_devstate devstate = MAX_DEVSTATE_INIT; signal(SIGINT, &shutdown); @@ -595,8 +650,8 @@ printf("Setting INT signalling...\n"); status = max_write(MAX_REG_CPUCTL, MAX_CPUCTL_IE); - printf("Setting connection signalling...\n"); - status = max_write(MAX_REG_HIEN, MAX_HIEN_CONDETIE); + printf("Setting event signalling...\n"); + status = max_write(MAX_REG_HIEN, MAX_HIEN_CONDETIE | MAX_HIEN_FRAMEIE | MAX_HIEN_BUSEVENTIE); /* Check various registers. */ @@ -620,19 +675,41 @@ { status = max_read(MAX_REG_HIRQ, NULL); - if ((status & MAX_HIRQ_CONDETIRQ) && devicechanged() && max_can_send()) + if (status & MAX_HIRQ_BUSEVENTIRQ) + printf("Bus "); + if (status & MAX_HIRQ_RCVDAVIRQ) + printf("Data "); + if (status & MAX_HIRQ_SUSDNIRQ) + printf("Suspended "); + if (status & MAX_HIRQ_CONDETIRQ) + printf("Connection "); + if (status & MAX_HIRQ_FRAMEIRQ) + printf("Frame "); + printf("\n"); + + /* Detect device connection/disconnection. */ + + if ((devstate == MAX_DEVSTATE_INIT) && (status & MAX_HIRQ_CONDETIRQ) && devicechanged()) { - 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, &in_toggle); + devstate = MAX_DEVSTATE_CONNECTED; } - if (status & MAX_HIRQ_SUSDNIRQ) - printf("Suspend done.\n"); - if (status & MAX_HIRQ_BUSEVENTIRQ) - printf("Bus event.\n"); - if (status & MAX_HIRQ_RCVDAVIRQ) - printf("Data received.\n"); + + /* Handle device reset initiation. */ + + else if ((devstate == MAX_DEVSTATE_CONNECTED) && (status & MAX_HIRQ_BUSEVENTIRQ)) + { + status = max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL) | MAX_MODE_SOFKAENAB); + devstate = MAX_DEVSTATE_RESET; + } + + /* Handle device reset completion, initiating communications. */ + + else if ((devstate == MAX_DEVSTATE_RESET) && (status & MAX_HIRQ_FRAMEIRQ) && max_can_send(&status)) + { + max_init_device(&in_toggle); + devstate = MAX_DEVSTATE_READY; + status = max_write(MAX_REG_HIEN, MAX_HIEN_CONDETIE | MAX_HIEN_BUSEVENTIE); + } max_write(MAX_REG_HIRQ, status); }