Added TARGET_DISCO_F469NI in USBHOST\USBHost\TARGET_STM\USBHALHost_STM_TARGET.h

Dependents:   DISCO-F469NI_USB_Disk STM32F4xx_USB_Memory

Fork of USBHOST by ST

Committer:
kenjiArai
Date:
Sat Jan 04 23:30:59 2020 +0000
Revision:
8:3e7a33f81048
updated for STM32F4xx

Who changed what in which revision?

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