This library is stripped down version of NetServices library. HTTP server and client function is NOT supported.

Dependents:   imu-daq-eth

Committer:
idinor
Date:
Wed Jul 20 11:45:39 2011 +0000
Revision:
0:dcf3c92487ca

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
idinor 0:dcf3c92487ca 1
idinor 0:dcf3c92487ca 2 /*
idinor 0:dcf3c92487ca 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
idinor 0:dcf3c92487ca 4
idinor 0:dcf3c92487ca 5 Permission is hereby granted, free of charge, to any person obtaining a copy
idinor 0:dcf3c92487ca 6 of this software and associated documentation files (the "Software"), to deal
idinor 0:dcf3c92487ca 7 in the Software without restriction, including without limitation the rights
idinor 0:dcf3c92487ca 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
idinor 0:dcf3c92487ca 9 copies of the Software, and to permit persons to whom the Software is
idinor 0:dcf3c92487ca 10 furnished to do so, subject to the following conditions:
idinor 0:dcf3c92487ca 11
idinor 0:dcf3c92487ca 12 The above copyright notice and this permission notice shall be included in
idinor 0:dcf3c92487ca 13 all copies or substantial portions of the Software.
idinor 0:dcf3c92487ca 14
idinor 0:dcf3c92487ca 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
idinor 0:dcf3c92487ca 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
idinor 0:dcf3c92487ca 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
idinor 0:dcf3c92487ca 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
idinor 0:dcf3c92487ca 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
idinor 0:dcf3c92487ca 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
idinor 0:dcf3c92487ca 21 THE SOFTWARE.
idinor 0:dcf3c92487ca 22 */
idinor 0:dcf3c92487ca 23
idinor 0:dcf3c92487ca 24 #include "UsbDevice.h"
idinor 0:dcf3c92487ca 25
idinor 0:dcf3c92487ca 26 #include "netCfg.h"
idinor 0:dcf3c92487ca 27 #if NET_USB
idinor 0:dcf3c92487ca 28
idinor 0:dcf3c92487ca 29 //#define __DEBUG
idinor 0:dcf3c92487ca 30 #include "dbg/dbg.h"
idinor 0:dcf3c92487ca 31
idinor 0:dcf3c92487ca 32 UsbDevice::UsbDevice( UsbHostMgr* pMgr, int hub, int port, int addr ) : m_pControlEp(NULL), /*m_controlEp( this, 0x00, false, USB_CONTROL, 8 ),*/
idinor 0:dcf3c92487ca 33 m_pMgr(pMgr), m_connected(false), m_enumerated(false), m_hub(hub), m_port(port), m_addr(addr), m_refs(0),
idinor 0:dcf3c92487ca 34 m_vid(0), m_pid(0)
idinor 0:dcf3c92487ca 35 {
idinor 0:dcf3c92487ca 36
idinor 0:dcf3c92487ca 37 }
idinor 0:dcf3c92487ca 38
idinor 0:dcf3c92487ca 39 UsbDevice::~UsbDevice()
idinor 0:dcf3c92487ca 40 {
idinor 0:dcf3c92487ca 41 if(m_pControlEp)
idinor 0:dcf3c92487ca 42 delete m_pControlEp;
idinor 0:dcf3c92487ca 43 }
idinor 0:dcf3c92487ca 44
idinor 0:dcf3c92487ca 45 UsbErr UsbDevice::enumerate()
idinor 0:dcf3c92487ca 46 {
idinor 0:dcf3c92487ca 47 // USB_INT32S rc;
idinor 0:dcf3c92487ca 48
idinor 0:dcf3c92487ca 49 UsbErr rc;
idinor 0:dcf3c92487ca 50
idinor 0:dcf3c92487ca 51 DBG("Starting enumeration (m_pMgr = %p)\n", m_pMgr);
idinor 0:dcf3c92487ca 52
idinor 0:dcf3c92487ca 53 #if 1
idinor 0:dcf3c92487ca 54 m_pMgr->resetPort(m_hub, m_port);
idinor 0:dcf3c92487ca 55 #else
idinor 0:dcf3c92487ca 56 wait_ms(100); /* USB 2.0 spec says atleast 50ms delay beore port reset */
idinor 0:dcf3c92487ca 57 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
idinor 0:dcf3c92487ca 58 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
idinor 0:dcf3c92487ca 59 __WFI(); // Wait for port reset to complete...
idinor 0:dcf3c92487ca 60 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
idinor 0:dcf3c92487ca 61 wait_ms(200); /* Wait for 100 MS after port reset */
idinor 0:dcf3c92487ca 62 #endif
idinor 0:dcf3c92487ca 63
idinor 0:dcf3c92487ca 64 DBG("Port reset\n");
idinor 0:dcf3c92487ca 65
idinor 0:dcf3c92487ca 66 wait_ms(200);
idinor 0:dcf3c92487ca 67
idinor 0:dcf3c92487ca 68 m_pControlEp = new UsbEndpoint( this, 0x00, false, USB_CONTROL, 8, 0 );
idinor 0:dcf3c92487ca 69
idinor 0:dcf3c92487ca 70 //EDCtrl->Control = 8 << 16;/* Put max pkt size = 8 */
idinor 0:dcf3c92487ca 71 /* Read first 8 bytes of device desc */
idinor 0:dcf3c92487ca 72 rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0, m_controlDataBuf, 8);
idinor 0:dcf3c92487ca 73 if (rc)
idinor 0:dcf3c92487ca 74 {
idinor 0:dcf3c92487ca 75 DBG("RC=%d",rc);
idinor 0:dcf3c92487ca 76 return (rc);
idinor 0:dcf3c92487ca 77 }
idinor 0:dcf3c92487ca 78
idinor 0:dcf3c92487ca 79 DBG("Got descriptor, max ep size is %d\n", m_controlDataBuf[7]);
idinor 0:dcf3c92487ca 80
idinor 0:dcf3c92487ca 81 m_pControlEp->updateSize(m_controlDataBuf[7]); /* Get max pkt size of endpoint 0 */
idinor 0:dcf3c92487ca 82 rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS, m_addr, 0, NULL, 0); /* Set the device address to m_addr */
idinor 0:dcf3c92487ca 83 if (rc)
idinor 0:dcf3c92487ca 84 {
idinor 0:dcf3c92487ca 85 // PRINT_Err(rc);
idinor 0:dcf3c92487ca 86 return (rc);
idinor 0:dcf3c92487ca 87 }
idinor 0:dcf3c92487ca 88 wait_ms(2);
idinor 0:dcf3c92487ca 89 //EDCtrl->Control = (EDCtrl->Control) | 1; /* Modify control pipe with address 1 */
idinor 0:dcf3c92487ca 90
idinor 0:dcf3c92487ca 91 //Update address
idinor 0:dcf3c92487ca 92 m_pControlEp->updateAddr(m_addr);
idinor 0:dcf3c92487ca 93 DBG("Ep addr is now %d", m_addr);
idinor 0:dcf3c92487ca 94 /**/
idinor 0:dcf3c92487ca 95
idinor 0:dcf3c92487ca 96 //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 17); //Read full device descriptor
idinor 0:dcf3c92487ca 97 rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_DEVICE << 8)|(0), 0, m_controlDataBuf, 17);
idinor 0:dcf3c92487ca 98 if (rc)
idinor 0:dcf3c92487ca 99 {
idinor 0:dcf3c92487ca 100 //PRINT_Err(rc);
idinor 0:dcf3c92487ca 101 return (rc);
idinor 0:dcf3c92487ca 102 }
idinor 0:dcf3c92487ca 103 /*
idinor 0:dcf3c92487ca 104 rc = SerialCheckVidPid();
idinor 0:dcf3c92487ca 105 if (rc != OK) {
idinor 0:dcf3c92487ca 106 PRINT_Err(rc);
idinor 0:dcf3c92487ca 107 return (rc);
idinor 0:dcf3c92487ca 108 }
idinor 0:dcf3c92487ca 109 */
idinor 0:dcf3c92487ca 110 /**/
idinor 0:dcf3c92487ca 111
idinor 0:dcf3c92487ca 112 m_vid = *((uint16_t*)&m_controlDataBuf[8]);
idinor 0:dcf3c92487ca 113 m_pid = *((uint16_t*)&m_controlDataBuf[10]);
idinor 0:dcf3c92487ca 114
idinor 0:dcf3c92487ca 115 DBG("VID: %02x, PID: %02x\n", m_vid, m_pid);
idinor 0:dcf3c92487ca 116 /* Get the configuration descriptor */
idinor 0:dcf3c92487ca 117 //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9);
idinor 0:dcf3c92487ca 118 rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_CONFIGURATION << 8)|(0), 0, m_controlDataBuf, 9);
idinor 0:dcf3c92487ca 119 if (rc)
idinor 0:dcf3c92487ca 120 {
idinor 0:dcf3c92487ca 121 //PRINT_Err(rc);
idinor 0:dcf3c92487ca 122 return (rc);
idinor 0:dcf3c92487ca 123 }
idinor 0:dcf3c92487ca 124 /* Get the first configuration data */
idinor 0:dcf3c92487ca 125 //rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, *((uint16_t*)&TDBuffer[2]));
idinor 0:dcf3c92487ca 126 rc = controlReceive(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR, (USB_DESCRIPTOR_TYPE_CONFIGURATION << 8)|(0), 0, m_controlDataBuf, *((uint16_t*)&m_controlDataBuf[2]));
idinor 0:dcf3c92487ca 127 if (rc)
idinor 0:dcf3c92487ca 128 {
idinor 0:dcf3c92487ca 129 //PRINT_Err(rc);
idinor 0:dcf3c92487ca 130 return (rc);
idinor 0:dcf3c92487ca 131 }
idinor 0:dcf3c92487ca 132
idinor 0:dcf3c92487ca 133 DBG("Desc len is %d\n", *((uint16_t*)&m_controlDataBuf[2]));
idinor 0:dcf3c92487ca 134
idinor 0:dcf3c92487ca 135 DBG("Set configuration\n");
idinor 0:dcf3c92487ca 136
idinor 0:dcf3c92487ca 137 //rc = USBH_SET_CONFIGURATION(1);/* Select device configuration 1 */
idinor 0:dcf3c92487ca 138 rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_CONFIGURATION, 1, 0, NULL, 0);
idinor 0:dcf3c92487ca 139 if (rc)
idinor 0:dcf3c92487ca 140 {
idinor 0:dcf3c92487ca 141 // PRINT_Err(rc);
idinor 0:dcf3c92487ca 142 return rc;
idinor 0:dcf3c92487ca 143 }
idinor 0:dcf3c92487ca 144 wait_ms(100);/* Some devices may require this delay */
idinor 0:dcf3c92487ca 145
idinor 0:dcf3c92487ca 146 m_enumerated = true;
idinor 0:dcf3c92487ca 147 return USBERR_OK;
idinor 0:dcf3c92487ca 148 }
idinor 0:dcf3c92487ca 149
idinor 0:dcf3c92487ca 150 bool UsbDevice::connected()
idinor 0:dcf3c92487ca 151 {
idinor 0:dcf3c92487ca 152 return m_connected;
idinor 0:dcf3c92487ca 153 }
idinor 0:dcf3c92487ca 154
idinor 0:dcf3c92487ca 155 bool UsbDevice::enumerated()
idinor 0:dcf3c92487ca 156 {
idinor 0:dcf3c92487ca 157 return m_enumerated;
idinor 0:dcf3c92487ca 158 }
idinor 0:dcf3c92487ca 159
idinor 0:dcf3c92487ca 160 int UsbDevice::getPid()
idinor 0:dcf3c92487ca 161 {
idinor 0:dcf3c92487ca 162 return m_pid;
idinor 0:dcf3c92487ca 163 }
idinor 0:dcf3c92487ca 164
idinor 0:dcf3c92487ca 165 int UsbDevice::getVid()
idinor 0:dcf3c92487ca 166 {
idinor 0:dcf3c92487ca 167 return m_vid;
idinor 0:dcf3c92487ca 168 }
idinor 0:dcf3c92487ca 169
idinor 0:dcf3c92487ca 170 UsbErr UsbDevice::getConfigurationDescriptor(int config, uint8_t** pBuf)
idinor 0:dcf3c92487ca 171 {
idinor 0:dcf3c92487ca 172 //For now olny one config
idinor 0:dcf3c92487ca 173 *pBuf = m_controlDataBuf;
idinor 0:dcf3c92487ca 174 return USBERR_OK;
idinor 0:dcf3c92487ca 175 }
idinor 0:dcf3c92487ca 176
idinor 0:dcf3c92487ca 177 UsbErr UsbDevice::getInterfaceDescriptor(int config, int item, uint8_t** pBuf)
idinor 0:dcf3c92487ca 178 {
idinor 0:dcf3c92487ca 179 byte* desc_ptr = m_controlDataBuf;
idinor 0:dcf3c92487ca 180
idinor 0:dcf3c92487ca 181 /* if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION)
idinor 0:dcf3c92487ca 182 {
idinor 0:dcf3c92487ca 183 return USBERR_BADCONFIG;
idinor 0:dcf3c92487ca 184 }*/
idinor 0:dcf3c92487ca 185
idinor 0:dcf3c92487ca 186 if(item>=m_controlDataBuf[4])//Interfaces count
idinor 0:dcf3c92487ca 187 return USBERR_NOTFOUND;
idinor 0:dcf3c92487ca 188
idinor 0:dcf3c92487ca 189 desc_ptr += desc_ptr[0];
idinor 0:dcf3c92487ca 190
idinor 0:dcf3c92487ca 191 *pBuf = NULL;
idinor 0:dcf3c92487ca 192
idinor 0:dcf3c92487ca 193 while (desc_ptr < m_controlDataBuf + *((uint16_t*)&m_controlDataBuf[2]))
idinor 0:dcf3c92487ca 194 {
idinor 0:dcf3c92487ca 195
idinor 0:dcf3c92487ca 196 switch (desc_ptr[1]) {
idinor 0:dcf3c92487ca 197 case USB_DESCRIPTOR_TYPE_INTERFACE:
idinor 0:dcf3c92487ca 198 if(desc_ptr[2] == item)
idinor 0:dcf3c92487ca 199 {
idinor 0:dcf3c92487ca 200 *pBuf = desc_ptr;
idinor 0:dcf3c92487ca 201 return USBERR_OK;
idinor 0:dcf3c92487ca 202 }
idinor 0:dcf3c92487ca 203 desc_ptr += desc_ptr[0]; // Move to next descriptor start
idinor 0:dcf3c92487ca 204 break;
idinor 0:dcf3c92487ca 205 }
idinor 0:dcf3c92487ca 206
idinor 0:dcf3c92487ca 207 }
idinor 0:dcf3c92487ca 208
idinor 0:dcf3c92487ca 209 if(*pBuf == NULL)
idinor 0:dcf3c92487ca 210 return USBERR_NOTFOUND;
idinor 0:dcf3c92487ca 211
idinor 0:dcf3c92487ca 212 return USBERR_OK;
idinor 0:dcf3c92487ca 213 }
idinor 0:dcf3c92487ca 214
idinor 0:dcf3c92487ca 215
idinor 0:dcf3c92487ca 216 UsbErr UsbDevice::setConfiguration(int config)
idinor 0:dcf3c92487ca 217 {
idinor 0:dcf3c92487ca 218 return USBERR_OK;
idinor 0:dcf3c92487ca 219 }
idinor 0:dcf3c92487ca 220
idinor 0:dcf3c92487ca 221 UsbErr UsbDevice::controlSend(byte requestType, byte request, word value, word index, const byte* buf, int len)
idinor 0:dcf3c92487ca 222 {
idinor 0:dcf3c92487ca 223 UsbErr rc;
idinor 0:dcf3c92487ca 224 fillControlBuf(requestType, request, value, index, len);
idinor 0:dcf3c92487ca 225 m_pControlEp->setNextToken(TD_SETUP);
idinor 0:dcf3c92487ca 226 rc = m_pControlEp->transfer(m_controlBuf, 8);
idinor 0:dcf3c92487ca 227 while(m_pControlEp->status() == USBERR_PROCESSING);
idinor 0:dcf3c92487ca 228 rc = (UsbErr) MIN(0, m_pControlEp->status());
idinor 0:dcf3c92487ca 229 if(rc)
idinor 0:dcf3c92487ca 230 return rc;
idinor 0:dcf3c92487ca 231 if(len)
idinor 0:dcf3c92487ca 232 {
idinor 0:dcf3c92487ca 233 m_pControlEp->setNextToken(TD_OUT);
idinor 0:dcf3c92487ca 234 rc = m_pControlEp->transfer((byte*)buf, len);
idinor 0:dcf3c92487ca 235 while(m_pControlEp->status() == USBERR_PROCESSING);
idinor 0:dcf3c92487ca 236 rc = (UsbErr) MIN(0, m_pControlEp->status());
idinor 0:dcf3c92487ca 237 if(rc)
idinor 0:dcf3c92487ca 238 return rc;
idinor 0:dcf3c92487ca 239 }
idinor 0:dcf3c92487ca 240 m_pControlEp->setNextToken(TD_IN);
idinor 0:dcf3c92487ca 241 rc = m_pControlEp->transfer(NULL, 0);
idinor 0:dcf3c92487ca 242 while(m_pControlEp->status() == USBERR_PROCESSING);
idinor 0:dcf3c92487ca 243 rc = (UsbErr) MIN(0, m_pControlEp->status());
idinor 0:dcf3c92487ca 244 if(rc)
idinor 0:dcf3c92487ca 245 return rc;
idinor 0:dcf3c92487ca 246 return USBERR_OK;
idinor 0:dcf3c92487ca 247 }
idinor 0:dcf3c92487ca 248
idinor 0:dcf3c92487ca 249 UsbErr UsbDevice::controlReceive(byte requestType, byte request, word value, word index, const byte* buf, int len)
idinor 0:dcf3c92487ca 250 {
idinor 0:dcf3c92487ca 251 UsbErr rc;
idinor 0:dcf3c92487ca 252 fillControlBuf(requestType, request, value, index, len);
idinor 0:dcf3c92487ca 253 m_pControlEp->setNextToken(TD_SETUP);
idinor 0:dcf3c92487ca 254 rc = m_pControlEp->transfer(m_controlBuf, 8);
idinor 0:dcf3c92487ca 255 while(m_pControlEp->status() == USBERR_PROCESSING);
idinor 0:dcf3c92487ca 256 rc = (UsbErr) MIN(0, m_pControlEp->status());
idinor 0:dcf3c92487ca 257 if(rc)
idinor 0:dcf3c92487ca 258 return rc;
idinor 0:dcf3c92487ca 259 if(len)
idinor 0:dcf3c92487ca 260 {
idinor 0:dcf3c92487ca 261 m_pControlEp->setNextToken(TD_IN);
idinor 0:dcf3c92487ca 262 rc = m_pControlEp->transfer( (byte*) buf, len);
idinor 0:dcf3c92487ca 263 while(m_pControlEp->status() == USBERR_PROCESSING);
idinor 0:dcf3c92487ca 264 rc = (UsbErr) MIN(0, m_pControlEp->status());
idinor 0:dcf3c92487ca 265 if(rc)
idinor 0:dcf3c92487ca 266 return rc;
idinor 0:dcf3c92487ca 267 }
idinor 0:dcf3c92487ca 268 m_pControlEp->setNextToken(TD_OUT);
idinor 0:dcf3c92487ca 269 rc = m_pControlEp->transfer(NULL, 0);
idinor 0:dcf3c92487ca 270 while(m_pControlEp->status() == USBERR_PROCESSING);
idinor 0:dcf3c92487ca 271 rc = (UsbErr) MIN(0, m_pControlEp->status());
idinor 0:dcf3c92487ca 272 if(rc)
idinor 0:dcf3c92487ca 273 return rc;
idinor 0:dcf3c92487ca 274 return USBERR_OK;
idinor 0:dcf3c92487ca 275 }
idinor 0:dcf3c92487ca 276
idinor 0:dcf3c92487ca 277 void UsbDevice::fillControlBuf(byte requestType, byte request, word value, word index, int len)
idinor 0:dcf3c92487ca 278 {
idinor 0:dcf3c92487ca 279 #ifdef __BIG_ENDIAN
idinor 0:dcf3c92487ca 280 #error "Must implement BE to LE conv here"
idinor 0:dcf3c92487ca 281 #endif
idinor 0:dcf3c92487ca 282 m_controlBuf[0] = requestType;
idinor 0:dcf3c92487ca 283 m_controlBuf[1] = request;
idinor 0:dcf3c92487ca 284 //We are in LE so it's fine
idinor 0:dcf3c92487ca 285 *((word*)&m_controlBuf[2]) = value;
idinor 0:dcf3c92487ca 286 *((word*)&m_controlBuf[4]) = index;
idinor 0:dcf3c92487ca 287 *((word*)&m_controlBuf[6]) = (word) len;
idinor 0:dcf3c92487ca 288 }
idinor 0:dcf3c92487ca 289
idinor 0:dcf3c92487ca 290
idinor 0:dcf3c92487ca 291 #endif