Webcam Server.

Dependencies:   uvchost FatFileSystem mbed HTTPServer NetServicesMin

Committer:
va009039
Date:
Wed Jun 06 11:47:06 2012 +0000
Revision:
0:2b4ea8a138e5

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:2b4ea8a138e5 1
va009039 0:2b4ea8a138e5 2 /*
va009039 0:2b4ea8a138e5 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
va009039 0:2b4ea8a138e5 4
va009039 0:2b4ea8a138e5 5 Permission is hereby granted, free of charge, to any person obtaining a copy
va009039 0:2b4ea8a138e5 6 of this software and associated documentation files (the "Software"), to deal
va009039 0:2b4ea8a138e5 7 in the Software without restriction, including without limitation the rights
va009039 0:2b4ea8a138e5 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
va009039 0:2b4ea8a138e5 9 copies of the Software, and to permit persons to whom the Software is
va009039 0:2b4ea8a138e5 10 furnished to do so, subject to the following conditions:
va009039 0:2b4ea8a138e5 11
va009039 0:2b4ea8a138e5 12 The above copyright notice and this permission notice shall be included in
va009039 0:2b4ea8a138e5 13 all copies or substantial portions of the Software.
va009039 0:2b4ea8a138e5 14
va009039 0:2b4ea8a138e5 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
va009039 0:2b4ea8a138e5 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
va009039 0:2b4ea8a138e5 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
va009039 0:2b4ea8a138e5 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
va009039 0:2b4ea8a138e5 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
va009039 0:2b4ea8a138e5 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
va009039 0:2b4ea8a138e5 21 THE SOFTWARE.
va009039 0:2b4ea8a138e5 22 */
va009039 0:2b4ea8a138e5 23
va009039 0:2b4ea8a138e5 24 #include "UsbDevice.h"
va009039 0:2b4ea8a138e5 25 //#define __DEBUG
va009039 0:2b4ea8a138e5 26 #include "mydbg.h"
va009039 0:2b4ea8a138e5 27
va009039 0:2b4ea8a138e5 28 UsbDevice::UsbDevice( UsbHostMgr* pMgr, int hub, int port, int addr ) : m_pControlEp(NULL), /*m_controlEp( this, 0x00, false, USB_CONTROL, 8 ),*/
va009039 0:2b4ea8a138e5 29 m_pMgr(pMgr), m_connected(false), m_enumerated(false), m_hub(hub), m_port(port), m_addr(addr), m_refs(0),
va009039 0:2b4ea8a138e5 30 m_vid(0), m_pid(0)
va009039 0:2b4ea8a138e5 31 {
va009039 0:2b4ea8a138e5 32 m_DeviceClass = 0x00;
va009039 0:2b4ea8a138e5 33 m_InterfaceClass = 0x00;
va009039 0:2b4ea8a138e5 34 }
va009039 0:2b4ea8a138e5 35
va009039 0:2b4ea8a138e5 36 UsbDevice::~UsbDevice()
va009039 0:2b4ea8a138e5 37 {
va009039 0:2b4ea8a138e5 38 DBG_ASSERT(0);
va009039 0:2b4ea8a138e5 39
va009039 0:2b4ea8a138e5 40 if(m_pControlEp)
va009039 0:2b4ea8a138e5 41 delete m_pControlEp;
va009039 0:2b4ea8a138e5 42 }
va009039 0:2b4ea8a138e5 43
va009039 0:2b4ea8a138e5 44 UsbErr UsbDevice::enumerate()
va009039 0:2b4ea8a138e5 45 {
va009039 0:2b4ea8a138e5 46 VERBOSE("Hub: %d Port: %d\n", m_hub, m_port);
va009039 0:2b4ea8a138e5 47 UsbErr rc;
va009039 0:2b4ea8a138e5 48 DBG("%p m_hub=%d m_port=%d\n", this, m_hub, m_port);
va009039 0:2b4ea8a138e5 49 DBG_ASSERT(m_pMgr);
va009039 0:2b4ea8a138e5 50 m_pMgr->resetPort(m_hub, m_port);
va009039 0:2b4ea8a138e5 51
va009039 0:2b4ea8a138e5 52 wait_ms(400);
va009039 0:2b4ea8a138e5 53
va009039 0:2b4ea8a138e5 54 uint8_t temp[8];
va009039 0:2b4ea8a138e5 55 DBG_ASSERT(m_pControlEp == NULL);
va009039 0:2b4ea8a138e5 56 m_pControlEp = new UsbEndpoint( this, 0x00, false, USB_CONTROL, sizeof(temp), 0 );
va009039 0:2b4ea8a138e5 57 DBG_ASSERT(m_pControlEp);
va009039 0:2b4ea8a138e5 58 //EDCtrl->Control = 8 << 16;/* Put max pkt size = 8 */
va009039 0:2b4ea8a138e5 59 /* Read first 8 bytes of device desc */
va009039 0:2b4ea8a138e5 60 DBG_ASSERT(sizeof(temp) >= 8);
va009039 0:2b4ea8a138e5 61 //rc = controlReceive(
va009039 0:2b4ea8a138e5 62 // USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR,
va009039 0:2b4ea8a138e5 63 // (USB_DESCRIPTOR_TYPE_DEVICE << 8) |(0), 0, temp, sizeof(temp));
va009039 0:2b4ea8a138e5 64 //DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 65 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, temp, sizeof(temp));
va009039 0:2b4ea8a138e5 66 if (rc != USBERR_OK) {
va009039 0:2b4ea8a138e5 67 DBG("rc=%d\n", rc);
va009039 0:2b4ea8a138e5 68 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 69 return rc;
va009039 0:2b4ea8a138e5 70 }
va009039 0:2b4ea8a138e5 71 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 72 DBG_BYTES("DeviceDescriptor first 8 bytes", temp, sizeof(temp));
va009039 0:2b4ea8a138e5 73 DBG_ASSERT(temp[0] == 18); // bLength
va009039 0:2b4ea8a138e5 74 DBG_ASSERT(temp[1] == 0x01); // bDescriptType
va009039 0:2b4ea8a138e5 75 if (rc)
va009039 0:2b4ea8a138e5 76 {
va009039 0:2b4ea8a138e5 77 DBG("RC=%d",rc);
va009039 0:2b4ea8a138e5 78 return (rc);
va009039 0:2b4ea8a138e5 79 }
va009039 0:2b4ea8a138e5 80 uint8_t bMaxPacketSize = temp[7];
va009039 0:2b4ea8a138e5 81 DBG_ASSERT(bMaxPacketSize >= 8);
va009039 0:2b4ea8a138e5 82 DBG("Got descriptor, max ep size is %d\n", bMaxPacketSize);
va009039 0:2b4ea8a138e5 83
va009039 0:2b4ea8a138e5 84 m_pControlEp->updateSize(bMaxPacketSize); /* Get max pkt size of endpoint 0 */
va009039 0:2b4ea8a138e5 85 rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, m_addr, 0, NULL, 0); /* Set the device address to m_addr */
va009039 0:2b4ea8a138e5 86 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 87 if (rc)
va009039 0:2b4ea8a138e5 88 {
va009039 0:2b4ea8a138e5 89 // PRINT_Err(rc);
va009039 0:2b4ea8a138e5 90 return (rc);
va009039 0:2b4ea8a138e5 91 }
va009039 0:2b4ea8a138e5 92 wait_ms(2);
va009039 0:2b4ea8a138e5 93 //EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */
va009039 0:2b4ea8a138e5 94
va009039 0:2b4ea8a138e5 95 //Update address
va009039 0:2b4ea8a138e5 96 m_pControlEp->updateAddr(m_addr);
va009039 0:2b4ea8a138e5 97 DBG("Ep addr is now %d", m_addr);
va009039 0:2b4ea8a138e5 98 /**/
va009039 0:2b4ea8a138e5 99
va009039 0:2b4ea8a138e5 100 //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor
va009039 0:2b4ea8a138e5 101 //rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR,
va009039 0:2b4ea8a138e5 102 // (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0,
va009039 0:2b4ea8a138e5 103 // m_controlDataBuf, 17);
va009039 0:2b4ea8a138e5 104 uint8_t DeviceDesc[18];
va009039 0:2b4ea8a138e5 105 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, DeviceDesc, sizeof(DeviceDesc));
va009039 0:2b4ea8a138e5 106 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 107 DBG_BYTES("DeviceDescriptor", DeviceDesc, sizeof(DeviceDesc));
va009039 0:2b4ea8a138e5 108 DBG_ASSERT(DeviceDesc[0] == 18);
va009039 0:2b4ea8a138e5 109 DBG_ASSERT(DeviceDesc[1] == 0x01);
va009039 0:2b4ea8a138e5 110 DBG_ASSERT(DeviceDesc[17] == 1); // bNumConfiguration
va009039 0:2b4ea8a138e5 111 if (rc)
va009039 0:2b4ea8a138e5 112 {
va009039 0:2b4ea8a138e5 113 //PRINT_Err(rc);
va009039 0:2b4ea8a138e5 114 return (rc);
va009039 0:2b4ea8a138e5 115 }
va009039 0:2b4ea8a138e5 116
va009039 0:2b4ea8a138e5 117 /*
va009039 0:2b4ea8a138e5 118 rc = SerialCheckVidPid();
va009039 0:2b4ea8a138e5 119 if (rc != OK) {
va009039 0:2b4ea8a138e5 120 PRINT_Err(rc);
va009039 0:2b4ea8a138e5 121 return (rc);
va009039 0:2b4ea8a138e5 122 }
va009039 0:2b4ea8a138e5 123 */
va009039 0:2b4ea8a138e5 124 /**/
va009039 0:2b4ea8a138e5 125 m_DeviceClass = DeviceDesc[4];
va009039 0:2b4ea8a138e5 126 VERBOSE("DeviceClass: %02X\n", m_DeviceClass);
va009039 0:2b4ea8a138e5 127
va009039 0:2b4ea8a138e5 128 m_vid = *((uint16_t*)&DeviceDesc[8]);
va009039 0:2b4ea8a138e5 129 m_pid = *((uint16_t*)&DeviceDesc[10]);
va009039 0:2b4ea8a138e5 130 VERBOSE("Vender: %04X\n", m_vid);
va009039 0:2b4ea8a138e5 131 VERBOSE("Product: %04X\n", m_pid);
va009039 0:2b4ea8a138e5 132 int iManufacture = DeviceDesc[14];
va009039 0:2b4ea8a138e5 133 if (iManufacture) {
va009039 0:2b4ea8a138e5 134 char str[64];
va009039 0:2b4ea8a138e5 135 rc = GetString(iManufacture, str, sizeof(str));
va009039 0:2b4ea8a138e5 136 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 137 VERBOSE("Manufacture: %s\n", str);
va009039 0:2b4ea8a138e5 138 }
va009039 0:2b4ea8a138e5 139 int iProduct = DeviceDesc[15];
va009039 0:2b4ea8a138e5 140 if (iProduct) {
va009039 0:2b4ea8a138e5 141 char str[64];
va009039 0:2b4ea8a138e5 142 rc = GetString(iProduct, str, sizeof(str));
va009039 0:2b4ea8a138e5 143 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 144 VERBOSE("Product: %s\n", str);
va009039 0:2b4ea8a138e5 145 }
va009039 0:2b4ea8a138e5 146 if (DeviceDesc[4] == 0x09) { // Hub
va009039 0:2b4ea8a138e5 147 return hub_init();
va009039 0:2b4ea8a138e5 148 }
va009039 0:2b4ea8a138e5 149
va009039 0:2b4ea8a138e5 150 uint8_t ConfigDesc[9];
va009039 0:2b4ea8a138e5 151 int index = 0;
va009039 0:2b4ea8a138e5 152 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
va009039 0:2b4ea8a138e5 153 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 154 DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
va009039 0:2b4ea8a138e5 155 DBG_ASSERT(ConfigDesc[0] == 9);
va009039 0:2b4ea8a138e5 156 DBG_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:2b4ea8a138e5 157 int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
va009039 0:2b4ea8a138e5 158 DBG("TotalLength: %d\n", wTotalLength);
va009039 0:2b4ea8a138e5 159 int bConfigValue = ConfigDesc[5];
va009039 0:2b4ea8a138e5 160 DBG_ASSERT(bConfigValue == 1);
va009039 0:2b4ea8a138e5 161 DBG("ConfigValue: %d\n", bConfigValue);
va009039 0:2b4ea8a138e5 162 DBG("MaxPower: %d mA\n", ConfigDesc[8]*2);
va009039 0:2b4ea8a138e5 163
va009039 0:2b4ea8a138e5 164 uint8_t* buf = new uint8_t[wTotalLength];
va009039 0:2b4ea8a138e5 165 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
va009039 0:2b4ea8a138e5 166 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 167 DBG_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:2b4ea8a138e5 168 int pos = 0;
va009039 0:2b4ea8a138e5 169 while(pos < wTotalLength) {
va009039 0:2b4ea8a138e5 170 DBG_BYTES("", buf+pos, buf[pos]);
va009039 0:2b4ea8a138e5 171 if (buf[pos+1] == 4) { // interface ?
va009039 0:2b4ea8a138e5 172 m_InterfaceClass = buf[pos+5];
va009039 0:2b4ea8a138e5 173 VERBOSE("InterfaceClass: %02X\n", m_InterfaceClass);
va009039 0:2b4ea8a138e5 174 break;
va009039 0:2b4ea8a138e5 175 }
va009039 0:2b4ea8a138e5 176 pos += buf[pos];
va009039 0:2b4ea8a138e5 177 }
va009039 0:2b4ea8a138e5 178 delete[] buf;
va009039 0:2b4ea8a138e5 179
va009039 0:2b4ea8a138e5 180 rc = setConfiguration(1);
va009039 0:2b4ea8a138e5 181 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 182 if (rc)
va009039 0:2b4ea8a138e5 183 {
va009039 0:2b4ea8a138e5 184 // PRINT_Err(rc);
va009039 0:2b4ea8a138e5 185 return rc;
va009039 0:2b4ea8a138e5 186 }
va009039 0:2b4ea8a138e5 187 wait_ms(100);/* Some devices may require this delay */
va009039 0:2b4ea8a138e5 188
va009039 0:2b4ea8a138e5 189 m_enumerated = true;
va009039 0:2b4ea8a138e5 190 return USBERR_OK;
va009039 0:2b4ea8a138e5 191 }
va009039 0:2b4ea8a138e5 192
va009039 0:2b4ea8a138e5 193 bool UsbDevice::connected()
va009039 0:2b4ea8a138e5 194 {
va009039 0:2b4ea8a138e5 195 return m_connected;
va009039 0:2b4ea8a138e5 196 }
va009039 0:2b4ea8a138e5 197
va009039 0:2b4ea8a138e5 198 bool UsbDevice::enumerated()
va009039 0:2b4ea8a138e5 199 {
va009039 0:2b4ea8a138e5 200 return m_enumerated;
va009039 0:2b4ea8a138e5 201 }
va009039 0:2b4ea8a138e5 202
va009039 0:2b4ea8a138e5 203 int UsbDevice::getPid()
va009039 0:2b4ea8a138e5 204 {
va009039 0:2b4ea8a138e5 205 return m_pid;
va009039 0:2b4ea8a138e5 206 }
va009039 0:2b4ea8a138e5 207
va009039 0:2b4ea8a138e5 208 int UsbDevice::getVid()
va009039 0:2b4ea8a138e5 209 {
va009039 0:2b4ea8a138e5 210 return m_vid;
va009039 0:2b4ea8a138e5 211 }
va009039 0:2b4ea8a138e5 212 #if 0
va009039 0:2b4ea8a138e5 213 UsbErr UsbDevice::getConfigurationDescriptor(int config, uint8_t** pBuf)
va009039 0:2b4ea8a138e5 214 {
va009039 0:2b4ea8a138e5 215 DBG_ASSERT(m_controlDataBuf);
va009039 0:2b4ea8a138e5 216 //For now olny one config
va009039 0:2b4ea8a138e5 217 *pBuf = m_controlDataBuf;
va009039 0:2b4ea8a138e5 218 return USBERR_OK;
va009039 0:2b4ea8a138e5 219 }
va009039 0:2b4ea8a138e5 220
va009039 0:2b4ea8a138e5 221 UsbErr UsbDevice::getInterfaceDescriptor(int config, int item, uint8_t** pBuf)
va009039 0:2b4ea8a138e5 222 {
va009039 0:2b4ea8a138e5 223 DBG_ASSERT(m_controlDataBuf);
va009039 0:2b4ea8a138e5 224 byte* desc_ptr = m_controlDataBuf;
va009039 0:2b4ea8a138e5 225
va009039 0:2b4ea8a138e5 226 /* if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION)
va009039 0:2b4ea8a138e5 227 {
va009039 0:2b4ea8a138e5 228 return USBERR_BADCONFIG;
va009039 0:2b4ea8a138e5 229 }*/
va009039 0:2b4ea8a138e5 230 DBG_ASSERT(m_controlDataBuf);
va009039 0:2b4ea8a138e5 231 if(item>=m_controlDataBuf[4])//Interfaces count
va009039 0:2b4ea8a138e5 232 return USBERR_NOTFOUND;
va009039 0:2b4ea8a138e5 233
va009039 0:2b4ea8a138e5 234 desc_ptr += desc_ptr[0];
va009039 0:2b4ea8a138e5 235
va009039 0:2b4ea8a138e5 236 *pBuf = NULL;
va009039 0:2b4ea8a138e5 237
va009039 0:2b4ea8a138e5 238 while (desc_ptr < m_controlDataBuf + *((uint16_t*)&m_controlDataBuf[2]))
va009039 0:2b4ea8a138e5 239 {
va009039 0:2b4ea8a138e5 240
va009039 0:2b4ea8a138e5 241 switch (desc_ptr[1]) {
va009039 0:2b4ea8a138e5 242 case USB_DESCRIPTOR_TYPE_INTERFACE:
va009039 0:2b4ea8a138e5 243 if(desc_ptr[2] == item)
va009039 0:2b4ea8a138e5 244 {
va009039 0:2b4ea8a138e5 245 *pBuf = desc_ptr;
va009039 0:2b4ea8a138e5 246 return USBERR_OK;
va009039 0:2b4ea8a138e5 247 }
va009039 0:2b4ea8a138e5 248 desc_ptr += desc_ptr[0]; // Move to next descriptor start
va009039 0:2b4ea8a138e5 249 break;
va009039 0:2b4ea8a138e5 250 }
va009039 0:2b4ea8a138e5 251
va009039 0:2b4ea8a138e5 252 }
va009039 0:2b4ea8a138e5 253
va009039 0:2b4ea8a138e5 254 if(*pBuf == NULL)
va009039 0:2b4ea8a138e5 255 return USBERR_NOTFOUND;
va009039 0:2b4ea8a138e5 256
va009039 0:2b4ea8a138e5 257 return USBERR_OK;
va009039 0:2b4ea8a138e5 258 }
va009039 0:2b4ea8a138e5 259 #endif
va009039 0:2b4ea8a138e5 260
va009039 0:2b4ea8a138e5 261 UsbErr UsbDevice::setConfiguration(int config)
va009039 0:2b4ea8a138e5 262 {
va009039 0:2b4ea8a138e5 263 DBG("config=%d\n", config);
va009039 0:2b4ea8a138e5 264 DBG_ASSERT(config == 1);
va009039 0:2b4ea8a138e5 265 UsbErr rc = controlSend(
va009039 0:2b4ea8a138e5 266 USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, // 0x00
va009039 0:2b4ea8a138e5 267 SET_CONFIGURATION, config, 0, 0, 0);
va009039 0:2b4ea8a138e5 268 return rc;
va009039 0:2b4ea8a138e5 269 }
va009039 0:2b4ea8a138e5 270
va009039 0:2b4ea8a138e5 271 UsbErr UsbDevice::controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len)
va009039 0:2b4ea8a138e5 272 {
va009039 0:2b4ea8a138e5 273 UsbErr rc;
va009039 0:2b4ea8a138e5 274 fillControlBuf(requestType, request, value, index, len);
va009039 0:2b4ea8a138e5 275 DBG_ASSERT(m_pControlEp);
va009039 0:2b4ea8a138e5 276 m_pControlEp->setNextToken(TD_SETUP);
va009039 0:2b4ea8a138e5 277 rc = m_pControlEp->transfer(m_controlBuf, 8);
va009039 0:2b4ea8a138e5 278 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:2b4ea8a138e5 279 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:2b4ea8a138e5 280 if(rc)
va009039 0:2b4ea8a138e5 281 return rc;
va009039 0:2b4ea8a138e5 282 if(len)
va009039 0:2b4ea8a138e5 283 {
va009039 0:2b4ea8a138e5 284 m_pControlEp->setNextToken(TD_OUT);
va009039 0:2b4ea8a138e5 285 rc = m_pControlEp->transfer((byte*)buf, len);
va009039 0:2b4ea8a138e5 286 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:2b4ea8a138e5 287 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:2b4ea8a138e5 288 if(rc)
va009039 0:2b4ea8a138e5 289 return rc;
va009039 0:2b4ea8a138e5 290 }
va009039 0:2b4ea8a138e5 291 m_pControlEp->setNextToken(TD_IN);
va009039 0:2b4ea8a138e5 292 rc = m_pControlEp->transfer(NULL, 0);
va009039 0:2b4ea8a138e5 293 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:2b4ea8a138e5 294 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:2b4ea8a138e5 295 if(rc)
va009039 0:2b4ea8a138e5 296 return rc;
va009039 0:2b4ea8a138e5 297 return USBERR_OK;
va009039 0:2b4ea8a138e5 298 }
va009039 0:2b4ea8a138e5 299
va009039 0:2b4ea8a138e5 300 UsbErr UsbDevice::controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len)
va009039 0:2b4ea8a138e5 301 {
va009039 0:2b4ea8a138e5 302 DBG("buf=%p len=%d\n", buf, len);
va009039 0:2b4ea8a138e5 303 UsbErr rc;
va009039 0:2b4ea8a138e5 304 fillControlBuf(requestType, request, value, index, len);
va009039 0:2b4ea8a138e5 305 DBG_ASSERT(m_pControlEp);
va009039 0:2b4ea8a138e5 306 m_pControlEp->setNextToken(TD_SETUP);
va009039 0:2b4ea8a138e5 307 rc = m_pControlEp->transfer(m_controlBuf, 8);
va009039 0:2b4ea8a138e5 308 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:2b4ea8a138e5 309 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:2b4ea8a138e5 310 if(rc)
va009039 0:2b4ea8a138e5 311 return rc;
va009039 0:2b4ea8a138e5 312 if(len)
va009039 0:2b4ea8a138e5 313 {
va009039 0:2b4ea8a138e5 314 m_pControlEp->setNextToken(TD_IN);
va009039 0:2b4ea8a138e5 315 rc = m_pControlEp->transfer( (byte*) buf, len);
va009039 0:2b4ea8a138e5 316 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:2b4ea8a138e5 317 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:2b4ea8a138e5 318 if(rc)
va009039 0:2b4ea8a138e5 319 return rc;
va009039 0:2b4ea8a138e5 320 }
va009039 0:2b4ea8a138e5 321 m_pControlEp->setNextToken(TD_OUT);
va009039 0:2b4ea8a138e5 322 rc = m_pControlEp->transfer(NULL, 0);
va009039 0:2b4ea8a138e5 323 while(m_pControlEp->status() == USBERR_PROCESSING);
va009039 0:2b4ea8a138e5 324 rc = (UsbErr) MIN(0, m_pControlEp->status());
va009039 0:2b4ea8a138e5 325 if(rc)
va009039 0:2b4ea8a138e5 326 return rc;
va009039 0:2b4ea8a138e5 327 return USBERR_OK;
va009039 0:2b4ea8a138e5 328 }
va009039 0:2b4ea8a138e5 329
va009039 0:2b4ea8a138e5 330 UsbErr UsbDevice::GetDescriptor(int type, int index, const byte* buf, int len)
va009039 0:2b4ea8a138e5 331 {
va009039 0:2b4ea8a138e5 332 DBG("type=%02X\n", type);
va009039 0:2b4ea8a138e5 333 return controlReceive(
va009039 0:2b4ea8a138e5 334 USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR,
va009039 0:2b4ea8a138e5 335 (type << 8) |(index), 0, buf, len);
va009039 0:2b4ea8a138e5 336
va009039 0:2b4ea8a138e5 337 }
va009039 0:2b4ea8a138e5 338
va009039 0:2b4ea8a138e5 339 UsbErr UsbDevice::GetString(int index, char* buf, int len)
va009039 0:2b4ea8a138e5 340 {
va009039 0:2b4ea8a138e5 341 DBG("index=%d buf=%p len=%d\n", index, buf, len);
va009039 0:2b4ea8a138e5 342 DBG_ASSERT(index >= 1);
va009039 0:2b4ea8a138e5 343 uint8_t temp[4];
va009039 0:2b4ea8a138e5 344 UsbErr rc;
va009039 0:2b4ea8a138e5 345 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, 0, temp, sizeof(temp));
va009039 0:2b4ea8a138e5 346 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 347 DBG_BYTES("LANG_ID", temp, sizeof(temp));
va009039 0:2b4ea8a138e5 348 DBG_ASSERT(temp[0] == 4);
va009039 0:2b4ea8a138e5 349 DBG_ASSERT(temp[1] == 0x03);
va009039 0:2b4ea8a138e5 350
va009039 0:2b4ea8a138e5 351 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp, 2);
va009039 0:2b4ea8a138e5 352 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 353 DBG_BYTES("length check", temp, 2);
va009039 0:2b4ea8a138e5 354 if (temp[0] == 0x00 && temp[1] == 0x00) { // for pl2303
va009039 0:2b4ea8a138e5 355 if (len > 0) {
va009039 0:2b4ea8a138e5 356 strcpy(buf, "");
va009039 0:2b4ea8a138e5 357 }
va009039 0:2b4ea8a138e5 358 return rc;
va009039 0:2b4ea8a138e5 359 }
va009039 0:2b4ea8a138e5 360 DBG_ASSERT(temp[1] == 0x03);
va009039 0:2b4ea8a138e5 361 int temp_len = temp[0];
va009039 0:2b4ea8a138e5 362
va009039 0:2b4ea8a138e5 363 uint8_t* temp_buf = new uint8_t[temp_len];
va009039 0:2b4ea8a138e5 364 DBG_ASSERT(temp_buf);
va009039 0:2b4ea8a138e5 365 rc = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, temp_buf, temp_len);
va009039 0:2b4ea8a138e5 366 DBG_ASSERT(rc == USBERR_OK);
va009039 0:2b4ea8a138e5 367 temp_len = temp_buf[0];
va009039 0:2b4ea8a138e5 368 DBG_HEX(temp_buf, temp_len);
va009039 0:2b4ea8a138e5 369 int i = 0;
va009039 0:2b4ea8a138e5 370 for(int pos = 2; pos < temp_len; pos+= 2) {
va009039 0:2b4ea8a138e5 371 buf[i++] = temp_buf[pos];
va009039 0:2b4ea8a138e5 372 DBG_ASSERT(i < len-1);
va009039 0:2b4ea8a138e5 373 }
va009039 0:2b4ea8a138e5 374 buf[i] = '\0';
va009039 0:2b4ea8a138e5 375 delete[] temp_buf;
va009039 0:2b4ea8a138e5 376 return rc;
va009039 0:2b4ea8a138e5 377 }
va009039 0:2b4ea8a138e5 378
va009039 0:2b4ea8a138e5 379 UsbErr UsbDevice::SetInterfaceAlternate(int interface, int alternate)
va009039 0:2b4ea8a138e5 380 {
va009039 0:2b4ea8a138e5 381 UsbErr rc = controlSend(
va009039 0:2b4ea8a138e5 382 USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE,
va009039 0:2b4ea8a138e5 383 SET_INTERFACE, alternate, interface, NULL, 0);
va009039 0:2b4ea8a138e5 384 return rc;
va009039 0:2b4ea8a138e5 385 }
va009039 0:2b4ea8a138e5 386
va009039 0:2b4ea8a138e5 387 void UsbDevice::fillControlBuf(byte requestType, byte request, word value, word index, int len)
va009039 0:2b4ea8a138e5 388 {
va009039 0:2b4ea8a138e5 389 #ifdef __BIG_ENDIAN
va009039 0:2b4ea8a138e5 390 #error "Must implement BE to LE conv here"
va009039 0:2b4ea8a138e5 391 #endif
va009039 0:2b4ea8a138e5 392 m_controlBuf[0] = requestType;
va009039 0:2b4ea8a138e5 393 m_controlBuf[1] = request;
va009039 0:2b4ea8a138e5 394 //We are in LE so it's fine
va009039 0:2b4ea8a138e5 395 *((word*)&m_controlBuf[2]) = value;
va009039 0:2b4ea8a138e5 396 *((word*)&m_controlBuf[4]) = index;
va009039 0:2b4ea8a138e5 397 *((word*)&m_controlBuf[6]) = (word) len;
va009039 0:2b4ea8a138e5 398 }
va009039 0:2b4ea8a138e5 399
va009039 0:2b4ea8a138e5 400