first release for keyboard

Dependencies:   FATFileSystem2

Dependents:   N64_Output_KB

Fork of F401RE-USBHost by Norimasa Okamoto

Committer:
va009039
Date:
Wed Feb 05 13:34:37 2014 +0000
Revision:
10:40c7f6788902
Parent:
9:7f9f64cf5ded
fix endpoint callback.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 7:9a20482c9a7a 1 // Simple USBHost for FRDM-KL46Z
va009039 7:9a20482c9a7a 2 #include "USBHost.h"
va009039 7:9a20482c9a7a 3 #include <algorithm>
va009039 7:9a20482c9a7a 4
va009039 7:9a20482c9a7a 5 USBHost* USBHost::inst = NULL;
va009039 7:9a20482c9a7a 6
va009039 7:9a20482c9a7a 7 USBHost* USBHost::getHostInst()
va009039 7:9a20482c9a7a 8 {
va009039 7:9a20482c9a7a 9 if (inst == NULL) {
va009039 7:9a20482c9a7a 10 inst = new USBHost();
va009039 7:9a20482c9a7a 11 inst->init();
va009039 7:9a20482c9a7a 12 }
va009039 7:9a20482c9a7a 13 return inst;
va009039 7:9a20482c9a7a 14 }
va009039 7:9a20482c9a7a 15
va009039 9:7f9f64cf5ded 16 void USBHost::poll()
va009039 9:7f9f64cf5ded 17 {
va009039 9:7f9f64cf5ded 18 if (inst) {
va009039 9:7f9f64cf5ded 19 inst->task();
va009039 9:7f9f64cf5ded 20 }
va009039 9:7f9f64cf5ded 21 }
va009039 9:7f9f64cf5ded 22
va009039 7:9a20482c9a7a 23 USBHost::USBHost() {
va009039 7:9a20482c9a7a 24 }
va009039 7:9a20482c9a7a 25
va009039 10:40c7f6788902 26 /* virtual */ bool USBHost::addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) {
va009039 8:6463cd1964c0 27 USBDeviceConnected* dev = new USBDeviceConnected;
va009039 10:40c7f6788902 28 USBEndpoint* ep = new USBEndpoint(dev);
va009039 10:40c7f6788902 29 dev->init(0, port, lowSpeed);
va009039 8:6463cd1964c0 30 dev->setAddress(0);
va009039 8:6463cd1964c0 31 dev->setEpCtl(ep);
va009039 8:6463cd1964c0 32 uint8_t desc[18];
va009039 7:9a20482c9a7a 33 wait_ms(100);
va009039 8:6463cd1964c0 34
va009039 8:6463cd1964c0 35 int rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, 8);
va009039 8:6463cd1964c0 36 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 10:40c7f6788902 37 if (rc != USB_TYPE_OK) {
va009039 10:40c7f6788902 38 USB_ERR("ADD DEVICE FAILD");
va009039 10:40c7f6788902 39 }
va009039 8:6463cd1964c0 40 USB_DBG_HEX(desc, 8);
va009039 7:9a20482c9a7a 41 DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc);
va009039 7:9a20482c9a7a 42 ep->setSize(dev_desc->bMaxPacketSize);
va009039 7:9a20482c9a7a 43
va009039 8:6463cd1964c0 44 int new_addr = USBDeviceConnected::getNewAddress();
va009039 8:6463cd1964c0 45 rc = controlWrite(dev, 0x00, SET_ADDRESS, new_addr, 0, NULL, 0);
va009039 8:6463cd1964c0 46 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 8:6463cd1964c0 47 dev->setAddress(new_addr);
va009039 7:9a20482c9a7a 48 wait_ms(100);
va009039 8:6463cd1964c0 49
va009039 8:6463cd1964c0 50 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc));
va009039 8:6463cd1964c0 51 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 8:6463cd1964c0 52 USB_DBG_HEX(desc, sizeof(desc));
va009039 7:9a20482c9a7a 53
va009039 8:6463cd1964c0 54 dev->setVid(dev_desc->idVendor);
va009039 8:6463cd1964c0 55 dev->setPid(dev_desc->idProduct);
va009039 8:6463cd1964c0 56 dev->setClass(dev_desc->bDeviceClass);
va009039 10:40c7f6788902 57 USB_INFO("parent:%p port:%d speed:%s VID:%04x PID:%04x class:%02x addr:%d",
va009039 10:40c7f6788902 58 parent, port, (lowSpeed ? "low " : "full"), dev->getVid(), dev->getPid(), dev->getClass(),
va009039 8:6463cd1964c0 59 dev->getAddress());
va009039 8:6463cd1964c0 60
va009039 10:40c7f6788902 61 DeviceLists.push_back(dev);
va009039 8:6463cd1964c0 62
va009039 8:6463cd1964c0 63 if (dev->getClass() == HUB_CLASS) {
va009039 8:6463cd1964c0 64 const int config = 1;
va009039 8:6463cd1964c0 65 int rc = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0);
va009039 8:6463cd1964c0 66 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 8:6463cd1964c0 67 wait_ms(100);
va009039 8:6463cd1964c0 68 Hub(dev);
va009039 7:9a20482c9a7a 69 }
va009039 8:6463cd1964c0 70 return true;
va009039 8:6463cd1964c0 71 }
va009039 7:9a20482c9a7a 72
va009039 8:6463cd1964c0 73 // enumerate a device with the control USBEndpoint
va009039 8:6463cd1964c0 74 USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator)
va009039 8:6463cd1964c0 75 {
va009039 8:6463cd1964c0 76 if (dev->getClass() == HUB_CLASS) { // skip hub class
va009039 8:6463cd1964c0 77 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 78 }
va009039 8:6463cd1964c0 79 uint8_t desc[18];
va009039 8:6463cd1964c0 80 USB_TYPE rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc));
va009039 8:6463cd1964c0 81 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 8:6463cd1964c0 82 USB_DBG_HEX(desc, sizeof(desc));
va009039 8:6463cd1964c0 83 if (rc != USB_TYPE_OK) {
va009039 8:6463cd1964c0 84 return rc;
va009039 8:6463cd1964c0 85 }
va009039 8:6463cd1964c0 86 DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc);
va009039 8:6463cd1964c0 87 dev->setClass(dev_desc->bDeviceClass);
va009039 8:6463cd1964c0 88 pEnumerator->setVidPid(dev->getVid(), dev->getPid());
va009039 7:9a20482c9a7a 89
va009039 8:6463cd1964c0 90 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, desc, 4);
va009039 8:6463cd1964c0 91 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 7:9a20482c9a7a 92 USB_DBG_HEX(desc, 4);
va009039 7:9a20482c9a7a 93
va009039 7:9a20482c9a7a 94 int TotalLength = desc[2]|desc[3]<<8;
va009039 7:9a20482c9a7a 95 uint8_t* buf = new uint8_t[TotalLength];
va009039 8:6463cd1964c0 96 rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, buf, TotalLength);
va009039 8:6463cd1964c0 97 USB_TEST_ASSERT(rc == USB_TYPE_OK);
va009039 8:6463cd1964c0 98 //USB_DBG_HEX(buf, TotalLength);
va009039 8:6463cd1964c0 99
va009039 8:6463cd1964c0 100 // Parse the configuration descriptor
va009039 8:6463cd1964c0 101 parseConfDescr(dev, buf, TotalLength, pEnumerator);
va009039 8:6463cd1964c0 102 delete[] buf;
va009039 8:6463cd1964c0 103 // only set configuration if not enumerated before
va009039 8:6463cd1964c0 104 if (!dev->isEnumerated()) {
va009039 8:6463cd1964c0 105 USB_DBG("Set configuration 1 on dev: %p", dev);
va009039 8:6463cd1964c0 106 // sixth step: set configuration (only 1 supported)
va009039 8:6463cd1964c0 107 int config = 1;
va009039 8:6463cd1964c0 108 USB_TYPE res = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0);
va009039 8:6463cd1964c0 109 if (res != USB_TYPE_OK) {
va009039 10:40c7f6788902 110 USB_ERR("SET CONF FAILED");
va009039 8:6463cd1964c0 111 return res;
va009039 8:6463cd1964c0 112 }
va009039 8:6463cd1964c0 113 // Some devices may require this delay
va009039 8:6463cd1964c0 114 wait_ms(100);
va009039 8:6463cd1964c0 115 dev->setEnumerated();
va009039 8:6463cd1964c0 116 // Now the device is enumerated!
va009039 8:6463cd1964c0 117 USB_DBG("dev %p is enumerated", dev);
va009039 7:9a20482c9a7a 118 }
va009039 8:6463cd1964c0 119 return USB_TYPE_OK;
va009039 8:6463cd1964c0 120 }
va009039 7:9a20482c9a7a 121
va009039 8:6463cd1964c0 122 // this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor.
va009039 8:6463cd1964c0 123 void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator)
va009039 8:6463cd1964c0 124 {
va009039 8:6463cd1964c0 125 uint32_t index = 0;
va009039 8:6463cd1964c0 126 uint32_t len_desc = 0;
va009039 8:6463cd1964c0 127 uint8_t id = 0;
va009039 8:6463cd1964c0 128 USBEndpoint * ep = NULL;
va009039 8:6463cd1964c0 129 uint8_t intf_nb = 0;
va009039 8:6463cd1964c0 130 bool parsing_intf = false;
va009039 8:6463cd1964c0 131 uint8_t current_intf = 0;
va009039 8:6463cd1964c0 132 EndpointDescriptor* ep_desc;
va009039 8:6463cd1964c0 133
va009039 8:6463cd1964c0 134 while (index < len) {
va009039 8:6463cd1964c0 135 len_desc = conf_descr[index];
va009039 8:6463cd1964c0 136 id = conf_descr[index+1];
va009039 9:7f9f64cf5ded 137 USB_DBG_HEX(conf_descr+index, len_desc);
va009039 8:6463cd1964c0 138 switch (id) {
va009039 8:6463cd1964c0 139 case CONFIGURATION_DESCRIPTOR:
va009039 8:6463cd1964c0 140 USB_DBG("dev: %p has %d intf", dev, conf_descr[4]);
va009039 8:6463cd1964c0 141 dev->setNbIntf(conf_descr[4]);
va009039 8:6463cd1964c0 142 break;
va009039 8:6463cd1964c0 143 case INTERFACE_DESCRIPTOR:
va009039 8:6463cd1964c0 144 if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) {
va009039 9:7f9f64cf5ded 145 intf_nb++;
va009039 9:7f9f64cf5ded 146 current_intf = conf_descr[index + 2];
va009039 9:7f9f64cf5ded 147 dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]);
va009039 9:7f9f64cf5ded 148 USB_DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", current_intf, dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]);
va009039 8:6463cd1964c0 149 parsing_intf = true;
va009039 8:6463cd1964c0 150 } else {
va009039 8:6463cd1964c0 151 parsing_intf = false;
va009039 7:9a20482c9a7a 152 }
va009039 8:6463cd1964c0 153 break;
va009039 8:6463cd1964c0 154 case ENDPOINT_DESCRIPTOR:
va009039 8:6463cd1964c0 155 ep_desc = reinterpret_cast<EndpointDescriptor*>(conf_descr+index);
va009039 8:6463cd1964c0 156 if (parsing_intf && (intf_nb <= MAX_INTF) ) {
va009039 9:7f9f64cf5ded 157 ENDPOINT_TYPE type = (ENDPOINT_TYPE)(ep_desc->bmAttributes & 0x03);
va009039 9:7f9f64cf5ded 158 ENDPOINT_DIRECTION dir = (ep_desc->bEndpointAddress & 0x80) ? IN : OUT;
va009039 9:7f9f64cf5ded 159 if(pEnumerator->useEndpoint(current_intf, type, dir)) {
va009039 10:40c7f6788902 160 ep = new USBEndpoint(dev);
va009039 10:40c7f6788902 161 ep->init(type, dir, ep_desc->wMaxPacketSize, ep_desc->bEndpointAddress);
va009039 9:7f9f64cf5ded 162 USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev);
va009039 9:7f9f64cf5ded 163 dev->addEndpoint(current_intf, ep);
va009039 8:6463cd1964c0 164 }
va009039 8:6463cd1964c0 165 }
va009039 8:6463cd1964c0 166 break;
va009039 8:6463cd1964c0 167 case HID_DESCRIPTOR:
va009039 8:6463cd1964c0 168 //lenReportDescr = conf_descr[index + 7] | (conf_descr[index + 8] << 8);
va009039 8:6463cd1964c0 169 break;
va009039 8:6463cd1964c0 170 default:
va009039 8:6463cd1964c0 171 break;
va009039 7:9a20482c9a7a 172 }
va009039 8:6463cd1964c0 173 index += len_desc;
va009039 7:9a20482c9a7a 174 }
va009039 7:9a20482c9a7a 175 }
va009039 7:9a20482c9a7a 176
va009039 7:9a20482c9a7a 177 USB_TYPE USBHost::controlRead(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
va009039 7:9a20482c9a7a 178 SETUP_PACKET setup = {requestType, request, value, index};
va009039 8:6463cd1964c0 179 int result = ControlRead(dev, &setup, buf, len);
va009039 8:6463cd1964c0 180 //USB_DBG2("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 181 return (result >= 0) ? USB_TYPE_OK : USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 182 }
va009039 7:9a20482c9a7a 183
va009039 7:9a20482c9a7a 184 USB_TYPE USBHost::controlWrite(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
va009039 7:9a20482c9a7a 185 SETUP_PACKET setup = {requestType, request, value, index};
va009039 8:6463cd1964c0 186 int result = ControlWrite(dev, &setup, buf, len);
va009039 7:9a20482c9a7a 187 if (result >= 0) {
va009039 7:9a20482c9a7a 188 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 189 }
va009039 7:9a20482c9a7a 190 USB_DBG("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 191 USB_DBG_HEX(buf, len);
va009039 7:9a20482c9a7a 192 return USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 193 }
va009039 7:9a20482c9a7a 194
va009039 9:7f9f64cf5ded 195 USB_TYPE USBHost::bulkRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 9:7f9f64cf5ded 196 if (blocking == false) {
va009039 9:7f9f64cf5ded 197 ep->setBuffer(buf, len);
va009039 9:7f9f64cf5ded 198 ep_queue.push(ep);
va009039 9:7f9f64cf5ded 199 return USB_TYPE_PROCESSING;
va009039 9:7f9f64cf5ded 200 }
va009039 9:7f9f64cf5ded 201 int result = bulkReadBLOCK(ep, buf, len, -1);
va009039 7:9a20482c9a7a 202 if (result >= 0) {
va009039 7:9a20482c9a7a 203 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 204 }
va009039 7:9a20482c9a7a 205 //USB_DBG2("result=%d %02x", result, host->LastStatus);
va009039 7:9a20482c9a7a 206 return USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 207 }
va009039 7:9a20482c9a7a 208
va009039 9:7f9f64cf5ded 209 USB_TYPE USBHost::bulkWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 7:9a20482c9a7a 210 USB_TEST_ASSERT(blocking);
va009039 9:7f9f64cf5ded 211 int result = bulkWriteNB(ep, buf, len);
va009039 7:9a20482c9a7a 212 if (result >= 0) {
va009039 7:9a20482c9a7a 213 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 214 }
va009039 7:9a20482c9a7a 215 USB_DBG2("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 216 return USB_TYPE_ERROR;
va009039 7:9a20482c9a7a 217 }
va009039 7:9a20482c9a7a 218
va009039 9:7f9f64cf5ded 219 USB_TYPE USBHost::interruptRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 9:7f9f64cf5ded 220 if (blocking == false) {
va009039 9:7f9f64cf5ded 221 ep->setBuffer(buf, len);
va009039 9:7f9f64cf5ded 222 ep_queue.push(ep);
va009039 9:7f9f64cf5ded 223 return USB_TYPE_PROCESSING;
va009039 7:9a20482c9a7a 224 }
va009039 9:7f9f64cf5ded 225 interruptReadNB(ep, buf, len);
va009039 9:7f9f64cf5ded 226 return USB_TYPE_OK;
va009039 9:7f9f64cf5ded 227 }
va009039 9:7f9f64cf5ded 228
va009039 9:7f9f64cf5ded 229 USB_TYPE USBHost::interruptWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 9:7f9f64cf5ded 230 USB_TEST_ASSERT(blocking);
va009039 9:7f9f64cf5ded 231 interruptWriteNB(ep, buf, len);
va009039 9:7f9f64cf5ded 232 return USB_TYPE_OK;
va009039 9:7f9f64cf5ded 233 }
va009039 9:7f9f64cf5ded 234
va009039 9:7f9f64cf5ded 235 USB_TYPE USBHost::isochronousRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) {
va009039 9:7f9f64cf5ded 236 if (blocking == false) {
va009039 9:7f9f64cf5ded 237 ep->setBuffer(buf, len);
va009039 9:7f9f64cf5ded 238 ep_queue.push(ep);
va009039 9:7f9f64cf5ded 239 return USB_TYPE_PROCESSING;
va009039 9:7f9f64cf5ded 240 }
va009039 9:7f9f64cf5ded 241 isochronousReadNB(ep, buf, len);
va009039 9:7f9f64cf5ded 242 return USB_TYPE_OK;
va009039 7:9a20482c9a7a 243 }
va009039 7:9a20482c9a7a 244
va009039 8:6463cd1964c0 245 int USBHost::ControlRead(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data, int size) {
va009039 8:6463cd1964c0 246 USB_TEST_ASSERT(dev);
va009039 8:6463cd1964c0 247 USBEndpoint* ep = dev->getEpCtl();
va009039 8:6463cd1964c0 248 USB_TEST_ASSERT(ep);
va009039 8:6463cd1964c0 249 setAddr(dev->getAddress(), dev->getSpeed());
va009039 7:9a20482c9a7a 250 token_setup(ep, setup, size); // setup stage
va009039 7:9a20482c9a7a 251 if (LastStatus != ACK) {
va009039 7:9a20482c9a7a 252 USB_DBG("setup %02x", LastStatus);
va009039 7:9a20482c9a7a 253 return -1;
va009039 7:9a20482c9a7a 254 }
va009039 7:9a20482c9a7a 255 int read_len = 0;
va009039 7:9a20482c9a7a 256 while(read_len < size) {
va009039 7:9a20482c9a7a 257 int size2 = std::min(size-read_len, ep->getSize());
va009039 7:9a20482c9a7a 258 int result = token_in(ep, data+read_len, size2);
va009039 7:9a20482c9a7a 259 //USB_DBG("token_in result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 260 if (result < 0) {
va009039 7:9a20482c9a7a 261 USB_DBG("token_in %d/%d %02x", read_len, size, LastStatus);
va009039 7:9a20482c9a7a 262 return result;
va009039 7:9a20482c9a7a 263 }
va009039 7:9a20482c9a7a 264 read_len += result;
va009039 7:9a20482c9a7a 265 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 266 break;
va009039 7:9a20482c9a7a 267 }
va009039 7:9a20482c9a7a 268 }
va009039 7:9a20482c9a7a 269 ep->setData01(DATA1);
va009039 7:9a20482c9a7a 270 int result = token_out(ep); // status stage
va009039 7:9a20482c9a7a 271 if (result < 0) {
va009039 7:9a20482c9a7a 272 USB_DBG("status token_out %02x", LastStatus);
va009039 7:9a20482c9a7a 273 if (LastStatus == STALL) {
va009039 8:6463cd1964c0 274 ep->setLengthTransferred(read_len);
va009039 7:9a20482c9a7a 275 return read_len;
va009039 7:9a20482c9a7a 276 }
va009039 7:9a20482c9a7a 277 return result;
va009039 7:9a20482c9a7a 278 }
va009039 8:6463cd1964c0 279 ep->setLengthTransferred(read_len);
va009039 7:9a20482c9a7a 280 return read_len;
va009039 7:9a20482c9a7a 281 }
va009039 7:9a20482c9a7a 282
va009039 8:6463cd1964c0 283 int USBHost::ControlWrite(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data, int size) {
va009039 8:6463cd1964c0 284 USB_TEST_ASSERT(dev);
va009039 8:6463cd1964c0 285 USBEndpoint* ep = dev->getEpCtl();
va009039 8:6463cd1964c0 286 USB_TEST_ASSERT(ep);
va009039 8:6463cd1964c0 287 setAddr(dev->getAddress(), dev->getSpeed());
va009039 7:9a20482c9a7a 288 token_setup(ep, setup, size); // setup stage
va009039 7:9a20482c9a7a 289 if (LastStatus != ACK) {
va009039 7:9a20482c9a7a 290 USB_DBG("setup %02x", LastStatus);
va009039 7:9a20482c9a7a 291 return -1;
va009039 7:9a20482c9a7a 292 }
va009039 7:9a20482c9a7a 293 int write_len = 0;
va009039 7:9a20482c9a7a 294 if (data != NULL) {
va009039 7:9a20482c9a7a 295 write_len = token_out(ep, data, size);
va009039 7:9a20482c9a7a 296 if (write_len < 0) {
va009039 7:9a20482c9a7a 297 return -1;
va009039 7:9a20482c9a7a 298 }
va009039 7:9a20482c9a7a 299 }
va009039 7:9a20482c9a7a 300 ep->setData01(DATA1);
va009039 7:9a20482c9a7a 301 int result = token_in(ep); // status stage
va009039 7:9a20482c9a7a 302 if (result < 0) {
va009039 7:9a20482c9a7a 303 USB_DBG("result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 304 //return result;
va009039 7:9a20482c9a7a 305 }
va009039 8:6463cd1964c0 306 ep->setLengthTransferred(write_len);
va009039 7:9a20482c9a7a 307 return write_len;
va009039 7:9a20482c9a7a 308 }
va009039 7:9a20482c9a7a 309
va009039 9:7f9f64cf5ded 310 int USBHost::interruptReadNB(USBEndpoint* ep, uint8_t* data, int size)
va009039 9:7f9f64cf5ded 311 {
va009039 8:6463cd1964c0 312 USB_TEST_ASSERT(ep);
va009039 8:6463cd1964c0 313 USBDeviceConnected* dev = ep->getDevice();
va009039 8:6463cd1964c0 314 USB_TEST_ASSERT(dev);
va009039 8:6463cd1964c0 315 setAddr(dev->getAddress(), dev->getSpeed());
va009039 7:9a20482c9a7a 316 setEndpoint();
va009039 7:9a20482c9a7a 317 const int retryLimit = 0;
va009039 7:9a20482c9a7a 318 int read_len = 0;
va009039 7:9a20482c9a7a 319 for(int n = 0; read_len < size; n++) {
va009039 7:9a20482c9a7a 320 int size2 = std::min(size-read_len, ep->getSize());
va009039 7:9a20482c9a7a 321 int result = token_in(ep, data+read_len, size2, retryLimit);
va009039 7:9a20482c9a7a 322 if (result < 0) {
va009039 7:9a20482c9a7a 323 if (LastStatus == NAK) {
va009039 7:9a20482c9a7a 324 if (n == 0) {
va009039 7:9a20482c9a7a 325 return -1;
va009039 7:9a20482c9a7a 326 }
va009039 7:9a20482c9a7a 327 break;
va009039 7:9a20482c9a7a 328 }
va009039 8:6463cd1964c0 329 //USB_DBG("token_in result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 330 return result;
va009039 7:9a20482c9a7a 331 }
va009039 7:9a20482c9a7a 332 read_len += result;
va009039 7:9a20482c9a7a 333 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 334 break;
va009039 7:9a20482c9a7a 335 }
va009039 7:9a20482c9a7a 336 }
va009039 8:6463cd1964c0 337 ep->setLengthTransferred(read_len);
va009039 7:9a20482c9a7a 338 return read_len;
va009039 7:9a20482c9a7a 339 }
va009039 7:9a20482c9a7a 340
va009039 9:7f9f64cf5ded 341 int USBHost::interruptWriteNB(USBEndpoint* ep, const uint8_t* data, int size)
va009039 9:7f9f64cf5ded 342 {
va009039 9:7f9f64cf5ded 343 USB_TEST_ASSERT(ep);
va009039 9:7f9f64cf5ded 344 USBDeviceConnected* dev = ep->getDevice();
va009039 9:7f9f64cf5ded 345 USB_TEST_ASSERT(dev);
va009039 9:7f9f64cf5ded 346 setAddr(dev->getAddress(), dev->getSpeed());
va009039 9:7f9f64cf5ded 347 setEndpoint();
va009039 9:7f9f64cf5ded 348 const int retryLimit = 0;
va009039 9:7f9f64cf5ded 349 int transferred_len = 0;
va009039 9:7f9f64cf5ded 350 for(int n = 0; transferred_len < size; n++) {
va009039 9:7f9f64cf5ded 351 int size2 = std::min(size-transferred_len, ep->getSize());
va009039 9:7f9f64cf5ded 352 int result = token_out(ep, data+transferred_len, size2, retryLimit);
va009039 9:7f9f64cf5ded 353 if (result < 0) {
va009039 9:7f9f64cf5ded 354 if (LastStatus == NAK) {
va009039 9:7f9f64cf5ded 355 if (n == 0) {
va009039 9:7f9f64cf5ded 356 return -1;
va009039 9:7f9f64cf5ded 357 }
va009039 9:7f9f64cf5ded 358 break;
va009039 9:7f9f64cf5ded 359 }
va009039 9:7f9f64cf5ded 360 //USB_DBG("token_in result=%d %02x", result, LastStatus);
va009039 9:7f9f64cf5ded 361 return result;
va009039 9:7f9f64cf5ded 362 }
va009039 9:7f9f64cf5ded 363 transferred_len += result;
va009039 9:7f9f64cf5ded 364 if (result < ep->getSize()) {
va009039 9:7f9f64cf5ded 365 break;
va009039 9:7f9f64cf5ded 366 }
va009039 9:7f9f64cf5ded 367 }
va009039 9:7f9f64cf5ded 368 ep->setLengthTransferred(transferred_len);
va009039 9:7f9f64cf5ded 369 return transferred_len;
va009039 9:7f9f64cf5ded 370 }
va009039 9:7f9f64cf5ded 371
va009039 9:7f9f64cf5ded 372 int USBHost::bulkReadNB(USBEndpoint* ep, uint8_t* data, int size)
va009039 9:7f9f64cf5ded 373 {
va009039 9:7f9f64cf5ded 374 return bulkReadBLOCK(ep, data, size, 0);
va009039 9:7f9f64cf5ded 375 }
va009039 9:7f9f64cf5ded 376
va009039 9:7f9f64cf5ded 377 int USBHost::bulkReadBLOCK(USBEndpoint* ep, uint8_t* data, int size, int timeout_ms) {
va009039 8:6463cd1964c0 378 USB_TEST_ASSERT(ep);
va009039 8:6463cd1964c0 379 USBDeviceConnected* dev = ep->getDevice();
va009039 8:6463cd1964c0 380 USB_TEST_ASSERT(dev);
va009039 8:6463cd1964c0 381 setAddr(dev->getAddress());
va009039 7:9a20482c9a7a 382 setEndpoint();
va009039 7:9a20482c9a7a 383 int retryLimit = (timeout_ms == 0) ? 0 : 10;
va009039 7:9a20482c9a7a 384 int read_len = 0;
va009039 7:9a20482c9a7a 385 Timer t;
va009039 7:9a20482c9a7a 386 for(int n = 0; read_len < size; n++) {
va009039 7:9a20482c9a7a 387 int size2 = std::min(size-read_len, ep->getSize());
va009039 7:9a20482c9a7a 388 int result = token_in(ep, data+read_len, size2, retryLimit);
va009039 7:9a20482c9a7a 389 if (result < 0) {
va009039 7:9a20482c9a7a 390 if (LastStatus == NAK) {
va009039 7:9a20482c9a7a 391 if (n == 0) {
va009039 7:9a20482c9a7a 392 return -1;
va009039 7:9a20482c9a7a 393 }
va009039 7:9a20482c9a7a 394 break;
va009039 7:9a20482c9a7a 395 }
va009039 8:6463cd1964c0 396 //USB_DBG("token_in result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 397 return result;
va009039 7:9a20482c9a7a 398 }
va009039 7:9a20482c9a7a 399 read_len += result;
va009039 7:9a20482c9a7a 400 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 401 break;
va009039 7:9a20482c9a7a 402 }
va009039 7:9a20482c9a7a 403 if (timeout_ms > 0 && t.read_ms() > timeout_ms) {
va009039 7:9a20482c9a7a 404 USB_DBG("timeout_ms: %d", timeout_ms);
va009039 7:9a20482c9a7a 405 break;
va009039 7:9a20482c9a7a 406 }
va009039 7:9a20482c9a7a 407 }
va009039 8:6463cd1964c0 408 ep->setLengthTransferred(read_len);
va009039 7:9a20482c9a7a 409 return read_len;
va009039 7:9a20482c9a7a 410 }
va009039 7:9a20482c9a7a 411
va009039 9:7f9f64cf5ded 412 int USBHost::bulkWriteNB(USBEndpoint* ep, const uint8_t* data, int size) {
va009039 8:6463cd1964c0 413 USB_TEST_ASSERT(ep);
va009039 8:6463cd1964c0 414 USBDeviceConnected* dev = ep->getDevice();
va009039 8:6463cd1964c0 415 USB_TEST_ASSERT(dev);
va009039 8:6463cd1964c0 416 setAddr(dev->getAddress());
va009039 7:9a20482c9a7a 417 setEndpoint();
va009039 7:9a20482c9a7a 418 int write_len = 0;
va009039 7:9a20482c9a7a 419 for(int n = 0; write_len < size; n++) {
va009039 7:9a20482c9a7a 420 int size2 = std::min(size-write_len, ep->getSize());
va009039 7:9a20482c9a7a 421 int result = token_out(ep, data+write_len, size2);
va009039 7:9a20482c9a7a 422 if (result < 0) {
va009039 7:9a20482c9a7a 423 if (LastStatus == NAK) {
va009039 7:9a20482c9a7a 424 if (n == 0) {
va009039 7:9a20482c9a7a 425 return -1;
va009039 7:9a20482c9a7a 426 }
va009039 7:9a20482c9a7a 427 break;
va009039 7:9a20482c9a7a 428 }
va009039 7:9a20482c9a7a 429 USB_DBG("token_out result=%d %02x", result, LastStatus);
va009039 7:9a20482c9a7a 430 return result;
va009039 7:9a20482c9a7a 431 }
va009039 7:9a20482c9a7a 432 write_len += result;
va009039 7:9a20482c9a7a 433 if (result < ep->getSize()) {
va009039 7:9a20482c9a7a 434 break;
va009039 7:9a20482c9a7a 435 }
va009039 7:9a20482c9a7a 436 }
va009039 8:6463cd1964c0 437 ep->setLengthTransferred(write_len);
va009039 7:9a20482c9a7a 438 return write_len;
va009039 7:9a20482c9a7a 439 }
va009039 7:9a20482c9a7a 440
va009039 9:7f9f64cf5ded 441 int USBHost::isochronousReadNB(USBEndpoint* ep, uint8_t* data, int size) {
va009039 8:6463cd1964c0 442 USBDeviceConnected* dev = ep->getDevice();
va009039 8:6463cd1964c0 443 USB_TEST_ASSERT(dev);
va009039 8:6463cd1964c0 444 setAddr(dev->getAddress());
va009039 8:6463cd1964c0 445 int result = token_iso_in(ep, data, size);
va009039 8:6463cd1964c0 446 if (result >= 0) {
va009039 8:6463cd1964c0 447 ep->setLengthTransferred(result);
va009039 8:6463cd1964c0 448 }
va009039 8:6463cd1964c0 449 return result;
va009039 7:9a20482c9a7a 450 }
va009039 7:9a20482c9a7a 451
va009039 9:7f9f64cf5ded 452 void USBHost::task()
va009039 9:7f9f64cf5ded 453 {
va009039 9:7f9f64cf5ded 454 if (ep_queue.empty()) {
va009039 9:7f9f64cf5ded 455 return;
va009039 9:7f9f64cf5ded 456 }
va009039 9:7f9f64cf5ded 457 USBEndpoint* ep = ep_queue.pop();
va009039 9:7f9f64cf5ded 458 USB_TEST_ASSERT(ep);
va009039 9:7f9f64cf5ded 459 ep->setLengthTransferred(0);
va009039 9:7f9f64cf5ded 460 switch(ep->getType()) {
va009039 9:7f9f64cf5ded 461 case INTERRUPT_ENDPOINT:
va009039 9:7f9f64cf5ded 462 if (ep->getDir() == IN) {
va009039 9:7f9f64cf5ded 463 interruptReadNB(ep, ep->getBufStart(), ep->getBufSize());
va009039 9:7f9f64cf5ded 464 }
va009039 9:7f9f64cf5ded 465 break;
va009039 9:7f9f64cf5ded 466 case BULK_ENDPOINT:
va009039 9:7f9f64cf5ded 467 if (ep->getDir() == IN) {
va009039 9:7f9f64cf5ded 468 bulkReadNB(ep, ep->getBufStart(), ep->getBufSize());
va009039 9:7f9f64cf5ded 469 }
va009039 9:7f9f64cf5ded 470 break;
va009039 9:7f9f64cf5ded 471 case ISOCHRONOUS_ENDPOINT:
va009039 9:7f9f64cf5ded 472 if (ep->getDir() == IN) {
va009039 9:7f9f64cf5ded 473 isochronousReadNB(ep, ep->getBufStart(), ep->getBufSize());
va009039 9:7f9f64cf5ded 474 }
va009039 9:7f9f64cf5ded 475 break;
va009039 9:7f9f64cf5ded 476 }
va009039 9:7f9f64cf5ded 477 ep->call();
va009039 9:7f9f64cf5ded 478 }