#include #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); } } } }