Version of http://mbed.org/cookbook/NetServicesTribute with setting set the same for LPC2368

Dependents:   UDPSocketExample 24LCxx_I2CApp WeatherPlatform_pachube HvZServerLib ... more

Committer:
simon
Date:
Tue Nov 23 14:15:36 2010 +0000
Revision:
0:350011bf8be7
Experimental version for testing UDP

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:350011bf8be7 1
simon 0:350011bf8be7 2 /*
simon 0:350011bf8be7 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
simon 0:350011bf8be7 4
simon 0:350011bf8be7 5 Permission is hereby granted, free of charge, to any person obtaining a copy
simon 0:350011bf8be7 6 of this software and associated documentation files (the "Software"), to deal
simon 0:350011bf8be7 7 in the Software without restriction, including without limitation the rights
simon 0:350011bf8be7 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 0:350011bf8be7 9 copies of the Software, and to permit persons to whom the Software is
simon 0:350011bf8be7 10 furnished to do so, subject to the following conditions:
simon 0:350011bf8be7 11
simon 0:350011bf8be7 12 The above copyright notice and this permission notice shall be included in
simon 0:350011bf8be7 13 all copies or substantial portions of the Software.
simon 0:350011bf8be7 14
simon 0:350011bf8be7 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 0:350011bf8be7 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 0:350011bf8be7 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 0:350011bf8be7 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 0:350011bf8be7 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 0:350011bf8be7 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 0:350011bf8be7 21 THE SOFTWARE.
simon 0:350011bf8be7 22 */
simon 0:350011bf8be7 23
simon 0:350011bf8be7 24 #include "UsbHostMgr.h"
simon 0:350011bf8be7 25
simon 0:350011bf8be7 26 #include "usb_mem.h"
simon 0:350011bf8be7 27
simon 0:350011bf8be7 28 #include "string.h" //For memcpy, memmove, memset
simon 0:350011bf8be7 29
simon 0:350011bf8be7 30 #include "netCfg.h"
simon 0:350011bf8be7 31 #if NET_USB
simon 0:350011bf8be7 32
simon 0:350011bf8be7 33 //#define __DEBUG
simon 0:350011bf8be7 34 #include "dbg/dbg.h"
simon 0:350011bf8be7 35
simon 0:350011bf8be7 36 // bits of the USB/OTG clock control register
simon 0:350011bf8be7 37 #define HOST_CLK_EN (1<<0)
simon 0:350011bf8be7 38 #define DEV_CLK_EN (1<<1)
simon 0:350011bf8be7 39 #define PORTSEL_CLK_EN (1<<3)
simon 0:350011bf8be7 40 #define AHB_CLK_EN (1<<4)
simon 0:350011bf8be7 41
simon 0:350011bf8be7 42 // bits of the USB/OTG clock status register
simon 0:350011bf8be7 43 #define HOST_CLK_ON (1<<0)
simon 0:350011bf8be7 44 #define DEV_CLK_ON (1<<1)
simon 0:350011bf8be7 45 #define PORTSEL_CLK_ON (1<<3)
simon 0:350011bf8be7 46 #define AHB_CLK_ON (1<<4)
simon 0:350011bf8be7 47
simon 0:350011bf8be7 48 // we need host clock, OTG/portsel clock and AHB clock
simon 0:350011bf8be7 49 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
simon 0:350011bf8be7 50
simon 0:350011bf8be7 51 static UsbHostMgr* pMgr = NULL;
simon 0:350011bf8be7 52
simon 0:350011bf8be7 53 extern "C" void sUsbIrqhandler(void) __irq
simon 0:350011bf8be7 54 {
simon 0:350011bf8be7 55 DBG("\n+Int\n");
simon 0:350011bf8be7 56 if(pMgr)
simon 0:350011bf8be7 57 pMgr->UsbIrqhandler();
simon 0:350011bf8be7 58 DBG("\n-Int\n");
simon 0:350011bf8be7 59 return;
simon 0:350011bf8be7 60 }
simon 0:350011bf8be7 61
simon 0:350011bf8be7 62 UsbHostMgr::UsbHostMgr() : m_lpDevices()
simon 0:350011bf8be7 63 {
simon 0:350011bf8be7 64 /*if(!pMgr)*/ //Assume singleton
simon 0:350011bf8be7 65 pMgr = this;
simon 0:350011bf8be7 66 usb_mem_init();
simon 0:350011bf8be7 67 memset(m_lpDevices, NULL, sizeof(UsbDevice*) * USB_HOSTMGR_MAX_DEVS);
simon 0:350011bf8be7 68 m_pHcca = (HCCA*) usb_get_hcca();
simon 0:350011bf8be7 69 memset((void*)m_pHcca, 0, 0x100);
simon 0:350011bf8be7 70 DBG("Host manager at %p\n", this);
simon 0:350011bf8be7 71 }
simon 0:350011bf8be7 72
simon 0:350011bf8be7 73 UsbHostMgr::~UsbHostMgr()
simon 0:350011bf8be7 74 {
simon 0:350011bf8be7 75 if(pMgr == this)
simon 0:350011bf8be7 76 pMgr = NULL;
simon 0:350011bf8be7 77 }
simon 0:350011bf8be7 78
simon 0:350011bf8be7 79 UsbErr UsbHostMgr::init() //Initialize host
simon 0:350011bf8be7 80 {
simon 0:350011bf8be7 81 NVIC_DisableIRQ(USB_IRQn); /* Disable the USB interrupt source */
simon 0:350011bf8be7 82
simon 0:350011bf8be7 83 LPC_SC->PCONP &= ~(1UL<<31); //Cut power
simon 0:350011bf8be7 84 wait(1);
simon 0:350011bf8be7 85
simon 0:350011bf8be7 86
simon 0:350011bf8be7 87 // turn on power for USB
simon 0:350011bf8be7 88 LPC_SC->PCONP |= (1UL<<31);
simon 0:350011bf8be7 89 // Enable USB host clock, port selection and AHB clock
simon 0:350011bf8be7 90 LPC_USB->USBClkCtrl |= CLOCK_MASK;
simon 0:350011bf8be7 91 // Wait for clocks to become available
simon 0:350011bf8be7 92 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
simon 0:350011bf8be7 93 ;
simon 0:350011bf8be7 94
simon 0:350011bf8be7 95 // it seems the bits[0:1] mean the following
simon 0:350011bf8be7 96 // 0: U1=device, U2=host
simon 0:350011bf8be7 97 // 1: U1=host, U2=host
simon 0:350011bf8be7 98 // 2: reserved
simon 0:350011bf8be7 99 // 3: U1=host, U2=device
simon 0:350011bf8be7 100 // NB: this register is only available if OTG clock (aka "port select") is enabled!!
simon 0:350011bf8be7 101 // since we don't care about port 2, set just bit 0 to 1 (U1=host)
simon 0:350011bf8be7 102 LPC_USB->OTGStCtrl |= 1;
simon 0:350011bf8be7 103
simon 0:350011bf8be7 104 // now that we've configured the ports, we can turn off the portsel clock
simon 0:350011bf8be7 105 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
simon 0:350011bf8be7 106
simon 0:350011bf8be7 107 // power pins are not connected on mbed, so we can skip them
simon 0:350011bf8be7 108 /* P1[18] = USB_UP_LED, 01 */
simon 0:350011bf8be7 109 /* P1[19] = /USB_PPWR, 10 */
simon 0:350011bf8be7 110 /* P1[22] = USB_PWRD, 10 */
simon 0:350011bf8be7 111 /* P1[27] = /USB_OVRCR, 10 */
simon 0:350011bf8be7 112 /*LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22));
simon 0:350011bf8be7 113 LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080
simon 0:350011bf8be7 114 */
simon 0:350011bf8be7 115
simon 0:350011bf8be7 116 // configure USB D+/D- pins
simon 0:350011bf8be7 117 /* P0[29] = USB_D+, 01 */
simon 0:350011bf8be7 118 /* P0[30] = USB_D-, 01 */
simon 0:350011bf8be7 119 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
simon 0:350011bf8be7 120 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000
simon 0:350011bf8be7 121
simon 0:350011bf8be7 122 DBG("Initializing Host Stack\n");
simon 0:350011bf8be7 123
simon 0:350011bf8be7 124 wait_ms(100); /* Wait 50 ms before apply reset */
simon 0:350011bf8be7 125 LPC_USB->HcControl = 0; /* HARDWARE RESET */
simon 0:350011bf8be7 126 LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */
simon 0:350011bf8be7 127 LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */
simon 0:350011bf8be7 128
simon 0:350011bf8be7 129 /* SOFTWARE RESET */
simon 0:350011bf8be7 130 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
simon 0:350011bf8be7 131 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */
simon 0:350011bf8be7 132
simon 0:350011bf8be7 133 /* Put HC in operational state */
simon 0:350011bf8be7 134 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
simon 0:350011bf8be7 135 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */
simon 0:350011bf8be7 136
simon 0:350011bf8be7 137 LPC_USB->HcHCCA = (uint32_t)(m_pHcca);
simon 0:350011bf8be7 138 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */
simon 0:350011bf8be7 139
simon 0:350011bf8be7 140
simon 0:350011bf8be7 141 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE |
simon 0:350011bf8be7 142 OR_INTR_ENABLE_WDH |
simon 0:350011bf8be7 143 OR_INTR_ENABLE_RHSC;
simon 0:350011bf8be7 144
simon 0:350011bf8be7 145 NVIC_SetPriority(USB_IRQn, 0); /* highest priority */
simon 0:350011bf8be7 146 /* Enable the USB Interrupt */
simon 0:350011bf8be7 147 NVIC_SetVector(USB_IRQn, (uint32_t)(sUsbIrqhandler));
simon 0:350011bf8be7 148 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
simon 0:350011bf8be7 149 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
simon 0:350011bf8be7 150
simon 0:350011bf8be7 151 /* Check for any connected devices */
simon 0:350011bf8be7 152 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected
simon 0:350011bf8be7 153 {
simon 0:350011bf8be7 154 //Device connected
simon 0:350011bf8be7 155 wait(1);
simon 0:350011bf8be7 156 DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1);
simon 0:350011bf8be7 157 onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1)
simon 0:350011bf8be7 158 }
simon 0:350011bf8be7 159
simon 0:350011bf8be7 160 DBG("Enabling IRQ\n");
simon 0:350011bf8be7 161 NVIC_EnableIRQ(USB_IRQn);
simon 0:350011bf8be7 162 DBG("End of host stack initialization\n");
simon 0:350011bf8be7 163 return USBERR_OK;
simon 0:350011bf8be7 164 }
simon 0:350011bf8be7 165
simon 0:350011bf8be7 166 void UsbHostMgr::poll() //Enumerate connected devices, etc
simon 0:350011bf8be7 167 {
simon 0:350011bf8be7 168 /* Check for any connected devices */
simon 0:350011bf8be7 169 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected
simon 0:350011bf8be7 170 {
simon 0:350011bf8be7 171 //Device connected
simon 0:350011bf8be7 172 wait(1);
simon 0:350011bf8be7 173 DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1);
simon 0:350011bf8be7 174 onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1)
simon 0:350011bf8be7 175 }
simon 0:350011bf8be7 176
simon 0:350011bf8be7 177 for(int i = 0; i < devicesCount(); i++)
simon 0:350011bf8be7 178 {
simon 0:350011bf8be7 179 if( (m_lpDevices[i]->m_connected)
simon 0:350011bf8be7 180 && !(m_lpDevices[i]->m_enumerated) )
simon 0:350011bf8be7 181 {
simon 0:350011bf8be7 182 m_lpDevices[i]->enumerate();
simon 0:350011bf8be7 183 return;
simon 0:350011bf8be7 184 }
simon 0:350011bf8be7 185 }
simon 0:350011bf8be7 186 }
simon 0:350011bf8be7 187
simon 0:350011bf8be7 188 int UsbHostMgr::devicesCount()
simon 0:350011bf8be7 189 {
simon 0:350011bf8be7 190 int i;
simon 0:350011bf8be7 191 for(i = 0; i < USB_HOSTMGR_MAX_DEVS; i++)
simon 0:350011bf8be7 192 {
simon 0:350011bf8be7 193 if (m_lpDevices[i] == NULL)
simon 0:350011bf8be7 194 break;
simon 0:350011bf8be7 195 }
simon 0:350011bf8be7 196 return i;
simon 0:350011bf8be7 197 }
simon 0:350011bf8be7 198
simon 0:350011bf8be7 199 UsbDevice* UsbHostMgr::getDevice(int item)
simon 0:350011bf8be7 200 {
simon 0:350011bf8be7 201 UsbDevice* pDev = m_lpDevices[item];
simon 0:350011bf8be7 202 if(!pDev)
simon 0:350011bf8be7 203 return NULL;
simon 0:350011bf8be7 204
simon 0:350011bf8be7 205 pDev->m_refs++;
simon 0:350011bf8be7 206 return pDev;
simon 0:350011bf8be7 207 }
simon 0:350011bf8be7 208
simon 0:350011bf8be7 209 void UsbHostMgr::releaseDevice(UsbDevice* pDev)
simon 0:350011bf8be7 210 {
simon 0:350011bf8be7 211 pDev->m_refs--;
simon 0:350011bf8be7 212 if(pDev->m_refs > 0)
simon 0:350011bf8be7 213 return;
simon 0:350011bf8be7 214 //If refs count = 0, delete
simon 0:350011bf8be7 215 //Find & remove from list
simon 0:350011bf8be7 216 int i;
simon 0:350011bf8be7 217 for(i = 0; i < USB_HOSTMGR_MAX_DEVS; i++)
simon 0:350011bf8be7 218 {
simon 0:350011bf8be7 219 if (m_lpDevices[i] == pDev)
simon 0:350011bf8be7 220 break;
simon 0:350011bf8be7 221 }
simon 0:350011bf8be7 222 if(i!=USB_HOSTMGR_MAX_DEVS)
simon 0:350011bf8be7 223 memmove(&m_lpDevices[i], &m_lpDevices[i+1], sizeof(UsbDevice*) * (USB_HOSTMGR_MAX_DEVS - (i + 1))); //Safer than memcpy because of overlapping mem
simon 0:350011bf8be7 224 m_lpDevices[USB_HOSTMGR_MAX_DEVS - 1] = NULL;
simon 0:350011bf8be7 225 delete pDev;
simon 0:350011bf8be7 226 }
simon 0:350011bf8be7 227
simon 0:350011bf8be7 228 void UsbHostMgr::UsbIrqhandler()
simon 0:350011bf8be7 229 {
simon 0:350011bf8be7 230 uint32_t int_status;
simon 0:350011bf8be7 231 uint32_t ie_status;
simon 0:350011bf8be7 232
simon 0:350011bf8be7 233 int_status = LPC_USB->HcInterruptStatus; /* Read Interrupt Status */
simon 0:350011bf8be7 234 ie_status = LPC_USB->HcInterruptEnable; /* Read Interrupt enable status */
simon 0:350011bf8be7 235
simon 0:350011bf8be7 236 if (!(int_status & ie_status))
simon 0:350011bf8be7 237 {
simon 0:350011bf8be7 238 return;
simon 0:350011bf8be7 239 }
simon 0:350011bf8be7 240 else
simon 0:350011bf8be7 241 {
simon 0:350011bf8be7 242 int_status = int_status & ie_status;
simon 0:350011bf8be7 243 if (int_status & OR_INTR_STATUS_RHSC) /* Root hub status change interrupt */
simon 0:350011bf8be7 244 {
simon 0:350011bf8be7 245 DBG("LPC_USB->HcRhPortStatus1 = %08x\n", LPC_USB->HcRhPortStatus1);
simon 0:350011bf8be7 246 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC)
simon 0:350011bf8be7 247 {
simon 0:350011bf8be7 248 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE)
simon 0:350011bf8be7 249 {
simon 0:350011bf8be7 250 /*
simon 0:350011bf8be7 251 * When DRWE is on, Connect Status Change
simon 0:350011bf8be7 252 * means a remote wakeup event.
simon 0:350011bf8be7 253 */
simon 0:350011bf8be7 254 //HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT
simon 0:350011bf8be7 255 }
simon 0:350011bf8be7 256 else
simon 0:350011bf8be7 257 {
simon 0:350011bf8be7 258 /*
simon 0:350011bf8be7 259 * When DRWE is off, Connect Status Change
simon 0:350011bf8be7 260 * is NOT a remote wakeup event
simon 0:350011bf8be7 261 */
simon 0:350011bf8be7 262 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) //Root device connected
simon 0:350011bf8be7 263 {
simon 0:350011bf8be7 264 //Device connected
simon 0:350011bf8be7 265 DBG("Device connected (%08x)\n", LPC_USB->HcRhPortStatus1);
simon 0:350011bf8be7 266 onUsbDeviceConnected(0, 1); //Hub 0 (root hub), Port 1 (count starts at 1)
simon 0:350011bf8be7 267 }
simon 0:350011bf8be7 268 else //Root device disconnected
simon 0:350011bf8be7 269 {
simon 0:350011bf8be7 270 //Device disconnected
simon 0:350011bf8be7 271 DBG("Device disconnected\n");
simon 0:350011bf8be7 272 onUsbDeviceDisconnected(0, 1);
simon 0:350011bf8be7 273 }
simon 0:350011bf8be7 274 //TODO: HUBS
simon 0:350011bf8be7 275 }
simon 0:350011bf8be7 276 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
simon 0:350011bf8be7 277 }
simon 0:350011bf8be7 278 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC)
simon 0:350011bf8be7 279 {
simon 0:350011bf8be7 280 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
simon 0:350011bf8be7 281 }
simon 0:350011bf8be7 282 }
simon 0:350011bf8be7 283 if (int_status & OR_INTR_STATUS_WDH) /* Writeback Done Head interrupt */
simon 0:350011bf8be7 284 {
simon 0:350011bf8be7 285 //UsbEndpoint::sOnCompletion((LPC_USB->HccaDoneHead) & 0xFE);
simon 0:350011bf8be7 286 if(m_pHcca->DoneHead)
simon 0:350011bf8be7 287 {
simon 0:350011bf8be7 288 UsbEndpoint::sOnCompletion(m_pHcca->DoneHead);
simon 0:350011bf8be7 289 m_pHcca->DoneHead = 0;
simon 0:350011bf8be7 290 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
simon 0:350011bf8be7 291 if(m_pHcca->DoneHead)
simon 0:350011bf8be7 292 DBG("??????????????????????????????\n\n\n");
simon 0:350011bf8be7 293 }
simon 0:350011bf8be7 294 else
simon 0:350011bf8be7 295 {
simon 0:350011bf8be7 296 //Probably an error
simon 0:350011bf8be7 297 int_status = LPC_USB->HcInterruptStatus;
simon 0:350011bf8be7 298 DBG("HcInterruptStatus = %08x\n", int_status);
simon 0:350011bf8be7 299 if (int_status & OR_INTR_STATUS_UE) //Unrecoverable error, disconnect devices and resume
simon 0:350011bf8be7 300 {
simon 0:350011bf8be7 301 onUsbDeviceDisconnected(0, 1);
simon 0:350011bf8be7 302 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_UE;
simon 0:350011bf8be7 303 LPC_USB->HcCommandStatus = 0x01; //Host Controller Reset
simon 0:350011bf8be7 304 }
simon 0:350011bf8be7 305 }
simon 0:350011bf8be7 306 }
simon 0:350011bf8be7 307 LPC_USB->HcInterruptStatus = int_status; /* Clear interrupt status register */
simon 0:350011bf8be7 308 }
simon 0:350011bf8be7 309 return;
simon 0:350011bf8be7 310 }
simon 0:350011bf8be7 311
simon 0:350011bf8be7 312 void UsbHostMgr::onUsbDeviceConnected(int hub, int port)
simon 0:350011bf8be7 313 {
simon 0:350011bf8be7 314 int item = devicesCount();
simon 0:350011bf8be7 315 if( item == USB_HOSTMGR_MAX_DEVS )
simon 0:350011bf8be7 316 return; //List full...
simon 0:350011bf8be7 317 //Find a free address (not optimized, but not really important)
simon 0:350011bf8be7 318 int i;
simon 0:350011bf8be7 319 int addr = 1;
simon 0:350011bf8be7 320 for(i = 0; i < item; i++)
simon 0:350011bf8be7 321 {
simon 0:350011bf8be7 322 addr = MAX( addr, m_lpDevices[i]->m_addr + 1 );
simon 0:350011bf8be7 323 }
simon 0:350011bf8be7 324 m_lpDevices[item] = new UsbDevice( this, hub, port, addr );
simon 0:350011bf8be7 325 m_lpDevices[item]->m_connected = true;
simon 0:350011bf8be7 326 }
simon 0:350011bf8be7 327
simon 0:350011bf8be7 328 void UsbHostMgr::onUsbDeviceDisconnected(int hub, int port)
simon 0:350011bf8be7 329 {
simon 0:350011bf8be7 330 for(int i = 0; i < devicesCount(); i++)
simon 0:350011bf8be7 331 {
simon 0:350011bf8be7 332 if( (m_lpDevices[i]->m_hub == hub)
simon 0:350011bf8be7 333 && (m_lpDevices[i]->m_port == port) )
simon 0:350011bf8be7 334 {
simon 0:350011bf8be7 335 m_lpDevices[i]->m_connected = false;
simon 0:350011bf8be7 336 if(!m_lpDevices[i]->m_enumerated)
simon 0:350011bf8be7 337 {
simon 0:350011bf8be7 338 delete m_lpDevices[i];
simon 0:350011bf8be7 339 m_lpDevices[i] = NULL;
simon 0:350011bf8be7 340 }
simon 0:350011bf8be7 341 return;
simon 0:350011bf8be7 342 }
simon 0:350011bf8be7 343 }
simon 0:350011bf8be7 344 }
simon 0:350011bf8be7 345
simon 0:350011bf8be7 346 void UsbHostMgr::resetPort(int hub, int port)
simon 0:350011bf8be7 347 {
simon 0:350011bf8be7 348 DBG("Resetting hub %d, port %d\n", hub, port);
simon 0:350011bf8be7 349 if(hub == 0) //Root hub
simon 0:350011bf8be7 350 {
simon 0:350011bf8be7 351 wait_ms(100); /* USB 2.0 spec says at least 50ms delay before port reset */
simon 0:350011bf8be7 352 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
simon 0:350011bf8be7 353 DBG("Before loop\n");
simon 0:350011bf8be7 354 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
simon 0:350011bf8be7 355 ;
simon 0:350011bf8be7 356 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
simon 0:350011bf8be7 357 DBG("After loop\n");
simon 0:350011bf8be7 358 wait_ms(200); /* Wait for 100 MS after port reset */
simon 0:350011bf8be7 359 }
simon 0:350011bf8be7 360 else
simon 0:350011bf8be7 361 {
simon 0:350011bf8be7 362 //TODO: Hubs
simon 0:350011bf8be7 363 }
simon 0:350011bf8be7 364 DBG("Port reset OK\n");
simon 0:350011bf8be7 365 }
simon 0:350011bf8be7 366
simon 0:350011bf8be7 367 #endif