USB Host Driver with Socket Modem support. Works with revision 323 of mbed-src but broken with any later version.
Dependencies: FATFileSystem
Fork of F401RE-USBHost by
USBHost/USBHALHost_F401RE.cpp@14:b167f2b97cb7, 2014-06-13 (annotated)
- Committer:
- va009039
- Date:
- Fri Jun 13 08:21:22 2014 +0900
- Revision:
- 14:b167f2b97cb7
- Parent:
- 13:8774c07f12a5
- Child:
- 16:981c3104f6c0
fix token out.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 11:61843badd06e | 1 | // Simple USBHost for Nucleo F401RE |
va009039 | 11:61843badd06e | 2 | #if defined(TARGET_NUCLEO_F401RE) |
va009039 | 11:61843badd06e | 3 | #include "USBHALHost_F401RE.h" |
va009039 | 11:61843badd06e | 4 | |
va009039 | 11:61843badd06e | 5 | template <bool>struct CtAssert; |
va009039 | 11:61843badd06e | 6 | template <>struct CtAssert<true> {}; |
va009039 | 11:61843badd06e | 7 | #define CTASSERT(A) CtAssert<A>(); |
va009039 | 11:61843badd06e | 8 | |
va009039 | 11:61843badd06e | 9 | |
va009039 | 11:61843badd06e | 10 | #ifdef _USB_DBG |
va009039 | 11:61843badd06e | 11 | extern RawSerial pc; |
va009039 | 11:61843badd06e | 12 | #include "mydebug.h" |
va009039 | 11:61843badd06e | 13 | #define USB_DBG(...) do{pc.printf("[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);pc.printf(__VA_ARGS__);pc.puts("\n");} while(0); |
va009039 | 11:61843badd06e | 14 | #define USB_DBG_HEX(A,B) debug_hex<RawSerial>(pc,A,B) |
va009039 | 11:61843badd06e | 15 | |
va009039 | 11:61843badd06e | 16 | #else |
va009039 | 11:61843badd06e | 17 | #define USB_DBG(...) while(0) |
va009039 | 11:61843badd06e | 18 | #define USB_DBG_HEX(A,B) while(0) |
va009039 | 11:61843badd06e | 19 | #endif |
va009039 | 11:61843badd06e | 20 | |
va009039 | 11:61843badd06e | 21 | #ifdef _USB_TEST |
va009039 | 11:61843badd06e | 22 | #define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; |
va009039 | 11:61843badd06e | 23 | #define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A)) |
va009039 | 11:61843badd06e | 24 | #else |
va009039 | 11:61843badd06e | 25 | #define USB_TEST_ASSERT(A) while(0) |
va009039 | 11:61843badd06e | 26 | #define USB_TEST_ASSERT_FALSE(A) while(0) |
va009039 | 11:61843badd06e | 27 | #endif |
va009039 | 11:61843badd06e | 28 | |
va009039 | 11:61843badd06e | 29 | #ifdef _USB_TRACE |
va009039 | 11:61843badd06e | 30 | #define USB_TRACE() while(0) |
va009039 | 11:61843badd06e | 31 | #define USB_TRACE1(A) while(0) |
va009039 | 11:61843badd06e | 32 | #define USB_TRACE_VIEW() while(0) |
va009039 | 11:61843badd06e | 33 | #define USB_TRACE_CLEAR() while(0) |
va009039 | 11:61843badd06e | 34 | #else |
va009039 | 11:61843badd06e | 35 | #define USB_TRACE() while(0) |
va009039 | 11:61843badd06e | 36 | #define USB_TRACE1(A) while(0) |
va009039 | 11:61843badd06e | 37 | #define USB_TRACE_VIEW() while(0) |
va009039 | 11:61843badd06e | 38 | #define USB_TRACE_CLEAR() while(0) |
va009039 | 11:61843badd06e | 39 | #endif |
va009039 | 11:61843badd06e | 40 | |
va009039 | 11:61843badd06e | 41 | #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); |
va009039 | 11:61843badd06e | 42 | |
va009039 | 11:61843badd06e | 43 | __IO bool attach_done = false; |
va009039 | 11:61843badd06e | 44 | __IO bool token_done = false; |
va009039 | 11:61843badd06e | 45 | __IO HCD_URBStateTypeDef g_urb_state = URB_IDLE; |
va009039 | 11:61843badd06e | 46 | |
va009039 | 11:61843badd06e | 47 | void delay_ms(uint32_t t) |
va009039 | 11:61843badd06e | 48 | { |
va009039 | 11:61843badd06e | 49 | HAL_Delay(t); |
va009039 | 11:61843badd06e | 50 | } |
va009039 | 11:61843badd06e | 51 | |
va009039 | 11:61843badd06e | 52 | // from usbh_conf.c |
va009039 | 11:61843badd06e | 53 | extern HCD_HandleTypeDef hhcd_USB_OTG_FS; |
va009039 | 11:61843badd06e | 54 | |
va009039 | 11:61843badd06e | 55 | void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) |
va009039 | 11:61843badd06e | 56 | { |
va009039 | 11:61843badd06e | 57 | GPIO_InitTypeDef GPIO_InitStruct; |
va009039 | 11:61843badd06e | 58 | if(hhcd->Instance==USB_OTG_FS) |
va009039 | 11:61843badd06e | 59 | { |
va009039 | 11:61843badd06e | 60 | /* Peripheral clock enable */ |
va009039 | 11:61843badd06e | 61 | __USB_OTG_FS_CLK_ENABLE(); |
va009039 | 11:61843badd06e | 62 | |
va009039 | 11:61843badd06e | 63 | /**USB_OTG_FS GPIO Configuration |
va009039 | 11:61843badd06e | 64 | PA11 ------> USB_OTG_FS_DM |
va009039 | 11:61843badd06e | 65 | PA12 ------> USB_OTG_FS_DP |
va009039 | 11:61843badd06e | 66 | */ |
va009039 | 11:61843badd06e | 67 | GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; |
va009039 | 11:61843badd06e | 68 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; |
va009039 | 11:61843badd06e | 69 | GPIO_InitStruct.Pull = GPIO_NOPULL; |
va009039 | 11:61843badd06e | 70 | GPIO_InitStruct.Speed = GPIO_SPEED_LOW; |
va009039 | 11:61843badd06e | 71 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; |
va009039 | 11:61843badd06e | 72 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); |
va009039 | 11:61843badd06e | 73 | |
va009039 | 11:61843badd06e | 74 | /* Peripheral interrupt init*/ |
va009039 | 11:61843badd06e | 75 | /* Sets the priority grouping field */ |
va009039 | 11:61843badd06e | 76 | HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); |
va009039 | 11:61843badd06e | 77 | HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); |
va009039 | 11:61843badd06e | 78 | HAL_NVIC_EnableIRQ(OTG_FS_IRQn); |
va009039 | 11:61843badd06e | 79 | } |
va009039 | 11:61843badd06e | 80 | } |
va009039 | 11:61843badd06e | 81 | |
va009039 | 11:61843badd06e | 82 | // from stm32f4xx_it.c |
va009039 | 11:61843badd06e | 83 | extern "C" { |
va009039 | 11:61843badd06e | 84 | void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) |
va009039 | 11:61843badd06e | 85 | { |
va009039 | 11:61843badd06e | 86 | USB_TRACE(); |
va009039 | 11:61843badd06e | 87 | attach_done = true; |
va009039 | 11:61843badd06e | 88 | } |
va009039 | 11:61843badd06e | 89 | |
va009039 | 11:61843badd06e | 90 | void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) |
va009039 | 11:61843badd06e | 91 | { |
va009039 | 11:61843badd06e | 92 | USB_TRACE(); |
va009039 | 11:61843badd06e | 93 | } |
va009039 | 11:61843badd06e | 94 | |
va009039 | 11:61843badd06e | 95 | void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) |
va009039 | 11:61843badd06e | 96 | { |
va009039 | 11:61843badd06e | 97 | USB_TRACE1(chnum); |
va009039 | 11:61843badd06e | 98 | USB_TRACE1(urb_state); |
va009039 | 11:61843badd06e | 99 | g_urb_state = urb_state; |
va009039 | 11:61843badd06e | 100 | token_done = true; |
va009039 | 11:61843badd06e | 101 | } |
va009039 | 11:61843badd06e | 102 | |
va009039 | 11:61843badd06e | 103 | } // extern "C" |
va009039 | 11:61843badd06e | 104 | |
va009039 | 11:61843badd06e | 105 | const int CH_CTL_IN = 0; |
va009039 | 11:61843badd06e | 106 | const int CH_CTL_OUT = 1; |
va009039 | 11:61843badd06e | 107 | const int CH_INT_IN = 2; |
va009039 | 11:61843badd06e | 108 | const int CH_INT_OUT = 3; |
va009039 | 11:61843badd06e | 109 | const int CH_BLK_IN = 4; |
va009039 | 11:61843badd06e | 110 | const int CH_BLK_OUT = 5; |
va009039 | 11:61843badd06e | 111 | const int CH_ISO_IN = 6; |
va009039 | 11:61843badd06e | 112 | const int DIR_IN = 1; |
va009039 | 11:61843badd06e | 113 | const int DIR_OUT = 0; |
va009039 | 11:61843badd06e | 114 | |
va009039 | 11:61843badd06e | 115 | |
va009039 | 11:61843badd06e | 116 | |
va009039 | 11:61843badd06e | 117 | USBHALHost* USBHALHost::instHost; |
va009039 | 11:61843badd06e | 118 | |
va009039 | 11:61843badd06e | 119 | USBHALHost::USBHALHost() { |
va009039 | 11:61843badd06e | 120 | instHost = this; |
va009039 | 11:61843badd06e | 121 | } |
va009039 | 11:61843badd06e | 122 | |
va009039 | 11:61843badd06e | 123 | void USBHALHost::init() { |
va009039 | 11:61843badd06e | 124 | hhcd_USB_OTG_FS.Instance = USB_OTG_FS; |
va009039 | 11:61843badd06e | 125 | hhcd_USB_OTG_FS.Init.Host_channels = 8; |
va009039 | 11:61843badd06e | 126 | hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL; |
va009039 | 11:61843badd06e | 127 | hhcd_USB_OTG_FS.Init.dma_enable = DISABLE; |
va009039 | 11:61843badd06e | 128 | hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED; |
va009039 | 11:61843badd06e | 129 | hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE; |
va009039 | 11:61843badd06e | 130 | hhcd_USB_OTG_FS.Init.low_power_enable = ENABLE; |
va009039 | 11:61843badd06e | 131 | hhcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; |
va009039 | 11:61843badd06e | 132 | hhcd_USB_OTG_FS.Init.use_external_vbus = DISABLE; |
va009039 | 11:61843badd06e | 133 | |
va009039 | 11:61843badd06e | 134 | HAL_HCD_Init(&hhcd_USB_OTG_FS); |
va009039 | 11:61843badd06e | 135 | HAL_HCD_Start(&hhcd_USB_OTG_FS); |
va009039 | 11:61843badd06e | 136 | |
va009039 | 11:61843badd06e | 137 | bool lowSpeed = wait_attach(); |
va009039 | 11:61843badd06e | 138 | delay_ms(200); |
va009039 | 11:61843badd06e | 139 | HAL_HCD_ResetPort(&hhcd_USB_OTG_FS); |
va009039 | 11:61843badd06e | 140 | delay_ms(100); // Wait for 100 ms after Reset |
va009039 | 11:61843badd06e | 141 | addDevice(NULL, 0, lowSpeed); |
va009039 | 11:61843badd06e | 142 | } |
va009039 | 11:61843badd06e | 143 | |
va009039 | 11:61843badd06e | 144 | bool USBHALHost::wait_attach() { |
va009039 | 11:61843badd06e | 145 | Timer t; |
va009039 | 11:61843badd06e | 146 | t.reset(); |
va009039 | 11:61843badd06e | 147 | t.start(); |
va009039 | 11:61843badd06e | 148 | while(!attach_done) { |
va009039 | 11:61843badd06e | 149 | if (t.read_ms() > 5*1000) { |
va009039 | 11:61843badd06e | 150 | t.reset(); |
va009039 | 11:61843badd06e | 151 | USB_INFO("Please attach USB device."); |
va009039 | 11:61843badd06e | 152 | } |
va009039 | 11:61843badd06e | 153 | } |
va009039 | 11:61843badd06e | 154 | wait_ms(100); |
va009039 | 11:61843badd06e | 155 | return HAL_HCD_GetCurrentSpeed(&hhcd_USB_OTG_FS) == USB_OTG_SPEED_LOW; |
va009039 | 11:61843badd06e | 156 | } |
va009039 | 11:61843badd06e | 157 | |
va009039 | 11:61843badd06e | 158 | int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) { |
va009039 | 11:61843badd06e | 159 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 | 11:61843badd06e | 160 | |
va009039 | 11:61843badd06e | 161 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, |
va009039 | 11:61843badd06e | 162 | dev->getAddress(), |
va009039 | 11:61843badd06e | 163 | dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, |
va009039 | 11:61843badd06e | 164 | EP_TYPE_CTRL, ep->getSize()); |
va009039 | 11:61843badd06e | 165 | |
va009039 | 11:61843badd06e | 166 | setup->wLength = wLength; |
va009039 | 11:61843badd06e | 167 | |
va009039 | 11:61843badd06e | 168 | HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 0, (uint8_t*)setup, 8, 0); |
va009039 | 11:61843badd06e | 169 | while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE); |
va009039 | 11:61843badd06e | 170 | |
va009039 | 11:61843badd06e | 171 | switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) { |
va009039 | 11:61843badd06e | 172 | case URB_DONE: |
va009039 | 11:61843badd06e | 173 | LastStatus = ACK; |
va009039 | 11:61843badd06e | 174 | break; |
va009039 | 11:61843badd06e | 175 | default: |
va009039 | 11:61843badd06e | 176 | LastStatus = 0xff; |
va009039 | 11:61843badd06e | 177 | break; |
va009039 | 11:61843badd06e | 178 | } |
va009039 | 11:61843badd06e | 179 | ep->setData01(DATA1); |
va009039 | 11:61843badd06e | 180 | return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_OUT); |
va009039 | 11:61843badd06e | 181 | } |
va009039 | 11:61843badd06e | 182 | |
va009039 | 11:61843badd06e | 183 | HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest2(HCD_HandleTypeDef *hhcd, |
va009039 | 11:61843badd06e | 184 | uint8_t ch_num, |
va009039 | 11:61843badd06e | 185 | uint8_t direction , |
va009039 | 11:61843badd06e | 186 | uint8_t ep_type, |
va009039 | 11:61843badd06e | 187 | uint8_t token, |
va009039 | 11:61843badd06e | 188 | uint8_t* pbuff, |
va009039 | 11:61843badd06e | 189 | uint16_t length, |
va009039 | 11:61843badd06e | 190 | uint8_t do_ping) |
va009039 | 11:61843badd06e | 191 | { |
va009039 | 11:61843badd06e | 192 | HCD_HCTypeDef* hc = &(hhcd->hc[ch_num]); |
va009039 | 11:61843badd06e | 193 | hc->ep_is_in = direction; |
va009039 | 11:61843badd06e | 194 | hc->ep_type = ep_type; |
va009039 | 11:61843badd06e | 195 | |
va009039 | 11:61843badd06e | 196 | if (hc->toggle_in == 0) { |
va009039 | 11:61843badd06e | 197 | hc->data_pid = HC_PID_DATA0; |
va009039 | 11:61843badd06e | 198 | } else { |
va009039 | 11:61843badd06e | 199 | hc->data_pid = HC_PID_DATA1; |
va009039 | 11:61843badd06e | 200 | } |
va009039 | 11:61843badd06e | 201 | |
va009039 | 11:61843badd06e | 202 | hc->xfer_buff = pbuff; |
va009039 | 11:61843badd06e | 203 | hc->xfer_len = length; |
va009039 | 11:61843badd06e | 204 | hc->urb_state = URB_IDLE; |
va009039 | 11:61843badd06e | 205 | hc->xfer_count = 0 ; |
va009039 | 11:61843badd06e | 206 | hc->ch_num = ch_num; |
va009039 | 11:61843badd06e | 207 | hc->state = HC_IDLE; |
va009039 | 11:61843badd06e | 208 | |
va009039 | 11:61843badd06e | 209 | return USB_HC_StartXfer(hhcd->Instance, hc, hhcd->Init.dma_enable); |
va009039 | 11:61843badd06e | 210 | } |
va009039 | 11:61843badd06e | 211 | |
va009039 | 11:61843badd06e | 212 | int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { |
va009039 | 11:61843badd06e | 213 | switch(ep->getType()) { |
va009039 | 11:61843badd06e | 214 | case CONTROL_ENDPOINT: |
va009039 | 11:61843badd06e | 215 | return token_ctl_in(ep, data, size, retryLimit); |
va009039 | 11:61843badd06e | 216 | case INTERRUPT_ENDPOINT: |
va009039 | 11:61843badd06e | 217 | return token_int_in(ep, data, size); |
va009039 | 11:61843badd06e | 218 | case BULK_ENDPOINT: |
va009039 | 11:61843badd06e | 219 | return token_blk_in(ep, data, size, retryLimit); |
va009039 | 11:61843badd06e | 220 | } |
va009039 | 11:61843badd06e | 221 | return -1; |
va009039 | 11:61843badd06e | 222 | } |
va009039 | 11:61843badd06e | 223 | |
va009039 | 11:61843badd06e | 224 | int USBHALHost::token_ctl_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { |
va009039 | 11:61843badd06e | 225 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 | 11:61843badd06e | 226 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_IN, 0x80, |
va009039 | 11:61843badd06e | 227 | dev->getAddress(), |
va009039 | 11:61843badd06e | 228 | dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, |
va009039 | 11:61843badd06e | 229 | EP_TYPE_CTRL, ep->getSize()); |
va009039 | 11:61843badd06e | 230 | hhcd_USB_OTG_FS.hc[CH_CTL_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; |
va009039 | 11:61843badd06e | 231 | |
va009039 | 11:61843badd06e | 232 | HAL_HCD_HC_SubmitRequest2(&hhcd_USB_OTG_FS, CH_CTL_IN, DIR_IN, EP_TYPE_CTRL, 1, data, size, 0); |
va009039 | 11:61843badd06e | 233 | while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN) == URB_IDLE); |
va009039 | 11:61843badd06e | 234 | |
va009039 | 11:61843badd06e | 235 | switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN)) { |
va009039 | 11:61843badd06e | 236 | case URB_DONE: |
va009039 | 11:61843badd06e | 237 | LastStatus = ACK; |
va009039 | 11:61843badd06e | 238 | break; |
va009039 | 11:61843badd06e | 239 | default: |
va009039 | 11:61843badd06e | 240 | LastStatus = 0xff; |
va009039 | 11:61843badd06e | 241 | return -1; |
va009039 | 11:61843badd06e | 242 | } |
va009039 | 11:61843badd06e | 243 | ep->toggleData01(); |
va009039 | 11:61843badd06e | 244 | return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_IN); |
va009039 | 11:61843badd06e | 245 | } |
va009039 | 11:61843badd06e | 246 | |
va009039 | 11:61843badd06e | 247 | int USBHALHost::token_int_in(USBEndpoint* ep, uint8_t* data, int size) { |
va009039 | 11:61843badd06e | 248 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 | 11:61843badd06e | 249 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_IN, |
va009039 | 11:61843badd06e | 250 | ep->getAddress(), |
va009039 | 11:61843badd06e | 251 | dev->getAddress(), |
va009039 | 11:61843badd06e | 252 | dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, |
va009039 | 11:61843badd06e | 253 | EP_TYPE_INTR, ep->getSize()); |
va009039 | 11:61843badd06e | 254 | hhcd_USB_OTG_FS.hc[CH_INT_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; |
va009039 | 11:61843badd06e | 255 | |
va009039 | 11:61843badd06e | 256 | HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_IN, DIR_IN, EP_TYPE_INTR, 1, data, size, 0); |
va009039 | 11:61843badd06e | 257 | while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN) == URB_IDLE); |
va009039 | 11:61843badd06e | 258 | switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN)) { |
va009039 | 11:61843badd06e | 259 | case URB_DONE: |
va009039 | 11:61843badd06e | 260 | switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_INT_IN)) { |
va009039 | 11:61843badd06e | 261 | case HC_XFRC: |
va009039 | 11:61843badd06e | 262 | LastStatus = ep->getData01(); |
va009039 | 11:61843badd06e | 263 | ep->toggleData01(); |
va009039 | 11:61843badd06e | 264 | return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_INT_IN); |
va009039 | 11:61843badd06e | 265 | case HC_NAK: |
va009039 | 11:61843badd06e | 266 | LastStatus = NAK; |
va009039 | 11:61843badd06e | 267 | return -1; |
va009039 | 11:61843badd06e | 268 | } |
va009039 | 11:61843badd06e | 269 | break; |
va009039 | 11:61843badd06e | 270 | } |
va009039 | 11:61843badd06e | 271 | LastStatus = STALL; |
va009039 | 11:61843badd06e | 272 | return -1; |
va009039 | 11:61843badd06e | 273 | } |
va009039 | 11:61843badd06e | 274 | |
va009039 | 11:61843badd06e | 275 | int USBHALHost::token_blk_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { |
va009039 | 11:61843badd06e | 276 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 | 11:61843badd06e | 277 | int retry = 0; |
va009039 | 11:61843badd06e | 278 | do { |
va009039 | 11:61843badd06e | 279 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_IN, |
va009039 | 11:61843badd06e | 280 | ep->getAddress(), |
va009039 | 11:61843badd06e | 281 | dev->getAddress(), |
va009039 | 11:61843badd06e | 282 | HCD_SPEED_FULL, |
va009039 | 11:61843badd06e | 283 | EP_TYPE_BULK, ep->getSize()); |
va009039 | 11:61843badd06e | 284 | hhcd_USB_OTG_FS.hc[CH_BLK_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; |
va009039 | 11:61843badd06e | 285 | |
va009039 | 11:61843badd06e | 286 | HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_IN, DIR_IN, EP_TYPE_BULK, 1, data, size, 0); |
va009039 | 11:61843badd06e | 287 | while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN) == URB_IDLE); |
va009039 | 11:61843badd06e | 288 | |
va009039 | 11:61843badd06e | 289 | switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN)) { |
va009039 | 11:61843badd06e | 290 | case URB_DONE: |
va009039 | 11:61843badd06e | 291 | switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_IN)) { |
va009039 | 11:61843badd06e | 292 | case HC_XFRC: |
va009039 | 11:61843badd06e | 293 | LastStatus = ep->getData01(); |
va009039 | 11:61843badd06e | 294 | ep->toggleData01(); |
va009039 | 11:61843badd06e | 295 | return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_BLK_IN); |
va009039 | 11:61843badd06e | 296 | case HC_NAK: |
va009039 | 11:61843badd06e | 297 | LastStatus = NAK; |
va009039 | 11:61843badd06e | 298 | if (retryLimit > 0) { |
va009039 | 11:61843badd06e | 299 | delay_ms(1 + 10 * retry); |
va009039 | 11:61843badd06e | 300 | } |
va009039 | 11:61843badd06e | 301 | break; |
va009039 | 11:61843badd06e | 302 | default: |
va009039 | 11:61843badd06e | 303 | break; |
va009039 | 11:61843badd06e | 304 | } |
va009039 | 11:61843badd06e | 305 | break; |
va009039 | 11:61843badd06e | 306 | case URB_STALL: |
va009039 | 11:61843badd06e | 307 | LastStatus = STALL; |
va009039 | 11:61843badd06e | 308 | return -1; |
va009039 | 11:61843badd06e | 309 | default: |
va009039 | 11:61843badd06e | 310 | LastStatus = STALL; |
va009039 | 11:61843badd06e | 311 | delay_ms(500 + 100 * retry); |
va009039 | 11:61843badd06e | 312 | break; |
va009039 | 11:61843badd06e | 313 | } |
va009039 | 11:61843badd06e | 314 | }while(retry++ < retryLimit); |
va009039 | 11:61843badd06e | 315 | return -1; |
va009039 | 11:61843badd06e | 316 | } |
va009039 | 11:61843badd06e | 317 | |
va009039 | 11:61843badd06e | 318 | int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { |
va009039 | 11:61843badd06e | 319 | switch(ep->getType()) { |
va009039 | 11:61843badd06e | 320 | case CONTROL_ENDPOINT: |
va009039 | 11:61843badd06e | 321 | return token_ctl_out(ep, data, size, retryLimit); |
va009039 | 11:61843badd06e | 322 | case INTERRUPT_ENDPOINT: |
va009039 | 11:61843badd06e | 323 | return token_int_out(ep, data, size); |
va009039 | 11:61843badd06e | 324 | case BULK_ENDPOINT: |
va009039 | 11:61843badd06e | 325 | return token_blk_out(ep, data, size, retryLimit); |
va009039 | 11:61843badd06e | 326 | } |
va009039 | 11:61843badd06e | 327 | return -1; |
va009039 | 11:61843badd06e | 328 | } |
va009039 | 11:61843badd06e | 329 | |
va009039 | 11:61843badd06e | 330 | int USBHALHost::token_ctl_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { |
va009039 | 11:61843badd06e | 331 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 | 11:61843badd06e | 332 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, |
va009039 | 11:61843badd06e | 333 | dev->getAddress(), |
va009039 | 11:61843badd06e | 334 | dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, |
va009039 | 11:61843badd06e | 335 | EP_TYPE_CTRL, ep->getSize()); |
va009039 | 11:61843badd06e | 336 | hhcd_USB_OTG_FS.hc[CH_CTL_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; |
va009039 | 11:61843badd06e | 337 | |
va009039 | 11:61843badd06e | 338 | do { |
va009039 | 11:61843badd06e | 339 | HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 1, (uint8_t*)data, size, 0); |
va009039 | 11:61843badd06e | 340 | while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE); |
va009039 | 11:61843badd06e | 341 | |
va009039 | 11:61843badd06e | 342 | switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) { |
va009039 | 11:61843badd06e | 343 | case URB_DONE: |
va009039 | 11:61843badd06e | 344 | LastStatus = ACK; |
va009039 | 11:61843badd06e | 345 | ep->toggleData01(); |
va009039 |
14:b167f2b97cb7 | 346 | return size; |
va009039 | 11:61843badd06e | 347 | |
va009039 | 11:61843badd06e | 348 | default: |
va009039 | 11:61843badd06e | 349 | break; |
va009039 | 11:61843badd06e | 350 | } |
va009039 | 11:61843badd06e | 351 | delay_ms(1); |
va009039 | 11:61843badd06e | 352 | }while(retryLimit-- > 0); |
va009039 | 11:61843badd06e | 353 | return -1; |
va009039 | 11:61843badd06e | 354 | } |
va009039 | 11:61843badd06e | 355 | |
va009039 | 11:61843badd06e | 356 | int USBHALHost::token_int_out(USBEndpoint* ep, const uint8_t* data, int size) { |
va009039 | 11:61843badd06e | 357 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 | 11:61843badd06e | 358 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_OUT, |
va009039 | 11:61843badd06e | 359 | ep->getAddress(), |
va009039 | 11:61843badd06e | 360 | dev->getAddress(), |
va009039 | 11:61843badd06e | 361 | dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, |
va009039 | 11:61843badd06e | 362 | EP_TYPE_INTR, ep->getSize()); |
va009039 | 11:61843badd06e | 363 | hhcd_USB_OTG_FS.hc[CH_INT_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; |
va009039 | 11:61843badd06e | 364 | |
va009039 | 11:61843badd06e | 365 | token_done = false; |
va009039 | 11:61843badd06e | 366 | HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_OUT, DIR_OUT, EP_TYPE_INTR, 1, (uint8_t*)data, size, 0); |
va009039 | 11:61843badd06e | 367 | while(!token_done); |
va009039 | 11:61843badd06e | 368 | |
va009039 | 11:61843badd06e | 369 | if (HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_OUT) != URB_DONE) { |
va009039 | 11:61843badd06e | 370 | return -1; |
va009039 | 11:61843badd06e | 371 | } |
va009039 | 11:61843badd06e | 372 | ep->toggleData01(); |
va009039 |
14:b167f2b97cb7 | 373 | return size; |
va009039 | 11:61843badd06e | 374 | } |
va009039 | 11:61843badd06e | 375 | |
va009039 | 11:61843badd06e | 376 | int USBHALHost::token_blk_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { |
va009039 | 11:61843badd06e | 377 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 | 11:61843badd06e | 378 | int retry = 0; |
va009039 | 11:61843badd06e | 379 | do { |
va009039 | 11:61843badd06e | 380 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_OUT, |
va009039 | 11:61843badd06e | 381 | ep->getAddress(), dev->getAddress(), |
va009039 | 11:61843badd06e | 382 | HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize()); |
va009039 | 11:61843badd06e | 383 | hhcd_USB_OTG_FS.hc[CH_BLK_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; |
va009039 | 11:61843badd06e | 384 | |
va009039 | 11:61843badd06e | 385 | HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_OUT, DIR_OUT, EP_TYPE_BULK, 1, (uint8_t*)data, size, 0); |
va009039 | 11:61843badd06e | 386 | while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT) == URB_IDLE); |
va009039 | 11:61843badd06e | 387 | |
va009039 | 11:61843badd06e | 388 | switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) { |
va009039 | 11:61843badd06e | 389 | case URB_DONE: |
va009039 | 11:61843badd06e | 390 | switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) { |
va009039 | 11:61843badd06e | 391 | case HC_XFRC: // ACK |
va009039 | 11:61843badd06e | 392 | LastStatus = ep->getData01(); |
va009039 | 11:61843badd06e | 393 | ep->toggleData01(); |
va009039 |
14:b167f2b97cb7 | 394 | return size; |
va009039 | 11:61843badd06e | 395 | default: |
va009039 | 11:61843badd06e | 396 | break; |
va009039 | 11:61843badd06e | 397 | } |
va009039 | 11:61843badd06e | 398 | break; |
va009039 | 11:61843badd06e | 399 | case URB_NOTREADY: // HC_NAK |
va009039 | 11:61843badd06e | 400 | LastStatus = NAK; |
va009039 | 11:61843badd06e | 401 | delay_ms(100 * retry); |
va009039 | 11:61843badd06e | 402 | break; |
va009039 | 11:61843badd06e | 403 | default: |
va009039 | 11:61843badd06e | 404 | LastStatus = STALL; |
va009039 | 11:61843badd06e | 405 | return -1; |
va009039 | 11:61843badd06e | 406 | } |
va009039 | 11:61843badd06e | 407 | } while(retry++ < retryLimit); |
va009039 | 11:61843badd06e | 408 | return -1; |
va009039 | 11:61843badd06e | 409 | } |
va009039 | 11:61843badd06e | 410 | |
va009039 | 11:61843badd06e | 411 | int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) { |
va009039 |
13:8774c07f12a5 | 412 | static bool init = false; |
va009039 |
13:8774c07f12a5 | 413 | if (!init) { |
va009039 |
13:8774c07f12a5 | 414 | init = true; |
va009039 |
13:8774c07f12a5 | 415 | USBDeviceConnected* dev = ep->getDevice(); |
va009039 |
13:8774c07f12a5 | 416 | HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_ISO_IN, |
va009039 |
13:8774c07f12a5 | 417 | ep->getAddress(), dev->getAddress(), |
va009039 |
13:8774c07f12a5 | 418 | HCD_SPEED_FULL, EP_TYPE_ISOC, ep->getSize()); |
va009039 |
13:8774c07f12a5 | 419 | } |
va009039 | 11:61843badd06e | 420 | HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_ISO_IN, DIR_IN, EP_TYPE_ISOC, 1, data, size, 0); |
va009039 |
13:8774c07f12a5 | 421 | while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_ISO_IN) == URB_IDLE); |
va009039 | 11:61843badd06e | 422 | return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_ISO_IN); |
va009039 | 11:61843badd06e | 423 | } |
va009039 | 11:61843badd06e | 424 | |
va009039 | 11:61843badd06e | 425 | #endif |
va009039 | 11:61843badd06e | 426 | |
va009039 | 11:61843badd06e | 427 |