void WANDongle::setVidPid(uint16_t vid, uint16_t pid) { WANDongleInitializer* initializer; for(int i = 0; i < m_totalInitializers; i++) { initializer = m_Initializers[i]; //USB_DBG("initializer=%p", initializer); //USB_DBG("initializer->getSerialVid()=%04x", initializer->getSerialVid()); //USB_DBG("initializer->getSerialPid()=%04x", initializer->getSerialPid()); if ((dev->getVid() == initializer->getSerialVid()) && (dev->getPid() == initializer->getSerialPid())) { USB_DBG("The dongle is in virtual serial mode"); m_pInitializer = initializer; break; } else if ((dev->getVid() == initializer->getMSDVid()) && (dev->getPid() == initializer->getMSDPid())) { USB_DBG("Dongle detected in MSD mode"); m_pInitializer = initializer; break; } initializer++; } //for if(m_pInitializer) { m_pInitializer->setVidPid(vid, pid); } }
int WANDongleSerialPort::readPacket() { USB_DBG("Read packet on %p", this); rx_mtx.lock(); if(lock_rx) { USB_ERR("Fail"); rx_mtx.unlock(); return -1; } if( bulk_in == NULL ) { USB_WARN("Port is disconnected"); rx_mtx.unlock(); return -1; } lock_rx = true; //Receiving rx_mtx.unlock(); // USB_DBG("readPacket"); //lock_rx.lock(); USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer if(res != USB_TYPE_PROCESSING) { //lock_rx.unlock(); USB_ERR("host->bulkRead() returned %d", res); ThisThread::sleep_for(100); return -1; } return 0; }
void WANDongleSerialPort::rxHandler() { if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success { buf_in_read_pos = 0; buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length //lock_rx.unlock(); rx_mtx.lock(); lock_rx = false; //Transmission complete if(cb_rx_en) { rx_mtx.unlock(); listener->readable(); //Call handler from the IRQ context //readPacket() should be called by the handler subsequently once the buffer has been emptied } else { cb_rx_pending = true; //Queue the callback rx_mtx.unlock(); } } else //Error, try reading again { //lock_rx.unlock(); USB_DBG("Trying again"); readPacket(); } }
bool USBHostSerial::connect() { if (dev) { for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { USBDeviceConnected* d = host->getDevice(i); if (dev == d) return true; } disconnect(); } for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { USBDeviceConnected* d = host->getDevice(i); if (d != NULL) { USB_DBG("Trying to connect serial device \r\n"); if(host->enumerate(d, this)) break; USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN); USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT); if (bulk_in && bulk_out) { USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out); dev = d; } } } return dev != NULL; }
int USB_ReadFrom(uint8_t *dst, uint32_t size, uint8_t endpoint) { USB_DBG("RD 0x%X\n",size); for(int i = 0; i < size; i++) { dst[i] = GET8(USB0_CORE+FIFOx+(endpoint<<2)); } return size; }
int USB_WriteTo(uint8_t *src, uint32_t size, uint8_t endpoint) { USB_DBG("WR 0x%X\n",size); for(int i = 0; i < size; i++) { PUT8(USB0_CORE+FIFOx+(endpoint<<2),src[i]); } return size; }
void USBHostHub::rxHandler() { uint32_t status; if (int_in) { if (int_in->getState() == USB_TYPE_IDLE) { for (int port = 1; port <= nb_port; port++) { status = getPortStatus(port); USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status); // if connection status has changed if (status & C_PORT_CONNECTION) { if (status & PORT_CONNECTION) { USB_DBG("[hub handler hub: %d - port: %d] new device connected", dev->getHub(), port); host->deviceConnected(dev->getHub() + 1, port, status & PORT_LOW_SPEED, this); } else { USB_DBG("[hub handler hub: %d - port: %d] device disconnected", dev->getHub(), port); host->deviceDisconnected(dev->getHub() + 1, port, this, 0); } clearPortFeature(C_PORT_CONNECTION_FEATURE, port); } if (status & C_PORT_RESET) { clearPortFeature(C_PORT_RESET_FEATURE, port); } if (status & C_PORT_ENABLE) { clearPortFeature(C_PORT_ENABLE_FEATURE, port); } if ((status & PORT_OVER_CURRENT)) { USB_ERR("OVER CURRENT DETECTED\r\n"); clearPortFeature(PORT_OVER_CURRENT, port); host->deviceDisconnected(dev->getHub() + 1, port, this, 0); } } } host->interruptRead(dev, int_in, buf, 1, false); } }
bool USBHostHub::connect(USBDeviceConnected * dev) { if (dev_connected) { return true; } if(host->enumerate(dev, this)) { init(); return false; } if (hub_device_found) { this->dev = dev; int_in = dev->getEndpoint(hub_intf, INTERRUPT_ENDPOINT, IN); if (!int_in) { init(); return false; } USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, hub_intf); dev->setName("Hub", hub_intf); host->registerDriver(dev, hub_intf, this, &USBHostHub::disconnect); int_in->attach(this, &USBHostHub::rxHandler); // get HUB descriptor host->controlRead( dev, USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS, GET_DESCRIPTOR, 0x29 << 8, 0, buf, sizeof(HubDescriptor)); nb_port = buf[2]; hub_characteristics = buf[3]; USB_DBG("Hub has %d port", nb_port); for (uint8_t j = 1; j <= nb_port; j++) { setPortFeature(PORT_POWER_FEATURE, j); } wait_ms(buf[5]*2); host->interruptRead(dev, int_in, buf, 1, false); dev_connected = true; return true; } return false; }
bool SaraU2DongleInitializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) {//Must return true if the endpoint will be used if( m_hasSwitched ) { USB_DBG("USBEndpoint on Inteface #%d; Type:%d; Direction:%d", intf_nb, type, dir); if( (type == BULK_ENDPOINT) && m_endpointsToFetch ) { m_endpointsToFetch--; return true; } } else { if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch ) { m_endpointsToFetch--; return true; } } return false; }
/*===========================================================================* * hcd_connect_cb * *===========================================================================*/ void hcd_connect_cb(hcd_device_state * dev) { unsigned int if_bitmask; DEBUG_DUMP; /* TODO: Magic numbers like in ddekit/devman */ /* Each bit starting from 0, represents valid interface */ if_bitmask = 0xFFFFFFFF >> (32 - dev->config_tree.num_interfaces); USB_DBG("Interfaces %d, mask %08X", dev->config_tree.num_interfaces, if_bitmask); connect_cb((struct ddekit_usb_dev *)dev, (int)if_bitmask); }
void USBHostHub::portReset(uint8_t port) { // reset port uint32_t status; USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this) setPortFeature(PORT_RESET_FEATURE, port); while(1) { status = getPortStatus(port); if (status & (PORT_ENABLE | PORT_RESET)) break; if (status & PORT_OVER_CURRENT) { USB_ERR("OVER CURRENT DETECTED\r\n"); clearPortFeature(PORT_OVER_CURRENT, port); host->deviceDisconnected(dev->getHub() + 1, port, this, 0); break; } Thread::wait(10); } }
bool USBHostSerial::connect() { if (dev_connected) { return true; } for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { if ((dev = host->getDevice(i)) != NULL) { USB_DBG("Trying to connect serial device\r\n"); if(host->enumerate(dev, this)) break; if (serial_device_found) { bulk_in = dev->getEndpoint(serial_intf, BULK_ENDPOINT, IN); bulk_out = dev->getEndpoint(serial_intf, BULK_ENDPOINT, OUT); if (!bulk_in || !bulk_out) break; USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf); dev->setName("Serial", serial_intf); host->registerDriver(dev, serial_intf, this, &USBHostSerial::init); baud(9600); size_bulk_in = bulk_in->getSize(); size_bulk_out = bulk_out->getSize(); bulk_in->attach(this, &USBHostSerial::rxHandler); bulk_out->attach(this, &USBHostSerial::txHandler); host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); dev_connected = true; return true; } } } init(); return false; }
/** * This functions delegates the setup command to the gadget driver. */ void do_gadget_setup( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl) { int value; u16 w_index = ctrl->wIndex; u16 w_value = ctrl->wValue; u16 w_length = ctrl->wLength; /* usually this just stores reply data in the pre-allocated ep0 buffer, * but config change events will also reconfigure hardware. */ switch (ctrl->bRequest) { case USB_REQ_GET_DESCRIPTOR: if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; //time_out_val = USB_ROM_DRIVER_TIMEOUT;// Wait SetConfig (PC install driver OK) need_check_timeout = 0; switch (w_value >> 8) { case USB_DT_DEVICE: USB_DBG("--get device descriptor\n\n"); value = min(w_length, (u16) sizeof device_desc); usb_memcpy(buff, (char*)&device_desc, value); _pcd->buf = buff; _pcd->length = value; break; case USB_DT_DEVICE_QUALIFIER: USB_DBG("--get device qualifier\n\n"); break; case USB_DT_OTHER_SPEED_CONFIG: DBG("--get other speed configuration descriptor\n"); DBG("--other speed configuration descriptor length :%d\n", value); break; case USB_DT_CONFIG: USB_DBG("--get configuration descriptor: size %d\n",w_length); if(w_length > USB_DT_CONFIG_SIZE) { value = TOTAL_CONFIG_DESC_LEN; usb_memcpy(buff+USB_DT_CONFIG_SIZE,(void*)&intf_desc[0],INTF_CONFIG_DESC_LEN); } else value = w_length; usb_memcpy(buff, (void*)&config_desc, USB_DT_CONFIG_SIZE); _pcd->buf = buff; _pcd->length = value; USB_DBG("--configuration descriptor length :%d\n\n", value); break; case USB_DT_STRING: USB_DBG("--get string descriptor: id: %d\n",w_value & 0xff); switch(w_value & 0xff){ case 0: // IDs usb_memcpy(buff,(void*)dt_string_id,DT_STRING_ID_LEN); break; case 1: // STRING_MANUFACTURER usb_memcpy(buff,(void*)dt_string_vid,DT_STRING_VID_LEN); break; case 2://STRING_PRODUCT usb_memcpy(buff,(void*)dt_string_pid,DT_STRING_PID_LEN); break; case 3://STRING_SERIAL usb_memcpy(buff,(void*)dt_string_serial,DT_STRING_SERIAL_LEN); break; default: USB_ERR("Error string id!\n"); buff[0] = 0; break; } _pcd->buf = buff; _pcd->length = buff[0]; USB_DBG("--get string descriptor: return length: %d\n\n",_pcd->length); break; } break; case USB_REQ_SET_CONFIGURATION: if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; USB_DBG("--set configuration\n\n"); _pcd->buf = 0; _pcd->length = 0; _pcd->request_config = 1; /* Configuration changed */ //need_check_timeout = 0; break; case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; USB_DBG("--get configuration\n\n"); buff[0] = 1; _pcd->buf = buff; _pcd->length = 1; break; default: USB_ERR("--unknown control req %02x.%02x v%04x i%04x l%u\n", ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); } w_index = 0; //remove compile warning return ; }
void USBHALHost::init() { NVIC_DisableIRQ(USB_IRQn); //Cut power LPC_SC->PCONP &= ~(1UL<<31); wait_ms(100); // turn on power for USB LPC_SC->PCONP |= (1UL<<31); // Enable USB host clock, port selection and AHB clock LPC_USB->USBClkCtrl |= CLOCK_MASK; // Wait for clocks to become available while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK); // it seems the bits[0:1] mean the following // 0: U1=device, U2=host // 1: U1=host, U2=host // 2: reserved // 3: U1=host, U2=device // NB: this register is only available if OTG clock (aka "port select") is enabled!! // since we don't care about port 2, set just bit 0 to 1 (U1=host) LPC_USB->OTGStCtrl |= 1; // now that we've configured the ports, we can turn off the portsel clock LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN; // configure USB D+/D- pins // P0[29] = USB_D+, 01 // P0[30] = USB_D-, 01 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28)); LPC_PINCON->PINSEL1 |= ((1<<26) | (1<<28)); LPC_USB->HcControl = 0; // HARDWARE RESET LPC_USB->HcControlHeadED = 0; // Initialize Control list head to Zero LPC_USB->HcBulkHeadED = 0; // Initialize Bulk list head to Zero // Wait 100 ms before apply reset wait_ms(100); // software reset LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR; // Write Fm Interval and Largest Data Packet Counter LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; LPC_USB->HcPeriodicStart = FI * 90 / 100; // Put HC in operational state LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; // Set Global Power LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; LPC_USB->HcHCCA = (uint32_t)(usb_hcca); // Clear Interrrupt Status LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC; // Enable the USB Interrupt NVIC_SetVector(USB_IRQn, (uint32_t)(_usbisr)); LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC; LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; NVIC_EnableIRQ(USB_IRQn); // Check for any connected devices if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) { //Device connected wait_ms(150); USB_DBG("Device connected (%08x)\n\r", LPC_USB->HcRhPortStatus1); deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA); } }
/* * This function will be called after a whole SETUP-OUT-IN transfer. */ void do_vendor_out_complete( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl) { int value = 0; u16 w_index = ctrl->wIndex; u16 w_value = ctrl->wValue; u16 w_length = ctrl->wLength; void (*fp)(void); char * buf; //USB_DBG("do_vendor_out_complete()\n"); switch (ctrl->bRequest) { case AM_REQ_WRITE_MEM: if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)) break; USB_DBG("--am req write memory completed\n\n"); break; case AM_REQ_FILL_MEM: buf = _pcd->buf; unsigned int addr,i; for(i = 0; i < _pcd->length; i+=8){ addr = *((unsigned int *)&buf[i]) ; value = *((unsigned int *)&buf[i+4]) ; *(unsigned int*)addr = value; } break; case AM_REQ_WRITE_AUX: buf = _pcd->buf; unsigned int data =0; data = *((unsigned int *)&buf[0]) ; //reg value value = (w_value << 16) + w_index; //aux reg //_sr(data,value); break; case AM_REQ_MODIFY_MEM: do_modify_memory(w_value,_pcd->buf); break; case AM_REQ_RUN_IN_ADDR: if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)) break; value = (w_value << 16) + w_index; USB_DBG("run addr = 0x%08X\n",value); fp = (void(*)(void))value; dwc_otg_power_off_phy(); fp(); break; case AM_REQ_WR_LARGE_MEM: value = 1; // is_out = 1 case AM_REQ_RD_LARGE_MEM: _pcd->bulk_out = value; // read or write _pcd->bulk_buf = (char *)(*(unsigned int*)buff); // board address _pcd->bulk_data_len = (*(unsigned int*) &buff[4]); // data length start_bulk_transfer(_pcd); break; default: USB_ERR("--unknown vendor req comp %02x.%02x v%04x i%04x l%u\n", ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); } w_length = 0;//remove compile warning return; }
bool SaraU2DongleInitializer::switchMode(USBDeviceConnected* pDev) { USB_DBG("Nothing to switch... just wait"); return false; }
void USBINT0_IRQHandler() { uint8_t intrusb = GET8(USB0_CORE+INTRUSB); uint16_t intrtx = GET16(USB0_CORE+INTRTX); uint16_t intrrx = GET16(USB0_CORE+INTRRX); NVIC_ClearPending(USBINT0_IRQn); if(intrusb & 0b10) // resume interrupt { // resume routine USB_DBG("resume\n"); } if(intrusb & 0b1000000) // session req interrupt { // session req routine USB_DBG("session req\n"); } if(intrusb & 0b10000000) // Vbus error interrupt { // Vbus error routine USB_DBG("vbus\n"); } if(intrusb & 0b1) // suspend interrupt { // suspend routine USB_DBG("suspend\n"); } if(intrusb & 0b10000) // connect interrupt { // connect routine USB_DBG("connect\n"); } if(intrusb & 0b100000) // disconnect interrupt { // disconnect routine USB_DBG("disconnect\n"); } if(intrusb & 0b100)// reset/babble interrupt { if(0) // host mode? { // babble routine USB_DBG("babble\n"); } else { // reset routine USB_DBG("reset\n"); } } if(intrusb & 0b1000) // SOF interrupt { // SOF routine USB_DBG("sof\n"); } if(intrtx & 0b1) // endpoint 0 interrupt { // endpoint 0 routine //USB_DBG("EP0\n"); USB0_ENDP0Handler(); } if(intrtx & 0xFFFE) // Tx endpoint interrupt { // Tx endpoint routine USB_DBG("TX\n"); } if(intrrx & 0xFFFE) // Rx endpoint interrupt { // Rx endpoint routine USB_DBG("RX\n"); } }
bool WANDongle::tryConnect() { //FIXME should run on USB thread USB_DBG("Trying to connect device"); if (dev_connected) { USB_DBG("Device is already connected!"); return true; } m_pInitializer = NULL; //Protect from concurrent access from USB thread USBHost::Lock lock(host); for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) { if ((dev = host->getDevice(i)) != NULL) { m_pInitializer = NULL; //Will be set in setVidPid callback USB_DBG("Enumerate"); int ret = host->enumerate(dev, this); if(ret) { return false; } USB_DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid()); if(m_pInitializer) { //If an initializer has been found //USB_DBG("m_pInitializer=%p", m_pInitializer); //USB_DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid()); //USB_DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid()); if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid())) { USB_DBG("The dongle is in virtual serial mode"); host->registerDriver(dev, 0, this, &WANDongle::init); m_serialCount = m_pInitializer->getSerialPortCount(); if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS ) { m_serialCount = WANDONGLE_MAX_SERIAL_PORTS; } USB_DBG("Initied Serial Ports %d",m_serialCount); for(int j = 0; j < m_serialCount; j++) { USB_DBG("Connecting serial port #%d", j+1); USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, false)); USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, true)); m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) ); } USB_DBG("Device connected"); dev_connected = true; return true; } else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid())) { USB_DBG("Dongle detected in Wrong USB mode"); //Try to switch if( m_pInitializer->switchMode(dev) ) { USB_DBG("Switched OK"); return false; //Will be connected on a next iteration } else { USB_ERR("Could not switch mode"); return false; } } } //if() } //if() } //for() return false; }
void USB_print_setup(struct USBSetupPacket s) { USB_DBG("0x%02X, ",s.bmRequestType); if(s.bmRequestType& 0x80) { USB_DBG("dev->host, "); } else { USB_DBG("host->dev, "); } switch(s.bmRequestType & 0x1F) { case 0: USB_DBG("Device, "); break; case 1: USB_DBG("Interface, ");break; case 2: USB_DBG("Endpoint, "); break; case 3: USB_DBG("Other, "); break; default:USB_DBG("Reserved, "); break; } switch (s.bRequest) { case GET_STATUS: USB_DBG("GET_STATUS, "); break; case CLEAR_FEATURE: USB_DBG("CLEAR_FEATURE, "); break; case SET_FEATURE: USB_DBG("SET_FEATURE, "); break; case SET_ADDRESS: USB_DBG("SET_ADDRESS, "); break; case GET_DESCRIPTOR: USB_DBG("GET_DESCRIPTOR, "); break; case SET_DESCRIPTOR: USB_DBG("SET_DESCRIPTOR, "); break; case GET_CONFIGURATION: USB_DBG("GET_CONFIGURATION, "); break; case SET_CONFIGURATION: USB_DBG("SET_CONFIGURATION, "); break; case GET_INTERFACE: USB_DBG("GET_INTERFACE, "); break; case SET_INTERFACE: USB_DBG("SET_INTERFACE, "); break; case SYNCH_FRAME: USB_DBG("SYNCH_FRAME, "); break; default: USB_DBG("unrecognized!! = 0x%X, ",s.bRequest); break; } USB_DBG("%04hX %04hX %04hX\n",s.wValue, s.wIndex, s.wLength); }
/** * This functions delegates vendor ctrl request. */ void do_vendor_request( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl) { int value =0; u16 w_index = ctrl->wIndex; u16 w_value = ctrl->wValue; u16 w_length = ctrl->wLength; switch (ctrl->bRequest) { case AM_REQ_WRITE_MEM: if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)) break; USB_DBG("--am req write memory\n"); value = (w_value << 16) + w_index; USB_DBG("addr = 0x%08X, size = %d\n\n",value,w_length); _pcd->buf = (char *)value; // copy to dst memory directly _pcd->length = w_length; break; case AM_REQ_READ_MEM: if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)) break; value = (w_value << 16) + w_index; usb_memcpy((char *)buff,(char*)value,w_length); _pcd->buf = buff; _pcd->length = w_length; break; case AM_REQ_READ_AUX: if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE)) break; unsigned int data = 0; value = (w_value << 16) + w_index; //data = _lr(value); *(unsigned int *)buff = data; _pcd->buf = buff; _pcd->length = w_length; break; case AM_REQ_FILL_MEM: case AM_REQ_WRITE_AUX: case AM_REQ_MODIFY_MEM: if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)) break; _pcd->buf = buff; _pcd->length = w_length; break; case AM_REQ_RUN_IN_ADDR: if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE)) break; value = (w_value << 16) + w_index; USB_DBG("--am req run in addr %p\n\n",value); _pcd->buf = buff; _pcd->length = w_length; break; case AM_REQ_WR_LARGE_MEM: value = 1; case AM_REQ_RD_LARGE_MEM: USB_DBG("--am req large %s mem \n\n",value?"write":"read"); _pcd->bulk_len = w_value; // block length _pcd->bulk_num = w_index; // number of block _pcd->buf = buff; _pcd->length = w_length; break; case AM_REQ_IDENTIFY_HOST: buff[0] = USB_ROM_VER_MAJOR; buff[1] = USB_ROM_VER_MINOR; buff[2] = USB_ROM_STAGE_MAJOR; buff[3] = USB_ROM_STAGE_MINOR; _pcd->buf = buff; _pcd->length = w_length; need_check_timeout = 0; break; default: USB_ERR("--unknown vendor req %02x.%02x v%04x i%04x l%u\n", ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); break; } return; }