USBHost library. NOTE: This library is only officially supported on the LPC1768 platform. For more information, please see the handbook page.

Dependencies:   FATFileSystem mbed-rtos

Dependents:   BTstack WallbotWii SD to Flash Data Transfer USBHost-MSD_HelloWorld ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Pull requests against this repository are no longer supported. Please raise against mbed OS 5 as documented above.

Committer:
Kojto
Date:
Thu Jul 20 10:13:56 2017 +0100
Revision:
37:f1e388e7b752
Update libraries (ed9d1da)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto 37:f1e388e7b752 1 /* mbed Microcontroller Library
Kojto 37:f1e388e7b752 2 * Copyright (c) 2015-2016 Nuvoton
Kojto 37:f1e388e7b752 3 *
Kojto 37:f1e388e7b752 4 * Licensed under the Apache License, Version 2.0 (the "License");
Kojto 37:f1e388e7b752 5 * you may not use this file except in compliance with the License.
Kojto 37:f1e388e7b752 6 * You may obtain a copy of the License at
Kojto 37:f1e388e7b752 7 *
Kojto 37:f1e388e7b752 8 * http://www.apache.org/licenses/LICENSE-2.0
Kojto 37:f1e388e7b752 9 *
Kojto 37:f1e388e7b752 10 * Unless required by applicable law or agreed to in writing, software
Kojto 37:f1e388e7b752 11 * distributed under the License is distributed on an "AS IS" BASIS,
Kojto 37:f1e388e7b752 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Kojto 37:f1e388e7b752 13 * See the License for the specific language governing permissions and
Kojto 37:f1e388e7b752 14 * limitations under the License.
Kojto 37:f1e388e7b752 15 */
Kojto 37:f1e388e7b752 16
Kojto 37:f1e388e7b752 17 #if defined(TARGET_NUC472)
Kojto 37:f1e388e7b752 18
Kojto 37:f1e388e7b752 19 #include "mbed.h"
Kojto 37:f1e388e7b752 20 #include "USBHALHost.h"
Kojto 37:f1e388e7b752 21 #include "dbg.h"
Kojto 37:f1e388e7b752 22 #include "pinmap.h"
Kojto 37:f1e388e7b752 23
Kojto 37:f1e388e7b752 24 #define HCCA_SIZE sizeof(HCCA)
Kojto 37:f1e388e7b752 25 #define ED_SIZE sizeof(HCED)
Kojto 37:f1e388e7b752 26 #define TD_SIZE sizeof(HCTD)
Kojto 37:f1e388e7b752 27
Kojto 37:f1e388e7b752 28 #define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
Kojto 37:f1e388e7b752 29
Kojto 37:f1e388e7b752 30 static volatile MBED_ALIGN(256) uint8_t usb_buf[TOTAL_SIZE]; // 256 bytes aligned!
Kojto 37:f1e388e7b752 31
Kojto 37:f1e388e7b752 32 USBHALHost * USBHALHost::instHost;
Kojto 37:f1e388e7b752 33
Kojto 37:f1e388e7b752 34 USBHALHost::USBHALHost()
Kojto 37:f1e388e7b752 35 {
Kojto 37:f1e388e7b752 36 instHost = this;
Kojto 37:f1e388e7b752 37 memInit();
Kojto 37:f1e388e7b752 38 memset((void*)usb_hcca, 0, HCCA_SIZE);
Kojto 37:f1e388e7b752 39 for (int i = 0; i < MAX_ENDPOINT; i++) {
Kojto 37:f1e388e7b752 40 edBufAlloc[i] = false;
Kojto 37:f1e388e7b752 41 }
Kojto 37:f1e388e7b752 42 for (int i = 0; i < MAX_TD; i++) {
Kojto 37:f1e388e7b752 43 tdBufAlloc[i] = false;
Kojto 37:f1e388e7b752 44 }
Kojto 37:f1e388e7b752 45 }
Kojto 37:f1e388e7b752 46
Kojto 37:f1e388e7b752 47 void USBHALHost::init()
Kojto 37:f1e388e7b752 48 {
Kojto 37:f1e388e7b752 49 // Unlock protected registers
Kojto 37:f1e388e7b752 50 SYS_UnlockReg();
Kojto 37:f1e388e7b752 51
Kojto 37:f1e388e7b752 52 // NOTE: Configure as OTG device first; otherwise, program will trap in wait loop CLK_STATUS_PLL2STB_Msk below.
Kojto 37:f1e388e7b752 53 SYS->USBPHY = SYS_USBPHY_LDO33EN_Msk | SYS_USBPHY_USBROLE_ON_THE_GO;
Kojto 37:f1e388e7b752 54
Kojto 37:f1e388e7b752 55 // NOTE: Enable OTG here; otherwise, program will trap in wait loop CLK_STATUS_PLL2STB_Msk below.
Kojto 37:f1e388e7b752 56 CLK_EnableModuleClock(OTG_MODULE);
Kojto 37:f1e388e7b752 57 OTG->PHYCTL = (OTG->PHYCTL | OTG_PHYCTL_OTGPHYEN_Msk) & ~OTG_PHYCTL_IDDETEN_Msk;
Kojto 37:f1e388e7b752 58 //OTG->CTL |= OTG_CTL_OTGEN_Msk | OTG_CTL_BUSREQ_Msk;
Kojto 37:f1e388e7b752 59
Kojto 37:f1e388e7b752 60 // PB.0: USB0 external VBUS regulator status
Kojto 37:f1e388e7b752 61 // USB_OC
Kojto 37:f1e388e7b752 62 // PB.1: USB0 external VBUS regulator enable
Kojto 37:f1e388e7b752 63 // NCT3520U low active (USB_PWR_EN)
Kojto 37:f1e388e7b752 64 pin_function(PB_0, SYS_GPB_MFPL_PB0MFP_USB0_OTG5V_ST);
Kojto 37:f1e388e7b752 65 pin_function(PB_1, SYS_GPB_MFPL_PB1MFP_USB0_OTG5V_EN);
Kojto 37:f1e388e7b752 66
Kojto 37:f1e388e7b752 67 // PB.2: USB1 differential signal D-
Kojto 37:f1e388e7b752 68 // PB.3: USB1 differential signal D+
Kojto 37:f1e388e7b752 69 //pin_function(PB_2, SYS_GPB_MFPL_PB2MFP_USB1_D_N);
Kojto 37:f1e388e7b752 70 //pin_function(PB_3, SYS_GPB_MFPL_PB3MFP_USB1_D_P);
Kojto 37:f1e388e7b752 71
Kojto 37:f1e388e7b752 72 // Set PB.4 output high to enable USB power
Kojto 37:f1e388e7b752 73 //gpio_t gpio;
Kojto 37:f1e388e7b752 74 //gpio_init_out_ex(&gpio, PB_4, 1);
Kojto 37:f1e388e7b752 75
Kojto 37:f1e388e7b752 76 // NOTE:
Kojto 37:f1e388e7b752 77 // 1. Set USBH clock source to PLL2; otherwise, program will trap in wait loop CLK_STATUS_PLL2STB_Msk below.
Kojto 37:f1e388e7b752 78 // 2. Don't set CLK_PLL2CTL_PLL2CKEN_Msk. USBH will work abnormally with it enabled.
Kojto 37:f1e388e7b752 79 CLK->CLKSEL0 &= ~CLK_CLKSEL0_USBHSEL_Msk;
Kojto 37:f1e388e7b752 80 // Enable PLL2, 480 MHz / 2 / (1+4) => 48 MHz output
Kojto 37:f1e388e7b752 81 CLK->PLL2CTL = /*CLK_PLL2CTL_PLL2CKEN_Msk | */ (4 << CLK_PLL2CTL_PLL2DIV_Pos);
Kojto 37:f1e388e7b752 82 // Wait PLL2 stable ...
Kojto 37:f1e388e7b752 83 while (!(CLK->STATUS & CLK_STATUS_PLL2STB_Msk));
Kojto 37:f1e388e7b752 84
Kojto 37:f1e388e7b752 85 // Select USB Host clock source from PLL2, clock divied by 1
Kojto 37:f1e388e7b752 86 CLK_SetModuleClock(USBH_MODULE, CLK_CLKSEL0_USBHSEL_PLL2, CLK_CLKDIV0_USB(1));
Kojto 37:f1e388e7b752 87
Kojto 37:f1e388e7b752 88 // Enable USB Host clock
Kojto 37:f1e388e7b752 89 CLK_EnableModuleClock(USBH_MODULE);
Kojto 37:f1e388e7b752 90
Kojto 37:f1e388e7b752 91 // Lock protected registers
Kojto 37:f1e388e7b752 92 SYS_LockReg();
Kojto 37:f1e388e7b752 93
Kojto 37:f1e388e7b752 94 // Overcurrent flag is high active
Kojto 37:f1e388e7b752 95 USBH->HcMiscControl &= ~USBH_HcMiscControl_OCAL_Msk;
Kojto 37:f1e388e7b752 96
Kojto 37:f1e388e7b752 97 // Disable HC interrupts
Kojto 37:f1e388e7b752 98 USBH->HcInterruptDisable = OR_INTR_ENABLE_MIE;
Kojto 37:f1e388e7b752 99
Kojto 37:f1e388e7b752 100 // Needed by some controllers
Kojto 37:f1e388e7b752 101 USBH->HcControl = 0;
Kojto 37:f1e388e7b752 102
Kojto 37:f1e388e7b752 103 // Software reset
Kojto 37:f1e388e7b752 104 USBH->HcCommandStatus = OR_CMD_STATUS_HCR;
Kojto 37:f1e388e7b752 105 while (USBH->HcCommandStatus & OR_CMD_STATUS_HCR);
Kojto 37:f1e388e7b752 106
Kojto 37:f1e388e7b752 107 // Put HC in reset state
Kojto 37:f1e388e7b752 108 USBH->HcControl = (USBH->HcControl & ~OR_CONTROL_HCFS) | OR_CONTROL_HC_RSET;
Kojto 37:f1e388e7b752 109 // HCD must wait 10ms for HC reset complete
Kojto 37:f1e388e7b752 110 wait_ms(100);
Kojto 37:f1e388e7b752 111
Kojto 37:f1e388e7b752 112 USBH->HcControlHeadED = 0; // Initialize Control ED list head to 0
Kojto 37:f1e388e7b752 113 USBH->HcBulkHeadED = 0; // Initialize Bulk ED list head to 0
Kojto 37:f1e388e7b752 114 USBH->HcHCCA = (uint32_t) usb_hcca;
Kojto 37:f1e388e7b752 115
Kojto 37:f1e388e7b752 116 USBH->HcFmInterval = DEFAULT_FMINTERVAL; // Frame interval = 12000 - 1
Kojto 37:f1e388e7b752 117 // MPS = 10,104
Kojto 37:f1e388e7b752 118 USBH->HcPeriodicStart = FI * 90 / 100; // 90% of frame interval
Kojto 37:f1e388e7b752 119 USBH->HcLSThreshold = 0x628; // Low speed threshold
Kojto 37:f1e388e7b752 120
Kojto 37:f1e388e7b752 121 // Put HC in operational state
Kojto 37:f1e388e7b752 122 USBH->HcControl = (USBH->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
Kojto 37:f1e388e7b752 123
Kojto 37:f1e388e7b752 124 // FIXME: Ports are power switched. All ports are powered at the same time. Doesn't match BSP sample.
Kojto 37:f1e388e7b752 125 USBH->HcRhDescriptorA = USBH->HcRhDescriptorA & ~USBH_HcRhDescriptorA_NPS_Msk & ~USBH_HcRhDescriptorA_PSM_Msk;
Kojto 37:f1e388e7b752 126 // Issue SetGlobalPower command
Kojto 37:f1e388e7b752 127 USBH->HcRhStatus = USBH_HcRhStatus_LPSC_Msk;
Kojto 37:f1e388e7b752 128 // Power On To Power Good Time, in 2 ms units
Kojto 37:f1e388e7b752 129 wait_ms(((USBH->HcRhDescriptorA & USBH_HcRhDescriptorA_POTPGT_Msk) >> USBH_HcRhDescriptorA_POTPGT_Pos) * 2);
Kojto 37:f1e388e7b752 130
Kojto 37:f1e388e7b752 131 // Clear Interrrupt Status
Kojto 37:f1e388e7b752 132 USBH->HcInterruptStatus |= USBH->HcInterruptStatus;
Kojto 37:f1e388e7b752 133 // Enable interrupts we care about
Kojto 37:f1e388e7b752 134 USBH->HcInterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC;
Kojto 37:f1e388e7b752 135
Kojto 37:f1e388e7b752 136
Kojto 37:f1e388e7b752 137 // Unlock protected registers
Kojto 37:f1e388e7b752 138 SYS_UnlockReg();
Kojto 37:f1e388e7b752 139
Kojto 37:f1e388e7b752 140 // NOTE: Configure as USB host after USBH init above; otherwise system will crash.
Kojto 37:f1e388e7b752 141 SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_USBROLE_STD_USBH;
Kojto 37:f1e388e7b752 142
Kojto 37:f1e388e7b752 143 // Lock protected registers
Kojto 37:f1e388e7b752 144 SYS_LockReg();
Kojto 37:f1e388e7b752 145
Kojto 37:f1e388e7b752 146 NVIC_SetVector(USBH_IRQn, (uint32_t)(_usbisr));
Kojto 37:f1e388e7b752 147 NVIC_EnableIRQ(USBH_IRQn);
Kojto 37:f1e388e7b752 148
Kojto 37:f1e388e7b752 149 // Check for any connected devices
Kojto 37:f1e388e7b752 150 if (USBH->HcRhPortStatus[0] & OR_RH_PORT_CCS) {
Kojto 37:f1e388e7b752 151 // Device connected
Kojto 37:f1e388e7b752 152 wait_ms(150);
Kojto 37:f1e388e7b752 153 deviceConnected(0, 1, USBH->HcRhPortStatus[0] & OR_RH_PORT_LSDA);
Kojto 37:f1e388e7b752 154 }
Kojto 37:f1e388e7b752 155 }
Kojto 37:f1e388e7b752 156
Kojto 37:f1e388e7b752 157 uint32_t USBHALHost::controlHeadED()
Kojto 37:f1e388e7b752 158 {
Kojto 37:f1e388e7b752 159 return USBH->HcControlHeadED;
Kojto 37:f1e388e7b752 160 }
Kojto 37:f1e388e7b752 161
Kojto 37:f1e388e7b752 162 uint32_t USBHALHost::bulkHeadED()
Kojto 37:f1e388e7b752 163 {
Kojto 37:f1e388e7b752 164 return USBH->HcBulkHeadED;
Kojto 37:f1e388e7b752 165 }
Kojto 37:f1e388e7b752 166
Kojto 37:f1e388e7b752 167 uint32_t USBHALHost::interruptHeadED()
Kojto 37:f1e388e7b752 168 {
Kojto 37:f1e388e7b752 169 // FIXME: Only support one INT ED?
Kojto 37:f1e388e7b752 170 return usb_hcca->IntTable[0];
Kojto 37:f1e388e7b752 171 }
Kojto 37:f1e388e7b752 172
Kojto 37:f1e388e7b752 173 void USBHALHost::updateBulkHeadED(uint32_t addr)
Kojto 37:f1e388e7b752 174 {
Kojto 37:f1e388e7b752 175 USBH->HcBulkHeadED = addr;
Kojto 37:f1e388e7b752 176 }
Kojto 37:f1e388e7b752 177
Kojto 37:f1e388e7b752 178
Kojto 37:f1e388e7b752 179 void USBHALHost::updateControlHeadED(uint32_t addr)
Kojto 37:f1e388e7b752 180 {
Kojto 37:f1e388e7b752 181 USBH->HcControlHeadED = addr;
Kojto 37:f1e388e7b752 182 }
Kojto 37:f1e388e7b752 183
Kojto 37:f1e388e7b752 184 void USBHALHost::updateInterruptHeadED(uint32_t addr)
Kojto 37:f1e388e7b752 185 {
Kojto 37:f1e388e7b752 186 // FIXME: Only support one INT ED?
Kojto 37:f1e388e7b752 187 usb_hcca->IntTable[0] = addr;
Kojto 37:f1e388e7b752 188 }
Kojto 37:f1e388e7b752 189
Kojto 37:f1e388e7b752 190
Kojto 37:f1e388e7b752 191 void USBHALHost::enableList(ENDPOINT_TYPE type)
Kojto 37:f1e388e7b752 192 {
Kojto 37:f1e388e7b752 193 switch(type) {
Kojto 37:f1e388e7b752 194 case CONTROL_ENDPOINT:
Kojto 37:f1e388e7b752 195 USBH->HcCommandStatus = OR_CMD_STATUS_CLF;
Kojto 37:f1e388e7b752 196 USBH->HcControl |= OR_CONTROL_CLE;
Kojto 37:f1e388e7b752 197 break;
Kojto 37:f1e388e7b752 198 case ISOCHRONOUS_ENDPOINT:
Kojto 37:f1e388e7b752 199 // FIXME
Kojto 37:f1e388e7b752 200 break;
Kojto 37:f1e388e7b752 201 case BULK_ENDPOINT:
Kojto 37:f1e388e7b752 202 USBH->HcCommandStatus = OR_CMD_STATUS_BLF;
Kojto 37:f1e388e7b752 203 USBH->HcControl |= OR_CONTROL_BLE;
Kojto 37:f1e388e7b752 204 break;
Kojto 37:f1e388e7b752 205 case INTERRUPT_ENDPOINT:
Kojto 37:f1e388e7b752 206 USBH->HcControl |= OR_CONTROL_PLE;
Kojto 37:f1e388e7b752 207 break;
Kojto 37:f1e388e7b752 208 }
Kojto 37:f1e388e7b752 209 }
Kojto 37:f1e388e7b752 210
Kojto 37:f1e388e7b752 211
Kojto 37:f1e388e7b752 212 bool USBHALHost::disableList(ENDPOINT_TYPE type)
Kojto 37:f1e388e7b752 213 {
Kojto 37:f1e388e7b752 214 switch(type) {
Kojto 37:f1e388e7b752 215 case CONTROL_ENDPOINT:
Kojto 37:f1e388e7b752 216 if(USBH->HcControl & OR_CONTROL_CLE) {
Kojto 37:f1e388e7b752 217 USBH->HcControl &= ~OR_CONTROL_CLE;
Kojto 37:f1e388e7b752 218 return true;
Kojto 37:f1e388e7b752 219 }
Kojto 37:f1e388e7b752 220 return false;
Kojto 37:f1e388e7b752 221 case ISOCHRONOUS_ENDPOINT:
Kojto 37:f1e388e7b752 222 // FIXME
Kojto 37:f1e388e7b752 223 return false;
Kojto 37:f1e388e7b752 224 case BULK_ENDPOINT:
Kojto 37:f1e388e7b752 225 if(USBH->HcControl & OR_CONTROL_BLE){
Kojto 37:f1e388e7b752 226 USBH->HcControl &= ~OR_CONTROL_BLE;
Kojto 37:f1e388e7b752 227 return true;
Kojto 37:f1e388e7b752 228 }
Kojto 37:f1e388e7b752 229 return false;
Kojto 37:f1e388e7b752 230 case INTERRUPT_ENDPOINT:
Kojto 37:f1e388e7b752 231 if(USBH->HcControl & OR_CONTROL_PLE) {
Kojto 37:f1e388e7b752 232 USBH->HcControl &= ~OR_CONTROL_PLE;
Kojto 37:f1e388e7b752 233 return true;
Kojto 37:f1e388e7b752 234 }
Kojto 37:f1e388e7b752 235 return false;
Kojto 37:f1e388e7b752 236 }
Kojto 37:f1e388e7b752 237 return false;
Kojto 37:f1e388e7b752 238 }
Kojto 37:f1e388e7b752 239
Kojto 37:f1e388e7b752 240
Kojto 37:f1e388e7b752 241 void USBHALHost::memInit()
Kojto 37:f1e388e7b752 242 {
Kojto 37:f1e388e7b752 243 usb_hcca = (volatile HCCA *)usb_buf;
Kojto 37:f1e388e7b752 244 usb_edBuf = usb_buf + HCCA_SIZE;
Kojto 37:f1e388e7b752 245 usb_tdBuf = usb_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE);
Kojto 37:f1e388e7b752 246 }
Kojto 37:f1e388e7b752 247
Kojto 37:f1e388e7b752 248 volatile uint8_t * USBHALHost::getED()
Kojto 37:f1e388e7b752 249 {
Kojto 37:f1e388e7b752 250 for (int i = 0; i < MAX_ENDPOINT; i++) {
Kojto 37:f1e388e7b752 251 if ( !edBufAlloc[i] ) {
Kojto 37:f1e388e7b752 252 edBufAlloc[i] = true;
Kojto 37:f1e388e7b752 253 return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
Kojto 37:f1e388e7b752 254 }
Kojto 37:f1e388e7b752 255 }
Kojto 37:f1e388e7b752 256 perror("Could not allocate ED\r\n");
Kojto 37:f1e388e7b752 257 return NULL; //Could not alloc ED
Kojto 37:f1e388e7b752 258 }
Kojto 37:f1e388e7b752 259
Kojto 37:f1e388e7b752 260 volatile uint8_t * USBHALHost::getTD()
Kojto 37:f1e388e7b752 261 {
Kojto 37:f1e388e7b752 262 int i;
Kojto 37:f1e388e7b752 263 for (i = 0; i < MAX_TD; i++) {
Kojto 37:f1e388e7b752 264 if ( !tdBufAlloc[i] ) {
Kojto 37:f1e388e7b752 265 tdBufAlloc[i] = true;
Kojto 37:f1e388e7b752 266 return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
Kojto 37:f1e388e7b752 267 }
Kojto 37:f1e388e7b752 268 }
Kojto 37:f1e388e7b752 269 perror("Could not allocate TD\r\n");
Kojto 37:f1e388e7b752 270 return NULL; //Could not alloc TD
Kojto 37:f1e388e7b752 271 }
Kojto 37:f1e388e7b752 272
Kojto 37:f1e388e7b752 273
Kojto 37:f1e388e7b752 274 void USBHALHost::freeED(volatile uint8_t * ed)
Kojto 37:f1e388e7b752 275 {
Kojto 37:f1e388e7b752 276 int i;
Kojto 37:f1e388e7b752 277 i = (ed - usb_edBuf) / ED_SIZE;
Kojto 37:f1e388e7b752 278 edBufAlloc[i] = false;
Kojto 37:f1e388e7b752 279 }
Kojto 37:f1e388e7b752 280
Kojto 37:f1e388e7b752 281 void USBHALHost::freeTD(volatile uint8_t * td)
Kojto 37:f1e388e7b752 282 {
Kojto 37:f1e388e7b752 283 int i;
Kojto 37:f1e388e7b752 284 i = (td - usb_tdBuf) / TD_SIZE;
Kojto 37:f1e388e7b752 285 tdBufAlloc[i] = false;
Kojto 37:f1e388e7b752 286 }
Kojto 37:f1e388e7b752 287
Kojto 37:f1e388e7b752 288
Kojto 37:f1e388e7b752 289 void USBHALHost::resetRootHub()
Kojto 37:f1e388e7b752 290 {
Kojto 37:f1e388e7b752 291 // Reset port1
Kojto 37:f1e388e7b752 292 USBH->HcRhPortStatus[0] = OR_RH_PORT_PRS;
Kojto 37:f1e388e7b752 293 while (USBH->HcRhPortStatus[0] & OR_RH_PORT_PRS);
Kojto 37:f1e388e7b752 294 USBH->HcRhPortStatus[0] = OR_RH_PORT_PRSC;
Kojto 37:f1e388e7b752 295 }
Kojto 37:f1e388e7b752 296
Kojto 37:f1e388e7b752 297
Kojto 37:f1e388e7b752 298 void USBHALHost::_usbisr(void)
Kojto 37:f1e388e7b752 299 {
Kojto 37:f1e388e7b752 300 if (instHost) {
Kojto 37:f1e388e7b752 301 instHost->UsbIrqhandler();
Kojto 37:f1e388e7b752 302 }
Kojto 37:f1e388e7b752 303 }
Kojto 37:f1e388e7b752 304
Kojto 37:f1e388e7b752 305 void USBHALHost::UsbIrqhandler()
Kojto 37:f1e388e7b752 306 {
Kojto 37:f1e388e7b752 307 uint32_t ints = USBH->HcInterruptStatus;
Kojto 37:f1e388e7b752 308
Kojto 37:f1e388e7b752 309 // Root hub status change interrupt
Kojto 37:f1e388e7b752 310 if (ints & OR_INTR_STATUS_RHSC) {
Kojto 37:f1e388e7b752 311 uint32_t ints_roothub = USBH->HcRhStatus;
Kojto 37:f1e388e7b752 312 uint32_t ints_port1 = USBH->HcRhPortStatus[0];
Kojto 37:f1e388e7b752 313
Kojto 37:f1e388e7b752 314 // Port1: ConnectStatusChange
Kojto 37:f1e388e7b752 315 if (ints_port1 & OR_RH_PORT_CSC) {
Kojto 37:f1e388e7b752 316 if (ints_roothub & OR_RH_STATUS_DRWE) {
Kojto 37:f1e388e7b752 317 // When DRWE is on, Connect Status Change means a remote wakeup event.
Kojto 37:f1e388e7b752 318 } else {
Kojto 37:f1e388e7b752 319 if (ints_port1 & OR_RH_PORT_CCS) {
Kojto 37:f1e388e7b752 320 // Root device connected
Kojto 37:f1e388e7b752 321
Kojto 37:f1e388e7b752 322 // wait 150ms to avoid bounce
Kojto 37:f1e388e7b752 323 wait_ms(150);
Kojto 37:f1e388e7b752 324
Kojto 37:f1e388e7b752 325 //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
Kojto 37:f1e388e7b752 326 deviceConnected(0, 1, ints_port1 & OR_RH_PORT_LSDA);
Kojto 37:f1e388e7b752 327 } else {
Kojto 37:f1e388e7b752 328 // Root device disconnected
Kojto 37:f1e388e7b752 329
Kojto 37:f1e388e7b752 330 if (!(ints & OR_INTR_STATUS_WDH)) {
Kojto 37:f1e388e7b752 331 usb_hcca->DoneHead = 0;
Kojto 37:f1e388e7b752 332 }
Kojto 37:f1e388e7b752 333
Kojto 37:f1e388e7b752 334 // wait 200ms to avoid bounce
Kojto 37:f1e388e7b752 335 wait_ms(200);
Kojto 37:f1e388e7b752 336
Kojto 37:f1e388e7b752 337 deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
Kojto 37:f1e388e7b752 338
Kojto 37:f1e388e7b752 339 if (ints & OR_INTR_STATUS_WDH) {
Kojto 37:f1e388e7b752 340 usb_hcca->DoneHead = 0;
Kojto 37:f1e388e7b752 341 USBH->HcInterruptStatus = OR_INTR_STATUS_WDH;
Kojto 37:f1e388e7b752 342 }
Kojto 37:f1e388e7b752 343 }
Kojto 37:f1e388e7b752 344 }
Kojto 37:f1e388e7b752 345 USBH->HcRhPortStatus[0] = OR_RH_PORT_CSC;
Kojto 37:f1e388e7b752 346 }
Kojto 37:f1e388e7b752 347 // Port1: Reset completed
Kojto 37:f1e388e7b752 348 if (ints_port1 & OR_RH_PORT_PRSC) {
Kojto 37:f1e388e7b752 349 USBH->HcRhPortStatus[0] = OR_RH_PORT_PRSC;
Kojto 37:f1e388e7b752 350 }
Kojto 37:f1e388e7b752 351 // Port1: PortEnableStatusChange
Kojto 37:f1e388e7b752 352 if (ints_port1 & OR_RH_PORT_PESC) {
Kojto 37:f1e388e7b752 353 USBH->HcRhPortStatus[0] = OR_RH_PORT_PESC;
Kojto 37:f1e388e7b752 354 }
Kojto 37:f1e388e7b752 355
Kojto 37:f1e388e7b752 356 USBH->HcInterruptStatus = OR_INTR_STATUS_RHSC;
Kojto 37:f1e388e7b752 357 }
Kojto 37:f1e388e7b752 358
Kojto 37:f1e388e7b752 359 // Writeback Done Head interrupt
Kojto 37:f1e388e7b752 360 if (ints & OR_INTR_STATUS_WDH) {
Kojto 37:f1e388e7b752 361 transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE);
Kojto 37:f1e388e7b752 362 USBH->HcInterruptStatus = OR_INTR_STATUS_WDH;
Kojto 37:f1e388e7b752 363 }
Kojto 37:f1e388e7b752 364 }
Kojto 37:f1e388e7b752 365 #endif