Add USB to USB converter. unmature.
This commit is contained in:
parent
c5060ea819
commit
e7c030375a
9 changed files with 699 additions and 2 deletions
|
@ -78,6 +78,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# define REPORT_KEYS 6
|
# define REPORT_KEYS 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t mods;
|
uint8_t mods;
|
||||||
uint8_t rserved;
|
uint8_t rserved;
|
||||||
|
@ -92,4 +97,8 @@ typedef struct {
|
||||||
int8_t h;
|
int8_t h;
|
||||||
} __attribute__ ((packed)) report_mouse_t;
|
} __attribute__ ((packed)) report_mouse_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
#define IS_ERROR(code) (KB_ROLL_OVER <= (code) && (code) <= KB_UNDEFINED)
|
#define IS_ERROR(code) (KB_ROLL_OVER <= (code) && (code) <= KB_UNDEFINED)
|
||||||
|
#define IS_ANY(code) (KB_A <= (code))
|
||||||
#define IS_KEY(code) (KB_A <= (code) && (code) <= KB_EXSEL)
|
#define IS_KEY(code) (KB_A <= (code) && (code) <= KB_EXSEL)
|
||||||
#define IS_MOD(code) (KB_LCTRL <= (code) && (code) <= KB_RGUI)
|
#define IS_MOD(code) (KB_LCTRL <= (code) && (code) <= KB_RGUI)
|
||||||
#define IS_FN(code) (KB_FN0 <= (code) && (code) <= KB_FN7)
|
#define IS_FN(code) (KB_FN0 <= (code) && (code) <= KB_FN7)
|
||||||
|
|
131
converter/usb_usb/Makefile
Normal file
131
converter/usb_usb/Makefile
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# On command line:
|
||||||
|
#
|
||||||
|
# make all = Make software.
|
||||||
|
#
|
||||||
|
# make clean = Clean out built project files.
|
||||||
|
#
|
||||||
|
# make coff = Convert ELF to AVR COFF.
|
||||||
|
#
|
||||||
|
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||||
|
#
|
||||||
|
# make program = Download the hex file to the device.
|
||||||
|
# Please customize your programmer settings(PROGRAM_CMD)
|
||||||
|
#
|
||||||
|
# make teensy = Download the hex file to the device, using teensy_loader_cli.
|
||||||
|
# (must have teensy_loader_cli installed).
|
||||||
|
#
|
||||||
|
# make dfu = Download the hex file to the device, using dfu-programmer (must
|
||||||
|
# have dfu-programmer installed).
|
||||||
|
#
|
||||||
|
# make flip = Download the hex file to the device, using Atmel FLIP (must
|
||||||
|
# have Atmel FLIP installed).
|
||||||
|
#
|
||||||
|
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
|
||||||
|
# (must have dfu-programmer installed).
|
||||||
|
#
|
||||||
|
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
|
||||||
|
# (must have Atmel FLIP installed).
|
||||||
|
#
|
||||||
|
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||||
|
# with avr-gdb or avr-insight as the front end for debugging.
|
||||||
|
#
|
||||||
|
# make filename.s = Just compile filename.c into the assembler code only.
|
||||||
|
#
|
||||||
|
# make filename.i = Create a preprocessed source file for use in submitting
|
||||||
|
# bug reports to the GCC project.
|
||||||
|
#
|
||||||
|
# To rebuild project do "make clean" then "make all".
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Target file name (without extension).
|
||||||
|
TARGET = usb_usb
|
||||||
|
|
||||||
|
TOP_DIR = ../..
|
||||||
|
|
||||||
|
# Directory keyboard dependent files exist
|
||||||
|
TARGET_DIR = .
|
||||||
|
|
||||||
|
# MCU name
|
||||||
|
MCU = atmega32u4
|
||||||
|
|
||||||
|
|
||||||
|
# Processor frequency.
|
||||||
|
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||||
|
# processor frequency in Hz. You can then use this symbol in your source code to
|
||||||
|
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||||
|
# automatically to create a 32-bit value in your source code.
|
||||||
|
#
|
||||||
|
# This will be an integer division of F_USB below, as it is sourced by
|
||||||
|
# F_USB after it has run through any CPU prescalers. Note that this value
|
||||||
|
# does not *change* the processor frequency - it should merely be updated to
|
||||||
|
# reflect the processor speed set externally so that the code can use accurate
|
||||||
|
# software delays.
|
||||||
|
F_CPU = 16000000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# LUFA specific
|
||||||
|
#
|
||||||
|
# Target architecture (see library "Board Types" documentation).
|
||||||
|
ARCH = AVR8
|
||||||
|
# Input clock frequency.
|
||||||
|
# This will define a symbol, F_USB, in all source code files equal to the
|
||||||
|
# input clock frequency (before any prescaling is performed) in Hz. This value may
|
||||||
|
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
||||||
|
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
||||||
|
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
||||||
|
# at the end, this will be done automatically to create a 32-bit value in your
|
||||||
|
# source code.
|
||||||
|
#
|
||||||
|
# If no clock division is performed on the input clock inside the AVR (via the
|
||||||
|
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
||||||
|
F_USB = $(F_CPU)
|
||||||
|
# Interrupt driven control endpoint task
|
||||||
|
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Build Options
|
||||||
|
# comment out to disable the options.
|
||||||
|
#
|
||||||
|
MOUSEKEY_ENABLE = yes # Mouse keys
|
||||||
|
EXTRAKEY_ENABLE = yes # Media control and System control
|
||||||
|
CONSOLE_ENABLE = yes # Console for debug
|
||||||
|
#NKRO_ENABLE = yes # USB Nkey Rollover
|
||||||
|
|
||||||
|
# Boot Section Size in bytes
|
||||||
|
# Teensy halfKay 512
|
||||||
|
# Atmel DFU loader 4096
|
||||||
|
# LUFA bootloader 4096
|
||||||
|
#OPT_DEFS += -DBOOT_SIZE=4096
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SRC = \
|
||||||
|
keymap.c \
|
||||||
|
matrix.c \
|
||||||
|
led.c \
|
||||||
|
main.cpp
|
||||||
|
|
||||||
|
CONFIG_H = config.h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Search Path
|
||||||
|
VPATH += $(TARGET_DIR)
|
||||||
|
VPATH += $(TOP_DIR)
|
||||||
|
#VPATH += $(TOP_DIR)/common
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# program Leonardo
|
||||||
|
PROGRAM_CMD = avrdude -p$(MCU) -cavr109 -P$(DEV) -b57600 -Uflash:w:$(TARGET).hex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
include $(TOP_DIR)/protocol/usb_hid.mk
|
||||||
|
include $(TOP_DIR)/protocol/lufa.mk
|
||||||
|
include $(TOP_DIR)/common.mk
|
||||||
|
include $(TOP_DIR)/rules.mk
|
40
converter/usb_usb/config.h
Normal file
40
converter/usb_usb/config.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
|
||||||
|
#define VENDOR_ID 0xFEED
|
||||||
|
#define PRODUCT_ID 0xCAFE
|
||||||
|
#define DEVICE_VER 0x0814
|
||||||
|
#define MANUFACTURER t.m.k.
|
||||||
|
#define PRODUCT USB to USB keyboard converter
|
||||||
|
|
||||||
|
|
||||||
|
#define DESCRIPTION Product from t.m.k. keyboard firmware project
|
||||||
|
|
||||||
|
|
||||||
|
/* matrix size */
|
||||||
|
#define MATRIX_ROWS 32
|
||||||
|
#define MATRIX_COLS 8
|
||||||
|
|
||||||
|
|
||||||
|
/* key combination for command */
|
||||||
|
#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)))
|
||||||
|
|
||||||
|
#endif
|
251
converter/usb_usb/keymap.c
Normal file
251
converter/usb_usb/keymap.c
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include "usb_keycodes.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "keymap.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define KEYMAP( \
|
||||||
|
K29,K3A,K3B,K3C,K3D,K3E,K3F,K40,K41,K42,K43,K44,K45, K46,K47,K48, \
|
||||||
|
K35,K1E,K1F,K20,K21,K22,K23,K24,K25,K26,K27,K2D,K2E,K2A, K49,K4A,K4B, K53,K54,K55,K56, \
|
||||||
|
K2B,K14,K1A,K08,K15,K17,K1C,K18,K0C,K12,K13,K2F,K30,K31, K4C,K4D,K4E, K5F,K60,K61, \
|
||||||
|
K39,K04,K16,K07,K09,K0A,K0B,K0D,K0E,K0F,K33,K34, K28, K5C,K5D,K5E,K57, \
|
||||||
|
KE1,K1D,K1B,K06,K19,K05,K11,K10,K36,K37,K38, KE5, K52, K59,K5A,K5B, \
|
||||||
|
KE0,KE3,KE2, K2C, KE6,KE7,K65,KE4, K50,K51,K4F, K62, K63,K58 \
|
||||||
|
) { \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, /* 00-07 */ \
|
||||||
|
{ KB_##K08, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, /* 08-0F */ \
|
||||||
|
{ KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, /* 10-17 */ \
|
||||||
|
{ KB_##K18, KB_##K19, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_##K1F }, /* 18-1F */ \
|
||||||
|
{ KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, /* 20-27 */ \
|
||||||
|
{ KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, /* 28-2F */ \
|
||||||
|
{ KB_##K30, KB_##K31, KB_NO, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_##K37 }, /* 30-37 */ \
|
||||||
|
{ KB_##K38, KB_##K39, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_##K3F }, /* 38-3F */ \
|
||||||
|
{ KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_##K47 }, /* 40-47 */ \
|
||||||
|
{ KB_##K48, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_##K4F }, /* 48-4F */ \
|
||||||
|
{ KB_##K50, KB_##K51, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, /* 50-57 */ \
|
||||||
|
{ KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_##K5C, KB_##K5D, KB_##K5E, KB_##K5F }, /* 58-5F */ \
|
||||||
|
{ KB_##K60, KB_##K61, KB_##K62, KB_##K63, KB_NO, KB_##K65, KB_NO, KB_NO }, /* 60-67 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* 68-6F */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* 70-77 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* 78-7F */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* 80-87 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* 88-8F */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* 90-97 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* 98-9F */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* A0-A7 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* A8-AF */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* B0-B7 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* B8-BF */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* C0-C7 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* C8-CF */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* D0-D7 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* D8-DF */ \
|
||||||
|
{ KB_##KE0, KB_##KE1, KB_##KE2, KB_##KE3, KB_##KE4, KB_##KE5, KB_##KE6, KB_##KE7 }, /* E0-E7 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* E8-EF */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* F0-F7 */ \
|
||||||
|
{ KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, /* F8-FF */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Layers to switch by holding Fn key(0-7)
|
||||||
|
static const uint8_t PROGMEM fn_layer[] = { 5, 6, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
// Codes to register by clicking Fn key(0-7)
|
||||||
|
static const uint8_t PROGMEM fn_keycode[] = { KB_SCLN, KB_SLSH, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO };
|
||||||
|
|
||||||
|
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
|
/* 0: default
|
||||||
|
* ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------.
|
||||||
|
* |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|Slp|Wak|
|
||||||
|
* `---' `---------------' `---------------' `---------------' `-----------' `-----------'
|
||||||
|
* ,-----------------------------------------------------------. ,-----------. ,---------------.
|
||||||
|
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -|
|
||||||
|
* |-----------------------------------------------------------| |-----------| |---------------|
|
||||||
|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
|
||||||
|
* |-----------------------------------------------------------| `-----------' |-----------| +|
|
||||||
|
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| |
|
||||||
|
* |-----------------------------------------------------------| ,---. |---------------|
|
||||||
|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
|
||||||
|
* |-----------------------------------------------------------| ,-----------. |-----------|Ent|
|
||||||
|
* |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| | 0| .| |
|
||||||
|
* `-----------------------------------------------------------' `-----------' `---------------'
|
||||||
|
* ; = Fn0(to Layer 5)
|
||||||
|
* / = Fn1(to Layer 6)
|
||||||
|
*/
|
||||||
|
KEYMAP(
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
|
||||||
|
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||||
|
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
|
||||||
|
CAPS,A, S, D, F, G, H, J, K, L, FN0, QUOT, ENT, P4, P5, P6, PPLS,
|
||||||
|
LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN1, RSFT, UP, P1, P2, P3,
|
||||||
|
LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||||
|
),
|
||||||
|
|
||||||
|
/* 1: plain Qwerty without layer switching
|
||||||
|
* ,-----------------------------------------------------------.
|
||||||
|
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
|
||||||
|
* `-----------------------------------------------------------'
|
||||||
|
*/
|
||||||
|
KEYMAP(
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
|
||||||
|
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||||
|
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
|
||||||
|
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS,
|
||||||
|
LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
|
||||||
|
LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||||
|
),
|
||||||
|
|
||||||
|
/* 2: Colemak http://colemak.com
|
||||||
|
* ,-----------------------------------------------------------.
|
||||||
|
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Tab | Q| W| F| P| G| J| L| U| Y| ;| [| ]| \|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |BackSp| A| R| S| T| D| H| N| E| I| O| '|Return |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Shift | Z| X| C| V| B| K| M| ,| ,| /|Shift |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
|
||||||
|
* `----------------------------------------------------------'
|
||||||
|
*/
|
||||||
|
KEYMAP(
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
|
||||||
|
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||||
|
TAB, Q, W, F, P, G, J, L, U, Y, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
|
||||||
|
BSPC,A, R, S, T, D, H, N, E, I, O, QUOT, ENT, P4, P5, P6, PPLS,
|
||||||
|
LSFT,Z, X, C, V, B, K, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
|
||||||
|
LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||||
|
),
|
||||||
|
|
||||||
|
/* 3: Dvorak http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard
|
||||||
|
* ,-----------------------------------------------------------.
|
||||||
|
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| [| ]|Backspa|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Tab | '| ,| .| P| Y| F| G| C| R| L| /| =| \|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |BackSp| A| O| E| U| I| D| H| T| N| S| -|Return |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Shift | ;| Q| J| K| X| B| M| Wl V| Z|Shift |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
|
||||||
|
* `-----------------------------------------------------------'
|
||||||
|
*/
|
||||||
|
KEYMAP(
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
|
||||||
|
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, LBRC,RBRC,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||||
|
TAB, QUOT,COMM,DOT, P, Y, F, G, C, R, L, SLSH,EQL, BSLS, DEL, END, PGDN, P7, P8, P9,
|
||||||
|
CAPS,A, O, E, U, I, D, H, T, N, S, MINS, ENT, P4, P5, P6, PPLS,
|
||||||
|
LSFT,SCLN,Q, J, K, X, B, M, W, V, Z, RSFT, UP, P1, P2, P3,
|
||||||
|
LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||||
|
),
|
||||||
|
|
||||||
|
/* 4: Workman http://viralintrospection.wordpress.com/2010/09/06/a-different-philosophy-in-designing-keyboard-layouts/
|
||||||
|
* ,-----------------------------------------------------------.
|
||||||
|
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Tab | Q| D| R| W| B| J| F| U| P| ;| [| ]| \|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |CapsLo| A| S| H| T| G| Y| N| E| O| I| '|Return |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Shift | Z| X| M| C| V| K| L| ,| ,| /|Shift |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
|
||||||
|
* `-----------------------------------------------------------'
|
||||||
|
*/
|
||||||
|
KEYMAP(
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
|
||||||
|
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||||
|
TAB, Q, D, R, W, B, J, F, U, P, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
|
||||||
|
BSPC,A, S, H, T, G, Y, N, E, O, I, QUOT, ENT, P4, P5, P6, PPLS,
|
||||||
|
LSFT,Z, X, M, C, V, K, L, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
|
||||||
|
LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||||
|
),
|
||||||
|
|
||||||
|
/* 5: Mouse keys
|
||||||
|
* ,-----------------------------------------------------------.
|
||||||
|
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Tab |MwL|MwU|McU|WwU|WwR|MwL|MwD|MwU|MwR| | | | \|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |CapsLo| |McL|McD|McR| |McL|McD|McU|McR|Fn0| |Return |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Shift |VoD|VoU|Mut|Mb2|Mb3|Mb2|Mb1|VoD|VoU|Mut|Shift |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Ctrl |Gui |Alt | Mb1 |Alt |Gui |Menu|Ctrl|
|
||||||
|
* `-----------------------------------------------------------'
|
||||||
|
* Mc = mouse cursor, Mw = mouse wheel, Mb = mouse button
|
||||||
|
* Vo = Volume, Mut = Mute
|
||||||
|
*/
|
||||||
|
KEYMAP(
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||||
|
TAB, WH_L,WH_D,MS_U,WH_U,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9,
|
||||||
|
CAPS,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN0, NO, ENT, P4, P5, P6, PPLS,
|
||||||
|
LSFT,VOLD,VOLU,MUTE,BTN2,BTN3,BTN2,BTN1,VOLD,VOLU,MUTE, RSFT, UP, P1, P2, P3,
|
||||||
|
LCTL,LGUI,LALT, BTN1, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||||
|
),
|
||||||
|
|
||||||
|
/* 6: Cursor keys
|
||||||
|
* ,-----------------------------------------------------------.
|
||||||
|
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Tab |Hom|PgU| Up|PgU|End|Hom|PgD|PgU|End| | | | \|
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |CapsLo| |Lef|Dow|Rig| |Lef|Dow| Up|Rig| | |Return |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Shift | | | | | |Hom|PgD|PgU|End|Fn1|Shift |
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
|
||||||
|
* `-----------------------------------------------------------'
|
||||||
|
*/
|
||||||
|
KEYMAP(
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
|
||||||
|
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
|
||||||
|
TAB, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9,
|
||||||
|
CAPS,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS,
|
||||||
|
LSFT,VOLD,VOLU,MUTE,NO, NO, HOME,PGDN,PGUP,END, FN1, RSFT, UP, P1, P2, P3,
|
||||||
|
LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
|
||||||
|
{
|
||||||
|
return pgm_read_byte(&keymaps[(layer)][(row)][(col)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t keymap_fn_layer(uint8_t fn_bits)
|
||||||
|
{
|
||||||
|
return pgm_read_byte(&fn_layer[biton(fn_bits)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t keymap_fn_keycode(uint8_t fn_bits)
|
||||||
|
{
|
||||||
|
return pgm_read_byte(&fn_keycode[(biton(fn_bits))]);
|
||||||
|
}
|
24
converter/usb_usb/led.c
Normal file
24
converter/usb_usb/led.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
|
|
||||||
|
void led_set(uint8_t usb_led)
|
||||||
|
{
|
||||||
|
}
|
95
converter/usb_usb/main.cpp
Normal file
95
converter/usb_usb/main.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#include <avr/power.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
// USB HID host
|
||||||
|
#include "Usb.h"
|
||||||
|
#include "hid.h"
|
||||||
|
#include "hidboot.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
// LUFA
|
||||||
|
#include "lufa.h"
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
|
||||||
|
#include "leonardo_led.h"
|
||||||
|
|
||||||
|
|
||||||
|
static USB usb_host;
|
||||||
|
static HIDBoot<HID_PROTOCOL_KEYBOARD> kbd(&usb_host);
|
||||||
|
static KBDReportParser kbd_parser;
|
||||||
|
|
||||||
|
static void LUFA_setup(void)
|
||||||
|
{
|
||||||
|
/* Disable watchdog if enabled by bootloader/fuses */
|
||||||
|
MCUSR &= ~(1 << WDRF);
|
||||||
|
wdt_disable();
|
||||||
|
|
||||||
|
/* Disable clock division */
|
||||||
|
clock_prescale_set(clock_div_1);
|
||||||
|
|
||||||
|
// Leonardo needs. Without this USB device is not recognized.
|
||||||
|
USB_Disable();
|
||||||
|
|
||||||
|
USB_Init();
|
||||||
|
|
||||||
|
// for Console_Task
|
||||||
|
USB_Device_EnableSOFEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HID_setup()
|
||||||
|
{
|
||||||
|
if (usb_host.Init() == -1) {
|
||||||
|
debug("HID init: failed\n");
|
||||||
|
LED_TX_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
_delay_ms(200);
|
||||||
|
|
||||||
|
kbd.SetReportParser(0, (HIDReportParser*)&kbd_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// LED for debug
|
||||||
|
LED_TX_INIT;
|
||||||
|
LED_TX_ON;
|
||||||
|
|
||||||
|
print_enable = true;
|
||||||
|
debug_enable = true;
|
||||||
|
debug_matrix = true;
|
||||||
|
debug_keyboard = true;
|
||||||
|
debug_mouse = true;
|
||||||
|
|
||||||
|
host_set_driver(&lufa_driver);
|
||||||
|
keyboard_init();
|
||||||
|
|
||||||
|
LUFA_setup();
|
||||||
|
sei();
|
||||||
|
|
||||||
|
// wait for startup of sendchar routine
|
||||||
|
while (USB_DeviceState != DEVICE_STATE_Configured) ;
|
||||||
|
if (debug_enable) {
|
||||||
|
_delay_ms(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
HID_setup();
|
||||||
|
|
||||||
|
debug("init: done\n");
|
||||||
|
for (;;) {
|
||||||
|
keyboard_proc();
|
||||||
|
|
||||||
|
usb_host.Task();
|
||||||
|
|
||||||
|
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||||
|
// LUFA Task for control request
|
||||||
|
USB_USBTask();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
133
converter/usb_usb/matrix.c
Normal file
133
converter/usb_usb/matrix.c
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "usb_hid.h"
|
||||||
|
#include "usb_keycodes.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
|
||||||
|
/* KEY CODE to Matrix
|
||||||
|
*
|
||||||
|
* HID keycode(1 byte):
|
||||||
|
* Higher 5 bits indicates ROW and lower 3 bits COL.
|
||||||
|
*
|
||||||
|
* 7 6 5 4 3 2 1 0
|
||||||
|
* +---------------+
|
||||||
|
* | ROW | COL |
|
||||||
|
* +---------------+
|
||||||
|
*
|
||||||
|
* Matrix space(32 * 8):
|
||||||
|
* 01234567
|
||||||
|
* 0 +--------+
|
||||||
|
* : | |
|
||||||
|
* : | |
|
||||||
|
* 31 +--------+
|
||||||
|
*/
|
||||||
|
#define ROW_MASK 0xF8
|
||||||
|
#define COL_MASK 0x07
|
||||||
|
#define CODE(row, col) (((row) << 3) | (col))
|
||||||
|
#define ROW(code) (((code) & ROW_MASK) >> 3)
|
||||||
|
#define COL(code) ((code) & COL_MASK)
|
||||||
|
#define ROW_BITS(code) (1 << COL(code))
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t matrix_rows(void) { return MATRIX_ROWS; }
|
||||||
|
uint8_t matrix_cols(void) { return MATRIX_COLS; }
|
||||||
|
void matrix_init(void) {}
|
||||||
|
bool matrix_has_ghost(void) { return false; }
|
||||||
|
|
||||||
|
static bool matrix_is_mod =false;
|
||||||
|
|
||||||
|
uint8_t matrix_scan(void) {
|
||||||
|
static uint16_t last_time_stamp = 0;
|
||||||
|
|
||||||
|
if (last_time_stamp != usb_hid_time_stamp) {
|
||||||
|
last_time_stamp = usb_hid_time_stamp;
|
||||||
|
matrix_is_mod = true;
|
||||||
|
} else {
|
||||||
|
matrix_is_mod = false;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matrix_is_modified(void) {
|
||||||
|
|
||||||
|
return matrix_is_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matrix_is_on(uint8_t row, uint8_t col) {
|
||||||
|
uint8_t code = CODE(row, col);
|
||||||
|
|
||||||
|
if (IS_MOD(code)) {
|
||||||
|
if (usb_hid_keyboard_report.mods & ROW_BITS(code)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < REPORT_KEYS; i++) {
|
||||||
|
if (usb_hid_keyboard_report.keys[i] == code) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t matrix_get_row(uint8_t row) {
|
||||||
|
uint8_t row_bits = 0;
|
||||||
|
|
||||||
|
if (IS_MOD(CODE(row, 0)) && usb_hid_keyboard_report.mods) {
|
||||||
|
row_bits |= usb_hid_keyboard_report.mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < REPORT_KEYS; i++) {
|
||||||
|
if (IS_ANY(usb_hid_keyboard_report.keys[i])) {
|
||||||
|
if (row == ROW(usb_hid_keyboard_report.keys[i])) {
|
||||||
|
row_bits |= ROW_BITS(usb_hid_keyboard_report.keys[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return row_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t matrix_key_count(void) {
|
||||||
|
uint8_t count = 0;
|
||||||
|
|
||||||
|
count += bitpop(usb_hid_keyboard_report.mods);
|
||||||
|
for (uint8_t i = 0; i < REPORT_KEYS; i++) {
|
||||||
|
if (IS_ANY(usb_hid_keyboard_report.keys[i])) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_print(void) {
|
||||||
|
print("\nr/c 01234567\n");
|
||||||
|
for (uint8_t row = 0; row < matrix_rows(); row++) {
|
||||||
|
phex(row); print(": ");
|
||||||
|
pbin_reverse(matrix_get_row(row));
|
||||||
|
#ifdef MATRIX_HAS_GHOST
|
||||||
|
if (matrix_has_ghost_in_row(row)) {
|
||||||
|
print(" <ghost");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,27 @@
|
||||||
|
#include <cstring.h>
|
||||||
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
#include "usb_hid.h"
|
||||||
|
|
||||||
#include "leonardo_led.h"
|
#include "leonardo_led.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
report_keyboard_t usb_hid_keyboard_report;
|
||||||
|
uint16_t usb_hid_time_stamp;
|
||||||
|
|
||||||
|
|
||||||
void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
||||||
{
|
{
|
||||||
|
::memcpy(&usb_hid_keyboard_report, buf, sizeof(report_keyboard_t));
|
||||||
|
usb_hid_time_stamp = millis();
|
||||||
|
|
||||||
LED_TX_TOGGLE;
|
LED_TX_TOGGLE;
|
||||||
debug("KBDReport: ");
|
debug("KBDReport: ");
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
debug_hex(usb_hid_keyboard_report.mods);
|
||||||
debug_hex(buf[i]);
|
for (uint8_t i = 0; i < 6; i++) {
|
||||||
debug(" ");
|
debug(" ");
|
||||||
|
debug_hex(usb_hid_keyboard_report.keys[i]);
|
||||||
}
|
}
|
||||||
debug("\r\n");
|
debug("\r\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue