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