Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: STM32F407VET6_USBHostMSD STM32F407VET6_USBHostMouse STM32F407VET6_USBHostKeyboard STM32F407VET6_USBHostMSD_1
USBHALHost_F401RE.cpp
00001 #if defined(TARGET_NUCLEO_F401RE)||defined(TARGET_NUCLEO_F411RE)||defined(TARGET_NUCLEO_F446RE)||defined(TARGET_ARCH_MAX) 00002 #include "USBHALHost.h" 00003 #include <algorithm> 00004 00005 #ifdef _USB_DBG 00006 extern RawSerial pc; 00007 //RawSerial pc(USBTX,USBRX); 00008 #include "mydebug.h" 00009 #define USB_DBG(...) do{pc.printf("[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);pc.printf(__VA_ARGS__);pc.puts("\n");} while(0); 00010 #define USB_DBG_HEX(A,B) debug_hex<RawSerial>(pc,A,B) 00011 00012 #else 00013 #define USB_DBG(...) while(0) 00014 #define USB_DBG_HEX(A,B) while(0) 00015 #endif 00016 00017 #undef USB_TEST_ASSERT 00018 void usb_test_assert_internal(const char *expr, const char *file, int line); 00019 #define USB_TEST_ASSERT(EXPR) while(!(EXPR)){usb_test_assert_internal(#EXPR,__FILE__,__LINE__);} 00020 00021 #define USB_TRACE1(A) while(0) 00022 00023 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); 00024 00025 __IO bool attach_done = false; 00026 00027 void delay_ms(uint32_t t) 00028 { 00029 HAL_Delay(t); 00030 } 00031 00032 // usbh_conf.c 00033 extern HCD_HandleTypeDef hhcd_USB_OTG_FS; 00034 00035 void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) 00036 { 00037 GPIO_InitTypeDef GPIO_InitStruct; 00038 00039 if(hhcd->Instance == USB_OTG_FS) 00040 { 00041 /* 00042 * Configure USB FS GPIOs 00043 * PA11 ------> USB_OTG_FS_DM 00044 * PA12 ------> USB_OTG_FS_DP 00045 */ 00046 __HAL_RCC_GPIOA_CLK_ENABLE(); 00047 00048 GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); 00049 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 00050 GPIO_InitStruct.Pull = GPIO_NOPULL; 00051 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 00052 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; 00053 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 00054 00055 /* Enable USB FS Clocks */ 00056 __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); 00057 00058 /* Set USBFS Interrupt to the lowest priority */ 00059 HAL_NVIC_SetPriority(OTG_FS_IRQn, 5, 0); 00060 00061 /* Enable USBFS Interrupt */ 00062 HAL_NVIC_EnableIRQ(OTG_FS_IRQn); 00063 } 00064 00065 } 00066 00067 // stm32f4xx_it.c 00068 extern "C" { 00069 void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) 00070 { 00071 USB_TRACE1(hhcd); 00072 attach_done = true; 00073 } 00074 00075 } // extern "C" 00076 00077 USBHALHost* USBHALHost::instHost; 00078 00079 USBHALHost::USBHALHost() { 00080 instHost = this; 00081 } 00082 00083 void USBHALHost::init() { 00084 hhcd_USB_OTG_FS.Instance = USB_OTG_FS; 00085 hhcd_USB_OTG_FS.Init.Host_channels = 8; 00086 hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL; 00087 hhcd_USB_OTG_FS.Init.dma_enable = DISABLE; 00088 hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED; 00089 hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE; 00090 hhcd_USB_OTG_FS.Init.low_power_enable = ENABLE; 00091 hhcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; 00092 hhcd_USB_OTG_FS.Init.use_external_vbus = DISABLE; 00093 00094 HAL_HCD_Init(&hhcd_USB_OTG_FS); 00095 HAL_HCD_Start(&hhcd_USB_OTG_FS); 00096 00097 bool lowSpeed = wait_attach(); 00098 delay_ms(200); 00099 HAL_HCD_ResetPort(&hhcd_USB_OTG_FS); 00100 delay_ms(100); // Wait for 100 ms after Reset 00101 addDevice(NULL, 0, lowSpeed); 00102 } 00103 00104 bool USBHALHost::wait_attach() { 00105 Timer t; 00106 t.reset(); 00107 t.start(); 00108 while(!attach_done) { 00109 if (t.read_ms() > 5*1000) { 00110 t.reset(); 00111 USB_INFO("Please attach USB device."); 00112 } 00113 } 00114 wait_ms(100); 00115 return HAL_HCD_GetCurrentSpeed(&hhcd_USB_OTG_FS) == USB_OTG_SPEED_LOW; 00116 } 00117 00118 int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) { 00119 const uint8_t ep_addr = 0x00; 00120 HC hc; 00121 USBDeviceConnected* dev = ep->getDevice(); 00122 hc.Init(ep_addr, 00123 dev->getAddress(), 00124 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, 00125 EP_TYPE_CTRL, ep->getSize()); 00126 00127 setup->wLength = wLength; 00128 hc.SubmitRequest((uint8_t*)setup, 8, true); // PID_SETUP 00129 while(hc.GetURBState() == URB_IDLE); 00130 00131 switch(hc.GetURBState()) { 00132 case URB_DONE: 00133 LastStatus = ACK; 00134 break; 00135 default: 00136 LastStatus = 0xff; 00137 break; 00138 } 00139 ep->setData01(DATA1); 00140 return 8; 00141 } 00142 00143 int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { 00144 switch(ep->getType()) { 00145 case CONTROL_ENDPOINT: 00146 return token_ctl_in(ep, data, size, retryLimit); 00147 case INTERRUPT_ENDPOINT: 00148 return token_int_in(ep, data, size); 00149 case BULK_ENDPOINT: 00150 return token_blk_in(ep, data, size, retryLimit); 00151 } 00152 return -1; 00153 } 00154 00155 int USBHALHost::token_ctl_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { 00156 const uint8_t ep_addr = 0x80; 00157 HC hc; 00158 USBDeviceConnected* dev = ep->getDevice(); 00159 hc.Init(ep_addr, 00160 dev->getAddress(), 00161 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, 00162 EP_TYPE_CTRL, ep->getSize()); 00163 00164 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); 00165 00166 hc.SubmitRequest(data, size); 00167 while(hc.GetURBState() == URB_IDLE); 00168 00169 switch(hc.GetURBState()) { 00170 case URB_DONE: 00171 LastStatus = ACK; 00172 break; 00173 default: 00174 LastStatus = 0xff; 00175 return -1; 00176 } 00177 ep->toggleData01(); 00178 return hc.GetXferCount(); 00179 } 00180 00181 int USBHALHost::token_int_in(USBEndpoint* ep, uint8_t* data, int size) { 00182 HC hc; 00183 USBDeviceConnected* dev = ep->getDevice(); 00184 hc.Init( 00185 ep->getAddress(), 00186 dev->getAddress(), 00187 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, 00188 EP_TYPE_INTR, ep->getSize()); 00189 00190 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); 00191 00192 hc.SubmitRequest(data, size); 00193 //while(hc.GetURBState() == URB_IDLE); 00194 wait_ms(2); 00195 switch(hc.GetURBState()) { 00196 case URB_DONE: 00197 switch(hc.GetState()) { 00198 case HC_XFRC: 00199 LastStatus = ep->getData01(); 00200 ep->toggleData01(); 00201 return hc.GetXferCount(); 00202 case HC_NAK: 00203 LastStatus = NAK; 00204 return -1; 00205 } 00206 break; 00207 } 00208 LastStatus = STALL; 00209 return -1; 00210 } 00211 00212 int USBHALHost::token_blk_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { 00213 HC hc; 00214 USBDeviceConnected* dev = ep->getDevice(); 00215 hc.Init( 00216 ep->getAddress(), 00217 dev->getAddress(), 00218 HCD_SPEED_FULL, 00219 EP_TYPE_BULK, ep->getSize()); 00220 00221 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); 00222 00223 int retry = 0; 00224 do { 00225 hc.SubmitRequest(data, size); 00226 while(hc.GetURBState() == URB_IDLE); 00227 00228 switch(hc.GetURBState()) { 00229 case URB_DONE: 00230 switch(hc.GetState()) { 00231 case HC_XFRC: 00232 LastStatus = ep->getData01(); 00233 ep->toggleData01(); 00234 return hc.GetXferCount(); 00235 case HC_NAK: 00236 LastStatus = NAK; 00237 if (retryLimit > 0) { 00238 delay_ms(1 + 10 * retry); 00239 } 00240 break; 00241 default: 00242 break; 00243 } 00244 break; 00245 case URB_STALL: 00246 LastStatus = STALL; 00247 return -1; 00248 default: 00249 LastStatus = STALL; 00250 delay_ms(500 + 100 * retry); 00251 break; 00252 } 00253 }while(retry++ < retryLimit); 00254 return -1; 00255 } 00256 00257 int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { 00258 switch(ep->getType()) { 00259 case CONTROL_ENDPOINT: 00260 return token_ctl_out(ep, data, size, retryLimit); 00261 case INTERRUPT_ENDPOINT: 00262 return token_int_out(ep, data, size); 00263 case BULK_ENDPOINT: 00264 return token_blk_out(ep, data, size, retryLimit); 00265 } 00266 return -1; 00267 } 00268 00269 int USBHALHost::token_ctl_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { 00270 const uint8_t ep_addr = 0x00; 00271 HC hc; 00272 USBDeviceConnected* dev = ep->getDevice(); 00273 hc.Init(ep_addr, 00274 dev->getAddress(), 00275 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, 00276 EP_TYPE_CTRL, ep->getSize()); 00277 00278 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); 00279 00280 do { 00281 hc.SubmitRequest((uint8_t*)data, size); 00282 while(hc.GetURBState() == URB_IDLE); 00283 00284 switch(hc.GetURBState()) { 00285 case URB_DONE: 00286 LastStatus = ACK; 00287 ep->toggleData01(); 00288 return size; 00289 00290 default: 00291 break; 00292 } 00293 delay_ms(1); 00294 }while(retryLimit-- > 0); 00295 return -1; 00296 } 00297 00298 int USBHALHost::token_int_out(USBEndpoint* ep, const uint8_t* data, int size) { 00299 HC hc; 00300 USBDeviceConnected* dev = ep->getDevice(); 00301 hc.Init( 00302 ep->getAddress(), 00303 dev->getAddress(), 00304 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, 00305 EP_TYPE_INTR, ep->getSize()); 00306 00307 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); 00308 00309 hc.SubmitRequest((uint8_t*)data, size); 00310 while(hc.GetURBState() == URB_IDLE); 00311 if (hc.GetURBState() != URB_DONE) { 00312 return -1; 00313 } 00314 ep->toggleData01(); 00315 return size; 00316 } 00317 00318 int USBHALHost::token_blk_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { 00319 HC hc; 00320 USBDeviceConnected* dev = ep->getDevice(); 00321 hc.Init( 00322 ep->getAddress(), dev->getAddress(), 00323 HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize()); 00324 00325 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); 00326 00327 int retry = 0; 00328 do { 00329 hc.SubmitRequest((uint8_t*)data, size); 00330 while(hc.GetURBState() == URB_IDLE); 00331 00332 switch(hc.GetURBState()) { 00333 case URB_DONE: 00334 switch(hc.GetState()) { 00335 case HC_XFRC: // ACK 00336 LastStatus = ep->getData01(); 00337 ep->toggleData01(); 00338 return size; 00339 default: 00340 break; 00341 } 00342 break; 00343 case URB_NOTREADY: // HC_NAK 00344 LastStatus = NAK; 00345 delay_ms(100 * retry); 00346 break; 00347 default: 00348 LastStatus = STALL; 00349 return -1; 00350 } 00351 } while(retry++ < retryLimit); 00352 return -1; 00353 } 00354 00355 int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) { 00356 HC* hc = ep->getHALData<HC*>(); 00357 if (hc == NULL) { 00358 hc = new HC; 00359 ep->setHALData<HC*>(hc); 00360 USBDeviceConnected* dev = ep->getDevice(); 00361 hc->Init( 00362 ep->getAddress(), dev->getAddress(), 00363 HCD_SPEED_FULL, EP_TYPE_ISOC, ep->getSize()); 00364 } 00365 hc->SubmitRequest(data, size); 00366 while(hc->GetURBState() == URB_IDLE); 00367 return hc->GetXferCount(); 00368 } 00369 00370 int USBHALHost::multi_token_in(USBEndpoint* ep, uint8_t* data, size_t total, bool block) { 00371 if (total == 0) { 00372 return token_in(ep); 00373 } 00374 int retryLimit = block ? 10 : 0; 00375 int read_len = 0; 00376 for(int n = 0; read_len < total; n++) { 00377 int size = std::min((int)total-read_len, ep->getSize()); 00378 int result = token_in(ep, data+read_len, size, retryLimit); 00379 if (result < 0) { 00380 if (block) { 00381 return -1; 00382 } 00383 if (LastStatus == NAK) { 00384 if (n == 0) { 00385 return -1; 00386 } 00387 break; 00388 } 00389 return result; 00390 } 00391 read_len += result; 00392 if (result < ep->getSize()) { 00393 break; 00394 } 00395 } 00396 return read_len; 00397 } 00398 00399 int USBHALHost::multi_token_out(USBEndpoint* ep, const uint8_t* data, size_t total) { 00400 if (total == 0) { 00401 return token_out(ep); 00402 } 00403 int write_len = 0; 00404 for(int n = 0; write_len < total; n++) { 00405 int size = std::min((int)total-write_len, ep->getSize()); 00406 int result = token_out(ep, data+write_len, size); 00407 if (result < 0) { 00408 if (LastStatus == NAK) { 00409 if (n == 0) { 00410 return -1; 00411 } 00412 break; 00413 } 00414 USB_DBG("token_out result=%d %02x", result, LastStatus); 00415 return result; 00416 } 00417 write_len += result; 00418 if (result < ep->getSize()) { 00419 break; 00420 } 00421 } 00422 return write_len; 00423 } 00424 void USBHALHost::multi_token_inNB(USBEndpoint* ep, uint8_t* data, int size) { 00425 USB_TRACE1(size); 00426 USB_TEST_ASSERT(ep->getState() != USB_TYPE_PROCESSING); 00427 ep->setBuffer(data, size); 00428 ep->setState(USB_TYPE_PROCESSING); 00429 } 00430 00431 USB_TYPE USBHALHost::multi_token_inNB_result(USBEndpoint* ep) { 00432 USB_TEST_ASSERT(ep->getState() == USB_TYPE_PROCESSING); 00433 uint8_t* buf = ep->getBufStart(); 00434 int size = ep->getBufSize(); 00435 int result = multi_token_in(ep, buf, size, false); 00436 USB_TRACE1(result); 00437 if (result < 0) { 00438 return USB_TYPE_PROCESSING; 00439 } 00440 ep->setLengthTransferred(result); 00441 ep->setState(USB_TYPE_IDLE); 00442 return USB_TYPE_OK; 00443 00444 } 00445 00446 void USBHALHost::setToggle(USBEndpoint* ep, uint8_t toggle) { 00447 USB_TEST_ASSERT(toggle == 1); 00448 ep->setData01(toggle == 0 ? DATA0 : DATA1); 00449 } 00450 00451 uint8_t HC::slot = 0x00; 00452 00453 HC::HC() { 00454 static const int start = 1; 00455 uint8_t mask = (1<<start); 00456 for(int i = start; i < 8; i++, mask <<= 1) { 00457 if (!(slot & mask)) { 00458 slot |= mask; 00459 _ch = i; 00460 return; 00461 } 00462 } 00463 _ch = 0; // ERROR!!! 00464 } 00465 00466 HC::HC(int ch) { 00467 _ch = ch; 00468 slot |= (1<<_ch); 00469 } 00470 00471 HC::~HC() { 00472 slot &= ~(1<<_ch); 00473 } 00474 00475 HAL_StatusTypeDef HC::Init(uint8_t epnum, uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps) { 00476 _ep_addr = epnum; 00477 _ep_type = ep_type; 00478 return HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, _ch, 00479 epnum, dev_address, speed, ep_type, mps); 00480 } 00481 00482 HAL_StatusTypeDef HC::SubmitRequest(uint8_t* pbuff, uint16_t length, bool setup) { 00483 uint8_t direction = (_ep_addr & 0x80) ? DIR_IN : DIR_OUT; 00484 if (_ep_type == EP_TYPE_CTRL) { 00485 HCD_HCTypeDef* hc = &hhcd_USB_OTG_FS.hc[_ch]; 00486 if (setup) { 00487 hc->data_pid = HC_PID_SETUP; 00488 hc->toggle_out = 0; 00489 } else { 00490 if (direction == DIR_IN) { 00491 if (hc->toggle_in == 0) { 00492 hc->data_pid = HC_PID_DATA0; 00493 } else { 00494 hc->data_pid = HC_PID_DATA1; 00495 } 00496 } else { // OUT 00497 if (hc->toggle_out == 0) { 00498 hc->data_pid = HC_PID_DATA0; 00499 } else { 00500 hc->data_pid = HC_PID_DATA1; 00501 } 00502 } 00503 } 00504 hc->xfer_buff = pbuff; 00505 hc->xfer_len = length; 00506 hc->urb_state = URB_IDLE; 00507 hc->xfer_count = 0; 00508 hc->ch_num = _ch; 00509 hc->state = HC_IDLE; 00510 00511 return USB_HC_StartXfer(hhcd_USB_OTG_FS.Instance, hc, 0); 00512 } 00513 return HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, _ch, 00514 direction, _ep_type, 0, pbuff, length, 0); 00515 } 00516 00517 HCD_URBStateTypeDef HC::GetURBState() { 00518 return HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, _ch); 00519 } 00520 00521 HCD_HCStateTypeDef HC::GetState() { 00522 return HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, _ch); 00523 } 00524 00525 uint32_t HC::GetXferCount() { 00526 return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, _ch); 00527 } 00528 00529 void HC::SetToggle(uint8_t toggle) { 00530 if (_ep_addr & 0x80) { // IN 00531 hhcd_USB_OTG_FS.hc[_ch].toggle_in = toggle; 00532 } else { // OUT 00533 hhcd_USB_OTG_FS.hc[_ch].toggle_out = toggle; 00534 } 00535 } 00536 00537 #endif 00538 00539
Generated on Wed Jul 13 2022 07:15:48 by
