USBHOST lib for STM

Dependents:   door-access-controller-dev

Committer:
jamike
Date:
Wed Apr 26 20:08:31 2017 +0000
Revision:
6:d3ac9e1c0035
Parent:
1:ab240722d7ef
fix error in read and write

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 1 /* mbed USBHost Library
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 2 * Copyright (c) 2006-2013 ARM Limited
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_RZ_A1H) || defined(TARGET_VK_RZ_A1H)
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
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 23 #include "ohci_wrapp_RZ_A1.h"
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 24
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 25
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 26 #define HCCA_SIZE sizeof(HCCA)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 27 #define ED_SIZE sizeof(HCED)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 28 #define TD_SIZE sizeof(HCTD)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 29
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 30 #define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 31 #define ALIGNE_MSK (0x0000000F)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 32
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 33 static volatile uint8_t usb_buf[TOTAL_SIZE + ALIGNE_MSK]; //16 bytes aligned!
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 34
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 35 USBHALHost * USBHALHost::instHost;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 36
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 37 USBHALHost::USBHALHost() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 38 instHost = this;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 39 memInit();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 40 memset((void*)usb_hcca, 0, HCCA_SIZE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 41 for (int i = 0; i < MAX_ENDPOINT; i++) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 42 edBufAlloc[i] = false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 43 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 44 for (int i = 0; i < MAX_TD; i++) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 45 tdBufAlloc[i] = false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 46 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 47 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 48
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 49 void USBHALHost::init() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 50 ohciwrapp_init(&_usbisr);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 51
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 52 ohciwrapp_reg_w(OHCI_REG_CONTROL, 1); // HARDWARE RESET
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 53 ohciwrapp_reg_w(OHCI_REG_CONTROLHEADED, 0); // Initialize Control list head to Zero
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 54 ohciwrapp_reg_w(OHCI_REG_BULKHEADED, 0); // Initialize Bulk list head to Zero
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 55
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 56 // Wait 100 ms before apply reset
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 57 wait_ms(100);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 58
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 59 // software reset
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 60 ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_HCR);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 61
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 62 // Write Fm Interval and Largest Data Packet Counter
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 63 ohciwrapp_reg_w(OHCI_REG_FMINTERVAL, DEFAULT_FMINTERVAL);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 64 ohciwrapp_reg_w(OHCI_REG_PERIODICSTART, FI * 90 / 100);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 65
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 66 // Put HC in operational state
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 67 ohciwrapp_reg_w(OHCI_REG_CONTROL, (ohciwrapp_reg_r(OHCI_REG_CONTROL) & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 68 // Set Global Power
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 69 ohciwrapp_reg_w(OHCI_REG_RHSTATUS, OR_RH_STATUS_LPSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 70
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 71 ohciwrapp_reg_w(OHCI_REG_HCCA, (uint32_t)(usb_hcca));
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 72
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 73 // Clear Interrrupt Status
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 74 ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, ohciwrapp_reg_r(OHCI_REG_INTERRUPTSTATUS));
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 75
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 76 ohciwrapp_reg_w(OHCI_REG_INTERRUPTENABLE, OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 77
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 78 // Enable the USB Interrupt
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 79 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_CSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 80 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 81
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 82 // Check for any connected devices
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 83 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CCS) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 84 //Device connected
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 85 wait_ms(150);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 86 USB_DBG("Device connected (%08x)\n\r", ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1));
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 87 deviceConnected(0, 1, ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_LSDA);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 88 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 89 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 90
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 91 uint32_t USBHALHost::controlHeadED() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 92 return ohciwrapp_reg_r(OHCI_REG_CONTROLHEADED);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 93 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 94
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 95 uint32_t USBHALHost::bulkHeadED() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 96 return ohciwrapp_reg_r(OHCI_REG_BULKHEADED);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 97 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 98
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 99 uint32_t USBHALHost::interruptHeadED() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 100 return usb_hcca->IntTable[0];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 101 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 102
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 103 void USBHALHost::updateBulkHeadED(uint32_t addr) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 104 ohciwrapp_reg_w(OHCI_REG_BULKHEADED, addr);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 105 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 106
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 107
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 108 void USBHALHost::updateControlHeadED(uint32_t addr) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 109 ohciwrapp_reg_w(OHCI_REG_CONTROLHEADED, addr);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 110 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 111
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 112 void USBHALHost::updateInterruptHeadED(uint32_t addr) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 113 usb_hcca->IntTable[0] = addr;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 114 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 115
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 116
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 117 void USBHALHost::enableList(ENDPOINT_TYPE type) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 118 uint32_t wk_data;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 119
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 120 switch(type) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 121 case CONTROL_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 122 ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_CLF);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 123 wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_CLE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 124 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 125 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 126 case ISOCHRONOUS_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 127 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 128 case BULK_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 129 ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_BLF);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 130 wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_BLE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 131 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 132 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 133 case INTERRUPT_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 134 wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_PLE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 135 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 136 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 137 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 138 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 139
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 140
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 141 bool USBHALHost::disableList(ENDPOINT_TYPE type) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 142 uint32_t wk_data;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 143
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 144 switch(type) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 145 case CONTROL_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 146 wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 147 if(wk_data & OR_CONTROL_CLE) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 148 wk_data &= ~OR_CONTROL_CLE;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 149 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 150 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 151 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 152 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 153 case ISOCHRONOUS_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 154 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 155 case BULK_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 156 wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 157 if(wk_data & OR_CONTROL_BLE) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 158 wk_data &= ~OR_CONTROL_BLE;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 159 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 160 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 161 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 162 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 163 case INTERRUPT_ENDPOINT:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 164 wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 165 if(wk_data & OR_CONTROL_PLE) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 166 wk_data &= ~OR_CONTROL_PLE;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 167 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 168 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 169 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 170 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 171 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 172 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 173 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 174
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 175
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 176 void USBHALHost::memInit() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 177 volatile uint8_t *p_wk_buf = (uint8_t *)(((uint32_t)usb_buf + ALIGNE_MSK) & ~ALIGNE_MSK);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 178
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 179 usb_hcca = (volatile HCCA *)p_wk_buf;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 180 usb_edBuf = (volatile uint8_t *)(p_wk_buf + HCCA_SIZE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 181 usb_tdBuf = (volatile uint8_t *)(p_wk_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE));
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 182 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 183
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 184 volatile uint8_t * USBHALHost::getED() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 185 for (int i = 0; i < MAX_ENDPOINT; i++) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 186 if ( !edBufAlloc[i] ) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 187 edBufAlloc[i] = true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 188 return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 189 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 190 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 191 perror("Could not allocate ED\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 192 return NULL; //Could not alloc ED
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 193 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 194
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 195 volatile uint8_t * USBHALHost::getTD() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 196 int i;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 197 for (i = 0; i < MAX_TD; i++) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 198 if ( !tdBufAlloc[i] ) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 199 tdBufAlloc[i] = true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 200 return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 201 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 202 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 203 perror("Could not allocate TD\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 204 return NULL; //Could not alloc TD
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 205 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 206
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 207
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 208 void USBHALHost::freeED(volatile uint8_t * ed) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 209 int i;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 210 i = (ed - usb_edBuf) / ED_SIZE;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 211 edBufAlloc[i] = 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 void USBHALHost::freeTD(volatile uint8_t * td) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 215 int i;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 216 i = (td - usb_tdBuf) / TD_SIZE;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 217 tdBufAlloc[i] = false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 218 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 219
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 220
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 221 void USBHALHost::resetRootHub() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 222 // Initiate port reset
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 223 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRS);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 224
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 225 while (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_PRS);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 226
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 227 // ...and clear port reset signal
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 228 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 229 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 230
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 231
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 232 void USBHALHost::_usbisr(void) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 233 if (instHost) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 234 instHost->UsbIrqhandler();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 235 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 236 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 237
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 238 void USBHALHost::UsbIrqhandler() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 239 uint32_t int_status = ohciwrapp_reg_r(OHCI_REG_INTERRUPTSTATUS) & ohciwrapp_reg_r(OHCI_REG_INTERRUPTENABLE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 240 uint32_t data;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 241
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 242 if (int_status != 0) { //Is there something to actually process?
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 243 // Root hub status change interrupt
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 244 if (int_status & OR_INTR_STATUS_RHSC) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 245 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CSC) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 246 if (ohciwrapp_reg_r(OHCI_REG_RHSTATUS) & OR_RH_STATUS_DRWE) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 247 // When DRWE is on, Connect Status Change
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 248 // means a remote wakeup event.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 249 } else {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 250
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 251 //Root device connected
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 252 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CCS) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 253
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 254 // wait 150ms to avoid bounce
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 255 wait_ms(150);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 256
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 257 //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 258 data = ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_LSDA;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 259 deviceConnected(0, 1, data);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 260 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 261
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 262 //Root device disconnected
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 263 else {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 264 deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 265 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 266 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 267 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_CSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 268 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 269 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_PRSC) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 270 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 271 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 272 ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_RHSC);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 273 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 274
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 275 // Writeback Done Head interrupt
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 276 if (int_status & OR_INTR_STATUS_WDH) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 277 transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 278 ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_WDH);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 279 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 280 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 281 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 282 #endif