Pierre Provent / USBHost

Dependents:   TEST_USB_Nucleo_F429ZI Essais_USB_Nucleo_F429ZI SID_V3_Nucleo_F429ZI SID_V4_Nucleo_F429ZI_copy

Committer:
pierreprovent
Date:
Fri Sep 25 10:17:49 2020 +0000
Revision:
0:77ca32e8e04e
Programme acquisition en enregistrement sur clef USB carte Nucleo F429ZI cours ELE118 Cnam

Who changed what in which revision?

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