Merge remote-tracking branch 'tmk/master'
This commit is contained in:
commit
ae2234765e
40 changed files with 4259 additions and 434 deletions
|
|
@ -69,7 +69,7 @@ OPT_DEFS += -DSUSPEND_MODE_STANDBY
|
|||
# comment out to disable the options.
|
||||
#
|
||||
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE ?= no # Mouse keys(+4700)
|
||||
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE ?= yes # Console for debug(+400)
|
||||
COMMAND_ENABLE ?= yes # Commands for debug and configuration
|
||||
|
|
@ -78,6 +78,10 @@ NKRO_ENABLE ?= yes # USB Nkey Rollover
|
|||
KEYMAP_SECTION_ENABLE ?= yes
|
||||
UNIMAP_ENABLE ?= yes
|
||||
|
||||
# IBMPC Options
|
||||
IBMPC_SECONDARY ?= no # enable secondary interface
|
||||
IBMPC_MOUSE_ENABLE ?= no # enable mouse support
|
||||
|
||||
|
||||
# Optimize size but this may cause error "relocation truncated to fit"
|
||||
#EXTRALDFLAGS = -Wl,--relax
|
||||
|
|
@ -102,6 +106,16 @@ else
|
|||
endif
|
||||
|
||||
|
||||
ifeq (yes,$(strip $(IBMPC_SECONDARY)))
|
||||
OPT_DEFS += -DIBMPC_SECONDARY
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(IBMPC_MOUSE_ENABLE)))
|
||||
OPT_DEFS += -DIBMPC_MOUSE_ENABLE
|
||||
OPT_DEFS += -DMOUSE_ENABLE
|
||||
endif
|
||||
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TMK_DIR)
|
||||
|
|
|
|||
12
converter/ibmpc_usb/Makefile.x2
Normal file
12
converter/ibmpc_usb/Makefile.x2
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# With two interfaces on PS/2 connector
|
||||
TARGET ?= ibmpc_usb_x2
|
||||
MCU = atmega32u2
|
||||
SRC ?= protocol/ibmpc.cpp \
|
||||
ibmpc_usb.cpp
|
||||
|
||||
COMMAND_ENABLE ?= no # Commands for debug and configuration
|
||||
|
||||
IBMPC_SECONDARY ?= yes # enable secondary interface
|
||||
IBMPC_MOUSE_ENABLE ?= yes # enable mouse support
|
||||
|
||||
include Makefile
|
||||
|
|
@ -1,22 +1,23 @@
|
|||
IBM PC Keyboard Converter
|
||||
=========================
|
||||
The converter translates IBM PC keyboard protocols to use classic keyboards with modern computer with USB ports.
|
||||
It supports both IBM XT and AT protocols, and all of scan code set 1, 2 and 3 with one firmware.
|
||||
|
||||
This is not finished project and still work in progress as of 2020-03-02. Test in the field and feedback from users are needed to improve firmware code.
|
||||
|
||||
You can discuss about this project here.
|
||||
|
||||
https://geekhack.org/index.php?topic=103648.0
|
||||
The converter translates IBM PC keyboard protocols into USB HID to use classic keyboards on modern computer with USB ports.
|
||||
This can supports IBM XT and AT protocols and recognize scan code set 1, 2 and 3 with just one firmware.
|
||||
|
||||
|
||||
This project is intended to integrated existent TMK XT, PS/2 and Terminal converters.
|
||||
This project is intended to integrated existent TMK XT, PS/2 and Terminal keyboard converters.
|
||||
|
||||
- IBM XT converter: https://geekhack.org/index.php?topic=94649.0
|
||||
- PS/2 converter: https://geekhack.org/index.php?topic=14618.0
|
||||
- IBM Terminal converter: http://geekhack.org/index.php?topic=27272.0
|
||||
|
||||
|
||||
Test in the field and feedback from users are needed to improve firmware code.
|
||||
|
||||
Discuss in this thread or on github. https://geekhack.org/index.php?topic=103648.0
|
||||
|
||||
You can buy prebuilt TMK converter to support this project here. https://geekhack.org/index.php?topic=72052.0
|
||||
|
||||
|
||||
|
||||
Keyboard supported
|
||||
------------------
|
||||
|
|
@ -27,87 +28,46 @@ Keyboard supported
|
|||
- PC Terminal keyboard of IBM 5271(3270 PC)
|
||||
- 122-key: 6110344 6110345 1397000
|
||||
- 102-key: 1390680 1395764 1392595
|
||||
- PS/2 keyboards(AT+CodeSet2)
|
||||
- Clones of above models
|
||||
- IBM 5576-001
|
||||
- PS/2 keyboards
|
||||
- Other IBM PC compatible keyboards
|
||||
|
||||
Optionally PS/2 mouses can be supported.
|
||||
- PS/2 mouse
|
||||
- Default
|
||||
- Microsoft IntelliMouse
|
||||
- Microsoft ExplorerMouse
|
||||
- Logitech PS/2++
|
||||
|
||||
|
||||
|
||||
Hardware
|
||||
Firmware
|
||||
--------
|
||||
Firmware supports ATMega32u4 and ATMega32u2 by default, Teensy2 or ProMicro can be used.
|
||||
Wire controller pins below to keyboard signals, besides VCC and GND. This is compatible for Soarer's converter.
|
||||
|
||||
- Data PD0
|
||||
- Clock PD1
|
||||
- Reset PB6 or PB7 (For some of XT keyboards. Not needed for AT, PS/2 and Terminal)
|
||||
|
||||
Pull up resistors of 1-4.7K Ohm on both Data and Clock line are recommended, without them it won't work in some cases.
|
||||
|
||||
### Reset
|
||||
Old Type-1 IBM XT keyboard and some of XT clones need this to reset its controller on startup. Many of IBM XT keyboards available are Type-2 and don't need the reset pin.
|
||||
|
||||
See this for Type-1 vs Type-2:
|
||||
https://vintagecomputer.ca/ibm-pc-model-f-keyboard-type-1-vs-type-2/
|
||||
|
||||
As for clones Zenith Z-150 XT and Leading Edge DC-2014 are known to need this.
|
||||
|
||||
### Connector pinouts
|
||||
#### XT
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibmpc.png
|
||||
- https://allpinouts.org/pinouts/connectors/input_device/keyboard-xt-5-pin/
|
||||
|
||||
#### AT
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ps2.png
|
||||
- https://old.pinouts.ru/InputCables/KeyboardPC5_pinout.shtml
|
||||
|
||||
#### PS/2
|
||||
- https://pinouts.ru/InputCables/KeyboardPC6_pinout.shtml
|
||||
|
||||
#### Terminal
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png
|
||||
|
||||
|
||||
|
||||
Source Code
|
||||
-----------
|
||||
https://github.com/tmk/tmk_keyboard/tree/master/converter/ibmpc_usb
|
||||
|
||||
|
||||
|
||||
Build Firmware
|
||||
--------------
|
||||
### Build Firmware
|
||||
|
||||
$ cd converter/ibmpc_usb
|
||||
$ make clean
|
||||
$ make
|
||||
$ make -f Makefile.<variant> clean
|
||||
$ make -f Makefile.<variant>
|
||||
|
||||
|
||||
### Build Options
|
||||
In Makefiile:
|
||||
|
||||
# IBMPC Options
|
||||
IBMPC_SECONDARY ?= no
|
||||
IBMPC_MOUSE_ENABLE ?= no
|
||||
|
||||
These options bloat firmware size and you may need to disable other options.
|
||||
|
||||
- `IBMPC_SECONDARY` - enables secondary interface for converter with PS/2 Mini-DIN-6 connector
|
||||
- `IBMPC_MOUSE_ENABLE` - enables PS/2 mouse support
|
||||
|
||||
|
||||
|
||||
Keyboard discrimination
|
||||
-----------------------
|
||||
This section explains how the converter determines proper protocol and scan code set for keyboard. The converter need to do that before starting to receive and translate scan codes from keyboard.
|
||||
### Keymap Editor
|
||||
You can edit keymap on web browser and download prebuilt firmware here.
|
||||
|
||||
### Keyboard ID
|
||||
After startup the converter sends 0xF2 command to get keyboard ID and sees how the keyboard responds to the command.
|
||||
|
||||
Response from keyboard:
|
||||
|
||||
- XT keyboard doesn't support any command and returns no response.
|
||||
- AT keyboard should respond with 0xFA to the command but returns no keyboard ID.
|
||||
- PS/2 keyboard should respond with 0xFA to the command, followd by keyboard ID, such as 0xAB86.
|
||||
- Terminal keyboard should respond with 0xFA to the command, followed by keyboard ID, such as 0xBFBF.
|
||||
|
||||
Now we can dscriminate the keyboard and determine suitable protocol and scan code set as described below.
|
||||
|
||||
### Protocol
|
||||
- Signals from XT keyboard are recognized by XT protocol.
|
||||
- Signals from AT, PS/2 and Terminal keyboard are recognized by AT protocol.
|
||||
|
||||
### Scan code Set
|
||||
- Scan codes from XT keyboard are handled as CodeSet1.
|
||||
- Scan codes from AT and PS/2 keyboard are handled as CodeSet2.
|
||||
- Scan codes from Terminal keyhboard are handled as CodeSet3.
|
||||
http://www.tmk-kbd.com/tmk_keyboard/editor/#ibmpc_usb
|
||||
|
||||
|
||||
|
||||
|
|
@ -115,62 +75,74 @@ Debug
|
|||
-----
|
||||
Use hid_listen to see debug outputs from the converter.
|
||||
|
||||
https://www.pjrc.com/teensy/hid_listen.html
|
||||
https://github.com/tmk/tmk_keyboard/wiki#debug
|
||||
|
||||
|
||||
|
||||
Converter Hardware
|
||||
------------------
|
||||
This firmware supports ATMega32u4, ATMega32u2 and AT90USB1286 by default, Teensy2/2++ or ProMicro can be used.
|
||||
Wire microcontroller pins below to keyboard signals, besides VCC and GND. This pin configuration is compatible for Soarer's converter.
|
||||
|
||||
Pull up resistors of 1-4.7K Ohm on both Data and Clock line are recommended, without them it won't work in some cases.
|
||||
|
||||
- Data PD0
|
||||
- Clock PD1
|
||||
- Reset PB6 or PB7 (For some of XT keyboards. Not needed for AT, PS/2 and Terminal)
|
||||
|
||||
For optional secondary interface use these pins.
|
||||
- Data PD2
|
||||
- Clock PD3
|
||||
|
||||
|
||||
### Reset
|
||||
Old Type-1 IBM XT keyboard and some of XT clones need Reset pin to starup its controller.
|
||||
Connect Reset pin to pin3 of DIN-5(180-degree) connector. This should not harm keyboards which don't require reset,
|
||||
it is safe and recommended to have Reset pin on AT/XT converter.
|
||||
|
||||
Zenith Z-150 XT and Leading Edge DC-2014 are also known to need this.
|
||||
|
||||
See this for IBM XT Type-1 vs Type-2: https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol#type-1-vs-type-2
|
||||
|
||||
|
||||
### Connector pinouts
|
||||
- DIN: https://en.wikipedia.org/wiki/DIN_connector#Circular_connectors
|
||||
- Mini-DIN: https://en.wikipedia.org/wiki/Mini-DIN_connector
|
||||
|
||||
#### XT - DIN-5(180-degree)
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibmpc.png
|
||||
- https://allpinouts.org/pinouts/connectors/input_device/keyboard-xt-5-pin/
|
||||
|
||||
#### AT - DIN-5(180-degree)
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ps2.png
|
||||
- https://old.pinouts.ru/InputCables/KeyboardPC5_pinout.shtml
|
||||
|
||||
#### Terminal - DIN-5(240-degree) or DIN-6
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png
|
||||
- http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png
|
||||
|
||||
#### PS/2 - Mini-DIN-6
|
||||
- https://pinouts.ru/InputCables/KeyboardPC6_pinout.shtml
|
||||
|
||||
For secondary interface use pin2 and pin6 for data and clock respectively.
|
||||
You can use PS/2 Y-splitter cable to access secondary interface.
|
||||
|
||||
|
||||
|
||||
Scan Code Mapping
|
||||
-----------------
|
||||
This is how the converter map keyboard scan code to USB key.
|
||||
|
||||
https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-Keyboard-Converter#default-mapping
|
||||
|
||||
|
||||
|
||||
Resources
|
||||
---------
|
||||
IBM PC Keyboard Protocol Resources:
|
||||
|
||||
[a] [Microsoft USB HID to PS/2 Translation Table - Scan Code Set 1 and 2](
|
||||
http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf)
|
||||
|
||||
[b] [Microsoft Keyboard Scan Code Specification - Special rules of Scan Code Set 1 and 2](
|
||||
http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc)
|
||||
|
||||
[1] [PS/2 Reference Manuals - Collection of IBM Personal System/2 documents](
|
||||
http://www.mcamafia.de/pdf/pdfref.htm)
|
||||
|
||||
[2] [Keyboard and Auxiliary Device Controller - Signal Timing and Format](
|
||||
http://www.mcamafia.de/pdf/ibm_hitrc07.pdf)
|
||||
|
||||
[3] [Keyboards(101- and 102-key) - Keyboard Layout, Scan Code Set, POR, and Commands](
|
||||
http://www.mcamafia.de/pdf/ibm_hitrc11.pdf)
|
||||
|
||||
[4] [IBM PC XT Keyboard Protocol](
|
||||
https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol)
|
||||
|
||||
[5] [IBM Keyboard Scan Code by John Elliott - 83-key, 84-key, 102-key and 122-key](
|
||||
https://www.seasip.info/VintagePC/index.html)
|
||||
|
||||
[6] [IBM 1391406 Keyboard - Scan Code Set 2 of 102-key PS/2 keyboard](
|
||||
https://www.seasip.info/VintagePC/ibm_1391406.html)
|
||||
|
||||
[7] [The IBM 6110344 Keyboard - Scan Code Set 3 of 122-key terminal keyboard](
|
||||
https://www.seasip.info/VintagePC/ibm_6110344.html)
|
||||
|
||||
[8] [IBM PC AT Technical Reference 1986](
|
||||
(http://bitsavers.org/pdf/ibm/pc/at/6183355_PC_AT_Technical_Reference_Mar86.pdf)
|
||||
|
||||
[y] [TrackPoint Engineering Specifications for version 3E](
|
||||
https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html)
|
||||
|
||||
[z] [Soarer's XT/AT/PS2/Terminal to USB converter](
|
||||
https://geekhack.org/index.php?topic=17458.0)
|
||||
|
||||
|
||||
|
||||
TODO
|
||||
----
|
||||
### Reset method for rescue
|
||||
For converter without accesible reset button when magickey combo doesn't work.
|
||||
|
||||
Check pin status at powerup:
|
||||
|
||||
- if Data and/or Clock are pull down to GND
|
||||
|
||||
### Force protocol and scan code set
|
||||
Keyboard discrimination may fail and you have to configure them by hand.
|
||||
|
||||
### Add AT90usb1286 support for Teensy2++
|
||||
- Source Code: https://github.com/tmk/tmk_keyboard/tree/master/converter/ibmpc_usb
|
||||
- Discussion: https://geekhack.org/index.php?topic=103648.0
|
||||
- Conveter impl: https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-Keyboard-Converter
|
||||
- XT Protocol: https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol
|
||||
- AT Protocol: https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol
|
||||
- Scan Code: https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#scan-codes
|
||||
- PS/2 Mouse: https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-Mouse
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 16 // keycode bit: 6-3
|
||||
#define MATRIX_COLS 8 // keycode bit: 2-0
|
||||
#define MATRIX_ROWS 8
|
||||
#define MATRIX_COLS 16
|
||||
|
||||
|
||||
/* key combination for command */
|
||||
|
|
@ -53,56 +53,77 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* Pin and interrupt configuration
|
||||
*/
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB1286__)
|
||||
/* clock line */
|
||||
// clock requires External Interrupt pin(INT*)
|
||||
#define IBMPC_CLOCK_PORT PORTD
|
||||
#define IBMPC_CLOCK_PIN PIND
|
||||
#define IBMPC_CLOCK_DDR DDRD
|
||||
#define IBMPC_CLOCK_BIT 1
|
||||
/* data line */
|
||||
#define IBMPC_DATA_PORT PORTD
|
||||
#define IBMPC_DATA_PIN PIND
|
||||
#define IBMPC_DATA_DDR DDRD
|
||||
|
||||
// primary interface
|
||||
#define IBMPC_CLOCK_BIT 1
|
||||
#define IBMPC_DATA_BIT 0
|
||||
/* reset line */
|
||||
#define IBMPC_RST_PORT PORTB
|
||||
#define IBMPC_RST_PIN PINB
|
||||
#define IBMPC_RST_DDR DDRB
|
||||
#define IBMPC_RST_BIT1 6
|
||||
#define IBMPC_RST_BIT2 7
|
||||
|
||||
/* reset for XT Type-1 keyboard: low pulse for 500ms */
|
||||
#define IBMPC_RST_HIZ() do { \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_DDR &= ~(1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT2); \
|
||||
IBMPC_RST_DDR &= ~(1<<IBMPC_RST_BIT2); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_RST_LO() do { \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_DDR |= (1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT2); \
|
||||
IBMPC_RST_DDR |= (1<<IBMPC_RST_BIT2); \
|
||||
} while (0)
|
||||
|
||||
/* interrupt for clock line */
|
||||
#define IBMPC_INT_INIT() do { \
|
||||
EICRA |= ((1<<ISC11) | \
|
||||
(0<<ISC10)); \
|
||||
} while (0)
|
||||
|
||||
/* NOTE: clear flag and enabling to ditch unwanted interrupt */
|
||||
#define IBMPC_INT_ON() do { \
|
||||
EIFR |= (1<<INTF1); \
|
||||
EIMSK |= (1<<INT1); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_INT_OFF() do { \
|
||||
EIMSK &= ~(1<<INT1); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_INT_VECT INT1_vect
|
||||
|
||||
// secondary interface
|
||||
#ifdef IBMPC_SECONDARY
|
||||
#define IBMPC_CLOCK_BIT1 3
|
||||
#define IBMPC_DATA_BIT1 2
|
||||
|
||||
#define IBMPC_INT_INIT1() do { \
|
||||
EICRA |= ((1<<ISC31) | \
|
||||
(0<<ISC30)); \
|
||||
} while (0)
|
||||
#define IBMPC_INT_ON1() do { \
|
||||
EIFR |= (1<<INTF3); \
|
||||
EIMSK |= (1<<INT3); \
|
||||
} while (0)
|
||||
#define IBMPC_INT_OFF1() do { \
|
||||
EIMSK &= ~(1<<INT3); \
|
||||
} while (0)
|
||||
#define IBMPC_INT_VECT1 INT3_vect
|
||||
#endif
|
||||
|
||||
|
||||
/* reset line */
|
||||
#define IBMPC_RST_PORT PORTB
|
||||
#define IBMPC_RST_PIN PINB
|
||||
#define IBMPC_RST_DDR DDRB
|
||||
#define IBMPC_RST_BIT0 6
|
||||
#define IBMPC_RST_BIT1 7
|
||||
|
||||
/* reset for XT Type-1 keyboard: low pulse for 500ms */
|
||||
#define IBMPC_RST_HIZ() do { \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT0); \
|
||||
IBMPC_RST_DDR &= ~(1<<IBMPC_RST_BIT0); \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_DDR &= ~(1<<IBMPC_RST_BIT1); \
|
||||
} while (0)
|
||||
|
||||
#define IBMPC_RST_LO() do { \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT0); \
|
||||
IBMPC_RST_DDR |= (1<<IBMPC_RST_BIT0); \
|
||||
IBMPC_RST_PORT &= ~(1<<IBMPC_RST_BIT1); \
|
||||
IBMPC_RST_DDR |= (1<<IBMPC_RST_BIT1); \
|
||||
} while (0)
|
||||
|
||||
// for debug
|
||||
#define LED_ON() do { DDRD |= (1<<6); PORTD |= (1<<6); } while (0)
|
||||
#define LED_OFF() do { DDRD |= (1<<6); PORTD &= ~(1<<6); } while (0)
|
||||
|
||||
#else
|
||||
#error "No pin configuration in config.h"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "print.h"
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
|
|
@ -26,6 +27,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "matrix.h"
|
||||
#include "timer.h"
|
||||
#include "action.h"
|
||||
#include "unimap.h"
|
||||
#include "unimap_trans.h"
|
||||
#include "ibmpc_usb.h"
|
||||
#include "ibmpc.h"
|
||||
|
||||
|
|
@ -38,9 +41,9 @@ static int8_t process_cs2(uint8_t code);
|
|||
static int8_t process_cs3(uint8_t code);
|
||||
|
||||
|
||||
static uint8_t matrix[MATRIX_ROWS];
|
||||
#define ROW(code) ((code>>3)&0x0F)
|
||||
#define COL(code) (code&0x07)
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
#define ROW(code) ((code>>4)&0x07)
|
||||
#define COL(code) (code&0x0F)
|
||||
|
||||
static int16_t read_wait(uint16_t wait_ms)
|
||||
{
|
||||
|
|
@ -131,6 +134,7 @@ uint8_t matrix_scan(void)
|
|||
READ_ID,
|
||||
SETUP,
|
||||
LOOP,
|
||||
ERROR,
|
||||
} state = INIT;
|
||||
static uint16_t init_time;
|
||||
|
||||
|
|
@ -152,7 +156,7 @@ uint8_t matrix_scan(void)
|
|||
// keyboard init again
|
||||
if (state == LOOP) {
|
||||
xprintf("[RST] ");
|
||||
state = INIT;
|
||||
state = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +176,7 @@ uint8_t matrix_scan(void)
|
|||
((current_protocol&IBMPC_PROTOCOL_AT) && (ibmpc_protocol&IBMPC_PROTOCOL_XT))) {
|
||||
if (state == LOOP) {
|
||||
xprintf("[CHG] ");
|
||||
state = INIT;
|
||||
state = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +192,6 @@ uint8_t matrix_scan(void)
|
|||
current_protocol = 0;
|
||||
|
||||
matrix_clear();
|
||||
clear_keyboard();
|
||||
|
||||
init_time = timer_read();
|
||||
state = WAIT_SETTLE;
|
||||
|
|
@ -473,13 +476,13 @@ MOUSE_DONE:
|
|||
|
||||
switch (keyboard_kind) {
|
||||
case PC_XT:
|
||||
if (process_cs1(code) == -1) state = INIT;
|
||||
if (process_cs1(code) == -1) state = ERROR;
|
||||
break;
|
||||
case PC_AT:
|
||||
if (process_cs2(code) == -1) state = INIT;
|
||||
if (process_cs2(code) == -1) state = ERROR;
|
||||
break;
|
||||
case PC_TERMINAL:
|
||||
if (process_cs3(code) == -1) state = INIT;
|
||||
if (process_cs3(code) == -1) state = ERROR;
|
||||
break;
|
||||
#ifdef IBMPC_MOUSE_ENABLE
|
||||
case PC_MOUSE: {
|
||||
|
|
@ -493,9 +496,9 @@ MOUSE_DONE:
|
|||
|
||||
b0 = code;
|
||||
b1 = ibmpc_host_recv_response();
|
||||
if (b1 == -1) break;
|
||||
if (b1 == -1) { state = ERROR; break; }
|
||||
b2 = ibmpc_host_recv_response();
|
||||
if (b2 == -1) break;
|
||||
if (b2 == -1) { state = ERROR; break; }
|
||||
|
||||
switch (mouse_id) {
|
||||
case MOUSE_DEFAULT:
|
||||
|
|
@ -593,6 +596,11 @@ MOUSE_DONE:
|
|||
}
|
||||
}
|
||||
break;
|
||||
case ERROR:
|
||||
// something goes wrong
|
||||
clear_keyboard();
|
||||
state = INIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -606,7 +614,7 @@ bool matrix_is_on(uint8_t row, uint8_t col)
|
|||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_get_row(uint8_t row)
|
||||
matrix_row_t matrix_get_row(uint8_t row)
|
||||
{
|
||||
return matrix[row];
|
||||
}
|
||||
|
|
@ -620,20 +628,44 @@ uint8_t matrix_key_count(void)
|
|||
return count;
|
||||
}
|
||||
|
||||
extern const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS];
|
||||
action_t action_for_key(uint8_t layer, keypos_t key)
|
||||
{
|
||||
return (action_t){ .code = pgm_read_word(&actionmaps[(layer)][key.row & 0x07][key.col & 0x0F]) };
|
||||
}
|
||||
|
||||
static uint8_t to_unimap(uint8_t code) {
|
||||
uint8_t row = ROW(code);
|
||||
uint8_t col = COL(code);
|
||||
switch (keyboard_kind) {
|
||||
case PC_XT:
|
||||
return pgm_read_byte(&unimap_cs1[row][col]);
|
||||
case PC_AT:
|
||||
return pgm_read_byte(&unimap_cs2[row][col]);
|
||||
case PC_TERMINAL:
|
||||
return pgm_read_byte(&unimap_cs3[row][col]);
|
||||
default:
|
||||
return UNIMAP_NO;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
static void matrix_make(uint8_t code)
|
||||
{
|
||||
if (!matrix_is_on(ROW(code), COL(code))) {
|
||||
matrix[ROW(code)] |= 1<<COL(code);
|
||||
uint8_t u = to_unimap(code);
|
||||
if (u > 0x7F) return;
|
||||
if (!matrix_is_on(ROW(u), COL(u))) {
|
||||
matrix[ROW(u)] |= 1<<COL(u);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
static void matrix_break(uint8_t code)
|
||||
{
|
||||
if (matrix_is_on(ROW(code), COL(code))) {
|
||||
matrix[ROW(code)] &= ~(1<<COL(code));
|
||||
uint8_t u = to_unimap(code);
|
||||
if (u > 0x7F) return;
|
||||
if (matrix_is_on(ROW(u), COL(u))) {
|
||||
matrix[ROW(u)] &= ~(1<<COL(u));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
1297
converter/ibmpc_usb/ibmpc_usb.cpp
Normal file
1297
converter/ibmpc_usb/ibmpc_usb.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -9,8 +9,4 @@ typedef enum { NONE, PC_XT, PC_AT, PC_TERMINAL, PC_MOUSE } keyboard_kind_t;
|
|||
kind == PC_MOUSE ? "MOUSE" : \
|
||||
"NONE")
|
||||
|
||||
|
||||
extern uint16_t keyboard_id;
|
||||
extern keyboard_kind_t keyboard_kind;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
164
converter/ibmpc_usb/ibmpc_usb.hpp
Normal file
164
converter/ibmpc_usb/ibmpc_usb.hpp
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
#ifndef IBMPC_USB_HPP
|
||||
#define IBMPC_USB_HPP
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include "matrix.h"
|
||||
#include "unimap_trans.h"
|
||||
#include "ibmpc_usb.h"
|
||||
|
||||
|
||||
|
||||
#define ID_STR(id) (id == 0xFFFE ? "_????" : \
|
||||
(id == 0xFFFD ? "_Z150" : \
|
||||
(id == 0x0000 ? "_AT84" : \
|
||||
"")))
|
||||
|
||||
#define ROW(code) ((code>>4)&0x07)
|
||||
#define COL(code) (code&0x0F)
|
||||
|
||||
|
||||
class IBMPCConverter {
|
||||
public:
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
|
||||
IBMPC &ibmpc;
|
||||
|
||||
IBMPCConverter(IBMPC &_ibmpc) : ibmpc(_ibmpc), keyboard_id(0), keyboard_kind(NONE), current_protocol(0) {
|
||||
matrix_clear();
|
||||
}
|
||||
|
||||
void init(void) {
|
||||
ibmpc.host_init();
|
||||
}
|
||||
|
||||
uint8_t process_interface(void);
|
||||
|
||||
void set_led(uint8_t usb_led);
|
||||
|
||||
static inline void matrix_clear(void) {
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
|
||||
}
|
||||
|
||||
static inline matrix_row_t matrix_get_row(uint8_t row) {
|
||||
return matrix[row];
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
uint16_t keyboard_id = 0x0000;
|
||||
keyboard_kind_t keyboard_kind = NONE;
|
||||
uint8_t current_protocol = 0;
|
||||
uint16_t init_time;
|
||||
|
||||
enum Converter_state {
|
||||
INIT,
|
||||
WAIT_SETTLE,
|
||||
AT_RESET,
|
||||
XT_RESET,
|
||||
XT_RESET_WAIT,
|
||||
XT_RESET_DONE,
|
||||
WAIT_AA,
|
||||
WAIT_AABF,
|
||||
WAIT_AABFBF,
|
||||
READ_ID,
|
||||
SETUP,
|
||||
LOOP,
|
||||
ERROR,
|
||||
} state = INIT;
|
||||
|
||||
enum CS1_state {
|
||||
CS1_INIT,
|
||||
CS1_E0,
|
||||
// Pause: E1 1D 45, E1 9D C5 [a]
|
||||
CS1_E1,
|
||||
CS1_E1_1D,
|
||||
CS1_E1_9D,
|
||||
} state_cs1 = CS1_INIT;
|
||||
|
||||
enum CS2_state {
|
||||
CS2_INIT,
|
||||
CS2_F0,
|
||||
CS2_E0,
|
||||
CS2_E0_F0,
|
||||
// Pause
|
||||
CS2_E1,
|
||||
CS2_E1_14,
|
||||
CS2_E1_F0,
|
||||
CS2_E1_F0_14,
|
||||
CS2_E1_F0_14_F0,
|
||||
} state_cs2 = CS2_INIT;
|
||||
|
||||
enum CS3_state {
|
||||
CS3_READY,
|
||||
CS3_F0,
|
||||
#ifdef G80_2551_SUPPORT
|
||||
// G80-2551 four extra keys around cursor keys
|
||||
CS3_G80,
|
||||
CS3_G80_F0,
|
||||
#endif
|
||||
} state_cs3 = CS3_READY;
|
||||
|
||||
int8_t process_cs1(uint8_t code);
|
||||
int8_t process_cs2(uint8_t code);
|
||||
int8_t process_cs3(uint8_t code);
|
||||
uint8_t cs1_e0code(uint8_t code);
|
||||
uint8_t cs2_e0code(uint8_t code);
|
||||
uint8_t translate_5576_cs2(uint8_t code);
|
||||
uint8_t translate_5576_cs2_e0(uint8_t code);
|
||||
uint8_t translate_5576_cs3(uint8_t code);
|
||||
|
||||
int16_t read_wait(uint16_t wait_ms);
|
||||
uint16_t read_keyboard_id(void);
|
||||
|
||||
// translate to Unimap before storing in matrix
|
||||
inline void matrix_make(uint8_t code) {
|
||||
uint8_t u = to_unimap(code);
|
||||
if (u > 0x7F) return;
|
||||
if (!matrix_is_on(ROW(u), COL(u))) {
|
||||
matrix[ROW(u)] |= 1<<COL(u);
|
||||
}
|
||||
}
|
||||
inline void matrix_break(uint8_t code) {
|
||||
uint8_t u = to_unimap(code);
|
||||
if (u > 0x7F) return;
|
||||
if (matrix_is_on(ROW(u), COL(u))) {
|
||||
matrix[ROW(u)] &= ~(1<<COL(u));
|
||||
}
|
||||
}
|
||||
uint8_t to_unimap(uint8_t code) {
|
||||
uint8_t row = ROW(code);
|
||||
uint8_t col = COL(code);
|
||||
switch (keyboard_kind) {
|
||||
case PC_XT:
|
||||
return pgm_read_byte(&unimap_cs1[row][col]);
|
||||
case PC_AT:
|
||||
return pgm_read_byte(&unimap_cs2[row][col]);
|
||||
case PC_TERMINAL:
|
||||
return pgm_read_byte(&unimap_cs3[row][col]);
|
||||
default:
|
||||
return UNIMAP_NO;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IBMPC_MOUSE_ENABLE
|
||||
enum {
|
||||
MOUSE_DEFAULT = 0, // Default three-button
|
||||
MOUSE_INTELLI = 3, // Intellimouse Explorer 3-button & wheel
|
||||
MOUSE_EXPLORER = 4, // Intellimouse Explorer 5-button & wheel
|
||||
MOUSE_LOGITECH = 9 // Logitech PS/2++
|
||||
} mouse_id = MOUSE_DEFAULT;
|
||||
uint8_t mouse_btn = 0;
|
||||
|
||||
void mouse_read_status(uint8_t *s) {
|
||||
ibmpc.host_send(0xE9);
|
||||
s[0] = ibmpc.host_recv_response();
|
||||
s[1] = ibmpc.host_recv_response();
|
||||
s[2] = ibmpc.host_recv_response();
|
||||
xprintf("S[%02X %02X %02X] ", s[0], s[1], s[2]);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
matrix_row_t IBMPCConverter::matrix[MATRIX_ROWS];
|
||||
|
||||
#endif
|
||||
|
|
@ -14,7 +14,7 @@ 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 "unimap_trans.h"
|
||||
#include "unimap.h"
|
||||
|
||||
|
||||
#define AC_FN0 ACTION_LAYER_TAP_KEY(1, KC_APPLICATION)
|
||||
|
|
|
|||
|
|
@ -17,12 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifndef UNIMAP_TRANS_H
|
||||
#define UNIMAP_TRANS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "unimap.h"
|
||||
#include "action.h"
|
||||
#include "ibmpc_usb.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -91,22 +87,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* Unsupported codes or error -> 00. UNIMAP_NUBS is unused.
|
||||
*/
|
||||
const uint8_t PROGMEM unimap_cs1[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{ UNIMAP_NO, UNIMAP_ESC, UNIMAP_1, UNIMAP_2, UNIMAP_3, UNIMAP_4, UNIMAP_5, UNIMAP_6 }, /* 00-07 */
|
||||
{ UNIMAP_7, UNIMAP_8, UNIMAP_9, UNIMAP_0, UNIMAP_MINUS, UNIMAP_EQUAL, UNIMAP_BSPACE,UNIMAP_TAB }, /* 08-0F */
|
||||
{ UNIMAP_Q, UNIMAP_W, UNIMAP_E, UNIMAP_R, UNIMAP_T, UNIMAP_Y, UNIMAP_U, UNIMAP_I }, /* 10-17 */
|
||||
{ UNIMAP_O, UNIMAP_P, UNIMAP_LBRC, UNIMAP_RBRC, UNIMAP_ENTER, UNIMAP_LCTL, UNIMAP_A, UNIMAP_S, }, /* 18-1F */
|
||||
{ UNIMAP_D, UNIMAP_F, UNIMAP_G, UNIMAP_H, UNIMAP_J, UNIMAP_K, UNIMAP_L, UNIMAP_SCLN }, /* 20-27 */
|
||||
{ UNIMAP_QUOTE, UNIMAP_GRAVE, UNIMAP_LSHIFT,UNIMAP_BSLASH,UNIMAP_Z, UNIMAP_X, UNIMAP_C, UNIMAP_V, }, /* 28-2F */
|
||||
{ UNIMAP_B, UNIMAP_N, UNIMAP_M, UNIMAP_COMMA, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_RSHIFT,UNIMAP_PAST }, /* 30-37 */
|
||||
{ UNIMAP_LALT, UNIMAP_SPACE, UNIMAP_CAPS, UNIMAP_F1, UNIMAP_F2, UNIMAP_F3, UNIMAP_F4, UNIMAP_F5 }, /* 38-3F */
|
||||
{ UNIMAP_F6, UNIMAP_F7, UNIMAP_F8, UNIMAP_F9, UNIMAP_F10, UNIMAP_NLCK, UNIMAP_SLCK, UNIMAP_P7 }, /* 40-47 */
|
||||
{ UNIMAP_P8, UNIMAP_P9, UNIMAP_PMNS, UNIMAP_P4, UNIMAP_P5, UNIMAP_P6, UNIMAP_PPLS, UNIMAP_P1 }, /* 48-4F */
|
||||
{ UNIMAP_P2, UNIMAP_P3, UNIMAP_P0, UNIMAP_PDOT, UNIMAP_PSCR, UNIMAP_PAUSE, UNIMAP_NUHS, UNIMAP_F11 }, /* 50-57 */
|
||||
{ UNIMAP_F12, UNIMAP_PEQL, UNIMAP_LGUI, UNIMAP_RGUI, UNIMAP_APP, UNIMAP_MUTE, UNIMAP_VOLD, UNIMAP_VOLU }, /* 58-5F */
|
||||
{ UNIMAP_UP, UNIMAP_LEFT, UNIMAP_DOWN, UNIMAP_RIGHT, UNIMAP_F13, UNIMAP_F14, UNIMAP_F15, UNIMAP_F16 }, /* 60-67 */
|
||||
{ UNIMAP_F17, UNIMAP_F18, UNIMAP_F19, UNIMAP_F20, UNIMAP_F21, UNIMAP_F22, UNIMAP_F23, UNIMAP_PENT }, /* 68-6F */
|
||||
{ UNIMAP_KANA, UNIMAP_INSERT,UNIMAP_DELETE,UNIMAP_RO, UNIMAP_HOME, UNIMAP_END, UNIMAP_F24, UNIMAP_PGUP }, /* 70-77 */
|
||||
{ UNIMAP_PGDN, UNIMAP_HENK, UNIMAP_RCTL, UNIMAP_MHEN, UNIMAP_RALT, UNIMAP_JYEN, UNIMAP_PCMM, UNIMAP_PSLS }, /* 78-7F */
|
||||
{ UNIMAP_NO, UNIMAP_ESC, UNIMAP_1, UNIMAP_2, UNIMAP_3, UNIMAP_4, UNIMAP_5, UNIMAP_6, /* 00-07 */
|
||||
UNIMAP_7, UNIMAP_8, UNIMAP_9, UNIMAP_0, UNIMAP_MINUS, UNIMAP_EQUAL, UNIMAP_BSPACE,UNIMAP_TAB }, /* 08-0F */
|
||||
{ UNIMAP_Q, UNIMAP_W, UNIMAP_E, UNIMAP_R, UNIMAP_T, UNIMAP_Y, UNIMAP_U, UNIMAP_I, /* 10-17 */
|
||||
UNIMAP_O, UNIMAP_P, UNIMAP_LBRC, UNIMAP_RBRC, UNIMAP_ENTER, UNIMAP_LCTL, UNIMAP_A, UNIMAP_S, }, /* 18-1F */
|
||||
{ UNIMAP_D, UNIMAP_F, UNIMAP_G, UNIMAP_H, UNIMAP_J, UNIMAP_K, UNIMAP_L, UNIMAP_SCLN, /* 20-27 */
|
||||
UNIMAP_QUOTE, UNIMAP_GRAVE, UNIMAP_LSHIFT,UNIMAP_BSLASH,UNIMAP_Z, UNIMAP_X, UNIMAP_C, UNIMAP_V, }, /* 28-2F */
|
||||
{ UNIMAP_B, UNIMAP_N, UNIMAP_M, UNIMAP_COMMA, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_RSHIFT,UNIMAP_PAST, /* 30-37 */
|
||||
UNIMAP_LALT, UNIMAP_SPACE, UNIMAP_CAPS, UNIMAP_F1, UNIMAP_F2, UNIMAP_F3, UNIMAP_F4, UNIMAP_F5 }, /* 38-3F */
|
||||
{ UNIMAP_F6, UNIMAP_F7, UNIMAP_F8, UNIMAP_F9, UNIMAP_F10, UNIMAP_NLCK, UNIMAP_SLCK, UNIMAP_P7, /* 40-47 */
|
||||
UNIMAP_P8, UNIMAP_P9, UNIMAP_PMNS, UNIMAP_P4, UNIMAP_P5, UNIMAP_P6, UNIMAP_PPLS, UNIMAP_P1 }, /* 48-4F */
|
||||
{ UNIMAP_P2, UNIMAP_P3, UNIMAP_P0, UNIMAP_PDOT, UNIMAP_PSCR, UNIMAP_PAUSE, UNIMAP_NUHS, UNIMAP_F11, /* 50-57 */
|
||||
UNIMAP_F12, UNIMAP_PEQL, UNIMAP_LGUI, UNIMAP_RGUI, UNIMAP_APP, UNIMAP_MUTE, UNIMAP_VOLD, UNIMAP_VOLU }, /* 58-5F */
|
||||
{ UNIMAP_UP, UNIMAP_LEFT, UNIMAP_DOWN, UNIMAP_RIGHT, UNIMAP_F13, UNIMAP_F14, UNIMAP_F15, UNIMAP_F16, /* 60-67 */
|
||||
UNIMAP_F17, UNIMAP_F18, UNIMAP_F19, UNIMAP_F20, UNIMAP_F21, UNIMAP_F22, UNIMAP_F23, UNIMAP_PENT }, /* 68-6F */
|
||||
{ UNIMAP_KANA, UNIMAP_INSERT,UNIMAP_DELETE,UNIMAP_RO, UNIMAP_HOME, UNIMAP_END, UNIMAP_F24, UNIMAP_PGUP, /* 70-77 */
|
||||
UNIMAP_PGDN, UNIMAP_HENK, UNIMAP_RCTL, UNIMAP_MHEN, UNIMAP_RALT, UNIMAP_JYEN, UNIMAP_PCMM, UNIMAP_PSLS }, /* 78-7F */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -151,22 +147,22 @@ const uint8_t PROGMEM unimap_cs1[MATRIX_ROWS][MATRIX_COLS] = {
|
|||
* 51, 63, 68, 6A, 6D: Hidden keys in IBM model M [6]
|
||||
*/
|
||||
const uint8_t PROGMEM unimap_cs2[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{ UNIMAP_PAUS, UNIMAP_F9, UNIMAP_F7, UNIMAP_F5, UNIMAP_F3, UNIMAP_F1, UNIMAP_F2, UNIMAP_F12 }, /* 00-07 */
|
||||
{ UNIMAP_F13, UNIMAP_F10, UNIMAP_F8, UNIMAP_F6, UNIMAP_F4, UNIMAP_TAB, UNIMAP_GRV, UNIMAP_RALT }, /* 08-0F */
|
||||
{ UNIMAP_F14, UNIMAP_LALT, UNIMAP_LSHIFT,UNIMAP_KANA, UNIMAP_LCTL, UNIMAP_Q, UNIMAP_1, UNIMAP_RCTL }, /* 10-17 */
|
||||
{ UNIMAP_F15, UNIMAP_LGUI, UNIMAP_Z, UNIMAP_S, UNIMAP_A, UNIMAP_W, UNIMAP_2, UNIMAP_RGUI }, /* 18-1F */
|
||||
{ UNIMAP_F16, UNIMAP_C, UNIMAP_X, UNIMAP_D, UNIMAP_E, UNIMAP_4, UNIMAP_3, UNIMAP_END }, /* 20-27 */
|
||||
{ UNIMAP_F17, UNIMAP_SPACE, UNIMAP_V, UNIMAP_F, UNIMAP_T, UNIMAP_R, UNIMAP_5, UNIMAP_HOME }, /* 28-2F */
|
||||
{ UNIMAP_F18, UNIMAP_N, UNIMAP_B, UNIMAP_H, UNIMAP_G, UNIMAP_Y, UNIMAP_6, UNIMAP_DEL }, /* 30-37 */
|
||||
{ UNIMAP_F19, UNIMAP_INS, UNIMAP_M, UNIMAP_J, UNIMAP_U, UNIMAP_7, UNIMAP_8, UNIMAP_DOWN }, /* 38-3F */
|
||||
{ UNIMAP_F20, UNIMAP_COMMA, UNIMAP_K, UNIMAP_I, UNIMAP_O, UNIMAP_0, UNIMAP_9, UNIMAP_RIGHT }, /* 40-47 */
|
||||
{ UNIMAP_F21, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_L, UNIMAP_SCOLON,UNIMAP_P, UNIMAP_MINUS, UNIMAP_UP }, /* 48-4F */
|
||||
{ UNIMAP_F22, UNIMAP_RO, UNIMAP_QUOTE, UNIMAP_LEFT, UNIMAP_LBRC, UNIMAP_EQUAL, UNIMAP_PGDN, UNIMAP_F23 }, /* 50-57 */
|
||||
{ UNIMAP_CAPS, UNIMAP_RSHIFT,UNIMAP_ENTER, UNIMAP_RBRC, UNIMAP_APP, UNIMAP_BSLASH,UNIMAP_PGUP, UNIMAP_F24 }, /* 58-5F */
|
||||
{ UNIMAP_PSLS, UNIMAP_NUBS, UNIMAP_PENT, UNIMAP_PEQL, UNIMAP_HENK, UNIMAP_VOLD, UNIMAP_BSPACE,UNIMAP_MHEN }, /* 60-67 */
|
||||
{ UNIMAP_NUHS, UNIMAP_P1, UNIMAP_JYEN, UNIMAP_P4, UNIMAP_P7, UNIMAP_PCMM, UNIMAP_VOLU, UNIMAP_MUTE }, /* 68-6F */
|
||||
{ UNIMAP_P0, UNIMAP_PDOT, UNIMAP_P2, UNIMAP_P5, UNIMAP_P6, UNIMAP_P8, UNIMAP_ESC, UNIMAP_NLCK }, /* 70-77 */
|
||||
{ UNIMAP_F11, UNIMAP_PPLS, UNIMAP_P3, UNIMAP_PMNS, UNIMAP_PAST, UNIMAP_P9, UNIMAP_SLCK, UNIMAP_PSCR }, /* 78-7F */
|
||||
{ UNIMAP_PAUS, UNIMAP_F9, UNIMAP_F7, UNIMAP_F5, UNIMAP_F3, UNIMAP_F1, UNIMAP_F2, UNIMAP_F12, /* 00-07 */
|
||||
UNIMAP_F13, UNIMAP_F10, UNIMAP_F8, UNIMAP_F6, UNIMAP_F4, UNIMAP_TAB, UNIMAP_GRV, UNIMAP_RALT }, /* 08-0F */
|
||||
{ UNIMAP_F14, UNIMAP_LALT, UNIMAP_LSHIFT,UNIMAP_KANA, UNIMAP_LCTL, UNIMAP_Q, UNIMAP_1, UNIMAP_RCTL, /* 10-17 */
|
||||
UNIMAP_F15, UNIMAP_LGUI, UNIMAP_Z, UNIMAP_S, UNIMAP_A, UNIMAP_W, UNIMAP_2, UNIMAP_RGUI }, /* 18-1F */
|
||||
{ UNIMAP_F16, UNIMAP_C, UNIMAP_X, UNIMAP_D, UNIMAP_E, UNIMAP_4, UNIMAP_3, UNIMAP_END, /* 20-27 */
|
||||
UNIMAP_F17, UNIMAP_SPACE, UNIMAP_V, UNIMAP_F, UNIMAP_T, UNIMAP_R, UNIMAP_5, UNIMAP_HOME }, /* 28-2F */
|
||||
{ UNIMAP_F18, UNIMAP_N, UNIMAP_B, UNIMAP_H, UNIMAP_G, UNIMAP_Y, UNIMAP_6, UNIMAP_DEL, /* 30-37 */
|
||||
UNIMAP_F19, UNIMAP_INS, UNIMAP_M, UNIMAP_J, UNIMAP_U, UNIMAP_7, UNIMAP_8, UNIMAP_DOWN }, /* 38-3F */
|
||||
{ UNIMAP_F20, UNIMAP_COMMA, UNIMAP_K, UNIMAP_I, UNIMAP_O, UNIMAP_0, UNIMAP_9, UNIMAP_RIGHT, /* 40-47 */
|
||||
UNIMAP_F21, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_L, UNIMAP_SCOLON,UNIMAP_P, UNIMAP_MINUS, UNIMAP_UP }, /* 48-4F */
|
||||
{ UNIMAP_F22, UNIMAP_RO, UNIMAP_QUOTE, UNIMAP_LEFT, UNIMAP_LBRC, UNIMAP_EQUAL, UNIMAP_PGDN, UNIMAP_F23, /* 50-57 */
|
||||
UNIMAP_CAPS, UNIMAP_RSHIFT,UNIMAP_ENTER, UNIMAP_RBRC, UNIMAP_APP, UNIMAP_BSLASH,UNIMAP_PGUP, UNIMAP_F24 }, /* 58-5F */
|
||||
{ UNIMAP_PSLS, UNIMAP_NUBS, UNIMAP_PENT, UNIMAP_PEQL, UNIMAP_HENK, UNIMAP_VOLD, UNIMAP_BSPACE,UNIMAP_MHEN, /* 60-67 */
|
||||
UNIMAP_NUHS, UNIMAP_P1, UNIMAP_JYEN, UNIMAP_P4, UNIMAP_P7, UNIMAP_PCMM, UNIMAP_VOLU, UNIMAP_MUTE }, /* 68-6F */
|
||||
{ UNIMAP_P0, UNIMAP_PDOT, UNIMAP_P2, UNIMAP_P5, UNIMAP_P6, UNIMAP_P8, UNIMAP_ESC, UNIMAP_NLCK, /* 70-77 */
|
||||
UNIMAP_F11, UNIMAP_PPLS, UNIMAP_P3, UNIMAP_PMNS, UNIMAP_PAST, UNIMAP_P9, UNIMAP_SLCK, UNIMAP_PSCR }, /* 78-7F */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -210,45 +206,22 @@ const uint8_t PROGMEM unimap_cs2[MATRIX_ROWS][MATRIX_COLS] = {
|
|||
* 51, 5C, 5D, 68, 78: Hidden keys in IBM 122-key terminal keyboard [7]
|
||||
*/
|
||||
const uint8_t PROGMEM unimap_cs3[MATRIX_ROWS][MATRIX_COLS] = {
|
||||
{ UNIMAP_KANA, UNIMAP_LGUI, UNIMAP_PSCR, UNIMAP_VOLD, UNIMAP_VOLU, UNIMAP_MUTE, UNIMAP_HENK, UNIMAP_F1 }, /* 00-07 */
|
||||
{ UNIMAP_F13, UNIMAP_RGUI, UNIMAP_APP, UNIMAP_MHEN, UNIMAP_PAUS, UNIMAP_TAB, UNIMAP_GRV, UNIMAP_F2 }, /* 08-0F */
|
||||
{ UNIMAP_F14, UNIMAP_LCTL, UNIMAP_LSHIFT,UNIMAP_NUBS, UNIMAP_CAPS, UNIMAP_Q, UNIMAP_1, UNIMAP_F3 }, /* 10-17 */
|
||||
{ UNIMAP_F15, UNIMAP_LALT, UNIMAP_Z, UNIMAP_S, UNIMAP_A, UNIMAP_W, UNIMAP_2, UNIMAP_F4 }, /* 18-1F */
|
||||
{ UNIMAP_F16, UNIMAP_C, UNIMAP_X, UNIMAP_D, UNIMAP_E, UNIMAP_4, UNIMAP_3, UNIMAP_F5 }, /* 20-27 */
|
||||
{ UNIMAP_F17, UNIMAP_SPACE, UNIMAP_V, UNIMAP_F, UNIMAP_T, UNIMAP_R, UNIMAP_5, UNIMAP_F6 }, /* 28-2F */
|
||||
{ UNIMAP_F18, UNIMAP_N, UNIMAP_B, UNIMAP_H, UNIMAP_G, UNIMAP_Y, UNIMAP_6, UNIMAP_F7 }, /* 30-37 */
|
||||
{ UNIMAP_F19, UNIMAP_RALT, UNIMAP_M, UNIMAP_J, UNIMAP_U, UNIMAP_7, UNIMAP_8, UNIMAP_F8 }, /* 38-3F */
|
||||
{ UNIMAP_F20, UNIMAP_COMMA, UNIMAP_K, UNIMAP_I, UNIMAP_O, UNIMAP_0, UNIMAP_9, UNIMAP_F9 }, /* 40-47 */
|
||||
{ UNIMAP_F21, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_L, UNIMAP_SCOLON,UNIMAP_P, UNIMAP_MINUS, UNIMAP_F10 }, /* 48-4F */
|
||||
{ UNIMAP_F22, UNIMAP_RO, UNIMAP_QUOTE, UNIMAP_NUHS, UNIMAP_LBRC, UNIMAP_EQUAL, UNIMAP_F11, UNIMAP_F23 }, /* 50-57 */
|
||||
{ UNIMAP_RCTL, UNIMAP_RSHIFT,UNIMAP_ENTER, UNIMAP_RBRC, UNIMAP_BSLASH,UNIMAP_JYEN, UNIMAP_F12, UNIMAP_F24 }, /* 58-5F */
|
||||
{ UNIMAP_DOWN, UNIMAP_LEFT, UNIMAP_HOME, UNIMAP_UP, UNIMAP_END, UNIMAP_INS, UNIMAP_BSPACE,UNIMAP_PSLS }, /* 60-67 */
|
||||
{ UNIMAP_PCMM, UNIMAP_P1, UNIMAP_RIGHT, UNIMAP_P4, UNIMAP_P7, UNIMAP_DEL, UNIMAP_PGUP, UNIMAP_PGDN }, /* 68-6F */
|
||||
{ UNIMAP_P0, UNIMAP_PDOT, UNIMAP_P2, UNIMAP_P5, UNIMAP_P6, UNIMAP_P8, UNIMAP_ESC, UNIMAP_NLCK }, /* 70-77 */
|
||||
{ UNIMAP_PEQL, UNIMAP_PENT, UNIMAP_P3, UNIMAP_PMNS, UNIMAP_PPLS, UNIMAP_P9, UNIMAP_SLCK, UNIMAP_PAST }, /* 78-7F */
|
||||
{ UNIMAP_KANA, UNIMAP_LGUI, UNIMAP_PSCR, UNIMAP_VOLD, UNIMAP_VOLU, UNIMAP_MUTE, UNIMAP_HENK, UNIMAP_F1, /* 00-07 */
|
||||
UNIMAP_F13, UNIMAP_RGUI, UNIMAP_APP, UNIMAP_MHEN, UNIMAP_PAUS, UNIMAP_TAB, UNIMAP_GRV, UNIMAP_F2 }, /* 08-0F */
|
||||
{ UNIMAP_F14, UNIMAP_LCTL, UNIMAP_LSHIFT,UNIMAP_NUBS, UNIMAP_CAPS, UNIMAP_Q, UNIMAP_1, UNIMAP_F3, /* 10-17 */
|
||||
UNIMAP_F15, UNIMAP_LALT, UNIMAP_Z, UNIMAP_S, UNIMAP_A, UNIMAP_W, UNIMAP_2, UNIMAP_F4 }, /* 18-1F */
|
||||
{ UNIMAP_F16, UNIMAP_C, UNIMAP_X, UNIMAP_D, UNIMAP_E, UNIMAP_4, UNIMAP_3, UNIMAP_F5, /* 20-27 */
|
||||
UNIMAP_F17, UNIMAP_SPACE, UNIMAP_V, UNIMAP_F, UNIMAP_T, UNIMAP_R, UNIMAP_5, UNIMAP_F6 }, /* 28-2F */
|
||||
{ UNIMAP_F18, UNIMAP_N, UNIMAP_B, UNIMAP_H, UNIMAP_G, UNIMAP_Y, UNIMAP_6, UNIMAP_F7, /* 30-37 */
|
||||
UNIMAP_F19, UNIMAP_RALT, UNIMAP_M, UNIMAP_J, UNIMAP_U, UNIMAP_7, UNIMAP_8, UNIMAP_F8 }, /* 38-3F */
|
||||
{ UNIMAP_F20, UNIMAP_COMMA, UNIMAP_K, UNIMAP_I, UNIMAP_O, UNIMAP_0, UNIMAP_9, UNIMAP_F9, /* 40-47 */
|
||||
UNIMAP_F21, UNIMAP_DOT, UNIMAP_SLASH, UNIMAP_L, UNIMAP_SCOLON,UNIMAP_P, UNIMAP_MINUS, UNIMAP_F10 }, /* 48-4F */
|
||||
{ UNIMAP_F22, UNIMAP_RO, UNIMAP_QUOTE, UNIMAP_NUHS, UNIMAP_LBRC, UNIMAP_EQUAL, UNIMAP_F11, UNIMAP_F23, /* 50-57 */
|
||||
UNIMAP_RCTL, UNIMAP_RSHIFT,UNIMAP_ENTER, UNIMAP_RBRC, UNIMAP_BSLASH,UNIMAP_JYEN, UNIMAP_F12, UNIMAP_F24 }, /* 58-5F */
|
||||
{ UNIMAP_DOWN, UNIMAP_LEFT, UNIMAP_HOME, UNIMAP_UP, UNIMAP_END, UNIMAP_INS, UNIMAP_BSPACE,UNIMAP_PSLS, /* 60-67 */
|
||||
UNIMAP_PCMM, UNIMAP_P1, UNIMAP_RIGHT, UNIMAP_P4, UNIMAP_P7, UNIMAP_DEL, UNIMAP_PGUP, UNIMAP_PGDN }, /* 68-6F */
|
||||
{ UNIMAP_P0, UNIMAP_PDOT, UNIMAP_P2, UNIMAP_P5, UNIMAP_P6, UNIMAP_P8, UNIMAP_ESC, UNIMAP_NLCK, /* 70-77 */
|
||||
UNIMAP_PEQL, UNIMAP_PENT, UNIMAP_P3, UNIMAP_PMNS, UNIMAP_PPLS, UNIMAP_P9, UNIMAP_SLCK, UNIMAP_PAST }, /* 78-7F */
|
||||
};
|
||||
|
||||
|
||||
extern const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS];
|
||||
action_t action_for_key(uint8_t layer, keypos_t key)
|
||||
{
|
||||
uint8_t unimap_pos;
|
||||
switch (keyboard_kind) {
|
||||
case PC_XT:
|
||||
unimap_pos = pgm_read_byte(&unimap_cs1[key.row][key.col]);
|
||||
break;
|
||||
case PC_AT:
|
||||
unimap_pos = pgm_read_byte(&unimap_cs2[key.row][key.col]);
|
||||
break;
|
||||
case PC_TERMINAL:
|
||||
unimap_pos = pgm_read_byte(&unimap_cs3[key.row][key.col]);
|
||||
break;
|
||||
default:
|
||||
return (action_t)ACTION_NO;
|
||||
}
|
||||
|
||||
if (unimap_pos == UNIMAP_NO) return (action_t)ACTION_NO;
|
||||
|
||||
return (action_t)pgm_read_word(&actionmaps[(layer)][(unimap_pos & 0x70) >> 4][(unimap_pos & 0x0f)]);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
88
converter/usb_desc_dump/Makefile
Normal file
88
converter/usb_desc_dump/Makefile
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
TARGET ?= usb_desc_dump
|
||||
TMK_DIR ?= ../../tmk_core
|
||||
TARGET_DIR ?= .
|
||||
|
||||
SRC ?= ino.cpp
|
||||
CONFIG_H ?= config.h
|
||||
|
||||
# MCU name
|
||||
MCU ?= atmega32u4
|
||||
# Processor frequency.
|
||||
F_CPU ?= 16000000
|
||||
|
||||
#
|
||||
# LUFA specific
|
||||
#
|
||||
ARCH ?= AVR8
|
||||
F_USB ?= $(F_CPU)
|
||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
#
|
||||
# Build Options
|
||||
#
|
||||
MOUSEKEY_ENABLE ?= no # Mouse keys
|
||||
EXTRAKEY_ENABLE ?= no # Media control and System control
|
||||
CONSOLE_ENABLE ?= yes # Console for debug
|
||||
COMMAND_ENABLE ?= no # Commands for debug and configuration
|
||||
NKRO_ENABLE ?= no # USB Nkey Rollover
|
||||
NO_KEYBOARD ?= yes # No keyboard interface
|
||||
|
||||
# Boot Section Size in bytes
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
OPT_DEFS += -DNO_DEBUG
|
||||
|
||||
EXTRACPPFLAGS = -fpermissive
|
||||
|
||||
# program Leonardo
|
||||
PROGRAM_CMD = avrdude -p$(MCU) -cavr109 -b57600 -Uflash:w:$(TARGET).hex -P$(DEV)
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TMK_DIR)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# USB_desc_dump build setting
|
||||
#
|
||||
include $(TMK_DIR)/protocol/usb_hid.mk
|
||||
|
||||
USB_DESC_DUMP_DIR = $(USB_HOST_SHIELD_DIR)/examples/USB_desc_dump
|
||||
SRC += $(USB_DESC_DUMP_DIR)/USB_desc_dump.cpp
|
||||
SRC += $(USB_HOST_SHIELD_DIR)/hidescriptorparser.cpp
|
||||
|
||||
# Print Standard descriptor
|
||||
OPT_DEFS += -DPRINT_DESC
|
||||
#OPT_DEFS += -DNO_PRINT_DESC
|
||||
|
||||
# Print High-speed Hub descriptor
|
||||
#OPT_DEFS += -DPRINT_DESC_HSHUB
|
||||
OPT_DEFS += -DNO_PRINT_DESC_HSHUB
|
||||
|
||||
# Print HID Report descriptor
|
||||
#OPT_DEFS += -DPRINT_DESC_REPORT
|
||||
OPT_DEFS += -DNO_PRINT_DESC_REPORT
|
||||
|
||||
|
||||
|
||||
include $(TMK_DIR)/protocol/lufa.mk
|
||||
include $(TMK_DIR)/common.mk
|
||||
include $(TMK_DIR)/rules.mk
|
||||
|
||||
|
||||
|
||||
$(OBJDIR)/$(USB_DESC_DUMP_DIR)/USB_desc_dump.cpp.o : $(OBJDIR)/$(USB_DESC_DUMP_DIR)/USB_desc_dump.cpp $(OBJDIR)/$(USB_DESC_DUMP_DIR)/desc.h
|
||||
@echo
|
||||
mkdir -p $(@D)
|
||||
@echo $(MSG_COMPILING_CPP) $<
|
||||
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
$(OBJDIR)/$(USB_DESC_DUMP_DIR)/USB_desc_dump.cpp : $(TMK_DIR)/$(USB_DESC_DUMP_DIR)/USB_desc_dump.ino
|
||||
@echo
|
||||
mkdir -p $(@D)
|
||||
$(COPY) $< $@
|
||||
|
||||
$(OBJDIR)/$(USB_DESC_DUMP_DIR)/desc.h : $(TMK_DIR)/$(USB_DESC_DUMP_DIR)/desc.h
|
||||
@echo
|
||||
mkdir -p $(@D)
|
||||
$(COPY) $< $@
|
||||
163
converter/usb_desc_dump/README.md
Normal file
163
converter/usb_desc_dump/README.md
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
USB Descriptor Dumper
|
||||
=====================
|
||||
2021-07-20
|
||||
|
||||
`Usb_desc_dump` gets USB descriptors and shows in HEX dump and human readable form.
|
||||
This works on TMK USB-USB converter and USB Host Shield with Arduino Leonardo.
|
||||
|
||||
|
||||
Following descriptors are supported.
|
||||
|
||||
- Device Descriptor
|
||||
- Configuration Descriptor
|
||||
- Interface Descriptor
|
||||
- Endpoint Descriptor
|
||||
- HID Descriptor
|
||||
- HID Report descriptor
|
||||
- String Descriptor
|
||||
- Device Qualifier*
|
||||
- Other Speed*
|
||||
- Audio/MIDI Class*
|
||||
*: partly supported
|
||||
|
||||
|
||||
See source code for the detail.
|
||||
|
||||
- https://github.com/tmk/USB_Host_Shield_2.0/tree/master/examples/USB_desc_dump
|
||||
|
||||
|
||||
|
||||
Example optput:
|
||||
|
||||
```
|
||||
usb_state: 90
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// USB_desc_dump
|
||||
// Address: 01
|
||||
// Lowspeed: 00
|
||||
|
||||
// Devicer dump:
|
||||
12 01 00 02 00 00 00 08 6A 04 11 00 00 01 00 00
|
||||
00 01
|
||||
|
||||
// Device:
|
||||
bLength: 12
|
||||
bDescriptorType: 01
|
||||
bcdUSB: 0200
|
||||
bDeviceClass: 00
|
||||
bDeviceSubClass: 00
|
||||
bDeviceProtocol: 00
|
||||
bMaxPacketSize0: 08
|
||||
idVendor: 046A
|
||||
idProduct: 0011
|
||||
bcdDevice: 0100
|
||||
iManufacturer: 00
|
||||
iProduct: 00
|
||||
iSerialNumber: 00
|
||||
bNumConfigurations: 01
|
||||
|
||||
// Config0 dump: len: 0022
|
||||
09 02 22 00 01 01 00 A0 32 09 04 00 00 01 03 01
|
||||
01 00 09 21 11 01 00 01 22 40 00 07 05 81 03 08
|
||||
00 0A
|
||||
|
||||
// Config:
|
||||
bLength: 09
|
||||
bDescriptorType: 02
|
||||
wTotalLength: 0022
|
||||
bNumInterfaces: 01
|
||||
bConfigurationValue: 01
|
||||
iConfiguration: 00
|
||||
bmAttributes: A0
|
||||
bMaxPower: 32
|
||||
|
||||
// Interface0.0:
|
||||
bLength: 09
|
||||
bDescriptorType: 04
|
||||
bInterfaceNumber: 00
|
||||
bAlternateSetting: 00
|
||||
bNumEndpoints: 01
|
||||
bInterfaceClass: 03
|
||||
bInterfaceSubClass: 01
|
||||
bInterfaceProtocol: 01
|
||||
iInterface: 00
|
||||
|
||||
// HID:
|
||||
bLength: 09
|
||||
bDescriptorType: 21
|
||||
bcdHID: 0111
|
||||
bCountryCode: 00
|
||||
bNumDescriptors: 01
|
||||
bDescrType: 22
|
||||
wDescriptorLength: 0040
|
||||
|
||||
// Report0 dump: len: 0040
|
||||
05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
|
||||
75 01 95 08 81 02 95 01 75 08 81 01 95 03 75 01
|
||||
05 08 19 01 29 03 91 02 95 05 75 01 91 01 95 06
|
||||
75 08 15 00 26 DD 00 05 07 19 00 29 DD 81 00 C0
|
||||
|
||||
// Endpoint:
|
||||
bLength: 07
|
||||
bDescriptorType: 05
|
||||
bEndpointAddress: 81
|
||||
bmAttributes: 03
|
||||
wMaxPacketSize: 0008
|
||||
bInterval: 0A
|
||||
|
||||
// Parse data here: http://eleccelerator.com/usbdescreqparser/
|
||||
```
|
||||
|
||||
|
||||
|
||||
To inspect descriptor content closely use 'USB Descriptor and Request Parser' on line.
|
||||
|
||||
- https://eleccelerator.com/usbdescreqparser/
|
||||
|
||||
|
||||
Also you can use command line tool `hidrd-convert` like below.
|
||||
|
||||
- https://github.com/DIGImend/hidrd
|
||||
|
||||
```
|
||||
$ cat | hidrd-convert -i hex -o spec
|
||||
05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
|
||||
75 01 95 08 81 02 95 01 75 08 81 01 95 03 75 01
|
||||
05 08 19 01 29 03 91 02 95 05 75 01 91 01 95 06
|
||||
75 08 15 00 26 DD 00 05 07 19 00 29 DD 81 00 C0
|
||||
^D
|
||||
|
||||
Usage Page (Desktop), ; Generic desktop controls (01h)
|
||||
Usage (Keyboard), ; Keyboard (06h, application collection)
|
||||
Collection (Application),
|
||||
Usage Page (Keyboard), ; Keyboard/keypad (07h)
|
||||
Usage Minimum (KB Leftcontrol), ; Keyboard left control (E0h, dynamic value)
|
||||
Usage Maximum (KB Right GUI), ; Keyboard right GUI (E7h, dynamic value)
|
||||
Logical Minimum (0),
|
||||
Logical Maximum (1),
|
||||
Report Size (1),
|
||||
Report Count (8),
|
||||
Input (Variable),
|
||||
Report Count (1),
|
||||
Report Size (8),
|
||||
Input (Constant),
|
||||
Report Count (3),
|
||||
Report Size (1),
|
||||
Usage Page (LED), ; LEDs (08h)
|
||||
Usage Minimum (01h),
|
||||
Usage Maximum (03h),
|
||||
Output (Variable),
|
||||
Report Count (5),
|
||||
Report Size (1),
|
||||
Output (Constant),
|
||||
Report Count (6),
|
||||
Report Size (8),
|
||||
Logical Minimum (0),
|
||||
Logical Maximum (221),
|
||||
Usage Page (Keyboard), ; Keyboard/keypad (07h)
|
||||
Usage Minimum (None), ; No event (00h, selector)
|
||||
Usage Maximum (KP Hexadecimal), ; Keypad Hexadecimal (DDh, selector)
|
||||
Input,
|
||||
End Collection
|
||||
```
|
||||
1191
converter/usb_desc_dump/binary/usb_desc_dump.hex
Normal file
1191
converter/usb_desc_dump/binary/usb_desc_dump.hex
Normal file
File diff suppressed because it is too large
Load diff
52
converter/usb_desc_dump/config.h
Normal file
52
converter/usb_desc_dump/config.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
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 0x005B
|
||||
#define DEVICE_VER 0x0814
|
||||
#define MANUFACTURER TMK
|
||||
#define PRODUCT USB Descriptor Dumper
|
||||
|
||||
|
||||
#define DESCRIPTION Product from TMK keyboard firmware project
|
||||
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 0
|
||||
#define MATRIX_COLS 0
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
|
||||
|
||||
|
||||
// Disable power saving in USB suspend loop but remote wakeup is still valid.
|
||||
// This allows keep USB::Task() going during suspend without power down time delay.
|
||||
//#define NO_SUSPEND_POWER_DOWN
|
||||
|
||||
|
||||
// Disable USB startup wait, which can delays starting UHS2 Task() for 350-600ms.
|
||||
//#define NO_USB_STARTUP_WAIT_LOOP
|
||||
|
||||
// Disable USB suspend loop, which blocks UHS2 Task() while power saving.
|
||||
// Note that this also disables power saving and remote wakeup from keyboard completely.
|
||||
//#define NO_USB_SUSPEND_LOOP
|
||||
|
||||
#endif
|
||||
37
converter/usb_desc_dump/ino.cpp
Normal file
37
converter/usb_desc_dump/ino.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2021 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "Arduino.h"
|
||||
#include "hook.h"
|
||||
|
||||
|
||||
void hook_early_init(void) {
|
||||
// arduino
|
||||
setup();
|
||||
}
|
||||
|
||||
void hook_late_init(void) {
|
||||
}
|
||||
|
||||
void hook_main_loop(void) {
|
||||
// arduino
|
||||
loop();
|
||||
}
|
||||
|
|
@ -17,7 +17,10 @@ SRC += $(COMMON_DIR)/host.c \
|
|||
$(COMMON_DIR)/avr/bootloader.c
|
||||
|
||||
|
||||
# Option modules
|
||||
ifeq (yes,$(strip $(NO_KEYBOARD)))
|
||||
OPT_DEFS += -DNO_KEYBOARD
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(UNIMAP_ENABLE)))
|
||||
SRC += $(COMMON_DIR)/unimap.c
|
||||
OPT_DEFS += -DUNIMAP_ENABLE
|
||||
|
|
@ -75,6 +78,10 @@ ifeq (yes,$(strip $(NKRO_ENABLE)))
|
|||
OPT_DEFS += -DNKRO_ENABLE
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(NKRO_6KRO_ENABLE)))
|
||||
OPT_DEFS += -DNKRO_6KRO_ENABLE
|
||||
endif
|
||||
|
||||
ifeq (yes,$(strip $(USB_6KRO_ENABLE)))
|
||||
OPT_DEFS += -DUSB_6KRO_ENABLE
|
||||
endif
|
||||
|
|
@ -109,7 +116,7 @@ ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE)))
|
|||
endif
|
||||
|
||||
# Version string
|
||||
TMK_VERSION := $(shell (git describe --always --dirty=+ || echo 'unknown') 2> /dev/null)
|
||||
TMK_VERSION := $(shell (git rev-parse --short=6 HEAD || echo 'unknown') 2> /dev/null)
|
||||
OPT_DEFS += -DTMK_VERSION=$(TMK_VERSION)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
static inline void add_key_byte(uint8_t code);
|
||||
static inline void del_key_byte(uint8_t code);
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
static inline void add_key_bit(uint8_t code);
|
||||
static inline void del_key_bit(uint8_t code);
|
||||
#endif
|
||||
|
|
@ -75,7 +75,7 @@ void send_keyboard_report(void) {
|
|||
/* key */
|
||||
void add_key(uint8_t key)
|
||||
{
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
if (keyboard_protocol && keyboard_nkro) {
|
||||
add_key_bit(key);
|
||||
return;
|
||||
|
|
@ -86,7 +86,7 @@ void add_key(uint8_t key)
|
|||
|
||||
void del_key(uint8_t key)
|
||||
{
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
if (keyboard_protocol && keyboard_nkro) {
|
||||
del_key_bit(key);
|
||||
return;
|
||||
|
|
@ -159,7 +159,7 @@ uint8_t has_anymod(void)
|
|||
|
||||
uint8_t get_first_key(void)
|
||||
{
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
if (keyboard_protocol && keyboard_nkro) {
|
||||
uint8_t i = 0;
|
||||
for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
|
||||
|
|
@ -286,7 +286,7 @@ static inline void del_key_byte(uint8_t code)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
static inline void add_key_bit(uint8_t code)
|
||||
{
|
||||
if ((code>>3) < KEYBOARD_REPORT_BITS) {
|
||||
|
|
|
|||
|
|
@ -115,21 +115,25 @@ void suspend_power_down(void)
|
|||
|
||||
bool suspend_wakeup_condition(void)
|
||||
{
|
||||
#ifndef NO_KEYBOARD
|
||||
matrix_power_up();
|
||||
matrix_scan();
|
||||
matrix_power_down();
|
||||
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
|
||||
if (matrix_get_row(r)) return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// run immediately after wakeup
|
||||
void suspend_wakeup_init(void)
|
||||
{
|
||||
#ifndef NO_KEYBOARD
|
||||
// clear keyboard state
|
||||
matrix_clear();
|
||||
clear_keyboard();
|
||||
#endif
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
backlight_init();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ void bootmagic(void)
|
|||
}
|
||||
eeconfig_write_keymap(keymap_config.raw);
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
keyboard_nkro = keymap_config.nkro;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ static void command_common_help(void)
|
|||
"e: eeprom\n"
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
"n: NKRO\n"
|
||||
#endif
|
||||
|
||||
|
|
@ -314,7 +314,7 @@ static bool command_common(uint8_t code)
|
|||
#ifdef COMMAND_ENABLE
|
||||
" COMMAND"
|
||||
#endif
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
" NKRO"
|
||||
#endif
|
||||
#ifdef KEYMAP_SECTION_ENABLE
|
||||
|
|
@ -336,7 +336,7 @@ static bool command_common(uint8_t code)
|
|||
print_val_hex8(host_keyboard_leds());
|
||||
print_val_hex8(keyboard_protocol);
|
||||
print_val_hex8(keyboard_idle);
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
print_val_hex8(keyboard_nkro);
|
||||
#endif
|
||||
print_val_hex32(timer_read32());
|
||||
|
|
@ -355,7 +355,7 @@ static bool command_common(uint8_t code)
|
|||
# endif
|
||||
#endif
|
||||
break;
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
case KC_N:
|
||||
clear_keyboard(); //Prevents stuck keys.
|
||||
keyboard_nkro = !keyboard_nkro;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* Definitions of default hooks
|
||||
* ------------------------------------------------- */
|
||||
|
||||
__attribute__((weak))
|
||||
void hook_main_loop(void) {}
|
||||
|
||||
__attribute__((weak))
|
||||
void hook_keyboard_loop(void) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ void hook_usb_wakeup(void);
|
|||
/* Default behaviour: do nothing. */
|
||||
void hook_usb_startup_wait_loop(void);
|
||||
|
||||
/* Called periodically from main loop */
|
||||
/* Default behaviour: do nothing. */
|
||||
void hook_main_loop(void);
|
||||
|
||||
|
||||
/* -------------------------------------
|
||||
* Keyboard hooks
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "debug.h"
|
||||
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
bool keyboard_nkro = true;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
extern bool keyboard_nkro;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -171,10 +171,6 @@ static action_t keycode_to_action(uint8_t keycode)
|
|||
* Legacy keymap support
|
||||
* Consider using new keymap API instead.
|
||||
*/
|
||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
|
||||
extern const uint8_t fn_layer[];
|
||||
extern const uint8_t fn_keycode[];
|
||||
|
||||
__attribute__ ((weak))
|
||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
|
||||
{
|
||||
|
|
@ -223,10 +219,6 @@ action_t keymap_fn_to_action(uint8_t keycode)
|
|||
|
||||
#else
|
||||
|
||||
/* user keymaps should be defined somewhere */
|
||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
|
||||
extern const action_t fn_actions[];
|
||||
|
||||
__attribute__ ((weak))
|
||||
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "action.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BOOTMAGIC_ENABLE
|
||||
/* NOTE: Not portable. Bit field order depends on implementation */
|
||||
typedef union {
|
||||
|
|
@ -40,6 +44,8 @@ typedef union {
|
|||
} keymap_config_t;
|
||||
#endif
|
||||
|
||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
|
||||
extern const action_t fn_actions[];
|
||||
|
||||
/* translates key to keycode */
|
||||
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
|
||||
|
|
@ -54,6 +60,10 @@ action_t keymap_fn_to_action(uint8_t keycode);
|
|||
* Legacy keymap
|
||||
* Consider using new keymap API above instead.
|
||||
*/
|
||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
|
||||
extern const uint8_t fn_layer[];
|
||||
extern const uint8_t fn_keycode[];
|
||||
|
||||
/* keycode of key */
|
||||
__attribute__ ((deprecated))
|
||||
uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col);
|
||||
|
|
@ -65,6 +75,16 @@ uint8_t keymap_fn_layer(uint8_t fn_bits);
|
|||
/* keycode to send when release Fn key without using */
|
||||
__attribute__ ((deprecated))
|
||||
uint8_t keymap_fn_keycode(uint8_t fn_bits);
|
||||
|
||||
#else
|
||||
|
||||
/* user keymaps should be defined somewhere */
|
||||
extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
|
||||
extern const action_t fn_actions[];
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -100,6 +100,12 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
|
|||
#else /* NO_PRINT */
|
||||
|
||||
#define xprintf(s,...) ((void)0)
|
||||
#define xsprintf(s,...) ((void)0)
|
||||
#define xfprintf(s,...) ((void)0)
|
||||
#define xputs(s) ((void)0)
|
||||
#define xputc(c) ((void)0)
|
||||
#define xitoa(v, r, w) ((void)0)
|
||||
#define xatoi(s, r) ((void)0)
|
||||
#define print(s) ((void)0)
|
||||
#define println(s) ((void)0)
|
||||
#define print_set_sendchar(func) ((void)0)
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
# define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
|
||||
# define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
|
||||
|
||||
#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
|
||||
#elif defined(PROTOCOL_LUFA) && (defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE))
|
||||
# include "protocol/lufa/descriptor.h"
|
||||
# define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
|
||||
# define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
|
||||
|
|
@ -142,7 +142,7 @@ typedef union {
|
|||
uint8_t reserved;
|
||||
uint8_t keys[KEYBOARD_REPORT_KEYS];
|
||||
};
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
struct {
|
||||
uint8_t mods;
|
||||
uint8_t bits[KEYBOARD_REPORT_BITS];
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ static inline void ringbuf_write(ringbuf_t *buf, uint8_t data);
|
|||
static inline bool ringbuf_is_empty(ringbuf_t *buf);
|
||||
static inline bool ringbuf_is_full(ringbuf_t *buf);
|
||||
static inline void ringbuf_reset(ringbuf_t *buf);
|
||||
static inline void ringbuf_push(ringbuf_t *buf, uint8_t data);
|
||||
|
||||
static inline void ringbuf_init(ringbuf_t *buf, uint8_t *array, uint8_t size)
|
||||
{
|
||||
|
|
@ -70,4 +71,10 @@ static inline void ringbuf_reset(ringbuf_t *buf)
|
|||
buf->head = 0;
|
||||
buf->tail = 0;
|
||||
}
|
||||
static inline void ringbuf_push(ringbuf_t *buf, uint8_t data)
|
||||
{
|
||||
buf->buffer[buf->head] = data;
|
||||
buf->head++;
|
||||
buf->head &= buf->size_mask;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -214,11 +214,10 @@ void ibmpc_host_isr_clear(void)
|
|||
ringbuf_reset(&rb);
|
||||
}
|
||||
|
||||
#define LO8(w) (*((uint8_t *)&(w)))
|
||||
#define HI8(w) (*(((uint8_t *)&(w))+1))
|
||||
// NOTE: With this ISR data line can be read within 2us after clock falling edge.
|
||||
// To read data line early as possible:
|
||||
// write naked ISR with asembly code to read the line and call C func to do other job?
|
||||
|
||||
// NOTE: With this ISR data line should be read within 5us after clock falling edge.
|
||||
// Confirmed that ATmega32u4 can read data line in 2.5us from interrupt after
|
||||
// ISR prologue pushs r18, r19, r20, r21, r24, r25 r30 and r31 with GCC 5.4.0
|
||||
ISR(IBMPC_INT_VECT)
|
||||
{
|
||||
uint8_t dbit;
|
||||
|
|
@ -366,16 +365,19 @@ ISR(IBMPC_INT_VECT)
|
|||
|
||||
DONE:
|
||||
// store data
|
||||
if (!ringbuf_put(&rb, isr_state & 0xFF)) {
|
||||
// buffer overflow
|
||||
ibmpc_error = IBMPC_ERR_FULL;
|
||||
|
||||
ringbuf_push(&rb, isr_state & 0xFF);
|
||||
if (ringbuf_is_full(&rb)) {
|
||||
// just became full
|
||||
// Disable ISR if buffer is full
|
||||
IBMPC_INT_OFF();
|
||||
// inhibit: clock_lo
|
||||
IBMPC_CLOCK_PORT &= ~(1<<IBMPC_CLOCK_BIT);
|
||||
IBMPC_CLOCK_DDR |= (1<<IBMPC_CLOCK_BIT);
|
||||
}
|
||||
if (ringbuf_is_empty(&rb)) {
|
||||
// buffer overflow
|
||||
ibmpc_error = IBMPC_ERR_FULL;
|
||||
}
|
||||
ERROR:
|
||||
// clear for next data
|
||||
isr_state = 0x8000;
|
||||
|
|
|
|||
405
tmk_core/protocol/ibmpc.cpp
Normal file
405
tmk_core/protocol/ibmpc.cpp
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
Copyright 2010,2011,2012,2013,2019 Jun WAKO <wakojun@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* IBM PC keyboard protocol
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/atomic.h>
|
||||
#include "debug.h"
|
||||
#include "timer.h"
|
||||
#include "wait.h"
|
||||
#include "ibmpc.hpp"
|
||||
|
||||
|
||||
#define WAIT(stat, us, err) do { \
|
||||
if (!wait_##stat(us)) { \
|
||||
error = err; \
|
||||
goto ERROR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
IBMPC IBMPC::interface0 = IBMPC(IBMPC_CLOCK_BIT, IBMPC_DATA_BIT);
|
||||
#if defined(IBMPC_CLOCK_BIT1) && defined(IBMPC_DATA_BIT1)
|
||||
IBMPC IBMPC::interface1 = IBMPC(IBMPC_CLOCK_BIT1, IBMPC_DATA_BIT1);
|
||||
#endif
|
||||
|
||||
|
||||
void IBMPC::host_init(void)
|
||||
{
|
||||
// initialize reset pin to HiZ
|
||||
IBMPC_RST_HIZ();
|
||||
inhibit();
|
||||
int_init();
|
||||
int_off();
|
||||
host_isr_clear();
|
||||
}
|
||||
|
||||
void IBMPC::host_enable(void)
|
||||
{
|
||||
int_on();
|
||||
idle();
|
||||
}
|
||||
|
||||
void IBMPC::host_disable(void)
|
||||
{
|
||||
int_off();
|
||||
inhibit();
|
||||
}
|
||||
|
||||
int16_t IBMPC::host_send(uint8_t data)
|
||||
{
|
||||
bool parity = true;
|
||||
error = IBMPC_ERR_NONE;
|
||||
uint8_t retry = 0;
|
||||
|
||||
dprintf("w%02X ", data);
|
||||
|
||||
// Not receiving data
|
||||
if (isr_state != 0x8000) dprintf("isr:%04X ", isr_state);
|
||||
while (isr_state != 0x8000) ;
|
||||
|
||||
// Not clock Lo
|
||||
if (!clock_in()) dprintf("c:%u ", wait_clock_hi(1000));
|
||||
|
||||
// Not data Lo
|
||||
if (!data_in()) dprintf("d:%u ", wait_data_hi(1000));
|
||||
|
||||
int_off();
|
||||
|
||||
RETRY:
|
||||
/* terminate a transmission if we have */
|
||||
inhibit();
|
||||
wait_us(200); // [5]p.54
|
||||
|
||||
/* 'Request to Send' and Start bit */
|
||||
data_lo();
|
||||
wait_us(200);
|
||||
clock_hi(); // [5]p.54 [clock low]>100us [5]p.50
|
||||
WAIT(clock_lo, 10000, 1); // [5]p.53, -10ms [5]p.50
|
||||
|
||||
/* Data bit[2-9] */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
wait_us(15);
|
||||
if (data&(1<<i)) {
|
||||
parity = !parity;
|
||||
data_hi();
|
||||
} else {
|
||||
data_lo();
|
||||
}
|
||||
WAIT(clock_hi, 50, 2);
|
||||
WAIT(clock_lo, 50, 3);
|
||||
}
|
||||
|
||||
/* Parity bit */
|
||||
wait_us(15);
|
||||
if (parity) { data_hi(); } else { data_lo(); }
|
||||
WAIT(clock_hi, 50, 4);
|
||||
WAIT(clock_lo, 50, 5);
|
||||
|
||||
/* Stop bit */
|
||||
wait_us(15);
|
||||
data_hi();
|
||||
|
||||
/* Ack */
|
||||
WAIT(data_lo, 300, 6);
|
||||
WAIT(data_hi, 300, 7);
|
||||
WAIT(clock_hi, 300, 8);
|
||||
|
||||
// clear buffer to get response correctly
|
||||
host_isr_clear();
|
||||
|
||||
idle();
|
||||
int_on();
|
||||
return host_recv_response();
|
||||
ERROR:
|
||||
// Retry for Z-150 AT start bit error
|
||||
if (error == 1 && retry++ < 10) {
|
||||
error = IBMPC_ERR_NONE;
|
||||
dprintf("R ");
|
||||
goto RETRY;
|
||||
}
|
||||
|
||||
error |= IBMPC_ERR_SEND;
|
||||
inhibit();
|
||||
wait_ms(2);
|
||||
idle();
|
||||
int_on();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive data from keyboard
|
||||
*/
|
||||
int16_t IBMPC::host_recv(void)
|
||||
{
|
||||
int16_t ret = -1;
|
||||
|
||||
// Enable ISR if buffer was full
|
||||
if (ringbuf_is_full()) {
|
||||
host_isr_clear();
|
||||
int_on();
|
||||
idle();
|
||||
}
|
||||
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
ret = ringbuf_get();
|
||||
}
|
||||
if (ret != -1) dprintf("r%02X ", ret&0xFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int16_t IBMPC::host_recv_response(void)
|
||||
{
|
||||
// Command may take 25ms/20ms at most([5]p.46, [3]p.21)
|
||||
uint8_t retry = 25;
|
||||
int16_t data = -1;
|
||||
while (retry-- && (data = host_recv()) == -1) {
|
||||
wait_ms(1);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void IBMPC::host_isr_clear(void)
|
||||
{
|
||||
isr_debug = 0;
|
||||
protocol = 0;
|
||||
error = 0;
|
||||
isr_state = 0x8000;
|
||||
ringbuf_reset();
|
||||
}
|
||||
|
||||
inline void IBMPC::isr(void)
|
||||
{
|
||||
uint8_t dbit;
|
||||
dbit = IBMPC_DATA_PIN&(1<<data_bit);
|
||||
|
||||
// Timeout check
|
||||
uint8_t t;
|
||||
// use only the least byte of millisecond timer
|
||||
asm("lds %0, %1" : "=r" (t) : "p" (&timer_count));
|
||||
//t = (uint8_t)timer_count; // compiler uses four registers instead of one
|
||||
if (isr_state == 0x8000) {
|
||||
timer_start = t;
|
||||
} else {
|
||||
// This gives 2.0ms at least before timeout
|
||||
if ((uint8_t)(t - timer_start) >= 3) {
|
||||
isr_debug = isr_state;
|
||||
error = IBMPC_ERR_TIMEOUT;
|
||||
goto ERROR;
|
||||
|
||||
// timeout error recovery - start receiving new data
|
||||
// it seems to work somehow but may not under unstable situation
|
||||
//timer_start = t;
|
||||
//isr_state = 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
isr_state = isr_state>>1;
|
||||
if (dbit) isr_state |= 0x8000;
|
||||
|
||||
// isr_state: state of receiving data from keyboard
|
||||
//
|
||||
// This should be initialized with 0x8000 before receiving data and
|
||||
// the MSB '*1' works as marker to discrimitate between protocols.
|
||||
// It stores sampled bit at MSB after right shift on each clock falling edge.
|
||||
//
|
||||
// XT protocol has two variants of signaling; XT_IBM and XT_Clone.
|
||||
// XT_IBM uses two start bits 0 and 1 while XT_Clone uses just start bit 1.
|
||||
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol
|
||||
//
|
||||
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
// -----------------------------------------------------
|
||||
// *1 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 Initial state(0x8000)
|
||||
//
|
||||
// x x x x x x x x | 0 0 0 0 0 0 0 0 midway(0-7 bits received)
|
||||
// x x x x x x x x | *1 0 0 0 0 0 0 0 midway(8 bits received)
|
||||
// b6 b5 b4 b3 b2 b1 b0 1 | 0 *1 0 0 0 0 0 0 XT_IBM-midway ^1
|
||||
// b7 b6 b5 b4 b3 b2 b1 b0 | 0 *1 0 0 0 0 0 0 AT-midway ^1
|
||||
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 *1 0 0 0 0 0 0 XT_Clone-done ^3
|
||||
// b6 b5 b4 b3 b2 b1 b0 1 | 1 *1 0 0 0 0 0 0 XT_IBM-error ^3
|
||||
// pr b7 b6 b5 b4 b3 b2 b1 | 0 0 *1 0 0 0 0 0 AT-midway[b0=0]
|
||||
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 0 *1 0 0 0 0 0 XT_IBM-done ^2
|
||||
// pr b7 b6 b5 b4 b3 b2 b1 | 1 0 *1 0 0 0 0 0 AT-midway[b0=1] ^2
|
||||
// b7 b6 b5 b4 b3 b2 b1 b0 | 1 1 *1 0 0 0 0 0 XT_IBM-error-done
|
||||
// x x x x x x x x | 0 1 *1 0 0 0 0 0 illegal
|
||||
// st pr b7 b6 b5 b4 b3 b2 | b1 b0 0 *1 0 0 0 0 AT-done
|
||||
// x x x x x x x x | x x 1 *1 0 0 0 0 illegal
|
||||
// all other states than above illegal
|
||||
//
|
||||
// ^1: AT and XT_IBM takes same state.
|
||||
// ^2: AT and XT_IBM takes same state in case that AT b0 is 1,
|
||||
// we have to check AT stop bit to discriminate between the two protocol.
|
||||
switch (isr_state & 0xFF) {
|
||||
case 0b00000000:
|
||||
case 0b10000000:
|
||||
case 0b01000000: // ^1
|
||||
case 0b00100000:
|
||||
// midway
|
||||
goto NEXT;
|
||||
break;
|
||||
case 0b11000000: // ^3
|
||||
{
|
||||
uint8_t us = 100;
|
||||
// wait for rising and falling edge of b7 of XT_IBM
|
||||
if (!protocol) {
|
||||
while (!(IBMPC_CLOCK_PIN & clock_mask) && us) { wait_us(1); us--; }
|
||||
while ( (IBMPC_CLOCK_PIN & clock_mask) && us) { wait_us(1); us--; }
|
||||
} else if (protocol == IBMPC_PROTOCOL_XT_CLONE) {
|
||||
us = 0;
|
||||
}
|
||||
|
||||
if (us) {
|
||||
// XT_IBM-error: read start(0) as 1
|
||||
goto NEXT;
|
||||
} else {
|
||||
// XT_Clone-done
|
||||
isr_debug = isr_state;
|
||||
isr_state = isr_state>>8;
|
||||
protocol = IBMPC_PROTOCOL_XT_CLONE;
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0b11100000:
|
||||
// XT_IBM-error-done
|
||||
isr_debug = isr_state;
|
||||
isr_state = isr_state>>8;
|
||||
protocol = IBMPC_PROTOCOL_XT_ERROR;
|
||||
goto DONE;
|
||||
break;
|
||||
case 0b10100000: // ^2
|
||||
{
|
||||
uint8_t us = 100;
|
||||
// wait for rising and falling edge of AT stop bit to discriminate between XT and AT
|
||||
if (!protocol) {
|
||||
while (!(IBMPC_CLOCK_PIN & clock_mask) && us) { wait_us(1); us--; }
|
||||
while ( (IBMPC_CLOCK_PIN & clock_mask) && us) { wait_us(1); us--; }
|
||||
} else if (protocol == IBMPC_PROTOCOL_XT_IBM) {
|
||||
us = 0;
|
||||
}
|
||||
|
||||
if (us) {
|
||||
// found stop bit: AT-midway - process the stop bit in next ISR
|
||||
goto NEXT;
|
||||
} else {
|
||||
// no stop bit: XT_IBM-done
|
||||
isr_debug = isr_state;
|
||||
isr_state = isr_state>>8;
|
||||
protocol = IBMPC_PROTOCOL_XT_IBM;
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0b00010000:
|
||||
case 0b10010000:
|
||||
case 0b01010000:
|
||||
case 0b11010000:
|
||||
// AT-done
|
||||
// TODO: parity check?
|
||||
isr_debug = isr_state;
|
||||
// stop bit check
|
||||
if (isr_state & 0x8000) {
|
||||
protocol = IBMPC_PROTOCOL_AT;
|
||||
} else {
|
||||
// Zenith Z-150 AT(beige/white lable) asserts stop bit as low
|
||||
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-AT-Keyboard-Protocol#zenith-z-150-beige
|
||||
protocol = IBMPC_PROTOCOL_AT_Z150;
|
||||
}
|
||||
isr_state = isr_state>>6;
|
||||
goto DONE;
|
||||
break;
|
||||
case 0b01100000:
|
||||
case 0b00110000:
|
||||
case 0b10110000:
|
||||
case 0b01110000:
|
||||
case 0b11110000:
|
||||
default: // xxxx_oooo(any 1 in low nibble)
|
||||
// Illegal
|
||||
protocol = 0;
|
||||
isr_debug = isr_state;
|
||||
error = IBMPC_ERR_ILLEGAL;
|
||||
goto ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
DONE:
|
||||
// store data
|
||||
ringbuf_put(isr_state & 0xFF);
|
||||
if (ringbuf_is_full()) {
|
||||
// Disable ISR if buffer is full
|
||||
int_off();
|
||||
// inhibit: clock_lo() instead of inhibit() for ISR optimization
|
||||
clock_lo();
|
||||
}
|
||||
if (ringbuf_is_empty()) {
|
||||
// buffer overflow
|
||||
error = IBMPC_ERR_FULL;
|
||||
}
|
||||
ERROR:
|
||||
// clear for next data
|
||||
isr_state = 0x8000;
|
||||
NEXT:
|
||||
return;
|
||||
}
|
||||
|
||||
/* send LED state to keyboard */
|
||||
void IBMPC::host_set_led(uint8_t led)
|
||||
{
|
||||
if (0xFA == host_send(0xED)) {
|
||||
host_send(led);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE: With this ISR data line should be read within 5us after clock falling edge.
|
||||
// Confirmed that ATmega32u4 can read data line in 2.5us from interrupt after
|
||||
// ISR prologue pushs r18, r19, r20, r21, r24, r25 r30 and r31 with GCC 5.4.0
|
||||
ISR(IBMPC_INT_VECT)
|
||||
{
|
||||
IBMPC::interface0.isr();
|
||||
}
|
||||
|
||||
#if defined(IBMPC_CLOCK_BIT1) && defined(IBMPC_DATA_BIT1) && defined(IBMPC_INT_VECT1)
|
||||
ISR(IBMPC_INT_VECT1)
|
||||
{
|
||||
IBMPC::interface1.isr();
|
||||
}
|
||||
#endif
|
||||
276
tmk_core/protocol/ibmpc.hpp
Normal file
276
tmk_core/protocol/ibmpc.hpp
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
Copyright 2010,2011,2012,2013,2019 Jun WAKO <wakojun@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IBMPC_HPP
|
||||
#define IBMPC_HPP
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "wait.h"
|
||||
|
||||
/*
|
||||
* IBM PC keyboard protocol
|
||||
*
|
||||
* PS/2 Resources
|
||||
* --------------
|
||||
* [1] The PS/2 Mouse/Keyboard Protocol
|
||||
* http://www.computer-engineering.org/ps2protocol/
|
||||
* Concise and thorough primer of PS/2 protocol.
|
||||
*
|
||||
* [2] Keyboard and Auxiliary Device Controller
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
|
||||
* Signal Timing and Format
|
||||
*
|
||||
* [3] Keyboards(101- and 102-key)
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
|
||||
* Keyboard Layout, Scan Code Set, POR, and Commands.
|
||||
*
|
||||
* [4] PS/2 Reference Manuals
|
||||
* http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
|
||||
* Collection of IBM Personal System/2 documents.
|
||||
*
|
||||
* [5] TrackPoint Engineering Specifications for version 3E
|
||||
* https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
|
||||
*/
|
||||
#define IBMPC_ACK 0xFA
|
||||
#define IBMPC_RESEND 0xFE
|
||||
#define IBMPC_SET_LED 0xED
|
||||
|
||||
#define IBMPC_PROTOCOL_NO 0
|
||||
#define IBMPC_PROTOCOL_AT 0x10
|
||||
#define IBMPC_PROTOCOL_AT_Z150 0x11
|
||||
#define IBMPC_PROTOCOL_XT 0x20
|
||||
#define IBMPC_PROTOCOL_XT_IBM 0x21
|
||||
#define IBMPC_PROTOCOL_XT_CLONE 0x22
|
||||
#define IBMPC_PROTOCOL_XT_ERROR 0x23
|
||||
|
||||
// Error numbers
|
||||
#define IBMPC_ERR_NONE 0
|
||||
#define IBMPC_ERR_RECV 0x00
|
||||
#define IBMPC_ERR_SEND 0x10
|
||||
#define IBMPC_ERR_TIMEOUT 0x20
|
||||
#define IBMPC_ERR_FULL 0x40
|
||||
#define IBMPC_ERR_ILLEGAL 0x80
|
||||
#define IBMPC_ERR_FF 0xF0
|
||||
|
||||
#define IBMPC_LED_SCROLL_LOCK 0
|
||||
#define IBMPC_LED_NUM_LOCK 1
|
||||
#define IBMPC_LED_CAPS_LOCK 2
|
||||
|
||||
|
||||
class IBMPC
|
||||
{
|
||||
public:
|
||||
static IBMPC interface0;
|
||||
#if defined(IBMPC_CLOCK_BIT1) && defined(IBMPC_DATA_BIT1)
|
||||
static IBMPC interface1;
|
||||
#endif
|
||||
|
||||
volatile uint16_t isr_debug;
|
||||
volatile uint8_t protocol;
|
||||
volatile uint8_t error;
|
||||
|
||||
void host_init(void);
|
||||
void host_enable(void);
|
||||
void host_disable(void);
|
||||
int16_t host_send(uint8_t data);
|
||||
int16_t host_recv_response(void);
|
||||
int16_t host_recv(void);
|
||||
void host_isr_clear(void);
|
||||
void host_set_led(uint8_t led);
|
||||
|
||||
IBMPC(uint8_t clock, uint8_t data) :
|
||||
isr_debug(IBMPC_ERR_NONE), protocol(IBMPC_PROTOCOL_NO), error(IBMPC_ERR_NONE),
|
||||
isr_state(0x8000), timer_start(0), clock_bit(clock), data_bit(data),
|
||||
clock_mask(1 << clock), data_mask(1 << data) {
|
||||
};
|
||||
|
||||
inline void isr(void) __attribute__((__always_inline__));
|
||||
|
||||
|
||||
private:
|
||||
volatile uint16_t isr_state;
|
||||
uint8_t timer_start;
|
||||
|
||||
/* ring buffer */
|
||||
// Size should be power of 2
|
||||
#define RINGBUF_SIZE 16
|
||||
uint8_t rb_head;
|
||||
uint8_t rb_tail;
|
||||
uint8_t rb_buffer[RINGBUF_SIZE];
|
||||
|
||||
const uint8_t clock_bit, data_bit;
|
||||
const uint8_t clock_mask, data_mask;
|
||||
|
||||
|
||||
inline void clock_lo(void) __attribute__((__always_inline__)) // needed for ISR optimization
|
||||
{
|
||||
IBMPC_CLOCK_PORT &= ~clock_mask;
|
||||
IBMPC_CLOCK_DDR |= clock_mask;
|
||||
}
|
||||
|
||||
inline void clock_hi(void)
|
||||
{
|
||||
/* input with pull up */
|
||||
IBMPC_CLOCK_DDR &= ~clock_mask;
|
||||
IBMPC_CLOCK_PORT |= clock_mask;
|
||||
}
|
||||
|
||||
inline bool clock_in(void)
|
||||
{
|
||||
IBMPC_CLOCK_DDR &= ~clock_mask;
|
||||
IBMPC_CLOCK_PORT |= clock_mask;
|
||||
wait_us(1);
|
||||
return IBMPC_CLOCK_PIN & clock_mask;
|
||||
}
|
||||
|
||||
inline void data_lo(void)
|
||||
{
|
||||
IBMPC_DATA_PORT &= ~data_mask;
|
||||
IBMPC_DATA_DDR |= data_mask;
|
||||
}
|
||||
|
||||
inline void data_hi(void)
|
||||
{
|
||||
/* input with pull up */
|
||||
IBMPC_DATA_DDR &= ~data_mask;
|
||||
IBMPC_DATA_PORT |= data_mask;
|
||||
}
|
||||
|
||||
inline bool data_in(void)
|
||||
{
|
||||
IBMPC_DATA_DDR &= ~data_mask;
|
||||
IBMPC_DATA_PORT |= data_mask;
|
||||
wait_us(1);
|
||||
return IBMPC_DATA_PIN & data_mask;
|
||||
}
|
||||
|
||||
inline uint16_t wait_clock_lo(uint16_t us)
|
||||
{
|
||||
while (clock_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
inline uint16_t wait_clock_hi(uint16_t us)
|
||||
{
|
||||
while (!clock_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
inline uint16_t wait_data_lo(uint16_t us)
|
||||
{
|
||||
while (data_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
inline uint16_t wait_data_hi(uint16_t us)
|
||||
{
|
||||
while (!data_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
|
||||
/* idle state that device can send */
|
||||
inline void idle(void)
|
||||
{
|
||||
clock_hi();
|
||||
data_hi();
|
||||
}
|
||||
|
||||
/* inhibit device to send(AT), soft reset(XT) */
|
||||
inline void inhibit(void)
|
||||
{
|
||||
clock_lo();
|
||||
data_hi();
|
||||
}
|
||||
|
||||
/* inhibit device to send(XT) */
|
||||
inline void inhibit_xt(void)
|
||||
{
|
||||
clock_hi();
|
||||
data_lo();
|
||||
}
|
||||
|
||||
void int_init(void)
|
||||
{
|
||||
// interrupt at falling edge
|
||||
if (clock_bit < 4) {
|
||||
EICRA |= (0x2 << ((clock_bit&0x3)*2));
|
||||
} else {
|
||||
EICRB |= (0x2 << ((clock_bit&0x3)*2));
|
||||
}
|
||||
}
|
||||
|
||||
void int_on(void)
|
||||
{
|
||||
EIFR |= clock_mask;
|
||||
EIMSK |= clock_mask;
|
||||
}
|
||||
|
||||
inline void int_off(void) __attribute__((__always_inline__)) // needed for ISR optimization
|
||||
{
|
||||
EIMSK &= ~clock_mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* ring buffer
|
||||
*/
|
||||
inline int16_t ringbuf_get(void) __attribute__((__always_inline__))
|
||||
{
|
||||
if (ringbuf_is_empty()) return -1;
|
||||
uint8_t data = rb_buffer[rb_tail];
|
||||
rb_tail++;
|
||||
rb_tail &= (RINGBUF_SIZE - 1);
|
||||
return data;
|
||||
}
|
||||
inline void ringbuf_put(uint8_t data) __attribute__((__always_inline__))
|
||||
{
|
||||
rb_buffer[rb_head] = data;
|
||||
rb_head++;
|
||||
rb_head &= (RINGBUF_SIZE - 1);
|
||||
}
|
||||
inline bool ringbuf_is_empty(void) __attribute__((__always_inline__))
|
||||
{
|
||||
return (rb_head == rb_tail);
|
||||
}
|
||||
inline bool ringbuf_is_full(void) __attribute__((__always_inline__))
|
||||
{
|
||||
return (((rb_head + 1) & (RINGBUF_SIZE - 1)) == rb_tail);
|
||||
}
|
||||
inline void ringbuf_reset(void) __attribute__((__always_inline__))
|
||||
{
|
||||
rb_head = 0;
|
||||
rb_tail = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -4,6 +4,10 @@ TMK_LUFA_DIR = protocol/lufa
|
|||
TMK_LUFA_PATH ?= $(TMK_LUFA_DIR)/lufa-abcminiuser
|
||||
|
||||
|
||||
# Version string
|
||||
TMK_LUFA_VERSION := $(shell (cd $(TMK_DIR)/$(TMK_LUFA_PATH); git rev-parse --short=6 HEAD || echo 'unknown') 2> /dev/null)
|
||||
OPT_DEFS += -DTMK_LUFA_VERSION=$(TMK_LUFA_VERSION)
|
||||
|
||||
# Create the LUFA source path variables by including the LUFA makefile
|
||||
ifneq (, $(wildcard $(TMK_DIR)/$(TMK_LUFA_PATH)/LUFA/Build/LUFA/lufa-sources.mk))
|
||||
LUFA_PATH = $(TMK_LUFA_PATH)/LUFA
|
||||
|
|
|
|||
|
|
@ -44,8 +44,11 @@
|
|||
/*******************************************************************************
|
||||
* HID Report Descriptors
|
||||
******************************************************************************/
|
||||
#ifndef NO_KEYBOARD
|
||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
||||
{
|
||||
#ifndef NKRO_ENABLE
|
||||
/* 6KRO - Boot protocol */
|
||||
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
|
||||
HID_RI_USAGE(8, 0x06), /* Keyboard */
|
||||
HID_RI_COLLECTION(8, 0x01), /* Application */
|
||||
|
|
@ -81,17 +84,55 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
|||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
};
|
||||
#else
|
||||
/* NKRO - Report protocol */
|
||||
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
|
||||
HID_RI_USAGE(8, 0x06), /* Keyboard */
|
||||
HID_RI_COLLECTION(8, 0x01), /* Application */
|
||||
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
|
||||
HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
|
||||
HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
|
||||
HID_RI_REPORT_COUNT(8, 0x08),
|
||||
HID_RI_REPORT_SIZE(8, 0x01),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
|
||||
HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
|
||||
HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
|
||||
HID_RI_REPORT_COUNT(8, 0x05),
|
||||
HID_RI_REPORT_SIZE(8, 0x01),
|
||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
|
||||
HID_RI_REPORT_COUNT(8, 0x01),
|
||||
HID_RI_REPORT_SIZE(8, 0x03),
|
||||
HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
|
||||
|
||||
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
|
||||
HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
|
||||
HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
|
||||
HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
|
||||
HID_RI_REPORT_SIZE(8, 0x01),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
|
||||
{
|
||||
#ifdef MOUSE_ENABLE
|
||||
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
|
||||
HID_RI_USAGE(8, 0x02), /* Mouse */
|
||||
HID_RI_COLLECTION(8, 0x01), /* Application */
|
||||
HID_RI_USAGE(8, 0x01), /* Pointer */
|
||||
HID_RI_COLLECTION(8, 0x00), /* Physical */
|
||||
|
||||
HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
|
||||
|
||||
HID_RI_USAGE_PAGE(8, 0x09), /* Button */
|
||||
HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */
|
||||
HID_RI_USAGE_MAXIMUM(8, 0x08), /* Button 8 */
|
||||
|
|
@ -147,12 +188,9 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
|
|||
|
||||
HID_RI_END_COLLECTION(0),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
|
||||
{
|
||||
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
|
||||
HID_RI_USAGE(8, 0x80), /* System Control */
|
||||
HID_RI_COLLECTION(8, 0x01), /* Application */
|
||||
|
|
@ -178,6 +216,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
|
|||
HID_RI_REPORT_COUNT(8, 1),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
@ -203,7 +242,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
|
||||
const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
|
||||
{
|
||||
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
|
||||
|
|
@ -289,6 +328,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
|||
/*
|
||||
* Keyboard
|
||||
*/
|
||||
#ifndef NO_KEYBOARD
|
||||
.Keyboard_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
|
@ -322,14 +362,20 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
|||
|
||||
.EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
#ifdef NKRO_ENABLE
|
||||
.EndpointSize = NKRO_EPSIZE,
|
||||
.PollingIntervalMS = 0x01
|
||||
#else
|
||||
.EndpointSize = KEYBOARD_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mouse
|
||||
*/
|
||||
#ifdef MOUSE_ENABLE
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
.Mouse_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
|
@ -340,8 +386,13 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
|||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = HID_CSCP_HIDClass,
|
||||
#if defined(MOUSE_ENABLE)
|
||||
.SubClass = HID_CSCP_BootSubclass,
|
||||
.Protocol = HID_CSCP_MouseBootProtocol,
|
||||
#else
|
||||
.SubClass = HID_CSCP_NonBootSubclass,
|
||||
.Protocol = HID_CSCP_NonBootProtocol,
|
||||
#endif
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
|
@ -364,49 +415,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
|||
.EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MOUSE_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
},
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Extra
|
||||
*/
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
.Extrakey_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = EXTRAKEY_INTERFACE,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = HID_CSCP_HIDClass,
|
||||
.SubClass = HID_CSCP_NonBootSubclass,
|
||||
.Protocol = HID_CSCP_NonBootProtocol,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Extrakey_HID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(1,1,1),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = HID_DTYPE_Report,
|
||||
.HIDReportLength = sizeof(ExtrakeyReport)
|
||||
},
|
||||
|
||||
.Extrakey_INEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = EXTRAKEY_EPSIZE,
|
||||
.PollingIntervalMS = 0x0A
|
||||
.PollingIntervalMS = 0x01
|
||||
},
|
||||
#endif
|
||||
|
||||
|
|
@ -465,7 +474,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
|||
/*
|
||||
* NKRO
|
||||
*/
|
||||
#ifdef NKRO_ENABLE
|
||||
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
|
||||
.NKRO_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
|
@ -578,29 +587,25 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
|||
break;
|
||||
case HID_DTYPE_HID:
|
||||
switch (wIndex) {
|
||||
#ifndef NO_KEYBOARD
|
||||
case KEYBOARD_INTERFACE:
|
||||
Address = &ConfigurationDescriptor.Keyboard_HID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
break;
|
||||
#ifdef MOUSE_ENABLE
|
||||
#endif
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
case MOUSE_INTERFACE:
|
||||
Address = &ConfigurationDescriptor.Mouse_HID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
break;
|
||||
#endif
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
case EXTRAKEY_INTERFACE:
|
||||
Address = &ConfigurationDescriptor.Extrakey_HID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONSOLE_ENABLE
|
||||
case CONSOLE_INTERFACE:
|
||||
Address = &ConfigurationDescriptor.Console_HID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
break;
|
||||
#endif
|
||||
#ifdef NKRO_ENABLE
|
||||
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
|
||||
case NKRO_INTERFACE:
|
||||
Address = &ConfigurationDescriptor.NKRO_HID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
|
|
@ -610,29 +615,25 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
|||
break;
|
||||
case HID_DTYPE_Report:
|
||||
switch (wIndex) {
|
||||
#ifndef NO_KEYBOARD
|
||||
case KEYBOARD_INTERFACE:
|
||||
Address = &KeyboardReport;
|
||||
Size = sizeof(KeyboardReport);
|
||||
break;
|
||||
#ifdef MOUSE_ENABLE
|
||||
#endif
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
case MOUSE_INTERFACE:
|
||||
Address = &MouseReport;
|
||||
Size = sizeof(MouseReport);
|
||||
break;
|
||||
#endif
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
case EXTRAKEY_INTERFACE:
|
||||
Address = &ExtrakeyReport;
|
||||
Size = sizeof(ExtrakeyReport);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONSOLE_ENABLE
|
||||
case CONSOLE_INTERFACE:
|
||||
Address = &ConsoleReport;
|
||||
Size = sizeof(ConsoleReport);
|
||||
break;
|
||||
#endif
|
||||
#ifdef NKRO_ENABLE
|
||||
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
|
||||
case NKRO_INTERFACE:
|
||||
Address = &NKROReport;
|
||||
Size = sizeof(NKROReport);
|
||||
|
|
|
|||
|
|
@ -52,25 +52,20 @@ typedef struct
|
|||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
// Keyboard HID Interface
|
||||
USB_Descriptor_Interface_t Keyboard_Interface;
|
||||
USB_HID_Descriptor_HID_t Keyboard_HID;
|
||||
USB_Descriptor_Endpoint_t Keyboard_INEndpoint;
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
// Mouse HID Interface
|
||||
USB_Descriptor_Interface_t Mouse_Interface;
|
||||
USB_HID_Descriptor_HID_t Mouse_HID;
|
||||
USB_Descriptor_Endpoint_t Mouse_INEndpoint;
|
||||
#endif
|
||||
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
// Extrakey HID Interface
|
||||
USB_Descriptor_Interface_t Extrakey_Interface;
|
||||
USB_HID_Descriptor_HID_t Extrakey_HID;
|
||||
USB_Descriptor_Endpoint_t Extrakey_INEndpoint;
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
// Console HID Interface
|
||||
USB_Descriptor_Interface_t Console_Interface;
|
||||
|
|
@ -79,7 +74,7 @@ typedef struct
|
|||
USB_Descriptor_Endpoint_t Console_OUTEndpoint;
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
|
||||
// NKRO HID Interface
|
||||
USB_Descriptor_Interface_t NKRO_Interface;
|
||||
USB_HID_Descriptor_HID_t NKRO_HID;
|
||||
|
|
@ -89,27 +84,25 @@ typedef struct
|
|||
|
||||
|
||||
/* index of interface */
|
||||
#define KEYBOARD_INTERFACE 0
|
||||
#ifndef NO_KEYBOARD
|
||||
# define KEYBOARD_INTERFACE 0
|
||||
#else
|
||||
# define KEYBOARD_INTERFACE -1
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
# define MOUSE_INTERFACE (KEYBOARD_INTERFACE + 1)
|
||||
#else
|
||||
# define MOUSE_INTERFACE KEYBOARD_INTERFACE
|
||||
#endif
|
||||
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
# define EXTRAKEY_INTERFACE (MOUSE_INTERFACE + 1)
|
||||
#else
|
||||
# define EXTRAKEY_INTERFACE MOUSE_INTERFACE
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
# define CONSOLE_INTERFACE (EXTRAKEY_INTERFACE + 1)
|
||||
# define CONSOLE_INTERFACE (MOUSE_INTERFACE + 1)
|
||||
#else
|
||||
# define CONSOLE_INTERFACE EXTRAKEY_INTERFACE
|
||||
# define CONSOLE_INTERFACE MOUSE_INTERFACE
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
|
||||
# define NKRO_INTERFACE (CONSOLE_INTERFACE + 1)
|
||||
#else
|
||||
# define NKRO_INTERFACE CONSOLE_INTERFACE
|
||||
|
|
@ -121,28 +114,26 @@ typedef struct
|
|||
|
||||
|
||||
// Endopoint number and size
|
||||
#define KEYBOARD_IN_EPNUM 1
|
||||
#ifndef NO_KEYBOARD
|
||||
# define KEYBOARD_IN_EPNUM 1
|
||||
#else
|
||||
# define KEYBOARD_IN_EPNUM 0
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
# define MOUSE_IN_EPNUM (KEYBOARD_IN_EPNUM + 1)
|
||||
#else
|
||||
# define MOUSE_IN_EPNUM KEYBOARD_IN_EPNUM
|
||||
#endif
|
||||
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
# define EXTRAKEY_IN_EPNUM (MOUSE_IN_EPNUM + 1)
|
||||
#else
|
||||
# define EXTRAKEY_IN_EPNUM MOUSE_IN_EPNUM
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
# define CONSOLE_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1)
|
||||
# define CONSOLE_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 1)
|
||||
# define CONSOLE_IN_EPNUM (MOUSE_IN_EPNUM + 1)
|
||||
# define CONSOLE_OUT_EPNUM (MOUSE_IN_EPNUM + 1)
|
||||
#else
|
||||
# define CONSOLE_OUT_EPNUM EXTRAKEY_IN_EPNUM
|
||||
# define CONSOLE_OUT_EPNUM MOUSE_IN_EPNUM
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#if !defined(NO_KEYBOARD) && defined(NKRO_6KRO_ENABLE)
|
||||
# define NKRO_IN_EPNUM (CONSOLE_OUT_EPNUM + 1)
|
||||
#else
|
||||
# define NKRO_IN_EPNUM CONSOLE_OUT_EPNUM
|
||||
|
|
@ -150,13 +141,18 @@ typedef struct
|
|||
|
||||
/* Check number of endpoints. ATmega32u2 has only four except for control endpoint. */
|
||||
#if defined(__AVR_ATmega32U2__) && NKRO_IN_EPNUM > 4
|
||||
# error "Endpoints are not available enough to support all functions. Disable some of build options in Makefile.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO)"
|
||||
# error "Endpoints are not available enough to support all functions. Disable some of build options in Makefile.(MOUSEKEY, CONSOLE, NKRO)"
|
||||
#endif
|
||||
|
||||
|
||||
#define KEYBOARD_EPSIZE 8
|
||||
|
||||
#if defined(MOUSE_EXT_REPORT)
|
||||
#define MOUSE_EPSIZE 10
|
||||
#else
|
||||
#define MOUSE_EPSIZE 8
|
||||
#define EXTRAKEY_EPSIZE 8
|
||||
#endif
|
||||
|
||||
#define CONSOLE_EPSIZE 32
|
||||
#define NKRO_EPSIZE 32
|
||||
|
||||
|
|
|
|||
|
|
@ -68,26 +68,35 @@
|
|||
//#define TMK_LUFA_DEBUG
|
||||
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
uint8_t keyboard_idle = 0;
|
||||
/* 0: Boot Protocol, 1: Report Protocol(default) */
|
||||
uint8_t keyboard_protocol = 1;
|
||||
static uint8_t keyboard_led_stats = 0;
|
||||
|
||||
static report_keyboard_t keyboard_report_sent;
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
uint8_t mouse_protocol = 1;
|
||||
#endif
|
||||
|
||||
|
||||
/* Host driver */
|
||||
#ifndef NO_KEYBOARD
|
||||
static uint8_t keyboard_leds(void);
|
||||
static void send_keyboard(report_keyboard_t *report);
|
||||
#endif
|
||||
static void send_mouse(report_mouse_t *report);
|
||||
static void send_system(uint16_t data);
|
||||
static void send_consumer(uint16_t data);
|
||||
host_driver_t lufa_driver = {
|
||||
keyboard_leds,
|
||||
send_keyboard,
|
||||
send_mouse,
|
||||
send_system,
|
||||
send_consumer
|
||||
#ifndef NO_KEYBOARD
|
||||
.keyboard_leds = keyboard_leds,
|
||||
.send_keyboard = send_keyboard,
|
||||
#endif
|
||||
.send_mouse = send_mouse,
|
||||
.send_system = send_system,
|
||||
.send_consumer = send_consumer
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -327,22 +336,23 @@ void EVENT_USB_Device_ConfigurationChanged(void)
|
|||
#endif
|
||||
bool ConfigSuccess = true;
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
/* Setup Keyboard HID Report Endpoints */
|
||||
ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
|
||||
KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
|
||||
#ifdef NKRO_ENABLE
|
||||
NKRO_EPSIZE,
|
||||
#else
|
||||
KEYBOARD_EPSIZE,
|
||||
#endif
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||
/* Setup Mouse HID Report Endpoint */
|
||||
ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
|
||||
MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
|
||||
#endif
|
||||
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
/* Setup Extra HID Report Endpoint */
|
||||
ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
|
||||
EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
/* Setup Console HID Report Endpoints */
|
||||
ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
|
||||
|
|
@ -353,7 +363,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#ifdef NKRO_6KRO_ENABLE
|
||||
/* Setup NKRO HID Report Endpoints */
|
||||
ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
|
||||
NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
|
||||
|
|
@ -378,15 +388,16 @@ Other Device Required Optional Optional Optional Optional Opti
|
|||
*/
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
uint8_t* ReportData = NULL;
|
||||
uint8_t ReportSize = 0;
|
||||
|
||||
/* Handle HID Class specific requests */
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case HID_REQ_GetReport:
|
||||
#ifndef NO_KEYBOARD
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
uint8_t* ReportData = NULL;
|
||||
uint8_t ReportSize = 0;
|
||||
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
// Interface
|
||||
|
|
@ -405,6 +416,7 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
xprintf("[r%d]", USB_ControlRequest.wIndex);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case HID_REQ_SetReport:
|
||||
|
|
@ -413,8 +425,9 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
|
||||
// Interface
|
||||
switch (USB_ControlRequest.wIndex) {
|
||||
#ifndef NO_KEYBOARD
|
||||
case KEYBOARD_INTERFACE:
|
||||
#ifdef NKRO_ENABLE
|
||||
#ifdef NKRO_6KRO_ENABLE
|
||||
case NKRO_INTERFACE:
|
||||
#endif
|
||||
Endpoint_ClearSETUP();
|
||||
|
|
@ -431,6 +444,7 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
xprintf("[L%d]", USB_ControlRequest.wIndex);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -440,6 +454,7 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
case HID_REQ_GetProtocol:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
#ifndef NO_KEYBOARD
|
||||
if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
|
||||
Endpoint_ClearSETUP();
|
||||
while (!(Endpoint_IsINReady()));
|
||||
|
|
@ -450,12 +465,23 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
print("[p]");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(MOUSE_ENABLE)
|
||||
if (USB_ControlRequest.wIndex == MOUSE_INTERFACE) {
|
||||
Endpoint_ClearSETUP();
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_Write_8(mouse_protocol);
|
||||
Endpoint_ClearIN();
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_SetProtocol:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
#ifndef NO_KEYBOARD
|
||||
if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
|
@ -466,18 +492,30 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
print("[P]");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(MOUSE_ENABLE)
|
||||
if (USB_ControlRequest.wIndex == MOUSE_INTERFACE) {
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
mouse_protocol = (USB_ControlRequest.wValue & 0xFF);
|
||||
clear_keyboard();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_SetIdle:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
#ifndef NO_KEYBOARD
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
|
||||
#ifdef TMK_LUFA_DEBUG
|
||||
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -485,6 +523,7 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
case HID_REQ_GetIdle:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
#ifndef NO_KEYBOARD
|
||||
Endpoint_ClearSETUP();
|
||||
while (!(Endpoint_IsINReady()));
|
||||
Endpoint_Write_8(keyboard_idle);
|
||||
|
|
@ -492,6 +531,7 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
Endpoint_ClearStatusStage();
|
||||
#ifdef TMK_LUFA_DEBUG
|
||||
print("[i]");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -502,6 +542,7 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
/*******************************************************************************
|
||||
* Host driver
|
||||
******************************************************************************/
|
||||
#ifndef NO_KEYBOARD
|
||||
static uint8_t keyboard_leds(void)
|
||||
{
|
||||
return keyboard_led_stats;
|
||||
|
|
@ -515,10 +556,14 @@ static void send_keyboard(report_keyboard_t *report)
|
|||
return;
|
||||
|
||||
/* Select the Keyboard Report Endpoint */
|
||||
#ifdef NKRO_ENABLE
|
||||
#if defined(NKRO_ENABLE) || defined(NKRO_6KRO_ENABLE)
|
||||
if (keyboard_protocol && keyboard_nkro) {
|
||||
/* Report protocol - NKRO */
|
||||
#if defined(NKRO_6KRO_ENABLE)
|
||||
Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
|
||||
#else
|
||||
Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
|
||||
#endif
|
||||
|
||||
/* Check if write ready for a polling interval around 1ms */
|
||||
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(8);
|
||||
|
|
@ -546,6 +591,7 @@ static void send_keyboard(report_keyboard_t *report)
|
|||
|
||||
keyboard_report_sent = *report;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void send_mouse(report_mouse_t *report)
|
||||
{
|
||||
|
|
@ -563,7 +609,14 @@ static void send_mouse(report_mouse_t *report)
|
|||
if (!Endpoint_IsReadWriteAllowed()) return;
|
||||
|
||||
/* Write Mouse Report Data */
|
||||
Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
|
||||
if (mouse_protocol) {
|
||||
// Report
|
||||
Endpoint_Write_8(REPORT_ID_MOUSE);
|
||||
Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
|
||||
} else {
|
||||
// Boot
|
||||
Endpoint_Write_Stream_LE(report, 3, NULL);
|
||||
}
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
|
@ -578,11 +631,13 @@ static void send_system(uint16_t data)
|
|||
if (USB_DeviceState != DEVICE_STATE_Configured)
|
||||
return;
|
||||
|
||||
report_extra_t r = {
|
||||
.report_id = REPORT_ID_SYSTEM,
|
||||
.usage = data - SYSTEM_POWER_DOWN + 1
|
||||
};
|
||||
Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
|
||||
report_extra_t r = { .report_id = REPORT_ID_SYSTEM };
|
||||
if (data < SYSTEM_POWER_DOWN) {
|
||||
r.usage = 0;
|
||||
} else {
|
||||
r.usage = data - SYSTEM_POWER_DOWN + 1;
|
||||
}
|
||||
Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
|
||||
|
||||
/* Check if write ready for a polling interval around 10ms */
|
||||
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
|
||||
|
|
@ -605,7 +660,7 @@ static void send_consumer(uint16_t data)
|
|||
.report_id = REPORT_ID_CONSUMER,
|
||||
.usage = data
|
||||
};
|
||||
Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
|
||||
Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
|
||||
|
||||
/* Check if write ready for a polling interval around 10ms */
|
||||
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
|
||||
|
|
@ -677,17 +732,32 @@ int main(void)
|
|||
print_set_sendchar(sendchar);
|
||||
host_set_driver(&lufa_driver);
|
||||
|
||||
print("\n\nTMK:" STR(TMK_VERSION) "/LUFA\n\n");
|
||||
print("\nTMK:" STR(TMK_VERSION) "/LUFA:" STR(TMK_LUFA_VERSION)
|
||||
#ifdef TMK_USB_HOST_SHIELD_VERSION
|
||||
"/UHS2:" STR(TMK_USB_HOST_SHIELD_VERSION)
|
||||
#endif
|
||||
"\n");
|
||||
|
||||
hook_early_init();
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
keyboard_setup();
|
||||
#endif
|
||||
|
||||
setup_usb();
|
||||
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_init();
|
||||
#endif
|
||||
|
||||
sei();
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
keyboard_init();
|
||||
#else
|
||||
// TODO: keyboard_init() should be used only for things related to keyboard
|
||||
timer_init();
|
||||
#endif
|
||||
|
||||
#ifndef NO_USB_STARTUP_WAIT_LOOP
|
||||
/* wait for USB startup */
|
||||
|
|
@ -704,7 +774,7 @@ int main(void)
|
|||
|
||||
hook_late_init();
|
||||
|
||||
print("\nKeyboard start.\n");
|
||||
print("\nLoop start.\n");
|
||||
while (1) {
|
||||
#ifndef NO_USB_SUSPEND_LOOP
|
||||
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
||||
|
|
@ -712,7 +782,11 @@ int main(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
hook_main_loop();
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
keyboard_task();
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
console_task();
|
||||
|
|
@ -732,10 +806,13 @@ void hook_early_init(void) {}
|
|||
__attribute__((weak))
|
||||
void hook_late_init(void) {}
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
static uint8_t _led_stats = 0;
|
||||
#endif
|
||||
__attribute__((weak))
|
||||
void hook_usb_suspend_entry(void)
|
||||
{
|
||||
#ifndef NO_KEYBOARD
|
||||
// Turn off LED to save power and keep its status to resotre it later.
|
||||
// LED status will be updated by keyboard_task() in main loop hopefully.
|
||||
_led_stats = keyboard_led_stats;
|
||||
|
|
@ -745,6 +822,7 @@ void hook_usb_suspend_entry(void)
|
|||
|
||||
matrix_clear();
|
||||
clear_keyboard();
|
||||
#endif
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_enable();
|
||||
#endif
|
||||
|
|
@ -770,8 +848,10 @@ void hook_usb_wakeup(void)
|
|||
sleep_led_disable();
|
||||
#endif
|
||||
|
||||
#ifndef NO_KEYBOARD
|
||||
// Restore LED status and update at keyboard_task() in main loop
|
||||
keyboard_led_stats = _led_stats;
|
||||
#endif
|
||||
|
||||
// Calling long task here can prevent USB state transition
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ USB_HOST_SHIELD_SRC = \
|
|||
$(USB_HOST_SHIELD_DIR)/parsetools.cpp \
|
||||
$(USB_HOST_SHIELD_DIR)/message.cpp
|
||||
|
||||
# Version string
|
||||
TMK_USB_HOST_SHIELD_VERSION := $(shell (cd $(TMK_DIR)/$(USB_HOST_SHIELD_DIR); git rev-parse --short=6 HEAD || echo 'unknown') 2> /dev/null)
|
||||
OPT_DEFS += -DTMK_USB_HOST_SHIELD_VERSION=$(TMK_USB_HOST_SHIELD_VERSION)
|
||||
|
||||
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b6128f252700a8dd2d12400c55680ef67cdcac86
|
||||
Subproject commit 96112d43858b5c5327565c36bd8ea2192ec77d1b
|
||||
|
|
@ -51,8 +51,10 @@ size_t Serial_::write(uint8_t c)
|
|||
|
||||
size_t Serial_::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
sendchar(*buffer);
|
||||
return 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
sendchar(buffer[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
Serial_::operator bool() {
|
||||
|
|
|
|||
|
|
@ -334,10 +334,10 @@ MSG_CREATING_LIBRARY = Creating library:
|
|||
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(patsubst %.cpp,$(OBJDIR)/%.o,$(patsubst %.S,$(OBJDIR)/%.o,$(SRC))))
|
||||
OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(patsubst %.cpp,$(OBJDIR)/%.cpp.o,$(patsubst %.S,$(OBJDIR)/%.o,$(SRC))))
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(patsubst %.c,$(OBJDIR)/%.lst,$(patsubst %.cpp,$(OBJDIR)/%.lst,$(patsubst %.S,$(OBJDIR)/%.lst,$(SRC))))
|
||||
LST = $(patsubst %.c,$(OBJDIR)/%.lst,$(patsubst %.cpp,$(OBJDIR)/%.cpp.lst,$(patsubst %.S,$(OBJDIR)/%.lst,$(SRC))))
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
|
|
@ -348,9 +348,9 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(subst /,_,$@).d
|
|||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
# You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar
|
||||
ALL_CFLAGS = -mmcu=$(MCU) $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
|
||||
ALL_CPPFLAGS = -mmcu=$(MCU) -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)
|
||||
ALL_CFLAGS = -mmcu=$(MCU) $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) $(EXTRACFLAGS)
|
||||
ALL_CPPFLAGS = -mmcu=$(MCU) -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) $(EXTRACPPFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) $(EXTRAASFLAGS)
|
||||
|
||||
|
||||
|
||||
|
|
@ -561,7 +561,7 @@ $(OBJDIR)/%.o : %.c
|
|||
|
||||
|
||||
# Compile: create object files from C++ source files.
|
||||
$(OBJDIR)/%.o : %.cpp
|
||||
$(OBJDIR)/%.cpp.o : %.cpp
|
||||
@echo
|
||||
mkdir -p $(@D)
|
||||
@echo $(MSG_COMPILING_CPP) $<
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue