Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of uvchost by
UsbDevice.cpp
00001 00002 /* 00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "UsbDevice.h" 00025 //#define __DEBUG 00026 #include "mydbg.h" 00027 00028 UsbDevice::UsbDevice(UsbHostMgr* pMgr, int hub, int port, int addr, bool lowspeed) : m_pControlEp(NULL), /*m_controlEp( this, 0x00, false, USB_CONTROL, 8 ),*/ 00029 m_pMgr(pMgr), m_connected(false), m_enumerated(false), m_hub(hub), m_port(port), m_addr(addr), m_refs(0), 00030 m_vid(0), m_pid(0) 00031 { 00032 m_DeviceClass = 0x00; 00033 m_InterfaceClass = 0x00; 00034 m_lowspeed = lowspeed; 00035 } 00036 00037 UsbDevice::~UsbDevice() 00038 { 00039 if(m_pControlEp) 00040 delete m_pControlEp; 00041 } 00042 00043 UsbErr UsbDevice::enumerate() 00044 { 00045 VERBOSE("Hub: %d Port: %d Speed: %s\n", m_hub, m_port, m_lowspeed ? "slow" : "full"); 00046 UsbErr rc; 00047 DBG("%p m_hub=%d m_port=%d\n", this, m_hub, m_port); 00048 DBG_ASSERT(m_pMgr); 00049 m_pMgr->resetPort(m_hub, m_port); 00050 00051 wait_ms(400); 00052 00053 uint8_t temp[8]; 00054 DBG_ASSERT(m_pControlEp == NULL); 00055 m_pControlEp = new UsbEndpoint( this, 0x00, false, USB_CONTROL, sizeof(temp), 0 ); 00056 DBG_ASSERT(m_pControlEp); 00057 /* Read first 8 bytes of device desc */ 00058 DBG_ASSERT(sizeof(temp) >= 8); 00059 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, temp, sizeof(temp)); 00060 if (rc != USBERR_OK) { 00061 DBG("rc=%d\n", rc); 00062 DBG_ASSERT(rc == USBERR_OK); 00063 return rc; 00064 } 00065 DBG_ASSERT(rc == USBERR_OK); 00066 DBG_BYTES("DeviceDescriptor first 8 bytes", temp, sizeof(temp)); 00067 DBG_ASSERT(temp[0] == 18); // bLength 00068 DBG_ASSERT(temp[1] == 0x01); // bDescriptType 00069 if (rc) 00070 { 00071 DBG("RC=%d",rc); 00072 return (rc); 00073 } 00074 uint8_t bMaxPacketSize = temp[7]; 00075 DBG_ASSERT(bMaxPacketSize >= 8); 00076 DBG("Got descriptor, max ep size is %d\n", bMaxPacketSize); 00077 00078 m_pControlEp->updateSize(bMaxPacketSize); /* Get max pkt size of endpoint 0 */ 00079 rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, m_addr, 0, NULL, 0); /* Set the device address to m_addr */ 00080 DBG_ASSERT(rc == USBERR_OK); 00081 if (rc) 00082 { 00083 // PRINT_Err(rc); 00084 return (rc); 00085 } 00086 wait_ms(2); 00087 //EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */ 00088 00089 //Update address 00090 m_pControlEp->updateAddr(m_addr); 00091 DBG("Ep addr is now %d", m_addr); 00092 00093 uint8_t DeviceDesc[18]; 00094 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, DeviceDesc, sizeof(DeviceDesc)); 00095 DBG_ASSERT(rc == USBERR_OK); 00096 DBG_BYTES("DeviceDescriptor", DeviceDesc, sizeof(DeviceDesc)); 00097 DBG_ASSERT(DeviceDesc[0] == 18); 00098 DBG_ASSERT(DeviceDesc[1] == 0x01); 00099 DBG_ASSERT(DeviceDesc[17] == 1); // bNumConfiguration 00100 if (rc) 00101 { 00102 return (rc); 00103 } 00104 00105 m_DeviceClass = DeviceDesc[4]; 00106 VERBOSE("DeviceClass: %02X\n", m_DeviceClass); 00107 00108 m_vid = *((uint16_t*)&DeviceDesc[8]); 00109 m_pid = *((uint16_t*)&DeviceDesc[10]); 00110 VERBOSE("Vender: %04X\n", m_vid); 00111 VERBOSE("Product: %04X\n", m_pid); 00112 int iManufacture = DeviceDesc[14]; 00113 if (iManufacture) { 00114 char str[64]; 00115 rc = GetString(iManufacture, str, sizeof(str)); 00116 if (rc == USBERR_OK) { 00117 VERBOSE("Manufacture: %s\n", str); 00118 } 00119 } 00120 int iProduct = DeviceDesc[15]; 00121 if (iProduct) { 00122 char str[64]; 00123 rc = GetString(iProduct, str, sizeof(str)); 00124 if (rc == USBERR_OK) { 00125 VERBOSE("Product: %s\n", str); 00126 } 00127 } 00128 if (DeviceDesc[4] == 0x09) { // Hub 00129 return hub_init(); 00130 } 00131 00132 uint8_t ConfigDesc[9]; 00133 int index = 0; 00134 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); 00135 DBG_ASSERT(rc == USBERR_OK); 00136 DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); 00137 DBG_ASSERT(ConfigDesc[0] == 9); 00138 DBG_ASSERT(ConfigDesc[1] == 0x02); 00139 int wTotalLength = *((uint16_t*)&ConfigDesc[2]); 00140 DBG("TotalLength: %d\n", wTotalLength); 00141 int bConfigValue = ConfigDesc[5]; 00142 DBG_ASSERT(bConfigValue == 1); 00143 DBG("ConfigValue: %d\n", bConfigValue); 00144 DBG("MaxPower: %d mA\n", ConfigDesc[8]*2); 00145 00146 uint8_t* buf = new uint8_t[wTotalLength]; 00147 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); 00148 DBG_ASSERT(rc == USBERR_OK); 00149 DBG_ASSERT(ConfigDesc[1] == 0x02); 00150 int pos = 0; 00151 while(pos < wTotalLength) { 00152 DBG_BYTES("", buf+pos, buf[pos]); 00153 if (buf[pos+1] == 4) { // interface ? 00154 m_InterfaceClass = buf[pos+5]; 00155 VERBOSE("InterfaceClass: %02X\n", m_InterfaceClass); 00156 break; 00157 } 00158 pos += buf[pos]; 00159 } 00160 delete[] buf; 00161 00162 rc = setConfiguration(1); 00163 DBG_ASSERT(rc == USBERR_OK); 00164 if (rc) 00165 { 00166 // PRINT_Err(rc); 00167 return rc; 00168 } 00169 wait_ms(100);/* Some devices may require this delay */ 00170 00171 m_enumerated = true; 00172 return USBERR_OK; 00173 } 00174 00175 bool UsbDevice::connected() 00176 { 00177 return m_connected; 00178 } 00179 00180 bool UsbDevice::enumerated() 00181 { 00182 return m_enumerated; 00183 } 00184 00185 int UsbDevice::getPid() 00186 { 00187 return m_pid; 00188 } 00189 00190 int UsbDevice::getVid() 00191 { 00192 return m_vid; 00193 } 00194 00195 UsbErr UsbDevice::setConfiguration(int config) 00196 { 00197 DBG("config=%d\n", config); 00198 DBG_ASSERT(config == 1); 00199 UsbErr rc = controlSend( 00200 USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, // 0x00 00201 SET_CONFIGURATION, config, 0, 0, 0); 00202 return rc; 00203 } 00204 00205 UsbErr UsbDevice::controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len) 00206 { 00207 UsbErr rc; 00208 fillControlBuf(requestType, request, value, index, len); 00209 DBG_ASSERT(m_pControlEp); 00210 m_pControlEp->setNextToken(TD_SETUP); 00211 rc = m_pControlEp->transfer(m_controlBuf, 8); 00212 while(m_pControlEp->status() == USBERR_PROCESSING); 00213 rc = (UsbErr) MIN(0, m_pControlEp->status()); 00214 if(rc) 00215 return rc; 00216 if(len) 00217 { 00218 m_pControlEp->setNextToken(TD_OUT); 00219 rc = m_pControlEp->transfer((byte*)buf, len); 00220 while(m_pControlEp->status() == USBERR_PROCESSING); 00221 rc = (UsbErr) MIN(0, m_pControlEp->status()); 00222 if(rc) 00223 return rc; 00224 } 00225 m_pControlEp->setNextToken(TD_IN); 00226 rc = m_pControlEp->transfer(NULL, 0); 00227 while(m_pControlEp->status() == USBERR_PROCESSING); 00228 rc = (UsbErr) MIN(0, m_pControlEp->status()); 00229 if(rc) 00230 return rc; 00231 return USBERR_OK; 00232 } 00233 00234 UsbErr UsbDevice::controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len) 00235 { 00236 DBG("buf=%p len=%d\n", buf, len); 00237 UsbErr rc; 00238 fillControlBuf(requestType, request, value, index, len); 00239 DBG_ASSERT(m_pControlEp); 00240 m_pControlEp->setNextToken(TD_SETUP); 00241 rc = m_pControlEp->transfer(m_controlBuf, 8); 00242 while(m_pControlEp->status() == USBERR_PROCESSING); 00243 rc = (UsbErr) MIN(0, m_pControlEp->status()); 00244 if(rc) 00245 return rc; 00246 if(len) 00247 { 00248 m_pControlEp->setNextToken(TD_IN); 00249 rc = m_pControlEp->transfer( (byte*) buf, len); 00250 while(m_pControlEp->status() == USBERR_PROCESSING); 00251 rc = (UsbErr) MIN(0, m_pControlEp->status()); 00252 if(rc) 00253 return rc; 00254 } 00255 m_pControlEp->setNextToken(TD_OUT); 00256 rc = m_pControlEp->transfer(NULL, 0); 00257 while(m_pControlEp->status() == USBERR_PROCESSING); 00258 rc = (UsbErr) MIN(0, m_pControlEp->status()); 00259 if(rc) 00260 return rc; 00261 return USBERR_OK; 00262 } 00263 00264 UsbErr UsbDevice::GetDescriptor(int type, int index, const byte* buf, int len) 00265 { 00266 DBG("type=%02X\n", type); 00267 return controlReceive( 00268 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, 00269 (type << 8) |(index), 0, buf, len); 00270 00271 } 00272 00273 UsbErr UsbDevice::GetString(int index, char* buf, int len) 00274 { 00275 DBG("index=%d buf=%p len=%d\n", index, buf, len); 00276 DBG_ASSERT(index >= 1); 00277 uint8_t temp[4]; 00278 UsbErr rc; 00279 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, 0, temp, sizeof(temp)); 00280 DBG_ASSERT(rc == USBERR_OK); 00281 DBG_BYTES("LANG_ID", temp, sizeof(temp)); 00282 DBG_ASSERT(temp[0] == 4); 00283 DBG_ASSERT(temp[1] == 0x03); 00284 00285 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp, 2); 00286 if (rc != USBERR_OK) { 00287 return rc; 00288 } 00289 DBG_BYTES("length check", temp, 2); 00290 if (temp[0] == 0x00 && temp[1] == 0x00) { // for pl2303 00291 if (len > 0) { 00292 strcpy(buf, ""); 00293 } 00294 return rc; 00295 } 00296 DBG_ASSERT(temp[1] == 0x03); 00297 int temp_len = temp[0]; 00298 00299 uint8_t* temp_buf = new uint8_t[temp_len]; 00300 DBG_ASSERT(temp_buf); 00301 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp_buf, temp_len); 00302 DBG_ASSERT(rc == USBERR_OK); 00303 temp_len = temp_buf[0]; 00304 DBG_HEX(temp_buf, temp_len); 00305 int i = 0; 00306 for(int pos = 2; pos < temp_len; pos+= 2) { 00307 buf[i++] = temp_buf[pos]; 00308 DBG_ASSERT(i < len-1); 00309 } 00310 buf[i] = '\0'; 00311 delete[] temp_buf; 00312 return rc; 00313 } 00314 00315 UsbErr UsbDevice::SetInterfaceAlternate(int interface, int alternate) 00316 { 00317 UsbErr rc = controlSend( 00318 USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, 00319 SET_INTERFACE, alternate, interface, NULL, 0); 00320 return rc; 00321 } 00322 00323 void UsbDevice::fillControlBuf(byte requestType, byte request, word value, word index, int len) 00324 { 00325 #ifdef __BIG_ENDIAN 00326 #error "Must implement BE to LE conv here" 00327 #endif 00328 m_controlBuf[0] = requestType; 00329 m_controlBuf[1] = request; 00330 //We are in LE so it's fine 00331 *((word*)&m_controlBuf[2]) = value; 00332 *((word*)&m_controlBuf[4]) = index; 00333 *((word*)&m_controlBuf[6]) = (word) len; 00334 } 00335 00336 void UsbDevice::DeleteControlEp() 00337 { 00338 delete m_pControlEp; 00339 }
Generated on Wed Jul 13 2022 01:34:55 by
1.7.2
