Michael Spencer / Mbed 2 deprecated LaOS

Dependencies:   mbed

Committer:
Michael J. Spencer
Date:
Wed Mar 05 06:14:02 2014 -0800
Revision:
1:f5ac63519541
Initial commit.

Who changed what in which revision?

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