Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768
Dependents: F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld
Fork of KL46Z-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 Wed Jul 13 2022 05:41:27 by 1.7.2