test

Dependencies:   SDFileSystem mbed-dev

Fork of Nucleo_Ex06_EMU by woodstock .

Committer:
charliex
Date:
Sat May 27 02:17:37 2017 +0000
Revision:
4:53ef91c87d74
Parent:
0:3dac1f1bc9e0
test

Who changed what in which revision?

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