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