X-TOUCH to djay bridge

Dependencies:   mbed mbed-rtos FATFileSystem

Committer:
okini3939
Date:
Wed Jun 05 04:54:37 2019 +0000
Revision:
1:0dac72ab5910
sample

Who changed what in which revision?

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