USB BARCODE READER

Fork of USBHOST by ST

Committer:
shivanandgowdakr
Date:
Mon Jul 02 12:10:45 2018 +0000
Revision:
7:ccd0ac9ae1c9
Parent:
1:ab240722d7ef
USB BARCODE READER ;

Who changed what in which revision?

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