Usb read
Dependencies: FATFileSystem
Fork of F401RE-USBHost by
USBHost/USBHALHost_F401RE.cpp
- Committer:
- va009039
- Date:
- 2014-06-13
- Revision:
- 14:b167f2b97cb7
- Parent:
- 13:8774c07f12a5
- Child:
- 16:981c3104f6c0
File content as of revision 14:b167f2b97cb7:
// Simple USBHost for Nucleo F401RE #if defined(TARGET_NUCLEO_F401RE) #include "USBHALHost_F401RE.h" template <bool>struct CtAssert; template <>struct CtAssert<true> {}; #define CTASSERT(A) CtAssert<A>(); #ifdef _USB_DBG extern RawSerial pc; #include "mydebug.h" #define USB_DBG(...) do{pc.printf("[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);pc.printf(__VA_ARGS__);pc.puts("\n");} while(0); #define USB_DBG_HEX(A,B) debug_hex<RawSerial>(pc,A,B) #else #define USB_DBG(...) while(0) #define USB_DBG_HEX(A,B) while(0) #endif #ifdef _USB_TEST #define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; #define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A)) #else #define USB_TEST_ASSERT(A) while(0) #define USB_TEST_ASSERT_FALSE(A) while(0) #endif #ifdef _USB_TRACE #define USB_TRACE() while(0) #define USB_TRACE1(A) while(0) #define USB_TRACE_VIEW() while(0) #define USB_TRACE_CLEAR() while(0) #else #define USB_TRACE() while(0) #define USB_TRACE1(A) while(0) #define USB_TRACE_VIEW() while(0) #define USB_TRACE_CLEAR() while(0) #endif #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); __IO bool attach_done = false; __IO bool token_done = false; __IO HCD_URBStateTypeDef g_urb_state = URB_IDLE; void delay_ms(uint32_t t) { HAL_Delay(t); } // from usbh_conf.c extern HCD_HandleTypeDef hhcd_USB_OTG_FS; void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) { GPIO_InitTypeDef GPIO_InitStruct; if(hhcd->Instance==USB_OTG_FS) { /* Peripheral clock enable */ __USB_OTG_FS_CLK_ENABLE(); /**USB_OTG_FS GPIO Configuration PA11 ------> USB_OTG_FS_DM PA12 ------> USB_OTG_FS_DP */ GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Peripheral interrupt init*/ /* Sets the priority grouping field */ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); HAL_NVIC_EnableIRQ(OTG_FS_IRQn); } } // from stm32f4xx_it.c extern "C" { void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) { USB_TRACE(); attach_done = true; } void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) { USB_TRACE(); } void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) { USB_TRACE1(chnum); USB_TRACE1(urb_state); g_urb_state = urb_state; token_done = true; } } // extern "C" const int CH_CTL_IN = 0; const int CH_CTL_OUT = 1; const int CH_INT_IN = 2; const int CH_INT_OUT = 3; const int CH_BLK_IN = 4; const int CH_BLK_OUT = 5; const int CH_ISO_IN = 6; const int DIR_IN = 1; const int DIR_OUT = 0; USBHALHost* USBHALHost::instHost; USBHALHost::USBHALHost() { instHost = this; } void USBHALHost::init() { hhcd_USB_OTG_FS.Instance = USB_OTG_FS; hhcd_USB_OTG_FS.Init.Host_channels = 8; hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL; hhcd_USB_OTG_FS.Init.dma_enable = DISABLE; hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED; hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE; hhcd_USB_OTG_FS.Init.low_power_enable = ENABLE; hhcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; hhcd_USB_OTG_FS.Init.use_external_vbus = DISABLE; HAL_HCD_Init(&hhcd_USB_OTG_FS); HAL_HCD_Start(&hhcd_USB_OTG_FS); bool lowSpeed = wait_attach(); delay_ms(200); HAL_HCD_ResetPort(&hhcd_USB_OTG_FS); delay_ms(100); // Wait for 100 ms after Reset addDevice(NULL, 0, lowSpeed); } bool USBHALHost::wait_attach() { Timer t; t.reset(); t.start(); while(!attach_done) { if (t.read_ms() > 5*1000) { t.reset(); USB_INFO("Please attach USB device."); } } wait_ms(100); return HAL_HCD_GetCurrentSpeed(&hhcd_USB_OTG_FS) == USB_OTG_SPEED_LOW; } int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) { USBDeviceConnected* dev = ep->getDevice(); HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_CTRL, ep->getSize()); setup->wLength = wLength; HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 0, (uint8_t*)setup, 8, 0); while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE); switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) { case URB_DONE: LastStatus = ACK; break; default: LastStatus = 0xff; break; } ep->setData01(DATA1); return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_OUT); } HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest2(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t direction , uint8_t ep_type, uint8_t token, uint8_t* pbuff, uint16_t length, uint8_t do_ping) { HCD_HCTypeDef* hc = &(hhcd->hc[ch_num]); hc->ep_is_in = direction; hc->ep_type = ep_type; if (hc->toggle_in == 0) { hc->data_pid = HC_PID_DATA0; } else { hc->data_pid = HC_PID_DATA1; } hc->xfer_buff = pbuff; hc->xfer_len = length; hc->urb_state = URB_IDLE; hc->xfer_count = 0 ; hc->ch_num = ch_num; hc->state = HC_IDLE; return USB_HC_StartXfer(hhcd->Instance, hc, hhcd->Init.dma_enable); } int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { switch(ep->getType()) { case CONTROL_ENDPOINT: return token_ctl_in(ep, data, size, retryLimit); case INTERRUPT_ENDPOINT: return token_int_in(ep, data, size); case BULK_ENDPOINT: return token_blk_in(ep, data, size, retryLimit); } return -1; } int USBHALHost::token_ctl_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { USBDeviceConnected* dev = ep->getDevice(); HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_IN, 0x80, dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_CTRL, ep->getSize()); hhcd_USB_OTG_FS.hc[CH_CTL_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; HAL_HCD_HC_SubmitRequest2(&hhcd_USB_OTG_FS, CH_CTL_IN, DIR_IN, EP_TYPE_CTRL, 1, data, size, 0); while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN) == URB_IDLE); switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN)) { case URB_DONE: LastStatus = ACK; break; default: LastStatus = 0xff; return -1; } ep->toggleData01(); return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_IN); } int USBHALHost::token_int_in(USBEndpoint* ep, uint8_t* data, int size) { USBDeviceConnected* dev = ep->getDevice(); HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_IN, ep->getAddress(), dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_INTR, ep->getSize()); hhcd_USB_OTG_FS.hc[CH_INT_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_IN, DIR_IN, EP_TYPE_INTR, 1, data, size, 0); while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN) == URB_IDLE); switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN)) { case URB_DONE: switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_INT_IN)) { case HC_XFRC: LastStatus = ep->getData01(); ep->toggleData01(); return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_INT_IN); case HC_NAK: LastStatus = NAK; return -1; } break; } LastStatus = STALL; return -1; } int USBHALHost::token_blk_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { USBDeviceConnected* dev = ep->getDevice(); int retry = 0; do { HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_IN, ep->getAddress(), dev->getAddress(), HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize()); hhcd_USB_OTG_FS.hc[CH_BLK_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_IN, DIR_IN, EP_TYPE_BULK, 1, data, size, 0); while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN) == URB_IDLE); switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN)) { case URB_DONE: switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_IN)) { case HC_XFRC: LastStatus = ep->getData01(); ep->toggleData01(); return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_BLK_IN); case HC_NAK: LastStatus = NAK; if (retryLimit > 0) { delay_ms(1 + 10 * retry); } break; default: break; } break; case URB_STALL: LastStatus = STALL; return -1; default: LastStatus = STALL; delay_ms(500 + 100 * retry); break; } }while(retry++ < retryLimit); return -1; } int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { switch(ep->getType()) { case CONTROL_ENDPOINT: return token_ctl_out(ep, data, size, retryLimit); case INTERRUPT_ENDPOINT: return token_int_out(ep, data, size); case BULK_ENDPOINT: return token_blk_out(ep, data, size, retryLimit); } return -1; } int USBHALHost::token_ctl_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { USBDeviceConnected* dev = ep->getDevice(); HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_CTRL, ep->getSize()); hhcd_USB_OTG_FS.hc[CH_CTL_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; do { HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 1, (uint8_t*)data, size, 0); while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE); switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) { case URB_DONE: LastStatus = ACK; ep->toggleData01(); return size; default: break; } delay_ms(1); }while(retryLimit-- > 0); return -1; } int USBHALHost::token_int_out(USBEndpoint* ep, const uint8_t* data, int size) { USBDeviceConnected* dev = ep->getDevice(); HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_OUT, ep->getAddress(), dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_INTR, ep->getSize()); hhcd_USB_OTG_FS.hc[CH_INT_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; token_done = false; HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_OUT, DIR_OUT, EP_TYPE_INTR, 1, (uint8_t*)data, size, 0); while(!token_done); if (HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_OUT) != URB_DONE) { return -1; } ep->toggleData01(); return size; } int USBHALHost::token_blk_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { USBDeviceConnected* dev = ep->getDevice(); int retry = 0; do { HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_OUT, ep->getAddress(), dev->getAddress(), HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize()); hhcd_USB_OTG_FS.hc[CH_BLK_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_OUT, DIR_OUT, EP_TYPE_BULK, 1, (uint8_t*)data, size, 0); while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT) == URB_IDLE); switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) { case URB_DONE: switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) { case HC_XFRC: // ACK LastStatus = ep->getData01(); ep->toggleData01(); return size; default: break; } break; case URB_NOTREADY: // HC_NAK LastStatus = NAK; delay_ms(100 * retry); break; default: LastStatus = STALL; return -1; } } while(retry++ < retryLimit); return -1; } int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) { static bool init = false; if (!init) { init = true; USBDeviceConnected* dev = ep->getDevice(); HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_ISO_IN, ep->getAddress(), dev->getAddress(), HCD_SPEED_FULL, EP_TYPE_ISOC, ep->getSize()); } HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_ISO_IN, DIR_IN, EP_TYPE_ISOC, 1, data, size, 0); while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_ISO_IN) == URB_IDLE); return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_ISO_IN); } #endif