|
@@ -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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|