Przeglądaj źródła

update: add tud_hid_get_report_cb()

Satoshi Yoneda 1 miesiąc temu
rodzic
commit
9d5c427097
1 zmienionych plików z 167 dodań i 156 usunięć
  1. 167 156
      usb_keypad1.c

+ 167 - 156
usb_keypad1.c

@@ -1,156 +1,167 @@
-#include <stdio.h>
-#include "pico/stdlib.h"
-
-#include "hardware/pio.h"
-#include "bsp/board_api.h"
-#include "tusb.h"
-#include "usb_descriptors.h"
-
-#include "keypad.h"
-#include "keymap.h"
-#include "display.h"
-
-#define KEYBOARD_REPORT_COUNT    6
-uint8_t key_report[KEYBOARD_REPORT_COUNT] = {0,0,0,0,0,0};
-
-char report_str[OLED_WIDTH/FONT_WIDTH];        // キーボードレポート表示用
-char indicator_str[OLED_WIDTH/FONT_WIDTH];     // LEDインジケーター表示用
-
-// レポート配列をクリア
-inline void clear_key_report(void)
-{
-    for(int i = 0; i < KEYBOARD_REPORT_COUNT; i++){
-        key_report[i] = 0;
-    }
-}
-
-// USBデバイスがマウントされた
-void tud_mount_cb(void)
-{
-    clear_key_report();
-}
-
-// USBデバイスがアンマウントされた
-void tud_umount_cb(void)
-{
-    clear_key_report();
-}
-
-// サスペンド状態に移行した
-void tud_suspend_cb(bool remote_wakeup_en)
-{
-    (void) remote_wakeup_en;
-    // 何もしない
-}
-
-// レジュームした
-void tud_resume_cb(void)
-{
-    // 何もしない
-}
-
-// REPORTが完了したら呼び出される
-// 次のREPORTを送るのに使える
-void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len)
-{
-  (void) instance;
-  (void) len;
-  (void) report;
-  // 何もしない
-}
-
-// コントロールリクエストGET_REPORT
-// キーボードは何も行わない
-uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
-{
-  // TODO not Implemented
-  (void) instance;
-  (void) report_id;
-  (void) report_type;
-  (void) buffer;
-  (void) reqlen;
-  // 何もしない
-  return 0;
-}
-
-// コントロールリクエストSET_REPORT
-// キーボードではCAPS LOCK等オンボードLEDの制御情報がホストから送られる
-void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
-{
-    (void) instance;
-
-    if( bufsize < 1 ) return;   // バッファゼロなら何もしない
-
-    if(report_type == HID_REPORT_TYPE_OUTPUT) {     // ホスト->デバイス
-        if(report_id == REPORT_ID_KEYBOARD) {     // キーボードレポート
-            uint8_t leds = buffer[0];               // LED制御情報
-
-            sprintf(indicator_str, "%s %s %s",
-                leds & KEYBOARD_LED_CAPSLOCK ? "CAP" : "   ",
-                leds & KEYBOARD_LED_NUMLOCK  ? "NUM" : "   ",
-                leds & KEYBOARD_LED_SCROLLLOCK ? "SCR" : "   "
-                // leds & KEYBOARD_LED_COMPOSE
-                // leds & KEYBOARD_LED_KANA
-                );
-            display_putstr(indicator_str, 0, 0, false);
-        }
-    }
-}
-
-// キーボードレポート表示
-void display_report(void)
-{
-    sprintf(report_str,"%02x%02x%02x%02x%02x%02x", key_report[0],key_report[1],key_report[2],key_report[3],key_report[4],key_report[5]);
-    display_putstr(report_str, 0, 3, false);
-}
-
-// メイン
-int main()
-{
-    // TinyUSBの初期化
-    board_init();
-    tud_init(BOARD_TUD_RHPORT);
-    if (board_init_after_tusb) {
-        board_init_after_tusb();
-    }
-    // シリアルコンソール
-    stdio_init_all();
-    // OLED表示
-    display_init();
-    display_report();
-    // キーパッド
-    keypad_init();
-
-    while (true) {
-        tud_task();     // TinyUSB定期的に呼び出す必要がある
-
-        key_t key = get_key();
-        if(tud_mounted()) {     // USBデバイスとしてマウントされていれば
-            if(key.state != KEYPAD_INVALID) {  // キー状態に変化あり
-                uint8_t scancode = keymap[key.code];
-                if(tud_suspended())     // サスペンド状態なら起こす
-                    tud_remote_wakeup();
-                
-                if(key.state == KEYPAD_PUSH) {    // キーが押された
-                    for(int i = 0; i < KEYBOARD_REPORT_COUNT; i++) {
-                        if(key_report[i] == 0) {
-                            key_report[i] = scancode;
-                            break;
-                        }
-                    }
-                }
-                else {                     // キーオフ
-                    for(int i = 0; i < KEYBOARD_REPORT_COUNT; i++) {
-                        if(key_report[i] == scancode)
-                            key_report[i] = 0;
-                    }
-                }
-                // キーボードレポートをOLEDに表示する
-                display_report();
-                // 空きがあればキーボードレポート送信
-                if(tud_hid_ready())
-                    tud_hid_keyboard_report(REPORT_ID_KEYBOARD,0, key_report);
-            }
-        }
-    }
-}
+#include <stdio.h>
+#include "pico/stdlib.h"
+
+#include "hardware/pio.h"
+#include "bsp/board_api.h"
+#include "tusb.h"
+#include "usb_descriptors.h"
+
+#include "keypad.h"
+#include "keymap.h"
+#include "display.h"
+
+#define KEYBOARD_REPORT_COUNT    6
+uint8_t key_report[KEYBOARD_REPORT_COUNT] = {0,0,0,0,0,0};
+
+char report_str[OLED_WIDTH/FONT_WIDTH];        // キーボードレポート表示用
+char indicator_str[OLED_WIDTH/FONT_WIDTH];     // LEDインジケーター表示用
+char debug_str[OLED_WIDTH/FONT_WIDTH];
+
+// レポート配列をクリア
+inline void clear_key_report(void)
+{
+    for(int i = 0; i < KEYBOARD_REPORT_COUNT; i++){
+        key_report[i] = 0;
+    }
+}
+
+// USBデバイスがマウントされた
+void tud_mount_cb(void)
+{
+    clear_key_report();
+}
+
+// USBデバイスがアンマウントされた
+void tud_umount_cb(void)
+{
+    clear_key_report();
+}
+
+// サスペンド状態に移行した
+void tud_suspend_cb(bool remote_wakeup_en)
+{
+    (void) remote_wakeup_en;
+    // 何もしない
+}
+
+// レジュームした
+void tud_resume_cb(void)
+{
+    // 何もしない
+}
+
+// REPORTが完了したら呼び出される
+// 次のREPORTを送るのに使える
+void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len)
+{
+  (void) instance;
+  (void) len;
+  (void) report;
+  // 何もしない
+}
+
+// コントロールリクエストGET_REPORT
+// キーボードではキーレポートを返すことになっている
+// だがこないみたいだぞ?
+uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
+{
+    (void) instance;
+    (void) report_id;
+    (void) report_type;
+
+    if(reqlen < sizeof(hid_keyboard_report_t) ) {
+        buffer[0] = 0;
+        return 1;       // とにかく何か返さないと駄目
+    }
+    else {
+        hid_keyboard_report_t   report;
+        report.modifier = 0;        // 修飾キー情報
+        report.reserved = 0;
+        memcpy(report.keycode, key_report, KEYBOARD_REPORT_COUNT );
+        memcpy(buffer, &report, sizeof(hid_keyboard_report_t));
+
+        return sizeof(hid_keyboard_report_t);
+    }
+}
+
+// コントロールリクエストSET_REPORT
+// キーボードではCAPS LOCK等オンボードLEDの制御情報がホストから送られる
+void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
+{
+    (void) instance;
+
+    if( bufsize < 1 ) return;   // バッファゼロなら何もしない
+
+    if(report_type == HID_REPORT_TYPE_OUTPUT) {     // ホスト->デバイス
+        if(report_id == REPORT_ID_KEYBOARD) {     // キーボードレポート
+            uint8_t leds = buffer[0];               // LED制御情報
+
+            sprintf(indicator_str, "%s %s %s",
+                leds & KEYBOARD_LED_CAPSLOCK ? "CAP" : "   ",
+                leds & KEYBOARD_LED_NUMLOCK  ? "NUM" : "   ",
+                leds & KEYBOARD_LED_SCROLLLOCK ? "SCR" : "   "
+                // leds & KEYBOARD_LED_COMPOSE
+                // leds & KEYBOARD_LED_KANA
+                );
+            display_putstr(indicator_str, 0, 0, false);
+        }
+    }
+}
+
+// キーボードレポート表示
+void display_report(void)
+{
+    sprintf(report_str,"%02x%02x%02x%02x%02x%02x", key_report[0],key_report[1],key_report[2],key_report[3],key_report[4],key_report[5]);
+    display_putstr(report_str, 0, 3, false);
+}
+
+// メイン
+int main()
+{
+    // TinyUSBの初期化
+    board_init();
+    tud_init(BOARD_TUD_RHPORT);
+    if (board_init_after_tusb) {
+        board_init_after_tusb();
+    }
+    // シリアルコンソール
+    stdio_init_all();
+    // OLED表示
+    display_init();
+    display_report();
+    // キーパッド
+    keypad_init();
+
+    while (true) {
+        tud_task();     // TinyUSB定期的に呼び出す必要がある
+
+        key_t key = get_key();
+        if(tud_mounted()) {     // USBデバイスとしてマウントされていれば
+            if(key.state != KEYPAD_INVALID) {  // キー状態に変化あり
+                uint8_t scancode = keymap[key.code];
+                if(tud_suspended())     // サスペンド状態なら起こす
+                    tud_remote_wakeup();
+                
+                if(key.state == KEYPAD_PUSH) {    // キーが押された
+                    for(int i = 0; i < KEYBOARD_REPORT_COUNT; i++) {
+                        if(key_report[i] == 0) {
+                            key_report[i] = scancode;
+                            break;
+                        }
+                    }
+                }
+                else {                     // キーオフ
+                    for(int i = 0; i < KEYBOARD_REPORT_COUNT; i++) {
+                        if(key_report[i] == scancode)
+                            key_report[i] = 0;
+                    }
+                }
+                // キーボードレポートをOLEDに表示する
+                display_report();
+                // 空きがあればキーボードレポート送信
+                if(tud_hid_ready())
+                    tud_hid_keyboard_report(REPORT_ID_KEYBOARD,0, key_report);
+            }
+        }
+    }
+}