# HG changeset patch # User Paul Boddie # Date 1361656704 0 # Node ID 34eb855a91a5ff3c61241c145511a40339abdb43 # Parent b58a34713be6cd533947832ef03c42a367bae104 Added a device abstraction, storage of device descriptors, and second reset handling. Made various diagnostic statements conditional. diff -r b58a34713be6 -r 34eb855a91a5 test.c --- a/test.c Sat Feb 23 19:34:47 2013 +0000 +++ b/test.c Sat Feb 23 21:58:24 2013 +0000 @@ -19,6 +19,7 @@ #include #include #include +#include /* Found in Python's asdl.h. */ @@ -33,9 +34,19 @@ MAX_DEVSTATE_INIT = 0, MAX_DEVSTATE_CONNECTED = 1, MAX_DEVSTATE_RESET = 2, - MAX_DEVSTATE_READY = 3 + MAX_DEVSTATE_INSPECTED = 3, + MAX_DEVSTATE_RESET_AGAIN = 4, + MAX_DEVSTATE_READY = 5 } max_devstate; +/* Device details. */ + +typedef struct +{ + bool in_toggle, out_toggle; + struct usb_device_descriptor desc; +} max_device; + /* Pin assignments: * * Sniffer UBB Shield @@ -507,7 +518,8 @@ /** * Handle the connection or disconnection of a device, returning true if the - * device is now connected or false otherwise. + * device is now connected or false otherwise. If the device is connected, a + * bus reset is performed. */ bool devicechanged() { @@ -565,34 +577,37 @@ setup[7] = length >> 8; } -bool max_init_device(bool *in_toggle) +bool max_init_device(max_device *device) { 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); + max_recv(0, 0, data, &len, &device->in_toggle); max_control_status(true); 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); + memcpy(&device->desc, data, sizeof(struct usb_device_descriptor)); + printf("bLength: %d\n", device->desc.bLength); + printf("bDescriptorType: %d\n", device->desc.bDescriptorType); + printf("bcdUSB: %d\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("iManufacturer: %d\n", device->desc.iManufacturer); + printf("iProduct: %d\n", device->desc.iProduct); + printf("iSerialNumber: %d\n", device->desc.iSerialNumber); + printf("bNumConfigurations: %d\n", device->desc.bNumConfigurations); + + /* Reset the device. */ + + max_write(MAX_REG_HCTL, MAX_HCTL_BUSRST); return true; } @@ -610,9 +625,13 @@ { uint8_t status = 0, revision = 0; uint16_t count; - bool in_toggle = 0, bus_event, data_event, suspended_event, connection_event, frame_event; + bool bus_event, data_event, suspended_event, connection_event, frame_event; + max_device device; max_devstate devstate = MAX_DEVSTATE_INIT; + device.in_toggle = false; + device.out_toggle = false; + signal(SIGINT, &shutdown); if (ubb_open(0) < 0) { @@ -695,18 +714,26 @@ { if (!PIN(MAX_INT)) { + /* Obtain interrupt conditions. */ + status = max_read(MAX_REG_HIRQ, NULL); - if ((bus_event = status & MAX_HIRQ_BUSEVENTIRQ)) - printf("Bus "); - if ((data_event = status & MAX_HIRQ_RCVDAVIRQ)) - printf("Data "); - if ((suspended_event = status & MAX_HIRQ_SUSDNIRQ)) - printf("Suspended "); - if ((connection_event = status & MAX_HIRQ_CONDETIRQ)) - printf("Connection "); + bus_event = status & MAX_HIRQ_BUSEVENTIRQ; + data_event = status & MAX_HIRQ_RCVDAVIRQ; + suspended_event = status & MAX_HIRQ_SUSDNIRQ; + connection_event = status & MAX_HIRQ_CONDETIRQ; frame_event = status & MAX_HIRQ_FRAMEIRQ; + + #ifdef DEBUG + if (bus_event) printf("Bus "); + if (data_event) printf("Data "); + if (suspended_event) printf("Suspended "); + if (connection_event) printf("Connection "); + if (frame_event) printf("Frame "); printf("\n"); + #endif + + /* Acknowledge the interrupts. */ max_write(MAX_REG_HIRQ, status); @@ -715,6 +742,7 @@ if ((devstate == MAX_DEVSTATE_INIT) && connection_event && devicechanged()) { devstate = MAX_DEVSTATE_CONNECTED; + printf("CONNECTED\n"); } /* Handle device reset initiation. */ @@ -723,15 +751,34 @@ { max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL) | MAX_MODE_SOFKAENAB); devstate = MAX_DEVSTATE_RESET; + printf("RESET\n"); } - /* Handle device reset completion, initiating communications. */ + /* Handle device reset completion, getting device details and + initiating a second reset. */ else if ((devstate == MAX_DEVSTATE_RESET) && frame_event && max_can_send(&status)) { - max_init_device(&in_toggle); + max_init_device(&device); + devstate = MAX_DEVSTATE_INSPECTED; + printf("INSPECTED\n"); + } + + /* Handle the second device reset initiation. */ + + else if ((devstate == MAX_DEVSTATE_INSPECTED) && bus_event) + { + devstate = MAX_DEVSTATE_RESET_AGAIN; + printf("RESET AGAIN\n"); + } + + /* Handle the second device reset completion, initiating communications. */ + + else if ((devstate == MAX_DEVSTATE_RESET_AGAIN) && frame_event && max_can_send(&status)) + { + max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL) & ~MAX_MODE_SOFKAENAB); devstate = MAX_DEVSTATE_READY; - max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL) & ~MAX_MODE_SOFKAENAB); + printf("READY\n"); } /* Handle device disconnection. */ @@ -739,6 +786,7 @@ else if ((devstate != MAX_DEVSTATE_INIT) && connection_event) { devstate = MAX_DEVSTATE_INIT; + printf("INIT\n"); } } }