Library to use Arduino USB host shield on mbed

Dependents:   USBHOST_PS5

ArduinoのUSB Host Shield 2.0をmbedで使えるようにしたライブラリです。
大体のコードがArduinoからそのまま移植可能です。

Arduino UNOやMega用のホストシールド以外にもミニサイズのホストシールドでも使用可能です https://os.mbed.com/media/uploads/kotakku/dffgfddswa.png

シールドについて

3.3VのI/O用にシールドの改造が必要になりますがネット上に記事がたくさんあるのでそちらを参考にしてください

接続例

https://os.mbed.com/media/uploads/kotakku/esgsvfvhjrekldkcjxvb.png

使い方

Arduinoのコードと違うのはUSBのインスタンスの宣言部分のみです。
ピンを自分で指定できるようにしたので使いやすくなりました。

仕様

  • Arduinoのmillis関数、micros関数の移植のために内部でTimerクラスを使用しています。

main.cpp

#include "mbed.h"
#include <PS3BT.h>
#include <usbhub.h>

Serial pc(USBTX, USBRX, 115200);

//Nucleo f303k8用
USB Usb(A6, A5, A4, A3, A2); // mosi, miso, sclk, ssel, intr
BTD Btd(&Usb);
PS3BT PS3(&Btd);

int main()
{
    bool printAngle = false;

    if (Usb.Init() == -1)
    {
        pc.printf("\r\nOSC did not start");
        while (1); // Halt
    }
    pc.printf("\r\nPS3 USB Library Started");

    while (1)
    {
        Usb.Task();
        
        if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
            if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117)
            {
                pc.printf("\r\nLeftHatX: %d", PS3.getAnalogHat(LeftHatX));
                pc.printf("\tLeftHatY: %d", PS3.getAnalogHat(LeftHatY));
                if (PS3.PS3Connected)
                { // The Navigation controller only have one joystick
                    pc.printf("\tRightHatX: %d", PS3.getAnalogHat(RightHatX));
                    pc.printf("\tRightHatY: %d", PS3.getAnalogHat(RightHatY));
                }
            }
            // Analog button values can be read from almost all buttons
            if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2))
            {
                pc.printf("\r\nL2: %d", PS3.getAnalogButton(L2));
                if (!PS3.PS3NavigationConnected)
                {
                    pc.printf("\tR2: %d", PS3.getAnalogButton(R2));
                }
            }
            if (PS3.getButtonClick(PS))
            {
                PS3.disconnect();
                pc.printf("\r\nPS");
            }
    
            if (PS3.getButtonClick(TRIANGLE))
                pc.printf("\r\nTriangle");
            if (PS3.getButtonClick(CIRCLE))
                pc.printf("\r\nCircle");
            if (PS3.getButtonClick(CROSS))
                pc.printf("\r\nCross");
            if (PS3.getButtonClick(SQUARE))
                pc.printf("\r\nSquare");
    
            if (PS3.getButtonClick(UP))
            {
                pc.printf("\r\nUp");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED4);
            }
            if (PS3.getButtonClick(RIGHT))
            {
                pc.printf("\r\nRight");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED1);
            }
            if (PS3.getButtonClick(DOWN))
            {
                pc.printf("\r\nDown");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED2);
            }
            if (PS3.getButtonClick(LEFT))
            {
                pc.printf("\r\nLeft");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED3);
            }
    
            if (PS3.getButtonClick(L1))
                pc.printf("\r\nL1");
            if (PS3.getButtonClick(L3))
                pc.printf("\r\nL3");
            if (PS3.getButtonClick(R1))
                pc.printf("\r\nR1");
            if (PS3.getButtonClick(R3))
                pc.printf("\r\nR3");
    
            if (PS3.getButtonClick(SELECT))
            {
                pc.printf("\r\nSelect - ");
                PS3.printStatusString();
            }
            if (PS3.getButtonClick(START))
            {
                pc.printf("\r\nStart");
                printAngle = !printAngle;
            }
            if (printAngle)
            {
                pc.printf("\r\nPitch: %.3lf", PS3.getAngle(Pitch));
                pc.printf("\tRoll: %.3lf", PS3.getAngle(Roll));
            }
        }
        else
        {
            pc.printf("not connect\n");
        }
    }
}
Committer:
robo_ichinoseki_a
Date:
Sat May 02 05:56:48 2020 +0000
Revision:
1:da31140f2a1c
Parent:
0:b1ce54272580
update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kotakku 0:b1ce54272580 1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
kotakku 0:b1ce54272580 2
kotakku 0:b1ce54272580 3 This software may be distributed and modified under the terms of the GNU
kotakku 0:b1ce54272580 4 General Public License version 2 (GPL2) as published by the Free Software
kotakku 0:b1ce54272580 5 Foundation and appearing in the file GPL2.TXT included in the packaging of
kotakku 0:b1ce54272580 6 this file. Please note that GPL2 Section 2[b] requires that all works based
kotakku 0:b1ce54272580 7 on this software must also be made publicly available under the terms of
kotakku 0:b1ce54272580 8 the GPL2 ("Copyleft").
kotakku 0:b1ce54272580 9
kotakku 0:b1ce54272580 10 Contact information
kotakku 0:b1ce54272580 11 -------------------
kotakku 0:b1ce54272580 12
kotakku 0:b1ce54272580 13 Circuits At Home, LTD
kotakku 0:b1ce54272580 14 Web : http://www.circuitsathome.com
kotakku 0:b1ce54272580 15 e-mail : support@circuitsathome.com
kotakku 0:b1ce54272580 16 */
kotakku 0:b1ce54272580 17 #if !defined(__HIDBOOT_H__)
kotakku 0:b1ce54272580 18 #define __HIDBOOT_H__
kotakku 0:b1ce54272580 19
kotakku 0:b1ce54272580 20 #include "usbhid.h"
kotakku 0:b1ce54272580 21
kotakku 0:b1ce54272580 22 #define UHS_HID_BOOT_KEY_ZERO 0x27
kotakku 0:b1ce54272580 23 #define UHS_HID_BOOT_KEY_ENTER 0x28
kotakku 0:b1ce54272580 24 #define UHS_HID_BOOT_KEY_SPACE 0x2c
kotakku 0:b1ce54272580 25 #define UHS_HID_BOOT_KEY_CAPS_LOCK 0x39
kotakku 0:b1ce54272580 26 #define UHS_HID_BOOT_KEY_SCROLL_LOCK 0x47
kotakku 0:b1ce54272580 27 #define UHS_HID_BOOT_KEY_NUM_LOCK 0x53
kotakku 0:b1ce54272580 28 #define UHS_HID_BOOT_KEY_ZERO2 0x62
kotakku 0:b1ce54272580 29 #define UHS_HID_BOOT_KEY_PERIOD 0x63
kotakku 0:b1ce54272580 30
kotakku 0:b1ce54272580 31 // Don't worry, GCC will optimize the result to a final value.
kotakku 0:b1ce54272580 32 #define bitsEndpoints(p) ((((p) & USB_HID_PROTOCOL_KEYBOARD)? 2 : 0) | (((p) & USB_HID_PROTOCOL_MOUSE)? 1 : 0))
kotakku 0:b1ce54272580 33 #define totalEndpoints(p) ((bitsEndpoints(p) == 3) ? 3 : 2)
kotakku 0:b1ce54272580 34 #define epMUL(p) ((((p) & USB_HID_PROTOCOL_KEYBOARD)? 1 : 0) + (((p) & USB_HID_PROTOCOL_MOUSE)? 1 : 0))
kotakku 0:b1ce54272580 35
kotakku 0:b1ce54272580 36 // Already defined in hid.h
kotakku 0:b1ce54272580 37 // #define HID_MAX_HID_CLASS_DESCRIPTORS 5
kotakku 0:b1ce54272580 38
kotakku 0:b1ce54272580 39 struct MOUSEINFO {
kotakku 0:b1ce54272580 40
kotakku 0:b1ce54272580 41 struct {
kotakku 0:b1ce54272580 42 uint8_t bmLeftButton : 1;
kotakku 0:b1ce54272580 43 uint8_t bmRightButton : 1;
kotakku 0:b1ce54272580 44 uint8_t bmMiddleButton : 1;
kotakku 0:b1ce54272580 45 uint8_t bmDummy : 5;
kotakku 0:b1ce54272580 46 };
kotakku 0:b1ce54272580 47 int8_t dX;
kotakku 0:b1ce54272580 48 int8_t dY;
kotakku 0:b1ce54272580 49 };
kotakku 0:b1ce54272580 50
kotakku 0:b1ce54272580 51 class MouseReportParser : public HIDReportParser {
kotakku 0:b1ce54272580 52
kotakku 0:b1ce54272580 53 union {
kotakku 0:b1ce54272580 54 MOUSEINFO mouseInfo;
kotakku 0:b1ce54272580 55 uint8_t bInfo[sizeof (MOUSEINFO)];
kotakku 0:b1ce54272580 56 } prevState;
kotakku 0:b1ce54272580 57
kotakku 0:b1ce54272580 58 public:
kotakku 0:b1ce54272580 59 void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
kotakku 0:b1ce54272580 60
kotakku 0:b1ce54272580 61 protected:
kotakku 0:b1ce54272580 62
kotakku 0:b1ce54272580 63 virtual void OnMouseMove(MOUSEINFO *mi __attribute__((unused))) {
kotakku 0:b1ce54272580 64 };
kotakku 0:b1ce54272580 65
kotakku 0:b1ce54272580 66 virtual void OnLeftButtonUp(MOUSEINFO *mi __attribute__((unused))) {
kotakku 0:b1ce54272580 67 };
kotakku 0:b1ce54272580 68
kotakku 0:b1ce54272580 69 virtual void OnLeftButtonDown(MOUSEINFO *mi __attribute__((unused))) {
kotakku 0:b1ce54272580 70 };
kotakku 0:b1ce54272580 71
kotakku 0:b1ce54272580 72 virtual void OnRightButtonUp(MOUSEINFO *mi __attribute__((unused))) {
kotakku 0:b1ce54272580 73 };
kotakku 0:b1ce54272580 74
kotakku 0:b1ce54272580 75 virtual void OnRightButtonDown(MOUSEINFO *mi __attribute__((unused))) {
kotakku 0:b1ce54272580 76 };
kotakku 0:b1ce54272580 77
kotakku 0:b1ce54272580 78 virtual void OnMiddleButtonUp(MOUSEINFO *mi __attribute__((unused))) {
kotakku 0:b1ce54272580 79 };
kotakku 0:b1ce54272580 80
kotakku 0:b1ce54272580 81 virtual void OnMiddleButtonDown(MOUSEINFO *mi __attribute__((unused))) {
kotakku 0:b1ce54272580 82 };
kotakku 0:b1ce54272580 83 };
kotakku 0:b1ce54272580 84
kotakku 0:b1ce54272580 85 struct MODIFIERKEYS {
kotakku 0:b1ce54272580 86 uint8_t bmLeftCtrl : 1;
kotakku 0:b1ce54272580 87 uint8_t bmLeftShift : 1;
kotakku 0:b1ce54272580 88 uint8_t bmLeftAlt : 1;
kotakku 0:b1ce54272580 89 uint8_t bmLeftGUI : 1;
kotakku 0:b1ce54272580 90 uint8_t bmRightCtrl : 1;
kotakku 0:b1ce54272580 91 uint8_t bmRightShift : 1;
kotakku 0:b1ce54272580 92 uint8_t bmRightAlt : 1;
kotakku 0:b1ce54272580 93 uint8_t bmRightGUI : 1;
kotakku 0:b1ce54272580 94 };
kotakku 0:b1ce54272580 95
kotakku 0:b1ce54272580 96 struct KBDINFO {
kotakku 0:b1ce54272580 97
kotakku 0:b1ce54272580 98 struct {
kotakku 0:b1ce54272580 99 uint8_t bmLeftCtrl : 1;
kotakku 0:b1ce54272580 100 uint8_t bmLeftShift : 1;
kotakku 0:b1ce54272580 101 uint8_t bmLeftAlt : 1;
kotakku 0:b1ce54272580 102 uint8_t bmLeftGUI : 1;
kotakku 0:b1ce54272580 103 uint8_t bmRightCtrl : 1;
kotakku 0:b1ce54272580 104 uint8_t bmRightShift : 1;
kotakku 0:b1ce54272580 105 uint8_t bmRightAlt : 1;
kotakku 0:b1ce54272580 106 uint8_t bmRightGUI : 1;
kotakku 0:b1ce54272580 107 };
kotakku 0:b1ce54272580 108 uint8_t bReserved;
kotakku 0:b1ce54272580 109 uint8_t Keys[6];
kotakku 0:b1ce54272580 110 };
kotakku 0:b1ce54272580 111
kotakku 0:b1ce54272580 112 struct KBDLEDS {
kotakku 0:b1ce54272580 113 uint8_t bmNumLock : 1;
kotakku 0:b1ce54272580 114 uint8_t bmCapsLock : 1;
kotakku 0:b1ce54272580 115 uint8_t bmScrollLock : 1;
kotakku 0:b1ce54272580 116 uint8_t bmCompose : 1;
kotakku 0:b1ce54272580 117 uint8_t bmKana : 1;
kotakku 0:b1ce54272580 118 uint8_t bmReserved : 3;
kotakku 0:b1ce54272580 119 };
kotakku 0:b1ce54272580 120
kotakku 0:b1ce54272580 121 class KeyboardReportParser : public HIDReportParser {
kotakku 0:b1ce54272580 122 static const uint8_t numKeys[10];
kotakku 0:b1ce54272580 123 static const uint8_t symKeysUp[12];
kotakku 0:b1ce54272580 124 static const uint8_t symKeysLo[12];
kotakku 0:b1ce54272580 125 static const uint8_t padKeys[5];
kotakku 0:b1ce54272580 126
kotakku 0:b1ce54272580 127 protected:
kotakku 0:b1ce54272580 128
kotakku 0:b1ce54272580 129 union {
kotakku 0:b1ce54272580 130 KBDINFO kbdInfo;
kotakku 0:b1ce54272580 131 uint8_t bInfo[sizeof (KBDINFO)];
kotakku 0:b1ce54272580 132 } prevState;
kotakku 0:b1ce54272580 133
kotakku 0:b1ce54272580 134 union {
kotakku 0:b1ce54272580 135 KBDLEDS kbdLeds;
kotakku 0:b1ce54272580 136 uint8_t bLeds;
kotakku 0:b1ce54272580 137 } kbdLockingKeys;
kotakku 0:b1ce54272580 138
kotakku 0:b1ce54272580 139 uint8_t OemToAscii(uint8_t mod, uint8_t key);
kotakku 0:b1ce54272580 140
kotakku 0:b1ce54272580 141 public:
kotakku 0:b1ce54272580 142
kotakku 0:b1ce54272580 143 KeyboardReportParser() {
kotakku 0:b1ce54272580 144 kbdLockingKeys.bLeds = 0;
kotakku 0:b1ce54272580 145 };
kotakku 0:b1ce54272580 146
kotakku 0:b1ce54272580 147 void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
kotakku 0:b1ce54272580 148
kotakku 0:b1ce54272580 149 protected:
kotakku 0:b1ce54272580 150
kotakku 0:b1ce54272580 151 virtual uint8_t HandleLockingKeys(USBHID* hid, uint8_t key) {
kotakku 0:b1ce54272580 152 uint8_t old_keys = kbdLockingKeys.bLeds;
kotakku 0:b1ce54272580 153
kotakku 0:b1ce54272580 154 switch(key) {
kotakku 0:b1ce54272580 155 case UHS_HID_BOOT_KEY_NUM_LOCK:
kotakku 0:b1ce54272580 156 kbdLockingKeys.kbdLeds.bmNumLock = ~kbdLockingKeys.kbdLeds.bmNumLock;
kotakku 0:b1ce54272580 157 break;
kotakku 0:b1ce54272580 158 case UHS_HID_BOOT_KEY_CAPS_LOCK:
kotakku 0:b1ce54272580 159 kbdLockingKeys.kbdLeds.bmCapsLock = ~kbdLockingKeys.kbdLeds.bmCapsLock;
kotakku 0:b1ce54272580 160 break;
kotakku 0:b1ce54272580 161 case UHS_HID_BOOT_KEY_SCROLL_LOCK:
kotakku 0:b1ce54272580 162 kbdLockingKeys.kbdLeds.bmScrollLock = ~kbdLockingKeys.kbdLeds.bmScrollLock;
kotakku 0:b1ce54272580 163 break;
kotakku 0:b1ce54272580 164 }
kotakku 0:b1ce54272580 165
kotakku 0:b1ce54272580 166 if(old_keys != kbdLockingKeys.bLeds && hid) {
kotakku 0:b1ce54272580 167 uint8_t lockLeds = kbdLockingKeys.bLeds;
kotakku 0:b1ce54272580 168 return (hid->SetReport(0, 0/*hid->GetIface()*/, 2, 0, 1, &lockLeds));
kotakku 0:b1ce54272580 169 }
kotakku 0:b1ce54272580 170
kotakku 0:b1ce54272580 171 return 0;
kotakku 0:b1ce54272580 172 };
kotakku 0:b1ce54272580 173
kotakku 0:b1ce54272580 174 virtual void OnControlKeysChanged(uint8_t before __attribute__((unused)), uint8_t after __attribute__((unused))) {
kotakku 0:b1ce54272580 175 };
kotakku 0:b1ce54272580 176
kotakku 0:b1ce54272580 177 virtual void OnKeyDown(uint8_t mod __attribute__((unused)), uint8_t key __attribute__((unused))) {
kotakku 0:b1ce54272580 178 };
kotakku 0:b1ce54272580 179
kotakku 0:b1ce54272580 180 virtual void OnKeyUp(uint8_t mod __attribute__((unused)), uint8_t key __attribute__((unused))) {
kotakku 0:b1ce54272580 181 };
kotakku 0:b1ce54272580 182
kotakku 0:b1ce54272580 183 virtual const uint8_t *getNumKeys() {
kotakku 0:b1ce54272580 184 return numKeys;
kotakku 0:b1ce54272580 185 };
kotakku 0:b1ce54272580 186
kotakku 0:b1ce54272580 187 virtual const uint8_t *getSymKeysUp() {
kotakku 0:b1ce54272580 188 return symKeysUp;
kotakku 0:b1ce54272580 189 };
kotakku 0:b1ce54272580 190
kotakku 0:b1ce54272580 191 virtual const uint8_t *getSymKeysLo() {
kotakku 0:b1ce54272580 192 return symKeysLo;
kotakku 0:b1ce54272580 193 };
kotakku 0:b1ce54272580 194
kotakku 0:b1ce54272580 195 virtual const uint8_t *getPadKeys() {
kotakku 0:b1ce54272580 196 return padKeys;
kotakku 0:b1ce54272580 197 };
kotakku 0:b1ce54272580 198 };
kotakku 0:b1ce54272580 199
kotakku 0:b1ce54272580 200 template <const uint8_t BOOT_PROTOCOL>
kotakku 0:b1ce54272580 201 class HIDBoot : public USBHID //public USBDeviceConfig, public UsbConfigXtracter
kotakku 0:b1ce54272580 202 {
kotakku 0:b1ce54272580 203 EpInfo epInfo[totalEndpoints(BOOT_PROTOCOL)];
kotakku 0:b1ce54272580 204 HIDReportParser *pRptParser[epMUL(BOOT_PROTOCOL)];
kotakku 0:b1ce54272580 205
kotakku 0:b1ce54272580 206 uint8_t bConfNum; // configuration number
kotakku 0:b1ce54272580 207 uint8_t bIfaceNum; // Interface Number
kotakku 0:b1ce54272580 208 uint8_t bNumIface; // number of interfaces in the configuration
kotakku 0:b1ce54272580 209 uint8_t bNumEP; // total number of EP in the configuration
kotakku 0:b1ce54272580 210 uint32_t qNextPollTime; // next poll time
kotakku 0:b1ce54272580 211 bool bPollEnable; // poll enable flag
kotakku 0:b1ce54272580 212 uint8_t bInterval; // largest interval
kotakku 0:b1ce54272580 213 bool bRptProtoEnable; // Report Protocol enable flag
kotakku 0:b1ce54272580 214
kotakku 0:b1ce54272580 215 void Initialize();
kotakku 0:b1ce54272580 216
kotakku 0:b1ce54272580 217 virtual HIDReportParser* GetReportParser(uint8_t id) {
kotakku 0:b1ce54272580 218 return pRptParser[id];
kotakku 0:b1ce54272580 219 };
kotakku 0:b1ce54272580 220
kotakku 0:b1ce54272580 221 public:
kotakku 0:b1ce54272580 222 HIDBoot(USB *p, bool bRptProtoEnable = false);
kotakku 0:b1ce54272580 223
kotakku 0:b1ce54272580 224 virtual bool SetReportParser(uint8_t id, HIDReportParser *prs) {
kotakku 0:b1ce54272580 225 pRptParser[id] = prs;
kotakku 0:b1ce54272580 226 return true;
kotakku 0:b1ce54272580 227 };
kotakku 0:b1ce54272580 228
kotakku 0:b1ce54272580 229 // USBDeviceConfig implementation
kotakku 0:b1ce54272580 230 uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
kotakku 0:b1ce54272580 231 uint8_t Release();
kotakku 0:b1ce54272580 232 uint8_t Poll();
kotakku 0:b1ce54272580 233
kotakku 0:b1ce54272580 234 virtual uint8_t GetAddress() {
kotakku 0:b1ce54272580 235 return bAddress;
kotakku 0:b1ce54272580 236 };
kotakku 0:b1ce54272580 237
kotakku 0:b1ce54272580 238 virtual bool isReady() {
kotakku 0:b1ce54272580 239 return bPollEnable;
kotakku 0:b1ce54272580 240 };
kotakku 0:b1ce54272580 241
kotakku 0:b1ce54272580 242 // UsbConfigXtracter implementation
kotakku 0:b1ce54272580 243 // Method should be defined here if virtual.
kotakku 0:b1ce54272580 244 virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
kotakku 0:b1ce54272580 245
kotakku 0:b1ce54272580 246 virtual bool DEVCLASSOK(uint8_t klass) {
kotakku 0:b1ce54272580 247 return (klass == USB_CLASS_HID);
kotakku 0:b1ce54272580 248 }
kotakku 0:b1ce54272580 249
kotakku 0:b1ce54272580 250 virtual bool DEVSUBCLASSOK(uint8_t subklass) {
kotakku 0:b1ce54272580 251 return (subklass == BOOT_PROTOCOL);
kotakku 0:b1ce54272580 252 }
kotakku 0:b1ce54272580 253 };
kotakku 0:b1ce54272580 254
kotakku 0:b1ce54272580 255 template <const uint8_t BOOT_PROTOCOL>
kotakku 0:b1ce54272580 256 HIDBoot<BOOT_PROTOCOL>::HIDBoot(USB *p, bool bRptProtoEnable/* = false*/) :
kotakku 0:b1ce54272580 257 USBHID(p),
kotakku 0:b1ce54272580 258 qNextPollTime(0),
kotakku 0:b1ce54272580 259 bPollEnable(false),
kotakku 0:b1ce54272580 260 bRptProtoEnable(bRptProtoEnable) {
kotakku 0:b1ce54272580 261 Initialize();
kotakku 0:b1ce54272580 262
kotakku 0:b1ce54272580 263 for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) {
kotakku 0:b1ce54272580 264 pRptParser[i] = NULL;
kotakku 0:b1ce54272580 265 }
kotakku 0:b1ce54272580 266 if(pUsb)
kotakku 0:b1ce54272580 267 pUsb->RegisterDeviceClass(this);
kotakku 0:b1ce54272580 268 }
kotakku 0:b1ce54272580 269
kotakku 0:b1ce54272580 270 template <const uint8_t BOOT_PROTOCOL>
kotakku 0:b1ce54272580 271 void HIDBoot<BOOT_PROTOCOL>::Initialize() {
kotakku 0:b1ce54272580 272 for(int i = 0; i < totalEndpoints(BOOT_PROTOCOL); i++) {
kotakku 0:b1ce54272580 273 epInfo[i].epAddr = 0;
kotakku 0:b1ce54272580 274 epInfo[i].maxPktSize = (i) ? 0 : 8;
kotakku 0:b1ce54272580 275 epInfo[i].bmSndToggle = 0;
kotakku 0:b1ce54272580 276 epInfo[i].bmRcvToggle = 0;
kotakku 0:b1ce54272580 277 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
kotakku 0:b1ce54272580 278 }
kotakku 0:b1ce54272580 279 bNumEP = 1;
kotakku 0:b1ce54272580 280 bNumIface = 0;
kotakku 0:b1ce54272580 281 bConfNum = 0;
kotakku 0:b1ce54272580 282 }
kotakku 0:b1ce54272580 283
kotakku 0:b1ce54272580 284 template <const uint8_t BOOT_PROTOCOL>
kotakku 0:b1ce54272580 285 uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed) {
kotakku 0:b1ce54272580 286 const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
kotakku 0:b1ce54272580 287
kotakku 0:b1ce54272580 288 uint8_t buf[constBufSize];
kotakku 0:b1ce54272580 289 USB_DEVICE_DESCRIPTOR* device;
kotakku 0:b1ce54272580 290 uint8_t rcode;
kotakku 0:b1ce54272580 291 UsbDevice *p = NULL;
kotakku 0:b1ce54272580 292 EpInfo *oldep_ptr = NULL;
kotakku 0:b1ce54272580 293 uint8_t len = 0;
kotakku 0:b1ce54272580 294 //uint16_t cd_len = 0;
kotakku 0:b1ce54272580 295
kotakku 0:b1ce54272580 296 uint8_t num_of_conf; // number of configurations
kotakku 0:b1ce54272580 297 //uint8_t num_of_intf; // number of interfaces
kotakku 0:b1ce54272580 298
kotakku 0:b1ce54272580 299 AddressPool &addrPool = pUsb->GetAddressPool();
kotakku 0:b1ce54272580 300
kotakku 0:b1ce54272580 301 USBTRACE("BM Init\r\n");
kotakku 0:b1ce54272580 302 //USBTRACE2("totalEndpoints:", (uint8_t) (totalEndpoints(BOOT_PROTOCOL)));
kotakku 0:b1ce54272580 303 //USBTRACE2("epMUL:", epMUL(BOOT_PROTOCOL));
kotakku 0:b1ce54272580 304
kotakku 0:b1ce54272580 305 if(bAddress)
kotakku 0:b1ce54272580 306 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
kotakku 0:b1ce54272580 307
kotakku 0:b1ce54272580 308 bInterval = 0;
kotakku 0:b1ce54272580 309 // Get pointer to pseudo device with address 0 assigned
kotakku 0:b1ce54272580 310 p = addrPool.GetUsbDevicePtr(0);
kotakku 0:b1ce54272580 311
kotakku 0:b1ce54272580 312 if(!p)
kotakku 0:b1ce54272580 313 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 314
kotakku 0:b1ce54272580 315 if(!p->epinfo) {
kotakku 0:b1ce54272580 316 USBTRACE("epinfo\r\n");
kotakku 0:b1ce54272580 317 return USB_ERROR_EPINFO_IS_NULL;
kotakku 0:b1ce54272580 318 }
kotakku 0:b1ce54272580 319
kotakku 0:b1ce54272580 320 // Save old pointer to EP_RECORD of address 0
kotakku 0:b1ce54272580 321 oldep_ptr = p->epinfo;
kotakku 0:b1ce54272580 322
kotakku 0:b1ce54272580 323 // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
kotakku 0:b1ce54272580 324 p->epinfo = epInfo;
kotakku 0:b1ce54272580 325
kotakku 0:b1ce54272580 326 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 327
kotakku 0:b1ce54272580 328 // Get device descriptor
kotakku 0:b1ce54272580 329 rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
kotakku 0:b1ce54272580 330
kotakku 0:b1ce54272580 331 if(!rcode)
kotakku 0:b1ce54272580 332 len = (buf[0] > constBufSize) ? constBufSize : buf[0];
kotakku 0:b1ce54272580 333
kotakku 0:b1ce54272580 334 device = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
kotakku 0:b1ce54272580 335
kotakku 0:b1ce54272580 336 if(rcode) {
kotakku 0:b1ce54272580 337 // Restore p->epinfo
kotakku 0:b1ce54272580 338 p->epinfo = oldep_ptr;
kotakku 0:b1ce54272580 339
kotakku 0:b1ce54272580 340 goto FailGetDevDescr;
kotakku 0:b1ce54272580 341 }
kotakku 0:b1ce54272580 342
kotakku 0:b1ce54272580 343 // Restore p->epinfo
kotakku 0:b1ce54272580 344 p->epinfo = oldep_ptr;
kotakku 0:b1ce54272580 345
kotakku 0:b1ce54272580 346 // Allocate new address according to device class
kotakku 0:b1ce54272580 347 bAddress = addrPool.AllocAddress(parent, false, port);
kotakku 0:b1ce54272580 348
kotakku 0:b1ce54272580 349 if(!bAddress)
kotakku 0:b1ce54272580 350 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
kotakku 0:b1ce54272580 351
kotakku 0:b1ce54272580 352 // Extract Max Packet Size from the device descriptor
kotakku 0:b1ce54272580 353 epInfo[0].maxPktSize = (uint8_t)(device->bMaxPacketSize0);
kotakku 0:b1ce54272580 354
kotakku 0:b1ce54272580 355 // Assign new address to the device
kotakku 0:b1ce54272580 356 rcode = pUsb->setAddr(0, 0, bAddress);
kotakku 0:b1ce54272580 357
kotakku 0:b1ce54272580 358 if(rcode) {
kotakku 0:b1ce54272580 359 p->lowspeed = false;
kotakku 0:b1ce54272580 360 addrPool.FreeAddress(bAddress);
kotakku 0:b1ce54272580 361 bAddress = 0;
kotakku 0:b1ce54272580 362 USBTRACE2("setAddr:", rcode);
kotakku 0:b1ce54272580 363 return rcode;
kotakku 0:b1ce54272580 364 }
kotakku 0:b1ce54272580 365 //delay(2); //per USB 2.0 sect.9.2.6.3
kotakku 0:b1ce54272580 366
kotakku 0:b1ce54272580 367 USBTRACE2("Addr:", bAddress);
kotakku 0:b1ce54272580 368
kotakku 0:b1ce54272580 369 p->lowspeed = false;
kotakku 0:b1ce54272580 370
kotakku 0:b1ce54272580 371 p = addrPool.GetUsbDevicePtr(bAddress);
kotakku 0:b1ce54272580 372
kotakku 0:b1ce54272580 373 if(!p)
kotakku 0:b1ce54272580 374 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 375
kotakku 0:b1ce54272580 376 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 377
kotakku 0:b1ce54272580 378 if(len)
kotakku 0:b1ce54272580 379 rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
kotakku 0:b1ce54272580 380
kotakku 0:b1ce54272580 381 if(rcode)
kotakku 0:b1ce54272580 382 goto FailGetDevDescr;
kotakku 0:b1ce54272580 383
kotakku 0:b1ce54272580 384 num_of_conf = device->bNumConfigurations;
kotakku 0:b1ce54272580 385
kotakku 0:b1ce54272580 386 USBTRACE2("NC:", num_of_conf);
kotakku 0:b1ce54272580 387
kotakku 0:b1ce54272580 388 // GCC will optimize unused stuff away.
kotakku 0:b1ce54272580 389 if((BOOT_PROTOCOL & (USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE)) == (USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE)) {
kotakku 0:b1ce54272580 390 USBTRACE("HID_PROTOCOL_KEYBOARD AND MOUSE\r\n");
kotakku 0:b1ce54272580 391 ConfigDescParser<
kotakku 0:b1ce54272580 392 USB_CLASS_HID,
kotakku 0:b1ce54272580 393 HID_BOOT_INTF_SUBCLASS,
kotakku 0:b1ce54272580 394 USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE,
kotakku 0:b1ce54272580 395 CP_MASK_COMPARE_ALL > confDescrParser(this);
kotakku 0:b1ce54272580 396 confDescrParser.SetOR(); // Use the OR variant.
kotakku 0:b1ce54272580 397 for(uint8_t i = 0; i < num_of_conf; i++) {
kotakku 0:b1ce54272580 398 pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
kotakku 0:b1ce54272580 399 if(bNumEP == (uint8_t)(totalEndpoints(BOOT_PROTOCOL)))
kotakku 0:b1ce54272580 400 break;
kotakku 0:b1ce54272580 401 }
kotakku 0:b1ce54272580 402 } else {
kotakku 0:b1ce54272580 403 // GCC will optimize unused stuff away.
kotakku 0:b1ce54272580 404 if(BOOT_PROTOCOL & USB_HID_PROTOCOL_KEYBOARD) {
kotakku 0:b1ce54272580 405 USBTRACE("HID_PROTOCOL_KEYBOARD\r\n");
kotakku 0:b1ce54272580 406 for(uint8_t i = 0; i < num_of_conf; i++) {
kotakku 0:b1ce54272580 407 ConfigDescParser<
kotakku 0:b1ce54272580 408 USB_CLASS_HID,
kotakku 0:b1ce54272580 409 HID_BOOT_INTF_SUBCLASS,
kotakku 0:b1ce54272580 410 USB_HID_PROTOCOL_KEYBOARD,
kotakku 0:b1ce54272580 411 CP_MASK_COMPARE_ALL> confDescrParserA(this);
kotakku 0:b1ce54272580 412
kotakku 0:b1ce54272580 413 pUsb->getConfDescr(bAddress, 0, i, &confDescrParserA);
kotakku 0:b1ce54272580 414 if(bNumEP == (uint8_t)(totalEndpoints(BOOT_PROTOCOL)))
kotakku 0:b1ce54272580 415 break;
kotakku 0:b1ce54272580 416 }
kotakku 0:b1ce54272580 417 }
kotakku 0:b1ce54272580 418
kotakku 0:b1ce54272580 419 // GCC will optimize unused stuff away.
kotakku 0:b1ce54272580 420 if(BOOT_PROTOCOL & USB_HID_PROTOCOL_MOUSE) {
kotakku 0:b1ce54272580 421 USBTRACE("HID_PROTOCOL_MOUSE\r\n");
kotakku 0:b1ce54272580 422 for(uint8_t i = 0; i < num_of_conf; i++) {
kotakku 0:b1ce54272580 423 ConfigDescParser<
kotakku 0:b1ce54272580 424 USB_CLASS_HID,
kotakku 0:b1ce54272580 425 HID_BOOT_INTF_SUBCLASS,
kotakku 0:b1ce54272580 426 USB_HID_PROTOCOL_MOUSE,
kotakku 0:b1ce54272580 427 CP_MASK_COMPARE_ALL> confDescrParserB(this);
kotakku 0:b1ce54272580 428
kotakku 0:b1ce54272580 429 pUsb->getConfDescr(bAddress, 0, i, &confDescrParserB);
kotakku 0:b1ce54272580 430 if(bNumEP == ((uint8_t)(totalEndpoints(BOOT_PROTOCOL))))
kotakku 0:b1ce54272580 431 break;
kotakku 0:b1ce54272580 432
kotakku 0:b1ce54272580 433 }
kotakku 0:b1ce54272580 434 }
kotakku 0:b1ce54272580 435 }
kotakku 0:b1ce54272580 436 USBTRACE2("bNumEP:", bNumEP);
kotakku 0:b1ce54272580 437
kotakku 0:b1ce54272580 438 if(bNumEP != (uint8_t)(totalEndpoints(BOOT_PROTOCOL))) {
kotakku 0:b1ce54272580 439 rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
kotakku 0:b1ce54272580 440 goto Fail;
kotakku 0:b1ce54272580 441 }
kotakku 0:b1ce54272580 442
kotakku 0:b1ce54272580 443 // Assign epInfo to epinfo pointer
kotakku 0:b1ce54272580 444 rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
kotakku 0:b1ce54272580 445 //USBTRACE2("setEpInfoEntry returned ", rcode);
kotakku 0:b1ce54272580 446 USBTRACE2("Cnf:", bConfNum);
kotakku 0:b1ce54272580 447
kotakku 0:b1ce54272580 448 delay(1000);
kotakku 0:b1ce54272580 449
kotakku 0:b1ce54272580 450 // Set Configuration Value
kotakku 0:b1ce54272580 451 rcode = pUsb->setConf(bAddress, 0, bConfNum);
kotakku 0:b1ce54272580 452
kotakku 0:b1ce54272580 453 if(rcode)
kotakku 0:b1ce54272580 454 goto FailSetConfDescr;
kotakku 0:b1ce54272580 455
kotakku 0:b1ce54272580 456 delay(1000);
kotakku 0:b1ce54272580 457
kotakku 0:b1ce54272580 458 USBTRACE2("bIfaceNum:", bIfaceNum);
kotakku 0:b1ce54272580 459 USBTRACE2("bNumIface:", bNumIface);
kotakku 0:b1ce54272580 460
kotakku 0:b1ce54272580 461 // Yes, mouse wants SetProtocol and SetIdle too!
kotakku 0:b1ce54272580 462 for(uint8_t i = 0; i < epMUL(BOOT_PROTOCOL); i++) {
kotakku 0:b1ce54272580 463 USBTRACE2("\r\nInterface:", i);
kotakku 0:b1ce54272580 464 rcode = SetProtocol(i, bRptProtoEnable ? HID_RPT_PROTOCOL : USB_HID_BOOT_PROTOCOL);
kotakku 0:b1ce54272580 465 if(rcode) goto FailSetProtocol;
kotakku 0:b1ce54272580 466 USBTRACE2("PROTOCOL SET HID_BOOT rcode:", rcode);
kotakku 0:b1ce54272580 467 rcode = SetIdle(i, 0, 0);
kotakku 0:b1ce54272580 468 USBTRACE2("SET_IDLE rcode:", rcode);
kotakku 0:b1ce54272580 469 // if(rcode) goto FailSetIdle; This can fail.
kotakku 0:b1ce54272580 470 // Get the RPIPE and just throw it away.
kotakku 0:b1ce54272580 471 SinkParser<USBReadParser, uint16_t, uint16_t> sink;
kotakku 0:b1ce54272580 472 rcode = GetReportDescr(i, &sink);
kotakku 0:b1ce54272580 473 USBTRACE2("RPIPE rcode:", rcode);
kotakku 0:b1ce54272580 474 }
kotakku 0:b1ce54272580 475
kotakku 0:b1ce54272580 476 // Get RPIPE and throw it away.
kotakku 0:b1ce54272580 477
kotakku 0:b1ce54272580 478 if(BOOT_PROTOCOL & USB_HID_PROTOCOL_KEYBOARD) {
kotakku 0:b1ce54272580 479 // Wake keyboard interface by twinkling up to 5 LEDs that are in the spec.
kotakku 0:b1ce54272580 480 // kana, compose, scroll, caps, num
kotakku 0:b1ce54272580 481 rcode = 0x20; // Reuse rcode.
kotakku 0:b1ce54272580 482 while(rcode) {
kotakku 0:b1ce54272580 483 rcode >>= 1;
kotakku 0:b1ce54272580 484 // Ignore any error returned, we don't care if LED is not supported
kotakku 0:b1ce54272580 485 SetReport(0, 0, 2, 0, 1, &rcode); // Eventually becomes zero (All off)
kotakku 0:b1ce54272580 486 delay(25);
kotakku 0:b1ce54272580 487 }
kotakku 0:b1ce54272580 488 }
kotakku 0:b1ce54272580 489 USBTRACE("BM configured\r\n");
kotakku 0:b1ce54272580 490
kotakku 0:b1ce54272580 491 bPollEnable = true;
kotakku 0:b1ce54272580 492 return 0;
kotakku 0:b1ce54272580 493
kotakku 0:b1ce54272580 494 FailGetDevDescr:
kotakku 0:b1ce54272580 495 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 496 NotifyFailGetDevDescr();
kotakku 0:b1ce54272580 497 goto Fail;
kotakku 0:b1ce54272580 498 #endif
kotakku 0:b1ce54272580 499
kotakku 0:b1ce54272580 500 //FailSetDevTblEntry:
kotakku 0:b1ce54272580 501 //#ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 502 // NotifyFailSetDevTblEntry();
kotakku 0:b1ce54272580 503 // goto Fail;
kotakku 0:b1ce54272580 504 //#endif
kotakku 0:b1ce54272580 505
kotakku 0:b1ce54272580 506 //FailGetConfDescr:
kotakku 0:b1ce54272580 507 //#ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 508 // NotifyFailGetConfDescr();
kotakku 0:b1ce54272580 509 // goto Fail;
kotakku 0:b1ce54272580 510 //#endif
kotakku 0:b1ce54272580 511
kotakku 0:b1ce54272580 512 FailSetConfDescr:
kotakku 0:b1ce54272580 513 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 514 NotifyFailSetConfDescr();
kotakku 0:b1ce54272580 515 goto Fail;
kotakku 0:b1ce54272580 516 #endif
kotakku 0:b1ce54272580 517
kotakku 0:b1ce54272580 518 FailSetProtocol:
kotakku 0:b1ce54272580 519 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 520 USBTRACE("SetProto:");
kotakku 0:b1ce54272580 521 goto Fail;
kotakku 0:b1ce54272580 522 #endif
kotakku 0:b1ce54272580 523
kotakku 0:b1ce54272580 524 //FailSetIdle:
kotakku 0:b1ce54272580 525 //#ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 526 // USBTRACE("SetIdle:");
kotakku 0:b1ce54272580 527 //#endif
kotakku 0:b1ce54272580 528
kotakku 0:b1ce54272580 529 Fail:
kotakku 0:b1ce54272580 530 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 531 NotifyFail(rcode);
kotakku 0:b1ce54272580 532 #endif
kotakku 0:b1ce54272580 533 Release();
kotakku 0:b1ce54272580 534
kotakku 0:b1ce54272580 535 return rcode;
kotakku 0:b1ce54272580 536 }
kotakku 0:b1ce54272580 537
kotakku 0:b1ce54272580 538 template <const uint8_t BOOT_PROTOCOL>
kotakku 0:b1ce54272580 539 void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
kotakku 0:b1ce54272580 540
kotakku 0:b1ce54272580 541 // If the first configuration satisfies, the others are not considered.
kotakku 0:b1ce54272580 542 //if(bNumEP > 1 && conf != bConfNum)
kotakku 0:b1ce54272580 543 if(bNumEP == totalEndpoints(BOOT_PROTOCOL))
kotakku 0:b1ce54272580 544 return;
kotakku 0:b1ce54272580 545
kotakku 0:b1ce54272580 546 bConfNum = conf;
kotakku 0:b1ce54272580 547 bIfaceNum = iface;
kotakku 0:b1ce54272580 548
kotakku 0:b1ce54272580 549 if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT && (pep->bEndpointAddress & 0x80) == 0x80) {
kotakku 0:b1ce54272580 550 if(pep->bInterval > bInterval) bInterval = pep->bInterval;
kotakku 0:b1ce54272580 551
kotakku 0:b1ce54272580 552 // Fill in the endpoint info structure
kotakku 0:b1ce54272580 553 epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
kotakku 0:b1ce54272580 554 epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
kotakku 0:b1ce54272580 555 epInfo[bNumEP].bmSndToggle = 0;
kotakku 0:b1ce54272580 556 epInfo[bNumEP].bmRcvToggle = 0;
kotakku 0:b1ce54272580 557 epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
kotakku 0:b1ce54272580 558 bNumEP++;
kotakku 0:b1ce54272580 559
kotakku 0:b1ce54272580 560 }
kotakku 0:b1ce54272580 561 }
kotakku 0:b1ce54272580 562
kotakku 0:b1ce54272580 563 template <const uint8_t BOOT_PROTOCOL>
kotakku 0:b1ce54272580 564 uint8_t HIDBoot<BOOT_PROTOCOL>::Release() {
kotakku 0:b1ce54272580 565 pUsb->GetAddressPool().FreeAddress(bAddress);
kotakku 0:b1ce54272580 566
kotakku 0:b1ce54272580 567 bConfNum = 0;
kotakku 0:b1ce54272580 568 bIfaceNum = 0;
kotakku 0:b1ce54272580 569 bNumEP = 1;
kotakku 0:b1ce54272580 570 bAddress = 0;
kotakku 0:b1ce54272580 571 qNextPollTime = 0;
kotakku 0:b1ce54272580 572 bPollEnable = false;
kotakku 0:b1ce54272580 573
kotakku 0:b1ce54272580 574 return 0;
kotakku 0:b1ce54272580 575 }
kotakku 0:b1ce54272580 576
kotakku 0:b1ce54272580 577 template <const uint8_t BOOT_PROTOCOL>
kotakku 0:b1ce54272580 578 uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
kotakku 0:b1ce54272580 579 uint8_t rcode = 0;
kotakku 0:b1ce54272580 580
kotakku 0:b1ce54272580 581 if(bPollEnable && ((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L)) {
kotakku 0:b1ce54272580 582
kotakku 0:b1ce54272580 583 // To-do: optimize manually, using the for loop only if needed.
kotakku 0:b1ce54272580 584 for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) {
kotakku 0:b1ce54272580 585 const uint16_t const_buff_len = 16;
kotakku 0:b1ce54272580 586 uint8_t buf[const_buff_len];
kotakku 0:b1ce54272580 587
kotakku 0:b1ce54272580 588 USBTRACE3("(hidboot.h) i=", i, 0x81);
kotakku 0:b1ce54272580 589 USBTRACE3("(hidboot.h) epInfo[epInterruptInIndex + i].epAddr=", epInfo[epInterruptInIndex + i].epAddr, 0x81);
kotakku 0:b1ce54272580 590 USBTRACE3("(hidboot.h) epInfo[epInterruptInIndex + i].maxPktSize=", epInfo[epInterruptInIndex + i].maxPktSize, 0x81);
kotakku 0:b1ce54272580 591 uint16_t read = (uint16_t)epInfo[epInterruptInIndex + i].maxPktSize;
kotakku 0:b1ce54272580 592
kotakku 0:b1ce54272580 593 rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex + i].epAddr, &read, buf);
kotakku 0:b1ce54272580 594 // SOME buggy dongles report extra keys (like sleep) using a 2 byte packet on the wrong endpoint.
kotakku 0:b1ce54272580 595 // Since keyboard and mice must report at least 3 bytes, we ignore the extra data.
kotakku 0:b1ce54272580 596 if(!rcode && read > 2) {
kotakku 0:b1ce54272580 597 if(pRptParser[i])
kotakku 0:b1ce54272580 598 pRptParser[i]->Parse((USBHID*)this, 0, (uint8_t)read, buf);
kotakku 0:b1ce54272580 599 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 600 // We really don't care about errors and anomalies unless we are debugging.
kotakku 0:b1ce54272580 601 } else {
kotakku 0:b1ce54272580 602 if(rcode != hrNAK) {
kotakku 0:b1ce54272580 603 USBTRACE3("(hidboot.h) Poll:", rcode, 0x81);
kotakku 0:b1ce54272580 604 }
kotakku 0:b1ce54272580 605 if(!rcode && read) {
kotakku 0:b1ce54272580 606 USBTRACE3("(hidboot.h) Strange read count: ", read, 0x80);
kotakku 0:b1ce54272580 607 USBTRACE3("(hidboot.h) Interface:", i, 0x80);
kotakku 0:b1ce54272580 608 }
kotakku 0:b1ce54272580 609 }
kotakku 0:b1ce54272580 610
kotakku 0:b1ce54272580 611 if(!rcode && read && (UsbDEBUGlvl > 0x7f)) {
kotakku 0:b1ce54272580 612 for(uint8_t i = 0; i < read; i++) {
kotakku 0:b1ce54272580 613 PrintHex<uint8_t > (buf[i], 0x80);
kotakku 0:b1ce54272580 614 USBTRACE1(" ", 0x80);
kotakku 0:b1ce54272580 615 }
kotakku 0:b1ce54272580 616 if(read)
kotakku 0:b1ce54272580 617 USBTRACE1("\r\n", 0x80);
kotakku 0:b1ce54272580 618 #endif
kotakku 0:b1ce54272580 619 }
kotakku 0:b1ce54272580 620
kotakku 0:b1ce54272580 621 }
kotakku 0:b1ce54272580 622 qNextPollTime = (uint32_t)millis() + bInterval;
kotakku 0:b1ce54272580 623 }
kotakku 0:b1ce54272580 624 return rcode;
kotakku 0:b1ce54272580 625 }
kotakku 0:b1ce54272580 626
kotakku 0:b1ce54272580 627 #endif // __HIDBOOTMOUSE_H__
kotakku 0:b1ce54272580 628