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 Norimasa Okamoto

Committer:
va009039
Date:
Tue Jul 01 18:33:31 2014 +0900
Revision:
18:61554f238584
Parent:
16:981c3104f6c0
Child:
19:47978c25c9b8
add lpc4088/lpc1768

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 11:61843badd06e 1 #if defined(TARGET_NUCLEO_F401RE)
va009039 18:61554f238584 2 #include "USBHALHost.h"
va009039 16:981c3104f6c0 3 #include <algorithm>
va009039 11:61843badd06e 4
va009039 11:61843badd06e 5 #ifdef _USB_DBG
va009039 11:61843badd06e 6 extern RawSerial pc;
va009039 16:981c3104f6c0 7 //RawSerial pc(USBTX,USBRX);
va009039 11:61843badd06e 8 #include "mydebug.h"
va009039 11:61843badd06e 9 #define USB_DBG(...) do{pc.printf("[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);pc.printf(__VA_ARGS__);pc.puts("\n");} while(0);
va009039 11:61843badd06e 10 #define USB_DBG_HEX(A,B) debug_hex<RawSerial>(pc,A,B)
va009039 11:61843badd06e 11
va009039 11:61843badd06e 12 #else
va009039 11:61843badd06e 13 #define USB_DBG(...) while(0)
va009039 11:61843badd06e 14 #define USB_DBG_HEX(A,B) while(0)
va009039 11:61843badd06e 15 #endif
va009039 11:61843badd06e 16
va009039 18:61554f238584 17 #undef USB_TEST_ASSERT
va009039 18:61554f238584 18 void usb_test_assert_internal(const char *expr, const char *file, int line);
va009039 18:61554f238584 19 #define USB_TEST_ASSERT(EXPR) while(!(EXPR)){usb_test_assert_internal(#EXPR,__FILE__,__LINE__);}
va009039 11:61843badd06e 20
va009039 11:61843badd06e 21 #define USB_TRACE1(A) while(0)
va009039 11:61843badd06e 22
va009039 11:61843badd06e 23 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0);
va009039 11:61843badd06e 24
va009039 11:61843badd06e 25 __IO bool attach_done = false;
va009039 11:61843badd06e 26
va009039 11:61843badd06e 27 void delay_ms(uint32_t t)
va009039 11:61843badd06e 28 {
va009039 11:61843badd06e 29 HAL_Delay(t);
va009039 11:61843badd06e 30 }
va009039 11:61843badd06e 31
va009039 16:981c3104f6c0 32 // usbh_conf.c
va009039 11:61843badd06e 33 extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
va009039 11:61843badd06e 34
va009039 11:61843badd06e 35 void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
va009039 11:61843badd06e 36 {
va009039 11:61843badd06e 37 GPIO_InitTypeDef GPIO_InitStruct;
va009039 11:61843badd06e 38 if(hhcd->Instance==USB_OTG_FS)
va009039 11:61843badd06e 39 {
va009039 11:61843badd06e 40 /* Peripheral clock enable */
va009039 11:61843badd06e 41 __USB_OTG_FS_CLK_ENABLE();
va009039 11:61843badd06e 42
va009039 11:61843badd06e 43 /**USB_OTG_FS GPIO Configuration
va009039 11:61843badd06e 44 PA11 ------> USB_OTG_FS_DM
va009039 11:61843badd06e 45 PA12 ------> USB_OTG_FS_DP
va009039 11:61843badd06e 46 */
va009039 11:61843badd06e 47 GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
va009039 11:61843badd06e 48 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
va009039 11:61843badd06e 49 GPIO_InitStruct.Pull = GPIO_NOPULL;
va009039 11:61843badd06e 50 GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
va009039 11:61843badd06e 51 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
va009039 11:61843badd06e 52 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
va009039 11:61843badd06e 53
va009039 11:61843badd06e 54 /* Peripheral interrupt init*/
va009039 11:61843badd06e 55 /* Sets the priority grouping field */
va009039 11:61843badd06e 56 HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
va009039 11:61843badd06e 57 HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
va009039 11:61843badd06e 58 HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
va009039 11:61843badd06e 59 }
va009039 11:61843badd06e 60 }
va009039 11:61843badd06e 61
va009039 16:981c3104f6c0 62 // stm32f4xx_it.c
va009039 11:61843badd06e 63 extern "C" {
va009039 11:61843badd06e 64 void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
va009039 11:61843badd06e 65 {
va009039 18:61554f238584 66 USB_TRACE1(hhcd);
va009039 11:61843badd06e 67 attach_done = true;
va009039 11:61843badd06e 68 }
va009039 11:61843badd06e 69
va009039 11:61843badd06e 70 } // extern "C"
va009039 11:61843badd06e 71
va009039 11:61843badd06e 72 USBHALHost* USBHALHost::instHost;
va009039 11:61843badd06e 73
va009039 11:61843badd06e 74 USBHALHost::USBHALHost() {
va009039 11:61843badd06e 75 instHost = this;
va009039 11:61843badd06e 76 }
va009039 11:61843badd06e 77
va009039 11:61843badd06e 78 void USBHALHost::init() {
va009039 11:61843badd06e 79 hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
va009039 11:61843badd06e 80 hhcd_USB_OTG_FS.Init.Host_channels = 8;
va009039 11:61843badd06e 81 hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
va009039 11:61843badd06e 82 hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
va009039 11:61843badd06e 83 hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
va009039 11:61843badd06e 84 hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
va009039 11:61843badd06e 85 hhcd_USB_OTG_FS.Init.low_power_enable = ENABLE;
va009039 11:61843badd06e 86 hhcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
va009039 11:61843badd06e 87 hhcd_USB_OTG_FS.Init.use_external_vbus = DISABLE;
va009039 11:61843badd06e 88
va009039 11:61843badd06e 89 HAL_HCD_Init(&hhcd_USB_OTG_FS);
va009039 11:61843badd06e 90 HAL_HCD_Start(&hhcd_USB_OTG_FS);
va009039 11:61843badd06e 91
va009039 11:61843badd06e 92 bool lowSpeed = wait_attach();
va009039 11:61843badd06e 93 delay_ms(200);
va009039 11:61843badd06e 94 HAL_HCD_ResetPort(&hhcd_USB_OTG_FS);
va009039 11:61843badd06e 95 delay_ms(100); // Wait for 100 ms after Reset
va009039 11:61843badd06e 96 addDevice(NULL, 0, lowSpeed);
va009039 11:61843badd06e 97 }
va009039 11:61843badd06e 98
va009039 11:61843badd06e 99 bool USBHALHost::wait_attach() {
va009039 11:61843badd06e 100 Timer t;
va009039 11:61843badd06e 101 t.reset();
va009039 11:61843badd06e 102 t.start();
va009039 11:61843badd06e 103 while(!attach_done) {
va009039 11:61843badd06e 104 if (t.read_ms() > 5*1000) {
va009039 11:61843badd06e 105 t.reset();
va009039 11:61843badd06e 106 USB_INFO("Please attach USB device.");
va009039 11:61843badd06e 107 }
va009039 11:61843badd06e 108 }
va009039 11:61843badd06e 109 wait_ms(100);
va009039 11:61843badd06e 110 return HAL_HCD_GetCurrentSpeed(&hhcd_USB_OTG_FS) == USB_OTG_SPEED_LOW;
va009039 11:61843badd06e 111 }
va009039 11:61843badd06e 112
va009039 11:61843badd06e 113 int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) {
va009039 16:981c3104f6c0 114 const uint8_t ep_addr = 0x00;
va009039 16:981c3104f6c0 115 HC hc;
va009039 11:61843badd06e 116 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 117 hc.Init(ep_addr,
va009039 11:61843badd06e 118 dev->getAddress(),
va009039 11:61843badd06e 119 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
va009039 11:61843badd06e 120 EP_TYPE_CTRL, ep->getSize());
va009039 11:61843badd06e 121
va009039 11:61843badd06e 122 setup->wLength = wLength;
va009039 16:981c3104f6c0 123 hc.SubmitRequest((uint8_t*)setup, 8, true); // PID_SETUP
va009039 16:981c3104f6c0 124 while(hc.GetURBState() == URB_IDLE);
va009039 11:61843badd06e 125
va009039 16:981c3104f6c0 126 switch(hc.GetURBState()) {
va009039 11:61843badd06e 127 case URB_DONE:
va009039 11:61843badd06e 128 LastStatus = ACK;
va009039 11:61843badd06e 129 break;
va009039 11:61843badd06e 130 default:
va009039 11:61843badd06e 131 LastStatus = 0xff;
va009039 11:61843badd06e 132 break;
va009039 11:61843badd06e 133 }
va009039 11:61843badd06e 134 ep->setData01(DATA1);
va009039 16:981c3104f6c0 135 return 8;
va009039 11:61843badd06e 136 }
va009039 11:61843badd06e 137
va009039 11:61843badd06e 138 int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) {
va009039 11:61843badd06e 139 switch(ep->getType()) {
va009039 11:61843badd06e 140 case CONTROL_ENDPOINT:
va009039 11:61843badd06e 141 return token_ctl_in(ep, data, size, retryLimit);
va009039 11:61843badd06e 142 case INTERRUPT_ENDPOINT:
va009039 11:61843badd06e 143 return token_int_in(ep, data, size);
va009039 11:61843badd06e 144 case BULK_ENDPOINT:
va009039 11:61843badd06e 145 return token_blk_in(ep, data, size, retryLimit);
va009039 11:61843badd06e 146 }
va009039 11:61843badd06e 147 return -1;
va009039 11:61843badd06e 148 }
va009039 11:61843badd06e 149
va009039 11:61843badd06e 150 int USBHALHost::token_ctl_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) {
va009039 16:981c3104f6c0 151 const uint8_t ep_addr = 0x80;
va009039 16:981c3104f6c0 152 HC hc;
va009039 11:61843badd06e 153 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 154 hc.Init(ep_addr,
va009039 11:61843badd06e 155 dev->getAddress(),
va009039 11:61843badd06e 156 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
va009039 11:61843badd06e 157 EP_TYPE_CTRL, ep->getSize());
va009039 16:981c3104f6c0 158
va009039 16:981c3104f6c0 159 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
va009039 11:61843badd06e 160
va009039 16:981c3104f6c0 161 hc.SubmitRequest(data, size);
va009039 16:981c3104f6c0 162 while(hc.GetURBState() == URB_IDLE);
va009039 11:61843badd06e 163
va009039 16:981c3104f6c0 164 switch(hc.GetURBState()) {
va009039 11:61843badd06e 165 case URB_DONE:
va009039 11:61843badd06e 166 LastStatus = ACK;
va009039 11:61843badd06e 167 break;
va009039 11:61843badd06e 168 default:
va009039 11:61843badd06e 169 LastStatus = 0xff;
va009039 11:61843badd06e 170 return -1;
va009039 11:61843badd06e 171 }
va009039 11:61843badd06e 172 ep->toggleData01();
va009039 16:981c3104f6c0 173 return hc.GetXferCount();
va009039 11:61843badd06e 174 }
va009039 11:61843badd06e 175
va009039 11:61843badd06e 176 int USBHALHost::token_int_in(USBEndpoint* ep, uint8_t* data, int size) {
va009039 16:981c3104f6c0 177 HC hc;
va009039 11:61843badd06e 178 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 179 hc.Init(
va009039 11:61843badd06e 180 ep->getAddress(),
va009039 11:61843badd06e 181 dev->getAddress(),
va009039 11:61843badd06e 182 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
va009039 11:61843badd06e 183 EP_TYPE_INTR, ep->getSize());
va009039 16:981c3104f6c0 184
va009039 16:981c3104f6c0 185 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
va009039 11:61843badd06e 186
va009039 16:981c3104f6c0 187 hc.SubmitRequest(data, size);
va009039 16:981c3104f6c0 188 while(hc.GetURBState() == URB_IDLE);
va009039 16:981c3104f6c0 189 switch(hc.GetURBState()) {
va009039 11:61843badd06e 190 case URB_DONE:
va009039 16:981c3104f6c0 191 switch(hc.GetState()) {
va009039 11:61843badd06e 192 case HC_XFRC:
va009039 11:61843badd06e 193 LastStatus = ep->getData01();
va009039 11:61843badd06e 194 ep->toggleData01();
va009039 16:981c3104f6c0 195 return hc.GetXferCount();
va009039 11:61843badd06e 196 case HC_NAK:
va009039 11:61843badd06e 197 LastStatus = NAK;
va009039 11:61843badd06e 198 return -1;
va009039 11:61843badd06e 199 }
va009039 11:61843badd06e 200 break;
va009039 11:61843badd06e 201 }
va009039 11:61843badd06e 202 LastStatus = STALL;
va009039 11:61843badd06e 203 return -1;
va009039 11:61843badd06e 204 }
va009039 11:61843badd06e 205
va009039 11:61843badd06e 206 int USBHALHost::token_blk_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) {
va009039 16:981c3104f6c0 207 HC hc;
va009039 11:61843badd06e 208 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 209 hc.Init(
va009039 16:981c3104f6c0 210 ep->getAddress(),
va009039 16:981c3104f6c0 211 dev->getAddress(),
va009039 16:981c3104f6c0 212 HCD_SPEED_FULL,
va009039 16:981c3104f6c0 213 EP_TYPE_BULK, ep->getSize());
va009039 16:981c3104f6c0 214
va009039 16:981c3104f6c0 215 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
va009039 16:981c3104f6c0 216
va009039 11:61843badd06e 217 int retry = 0;
va009039 11:61843badd06e 218 do {
va009039 16:981c3104f6c0 219 hc.SubmitRequest(data, size);
va009039 16:981c3104f6c0 220 while(hc.GetURBState() == URB_IDLE);
va009039 11:61843badd06e 221
va009039 16:981c3104f6c0 222 switch(hc.GetURBState()) {
va009039 11:61843badd06e 223 case URB_DONE:
va009039 16:981c3104f6c0 224 switch(hc.GetState()) {
va009039 11:61843badd06e 225 case HC_XFRC:
va009039 11:61843badd06e 226 LastStatus = ep->getData01();
va009039 11:61843badd06e 227 ep->toggleData01();
va009039 16:981c3104f6c0 228 return hc.GetXferCount();
va009039 11:61843badd06e 229 case HC_NAK:
va009039 11:61843badd06e 230 LastStatus = NAK;
va009039 11:61843badd06e 231 if (retryLimit > 0) {
va009039 11:61843badd06e 232 delay_ms(1 + 10 * retry);
va009039 11:61843badd06e 233 }
va009039 11:61843badd06e 234 break;
va009039 11:61843badd06e 235 default:
va009039 11:61843badd06e 236 break;
va009039 11:61843badd06e 237 }
va009039 11:61843badd06e 238 break;
va009039 11:61843badd06e 239 case URB_STALL:
va009039 11:61843badd06e 240 LastStatus = STALL;
va009039 11:61843badd06e 241 return -1;
va009039 11:61843badd06e 242 default:
va009039 11:61843badd06e 243 LastStatus = STALL;
va009039 11:61843badd06e 244 delay_ms(500 + 100 * retry);
va009039 11:61843badd06e 245 break;
va009039 11:61843badd06e 246 }
va009039 11:61843badd06e 247 }while(retry++ < retryLimit);
va009039 11:61843badd06e 248 return -1;
va009039 11:61843badd06e 249 }
va009039 11:61843badd06e 250
va009039 11:61843badd06e 251 int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) {
va009039 11:61843badd06e 252 switch(ep->getType()) {
va009039 11:61843badd06e 253 case CONTROL_ENDPOINT:
va009039 11:61843badd06e 254 return token_ctl_out(ep, data, size, retryLimit);
va009039 11:61843badd06e 255 case INTERRUPT_ENDPOINT:
va009039 11:61843badd06e 256 return token_int_out(ep, data, size);
va009039 11:61843badd06e 257 case BULK_ENDPOINT:
va009039 11:61843badd06e 258 return token_blk_out(ep, data, size, retryLimit);
va009039 11:61843badd06e 259 }
va009039 11:61843badd06e 260 return -1;
va009039 11:61843badd06e 261 }
va009039 11:61843badd06e 262
va009039 11:61843badd06e 263 int USBHALHost::token_ctl_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) {
va009039 16:981c3104f6c0 264 const uint8_t ep_addr = 0x00;
va009039 16:981c3104f6c0 265 HC hc;
va009039 11:61843badd06e 266 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 267 hc.Init(ep_addr,
va009039 16:981c3104f6c0 268 dev->getAddress(),
va009039 16:981c3104f6c0 269 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
va009039 16:981c3104f6c0 270 EP_TYPE_CTRL, ep->getSize());
va009039 16:981c3104f6c0 271
va009039 16:981c3104f6c0 272 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
va009039 11:61843badd06e 273
va009039 11:61843badd06e 274 do {
va009039 16:981c3104f6c0 275 hc.SubmitRequest((uint8_t*)data, size);
va009039 16:981c3104f6c0 276 while(hc.GetURBState() == URB_IDLE);
va009039 11:61843badd06e 277
va009039 16:981c3104f6c0 278 switch(hc.GetURBState()) {
va009039 11:61843badd06e 279 case URB_DONE:
va009039 11:61843badd06e 280 LastStatus = ACK;
va009039 11:61843badd06e 281 ep->toggleData01();
va009039 14:b167f2b97cb7 282 return size;
va009039 11:61843badd06e 283
va009039 11:61843badd06e 284 default:
va009039 11:61843badd06e 285 break;
va009039 11:61843badd06e 286 }
va009039 11:61843badd06e 287 delay_ms(1);
va009039 11:61843badd06e 288 }while(retryLimit-- > 0);
va009039 11:61843badd06e 289 return -1;
va009039 11:61843badd06e 290 }
va009039 11:61843badd06e 291
va009039 11:61843badd06e 292 int USBHALHost::token_int_out(USBEndpoint* ep, const uint8_t* data, int size) {
va009039 16:981c3104f6c0 293 HC hc;
va009039 11:61843badd06e 294 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 295 hc.Init(
va009039 11:61843badd06e 296 ep->getAddress(),
va009039 11:61843badd06e 297 dev->getAddress(),
va009039 11:61843badd06e 298 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
va009039 11:61843badd06e 299 EP_TYPE_INTR, ep->getSize());
va009039 16:981c3104f6c0 300
va009039 16:981c3104f6c0 301 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
va009039 11:61843badd06e 302
va009039 16:981c3104f6c0 303 hc.SubmitRequest((uint8_t*)data, size);
va009039 16:981c3104f6c0 304 while(hc.GetURBState() == URB_IDLE);
va009039 16:981c3104f6c0 305 if (hc.GetURBState() != URB_DONE) {
va009039 11:61843badd06e 306 return -1;
va009039 11:61843badd06e 307 }
va009039 11:61843badd06e 308 ep->toggleData01();
va009039 14:b167f2b97cb7 309 return size;
va009039 11:61843badd06e 310 }
va009039 11:61843badd06e 311
va009039 11:61843badd06e 312 int USBHALHost::token_blk_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) {
va009039 16:981c3104f6c0 313 HC hc;
va009039 11:61843badd06e 314 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 315 hc.Init(
va009039 16:981c3104f6c0 316 ep->getAddress(), dev->getAddress(),
va009039 16:981c3104f6c0 317 HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize());
va009039 16:981c3104f6c0 318
va009039 16:981c3104f6c0 319 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
va009039 16:981c3104f6c0 320
va009039 11:61843badd06e 321 int retry = 0;
va009039 11:61843badd06e 322 do {
va009039 16:981c3104f6c0 323 hc.SubmitRequest((uint8_t*)data, size);
va009039 16:981c3104f6c0 324 while(hc.GetURBState() == URB_IDLE);
va009039 11:61843badd06e 325
va009039 16:981c3104f6c0 326 switch(hc.GetURBState()) {
va009039 11:61843badd06e 327 case URB_DONE:
va009039 16:981c3104f6c0 328 switch(hc.GetState()) {
va009039 11:61843badd06e 329 case HC_XFRC: // ACK
va009039 11:61843badd06e 330 LastStatus = ep->getData01();
va009039 11:61843badd06e 331 ep->toggleData01();
va009039 14:b167f2b97cb7 332 return size;
va009039 11:61843badd06e 333 default:
va009039 11:61843badd06e 334 break;
va009039 11:61843badd06e 335 }
va009039 11:61843badd06e 336 break;
va009039 11:61843badd06e 337 case URB_NOTREADY: // HC_NAK
va009039 11:61843badd06e 338 LastStatus = NAK;
va009039 11:61843badd06e 339 delay_ms(100 * retry);
va009039 11:61843badd06e 340 break;
va009039 11:61843badd06e 341 default:
va009039 11:61843badd06e 342 LastStatus = STALL;
va009039 11:61843badd06e 343 return -1;
va009039 11:61843badd06e 344 }
va009039 11:61843badd06e 345 } while(retry++ < retryLimit);
va009039 11:61843badd06e 346 return -1;
va009039 11:61843badd06e 347 }
va009039 11:61843badd06e 348
va009039 11:61843badd06e 349 int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) {
va009039 16:981c3104f6c0 350 HC* hc = ep->getHALData<HC*>();
va009039 16:981c3104f6c0 351 if (hc == NULL) {
va009039 16:981c3104f6c0 352 hc = new HC;
va009039 16:981c3104f6c0 353 ep->setHALData<HC*>(hc);
va009039 13:8774c07f12a5 354 USBDeviceConnected* dev = ep->getDevice();
va009039 16:981c3104f6c0 355 hc->Init(
va009039 13:8774c07f12a5 356 ep->getAddress(), dev->getAddress(),
va009039 13:8774c07f12a5 357 HCD_SPEED_FULL, EP_TYPE_ISOC, ep->getSize());
va009039 13:8774c07f12a5 358 }
va009039 16:981c3104f6c0 359 hc->SubmitRequest(data, size);
va009039 16:981c3104f6c0 360 while(hc->GetURBState() == URB_IDLE);
va009039 16:981c3104f6c0 361 return hc->GetXferCount();
va009039 16:981c3104f6c0 362 }
va009039 16:981c3104f6c0 363
va009039 16:981c3104f6c0 364 int USBHALHost::multi_token_in(USBEndpoint* ep, uint8_t* data, size_t total, bool block) {
va009039 16:981c3104f6c0 365 if (total == 0) {
va009039 16:981c3104f6c0 366 return token_in(ep);
va009039 16:981c3104f6c0 367 }
va009039 16:981c3104f6c0 368 int retryLimit = block ? 10 : 0;
va009039 16:981c3104f6c0 369 int read_len = 0;
va009039 16:981c3104f6c0 370 for(int n = 0; read_len < total; n++) {
va009039 16:981c3104f6c0 371 int size = std::min((int)total-read_len, ep->getSize());
va009039 16:981c3104f6c0 372 int result = token_in(ep, data+read_len, size, retryLimit);
va009039 16:981c3104f6c0 373 if (result < 0) {
va009039 16:981c3104f6c0 374 if (block) {
va009039 16:981c3104f6c0 375 return -1;
va009039 16:981c3104f6c0 376 }
va009039 16:981c3104f6c0 377 if (LastStatus == NAK) {
va009039 16:981c3104f6c0 378 if (n == 0) {
va009039 16:981c3104f6c0 379 return -1;
va009039 16:981c3104f6c0 380 }
va009039 16:981c3104f6c0 381 break;
va009039 16:981c3104f6c0 382 }
va009039 16:981c3104f6c0 383 return result;
va009039 16:981c3104f6c0 384 }
va009039 16:981c3104f6c0 385 read_len += result;
va009039 16:981c3104f6c0 386 if (result < ep->getSize()) {
va009039 16:981c3104f6c0 387 break;
va009039 16:981c3104f6c0 388 }
va009039 16:981c3104f6c0 389 }
va009039 16:981c3104f6c0 390 return read_len;
va009039 16:981c3104f6c0 391 }
va009039 16:981c3104f6c0 392
va009039 18:61554f238584 393 int USBHALHost::multi_token_out(USBEndpoint* ep, const uint8_t* data, size_t total) {
va009039 16:981c3104f6c0 394 if (total == 0) {
va009039 16:981c3104f6c0 395 return token_out(ep);
va009039 16:981c3104f6c0 396 }
va009039 16:981c3104f6c0 397 int write_len = 0;
va009039 16:981c3104f6c0 398 for(int n = 0; write_len < total; n++) {
va009039 16:981c3104f6c0 399 int size = std::min((int)total-write_len, ep->getSize());
va009039 16:981c3104f6c0 400 int result = token_out(ep, data+write_len, size);
va009039 16:981c3104f6c0 401 if (result < 0) {
va009039 16:981c3104f6c0 402 if (LastStatus == NAK) {
va009039 16:981c3104f6c0 403 if (n == 0) {
va009039 16:981c3104f6c0 404 return -1;
va009039 16:981c3104f6c0 405 }
va009039 16:981c3104f6c0 406 break;
va009039 16:981c3104f6c0 407 }
va009039 16:981c3104f6c0 408 USB_DBG("token_out result=%d %02x", result, LastStatus);
va009039 16:981c3104f6c0 409 return result;
va009039 16:981c3104f6c0 410 }
va009039 16:981c3104f6c0 411 write_len += result;
va009039 16:981c3104f6c0 412 if (result < ep->getSize()) {
va009039 16:981c3104f6c0 413 break;
va009039 16:981c3104f6c0 414 }
va009039 16:981c3104f6c0 415 }
va009039 16:981c3104f6c0 416 return write_len;
va009039 16:981c3104f6c0 417 }
va009039 18:61554f238584 418 void USBHALHost::multi_token_inNB(USBEndpoint* ep, uint8_t* data, int size) {
va009039 18:61554f238584 419 USB_TRACE1(size);
va009039 18:61554f238584 420 USB_TEST_ASSERT(ep->getState() != USB_TYPE_PROCESSING);
va009039 18:61554f238584 421 ep->setBuffer(data, size);
va009039 18:61554f238584 422 ep->setState(USB_TYPE_PROCESSING);
va009039 18:61554f238584 423 }
va009039 18:61554f238584 424
va009039 18:61554f238584 425 USB_TYPE USBHALHost::multi_token_inNB_result(USBEndpoint* ep) {
va009039 18:61554f238584 426 USB_TEST_ASSERT(ep->getState() == USB_TYPE_PROCESSING);
va009039 18:61554f238584 427 uint8_t* buf = ep->getBufStart();
va009039 18:61554f238584 428 int size = ep->getBufSize();
va009039 18:61554f238584 429 int result = multi_token_in(ep, buf, size, false);
va009039 18:61554f238584 430 USB_TRACE1(result);
va009039 18:61554f238584 431 if (result < 0) {
va009039 18:61554f238584 432 return USB_TYPE_PROCESSING;
va009039 18:61554f238584 433 }
va009039 18:61554f238584 434 ep->setLengthTransferred(result);
va009039 18:61554f238584 435 ep->setState(USB_TYPE_IDLE);
va009039 18:61554f238584 436 return USB_TYPE_OK;
va009039 18:61554f238584 437
va009039 18:61554f238584 438 }
va009039 18:61554f238584 439
va009039 18:61554f238584 440 void USBHALHost::setToggle(USBEndpoint* ep, uint8_t toggle) {
va009039 18:61554f238584 441 USB_TEST_ASSERT(toggle == 1);
va009039 18:61554f238584 442 ep->setData01(toggle == 0 ? DATA0 : DATA1);
va009039 18:61554f238584 443 }
va009039 16:981c3104f6c0 444
va009039 16:981c3104f6c0 445 uint8_t HC::slot = 0x00;
va009039 16:981c3104f6c0 446
va009039 16:981c3104f6c0 447 HC::HC() {
va009039 18:61554f238584 448 static const int start = 1;
va009039 18:61554f238584 449 uint8_t mask = (1<<start);
va009039 18:61554f238584 450 for(int i = start; i < 8; i++, mask <<= 1) {
va009039 16:981c3104f6c0 451 if (!(slot & mask)) {
va009039 16:981c3104f6c0 452 slot |= mask;
va009039 16:981c3104f6c0 453 _ch = i;
va009039 16:981c3104f6c0 454 return;
va009039 16:981c3104f6c0 455 }
va009039 16:981c3104f6c0 456 }
va009039 16:981c3104f6c0 457 _ch = 0; // ERROR!!!
va009039 16:981c3104f6c0 458 }
va009039 16:981c3104f6c0 459
va009039 16:981c3104f6c0 460 HC::HC(int ch) {
va009039 16:981c3104f6c0 461 _ch = ch;
va009039 16:981c3104f6c0 462 slot |= (1<<_ch);
va009039 16:981c3104f6c0 463 }
va009039 16:981c3104f6c0 464
va009039 16:981c3104f6c0 465 HC::~HC() {
va009039 16:981c3104f6c0 466 slot &= ~(1<<_ch);
va009039 16:981c3104f6c0 467 }
va009039 16:981c3104f6c0 468
va009039 16:981c3104f6c0 469 HAL_StatusTypeDef HC::Init(uint8_t epnum, uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps) {
va009039 16:981c3104f6c0 470 _ep_addr = epnum;
va009039 16:981c3104f6c0 471 _ep_type = ep_type;
va009039 16:981c3104f6c0 472 return HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, _ch,
va009039 16:981c3104f6c0 473 epnum, dev_address, speed, ep_type, mps);
va009039 16:981c3104f6c0 474 }
va009039 16:981c3104f6c0 475
va009039 16:981c3104f6c0 476 HAL_StatusTypeDef HC::SubmitRequest(uint8_t* pbuff, uint16_t length, bool setup) {
va009039 16:981c3104f6c0 477 uint8_t direction = (_ep_addr & 0x80) ? DIR_IN : DIR_OUT;
va009039 16:981c3104f6c0 478 if (_ep_type == EP_TYPE_CTRL) {
va009039 16:981c3104f6c0 479 HCD_HCTypeDef* hc = &hhcd_USB_OTG_FS.hc[_ch];
va009039 16:981c3104f6c0 480 if (setup) {
va009039 16:981c3104f6c0 481 hc->data_pid = HC_PID_SETUP;
va009039 16:981c3104f6c0 482 hc->toggle_out = 0;
va009039 16:981c3104f6c0 483 } else {
va009039 16:981c3104f6c0 484 if (direction == DIR_IN) {
va009039 16:981c3104f6c0 485 if (hc->toggle_in == 0) {
va009039 16:981c3104f6c0 486 hc->data_pid = HC_PID_DATA0;
va009039 16:981c3104f6c0 487 } else {
va009039 16:981c3104f6c0 488 hc->data_pid = HC_PID_DATA1;
va009039 16:981c3104f6c0 489 }
va009039 16:981c3104f6c0 490 } else { // OUT
va009039 16:981c3104f6c0 491 if (hc->toggle_out == 0) {
va009039 16:981c3104f6c0 492 hc->data_pid = HC_PID_DATA0;
va009039 16:981c3104f6c0 493 } else {
va009039 16:981c3104f6c0 494 hc->data_pid = HC_PID_DATA1;
va009039 16:981c3104f6c0 495 }
va009039 16:981c3104f6c0 496 }
va009039 16:981c3104f6c0 497 }
va009039 16:981c3104f6c0 498 hc->xfer_buff = pbuff;
va009039 16:981c3104f6c0 499 hc->xfer_len = length;
va009039 16:981c3104f6c0 500 hc->urb_state = URB_IDLE;
va009039 16:981c3104f6c0 501 hc->xfer_count = 0;
va009039 16:981c3104f6c0 502 hc->ch_num = _ch;
va009039 16:981c3104f6c0 503 hc->state = HC_IDLE;
va009039 16:981c3104f6c0 504
va009039 16:981c3104f6c0 505 return USB_HC_StartXfer(hhcd_USB_OTG_FS.Instance, hc, 0);
va009039 16:981c3104f6c0 506 }
va009039 16:981c3104f6c0 507 return HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, _ch,
va009039 16:981c3104f6c0 508 direction, _ep_type, 0, pbuff, length, 0);
va009039 16:981c3104f6c0 509 }
va009039 16:981c3104f6c0 510
va009039 16:981c3104f6c0 511 HCD_URBStateTypeDef HC::GetURBState() {
va009039 16:981c3104f6c0 512 return HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, _ch);
va009039 16:981c3104f6c0 513 }
va009039 16:981c3104f6c0 514
va009039 16:981c3104f6c0 515 HCD_HCStateTypeDef HC::GetState() {
va009039 16:981c3104f6c0 516 return HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, _ch);
va009039 16:981c3104f6c0 517 }
va009039 16:981c3104f6c0 518
va009039 16:981c3104f6c0 519 uint32_t HC::GetXferCount() {
va009039 16:981c3104f6c0 520 return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, _ch);
va009039 16:981c3104f6c0 521 }
va009039 16:981c3104f6c0 522
va009039 16:981c3104f6c0 523 void HC::SetToggle(uint8_t toggle) {
va009039 16:981c3104f6c0 524 if (_ep_addr & 0x80) { // IN
va009039 16:981c3104f6c0 525 hhcd_USB_OTG_FS.hc[_ch].toggle_in = toggle;
va009039 16:981c3104f6c0 526 } else { // OUT
va009039 16:981c3104f6c0 527 hhcd_USB_OTG_FS.hc[_ch].toggle_out = toggle;
va009039 16:981c3104f6c0 528 }
va009039 11:61843badd06e 529 }
va009039 11:61843badd06e 530
va009039 11:61843badd06e 531 #endif
va009039 11:61843badd06e 532
va009039 11:61843badd06e 533