USBHost library with fixes

Dependencies:   mbed-rtos FATFileSystem

Dependents:   mbedica

Committer:
zrussell3
Date:
Thu Dec 13 19:24:21 2018 +0000
Revision:
0:b176d95bb38f
Modified USBHost library to fix modifier input

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zrussell3 0:b176d95bb38f 1 /* mbed USBHost Library
zrussell3 0:b176d95bb38f 2 * Copyright (c) 2006-2013 ARM Limited
zrussell3 0:b176d95bb38f 3 *
zrussell3 0:b176d95bb38f 4 * Licensed under the Apache License, Version 2.0 (the "License");
zrussell3 0:b176d95bb38f 5 * you may not use this file except in compliance with the License.
zrussell3 0:b176d95bb38f 6 * You may obtain a copy of the License at
zrussell3 0:b176d95bb38f 7 *
zrussell3 0:b176d95bb38f 8 * http://www.apache.org/licenses/LICENSE-2.0
zrussell3 0:b176d95bb38f 9 *
zrussell3 0:b176d95bb38f 10 * Unless required by applicable law or agreed to in writing, software
zrussell3 0:b176d95bb38f 11 * distributed under the License is distributed on an "AS IS" BASIS,
zrussell3 0:b176d95bb38f 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
zrussell3 0:b176d95bb38f 13 * See the License for the specific language governing permissions and
zrussell3 0:b176d95bb38f 14 * limitations under the License.
zrussell3 0:b176d95bb38f 15 */
zrussell3 0:b176d95bb38f 16
zrussell3 0:b176d95bb38f 17 #include "mbed.h"
zrussell3 0:b176d95bb38f 18 #include "USBHALHost.h"
zrussell3 0:b176d95bb38f 19 #include "dbg.h"
zrussell3 0:b176d95bb38f 20
zrussell3 0:b176d95bb38f 21 // bits of the USB/OTG clock control register
zrussell3 0:b176d95bb38f 22 #define HOST_CLK_EN (1<<0)
zrussell3 0:b176d95bb38f 23 #define DEV_CLK_EN (1<<1)
zrussell3 0:b176d95bb38f 24 #define PORTSEL_CLK_EN (1<<3)
zrussell3 0:b176d95bb38f 25 #define AHB_CLK_EN (1<<4)
zrussell3 0:b176d95bb38f 26
zrussell3 0:b176d95bb38f 27 // bits of the USB/OTG clock status register
zrussell3 0:b176d95bb38f 28 #define HOST_CLK_ON (1<<0)
zrussell3 0:b176d95bb38f 29 #define DEV_CLK_ON (1<<1)
zrussell3 0:b176d95bb38f 30 #define PORTSEL_CLK_ON (1<<3)
zrussell3 0:b176d95bb38f 31 #define AHB_CLK_ON (1<<4)
zrussell3 0:b176d95bb38f 32
zrussell3 0:b176d95bb38f 33 // we need host clock, OTG/portsel clock and AHB clock
zrussell3 0:b176d95bb38f 34 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
zrussell3 0:b176d95bb38f 35
zrussell3 0:b176d95bb38f 36 #define HCCA_SIZE sizeof(HCCA)
zrussell3 0:b176d95bb38f 37 #define ED_SIZE sizeof(HCED)
zrussell3 0:b176d95bb38f 38 #define TD_SIZE sizeof(HCTD)
zrussell3 0:b176d95bb38f 39
zrussell3 0:b176d95bb38f 40 #define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
zrussell3 0:b176d95bb38f 41
zrussell3 0:b176d95bb38f 42 static volatile uint8_t usb_buf[TOTAL_SIZE] __attribute((section("AHBSRAM1"),aligned(256))); //256 bytes aligned!
zrussell3 0:b176d95bb38f 43
zrussell3 0:b176d95bb38f 44 USBHALHost * USBHALHost::instHost;
zrussell3 0:b176d95bb38f 45
zrussell3 0:b176d95bb38f 46 USBHALHost::USBHALHost() {
zrussell3 0:b176d95bb38f 47 instHost = this;
zrussell3 0:b176d95bb38f 48 memInit();
zrussell3 0:b176d95bb38f 49 memset((void*)usb_hcca, 0, HCCA_SIZE);
zrussell3 0:b176d95bb38f 50 for (int i = 0; i < MAX_ENDPOINT; i++) {
zrussell3 0:b176d95bb38f 51 edBufAlloc[i] = false;
zrussell3 0:b176d95bb38f 52 }
zrussell3 0:b176d95bb38f 53 for (int i = 0; i < MAX_TD; i++) {
zrussell3 0:b176d95bb38f 54 tdBufAlloc[i] = false;
zrussell3 0:b176d95bb38f 55 }
zrussell3 0:b176d95bb38f 56 }
zrussell3 0:b176d95bb38f 57
zrussell3 0:b176d95bb38f 58 void USBHALHost::init() {
zrussell3 0:b176d95bb38f 59 NVIC_DisableIRQ(USB_IRQn);
zrussell3 0:b176d95bb38f 60
zrussell3 0:b176d95bb38f 61 //Cut power
zrussell3 0:b176d95bb38f 62 LPC_SC->PCONP &= ~(1UL<<31);
zrussell3 0:b176d95bb38f 63 wait_ms(100);
zrussell3 0:b176d95bb38f 64
zrussell3 0:b176d95bb38f 65 // turn on power for USB
zrussell3 0:b176d95bb38f 66 LPC_SC->PCONP |= (1UL<<31);
zrussell3 0:b176d95bb38f 67
zrussell3 0:b176d95bb38f 68 // Enable USB host clock, port selection and AHB clock
zrussell3 0:b176d95bb38f 69 LPC_USB->USBClkCtrl |= CLOCK_MASK;
zrussell3 0:b176d95bb38f 70
zrussell3 0:b176d95bb38f 71 // Wait for clocks to become available
zrussell3 0:b176d95bb38f 72 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK);
zrussell3 0:b176d95bb38f 73
zrussell3 0:b176d95bb38f 74 // it seems the bits[0:1] mean the following
zrussell3 0:b176d95bb38f 75 // 0: U1=device, U2=host
zrussell3 0:b176d95bb38f 76 // 1: U1=host, U2=host
zrussell3 0:b176d95bb38f 77 // 2: reserved
zrussell3 0:b176d95bb38f 78 // 3: U1=host, U2=device
zrussell3 0:b176d95bb38f 79 // NB: this register is only available if OTG clock (aka "port select") is enabled!!
zrussell3 0:b176d95bb38f 80 // since we don't care about port 2, set just bit 0 to 1 (U1=host)
zrussell3 0:b176d95bb38f 81 LPC_USB->OTGStCtrl |= 1;
zrussell3 0:b176d95bb38f 82
zrussell3 0:b176d95bb38f 83 // now that we've configured the ports, we can turn off the portsel clock
zrussell3 0:b176d95bb38f 84 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
zrussell3 0:b176d95bb38f 85
zrussell3 0:b176d95bb38f 86 // configure USB D+/D- pins
zrussell3 0:b176d95bb38f 87 // P0[29] = USB_D+, 01
zrussell3 0:b176d95bb38f 88 // P0[30] = USB_D-, 01
zrussell3 0:b176d95bb38f 89 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
zrussell3 0:b176d95bb38f 90 LPC_PINCON->PINSEL1 |= ((1<<26) | (1<<28));
zrussell3 0:b176d95bb38f 91
zrussell3 0:b176d95bb38f 92 LPC_USB->HcControl = 0; // HARDWARE RESET
zrussell3 0:b176d95bb38f 93 LPC_USB->HcControlHeadED = 0; // Initialize Control list head to Zero
zrussell3 0:b176d95bb38f 94 LPC_USB->HcBulkHeadED = 0; // Initialize Bulk list head to Zero
zrussell3 0:b176d95bb38f 95
zrussell3 0:b176d95bb38f 96 // Wait 100 ms before apply reset
zrussell3 0:b176d95bb38f 97 wait_ms(100);
zrussell3 0:b176d95bb38f 98
zrussell3 0:b176d95bb38f 99 // software reset
zrussell3 0:b176d95bb38f 100 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
zrussell3 0:b176d95bb38f 101
zrussell3 0:b176d95bb38f 102 // Write Fm Interval and Largest Data Packet Counter
zrussell3 0:b176d95bb38f 103 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL;
zrussell3 0:b176d95bb38f 104 LPC_USB->HcPeriodicStart = FI * 90 / 100;
zrussell3 0:b176d95bb38f 105
zrussell3 0:b176d95bb38f 106 // Put HC in operational state
zrussell3 0:b176d95bb38f 107 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
zrussell3 0:b176d95bb38f 108 // Set Global Power
zrussell3 0:b176d95bb38f 109 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC;
zrussell3 0:b176d95bb38f 110
zrussell3 0:b176d95bb38f 111 LPC_USB->HcHCCA = (uint32_t)(usb_hcca);
zrussell3 0:b176d95bb38f 112
zrussell3 0:b176d95bb38f 113 // Clear Interrrupt Status
zrussell3 0:b176d95bb38f 114 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;
zrussell3 0:b176d95bb38f 115
zrussell3 0:b176d95bb38f 116 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC;
zrussell3 0:b176d95bb38f 117
zrussell3 0:b176d95bb38f 118 // Enable the USB Interrupt
zrussell3 0:b176d95bb38f 119 NVIC_SetVector(USB_IRQn, (uint32_t)(_usbisr));
zrussell3 0:b176d95bb38f 120 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
zrussell3 0:b176d95bb38f 121 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
zrussell3 0:b176d95bb38f 122
zrussell3 0:b176d95bb38f 123 NVIC_EnableIRQ(USB_IRQn);
zrussell3 0:b176d95bb38f 124
zrussell3 0:b176d95bb38f 125 // Check for any connected devices
zrussell3 0:b176d95bb38f 126 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
zrussell3 0:b176d95bb38f 127 //Device connected
zrussell3 0:b176d95bb38f 128 wait_ms(150);
zrussell3 0:b176d95bb38f 129 USB_DBG("Device connected (%08x)\n\r", LPC_USB->HcRhPortStatus1);
zrussell3 0:b176d95bb38f 130 deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
zrussell3 0:b176d95bb38f 131 }
zrussell3 0:b176d95bb38f 132 }
zrussell3 0:b176d95bb38f 133
zrussell3 0:b176d95bb38f 134 uint32_t USBHALHost::controlHeadED() {
zrussell3 0:b176d95bb38f 135 return LPC_USB->HcControlHeadED;
zrussell3 0:b176d95bb38f 136 }
zrussell3 0:b176d95bb38f 137
zrussell3 0:b176d95bb38f 138 uint32_t USBHALHost::bulkHeadED() {
zrussell3 0:b176d95bb38f 139 return LPC_USB->HcBulkHeadED;
zrussell3 0:b176d95bb38f 140 }
zrussell3 0:b176d95bb38f 141
zrussell3 0:b176d95bb38f 142 uint32_t USBHALHost::interruptHeadED() {
zrussell3 0:b176d95bb38f 143 return usb_hcca->IntTable[0];
zrussell3 0:b176d95bb38f 144 }
zrussell3 0:b176d95bb38f 145
zrussell3 0:b176d95bb38f 146 void USBHALHost::updateBulkHeadED(uint32_t addr) {
zrussell3 0:b176d95bb38f 147 LPC_USB->HcBulkHeadED = addr;
zrussell3 0:b176d95bb38f 148 }
zrussell3 0:b176d95bb38f 149
zrussell3 0:b176d95bb38f 150
zrussell3 0:b176d95bb38f 151 void USBHALHost::updateControlHeadED(uint32_t addr) {
zrussell3 0:b176d95bb38f 152 LPC_USB->HcControlHeadED = addr;
zrussell3 0:b176d95bb38f 153 }
zrussell3 0:b176d95bb38f 154
zrussell3 0:b176d95bb38f 155 void USBHALHost::updateInterruptHeadED(uint32_t addr) {
zrussell3 0:b176d95bb38f 156 usb_hcca->IntTable[0] = addr;
zrussell3 0:b176d95bb38f 157 }
zrussell3 0:b176d95bb38f 158
zrussell3 0:b176d95bb38f 159
zrussell3 0:b176d95bb38f 160 void USBHALHost::enableList(ENDPOINT_TYPE type) {
zrussell3 0:b176d95bb38f 161 switch(type) {
zrussell3 0:b176d95bb38f 162 case CONTROL_ENDPOINT:
zrussell3 0:b176d95bb38f 163 LPC_USB->HcCommandStatus = OR_CMD_STATUS_CLF;
zrussell3 0:b176d95bb38f 164 LPC_USB->HcControl |= OR_CONTROL_CLE;
zrussell3 0:b176d95bb38f 165 break;
zrussell3 0:b176d95bb38f 166 case ISOCHRONOUS_ENDPOINT:
zrussell3 0:b176d95bb38f 167 break;
zrussell3 0:b176d95bb38f 168 case BULK_ENDPOINT:
zrussell3 0:b176d95bb38f 169 LPC_USB->HcCommandStatus = OR_CMD_STATUS_BLF;
zrussell3 0:b176d95bb38f 170 LPC_USB->HcControl |= OR_CONTROL_BLE;
zrussell3 0:b176d95bb38f 171 break;
zrussell3 0:b176d95bb38f 172 case INTERRUPT_ENDPOINT:
zrussell3 0:b176d95bb38f 173 LPC_USB->HcControl |= OR_CONTROL_PLE;
zrussell3 0:b176d95bb38f 174 break;
zrussell3 0:b176d95bb38f 175 }
zrussell3 0:b176d95bb38f 176 }
zrussell3 0:b176d95bb38f 177
zrussell3 0:b176d95bb38f 178
zrussell3 0:b176d95bb38f 179 bool USBHALHost::disableList(ENDPOINT_TYPE type) {
zrussell3 0:b176d95bb38f 180 switch(type) {
zrussell3 0:b176d95bb38f 181 case CONTROL_ENDPOINT:
zrussell3 0:b176d95bb38f 182 if(LPC_USB->HcControl & OR_CONTROL_CLE) {
zrussell3 0:b176d95bb38f 183 LPC_USB->HcControl &= ~OR_CONTROL_CLE;
zrussell3 0:b176d95bb38f 184 return true;
zrussell3 0:b176d95bb38f 185 }
zrussell3 0:b176d95bb38f 186 return false;
zrussell3 0:b176d95bb38f 187 case ISOCHRONOUS_ENDPOINT:
zrussell3 0:b176d95bb38f 188 return false;
zrussell3 0:b176d95bb38f 189 case BULK_ENDPOINT:
zrussell3 0:b176d95bb38f 190 if(LPC_USB->HcControl & OR_CONTROL_BLE){
zrussell3 0:b176d95bb38f 191 LPC_USB->HcControl &= ~OR_CONTROL_BLE;
zrussell3 0:b176d95bb38f 192 return true;
zrussell3 0:b176d95bb38f 193 }
zrussell3 0:b176d95bb38f 194 return false;
zrussell3 0:b176d95bb38f 195 case INTERRUPT_ENDPOINT:
zrussell3 0:b176d95bb38f 196 if(LPC_USB->HcControl & OR_CONTROL_PLE) {
zrussell3 0:b176d95bb38f 197 LPC_USB->HcControl &= ~OR_CONTROL_PLE;
zrussell3 0:b176d95bb38f 198 return true;
zrussell3 0:b176d95bb38f 199 }
zrussell3 0:b176d95bb38f 200 return false;
zrussell3 0:b176d95bb38f 201 }
zrussell3 0:b176d95bb38f 202 return false;
zrussell3 0:b176d95bb38f 203 }
zrussell3 0:b176d95bb38f 204
zrussell3 0:b176d95bb38f 205
zrussell3 0:b176d95bb38f 206 void USBHALHost::memInit() {
zrussell3 0:b176d95bb38f 207 usb_hcca = (volatile HCCA *)usb_buf;
zrussell3 0:b176d95bb38f 208 usb_edBuf = usb_buf + HCCA_SIZE;
zrussell3 0:b176d95bb38f 209 usb_tdBuf = usb_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE);
zrussell3 0:b176d95bb38f 210 }
zrussell3 0:b176d95bb38f 211
zrussell3 0:b176d95bb38f 212 volatile uint8_t * USBHALHost::getED() {
zrussell3 0:b176d95bb38f 213 for (int i = 0; i < MAX_ENDPOINT; i++) {
zrussell3 0:b176d95bb38f 214 if ( !edBufAlloc[i] ) {
zrussell3 0:b176d95bb38f 215 edBufAlloc[i] = true;
zrussell3 0:b176d95bb38f 216 return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
zrussell3 0:b176d95bb38f 217 }
zrussell3 0:b176d95bb38f 218 }
zrussell3 0:b176d95bb38f 219 perror("Could not allocate ED\r\n");
zrussell3 0:b176d95bb38f 220 return NULL; //Could not alloc ED
zrussell3 0:b176d95bb38f 221 }
zrussell3 0:b176d95bb38f 222
zrussell3 0:b176d95bb38f 223 volatile uint8_t * USBHALHost::getTD() {
zrussell3 0:b176d95bb38f 224 int i;
zrussell3 0:b176d95bb38f 225 for (i = 0; i < MAX_TD; i++) {
zrussell3 0:b176d95bb38f 226 if ( !tdBufAlloc[i] ) {
zrussell3 0:b176d95bb38f 227 tdBufAlloc[i] = true;
zrussell3 0:b176d95bb38f 228 return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
zrussell3 0:b176d95bb38f 229 }
zrussell3 0:b176d95bb38f 230 }
zrussell3 0:b176d95bb38f 231 perror("Could not allocate TD\r\n");
zrussell3 0:b176d95bb38f 232 return NULL; //Could not alloc TD
zrussell3 0:b176d95bb38f 233 }
zrussell3 0:b176d95bb38f 234
zrussell3 0:b176d95bb38f 235
zrussell3 0:b176d95bb38f 236 void USBHALHost::freeED(volatile uint8_t * ed) {
zrussell3 0:b176d95bb38f 237 int i;
zrussell3 0:b176d95bb38f 238 i = (ed - usb_edBuf) / ED_SIZE;
zrussell3 0:b176d95bb38f 239 edBufAlloc[i] = false;
zrussell3 0:b176d95bb38f 240 }
zrussell3 0:b176d95bb38f 241
zrussell3 0:b176d95bb38f 242 void USBHALHost::freeTD(volatile uint8_t * td) {
zrussell3 0:b176d95bb38f 243 int i;
zrussell3 0:b176d95bb38f 244 i = (td - usb_tdBuf) / TD_SIZE;
zrussell3 0:b176d95bb38f 245 tdBufAlloc[i] = false;
zrussell3 0:b176d95bb38f 246 }
zrussell3 0:b176d95bb38f 247
zrussell3 0:b176d95bb38f 248
zrussell3 0:b176d95bb38f 249 void USBHALHost::resetRootHub() {
zrussell3 0:b176d95bb38f 250 // Initiate port reset
zrussell3 0:b176d95bb38f 251 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS;
zrussell3 0:b176d95bb38f 252
zrussell3 0:b176d95bb38f 253 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS);
zrussell3 0:b176d95bb38f 254
zrussell3 0:b176d95bb38f 255 // ...and clear port reset signal
zrussell3 0:b176d95bb38f 256 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
zrussell3 0:b176d95bb38f 257 }
zrussell3 0:b176d95bb38f 258
zrussell3 0:b176d95bb38f 259
zrussell3 0:b176d95bb38f 260 void USBHALHost::_usbisr(void) {
zrussell3 0:b176d95bb38f 261 if (instHost) {
zrussell3 0:b176d95bb38f 262 instHost->UsbIrqhandler();
zrussell3 0:b176d95bb38f 263 }
zrussell3 0:b176d95bb38f 264 }
zrussell3 0:b176d95bb38f 265
zrussell3 0:b176d95bb38f 266 void USBHALHost::UsbIrqhandler() {
zrussell3 0:b176d95bb38f 267 if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process?
zrussell3 0:b176d95bb38f 268 {
zrussell3 0:b176d95bb38f 269
zrussell3 0:b176d95bb38f 270 uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable;
zrussell3 0:b176d95bb38f 271
zrussell3 0:b176d95bb38f 272 // Root hub status change interrupt
zrussell3 0:b176d95bb38f 273 if (int_status & OR_INTR_STATUS_RHSC) {
zrussell3 0:b176d95bb38f 274 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
zrussell3 0:b176d95bb38f 275 if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
zrussell3 0:b176d95bb38f 276 // When DRWE is on, Connect Status Change
zrussell3 0:b176d95bb38f 277 // means a remote wakeup event.
zrussell3 0:b176d95bb38f 278 } else {
zrussell3 0:b176d95bb38f 279
zrussell3 0:b176d95bb38f 280 //Root device connected
zrussell3 0:b176d95bb38f 281 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
zrussell3 0:b176d95bb38f 282
zrussell3 0:b176d95bb38f 283 // wait 150ms to avoid bounce
zrussell3 0:b176d95bb38f 284 wait_ms(150);
zrussell3 0:b176d95bb38f 285
zrussell3 0:b176d95bb38f 286 //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
zrussell3 0:b176d95bb38f 287 deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
zrussell3 0:b176d95bb38f 288 }
zrussell3 0:b176d95bb38f 289
zrussell3 0:b176d95bb38f 290 //Root device disconnected
zrussell3 0:b176d95bb38f 291 else {
zrussell3 0:b176d95bb38f 292
zrussell3 0:b176d95bb38f 293 if (!(int_status & OR_INTR_STATUS_WDH)) {
zrussell3 0:b176d95bb38f 294 usb_hcca->DoneHead = 0;
zrussell3 0:b176d95bb38f 295 }
zrussell3 0:b176d95bb38f 296
zrussell3 0:b176d95bb38f 297 // wait 200ms to avoid bounce
zrussell3 0:b176d95bb38f 298 wait_ms(200);
zrussell3 0:b176d95bb38f 299
zrussell3 0:b176d95bb38f 300 deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
zrussell3 0:b176d95bb38f 301
zrussell3 0:b176d95bb38f 302 if (int_status & OR_INTR_STATUS_WDH) {
zrussell3 0:b176d95bb38f 303 usb_hcca->DoneHead = 0;
zrussell3 0:b176d95bb38f 304 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
zrussell3 0:b176d95bb38f 305 }
zrussell3 0:b176d95bb38f 306 }
zrussell3 0:b176d95bb38f 307 }
zrussell3 0:b176d95bb38f 308 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
zrussell3 0:b176d95bb38f 309 }
zrussell3 0:b176d95bb38f 310 if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
zrussell3 0:b176d95bb38f 311 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
zrussell3 0:b176d95bb38f 312 }
zrussell3 0:b176d95bb38f 313 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_RHSC;
zrussell3 0:b176d95bb38f 314 }
zrussell3 0:b176d95bb38f 315
zrussell3 0:b176d95bb38f 316 // Writeback Done Head interrupt
zrussell3 0:b176d95bb38f 317 if (int_status & OR_INTR_STATUS_WDH) {
zrussell3 0:b176d95bb38f 318 transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE);
zrussell3 0:b176d95bb38f 319 LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
zrussell3 0:b176d95bb38f 320 }
zrussell3 0:b176d95bb38f 321 }
zrussell3 0:b176d95bb38f 322 }