UVC host library

Dependents:   LifeCam WebcamServer

Committer:
va009039
Date:
Wed Aug 15 13:52:53 2012 +0000
Revision:
3:3eb41d749f9a
Parent:
0:b0f04c137829
add USB_USE_MALLOC

Who changed what in which revision?

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