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