/** * Print USB device information. */ int usb_printDeviceInfo(usb_device * device) { int rcode; // char buf[128]; // Read the device descriptor usb_deviceDescriptor deviceDescriptor; rcode = usb_getDeviceDescriptor(device, &deviceDescriptor); if (rcode) return rcode; xSerialPrintf_P(PSTR("\r\nVendor ID: %x\r\n"), deviceDescriptor.idVendor); xSerialPrintf_P(PSTR("Product ID: %x\r\n"), deviceDescriptor.idProduct); xSerialPrintf_P(PSTR("Configuration count: %d\r\n"), deviceDescriptor.bNumConfigurations); xSerialPrintf_P(PSTR("Device class: %d\r\n"), deviceDescriptor.bDeviceClass); xSerialPrintf_P(PSTR("Device subclass: %d\r\n"), deviceDescriptor.bDeviceSubClass); xSerialPrintf_P(PSTR("Device protocol: %d\r\n"), deviceDescriptor.bDeviceProtocol); /* usb_getString(device, deviceDescriptor.iManufacturer, device->firstStringLanguage, 128, buf); avr_serialPrintf("Manufacturer: %d %s\n", deviceDescriptor.iManufacturer, buf); usb_getString(device, deviceDescriptor.iProduct, device->firstStringLanguage, 128, buf); avr_serialPrintf("Product: %s\n", buf); usb_getString(device, deviceDescriptor.iSerialNumber, device->firstStringLanguage, 128, buf); avr_serialPrintf("Serial number: %s\n", buf); */ return 0; }
/** * USB main task. Performs enumeration/cleanup */ void usb_poll(void) { uint8_t i; uint8_t rcode; uint8_t tmpdata; static uint16_t delay = 0; usb_deviceDescriptor deviceDescriptor; // Poll the MAX3421E device. max3421e_poll(); /* modify USB task state if Vbus changed */ tmpdata = max3421e_getVbusState(); switch (tmpdata) { case SE1: //illegal state usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; break; case SE0: //disconnected if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED) { usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; } break; case FSHOST: //attached case LSHOST: if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { delay = xTaskGetTickCount() + USB_SETTLE_DELAY / portTICK_RATE_MS; usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; } break; }// switch( tmpdata switch (usb_task_state) { case USB_DETACHED_SUBSTATE_INITIALIZE: // TODO right now it looks like the USB board is just reset on disconnect. Fire disconnect for all connected // devices. for (i = 1; i < USB_NUMDEVICES; i++) if (deviceTable[i].active) usb_fireEvent(&(deviceTable[i]), USB_DISCONNECT); usb_init(); usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; break; case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here break; case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here break; case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device if (delay < xTaskGetTickCount() ) { usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; } break; case USB_ATTACHED_SUBSTATE_RESET_DEVICE: // Issue bus reset. max3421e_write(MAX_REG_HCTL, bmBUSRST); usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; break; case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: if ((max3421e_read(MAX_REG_HCTL) & bmBUSRST) == 0) { tmpdata = max3421e_read(MAX_REG_MODE) | bmSOFKAENAB; //start SOF generation max3421e_write(MAX_REG_MODE, tmpdata); // max3421e_regWr( rMODE, bmSOFKAENAB ); usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; delay = xTaskGetTickCount() + 20 / portTICK_RATE_MS; //20ms wait after reset per USB spec } break; case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order if (max3421e_read(MAX_REG_HIRQ) & bmFRAMEIRQ) { //when first SOF received we can continue if (delay < xTaskGetTickCount() ) { //20ms passed usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE; } } break; case USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE: // toggle( BPNT_0 ); deviceTable[0].control.maxPacketSize = 8; rcode = usb_getDeviceDescriptor(&deviceTable[0], &deviceDescriptor); if (rcode == 0) { deviceTable[0].control.maxPacketSize = deviceDescriptor.bMaxPacketSize0; usb_task_state = USB_STATE_ADDRESSING; } else { usb_error = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE; usb_task_state = USB_STATE_ERROR; } break; case USB_STATE_ADDRESSING: // Look for an empty spot for (i = 1; i < USB_NUMDEVICES; i++) { if (!deviceTable[i].active) { // Set correct MaxPktSize // deviceTable[i].epinfo = deviceTable[0].epinfo; deviceTable[i].address = i; deviceTable[i].active = true; usb_initEndPoint(&(deviceTable[i].control), 0); //temporary record //until plugged with real device endpoint structure rcode = usb_setAddress(&deviceTable[0], i); if (rcode == 0) { usb_fireEvent(&deviceTable[i], USB_CONNECT); // usb_task_state = USB_STATE_CONFIGURING; // NB: I've bypassed the configuring state, because configuration should be handled // in the usb event handler. usb_task_state = USB_STATE_RUNNING; } else { usb_fireEvent(&deviceTable[i], USB_ADRESSING_ERROR); // TODO remove usb_error at some point? usb_error = USB_STATE_ADDRESSING; usb_task_state = USB_STATE_ERROR; } break; //break if address assigned or error occurred during address assignment attempt } } // If no vacant spot was found in the device table, fire an error. if (usb_task_state == USB_STATE_ADDRESSING) { usb_fireEvent(&deviceTable[i], USB_ADRESSING_ERROR); // No vacant place in devtable usb_error = 0xfe; usb_task_state = USB_STATE_ERROR; } break; case USB_STATE_CONFIGURING: break; case USB_STATE_RUNNING: break; case USB_STATE_ERROR: break; } // xSerialPrintf_P(PSTR("\r\nusb_poll usb_task_state: %u @ Tick: %u"), usb_task_state, xTaskGetTickCount()); // FIXME remove this debugging }
void usb_setupDevice(usb_device_t* device, uint8_t address) { device->num = 0; // device number has to be set to 0 bool success = false; success = usb_getDeviceDescriptor(device); if (!success) { success = usb_getDeviceDescriptor(device); } if (!success) { textColor(ERROR); printf("\nSetup Device interrupted!"); textColor(TEXT); return; } waitForKeyStroke(); device->num = usb_setDeviceAddress(device->disk->port, address); success = usb_getConfigDescriptor(device); if (!success) { success = usb_getConfigDescriptor(device); } if (!success) { textColor(ERROR); printf("\nSetup Device interrupted!"); textColor(TEXT); return; } waitForKeyStroke(); usb_getStringDescriptor(device); waitForKeyStroke(); for (uint8_t i=1; i<4; i++) // fetch 3 strings { usb_getUnicodeStringDescriptor(device, i); waitForKeyStroke(); } usb_setConfiguration(device, 1); // set first configuration waitForKeyStroke(); #ifdef _USB_DIAGNOSIS_ uint8_t config = usb_getConfiguration(device); printf("\nconfiguration: %u", config); // check configuration waitForKeyStroke(); #endif if (device->InterfaceClass != 0x08) { textColor(ERROR); printf("\nThis is no Mass Storage Device! MSD test and addition to device manager will not be carried out."); textColor(TEXT); waitForKeyStroke(); } else { // Disk device->disk->type = &USB_MSD; device->disk->sectorSize = 512; strcpy(device->disk->name, device->productName); attachDisk(device->disk); #ifdef _USB_DIAGNOSIS_ showPortList(); // TEST showDiskList(); // TEST // device, interface, endpoints textColor(HEADLINE); printf("\n\nMSD test now with device: %X interface: %u endpOUT: %u endpIN: %u\n", device, device->numInterfaceMSD, device->numEndpointOutMSD, device->numEndpointInMSD); textColor(TEXT); #endif testMSD(device); // test with some SCSI commands } }