final

Dependencies:   mbed FATFileSystem

Fork of KL46Z-USBHostMSD_HelloWorld by Norimasa Okamoto

Committer:
homzovam
Date:
Sat Apr 04 20:16:39 2015 +0000
Revision:
4:77d6450f34d7
prijimac-funkcni final

Who changed what in which revision?

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