SkyTEM BMAG / Mbed 2 deprecated BMAGThrRev

Dependencies:   mbed WDT MODSERIAL BME280

Committer:
gert_lauritsen
Date:
Thu Jun 20 07:13:18 2019 +0000
Revision:
56:df9052e3808c
change date stamp from gps, reads serialnumb from file.

Who changed what in which revision?

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