うおーるぼっとをiPhoneでコントロールするプログラムです。 iPhoneとはBTLEで接続しています。

Dependencies:   FatFileSystem HighSpeedAnalogIn TB6612FNG2 mbed

Committer:
jksoft
Date:
Fri May 10 11:48:07 2013 +0000
Revision:
0:373bcb197dc8
?????????

Who changed what in which revision?

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