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
hudakz 0:84353c479782 18 #include "hiduniversal.h"
hudakz 0:84353c479782 19
hudakz 0:84353c479782 20 HIDUniversal::HIDUniversal(USB *p) :
hudakz 0:84353c479782 21 USBHID(p),
hudakz 0:84353c479782 22 qNextPollTime(0),
hudakz 0:84353c479782 23 pollInterval(0),
hudakz 0:84353c479782 24 bPollEnable(false),
hudakz 0:84353c479782 25 bHasReportId(false) {
hudakz 0:84353c479782 26 Initialize();
hudakz 0:84353c479782 27
hudakz 0:84353c479782 28 if(pUsb)
hudakz 0:84353c479782 29 pUsb->RegisterDeviceClass(this);
hudakz 0:84353c479782 30 }
hudakz 0:84353c479782 31
hudakz 0:84353c479782 32 uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
hudakz 0:84353c479782 33 for(uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
hudakz 0:84353c479782 34 if(descrInfo[i].bDescrType == type) {
hudakz 0:84353c479782 35 if(n == num)
hudakz 0:84353c479782 36 return descrInfo[i].wDescriptorLength;
hudakz 0:84353c479782 37 n++;
hudakz 0:84353c479782 38 }
hudakz 0:84353c479782 39 }
hudakz 0:84353c479782 40 return 0;
hudakz 0:84353c479782 41 }
hudakz 0:84353c479782 42
hudakz 0:84353c479782 43 void HIDUniversal::Initialize() {
hudakz 0:84353c479782 44 for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
hudakz 0:84353c479782 45 rptParsers[i].rptId = 0;
hudakz 0:84353c479782 46 rptParsers[i].rptParser = NULL;
hudakz 0:84353c479782 47 }
hudakz 0:84353c479782 48 for(uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
hudakz 0:84353c479782 49 descrInfo[i].bDescrType = 0;
hudakz 0:84353c479782 50 descrInfo[i].wDescriptorLength = 0;
hudakz 0:84353c479782 51 }
hudakz 0:84353c479782 52 for(uint8_t i = 0; i < maxHidInterfaces; i++) {
hudakz 0:84353c479782 53 hidInterfaces[i].bmInterface = 0;
hudakz 0:84353c479782 54 hidInterfaces[i].bmProtocol = 0;
hudakz 0:84353c479782 55
hudakz 0:84353c479782 56 for(uint8_t j = 0; j < maxEpPerInterface; j++)
hudakz 0:84353c479782 57 hidInterfaces[i].epIndex[j] = 0;
hudakz 0:84353c479782 58 }
hudakz 0:84353c479782 59 for(uint8_t i = 0; i < totalEndpoints; i++) {
hudakz 0:84353c479782 60 epInfo[i].epAddr = 0;
hudakz 0:84353c479782 61 epInfo[i].maxPktSize = (i) ? 0 : 8;
hudakz 0:84353c479782 62 epInfo[i].bmSndToggle = 0;
hudakz 0:84353c479782 63 epInfo[i].bmRcvToggle = 0;
hudakz 0:84353c479782 64 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
hudakz 0:84353c479782 65 }
hudakz 0:84353c479782 66 bNumEP = 1;
hudakz 0:84353c479782 67 bNumIface = 0;
hudakz 0:84353c479782 68 bConfNum = 0;
hudakz 0:84353c479782 69 pollInterval = 0;
hudakz 0:84353c479782 70
hudakz 0:84353c479782 71 ZeroMemory(constBuffLen, prevBuf);
hudakz 0:84353c479782 72 }
hudakz 0:84353c479782 73
hudakz 0:84353c479782 74 bool HIDUniversal::SetReportParser(uint8_t id, HIDReportParser *prs) {
hudakz 0:84353c479782 75 for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
hudakz 0:84353c479782 76 if(rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
hudakz 0:84353c479782 77 rptParsers[i].rptId = id;
hudakz 0:84353c479782 78 rptParsers[i].rptParser = prs;
hudakz 0:84353c479782 79 return true;
hudakz 0:84353c479782 80 }
hudakz 0:84353c479782 81 }
hudakz 0:84353c479782 82 return false;
hudakz 0:84353c479782 83 }
hudakz 0:84353c479782 84
hudakz 0:84353c479782 85 HIDReportParser* HIDUniversal::GetReportParser(uint8_t id) {
hudakz 0:84353c479782 86 if(!bHasReportId)
hudakz 0:84353c479782 87 return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
hudakz 0:84353c479782 88
hudakz 0:84353c479782 89 for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
hudakz 0:84353c479782 90 if(rptParsers[i].rptId == id)
hudakz 0:84353c479782 91 return rptParsers[i].rptParser;
hudakz 0:84353c479782 92 }
hudakz 0:84353c479782 93 return NULL;
hudakz 0:84353c479782 94 }
hudakz 0:84353c479782 95
hudakz 0:84353c479782 96 uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
hudakz 0:84353c479782 97 const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
hudakz 0:84353c479782 98
hudakz 0:84353c479782 99 uint8_t buf[constBufSize];
hudakz 0:84353c479782 100 USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
hudakz 0:84353c479782 101 uint8_t rcode;
hudakz 0:84353c479782 102 UsbDevice *p = NULL;
hudakz 0:84353c479782 103 EpInfo *oldep_ptr = NULL;
hudakz 0:84353c479782 104 uint8_t len = 0;
hudakz 0:84353c479782 105
hudakz 0:84353c479782 106 uint8_t num_of_conf; // number of configurations
hudakz 0:84353c479782 107 //uint8_t num_of_intf; // number of interfaces
hudakz 0:84353c479782 108
hudakz 0:84353c479782 109 AddressPool &addrPool = pUsb->GetAddressPool();
hudakz 0:84353c479782 110
hudakz 0:84353c479782 111 USBTRACE("HU Init\r\n");
hudakz 0:84353c479782 112
hudakz 0:84353c479782 113 if(bAddress)
hudakz 0:84353c479782 114 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
hudakz 0:84353c479782 115
hudakz 0:84353c479782 116 // Get pointer to pseudo device with address 0 assigned
hudakz 0:84353c479782 117 p = addrPool.GetUsbDevicePtr(0);
hudakz 0:84353c479782 118
hudakz 0:84353c479782 119 if(!p)
hudakz 0:84353c479782 120 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
hudakz 0:84353c479782 121
hudakz 0:84353c479782 122 if(!p->epinfo) {
hudakz 0:84353c479782 123 USBTRACE("epinfo\r\n");
hudakz 0:84353c479782 124 return USB_ERROR_EPINFO_IS_NULL;
hudakz 0:84353c479782 125 }
hudakz 0:84353c479782 126
hudakz 0:84353c479782 127 // Save old pointer to EP_RECORD of address 0
hudakz 0:84353c479782 128 oldep_ptr = p->epinfo;
hudakz 0:84353c479782 129
hudakz 0:84353c479782 130 // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
hudakz 0:84353c479782 131 p->epinfo = epInfo;
hudakz 0:84353c479782 132
hudakz 0:84353c479782 133 p->lowspeed = lowspeed;
hudakz 0:84353c479782 134
hudakz 0:84353c479782 135 // Get device descriptor
hudakz 0:84353c479782 136 rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
hudakz 0:84353c479782 137
hudakz 0:84353c479782 138 if(!rcode)
hudakz 0:84353c479782 139 len = (buf[0] > constBufSize) ? constBufSize : buf[0];
hudakz 0:84353c479782 140
hudakz 0:84353c479782 141 if(rcode) {
hudakz 0:84353c479782 142 // Restore p->epinfo
hudakz 0:84353c479782 143 p->epinfo = oldep_ptr;
hudakz 0:84353c479782 144
hudakz 0:84353c479782 145 goto FailGetDevDescr;
hudakz 0:84353c479782 146 }
hudakz 0:84353c479782 147
hudakz 0:84353c479782 148 // Restore p->epinfo
hudakz 0:84353c479782 149 p->epinfo = oldep_ptr;
hudakz 0:84353c479782 150
hudakz 0:84353c479782 151 // Allocate new address according to device class
hudakz 0:84353c479782 152 bAddress = addrPool.AllocAddress(parent, false, port);
hudakz 0:84353c479782 153
hudakz 0:84353c479782 154 if(!bAddress)
hudakz 0:84353c479782 155 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
hudakz 0:84353c479782 156
hudakz 0:84353c479782 157 // Extract Max Packet Size from the device descriptor
hudakz 0:84353c479782 158 epInfo[0].maxPktSize = udd->bMaxPacketSize0;
hudakz 0:84353c479782 159
hudakz 0:84353c479782 160 // Assign new address to the device
hudakz 0:84353c479782 161 rcode = pUsb->setAddr(0, 0, bAddress);
hudakz 0:84353c479782 162
hudakz 0:84353c479782 163 if(rcode) {
hudakz 0:84353c479782 164 p->lowspeed = false;
hudakz 0:84353c479782 165 addrPool.FreeAddress(bAddress);
hudakz 0:84353c479782 166 bAddress = 0;
hudakz 0:84353c479782 167 USBTRACE2("setAddr:", rcode);
hudakz 0:84353c479782 168 return rcode;
hudakz 0:84353c479782 169 }
hudakz 0:84353c479782 170
hudakz 0:84353c479782 171 //delay(2); //per USB 2.0 sect.9.2.6.3
hudakz 0:84353c479782 172
hudakz 0:84353c479782 173 USBTRACE2("Addr:", bAddress);
hudakz 0:84353c479782 174
hudakz 0:84353c479782 175 p->lowspeed = false;
hudakz 0:84353c479782 176
hudakz 0:84353c479782 177 p = addrPool.GetUsbDevicePtr(bAddress);
hudakz 0:84353c479782 178
hudakz 0:84353c479782 179 if(!p)
hudakz 0:84353c479782 180 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
hudakz 0:84353c479782 181
hudakz 0:84353c479782 182 p->lowspeed = lowspeed;
hudakz 0:84353c479782 183
hudakz 0:84353c479782 184 if(len)
hudakz 0:84353c479782 185 rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
hudakz 0:84353c479782 186
hudakz 0:84353c479782 187 if(rcode)
hudakz 0:84353c479782 188 goto FailGetDevDescr;
hudakz 0:84353c479782 189
hudakz 0:84353c479782 190 VID = udd->idVendor; // Can be used by classes that inherits this class to check the VID and PID of the connected device
hudakz 0:84353c479782 191 PID = udd->idProduct;
hudakz 0:84353c479782 192
hudakz 0:84353c479782 193 num_of_conf = udd->bNumConfigurations;
hudakz 0:84353c479782 194
hudakz 0:84353c479782 195 // Assign epInfo to epinfo pointer
hudakz 0:84353c479782 196 rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
hudakz 0:84353c479782 197
hudakz 0:84353c479782 198 if(rcode)
hudakz 0:84353c479782 199 goto FailSetDevTblEntry;
hudakz 0:84353c479782 200
hudakz 0:84353c479782 201 USBTRACE2("NC:", num_of_conf);
hudakz 0:84353c479782 202
hudakz 0:84353c479782 203 for(uint8_t i = 0; i < num_of_conf; i++) {
hudakz 0:84353c479782 204 //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
hudakz 0:84353c479782 205 ConfigDescParser<USB_CLASS_HID, 0, 0,
hudakz 0:84353c479782 206 CP_MASK_COMPARE_CLASS> confDescrParser(this);
hudakz 0:84353c479782 207
hudakz 0:84353c479782 208 //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
hudakz 0:84353c479782 209 rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
hudakz 0:84353c479782 210
hudakz 0:84353c479782 211 if(rcode)
hudakz 0:84353c479782 212 goto FailGetConfDescr;
hudakz 0:84353c479782 213
hudakz 0:84353c479782 214 if(bNumEP > 1)
hudakz 0:84353c479782 215 break;
hudakz 0:84353c479782 216 } // for
hudakz 0:84353c479782 217
hudakz 0:84353c479782 218 if(bNumEP < 2)
hudakz 0:84353c479782 219 return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
hudakz 0:84353c479782 220
hudakz 0:84353c479782 221 // Assign epInfo to epinfo pointer
hudakz 0:84353c479782 222 rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
hudakz 0:84353c479782 223
hudakz 0:84353c479782 224 USBTRACE2("Cnf:", bConfNum);
hudakz 0:84353c479782 225
hudakz 0:84353c479782 226 // Set Configuration Value
hudakz 0:84353c479782 227 rcode = pUsb->setConf(bAddress, 0, bConfNum);
hudakz 0:84353c479782 228
hudakz 0:84353c479782 229 if(rcode)
hudakz 0:84353c479782 230 goto FailSetConfDescr;
hudakz 0:84353c479782 231
hudakz 0:84353c479782 232 for(uint8_t i = 0; i < bNumIface; i++) {
hudakz 0:84353c479782 233 if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
hudakz 0:84353c479782 234 continue;
hudakz 0:84353c479782 235
hudakz 0:84353c479782 236 rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
hudakz 0:84353c479782 237
hudakz 0:84353c479782 238 if(rcode && rcode != hrSTALL)
hudakz 0:84353c479782 239 goto FailSetIdle;
hudakz 0:84353c479782 240 }
hudakz 0:84353c479782 241
hudakz 0:84353c479782 242 USBTRACE("HU configured\r\n");
hudakz 0:84353c479782 243
hudakz 0:84353c479782 244 OnInitSuccessful();
hudakz 0:84353c479782 245
hudakz 0:84353c479782 246 bPollEnable = true;
hudakz 0:84353c479782 247 return 0;
hudakz 0:84353c479782 248
hudakz 0:84353c479782 249 FailGetDevDescr:
hudakz 0:84353c479782 250 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 251 NotifyFailGetDevDescr();
hudakz 0:84353c479782 252 goto Fail;
hudakz 0:84353c479782 253 #endif
hudakz 0:84353c479782 254
hudakz 0:84353c479782 255 FailSetDevTblEntry:
hudakz 0:84353c479782 256 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 257 NotifyFailSetDevTblEntry();
hudakz 0:84353c479782 258 goto Fail;
hudakz 0:84353c479782 259 #endif
hudakz 0:84353c479782 260
hudakz 0:84353c479782 261 FailGetConfDescr:
hudakz 0:84353c479782 262 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 263 NotifyFailGetConfDescr();
hudakz 0:84353c479782 264 goto Fail;
hudakz 0:84353c479782 265 #endif
hudakz 0:84353c479782 266
hudakz 0:84353c479782 267 FailSetConfDescr:
hudakz 0:84353c479782 268 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 269 NotifyFailSetConfDescr();
hudakz 0:84353c479782 270 goto Fail;
hudakz 0:84353c479782 271 #endif
hudakz 0:84353c479782 272
hudakz 0:84353c479782 273
hudakz 0:84353c479782 274 FailSetIdle:
hudakz 0:84353c479782 275 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 276 USBTRACE("SetIdle:");
hudakz 0:84353c479782 277 #endif
hudakz 0:84353c479782 278
hudakz 0:84353c479782 279 #ifdef DEBUG_USB_HOST
hudakz 0:84353c479782 280 Fail:
hudakz 0:84353c479782 281 NotifyFail(rcode);
hudakz 0:84353c479782 282 #endif
hudakz 0:84353c479782 283 Release();
hudakz 0:84353c479782 284 return rcode;
hudakz 0:84353c479782 285 }
hudakz 0:84353c479782 286
hudakz 0:84353c479782 287 HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
hudakz 0:84353c479782 288 for(uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
hudakz 0:84353c479782 289 if(hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
hudakz 0:84353c479782 290 && hidInterfaces[i].bmProtocol == proto)
hudakz 0:84353c479782 291 return hidInterfaces + i;
hudakz 0:84353c479782 292 return NULL;
hudakz 0:84353c479782 293 }
hudakz 0:84353c479782 294
hudakz 0:84353c479782 295 void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
hudakz 0:84353c479782 296 // If the first configuration satisfies, the others are not concidered.
hudakz 0:84353c479782 297 if(bNumEP > 1 && conf != bConfNum)
hudakz 0:84353c479782 298 return;
hudakz 0:84353c479782 299
hudakz 0:84353c479782 300 //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
hudakz 0:84353c479782 301 //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
hudakz 0:84353c479782 302 //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
hudakz 0:84353c479782 303
hudakz 0:84353c479782 304 bConfNum = conf;
hudakz 0:84353c479782 305
hudakz 0:84353c479782 306 uint8_t index = 0;
hudakz 0:84353c479782 307 HIDInterface *piface = FindInterface(iface, alt, proto);
hudakz 0:84353c479782 308
hudakz 0:84353c479782 309 // Fill in interface structure in case of new interface
hudakz 0:84353c479782 310 if(!piface) {
hudakz 0:84353c479782 311 piface = hidInterfaces + bNumIface;
hudakz 0:84353c479782 312 piface->bmInterface = iface;
hudakz 0:84353c479782 313 piface->bmAltSet = alt;
hudakz 0:84353c479782 314 piface->bmProtocol = proto;
hudakz 0:84353c479782 315 bNumIface++;
hudakz 0:84353c479782 316 }
hudakz 0:84353c479782 317
hudakz 0:84353c479782 318 if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT)
hudakz 0:84353c479782 319 index = (pep->bEndpointAddress & 0x80) == 0x80 ? epInterruptInIndex : epInterruptOutIndex;
hudakz 0:84353c479782 320
hudakz 0:84353c479782 321 if(index) {
hudakz 0:84353c479782 322 // Fill in the endpoint info structure
hudakz 0:84353c479782 323 epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
hudakz 0:84353c479782 324 epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
hudakz 0:84353c479782 325 epInfo[bNumEP].bmSndToggle = 0;
hudakz 0:84353c479782 326 epInfo[bNumEP].bmRcvToggle = 0;
hudakz 0:84353c479782 327 epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
hudakz 0:84353c479782 328
hudakz 0:84353c479782 329 // Fill in the endpoint index list
hudakz 0:84353c479782 330 piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
hudakz 0:84353c479782 331
hudakz 0:84353c479782 332 if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
hudakz 0:84353c479782 333 pollInterval = pep->bInterval;
hudakz 0:84353c479782 334
hudakz 0:84353c479782 335 bNumEP++;
hudakz 0:84353c479782 336 }
hudakz 0:84353c479782 337 //PrintEndpointDescriptor(pep);
hudakz 0:84353c479782 338 }
hudakz 0:84353c479782 339
hudakz 0:84353c479782 340 uint8_t HIDUniversal::Release() {
hudakz 0:84353c479782 341 pUsb->GetAddressPool().FreeAddress(bAddress);
hudakz 0:84353c479782 342
hudakz 0:84353c479782 343 bNumEP = 1;
hudakz 0:84353c479782 344 bAddress = 0;
hudakz 0:84353c479782 345 qNextPollTime = 0;
hudakz 0:84353c479782 346 bPollEnable = false;
hudakz 0:84353c479782 347 return 0;
hudakz 0:84353c479782 348 }
hudakz 0:84353c479782 349
hudakz 0:84353c479782 350 bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2) {
hudakz 0:84353c479782 351 for(uint8_t i = 0; i < len; i++)
hudakz 0:84353c479782 352 if(buf1[i] != buf2[i])
hudakz 0:84353c479782 353 return false;
hudakz 0:84353c479782 354 return true;
hudakz 0:84353c479782 355 }
hudakz 0:84353c479782 356
hudakz 0:84353c479782 357 void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf) {
hudakz 0:84353c479782 358 for(uint8_t i = 0; i < len; i++)
hudakz 0:84353c479782 359 buf[i] = 0;
hudakz 0:84353c479782 360 }
hudakz 0:84353c479782 361
hudakz 0:84353c479782 362 void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest) {
hudakz 0:84353c479782 363 for(uint8_t i = 0; i < len; i++)
hudakz 0:84353c479782 364 dest[i] = src[i];
hudakz 0:84353c479782 365 }
hudakz 0:84353c479782 366
hudakz 0:84353c479782 367 uint8_t HIDUniversal::Poll() {
hudakz 0:84353c479782 368 uint8_t rcode = 0;
hudakz 0:84353c479782 369
hudakz 0:84353c479782 370 if(!bPollEnable)
hudakz 0:84353c479782 371 return 0;
hudakz 0:84353c479782 372
hudakz 0:84353c479782 373 if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) {
hudakz 0:84353c479782 374 qNextPollTime = (uint32_t)millis() + pollInterval;
hudakz 0:84353c479782 375
hudakz 0:84353c479782 376 uint8_t buf[constBuffLen];
hudakz 0:84353c479782 377
hudakz 0:84353c479782 378 for(uint8_t i = 0; i < bNumIface; i++) {
hudakz 0:84353c479782 379 uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
hudakz 0:84353c479782 380 uint16_t read = (uint16_t)epInfo[index].maxPktSize;
hudakz 0:84353c479782 381
hudakz 0:84353c479782 382 ZeroMemory(constBuffLen, buf);
hudakz 0:84353c479782 383
hudakz 0:84353c479782 384 uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
hudakz 0:84353c479782 385
hudakz 0:84353c479782 386 if(rcode) {
hudakz 0:84353c479782 387 if(rcode != hrNAK)
hudakz 0:84353c479782 388 USBTRACE3("(hiduniversal.h) Poll:", rcode, 0x81);
hudakz 0:84353c479782 389 return rcode;
hudakz 0:84353c479782 390 }
hudakz 0:84353c479782 391
hudakz 0:84353c479782 392 if(read > constBuffLen)
hudakz 0:84353c479782 393 read = constBuffLen;
hudakz 0:84353c479782 394
hudakz 0:84353c479782 395 bool identical = BuffersIdentical(read, buf, prevBuf);
hudakz 0:84353c479782 396
hudakz 0:84353c479782 397 SaveBuffer(read, buf, prevBuf);
hudakz 0:84353c479782 398
hudakz 0:84353c479782 399 if(identical)
hudakz 0:84353c479782 400 return 0;
hudakz 0:84353c479782 401 #if 0
hudakz 0:84353c479782 402 Notify(PSTR("\r\nBuf: "), 0x80);
hudakz 0:84353c479782 403
hudakz 0:84353c479782 404 for(uint8_t i = 0; i < read; i++) {
hudakz 0:84353c479782 405 D_PrintHex<uint8_t > (buf[i], 0x80);
hudakz 0:84353c479782 406 Notify(PSTR(" "), 0x80);
hudakz 0:84353c479782 407 }
hudakz 0:84353c479782 408
hudakz 0:84353c479782 409 Notify(PSTR("\r\n"), 0x80);
hudakz 0:84353c479782 410 #endif
hudakz 0:84353c479782 411 ParseHIDData(this, bHasReportId, (uint8_t)read, buf);
hudakz 0:84353c479782 412
hudakz 0:84353c479782 413 HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
hudakz 0:84353c479782 414
hudakz 0:84353c479782 415 if(prs)
hudakz 0:84353c479782 416 prs->Parse(this, bHasReportId, (uint8_t)read, buf);
hudakz 0:84353c479782 417 }
hudakz 0:84353c479782 418 }
hudakz 0:84353c479782 419 return rcode;
hudakz 0:84353c479782 420 }
hudakz 0:84353c479782 421
hudakz 0:84353c479782 422 // Send a report to interrupt out endpoint. This is NOT SetReport() request!
hudakz 0:84353c479782 423 uint8_t HIDUniversal::SndRpt(uint16_t nbytes, uint8_t *dataptr) {
hudakz 0:84353c479782 424 return pUsb->outTransfer(bAddress, epInfo[epInterruptOutIndex].epAddr, nbytes, dataptr);
hudakz 0:84353c479782 425 }