Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

Committer:
hudakz
Date:
Sun Jul 12 20:39:26 2020 +0000
Revision:
0:84353c479782
Child:
1:2263e77400e9
MAX3421E-based USB Host Shield Library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:84353c479782 1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
hudakz 0:84353c479782 2
hudakz 0:84353c479782 3 This software may be distributed and modified under the terms of the GNU
hudakz 0:84353c479782 4 General Public License version 2 (GPL2) as published by the Free Software
hudakz 0:84353c479782 5 Foundation and appearing in the file GPL2.TXT included in the packaging of
hudakz 0:84353c479782 6 this file. Please note that GPL2 Section 2[b] requires that all works based
hudakz 0:84353c479782 7 on this software must also be made publicly available under the terms of
hudakz 0:84353c479782 8 the GPL2 ("Copyleft").
hudakz 0:84353c479782 9
hudakz 0:84353c479782 10 Contact information
hudakz 0:84353c479782 11 -------------------
hudakz 0:84353c479782 12
hudakz 0:84353c479782 13 Circuits At Home, LTD
hudakz 0:84353c479782 14 Web : http://www.circuitsathome.com
hudakz 0:84353c479782 15 e-mail : support@circuitsathome.com
hudakz 0:84353c479782 16 */
hudakz 0:84353c479782 17 #include "cdcftdi.h"
hudakz 0:84353c479782 18
hudakz 0:84353c479782 19 const uint8_t FTDI::epDataInIndex = 1;
hudakz 0:84353c479782 20 const uint8_t FTDI::epDataOutIndex = 2;
hudakz 0:84353c479782 21 const uint8_t FTDI::epInterruptInIndex = 3;
hudakz 0:84353c479782 22
hudakz 0:84353c479782 23 FTDI::FTDI(USB *p, FTDIAsyncOper *pasync, uint16_t idProduct) :
hudakz 0:84353c479782 24 pAsync(pasync),
hudakz 0:84353c479782 25 pUsb(p),
hudakz 0:84353c479782 26 bAddress(0),
hudakz 0:84353c479782 27 bNumEP(1),
hudakz 0:84353c479782 28 wFTDIType(0),
hudakz 0:84353c479782 29 wIdProduct(idProduct) {
hudakz 0:84353c479782 30 for(uint8_t i = 0; i < FTDI_MAX_ENDPOINTS; i++) {
hudakz 0:84353c479782 31 epInfo[i].epAddr = 0;
hudakz 0:84353c479782 32 epInfo[i].maxPktSize = (i) ? 0 : 8;
hudakz 0:84353c479782 33 epInfo[i].bmSndToggle = 0;
hudakz 0:84353c479782 34 epInfo[i].bmRcvToggle = 0;
hudakz 0:84353c479782 35 epInfo[i].bmNakPower = (i == epDataInIndex) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
hudakz 0:84353c479782 36 }
hudakz 0:84353c479782 37 if(pUsb)
hudakz 0:84353c479782 38 pUsb->RegisterDeviceClass(this);
hudakz 0:84353c479782 39 }
hudakz 0:84353c479782 40
hudakz 0:84353c479782 41 uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
hudakz 0:84353c479782 42 const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
hudakz 0:84353c479782 43
hudakz 0:84353c479782 44 uint8_t buf[constBufSize];
hudakz 0:84353c479782 45 USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
hudakz 0:84353c479782 46 uint8_t rcode;
hudakz 0:84353c479782 47 UsbDevice *p = NULL;
hudakz 0:84353c479782 48 EpInfo *oldep_ptr = NULL;
hudakz 0:84353c479782 49
hudakz 0:84353c479782 50 uint8_t num_of_conf; // number of configurations
hudakz 0:84353c479782 51
hudakz 0:84353c479782 52 AddressPool &addrPool = pUsb->GetAddressPool();
hudakz 0:84353c479782 53
hudakz 0:84353c479782 54 USBTRACE("FTDI Init\r\n");
hudakz 0:84353c479782 55
hudakz 0:84353c479782 56 if(bAddress) {
hudakz 0:84353c479782 57 USBTRACE("FTDI CLASS IN USE??\r\n");
hudakz 0:84353c479782 58 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
hudakz 0:84353c479782 59 }
hudakz 0:84353c479782 60 // Get pointer to pseudo device with address 0 assigned
hudakz 0:84353c479782 61 p = addrPool.GetUsbDevicePtr(0);
hudakz 0:84353c479782 62
hudakz 0:84353c479782 63 if(!p) {
hudakz 0:84353c479782 64 USBTRACE("FTDI NO ADDRESS??\r\n");
hudakz 0:84353c479782 65 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
hudakz 0:84353c479782 66 }
hudakz 0:84353c479782 67 if(!p->epinfo) {
hudakz 0:84353c479782 68 USBTRACE("epinfo\r\n");
hudakz 0:84353c479782 69 return USB_ERROR_EPINFO_IS_NULL;
hudakz 0:84353c479782 70 }
hudakz 0:84353c479782 71
hudakz 0:84353c479782 72 // Save old pointer to EP_RECORD of address 0
hudakz 0:84353c479782 73 oldep_ptr = p->epinfo;
hudakz 0:84353c479782 74
hudakz 0:84353c479782 75 // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
hudakz 0:84353c479782 76 p->epinfo = epInfo;
hudakz 0:84353c479782 77
hudakz 0:84353c479782 78 p->lowspeed = lowspeed;
hudakz 0:84353c479782 79
hudakz 0:84353c479782 80 // Get device descriptor
hudakz 0:84353c479782 81 rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), buf);
hudakz 0:84353c479782 82
hudakz 0:84353c479782 83 // Restore p->epinfo
hudakz 0:84353c479782 84 p->epinfo = oldep_ptr;
hudakz 0:84353c479782 85
hudakz 0:84353c479782 86 if(rcode) {
hudakz 0:84353c479782 87 goto FailGetDevDescr;
hudakz 0:84353c479782 88 }
hudakz 0:84353c479782 89 if(udd->idVendor != FTDI_VID || udd->idProduct != wIdProduct) {
hudakz 0:84353c479782 90 USBTRACE("FTDI Init: Product not supported\r\n");
hudakz 0:84353c479782 91 USBTRACE2("Expected VID:", FTDI_VID);
hudakz 0:84353c479782 92 USBTRACE2("Found VID:", udd->idVendor);
hudakz 0:84353c479782 93
hudakz 0:84353c479782 94 USBTRACE2("Expected PID:", wIdProduct);
hudakz 0:84353c479782 95 USBTRACE2("Found PID:", udd->idProduct);
hudakz 0:84353c479782 96 return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
hudakz 0:84353c479782 97 }
hudakz 0:84353c479782 98
hudakz 0:84353c479782 99 // Save type of FTDI chip
hudakz 0:84353c479782 100 wFTDIType = udd->bcdDevice;
hudakz 0:84353c479782 101
hudakz 0:84353c479782 102 // Allocate new address according to device class
hudakz 0:84353c479782 103 bAddress = addrPool.AllocAddress(parent, false, port);
hudakz 0:84353c479782 104
hudakz 0:84353c479782 105 if(!bAddress)
hudakz 0:84353c479782 106 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
hudakz 0:84353c479782 107
hudakz 0:84353c479782 108 // Extract Max Packet Size from the device descriptor
hudakz 0:84353c479782 109 epInfo[0].maxPktSize = udd->bMaxPacketSize0;
hudakz 0:84353c479782 110 // Some devices set endpoint lengths to zero, which is incorrect.
hudakz 0:84353c479782 111 // we should check them, and if zero, set them to 64.
hudakz 0:84353c479782 112 if(epInfo[0].maxPktSize == 0) epInfo[0].maxPktSize = 64;
hudakz 0:84353c479782 113
hudakz 0:84353c479782 114 // Assign new address to the device
hudakz 0:84353c479782 115 rcode = pUsb->setAddr(0, 0, bAddress);
hudakz 0:84353c479782 116
hudakz 0:84353c479782 117 if(rcode) {
hudakz 0:84353c479782 118 p->lowspeed = false;
hudakz 0:84353c479782 119 addrPool.FreeAddress(bAddress);
hudakz 0:84353c479782 120 bAddress = 0;
hudakz 0:84353c479782 121 USBTRACE2("setAddr:", rcode);
hudakz 0:84353c479782 122 return rcode;
hudakz 0:84353c479782 123 }
hudakz 0:84353c479782 124
hudakz 0:84353c479782 125 USBTRACE2("Addr:", bAddress);
hudakz 0:84353c479782 126
hudakz 0:84353c479782 127 p->lowspeed = false;
hudakz 0:84353c479782 128
hudakz 0:84353c479782 129 p = addrPool.GetUsbDevicePtr(bAddress);
hudakz 0:84353c479782 130
hudakz 0:84353c479782 131 if(!p)
hudakz 0:84353c479782 132 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
hudakz 0:84353c479782 133
hudakz 0:84353c479782 134 p->lowspeed = lowspeed;
hudakz 0:84353c479782 135
hudakz 0:84353c479782 136 num_of_conf = udd->bNumConfigurations;
hudakz 0:84353c479782 137
hudakz 0:84353c479782 138 // Assign epInfo to epinfo pointer
hudakz 0:84353c479782 139 rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
hudakz 0:84353c479782 140
hudakz 0:84353c479782 141 if(rcode)
hudakz 0:84353c479782 142 goto FailSetDevTblEntry;
hudakz 0:84353c479782 143
hudakz 0:84353c479782 144 USBTRACE2("NC:", num_of_conf);
hudakz 0:84353c479782 145
hudakz 0:84353c479782 146 for(uint8_t i = 0; i < num_of_conf; i++) {
hudakz 0:84353c479782 147 ConfigDescParser < 0xFF, 0xFF, 0xFF, CP_MASK_COMPARE_ALL> confDescrParser(this);
hudakz 0:84353c479782 148
hudakz 0:84353c479782 149 // This interferes with serial output, and should be opt-in for debugging.
hudakz 0:84353c479782 150 //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
hudakz 0:84353c479782 151 //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
hudakz 0:84353c479782 152 //if(rcode)
hudakz 0:84353c479782 153 // goto FailGetConfDescr;
hudakz 0:84353c479782 154
hudakz 0:84353c479782 155 rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
hudakz 0:84353c479782 156
hudakz 0:84353c479782 157 if(rcode)
hudakz 0:84353c479782 158 goto FailGetConfDescr;
hudakz 0:84353c479782 159
hudakz 0:84353c479782 160 if(bNumEP > 1)
hudakz 0:84353c479782 161 break;
hudakz 0:84353c479782 162 } // for
hudakz 0:84353c479782 163
hudakz 0:84353c479782 164 if(bNumEP < 2)
hudakz 0:84353c479782 165 return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
hudakz 0:84353c479782 166
hudakz 0:84353c479782 167 USBTRACE2("NumEP:", bNumEP);
hudakz 0:84353c479782 168
hudakz 0:84353c479782 169 // Assign epInfo to epinfo pointer
hudakz 0:84353c479782 170 rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
hudakz 0:84353c479782 171
hudakz 0:84353c479782 172 USBTRACE2("Conf:", bConfNum);
hudakz 0:84353c479782 173
hudakz 0:84353c479782 174 // Set Configuration Value
hudakz 0:84353c479782 175 rcode = pUsb->setConf(bAddress, 0, bConfNum);
hudakz 0:84353c479782 176
hudakz 0:84353c479782 177 if(rcode)
hudakz 0:84353c479782 178 goto FailSetConfDescr;
hudakz 0:84353c479782 179
hudakz 0:84353c479782 180 // default latency is 16ms on-chip, reduce it to 1
hudakz 0:84353c479782 181 rcode = SetLatency(1);
hudakz 0:84353c479782 182 if(rcode)
hudakz 0:84353c479782 183 goto FailOnLatency;
hudakz 0:84353c479782 184
hudakz 0:84353c479782 185
hudakz 0:84353c479782 186 rcode = pAsync->OnInit(this);
hudakz 0:84353c479782 187
hudakz 0:84353c479782 188 if(rcode)
hudakz 0:84353c479782 189 goto FailOnInit;
hudakz 0:84353c479782 190
hudakz 0:84353c479782 191 USBTRACE("FTDI configured\r\n");
hudakz 0:84353c479782 192
hudakz 0:84353c479782 193 ready = true;
hudakz 0:84353c479782 194 return 0;
hudakz 0:84353c479782 195
hudakz 0:84353c479782 196 FailOnLatency:
hudakz 0:84353c479782 197 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 198 USBTRACE("SetLatency: ");
hudakz 0:84353c479782 199 goto Fail;
hudakz 0:84353c479782 200 #endif
hudakz 0:84353c479782 201
hudakz 0:84353c479782 202 FailGetDevDescr:
hudakz 0:84353c479782 203 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 204 NotifyFailGetDevDescr();
hudakz 0:84353c479782 205 goto Fail;
hudakz 0:84353c479782 206 #endif
hudakz 0:84353c479782 207
hudakz 0:84353c479782 208 FailSetDevTblEntry:
hudakz 0:84353c479782 209 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 210 NotifyFailSetDevTblEntry();
hudakz 0:84353c479782 211 goto Fail;
hudakz 0:84353c479782 212 #endif
hudakz 0:84353c479782 213
hudakz 0:84353c479782 214 FailGetConfDescr:
hudakz 0:84353c479782 215 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 216 NotifyFailGetConfDescr();
hudakz 0:84353c479782 217 goto Fail;
hudakz 0:84353c479782 218 #endif
hudakz 0:84353c479782 219
hudakz 0:84353c479782 220 FailSetConfDescr:
hudakz 0:84353c479782 221 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 222 NotifyFailSetConfDescr();
hudakz 0:84353c479782 223 goto Fail;
hudakz 0:84353c479782 224 #endif
hudakz 0:84353c479782 225
hudakz 0:84353c479782 226 FailOnInit:
hudakz 0:84353c479782 227 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 228 USBTRACE("OnInit:");
hudakz 0:84353c479782 229
hudakz 0:84353c479782 230 Fail:
hudakz 0:84353c479782 231 NotifyFail(rcode);
hudakz 0:84353c479782 232 #endif
hudakz 0:84353c479782 233 Release();
hudakz 0:84353c479782 234 return rcode;
hudakz 0:84353c479782 235 }
hudakz 0:84353c479782 236
hudakz 0:84353c479782 237 void FTDI::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *pep) {
hudakz 0:84353c479782 238 ErrorMessage<uint8_t > (PSTR("Conf.Val"), conf);
hudakz 0:84353c479782 239 ErrorMessage<uint8_t > (PSTR("Iface Num"), iface);
hudakz 0:84353c479782 240 ErrorMessage<uint8_t > (PSTR("Alt.Set"), alt);
hudakz 0:84353c479782 241
hudakz 0:84353c479782 242 bConfNum = conf;
hudakz 0:84353c479782 243
hudakz 0:84353c479782 244 uint8_t index;
hudakz 0:84353c479782 245
hudakz 0:84353c479782 246 if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT && (pep->bEndpointAddress & 0x80) == 0x80)
hudakz 0:84353c479782 247 index = epInterruptInIndex;
hudakz 0:84353c479782 248 else if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_BULK)
hudakz 0:84353c479782 249 index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
hudakz 0:84353c479782 250 else
hudakz 0:84353c479782 251 return;
hudakz 0:84353c479782 252
hudakz 0:84353c479782 253 // Fill in the endpoint info structure
hudakz 0:84353c479782 254 epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
hudakz 0:84353c479782 255 epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
hudakz 0:84353c479782 256 epInfo[index].bmSndToggle = 0;
hudakz 0:84353c479782 257 epInfo[index].bmRcvToggle = 0;
hudakz 0:84353c479782 258 // Some device vendors set endpoint lengths to zero, which is incorrect.
hudakz 0:84353c479782 259 // Check, and if zero, set to 64.
hudakz 0:84353c479782 260 if(epInfo[index].maxPktSize == 0) epInfo[index].maxPktSize = 64;
hudakz 0:84353c479782 261
hudakz 0:84353c479782 262 bNumEP++;
hudakz 0:84353c479782 263
hudakz 0:84353c479782 264 PrintEndpointDescriptor(pep);
hudakz 0:84353c479782 265 }
hudakz 0:84353c479782 266
hudakz 0:84353c479782 267 uint8_t FTDI::Release() {
hudakz 0:84353c479782 268 pUsb->GetAddressPool().FreeAddress(bAddress);
hudakz 0:84353c479782 269
hudakz 0:84353c479782 270 bAddress = 0;
hudakz 0:84353c479782 271 bNumEP = 1;
hudakz 0:84353c479782 272 qNextPollTime = 0;
hudakz 0:84353c479782 273 bPollEnable = false;
hudakz 0:84353c479782 274 ready = false;
hudakz 0:84353c479782 275 return pAsync->OnRelease(this);
hudakz 0:84353c479782 276 }
hudakz 0:84353c479782 277
hudakz 0:84353c479782 278 uint8_t FTDI::Poll() {
hudakz 0:84353c479782 279 uint8_t rcode = 0;
hudakz 0:84353c479782 280
hudakz 0:84353c479782 281 //if (!bPollEnable)
hudakz 0:84353c479782 282 // return 0;
hudakz 0:84353c479782 283
hudakz 0:84353c479782 284 //if (qNextPollTime <= (uint32_t)millis())
hudakz 0:84353c479782 285 //{
hudakz 0:84353c479782 286 // USB_HOST_SERIAL.println(bAddress, HEX);
hudakz 0:84353c479782 287
hudakz 0:84353c479782 288 // qNextPollTime = (uint32_t)millis() + 100;
hudakz 0:84353c479782 289 //}
hudakz 0:84353c479782 290 return rcode;
hudakz 0:84353c479782 291 }
hudakz 0:84353c479782 292
hudakz 0:84353c479782 293 uint8_t FTDI::SetBaudRate(uint32_t baud) {
hudakz 0:84353c479782 294 uint16_t baud_value, baud_index = 0;
hudakz 0:84353c479782 295 uint32_t divisor3;
hudakz 0:84353c479782 296 divisor3 = 48000000 / 2 / baud; // divisor shifted 3 bits to the left
hudakz 0:84353c479782 297
hudakz 0:84353c479782 298 if(wFTDIType == FT232AM) {
hudakz 0:84353c479782 299 if((divisor3 & 0x7) == 7)
hudakz 0:84353c479782 300 divisor3++; // round x.7/8 up to x+1
hudakz 0:84353c479782 301
hudakz 0:84353c479782 302 baud_value = divisor3 >> 3;
hudakz 0:84353c479782 303 divisor3 &= 0x7;
hudakz 0:84353c479782 304
hudakz 0:84353c479782 305 if(divisor3 == 1) baud_value |= 0xc000;
hudakz 0:84353c479782 306 else // 0.125
hudakz 0:84353c479782 307 if(divisor3 >= 4) baud_value |= 0x4000;
hudakz 0:84353c479782 308 else // 0.5
hudakz 0:84353c479782 309 if(divisor3 != 0) baud_value |= 0x8000; // 0.25
hudakz 0:84353c479782 310 if(baud_value == 1) baud_value = 0; /* special case for maximum baud rate */
hudakz 0:84353c479782 311 } else {
hudakz 0:84353c479782 312 static const uint8_t divfrac [8] = {0, 3, 2, 0, 1, 1, 2, 3};
hudakz 0:84353c479782 313 static const uint8_t divindex[8] = {0, 0, 0, 1, 0, 1, 1, 1};
hudakz 0:84353c479782 314
hudakz 0:84353c479782 315 baud_value = divisor3 >> 3;
hudakz 0:84353c479782 316 baud_value |= divfrac [divisor3 & 0x7] << 14;
hudakz 0:84353c479782 317 baud_index = divindex[divisor3 & 0x7];
hudakz 0:84353c479782 318
hudakz 0:84353c479782 319 /* Deal with special cases for highest baud rates. */
hudakz 0:84353c479782 320 if(baud_value == 1) baud_value = 0;
hudakz 0:84353c479782 321 else // 1.0
hudakz 0:84353c479782 322 if(baud_value == 0x4001) baud_value = 1; // 1.5
hudakz 0:84353c479782 323 }
hudakz 0:84353c479782 324 USBTRACE2("baud_value:", baud_value);
hudakz 0:84353c479782 325 USBTRACE2("baud_index:", baud_index);
hudakz 0:84353c479782 326 uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_BAUD_RATE, baud_value & 0xff, baud_value >> 8, baud_index, 0, 0, NULL, NULL);
hudakz 0:84353c479782 327 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 328 Release();
hudakz 0:84353c479782 329 }
hudakz 0:84353c479782 330 return rv;
hudakz 0:84353c479782 331 }
hudakz 0:84353c479782 332
hudakz 0:84353c479782 333 // No docs on if this is 8 or 16 bit, so play it safe, make maximum 255ms
hudakz 0:84353c479782 334
hudakz 0:84353c479782 335 uint8_t FTDI::SetLatency(uint8_t l) {
hudakz 0:84353c479782 336 uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_LATENCY_TIMER, l, 0, 0, 0, 0, NULL, NULL);
hudakz 0:84353c479782 337 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 338 Release();
hudakz 0:84353c479782 339 }
hudakz 0:84353c479782 340 return rv;
hudakz 0:84353c479782 341 }
hudakz 0:84353c479782 342
hudakz 0:84353c479782 343 // No docs on if this is 8 or 16 bit, so play it safe, make maximum 255ms
hudakz 0:84353c479782 344
hudakz 0:84353c479782 345 uint8_t FTDI::GetLatency(uint8_t *l) {
hudakz 0:84353c479782 346 uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_GET_LATENCY_TIMER, 0, 0, 0, 0, 1, (uint8_t *)l, NULL);
hudakz 0:84353c479782 347 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 348 Release();
hudakz 0:84353c479782 349 }
hudakz 0:84353c479782 350 return rv;
hudakz 0:84353c479782 351 }
hudakz 0:84353c479782 352
hudakz 0:84353c479782 353 uint8_t FTDI::SetModemControl(uint16_t signal) {
hudakz 0:84353c479782 354 uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_MODEM_CTRL, signal & 0xff, signal >> 8, 0, 0, 0, NULL, NULL);
hudakz 0:84353c479782 355 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 356 Release();
hudakz 0:84353c479782 357 }
hudakz 0:84353c479782 358 return rv;
hudakz 0:84353c479782 359 }
hudakz 0:84353c479782 360
hudakz 0:84353c479782 361 uint8_t FTDI::SetFlowControl(uint8_t protocol, uint8_t xon, uint8_t xoff) {
hudakz 0:84353c479782 362 uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_FLOW_CTRL, xon, xoff, protocol << 8, 0, 0, NULL, NULL);
hudakz 0:84353c479782 363 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 364 Release();
hudakz 0:84353c479782 365 }
hudakz 0:84353c479782 366 return rv;
hudakz 0:84353c479782 367 }
hudakz 0:84353c479782 368
hudakz 0:84353c479782 369 uint8_t FTDI::SetData(uint16_t databm) {
hudakz 0:84353c479782 370 uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_DATA, databm & 0xff, databm >> 8, 0, 0, 0, NULL, NULL);
hudakz 0:84353c479782 371 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 372 Release();
hudakz 0:84353c479782 373 }
hudakz 0:84353c479782 374 return rv;
hudakz 0:84353c479782 375 }
hudakz 0:84353c479782 376
hudakz 0:84353c479782 377 uint8_t FTDI::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) {
hudakz 0:84353c479782 378 uint8_t rv = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr);
hudakz 0:84353c479782 379 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 380 Release();
hudakz 0:84353c479782 381 }
hudakz 0:84353c479782 382 return rv;
hudakz 0:84353c479782 383 }
hudakz 0:84353c479782 384
hudakz 0:84353c479782 385 uint8_t FTDI::SndData(uint16_t nbytes, uint8_t *dataptr) {
hudakz 0:84353c479782 386 uint8_t rv = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr);
hudakz 0:84353c479782 387 if(rv && rv != hrNAK) {
hudakz 0:84353c479782 388 Release();
hudakz 0:84353c479782 389 }
hudakz 0:84353c479782 390 return rv;
hudakz 0:84353c479782 391 }
hudakz 0:84353c479782 392
hudakz 0:84353c479782 393 void FTDI::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
hudakz 0:84353c479782 394 Notify(PSTR("Endpoint descriptor:"), 0x80);
hudakz 0:84353c479782 395 Notify(PSTR("\r\nLength:\t\t"), 0x80);
hudakz 0:84353c479782 396 D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80);
hudakz 0:84353c479782 397 Notify(PSTR("\r\nType:\t\t"), 0x80);
hudakz 0:84353c479782 398 D_PrintHex<uint8_t > (ep_ptr->bDescriptorType, 0x80);
hudakz 0:84353c479782 399 Notify(PSTR("\r\nAddress:\t"), 0x80);
hudakz 0:84353c479782 400 D_PrintHex<uint8_t > (ep_ptr->bEndpointAddress, 0x80);
hudakz 0:84353c479782 401 Notify(PSTR("\r\nAttributes:\t"), 0x80);
hudakz 0:84353c479782 402 D_PrintHex<uint8_t > (ep_ptr->bmAttributes, 0x80);
hudakz 0:84353c479782 403 Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
hudakz 0:84353c479782 404 D_PrintHex<uint16_t > (ep_ptr->wMaxPacketSize, 0x80);
hudakz 0:84353c479782 405 Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
hudakz 0:84353c479782 406 D_PrintHex<uint8_t > (ep_ptr->bInterval, 0x80);
hudakz 0:84353c479782 407 Notify(PSTR("\r\n"), 0x80);
hudakz 0:84353c479782 408 }