LoginSignup
0
1

More than 1 year has passed since last update.

Arduinoでキー変換器を作る(BLE編):スクロール対応

Posted at

こちらでBLE対応したキー変換器を作ったが、
USB接続するキーボードはThinkpad Tracpoint Keyboardなので、Tracpointでスクロールができる。

これに対応するためにUSB Host Shield Libraryとキー変換器のソースに変更を加えた

USB Host Shieldの変更

USBのKeyboardやMouseはHIDとして認識され、デフォルトではBOOT PROTOCOLが有効になっている。このままではスクロールの情報は取得できないのでREPORTER PROTOCOLを使う。

REPORER PROTOCOLを有効にするにはHIDBootクラスのコンストラクタの第二引数をtrueにする

USB Usb;
USBHub Hub(&Usb);
HIDBoot<USB_HID_PROTOCOL_KEYBOARD | USB_HID_PROTOCOL_MOUSE> HidComposite(&Usb, true);

また、これだけではreportデータの処理がうまくいかないのでhidboot.h/cppに手を加える

hidboot.h diff
diff --git a/libraries/USB_Host_Shield_Library_2.0/hidboot.h b/libraries/USB_Host_Shield_Library_2.0/hidboot.h
index 4076400..722bea6 100644
--- a/libraries/USB_Host_Shield_Library_2.0/hidboot.h
+++ b/libraries/USB_Host_Shield_Library_2.0/hidboot.h
@@ -46,6 +46,7 @@ struct MOUSEINFO {
         };
         int8_t dX;
         int8_t dY;
+        int8_t dH;
 };
 
 class MouseReportParser : public HIDReportParser {
@@ -63,6 +64,9 @@ protected:
         virtual void OnMouseMove(MOUSEINFO *mi __attribute__((unused))) {
         };
 
+        virtual void OnScroll(MOUSEINFO *mi __attribute__((unused))) {
+        };
+
         virtual void OnLeftButtonUp(MOUSEINFO *mi __attribute__((unused))) {
         };
 
@@ -593,9 +597,20 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
                         rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex + i].epAddr, &read, buf);
                         // SOME buggy dongles report extra keys (like sleep) using a 2 byte packet on the wrong endpoint.
                         // Since keyboard and mice must report at least 3 bytes, we ignore the extra data.
-                        if(!rcode && read > 2) {
+                        // if protocol is Report, data must be at least 6 bytes.
+                        if(!rcode && read > ((!bRptProtoEnable) ? 2 : 5)) {
+# if 0
+                                Serial.print(read);
+                                Serial.print(":");
+                                for(uint16_t j = 0; j < read; j++)
+                                {
+                                        Serial.print(buf[j], HEX);
+                                        Serial.print(",");
+                                }
+                                Serial.println();
+#endif
                                 if(pRptParser[i])
-                                        pRptParser[i]->Parse((USBHID*)this, 0, (uint8_t)read, buf);
+                                        pRptParser[i]->Parse((USBHID*)this, bRptProtoEnable, (uint8_t)read, buf);
 #ifdef DEBUG_USB_HOST
                                 // We really don't care about errors and anomalies unless we are debugging.
                         } else {
hidboo.cpp diff
diff --git a/libraries/USB_Host_Shield_Library_2.0/hidboot.cpp b/libraries/USB_Host_Shield_Library_2.0/hidboot.cpp
index e372e62..5bd23d1 100644
--- a/libraries/USB_Host_Shield_Library_2.0/hidboot.cpp
+++ b/libraries/USB_Host_Shield_Library_2.0/hidboot.cpp
@@ -17,7 +17,12 @@ e-mail   :  support@circuitsathome.com
 #include "hidboot.h"
 
 void MouseReportParser::Parse(USBHID *hid __attribute__((unused)), bool is_rpt_id __attribute__((unused)), uint8_t len __attribute__((unused)), uint8_t *buf) {
-        MOUSEINFO *pmi = (MOUSEINFO*)buf;
+        MOUSEINFO *pmi;
+        if(is_rpt_id && (len > 3)) {
+                pmi = (MOUSEINFO*)(buf + 1);
+        } else {
+                pmi = (MOUSEINFO*)buf;
+        }
         // Future:
         // bool event;
 
@@ -111,6 +116,12 @@ void MouseReportParser::Parse(USBHID *hid __attribute__((unused)), bool is_rpt_i
                 // event = true;
         }
 
+        if(len > 3) {
+                if(pmi->dH) {
+                        OnScroll(pmi);
+                }
+        }
+
         //
         // Future:
         // Provide a callback that operates on the gathered events from above.
@@ -119,7 +130,7 @@ void MouseReportParser::Parse(USBHID *hid __attribute__((unused)), bool is_rpt_i
         //
 
         // Only the first byte matters (buttons). We do NOT need to save position info.
-        prevState.bInfo[0] = buf[0];
+        prevState.bInfo[0] = *(uint8_t*)pmi;
 #endif
 
 };

inoの修正

修正したソースは以下においてある

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1