Pierre Provent / USBHost

Dependents:   TEST_USB_Nucleo_F429ZI Essais_USB_Nucleo_F429ZI SID_V3_Nucleo_F429ZI SID_V4_Nucleo_F429ZI_copy

Committer:
pierreprovent
Date:
Fri Sep 25 10:17:49 2020 +0000
Revision:
0:77ca32e8e04e
Programme acquisition en enregistrement sur clef USB carte Nucleo F429ZI cours ELE118 Cnam

Who changed what in which revision?

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