Fork of the USBHost library by mbed.
Dependencies: FATFileSystem mbed-rtos
Fork of USBHost by
USBHALHost_RZ_A1.cpp
00001 /* mbed USBHost Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #if defined(TARGET_RZ_A1H) 00018 00019 #include "mbed.h" 00020 #include "USBHALHost.h" 00021 #include "dbg.h" 00022 00023 #include "ohci_wrapp_RZ_A1.h" 00024 00025 00026 #define HCCA_SIZE sizeof(HCCA) 00027 #define ED_SIZE sizeof(HCED) 00028 #define TD_SIZE sizeof(HCTD) 00029 00030 #define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE)) 00031 #define ALIGNE_MSK (0x0000000F) 00032 00033 static volatile uint8_t usb_buf[TOTAL_SIZE + ALIGNE_MSK]; //16 bytes aligned! 00034 00035 USBHALHost * USBHALHost::instHost; 00036 00037 USBHALHost::USBHALHost() { 00038 instHost = this; 00039 memInit(); 00040 memset((void*)usb_hcca, 0, HCCA_SIZE); 00041 for (int i = 0; i < MAX_ENDPOINT; i++) { 00042 edBufAlloc[i] = false; 00043 } 00044 for (int i = 0; i < MAX_TD; i++) { 00045 tdBufAlloc[i] = false; 00046 } 00047 } 00048 00049 void USBHALHost::init() { 00050 ohciwrapp_init(&_usbisr); 00051 00052 ohciwrapp_reg_w(OHCI_REG_CONTROL, 1); // HARDWARE RESET 00053 ohciwrapp_reg_w(OHCI_REG_CONTROLHEADED, 0); // Initialize Control list head to Zero 00054 ohciwrapp_reg_w(OHCI_REG_BULKHEADED, 0); // Initialize Bulk list head to Zero 00055 00056 // Wait 100 ms before apply reset 00057 wait_ms(100); 00058 00059 // software reset 00060 ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_HCR); 00061 00062 // Write Fm Interval and Largest Data Packet Counter 00063 ohciwrapp_reg_w(OHCI_REG_FMINTERVAL, DEFAULT_FMINTERVAL); 00064 ohciwrapp_reg_w(OHCI_REG_PERIODICSTART, FI * 90 / 100); 00065 00066 // Put HC in operational state 00067 ohciwrapp_reg_w(OHCI_REG_CONTROL, (ohciwrapp_reg_r(OHCI_REG_CONTROL) & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER); 00068 // Set Global Power 00069 ohciwrapp_reg_w(OHCI_REG_RHSTATUS, OR_RH_STATUS_LPSC); 00070 00071 ohciwrapp_reg_w(OHCI_REG_HCCA, (uint32_t)(usb_hcca)); 00072 00073 // Clear Interrrupt Status 00074 ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, ohciwrapp_reg_r(OHCI_REG_INTERRUPTSTATUS)); 00075 00076 ohciwrapp_reg_w(OHCI_REG_INTERRUPTENABLE, OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC); 00077 00078 // Enable the USB Interrupt 00079 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_CSC); 00080 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC); 00081 00082 // Check for any connected devices 00083 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CCS) { 00084 //Device connected 00085 wait_ms(150); 00086 USB_DBG("Device connected (%08x)\n\r", ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1)); 00087 deviceConnected(0, 1, ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_LSDA); 00088 } 00089 } 00090 00091 uint32_t USBHALHost::controlHeadED() { 00092 return ohciwrapp_reg_r(OHCI_REG_CONTROLHEADED); 00093 } 00094 00095 uint32_t USBHALHost::bulkHeadED() { 00096 return ohciwrapp_reg_r(OHCI_REG_BULKHEADED); 00097 } 00098 00099 uint32_t USBHALHost::interruptHeadED() { 00100 return usb_hcca->IntTable[0]; 00101 } 00102 00103 void USBHALHost::updateBulkHeadED(uint32_t addr) { 00104 ohciwrapp_reg_w(OHCI_REG_BULKHEADED, addr); 00105 } 00106 00107 00108 void USBHALHost::updateControlHeadED(uint32_t addr) { 00109 ohciwrapp_reg_w(OHCI_REG_CONTROLHEADED, addr); 00110 } 00111 00112 void USBHALHost::updateInterruptHeadED(uint32_t addr) { 00113 usb_hcca->IntTable[0] = addr; 00114 } 00115 00116 00117 void USBHALHost::enableList(ENDPOINT_TYPE type) { 00118 uint32_t wk_data; 00119 00120 switch(type) { 00121 case CONTROL_ENDPOINT: 00122 ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_CLF); 00123 wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_CLE); 00124 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data); 00125 break; 00126 case ISOCHRONOUS_ENDPOINT: 00127 break; 00128 case BULK_ENDPOINT: 00129 ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_BLF); 00130 wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_BLE); 00131 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data); 00132 break; 00133 case INTERRUPT_ENDPOINT: 00134 wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_PLE); 00135 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data); 00136 break; 00137 } 00138 } 00139 00140 00141 bool USBHALHost::disableList(ENDPOINT_TYPE type) { 00142 uint32_t wk_data; 00143 00144 switch(type) { 00145 case CONTROL_ENDPOINT: 00146 wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL); 00147 if(wk_data & OR_CONTROL_CLE) { 00148 wk_data &= ~OR_CONTROL_CLE; 00149 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data); 00150 return true; 00151 } 00152 return false; 00153 case ISOCHRONOUS_ENDPOINT: 00154 return false; 00155 case BULK_ENDPOINT: 00156 wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL); 00157 if(wk_data & OR_CONTROL_BLE) { 00158 wk_data &= ~OR_CONTROL_BLE; 00159 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data); 00160 return true; 00161 } 00162 return false; 00163 case INTERRUPT_ENDPOINT: 00164 wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL); 00165 if(wk_data & OR_CONTROL_PLE) { 00166 wk_data &= ~OR_CONTROL_PLE; 00167 ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data); 00168 return true; 00169 } 00170 return false; 00171 } 00172 return false; 00173 } 00174 00175 00176 void USBHALHost::memInit() { 00177 volatile uint8_t *p_wk_buf = (uint8_t *)(((uint32_t)usb_buf + ALIGNE_MSK) & ~ALIGNE_MSK); 00178 00179 usb_hcca = (volatile HCCA *)p_wk_buf; 00180 usb_edBuf = (volatile uint8_t *)(p_wk_buf + HCCA_SIZE); 00181 usb_tdBuf = (volatile uint8_t *)(p_wk_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE)); 00182 } 00183 00184 volatile uint8_t * USBHALHost::getED() { 00185 for (int i = 0; i < MAX_ENDPOINT; i++) { 00186 if ( !edBufAlloc[i] ) { 00187 edBufAlloc[i] = true; 00188 return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE); 00189 } 00190 } 00191 perror("Could not allocate ED\r\n"); 00192 return NULL; //Could not alloc ED 00193 } 00194 00195 volatile uint8_t * USBHALHost::getTD() { 00196 int i; 00197 for (i = 0; i < MAX_TD; i++) { 00198 if ( !tdBufAlloc[i] ) { 00199 tdBufAlloc[i] = true; 00200 return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE); 00201 } 00202 } 00203 perror("Could not allocate TD\r\n"); 00204 return NULL; //Could not alloc TD 00205 } 00206 00207 00208 void USBHALHost::freeED(volatile uint8_t * ed) { 00209 int i; 00210 i = (ed - usb_edBuf) / ED_SIZE; 00211 edBufAlloc[i] = false; 00212 } 00213 00214 void USBHALHost::freeTD(volatile uint8_t * td) { 00215 int i; 00216 i = (td - usb_tdBuf) / TD_SIZE; 00217 tdBufAlloc[i] = false; 00218 } 00219 00220 00221 void USBHALHost::resetRootHub() { 00222 // Initiate port reset 00223 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRS); 00224 00225 while (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_PRS); 00226 00227 // ...and clear port reset signal 00228 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC); 00229 } 00230 00231 00232 void USBHALHost::_usbisr(void) { 00233 if (instHost) { 00234 instHost->UsbIrqhandler(); 00235 } 00236 } 00237 00238 void USBHALHost::UsbIrqhandler() { 00239 uint32_t int_status = ohciwrapp_reg_r(OHCI_REG_INTERRUPTSTATUS) & ohciwrapp_reg_r(OHCI_REG_INTERRUPTENABLE); 00240 uint32_t data; 00241 00242 if (int_status != 0) { //Is there something to actually process? 00243 // Root hub status change interrupt 00244 if (int_status & OR_INTR_STATUS_RHSC) { 00245 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CSC) { 00246 if (ohciwrapp_reg_r(OHCI_REG_RHSTATUS) & OR_RH_STATUS_DRWE) { 00247 // When DRWE is on, Connect Status Change 00248 // means a remote wakeup event. 00249 } else { 00250 00251 //Root device connected 00252 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CCS) { 00253 00254 // wait 150ms to avoid bounce 00255 wait_ms(150); 00256 00257 //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed 00258 data = ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_LSDA; 00259 deviceConnected(0, 1, data); 00260 } 00261 00262 //Root device disconnected 00263 else { 00264 00265 if (!(int_status & OR_INTR_STATUS_WDH)) { 00266 usb_hcca->DoneHead = 0; 00267 } 00268 00269 deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE); 00270 00271 if (int_status & OR_INTR_STATUS_WDH) { 00272 usb_hcca->DoneHead = 0; 00273 ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_WDH); 00274 } 00275 } 00276 } 00277 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_CSC); 00278 } 00279 if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_PRSC) { 00280 ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC); 00281 } 00282 ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_RHSC); 00283 } 00284 00285 // Writeback Done Head interrupt 00286 if (int_status & OR_INTR_STATUS_WDH) { 00287 transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE); 00288 ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_WDH); 00289 } 00290 } 00291 } 00292 #endif
Generated on Tue Jul 12 2022 20:10:19 by
![doxygen](doxygen.png)