HEBOCON machine

Dependencies:   mbed Motorfader Servo WT2003M03

Committer:
abanum
Date:
Mon Jul 29 05:51:31 2019 +0000
Revision:
1:312b63cf250e
Parent:
0:a30ec7d94c3a
first pubrish

Who changed what in which revision?

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