[136] | 1 | /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
|
---|
| 2 |
|
---|
| 3 | This software may be distributed and modified under the terms of the GNU
|
---|
| 4 | General Public License version 2 (GPL2) as published by the Free Software
|
---|
| 5 | Foundation and appearing in the file GPL2.TXT included in the packaging of
|
---|
| 6 | this file. Please note that GPL2 Section 2[b] requires that all works based
|
---|
| 7 | on this software must also be made publicly available under the terms of
|
---|
| 8 | the GPL2 ("Copyleft").
|
---|
| 9 |
|
---|
| 10 | Contact information
|
---|
| 11 | -------------------
|
---|
| 12 |
|
---|
| 13 | Circuits At Home, LTD
|
---|
| 14 | Web : http://www.circuitsathome.com
|
---|
| 15 | e-mail : support@circuitsathome.com
|
---|
| 16 | */
|
---|
| 17 |
|
---|
| 18 | #ifndef HIDBOOT_H_INCLUDED
|
---|
| 19 | #define HIDBOOT_H_INCLUDED
|
---|
| 20 |
|
---|
| 21 | #include <stdint.h>
|
---|
| 22 | #include "usb_ch9.h"
|
---|
| 23 | #include "Usb.h"
|
---|
| 24 | #include "hid.h"
|
---|
| 25 | #include "Arduino.h"
|
---|
| 26 | #include "confdescparser.h"
|
---|
| 27 |
|
---|
| 28 | #define KEY_SPACE 0x2c
|
---|
| 29 | #define KEY_ZERO 0x27
|
---|
| 30 | #define KEY_ZERO2 0x62
|
---|
| 31 | #define KEY_ENTER 0x28
|
---|
| 32 | #define KEY_PERIOD 0x63
|
---|
| 33 |
|
---|
| 34 | /**
|
---|
| 35 | * \brief MOUSEINFO definition.
|
---|
| 36 | */
|
---|
| 37 | struct MOUSEINFO
|
---|
| 38 | {
|
---|
| 39 | struct
|
---|
| 40 | {
|
---|
| 41 | uint8_t bmLeftButton : 1;
|
---|
| 42 | uint8_t bmRightButton : 1;
|
---|
| 43 | uint8_t bmMiddleButton : 1;
|
---|
| 44 | uint8_t bmDummy : 1;
|
---|
| 45 | };
|
---|
| 46 | int8_t dX;
|
---|
| 47 | int8_t dY;
|
---|
| 48 | };
|
---|
| 49 |
|
---|
| 50 | /**
|
---|
| 51 | * \class MouseReportParser definition.
|
---|
| 52 | */
|
---|
| 53 | class MouseReportParser : public HIDReportParser
|
---|
| 54 | {
|
---|
| 55 | union
|
---|
| 56 | {
|
---|
| 57 | MOUSEINFO mouseInfo;
|
---|
| 58 | uint8_t bInfo[3];
|
---|
| 59 | } prevState;
|
---|
| 60 |
|
---|
| 61 | public:
|
---|
| 62 | virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf);
|
---|
| 63 |
|
---|
| 64 | protected:
|
---|
| 65 | virtual void OnMouseMove (MOUSEINFO *mi) {};
|
---|
| 66 | virtual void OnLeftButtonUp (MOUSEINFO *mi) {};
|
---|
| 67 | virtual void OnLeftButtonDown (MOUSEINFO *mi) {};
|
---|
| 68 | virtual void OnRightButtonUp (MOUSEINFO *mi) {};
|
---|
| 69 | virtual void OnRightButtonDown (MOUSEINFO *mi) {};
|
---|
| 70 | virtual void OnMiddleButtonUp (MOUSEINFO *mi) {};
|
---|
| 71 | virtual void OnMiddleButtonDown (MOUSEINFO *mi) {};
|
---|
| 72 | };
|
---|
| 73 |
|
---|
| 74 | /**
|
---|
| 75 | * \brief MODIFIERKEYS definition.
|
---|
| 76 | */
|
---|
| 77 | struct MODIFIERKEYS
|
---|
| 78 | {
|
---|
| 79 | uint8_t bmLeftCtrl : 1;
|
---|
| 80 | uint8_t bmLeftShift : 1;
|
---|
| 81 | uint8_t bmLeftAlt : 1;
|
---|
| 82 | uint8_t bmLeftGUI : 1;
|
---|
| 83 | uint8_t bmRightCtrl : 1;
|
---|
| 84 | uint8_t bmRightShift : 1;
|
---|
| 85 | uint8_t bmRightAlt : 1;
|
---|
| 86 | uint8_t bmRightGUI : 1;
|
---|
| 87 | };
|
---|
| 88 |
|
---|
| 89 | /**
|
---|
| 90 | * \brief KBDINFO definition.
|
---|
| 91 | */
|
---|
| 92 | struct KBDINFO
|
---|
| 93 | {
|
---|
| 94 | struct
|
---|
| 95 | {
|
---|
| 96 | uint8_t bmLeftCtrl : 1;
|
---|
| 97 | uint8_t bmLeftShift : 1;
|
---|
| 98 | uint8_t bmLeftAlt : 1;
|
---|
| 99 | uint8_t bmLeftGUI : 1;
|
---|
| 100 | uint8_t bmRightCtrl : 1;
|
---|
| 101 | uint8_t bmRightShift : 1;
|
---|
| 102 | uint8_t bmRightAlt : 1;
|
---|
| 103 | uint8_t bmRightGUI : 1;
|
---|
| 104 | };
|
---|
| 105 | uint8_t bReserved;
|
---|
| 106 | uint8_t Keys[6];
|
---|
| 107 | };
|
---|
| 108 |
|
---|
| 109 | /**
|
---|
| 110 | * \brief KBDLEDS definition.
|
---|
| 111 | */
|
---|
| 112 | struct KBDLEDS
|
---|
| 113 | {
|
---|
| 114 | uint8_t bmNumLock : 1;
|
---|
| 115 | uint8_t bmCapsLock : 1;
|
---|
| 116 | uint8_t bmScrollLock : 1;
|
---|
| 117 | uint8_t bmCompose : 1;
|
---|
| 118 | uint8_t bmKana : 1;
|
---|
| 119 | uint8_t bmReserved : 3;
|
---|
| 120 | };
|
---|
| 121 |
|
---|
| 122 | #define KEY_NUM_LOCK 0x53
|
---|
| 123 |
|
---|
| 124 | // Clear compiler warning
|
---|
| 125 | #ifdef KEY_CAPS_LOCK
|
---|
| 126 | #undef KEY_CAPS_LOCK
|
---|
| 127 | #endif
|
---|
| 128 |
|
---|
| 129 | #define KEY_CAPS_LOCK 0x39
|
---|
| 130 | #define KEY_SCROLL_LOCK 0x47
|
---|
| 131 |
|
---|
| 132 | /**
|
---|
| 133 | * \class KeyboardReportParser definition.
|
---|
| 134 | */
|
---|
| 135 | class KeyboardReportParser : public HIDReportParser
|
---|
| 136 | {
|
---|
| 137 | static const uint8_t numKeys[];
|
---|
| 138 | static const uint8_t symKeysUp[];
|
---|
| 139 | static const uint8_t symKeysLo[];
|
---|
| 140 | static const uint8_t padKeys[];
|
---|
| 141 |
|
---|
| 142 | protected:
|
---|
| 143 | union
|
---|
| 144 | {
|
---|
| 145 | KBDINFO kbdInfo;
|
---|
| 146 | uint8_t bInfo[sizeof(KBDINFO)];
|
---|
| 147 | } prevState;
|
---|
| 148 |
|
---|
| 149 | union
|
---|
| 150 | {
|
---|
| 151 | KBDLEDS kbdLeds;
|
---|
| 152 | uint8_t bLeds;
|
---|
| 153 | } kbdLockingKeys;
|
---|
| 154 |
|
---|
| 155 | uint8_t OemToAscii(uint8_t mod, uint8_t key);
|
---|
| 156 |
|
---|
| 157 | public:
|
---|
| 158 | KeyboardReportParser() { kbdLockingKeys.bLeds = 0; };
|
---|
| 159 |
|
---|
| 160 | virtual void Parse(HID *hid, bool is_rpt_id, uint32_t len, uint8_t *buf);
|
---|
| 161 |
|
---|
| 162 | protected:
|
---|
| 163 | uint8_t HandleLockingKeys(HID* hid, uint8_t key);
|
---|
| 164 |
|
---|
| 165 | virtual void OnKeyDown (uint8_t mod, uint8_t key) {};
|
---|
| 166 | virtual void OnKeyUp (uint8_t mod, uint8_t key) {};
|
---|
| 167 | };
|
---|
| 168 |
|
---|
| 169 | #define totalEndpoints 2
|
---|
| 170 |
|
---|
| 171 | #define HID_MAX_HID_CLASS_DESCRIPTORS 5
|
---|
| 172 |
|
---|
| 173 | /**
|
---|
| 174 | * \class HIDBoot definition.
|
---|
| 175 | */
|
---|
| 176 | template <const uint8_t BOOT_PROTOCOL>
|
---|
| 177 | class HIDBoot : public HID
|
---|
| 178 | {
|
---|
| 179 | EpInfo epInfo[totalEndpoints];
|
---|
| 180 |
|
---|
| 181 | HIDReportParser *pRptParser;
|
---|
| 182 |
|
---|
| 183 | uint32_t bConfNum; // configuration number
|
---|
| 184 | uint32_t bIfaceNum; // Interface Number
|
---|
| 185 | uint32_t bNumIface; // number of interfaces in the configuration
|
---|
| 186 | uint32_t bNumEP; // total number of EP in the configuration
|
---|
| 187 | uint32_t qNextPollTime; // next poll time
|
---|
| 188 | bool bPollEnable; // poll enable flag
|
---|
| 189 |
|
---|
| 190 | void Initialize();
|
---|
| 191 |
|
---|
| 192 | virtual HIDReportParser* GetReportParser(uint32_t id) { return pRptParser; };
|
---|
| 193 |
|
---|
| 194 | public:
|
---|
| 195 | HIDBoot(USBHost *p);
|
---|
| 196 |
|
---|
| 197 | virtual bool SetReportParser(uint32_t id, HIDReportParser *prs) { pRptParser = prs; return true; };
|
---|
| 198 |
|
---|
| 199 | // USBDeviceConfig implementation
|
---|
| 200 | virtual uint32_t Init(uint32_t parent, uint32_t port, uint32_t lowspeed);
|
---|
| 201 | virtual uint32_t Release();
|
---|
| 202 | virtual uint32_t Poll();
|
---|
| 203 | virtual uint32_t GetAddress() { return bAddress; };
|
---|
| 204 |
|
---|
| 205 | // UsbConfigXtracter implementation
|
---|
| 206 | virtual void EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
---|
| 207 | };
|
---|
| 208 |
|
---|
| 209 | /**
|
---|
| 210 | * \brief HIDBoot class constructor.
|
---|
| 211 | */
|
---|
| 212 | template <const uint8_t BOOT_PROTOCOL>
|
---|
| 213 | HIDBoot<BOOT_PROTOCOL>::HIDBoot(USBHost *p) :
|
---|
| 214 | HID(p),
|
---|
| 215 | pRptParser(NULL),
|
---|
| 216 | qNextPollTime(0),
|
---|
| 217 | bPollEnable(false)
|
---|
| 218 | {
|
---|
| 219 | Initialize();
|
---|
| 220 |
|
---|
| 221 | if (pUsb)
|
---|
| 222 | pUsb->RegisterDeviceClass(this);
|
---|
| 223 | }
|
---|
| 224 |
|
---|
| 225 | /**
|
---|
| 226 | * \brief Initialize HIDBoot class.
|
---|
| 227 | */
|
---|
| 228 | template <const uint8_t BOOT_PROTOCOL>
|
---|
| 229 | void HIDBoot<BOOT_PROTOCOL>::Initialize()
|
---|
| 230 | {
|
---|
| 231 | for (uint32_t i = 0; i < totalEndpoints; ++i)
|
---|
| 232 | {
|
---|
| 233 | epInfo[i].deviceEpNum = 0;
|
---|
| 234 | epInfo[i].hostPipeNum = 0;
|
---|
| 235 | epInfo[i].maxPktSize = (i) ? 0 : 8;
|
---|
| 236 | epInfo[i].epAttribs = 0;
|
---|
| 237 | epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
---|
| 238 | }
|
---|
| 239 |
|
---|
| 240 | bNumEP = 1;
|
---|
| 241 | bNumIface = 0;
|
---|
| 242 | bConfNum = 0;
|
---|
| 243 | }
|
---|
| 244 |
|
---|
| 245 | /**
|
---|
| 246 | * \brief Initialize connection to an HID device.
|
---|
| 247 | *
|
---|
| 248 | * \param parent USB device address of the Parent device.
|
---|
| 249 | * \param port USB device base address.
|
---|
| 250 | * \param lowspeed USB device speed.
|
---|
| 251 | *
|
---|
| 252 | * \return 0 on success, error code otherwise.
|
---|
| 253 | */
|
---|
| 254 | template <const uint8_t BOOT_PROTOCOL>
|
---|
| 255 | uint32_t HIDBoot<BOOT_PROTOCOL>::Init(uint32_t parent, uint32_t port, uint32_t lowspeed)
|
---|
| 256 | {
|
---|
| 257 | const uint32_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);
|
---|
| 258 |
|
---|
| 259 | uint8_t buf[constBufSize];
|
---|
| 260 | uint32_t rcode = 0;
|
---|
| 261 | UsbDevice *p = 0;
|
---|
| 262 | EpInfo *oldep_ptr = 0;
|
---|
| 263 | uint32_t len = 0;
|
---|
| 264 |
|
---|
| 265 | uint32_t num_of_conf = 0; // number of configurations
|
---|
| 266 |
|
---|
| 267 | AddressPool &addrPool = pUsb->GetAddressPool();
|
---|
| 268 |
|
---|
| 269 | TRACE_USBHOST(printf("HIDBoot::Init\r\n");)
|
---|
| 270 |
|
---|
| 271 | if (bAddress)
|
---|
| 272 | return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
---|
| 273 |
|
---|
| 274 | // Get pointer to pseudo device with address 0 assigned
|
---|
| 275 | p = addrPool.GetUsbDevicePtr(0);
|
---|
| 276 |
|
---|
| 277 | if (!p)
|
---|
| 278 | return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
---|
| 279 |
|
---|
| 280 | if (!p->epinfo)
|
---|
| 281 | {
|
---|
| 282 | TRACE_USBHOST(printf("HIDBoot::Init : epinfo is null!\r\n");)
|
---|
| 283 | return USB_ERROR_EPINFO_IS_NULL;
|
---|
| 284 | }
|
---|
| 285 |
|
---|
| 286 | // Save old pointer to EP_RECORD of address 0
|
---|
| 287 | oldep_ptr = p->epinfo;
|
---|
| 288 |
|
---|
| 289 | // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
---|
| 290 | p->epinfo = epInfo;
|
---|
| 291 |
|
---|
| 292 | p->lowspeed = lowspeed;
|
---|
| 293 |
|
---|
| 294 | // Get device descriptor
|
---|
| 295 | rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
|
---|
| 296 |
|
---|
| 297 | if (!rcode)
|
---|
| 298 | len = (buf[0] > constBufSize) ? constBufSize : buf[0];
|
---|
| 299 |
|
---|
| 300 | if (rcode)
|
---|
| 301 | {
|
---|
| 302 | // Restore p->epinfo
|
---|
| 303 | p->epinfo = oldep_ptr;
|
---|
| 304 |
|
---|
| 305 | goto FailGetDevDescr;
|
---|
| 306 | }
|
---|
| 307 |
|
---|
| 308 | // Restore p->epinfo
|
---|
| 309 | p->epinfo = oldep_ptr;
|
---|
| 310 |
|
---|
| 311 | // Allocate new address according to device class
|
---|
| 312 | bAddress = addrPool.AllocAddress(parent, false, port);
|
---|
| 313 |
|
---|
| 314 | if (!bAddress)
|
---|
| 315 | return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
---|
| 316 |
|
---|
| 317 | // Extract Max Packet Size from the device descriptor
|
---|
| 318 | epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
---|
| 319 |
|
---|
| 320 | // Assign new address to the device
|
---|
| 321 | rcode = pUsb->setAddr(0, 0, bAddress);
|
---|
| 322 |
|
---|
| 323 | if (rcode)
|
---|
| 324 | {
|
---|
| 325 | p->lowspeed = false;
|
---|
| 326 | addrPool.FreeAddress(bAddress);
|
---|
| 327 | bAddress = 0;
|
---|
| 328 | TRACE_USBHOST(printf("HIDBoot::Init : setAddr failed with rcode %lu\r\n", rcode);)
|
---|
| 329 | return rcode;
|
---|
| 330 | }
|
---|
| 331 |
|
---|
| 332 | TRACE_USBHOST(printf("HIDBoot::Init : device address is now %lu\r\n", bAddress);)
|
---|
| 333 |
|
---|
| 334 | p->lowspeed = false;
|
---|
| 335 |
|
---|
| 336 | p = addrPool.GetUsbDevicePtr(bAddress);
|
---|
| 337 |
|
---|
| 338 | if (!p)
|
---|
| 339 | return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
---|
| 340 |
|
---|
| 341 | p->lowspeed = lowspeed;
|
---|
| 342 |
|
---|
| 343 | if (len)
|
---|
| 344 | rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
|
---|
| 345 |
|
---|
| 346 | if(rcode)
|
---|
| 347 | goto FailGetDevDescr;
|
---|
| 348 |
|
---|
| 349 | num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
|
---|
| 350 |
|
---|
| 351 | // Assign epInfo to epinfo pointer
|
---|
| 352 | rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
---|
| 353 |
|
---|
| 354 | if (rcode)
|
---|
| 355 | goto FailSetDevTblEntry;
|
---|
| 356 |
|
---|
| 357 | TRACE_USBHOST(printf("HIDBoot::Init : number of configuration is %lu\r\n", num_of_conf);)
|
---|
| 358 |
|
---|
| 359 | for (uint32_t i = 0; i < num_of_conf; ++i)
|
---|
| 360 | {
|
---|
| 361 | ConfigDescParser<
|
---|
| 362 | USB_CLASS_HID,
|
---|
| 363 | HID_BOOT_INTF_SUBCLASS,
|
---|
| 364 | BOOT_PROTOCOL,
|
---|
| 365 | CP_MASK_COMPARE_ALL> confDescrParser(this);
|
---|
| 366 |
|
---|
| 367 | rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
---|
| 368 |
|
---|
| 369 | if (bNumEP > 1)
|
---|
| 370 | break;
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 | if (bNumEP < 2)
|
---|
| 374 | return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
---|
| 375 |
|
---|
| 376 | TRACE_USBHOST(printf("HIDBoot::Init : bAddress: %lu\r\n", bAddress);)
|
---|
| 377 | TRACE_USBHOST(printf("HIDBoot::Init : bNumEP: %lu\r\n", bNumEP);)
|
---|
| 378 |
|
---|
| 379 | // Assign epInfo to epinfo pointer
|
---|
| 380 | rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
---|
| 381 |
|
---|
| 382 | TRACE_USBHOST(printf("HIDBoot::Init : bConfNum: %lu\r\n", bConfNum);)
|
---|
| 383 |
|
---|
| 384 | // Set Configuration Value
|
---|
| 385 | rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
---|
| 386 |
|
---|
| 387 | if (rcode)
|
---|
| 388 | goto FailSetConfDescr;
|
---|
| 389 |
|
---|
| 390 | TRACE_USBHOST(printf("HIDBoot::Init : bIfaceNum: %lu\r\n", bIfaceNum);)
|
---|
| 391 |
|
---|
| 392 | rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
|
---|
| 393 |
|
---|
| 394 | if (rcode)
|
---|
| 395 | goto FailSetProtocol;
|
---|
| 396 |
|
---|
| 397 | if (BOOT_PROTOCOL == 1)
|
---|
| 398 | {
|
---|
| 399 | rcode = SetIdle(bIfaceNum, 0, 0);
|
---|
| 400 |
|
---|
| 401 | if (rcode)
|
---|
| 402 | goto FailSetIdle;
|
---|
| 403 | }
|
---|
| 404 |
|
---|
| 405 | TRACE_USBHOST(printf("HIDBoot::Init : HID device configured successfully\r\n");)
|
---|
| 406 |
|
---|
| 407 | bPollEnable = true;
|
---|
| 408 | return 0;
|
---|
| 409 |
|
---|
| 410 | FailGetDevDescr:
|
---|
| 411 | TRACE_USBHOST(printf("HIDBoot::Init getDevDescr : ");)
|
---|
| 412 | goto Fail;
|
---|
| 413 |
|
---|
| 414 | FailSetDevTblEntry:
|
---|
| 415 | TRACE_USBHOST(printf("HIDBoot::Init setDevTblEn : ");)
|
---|
| 416 | goto Fail;
|
---|
| 417 |
|
---|
| 418 | FailSetProtocol:
|
---|
| 419 | TRACE_USBHOST(printf("HIDBoot::Init SetProto : ");)
|
---|
| 420 | goto Fail;
|
---|
| 421 |
|
---|
| 422 | FailSetIdle:
|
---|
| 423 | TRACE_USBHOST(printf("HIDBoot::Init SetIdle : ");)
|
---|
| 424 | goto Fail;
|
---|
| 425 |
|
---|
| 426 | FailSetConfDescr:
|
---|
| 427 | TRACE_USBHOST(printf("HIDBoot::Init setConf : ");)
|
---|
| 428 | goto Fail;
|
---|
| 429 |
|
---|
| 430 | Fail:
|
---|
| 431 | TRACE_USBHOST(printf("error code: %lu\r\n", rcode);)
|
---|
| 432 | Release();
|
---|
| 433 | return rcode;
|
---|
| 434 | }
|
---|
| 435 |
|
---|
| 436 | /**
|
---|
| 437 | * \brief Extract interrupt-IN endpoint information from configuration
|
---|
| 438 | * descriptor.
|
---|
| 439 | *
|
---|
| 440 | * \param conf Configuration number.
|
---|
| 441 | * \param iface Interface number.
|
---|
| 442 | * \param alt Alternate setting.
|
---|
| 443 | * \param proto Protocol version used.
|
---|
| 444 | * \param pep Pointer to endpoint descriptor.
|
---|
| 445 | */
|
---|
| 446 | template <const uint8_t BOOT_PROTOCOL>
|
---|
| 447 | void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint32_t conf, uint32_t iface, uint32_t alt, uint32_t proto, const USB_ENDPOINT_DESCRIPTOR *pep)
|
---|
| 448 | {
|
---|
| 449 | // If the first configuration satisfies, the others are not considered.
|
---|
| 450 | if (bNumEP > 1 && conf != bConfNum)
|
---|
| 451 | return;
|
---|
| 452 |
|
---|
| 453 | bConfNum = conf;
|
---|
| 454 | bIfaceNum = iface;
|
---|
| 455 |
|
---|
| 456 | uint32_t index = 0;
|
---|
| 457 | uint32_t pipe = 0;
|
---|
| 458 |
|
---|
| 459 | if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
|
---|
| 460 | {
|
---|
| 461 | index = epInterruptInIndex;
|
---|
| 462 |
|
---|
| 463 | // Fill in the endpoint info structure
|
---|
| 464 | epInfo[index].deviceEpNum = (pep->bEndpointAddress & 0x0F);
|
---|
| 465 | epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
---|
| 466 | epInfo[index].epAttribs = 0;
|
---|
| 467 |
|
---|
| 468 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : Found new endpoint\r\n");)
|
---|
| 469 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : deviceEpNum: %lu\r\n", epInfo[index].deviceEpNum);)
|
---|
| 470 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : maxPktSize: %lu\r\n", epInfo[index].maxPktSize);)
|
---|
| 471 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : index: %lu\r\n", index);)
|
---|
| 472 |
|
---|
| 473 | // Ensure pipe allocation is okay
|
---|
| 474 | pipe = UHD_Pipe_Alloc(bAddress, epInfo[index].deviceEpNum, UOTGHS_HSTPIPCFG_PTYPE_INTRPT, UOTGHS_HSTPIPCFG_PTOKEN_IN, epInfo[index].maxPktSize, 10, UOTGHS_HSTPIPCFG_PBK_1_BANK);
|
---|
| 475 | if (pipe == 0)
|
---|
| 476 | {
|
---|
| 477 | TRACE_USBHOST(printf("HIDBoot::EndpointXtract : Pipe allocation failure\r\n");)
|
---|
| 478 | // Enumeration failed
|
---|
| 479 | return;
|
---|
| 480 | }
|
---|
| 481 |
|
---|
| 482 | epInfo[index].hostPipeNum = pipe;
|
---|
| 483 |
|
---|
| 484 | bNumEP++;
|
---|
| 485 | }
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | /**
|
---|
| 489 | * \brief Release USB allocated resources (pipes and address).
|
---|
| 490 | *
|
---|
| 491 | * \note Release call is made from USBHost.task() on disconnection events.
|
---|
| 492 | * \note Release call is made from Init() on enumeration failure.
|
---|
| 493 | *
|
---|
| 494 | * \return Always 0.
|
---|
| 495 | */
|
---|
| 496 | template <const uint8_t BOOT_PROTOCOL>
|
---|
| 497 | uint32_t HIDBoot<BOOT_PROTOCOL>::Release()
|
---|
| 498 | {
|
---|
| 499 | // Free allocated host pipes
|
---|
| 500 | UHD_Pipe_Free(epInfo[epInterruptInIndex].hostPipeNum);
|
---|
| 501 |
|
---|
| 502 | // Free allocated USB address
|
---|
| 503 | pUsb->GetAddressPool().FreeAddress(bAddress);
|
---|
| 504 |
|
---|
| 505 | bConfNum = 0;
|
---|
| 506 | bIfaceNum = 0;
|
---|
| 507 | bNumEP = 1;
|
---|
| 508 | bAddress = 0;
|
---|
| 509 | qNextPollTime = 0;
|
---|
| 510 | bPollEnable = false;
|
---|
| 511 |
|
---|
| 512 | return 0;
|
---|
| 513 | }
|
---|
| 514 |
|
---|
| 515 | /**
|
---|
| 516 | * \brief Poll USB device activity.
|
---|
| 517 | *
|
---|
| 518 | * \note Poll call is periodically made from USBHost.task().
|
---|
| 519 | *
|
---|
| 520 | * \return 0 on success, error code otherwise.
|
---|
| 521 | */
|
---|
| 522 | template <const uint8_t BOOT_PROTOCOL>
|
---|
| 523 | uint32_t HIDBoot<BOOT_PROTOCOL>::Poll()
|
---|
| 524 | {
|
---|
| 525 | uint32_t rcode = 0;
|
---|
| 526 |
|
---|
| 527 | if (!bPollEnable)
|
---|
| 528 | return 0;
|
---|
| 529 |
|
---|
| 530 | if (qNextPollTime <= millis())
|
---|
| 531 | {
|
---|
| 532 | qNextPollTime = millis() + 10;
|
---|
| 533 |
|
---|
| 534 | const uint32_t const_buff_len = 16;
|
---|
| 535 | uint8_t buf[const_buff_len];
|
---|
| 536 |
|
---|
| 537 | uint32_t read = epInfo[epInterruptInIndex].maxPktSize;
|
---|
| 538 |
|
---|
| 539 | rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].deviceEpNum, &read, buf);
|
---|
| 540 |
|
---|
| 541 | if (rcode)
|
---|
| 542 | {
|
---|
| 543 | return rcode;
|
---|
| 544 | }
|
---|
| 545 |
|
---|
| 546 | if (pRptParser)
|
---|
| 547 | pRptParser->Parse((HID*)this, 0, (uint32_t)read, buf);
|
---|
| 548 | }
|
---|
| 549 |
|
---|
| 550 | return rcode;
|
---|
| 551 | }
|
---|
| 552 |
|
---|
| 553 | #endif /* HIDBOOT_H_INCLUDED */
|
---|