Committer:
mbed714
Date:
Sat Sep 18 23:05:49 2010 +0000
Revision:
0:d616ece2d859

        

Who changed what in which revision?

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