USBHost library. NOTE: This library is only officially supported on the LPC1768 platform. For more information, please see the handbook page.

Dependencies:   FATFileSystem mbed-rtos

Dependents:   BTstack WallbotWii SD to Flash Data Transfer USBHost-MSD_HelloWorld ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Pull requests against this repository are no longer supported. Please raise against mbed OS 5 as documented above.

Committer:
Kojto
Date:
Thu Jul 20 10:13:56 2017 +0100
Revision:
37:f1e388e7b752
Update libraries (ed9d1da)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto 37:f1e388e7b752 1 /* mbed USBHost Library
Kojto 37:f1e388e7b752 2 * Copyright (c) 2006-2013 ARM Limited
Kojto 37:f1e388e7b752 3 *
Kojto 37:f1e388e7b752 4 * Licensed under the Apache License, Version 2.0 (the "License");
Kojto 37:f1e388e7b752 5 * you may not use this file except in compliance with the License.
Kojto 37:f1e388e7b752 6 * You may obtain a copy of the License at
Kojto 37:f1e388e7b752 7 *
Kojto 37:f1e388e7b752 8 * http://www.apache.org/licenses/LICENSE-2.0
Kojto 37:f1e388e7b752 9 *
Kojto 37:f1e388e7b752 10 * Unless required by applicable law or agreed to in writing, software
Kojto 37:f1e388e7b752 11 * distributed under the License is distributed on an "AS IS" BASIS,
Kojto 37:f1e388e7b752 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Kojto 37:f1e388e7b752 13 * See the License for the specific language governing permissions and
Kojto 37:f1e388e7b752 14 * limitations under the License.
Kojto 37:f1e388e7b752 15 */
Kojto 37:f1e388e7b752 16
Kojto 37:f1e388e7b752 17 #ifdef TARGET_STM
Kojto 37:f1e388e7b752 18 #include "mbed.h"
Kojto 37:f1e388e7b752 19 #include "USBHALHost.h"
Kojto 37:f1e388e7b752 20 #include "dbg.h"
Kojto 37:f1e388e7b752 21 #include "pinmap.h"
Kojto 37:f1e388e7b752 22
Kojto 37:f1e388e7b752 23 #include "USBHALHost_STM_TARGET.h"
Kojto 37:f1e388e7b752 24
Kojto 37:f1e388e7b752 25 void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
Kojto 37:f1e388e7b752 26 {
Kojto 37:f1e388e7b752 27 USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
Kojto 37:f1e388e7b752 28 USBHALHost *obj= priv->inst;
Kojto 37:f1e388e7b752 29 void (USBHALHost::*func)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent ) = priv->deviceConnected;
Kojto 37:f1e388e7b752 30 (obj->*func)(0,1,0,NULL);
Kojto 37:f1e388e7b752 31 }
Kojto 37:f1e388e7b752 32 void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
Kojto 37:f1e388e7b752 33 {
Kojto 37:f1e388e7b752 34 USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
Kojto 37:f1e388e7b752 35 USBHALHost *obj= priv->inst;
Kojto 37:f1e388e7b752 36 void (USBHALHost::*func1)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)= priv->deviceDisconnected;
Kojto 37:f1e388e7b752 37 (obj->*func1)(0,1,(USBHostHub *)NULL,0);
Kojto 37:f1e388e7b752 38 }
Kojto 37:f1e388e7b752 39 int HAL_HCD_HC_GetDirection(HCD_HandleTypeDef *hhcd,uint8_t chnum)
Kojto 37:f1e388e7b752 40 {
Kojto 37:f1e388e7b752 41 /* useful for transmission */
Kojto 37:f1e388e7b752 42 return hhcd->hc[chnum].ep_is_in;
Kojto 37:f1e388e7b752 43 }
Kojto 37:f1e388e7b752 44
Kojto 37:f1e388e7b752 45 uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd,uint8_t chnum)
Kojto 37:f1e388e7b752 46 {
Kojto 37:f1e388e7b752 47 /* useful for transmission */
Kojto 37:f1e388e7b752 48 return hhcd->hc[chnum].max_packet;
Kojto 37:f1e388e7b752 49 }
Kojto 37:f1e388e7b752 50
Kojto 37:f1e388e7b752 51 void HAL_HCD_EnableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum)
Kojto 37:f1e388e7b752 52 {
Kojto 37:f1e388e7b752 53 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
Kojto 37:f1e388e7b752 54 USBx_HOST->HAINTMSK |= (1 << chnum);
Kojto 37:f1e388e7b752 55 }
Kojto 37:f1e388e7b752 56
Kojto 37:f1e388e7b752 57
Kojto 37:f1e388e7b752 58 void HAL_HCD_DisableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum)
Kojto 37:f1e388e7b752 59 {
Kojto 37:f1e388e7b752 60 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
Kojto 37:f1e388e7b752 61 USBx_HOST->HAINTMSK &= ~(1 << chnum);
Kojto 37:f1e388e7b752 62 }
Kojto 37:f1e388e7b752 63 uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd,uint8_t chnum)
Kojto 37:f1e388e7b752 64 {
Kojto 37:f1e388e7b752 65 /* useful for transmission */
Kojto 37:f1e388e7b752 66 return hhcd->hc[chnum].ep_type;
Kojto 37:f1e388e7b752 67 }
Kojto 37:f1e388e7b752 68
Kojto 37:f1e388e7b752 69 void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,uint8_t chnum, HCD_URBStateTypeDef urb_state)
Kojto 37:f1e388e7b752 70 {
Kojto 37:f1e388e7b752 71 USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
Kojto 37:f1e388e7b752 72 USBHALHost *obj= priv->inst;
Kojto 37:f1e388e7b752 73 void (USBHALHost::*func)(volatile uint32_t addr)= priv->transferCompleted;
Kojto 37:f1e388e7b752 74
Kojto 37:f1e388e7b752 75 uint32_t addr = priv->addr[chnum];
Kojto 37:f1e388e7b752 76 uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, chnum);
Kojto 37:f1e388e7b752 77 uint32_t type = HAL_HCD_HC_GetType(hhcd, chnum);
Kojto 37:f1e388e7b752 78 uint32_t dir = HAL_HCD_HC_GetDirection(hhcd,chnum);
Kojto 37:f1e388e7b752 79 uint32_t length;
Kojto 37:f1e388e7b752 80 if ( (addr!=0)) {
Kojto 37:f1e388e7b752 81 HCTD *td = (HCTD *)addr;
Kojto 37:f1e388e7b752 82
Kojto 37:f1e388e7b752 83 if ((type == EP_TYPE_BULK) || (type == EP_TYPE_CTRL )) {
Kojto 37:f1e388e7b752 84 switch (urb_state) {
Kojto 37:f1e388e7b752 85 case URB_DONE:
Kojto 37:f1e388e7b752 86 #if defined(MAX_NYET_RETRY)
Kojto 37:f1e388e7b752 87 td->retry = 0;
Kojto 37:f1e388e7b752 88 #endif
Kojto 37:f1e388e7b752 89 if (td->size > max_size) {
Kojto 37:f1e388e7b752 90 /* enqueue another request */
Kojto 37:f1e388e7b752 91 td->currBufPtr += max_size;
Kojto 37:f1e388e7b752 92 td->size -= max_size;
Kojto 37:f1e388e7b752 93 length = td->size <= max_size ? td->size : max_size;
Kojto 37:f1e388e7b752 94 MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
Kojto 37:f1e388e7b752 95 HAL_HCD_EnableInt(hhcd, chnum);
Kojto 37:f1e388e7b752 96 return;
Kojto 37:f1e388e7b752 97 }
Kojto 37:f1e388e7b752 98 break;
Kojto 37:f1e388e7b752 99 case URB_NOTREADY:
Kojto 37:f1e388e7b752 100 /* try again */
Kojto 37:f1e388e7b752 101 /* abritary limit , to avoid dead lock if other error than
Kojto 37:f1e388e7b752 102 * slow response is */
Kojto 37:f1e388e7b752 103 #if defined(MAX_NYET_RETRY)
Kojto 37:f1e388e7b752 104 if (td->retry < MAX_NYET_RETRY) {
Kojto 37:f1e388e7b752 105 /* increment retry counter */
Kojto 37:f1e388e7b752 106 td->retry++;
Kojto 37:f1e388e7b752 107 #endif
Kojto 37:f1e388e7b752 108 length = td->size <= max_size ? td->size : max_size;
Kojto 37:f1e388e7b752 109 MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
Kojto 37:f1e388e7b752 110 HAL_HCD_EnableInt(hhcd, chnum);
Kojto 37:f1e388e7b752 111 return;
Kojto 37:f1e388e7b752 112 #if defined(MAX_NYET_RETRY)
Kojto 37:f1e388e7b752 113 } else {
Kojto 37:f1e388e7b752 114 USB_ERR("urb_state != URB_NOTREADY");
Kojto 37:f1e388e7b752 115 }
Kojto 37:f1e388e7b752 116 #endif
Kojto 37:f1e388e7b752 117 break;
Kojto 37:f1e388e7b752 118 }
Kojto 37:f1e388e7b752 119 }
Kojto 37:f1e388e7b752 120 if ((type == EP_TYPE_INTR) ) {
Kojto 37:f1e388e7b752 121 /* reply a packet of length NULL, this will be analyse in call back
Kojto 37:f1e388e7b752 122 * for mouse or hub */
Kojto 37:f1e388e7b752 123 td->state =USB_TYPE_IDLE ;
Kojto 37:f1e388e7b752 124 HAL_HCD_DisableInt(hhcd, chnum);
Kojto 37:f1e388e7b752 125
Kojto 37:f1e388e7b752 126 } else {
Kojto 37:f1e388e7b752 127 td->state = (urb_state == URB_DONE) ? USB_TYPE_IDLE : USB_TYPE_ERROR;
Kojto 37:f1e388e7b752 128 }
Kojto 37:f1e388e7b752 129 td->currBufPtr +=HAL_HCD_HC_GetXferCount(hhcd, chnum);
Kojto 37:f1e388e7b752 130 (obj->*func)(addr);
Kojto 37:f1e388e7b752 131 } else {
Kojto 37:f1e388e7b752 132 if (urb_state !=0) {
Kojto 37:f1e388e7b752 133 USB_DBG_EVENT("spurious %d %d",chnum, urb_state);
Kojto 37:f1e388e7b752 134 }
Kojto 37:f1e388e7b752 135 }
Kojto 37:f1e388e7b752 136 }
Kojto 37:f1e388e7b752 137
Kojto 37:f1e388e7b752 138 USBHALHost * USBHALHost::instHost;
Kojto 37:f1e388e7b752 139
Kojto 37:f1e388e7b752 140
Kojto 37:f1e388e7b752 141 void USBHALHost::init()
Kojto 37:f1e388e7b752 142 {
Kojto 37:f1e388e7b752 143
Kojto 37:f1e388e7b752 144 NVIC_DisableIRQ(USBHAL_IRQn);
Kojto 37:f1e388e7b752 145 NVIC_SetVector(USBHAL_IRQn, (uint32_t)(_usbisr));
Kojto 37:f1e388e7b752 146 HAL_HCD_Init((HCD_HandleTypeDef *) usb_hcca);
Kojto 37:f1e388e7b752 147 NVIC_EnableIRQ(USBHAL_IRQn);
Kojto 37:f1e388e7b752 148 control_disable = 0;
Kojto 37:f1e388e7b752 149 HAL_HCD_Start((HCD_HandleTypeDef *) usb_hcca);
Kojto 37:f1e388e7b752 150 usb_vbus(1);
Kojto 37:f1e388e7b752 151 }
Kojto 37:f1e388e7b752 152
Kojto 37:f1e388e7b752 153 uint32_t USBHALHost::controlHeadED()
Kojto 37:f1e388e7b752 154 {
Kojto 37:f1e388e7b752 155 return 0xffffffff;
Kojto 37:f1e388e7b752 156 }
Kojto 37:f1e388e7b752 157
Kojto 37:f1e388e7b752 158 uint32_t USBHALHost::bulkHeadED()
Kojto 37:f1e388e7b752 159 {
Kojto 37:f1e388e7b752 160 return 0xffffffff;
Kojto 37:f1e388e7b752 161 }
Kojto 37:f1e388e7b752 162
Kojto 37:f1e388e7b752 163 uint32_t USBHALHost::interruptHeadED()
Kojto 37:f1e388e7b752 164 {
Kojto 37:f1e388e7b752 165 return 0xffffffff;
Kojto 37:f1e388e7b752 166 }
Kojto 37:f1e388e7b752 167
Kojto 37:f1e388e7b752 168 void USBHALHost::updateBulkHeadED(uint32_t addr)
Kojto 37:f1e388e7b752 169 {
Kojto 37:f1e388e7b752 170 }
Kojto 37:f1e388e7b752 171
Kojto 37:f1e388e7b752 172
Kojto 37:f1e388e7b752 173 void USBHALHost::updateControlHeadED(uint32_t addr)
Kojto 37:f1e388e7b752 174 {
Kojto 37:f1e388e7b752 175 }
Kojto 37:f1e388e7b752 176
Kojto 37:f1e388e7b752 177 void USBHALHost::updateInterruptHeadED(uint32_t addr)
Kojto 37:f1e388e7b752 178 {
Kojto 37:f1e388e7b752 179 }
Kojto 37:f1e388e7b752 180
Kojto 37:f1e388e7b752 181
Kojto 37:f1e388e7b752 182 void USBHALHost::enableList(ENDPOINT_TYPE type)
Kojto 37:f1e388e7b752 183 {
Kojto 37:f1e388e7b752 184 /* react when the 3 lists are requested to be disabled */
Kojto 37:f1e388e7b752 185 if (type == CONTROL_ENDPOINT) {
Kojto 37:f1e388e7b752 186 control_disable--;
Kojto 37:f1e388e7b752 187 if (control_disable == 0) {
Kojto 37:f1e388e7b752 188 NVIC_EnableIRQ(USBHAL_IRQn);
Kojto 37:f1e388e7b752 189 } else {
Kojto 37:f1e388e7b752 190 printf("reent\n");
Kojto 37:f1e388e7b752 191 }
Kojto 37:f1e388e7b752 192 }
Kojto 37:f1e388e7b752 193 }
Kojto 37:f1e388e7b752 194
Kojto 37:f1e388e7b752 195
Kojto 37:f1e388e7b752 196 bool USBHALHost::disableList(ENDPOINT_TYPE type)
Kojto 37:f1e388e7b752 197 {
Kojto 37:f1e388e7b752 198 if (type == CONTROL_ENDPOINT) {
Kojto 37:f1e388e7b752 199 NVIC_DisableIRQ(USBHAL_IRQn);
Kojto 37:f1e388e7b752 200 control_disable++;
Kojto 37:f1e388e7b752 201 if (control_disable > 1) {
Kojto 37:f1e388e7b752 202 printf("disable reentrance !!!\n");
Kojto 37:f1e388e7b752 203 }
Kojto 37:f1e388e7b752 204 return true;
Kojto 37:f1e388e7b752 205 }
Kojto 37:f1e388e7b752 206 return false;
Kojto 37:f1e388e7b752 207 }
Kojto 37:f1e388e7b752 208
Kojto 37:f1e388e7b752 209
Kojto 37:f1e388e7b752 210 void USBHALHost::memInit()
Kojto 37:f1e388e7b752 211 {
Kojto 37:f1e388e7b752 212 usb_hcca = (volatile HCD_HandleTypeDef *)usb_buf;
Kojto 37:f1e388e7b752 213 usb_edBuf = usb_buf + HCCA_SIZE;
Kojto 37:f1e388e7b752 214 usb_tdBuf = usb_buf + HCCA_SIZE +(MAX_ENDPOINT*ED_SIZE);
Kojto 37:f1e388e7b752 215 /* init channel */
Kojto 37:f1e388e7b752 216 memset((void*)usb_buf,0, TOTAL_SIZE);
Kojto 37:f1e388e7b752 217 for (int i=0; i < MAX_ENDPOINT; i++) {
Kojto 37:f1e388e7b752 218 HCED *hced = (HCED*)(usb_edBuf + i*ED_SIZE);
Kojto 37:f1e388e7b752 219 hced->ch_num = i;
Kojto 37:f1e388e7b752 220 hced->hhcd = (HCCA *) usb_hcca;
Kojto 37:f1e388e7b752 221 }
Kojto 37:f1e388e7b752 222 }
Kojto 37:f1e388e7b752 223
Kojto 37:f1e388e7b752 224 volatile uint8_t * USBHALHost::getED()
Kojto 37:f1e388e7b752 225 {
Kojto 37:f1e388e7b752 226 for (int i = 0; i < MAX_ENDPOINT; i++) {
Kojto 37:f1e388e7b752 227 if ( !edBufAlloc[i] ) {
Kojto 37:f1e388e7b752 228 edBufAlloc[i] = true;
Kojto 37:f1e388e7b752 229 return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
Kojto 37:f1e388e7b752 230 }
Kojto 37:f1e388e7b752 231 }
Kojto 37:f1e388e7b752 232 perror("Could not allocate ED\r\n");
Kojto 37:f1e388e7b752 233 return NULL; //Could not alloc ED
Kojto 37:f1e388e7b752 234 }
Kojto 37:f1e388e7b752 235
Kojto 37:f1e388e7b752 236 volatile uint8_t * USBHALHost::getTD()
Kojto 37:f1e388e7b752 237 {
Kojto 37:f1e388e7b752 238 int i;
Kojto 37:f1e388e7b752 239 for (i = 0; i < MAX_TD; i++) {
Kojto 37:f1e388e7b752 240 if ( !tdBufAlloc[i] ) {
Kojto 37:f1e388e7b752 241 tdBufAlloc[i] = true;
Kojto 37:f1e388e7b752 242 return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
Kojto 37:f1e388e7b752 243 }
Kojto 37:f1e388e7b752 244 }
Kojto 37:f1e388e7b752 245 perror("Could not allocate TD\r\n");
Kojto 37:f1e388e7b752 246 return NULL; //Could not alloc TD
Kojto 37:f1e388e7b752 247 }
Kojto 37:f1e388e7b752 248
Kojto 37:f1e388e7b752 249
Kojto 37:f1e388e7b752 250 void USBHALHost::freeED(volatile uint8_t * ed)
Kojto 37:f1e388e7b752 251 {
Kojto 37:f1e388e7b752 252 int i;
Kojto 37:f1e388e7b752 253 i = (ed - usb_edBuf) / ED_SIZE;
Kojto 37:f1e388e7b752 254 edBufAlloc[i] = false;
Kojto 37:f1e388e7b752 255 }
Kojto 37:f1e388e7b752 256
Kojto 37:f1e388e7b752 257 void USBHALHost::freeTD(volatile uint8_t * td)
Kojto 37:f1e388e7b752 258 {
Kojto 37:f1e388e7b752 259 int i;
Kojto 37:f1e388e7b752 260 i = (td - usb_tdBuf) / TD_SIZE;
Kojto 37:f1e388e7b752 261 tdBufAlloc[i] = false;
Kojto 37:f1e388e7b752 262 }
Kojto 37:f1e388e7b752 263
Kojto 37:f1e388e7b752 264
Kojto 37:f1e388e7b752 265 void USBHALHost::resetRootHub()
Kojto 37:f1e388e7b752 266 {
Kojto 37:f1e388e7b752 267 // Initiate port reset
Kojto 37:f1e388e7b752 268 wait(0.2);
Kojto 37:f1e388e7b752 269 HAL_HCD_ResetPort((HCD_HandleTypeDef *)usb_hcca);
Kojto 37:f1e388e7b752 270 }
Kojto 37:f1e388e7b752 271
Kojto 37:f1e388e7b752 272
Kojto 37:f1e388e7b752 273 void USBHALHost::_usbisr(void)
Kojto 37:f1e388e7b752 274 {
Kojto 37:f1e388e7b752 275 if (instHost) {
Kojto 37:f1e388e7b752 276 instHost->UsbIrqhandler();
Kojto 37:f1e388e7b752 277 }
Kojto 37:f1e388e7b752 278 }
Kojto 37:f1e388e7b752 279
Kojto 37:f1e388e7b752 280 void USBHALHost::UsbIrqhandler()
Kojto 37:f1e388e7b752 281 {
Kojto 37:f1e388e7b752 282 HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca);
Kojto 37:f1e388e7b752 283 }
Kojto 37:f1e388e7b752 284 #endif