BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS

Dependencies:   FatFileSystem mbed

Fork of BTstack by Norimasa Okamoto

Committer:
todotani
Date:
Wed Feb 20 14:18:38 2013 +0000
Revision:
6:cf06ba884429
Parent:
0:1ed23ab1345f
Change tick timer to 1ms. Change attribute 0xFFF1 as read of DigitalIn p5

Who changed what in which revision?

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