Takao Aratani / uvchost

Dependents:   WebCamera_SD

Fork of uvchost by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UsbDevice.cpp Source File

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 }