Squashed 'tmk_core/' changes from 8da1898..e5f9940
e5f9940 Merge commit '1bc3dd200b023cecf063a0cb3ba347f77f6d759d' into core_update da03c50 Add note for L/R side bit being ignored e80f3c1 Add in basic documentation for Macro system 35e8a76 core: Swap position of PEQL and PENT in unimap 00751f1 Merge pull request #406 from 39aldo39/patch-1 e50d7de V-USB remote wakeup 4340997 core: Fix typo in definition AC_g 958144d core: Debug print for system and consumer keys e7e1030 core: Fix sleep_led 0866323 core: Change matrix_init and matrix_print 0dbf73d core: Add matrix_clear() and default impl. 3202ca3 core: Add suspend mode options 4cda3aa core: Fix suspend/wake for converters #386 4e15247 core: LUFA_DEBUG_SUART for serial debug b9cf8e7 core: Fix mechanical locking supoort #390 12aa0fd Merge branch 'nemith-master' fccb3fa core: Fix OPT_DEFS for mbed build 2e2d2c8 Merge branch 'master' of github.com:leizzer/tmk_keyboard f1d3634 Change .gitignore for ChibiOS 3aab802 core: Fix build config in protocol.mk 5e43da0 core: Add short names in unimap 7a56998 core: Fix dfu wait in rules.mk 6d9c500 Merge branch 'mediakey-fix' 08382ac core: Fix 'make dfu' message 78cb04e Fix OS X Recognizing keyboard as Mouse/Tablet a114714 core: 'make dfu' waits for bootloader to start d0a8f13 core: Fix unimap UNIMAP_NO case e17abef core: Change lufa NKRO report size 16 to 32 bytes 375b20f core: Fix common.mk for build options 394fdff core: Fix unimap layout comment 912326c core: Add unimap support 00f4011 core: Fix doc/keymap.md for new keymap framework ddbd7b4 core: Add default implemenation of keymap read 671cacc core: action codes are action_t struct now b4fdb27 core: Change chibios repo directory names 7daed10 core: Fix keycode.txt 90399d7 core: Fix USB remote wakeup on ATmega32U2 #361 3677e84 usb_usb: Add multiple keyboard support 54d5b26 core: Fix Logical Maximum in report descriptor bd0d372 core: Fix LUFA report descriptor 95327b5 Merge pull request #355 from papodaca/XT 62bf548 core: change API of adb.c to accept device address 3097c9e Fix function name in host.h 836e209 Merge branch 'core_split_160522' 3918ea2 Merge commit '20b787fc12' 7f87b11 core: Add comment of register 3 of ADB ef6478a core: Add adb_host_talk() 5c665b4 update macro names in bluefruit 4f2c5bf Merge commit '71381457fa' 53a9c08 Merge pull request #321 from njbair/master f08a656 core: Fix media/consumer keys d526de8 Clean up wording in keymap example 0bb3dbb Clarify layer precedence d915c75 clarify layer documentation 72070d4 ps2_usb: Fix for VUSB configuration 170e2dc Mostly working. Is unstable, will emit bad codes after a while. c8e45b5 core: Actionmap support aabaa24 Codes appear to be detected correctly, the break codes are broken. git-subtree-dir: tmk_core git-subtree-split: e5f994033cbc8700745ac0c6d12772820492eed0
This commit is contained in:
parent
20b787fc12
commit
22b6e15a17
55 changed files with 2042 additions and 405 deletions
132
protocol/adb.c
132
protocol/adb.c
|
|
@ -60,7 +60,6 @@ static inline void place_bit1(void);
|
|||
static inline void send_byte(uint8_t data);
|
||||
static inline uint16_t wait_data_lo(uint16_t us);
|
||||
static inline uint16_t wait_data_hi(uint16_t us);
|
||||
static inline uint16_t adb_host_dev_recv(uint8_t device);
|
||||
|
||||
|
||||
void adb_host_init(void)
|
||||
|
|
@ -87,49 +86,9 @@ bool adb_host_psw(void)
|
|||
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
|
||||
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
|
||||
*/
|
||||
|
||||
// ADB Bit Cells
|
||||
//
|
||||
// bit cell time: 70-130us
|
||||
// low part of bit0: 60-70% of bit cell
|
||||
// low part of bit1: 30-40% of bit cell
|
||||
//
|
||||
// bit cell time 70us 130us
|
||||
// --------------------------------------------
|
||||
// low part of bit0 42-49 78-91
|
||||
// high part of bit0 21-28 39-52
|
||||
// low part of bit1 21-28 39-52
|
||||
// high part of bit1 42-49 78-91
|
||||
//
|
||||
//
|
||||
// bit0:
|
||||
// 70us bit cell:
|
||||
// ____________~~~~~~
|
||||
// 42-49 21-28
|
||||
//
|
||||
// 130us bit cell:
|
||||
// ____________~~~~~~
|
||||
// 78-91 39-52
|
||||
//
|
||||
// bit1:
|
||||
// 70us bit cell:
|
||||
// ______~~~~~~~~~~~~
|
||||
// 21-28 42-49
|
||||
//
|
||||
// 130us bit cell:
|
||||
// ______~~~~~~~~~~~~
|
||||
// 39-52 78-91
|
||||
//
|
||||
// [from Apple IIgs Hardware Reference Second Edition]
|
||||
|
||||
enum {
|
||||
ADDR_KEYB = 0x20,
|
||||
ADDR_MOUSE = 0x30
|
||||
};
|
||||
|
||||
uint16_t adb_host_kbd_recv(void)
|
||||
uint16_t adb_host_kbd_recv(uint8_t addr)
|
||||
{
|
||||
return adb_host_dev_recv(ADDR_KEYB);
|
||||
return adb_host_talk(addr, ADB_REG_0);
|
||||
}
|
||||
|
||||
#ifdef ADB_MOUSE_ENABLE
|
||||
|
|
@ -139,16 +98,16 @@ void adb_mouse_init(void) {
|
|||
|
||||
uint16_t adb_host_mouse_recv(void)
|
||||
{
|
||||
return adb_host_dev_recv(ADDR_MOUSE);
|
||||
return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint16_t adb_host_dev_recv(uint8_t device)
|
||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
cli();
|
||||
attention();
|
||||
send_byte(device|0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
|
||||
send_byte((addr<<4) | (ADB_CMD_TALK<<2) | reg);
|
||||
place_bit0(); // Stopbit(0)
|
||||
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
|
||||
sei();
|
||||
|
|
@ -158,20 +117,20 @@ static inline uint16_t adb_host_dev_recv(uint8_t device)
|
|||
sei();
|
||||
return 0; // No data to send
|
||||
}
|
||||
|
||||
|
||||
uint8_t n = 17; // start bit + 16 data bits
|
||||
do {
|
||||
uint8_t lo = (uint8_t) wait_data_hi(130);
|
||||
if (!lo)
|
||||
goto error;
|
||||
|
||||
|
||||
uint8_t hi = (uint8_t) wait_data_lo(lo);
|
||||
if (!hi)
|
||||
goto error;
|
||||
|
||||
|
||||
hi = lo - hi;
|
||||
lo = 130 - lo;
|
||||
|
||||
|
||||
data <<= 1;
|
||||
if (lo < hi) {
|
||||
data |= 1;
|
||||
|
|
@ -197,27 +156,27 @@ error:
|
|||
return -n;
|
||||
}
|
||||
|
||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
|
||||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l)
|
||||
{
|
||||
cli();
|
||||
attention();
|
||||
send_byte(cmd);
|
||||
send_byte((addr<<4) | (ADB_CMD_LISTEN<<2) | reg);
|
||||
place_bit0(); // Stopbit(0)
|
||||
_delay_us(200); // Tlt/Stop to Start
|
||||
place_bit1(); // Startbit(1)
|
||||
send_byte(data_h);
|
||||
send_byte(data_h);
|
||||
send_byte(data_l);
|
||||
place_bit0(); // Stopbit(0);
|
||||
sei();
|
||||
}
|
||||
|
||||
// send state of LEDs
|
||||
void adb_host_kbd_led(uint8_t led)
|
||||
void adb_host_kbd_led(uint8_t addr, uint8_t led)
|
||||
{
|
||||
// Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
|
||||
// send upper byte (not used)
|
||||
// send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
|
||||
adb_host_listen(0x2A,0,led&0x07);
|
||||
// Listen Register2
|
||||
// upper byte: not used
|
||||
// lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
|
||||
adb_host_listen(addr, 2, 0, led & 0x07);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -366,7 +325,7 @@ Commands
|
|||
|
||||
bits commands
|
||||
------------------------------------------------------
|
||||
- - - - 0 0 0 0 Send Request(reset all devices)
|
||||
- - - - 0 0 0 0 Send Reset(reset all devices)
|
||||
A A A A 0 0 0 1 Flush(reset a device)
|
||||
- - - - 0 0 1 0 Reserved
|
||||
- - - - 0 0 1 1 Reserved
|
||||
|
|
@ -375,7 +334,7 @@ Commands
|
|||
A A A A 1 1 R R Talk(read from a device)
|
||||
|
||||
The command to read keycodes from keyboard is 0x2C which
|
||||
consist of keyboard address 2 and Talk against register 0.
|
||||
consist of keyboard address 2 and Talk against register 0.
|
||||
|
||||
Address:
|
||||
2: keyboard
|
||||
|
|
@ -457,7 +416,7 @@ Keyboard Data(Register0)
|
|||
Keyboard LEDs & state of keys(Register2)
|
||||
This register hold current state of three LEDs and nine keys.
|
||||
The state of LEDs can be changed by sending Listen command.
|
||||
|
||||
|
||||
1514 . . . . . . 7 6 5 . 3 2 1 0
|
||||
| | | | | | | | | | | | | | | +- LED1(NumLock)
|
||||
| | | | | | | | | | | | | | +--- LED2(CapsLock)
|
||||
|
|
@ -474,5 +433,56 @@ Keyboard LEDs & state of keys(Register2)
|
|||
| +----------------------------- Delete
|
||||
+------------------------------- Reserved
|
||||
|
||||
Address, Handler ID and bits(Register3)
|
||||
1514131211 . . 8 7 . . . . . . 0
|
||||
| | | | | | | | | | | | | | | |
|
||||
| | | | | | | | +-+-+-+-+-+-+-+- Handler ID
|
||||
| | | | +-+-+-+----------------- Address
|
||||
| | | +------------------------- 0
|
||||
| | +--------------------------- Service request enable(1 = enabled)
|
||||
| +----------------------------- Exceptional event(alwyas 1 if not used)
|
||||
+------------------------------- 0
|
||||
|
||||
ADB Bit Cells
|
||||
bit cell time: 70-130us
|
||||
low part of bit0: 60-70% of bit cell
|
||||
low part of bit1: 30-40% of bit cell
|
||||
|
||||
bit cell time 70us 130us
|
||||
--------------------------------------------
|
||||
low part of bit0 42-49 78-91
|
||||
high part of bit0 21-28 39-52
|
||||
low part of bit1 21-28 39-52
|
||||
high part of bit1 42-49 78-91
|
||||
|
||||
|
||||
bit0:
|
||||
70us bit cell:
|
||||
____________~~~~~~
|
||||
42-49 21-28
|
||||
|
||||
130us bit cell:
|
||||
____________~~~~~~
|
||||
78-91 39-52
|
||||
|
||||
bit1:
|
||||
70us bit cell:
|
||||
______~~~~~~~~~~~~
|
||||
21-28 42-49
|
||||
|
||||
130us bit cell:
|
||||
______~~~~~~~~~~~~
|
||||
39-52 78-91
|
||||
|
||||
[from Apple IIgs Hardware Reference Second Edition]
|
||||
|
||||
Keyboard Handle ID
|
||||
Apple Standard Keyboard M0116: 0x01
|
||||
Apple Extended Keyboard M0115: 0x02
|
||||
Apple Extended Keyboard II M3501: 0x02
|
||||
Apple Adjustable Keybaord: 0x10
|
||||
|
||||
http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
|
||||
|
||||
END_OF_ADB
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -52,13 +52,41 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define ADB_CAPS 0x39
|
||||
|
||||
|
||||
/* ADB commands */
|
||||
// Default Address
|
||||
#define ADB_ADDR_DONGLE 1
|
||||
#define ADB_ADDR_KEYBOARD 2
|
||||
#define ADB_ADDR_MOUSE 3
|
||||
#define ADB_ADDR_TABLET 4
|
||||
#define ADB_ADDR_APPLIANCE 7
|
||||
// Command Type
|
||||
#define ADB_CMD_RESET 0
|
||||
#define ADB_CMD_FLUSH 1
|
||||
#define ADB_CMD_LISTEN 2
|
||||
#define ADB_CMD_TALK 3
|
||||
// Register
|
||||
#define ADB_REG_0 0
|
||||
#define ADB_REG_1 1
|
||||
#define ADB_REG_2 2
|
||||
#define ADB_REG_3 3
|
||||
|
||||
/* ADB keyboard handler id */
|
||||
#define ADB_HANDLER_M0116 0x01
|
||||
#define ADB_HANDLER_IIGS 0x01
|
||||
#define ADB_HANDLER_M0115 0x02
|
||||
#define ADB_HANDLER_M3501 0x02
|
||||
#define ADB_HANDLER_M1242_ANSI 0x10
|
||||
#define ADB_HANDLER_EXTENDED_PROTOCOL 0x03
|
||||
|
||||
|
||||
// ADB host
|
||||
void adb_host_init(void);
|
||||
bool adb_host_psw(void);
|
||||
uint16_t adb_host_kbd_recv(void);
|
||||
uint16_t adb_host_kbd_recv(uint8_t addr);
|
||||
uint16_t adb_host_mouse_recv(void);
|
||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
|
||||
void adb_host_kbd_led(uint8_t led);
|
||||
uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
|
||||
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
|
||||
void adb_host_kbd_led(uint8_t addr, uint8_t led);
|
||||
void adb_mouse_task(void);
|
||||
void adb_mouse_init(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -150,25 +150,25 @@ static void send_system(uint16_t data)
|
|||
+-------------------------------------+-------+
|
||||
*/
|
||||
#define CONSUMER2BLUEFRUIT(usage) \
|
||||
(usage == AUDIO_MUTE ? 0x0000 : \
|
||||
(usage == AUDIO_VOL_UP ? 0x1000 : \
|
||||
(usage == AUDIO_VOL_DOWN ? 0x2000 : \
|
||||
(usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \
|
||||
(usage == TRANSPORT_PREV_TRACK ? 0x0004 : \
|
||||
(usage == TRANSPORT_STOP ? 0x0010 : \
|
||||
(usage == TRANSPORT_STOP_EJECT ? 0x0000 : \
|
||||
(usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \
|
||||
(usage == AL_CC_CONFIG ? 0x0000 : \
|
||||
(usage == AL_EMAIL ? 0x0000 : \
|
||||
(usage == AL_CALCULATOR ? 0x0000 : \
|
||||
(usage == AL_LOCAL_BROWSER ? 0x0000 : \
|
||||
(usage == AC_SEARCH ? 0x0400 : \
|
||||
(usage == AC_HOME ? 0x0100 : \
|
||||
(usage == AC_BACK ? 0x0000 : \
|
||||
(usage == AC_FORWARD ? 0x0000 : \
|
||||
(usage == AC_STOP ? 0x0000 : \
|
||||
(usage == AC_REFRESH ? 0x0000 : \
|
||||
(usage == AC_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
|
||||
(usage == AUDIO_MUTE ? 0x0000 : \
|
||||
(usage == AUDIO_VOL_UP ? 0x1000 : \
|
||||
(usage == AUDIO_VOL_DOWN ? 0x2000 : \
|
||||
(usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \
|
||||
(usage == TRANSPORT_PREV_TRACK ? 0x0004 : \
|
||||
(usage == TRANSPORT_STOP ? 0x0010 : \
|
||||
(usage == TRANSPORT_STOP_EJECT ? 0x0000 : \
|
||||
(usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \
|
||||
(usage == APPLAUNCH_CC_CONFIG ? 0x0000 : \
|
||||
(usage == APPLAUNCH_EMAIL ? 0x0000 : \
|
||||
(usage == APPLAUNCH_CALCULATOR ? 0x0000 : \
|
||||
(usage == APPLAUNCH_LOCAL_BROWSER ? 0x0000 : \
|
||||
(usage == APPCONTROL_SEARCH ? 0x0400 : \
|
||||
(usage == APPCONTROL_HOME ? 0x0100 : \
|
||||
(usage == APPCONTROL_BACK ? 0x0000 : \
|
||||
(usage == APPCONTROL_FORWARD ? 0x0000 : \
|
||||
(usage == APPCONTROL_STOP ? 0x0000 : \
|
||||
(usage == APPCONTROL_REFRESH ? 0x0000 : \
|
||||
(usage == APPCONTROL_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
|
||||
|
||||
static void send_consumer(uint16_t data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
## TMK running on top of ChibiOS
|
||||
|
||||
This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever [ChibiOS] supports. The notable examples are ARM-based Teensies (3.x and LC) and on the boards with STM32 MCUs.
|
||||
This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever ChibiOS supports. The notable examples are PJRC Teensies(3.x and LC) with NXP Kinetis and dev boards with ST Micro STM32 MCUs.
|
||||
|
||||
### Usage
|
||||
|
||||
- To use, [get a zip of chibios](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) and unpack/rename it to `tmk_core/tool/chibios/chibios`; or you can just clone [the repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning ARM Teensies and the Infinity keyboard), you'll also need [a zip of chibios-contrib](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip), unpacked/renamed to `tmk_core/tool/chibios/chibios-contrib`. Likewise, for git-savvy people, just clone [the repo](https://github.com/ChibiOS/ChibiOS-Contrib) there.
|
||||
- Note: the abovementioned directories are the defaults. You can have the two chibios repositories wherever you want, just define their location in `CHIBIOS` and `CHIBIOS_CONTRIB` variables in your `Makefile`.
|
||||
- To use, get a [zip file](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) of ChibiOS and unpack/rename it to `tmk_core/tool/chibios/ChibiOS`; or you can just clone [ChibiOS repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning Teensies 3.x/LC and the Infinity keyboard), you'll also need a [zip](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip) of ChibiOS-Contrib, unpacked/renamed to `tmk_core/tool/chibios/ChibiOS-Contrib`. Likewise, for git-savvy people, just clone [ChibiOS-Contrib repo](https://github.com/ChibiOS/ChibiOS-Contrib) there.
|
||||
- Note: the above mentioned directories are the defaults. You can have the two ChibiOS repositories wherever you want, just define their location in `CHIBIOS` and `CHIBIOS_CONTRIB` variables in your `Makefile`.
|
||||
- You will also need to install an ARM toolchain, for instance from [here](https://launchpad.net/gcc-arm-embedded). On linux, this is usually also present as a package for your distribution (as `gcc-arm` or something similar). On OS X, you can use [homebrew](http://brew.sh/) with an appropriate tap.
|
||||
|
||||
### Notes
|
||||
|
||||
- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for ARM Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md).
|
||||
- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md).
|
||||
- For gcc options, inspect `tmk_core/tool/chibios/chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of warnings on that.
|
||||
- For debugging, it is sometimes useful disable gcc optimisations, you can do that by adding `-O0` to `OPT_DEFS` in your `Makefile`.
|
||||
- USB string descriptors are messy. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck.
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ static const uint8_t keyboard_hid_report_desc_data[] = {
|
|||
0x95, KBD_REPORT_KEYS, // Report Count (),
|
||||
0x75, 0x08, // Report Size (8),
|
||||
0x15, 0x00, // Logical Minimum (0),
|
||||
0x25, 0xFF, // Logical Maximum(255),
|
||||
0x26, 0xFF, 0x00, // Logical Maximum(255),
|
||||
0x05, 0x07, // Usage Page (Key Codes),
|
||||
0x19, 0x00, // Usage Minimum (0),
|
||||
0x29, 0xFF, // Usage Maximum (255),
|
||||
|
|
@ -299,7 +299,7 @@ static const uint8_t extra_hid_report_desc_data[] = {
|
|||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (0x1)
|
||||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7)
|
||||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7)
|
||||
0x19, 0x01, // USAGE_MINIMUM (0x1)
|
||||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABL
|
|||
#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
|
||||
LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
|
||||
# Remote wakeup fix for ATmega32U2 https://github.com/tmk/tmk_keyboard/issues/361
|
||||
ifeq ($(MCU),atmega32u2)
|
||||
LUFA_OPTS += -DNO_LIMITED_CONTROLLER_CONNECT
|
||||
endif
|
||||
|
||||
OPT_DEFS += -DF_USB=$(F_USB)UL
|
||||
OPT_DEFS += -DARCH=ARCH_$(ARCH)
|
||||
|
|
@ -44,3 +48,8 @@ OPT_DEFS += $(LUFA_OPTS)
|
|||
|
||||
# This indicates using LUFA stack
|
||||
OPT_DEFS += -DPROTOCOL_LUFA
|
||||
|
||||
ifeq (yes,$(strip $(LUFA_DEBUG_SUART)))
|
||||
SRC += common/avr/suart.S
|
||||
LUFA_OPTS += -DLUFA_DEBUG_SUART
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -73,10 +73,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
|
|||
HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
|
||||
|
||||
HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */
|
||||
HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */
|
||||
HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */
|
||||
HID_RI_USAGE_MINIMUM(8, 0x00),
|
||||
HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Usage ID 0x00-0xFF */
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF), /* needs 16 bit to indicate positive value */
|
||||
HID_RI_REPORT_COUNT(8, 0x06),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
||||
|
|
@ -140,9 +140,9 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
|
|||
HID_RI_USAGE(8, 0x80), /* System Control */
|
||||
HID_RI_COLLECTION(8, 0x01), /* Application */
|
||||
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
|
||||
HID_RI_LOGICAL_MINIMUM(16, 0x0001),
|
||||
HID_RI_LOGICAL_MINIMUM(16, 0x0081),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
|
||||
HID_RI_USAGE_MINIMUM(16, 0x0001), /* System Power Down */
|
||||
HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
|
||||
HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */
|
||||
HID_RI_REPORT_SIZE(8, 16),
|
||||
HID_RI_REPORT_COUNT(8, 1),
|
||||
|
|
@ -172,13 +172,13 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
|
|||
HID_RI_COLLECTION(8, 0x01), /* Application */
|
||||
HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
|
||||
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||
HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
|
||||
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
|
||||
HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ typedef struct
|
|||
#define MOUSE_EPSIZE 8
|
||||
#define EXTRAKEY_EPSIZE 8
|
||||
#define CONSOLE_EPSIZE 32
|
||||
#define NKRO_EPSIZE 16
|
||||
#define NKRO_EPSIZE 32
|
||||
|
||||
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
* This file is based on:
|
||||
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
|
||||
|
|
@ -50,9 +50,18 @@
|
|||
#include "suspend.h"
|
||||
#include "hook.h"
|
||||
|
||||
#ifdef LUFA_DEBUG_SUART
|
||||
#include "avr/suart.h"
|
||||
#endif
|
||||
|
||||
#include "matrix.h"
|
||||
#include "descriptor.h"
|
||||
#include "lufa.h"
|
||||
|
||||
|
||||
//#define LUFA_DEBUG
|
||||
|
||||
|
||||
uint8_t keyboard_idle = 0;
|
||||
/* 0: Boot Protocol, 1: Report Protocol(default) */
|
||||
uint8_t keyboard_protocol = 1;
|
||||
|
|
@ -100,10 +109,10 @@ static void Console_Task(void)
|
|||
{
|
||||
/* Create a temporary buffer to hold the read in report from the host */
|
||||
uint8_t ConsoleData[CONSOLE_EPSIZE];
|
||||
|
||||
|
||||
/* Read Console Report Data */
|
||||
Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
|
||||
|
||||
|
||||
/* Process Console Report Data */
|
||||
//ProcessConsoleHIDReport(ConsoleData);
|
||||
}
|
||||
|
|
@ -164,7 +173,7 @@ void EVENT_USB_Device_Disconnect(void)
|
|||
print("[D]");
|
||||
/* For battery powered device */
|
||||
USB_IsInitialized = false;
|
||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
|
||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
|
||||
if (USB_IsInitialized) {
|
||||
USB_Disable(); // Disable all interrupts
|
||||
USB_Controller_Enable();
|
||||
|
|
@ -175,18 +184,24 @@ void EVENT_USB_Device_Disconnect(void)
|
|||
|
||||
void EVENT_USB_Device_Reset(void)
|
||||
{
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[R]");
|
||||
#endif
|
||||
}
|
||||
|
||||
void EVENT_USB_Device_Suspend()
|
||||
{
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[S]");
|
||||
#endif
|
||||
hook_usb_suspend_entry();
|
||||
}
|
||||
|
||||
void EVENT_USB_Device_WakeUp()
|
||||
{
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[W]");
|
||||
#endif
|
||||
hook_usb_wakeup();
|
||||
}
|
||||
|
||||
|
|
@ -217,6 +232,9 @@ void EVENT_USB_Device_StartOfFrame(void)
|
|||
*/
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[c]");
|
||||
#endif
|
||||
bool ConfigSuccess = true;
|
||||
|
||||
/* Setup Keyboard HID Report Endpoints */
|
||||
|
|
@ -293,6 +311,9 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
/* Write the report data to the control endpoint */
|
||||
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
|
||||
Endpoint_ClearOUT();
|
||||
#ifdef LUFA_DEBUG
|
||||
xprintf("[r%d]", USB_ControlRequest.wIndex);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -316,6 +337,9 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
|
||||
Endpoint_ClearOUT();
|
||||
Endpoint_ClearStatusStage();
|
||||
#ifdef LUFA_DEBUG
|
||||
xprintf("[L%d]", USB_ControlRequest.wIndex);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -332,6 +356,9 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
Endpoint_Write_8(keyboard_protocol);
|
||||
Endpoint_ClearIN();
|
||||
Endpoint_ClearStatusStage();
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[p]");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -345,6 +372,9 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
|
||||
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
|
||||
clear_keyboard();
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[P]");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -356,6 +386,9 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
Endpoint_ClearStatusStage();
|
||||
|
||||
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
|
||||
#ifdef LUFA_DEBUG
|
||||
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -367,6 +400,9 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
Endpoint_Write_8(keyboard_idle);
|
||||
Endpoint_ClearIN();
|
||||
Endpoint_ClearStatusStage();
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[i]");
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -374,7 +410,7 @@ void EVENT_USB_Device_ControlRequest(void)
|
|||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Host driver
|
||||
* Host driver
|
||||
******************************************************************************/
|
||||
static uint8_t keyboard_leds(void)
|
||||
{
|
||||
|
|
@ -494,6 +530,9 @@ static void send_consumer(uint16_t data)
|
|||
#define SEND_TIMEOUT 5
|
||||
int8_t sendchar(uint8_t c)
|
||||
{
|
||||
#ifdef LUFA_DEBUG_SUART
|
||||
xmit(c);
|
||||
#endif
|
||||
// Not wait once timeouted.
|
||||
// Because sendchar() is called so many times, waiting each call causes big lag.
|
||||
static bool timeouted = false;
|
||||
|
|
@ -551,6 +590,9 @@ ERROR_EXIT:
|
|||
#else
|
||||
int8_t sendchar(uint8_t c)
|
||||
{
|
||||
#ifdef LUFA_DEBUG_SUART
|
||||
xmit(c);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -578,13 +620,20 @@ static void setup_usb(void)
|
|||
|
||||
// for Console_Task
|
||||
USB_Device_EnableSOFEvents();
|
||||
print_set_sendchar(sendchar);
|
||||
}
|
||||
|
||||
int main(void) __attribute__ ((weak));
|
||||
int main(void)
|
||||
{
|
||||
setup_mcu();
|
||||
|
||||
#ifdef LUFA_DEBUG_SUART
|
||||
SUART_OUT_DDR |= (1<<SUART_OUT_BIT);
|
||||
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
|
||||
#endif
|
||||
print_set_sendchar(sendchar);
|
||||
print("\r\ninit\n");
|
||||
|
||||
hook_early_init();
|
||||
keyboard_setup();
|
||||
setup_usb();
|
||||
|
|
@ -611,7 +660,9 @@ int main(void)
|
|||
hook_late_init();
|
||||
while (1) {
|
||||
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
||||
#ifdef LUFA_DEBUG
|
||||
print("[s]");
|
||||
#endif
|
||||
hook_usb_suspend_loop();
|
||||
}
|
||||
|
||||
|
|
@ -631,9 +682,19 @@ void hook_early_init(void) {}
|
|||
__attribute__((weak))
|
||||
void hook_late_init(void) {}
|
||||
|
||||
static uint8_t _led_stats = 0;
|
||||
__attribute__((weak))
|
||||
void hook_usb_suspend_entry(void)
|
||||
{
|
||||
// Turn LED off to save power
|
||||
// Set 0 with putting aside status before suspend and restore
|
||||
// it after wakeup, then LED is updated at keyboard_task() in main loop
|
||||
_led_stats = keyboard_led_stats;
|
||||
keyboard_led_stats = 0;
|
||||
led_set(keyboard_led_stats);
|
||||
|
||||
matrix_clear();
|
||||
clear_keyboard();
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_enable();
|
||||
#endif
|
||||
|
|
@ -644,7 +705,7 @@ void hook_usb_suspend_loop(void)
|
|||
{
|
||||
suspend_power_down();
|
||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
|
||||
USB_Device_SendRemoteWakeup();
|
||||
USB_Device_SendRemoteWakeup();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -654,7 +715,12 @@ void hook_usb_wakeup(void)
|
|||
suspend_wakeup_init();
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_disable();
|
||||
// NOTE: converters may not accept this
|
||||
led_set(host_keyboard_leds());
|
||||
#endif
|
||||
|
||||
// Restore LED status
|
||||
// BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?)
|
||||
// Converters fall into the case and miss wakeup event(timeout to reply?) in the end.
|
||||
//led_set(host_keyboard_leds());
|
||||
// Instead, restore stats and update at keyboard_task() in main loop
|
||||
keyboard_led_stats = _led_stats;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ uint8_t * HIDKeyboard::reportDesc() {
|
|||
REPORT_COUNT(1), 0x06,
|
||||
REPORT_SIZE(1), 0x08,
|
||||
LOGICAL_MINIMUM(1), 0x00,
|
||||
LOGICAL_MAXIMUM(1), 0xFF,
|
||||
LOGICAL_MAXIMUM(2), 0xFF, 0x00,
|
||||
USAGE_PAGE(1), 0x07, // Key Codes
|
||||
USAGE_MINIMUM(1), 0x00,
|
||||
USAGE_MAXIMUM(1), 0xFF,
|
||||
|
|
|
|||
57
protocol/pbuff.h
Normal file
57
protocol/pbuff.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*--------------------------------------------------------------------
|
||||
* Ring buffer to store scan codes from keyboard
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#ifndef PBUFF_H
|
||||
#define PBUFF_H
|
||||
|
||||
#include "print.h"
|
||||
|
||||
#define PBUF_SIZE 32
|
||||
static uint16_t pbuf[PBUF_SIZE];
|
||||
static uint16_t pbuf_head = 0;
|
||||
static uint16_t pbuf_tail = 0;
|
||||
static inline void pbuf_enqueue(uint16_t data)
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
uint16_t next = (pbuf_head + 1) % PBUF_SIZE;
|
||||
if (next != pbuf_tail) {
|
||||
pbuf[pbuf_head] = data;
|
||||
pbuf_head = next;
|
||||
} else {
|
||||
print("pbuf: full\n");
|
||||
}
|
||||
SREG = sreg;
|
||||
}
|
||||
static inline uint16_t pbuf_dequeue(void)
|
||||
{
|
||||
uint16_t val = 0;
|
||||
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
if (pbuf_head != pbuf_tail) {
|
||||
val = pbuf[pbuf_tail];
|
||||
pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
|
||||
}
|
||||
SREG = sreg;
|
||||
|
||||
return val;
|
||||
}
|
||||
static inline bool pbuf_has_data(void)
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
bool has_data = (pbuf_head != pbuf_tail);
|
||||
SREG = sreg;
|
||||
return has_data;
|
||||
}
|
||||
static inline void pbuf_clear(void)
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
pbuf_head = pbuf_tail = 0;
|
||||
SREG = sreg;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -184,7 +184,7 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
|
|||
0x95, KBD_REPORT_KEYS, // Report Count (),
|
||||
0x75, 0x08, // Report Size (8),
|
||||
0x15, 0x00, // Logical Minimum (0),
|
||||
0x25, 0xFF, // Logical Maximum(255),
|
||||
0x26, 0xFF, 0x00, // Logical Maximum(255),
|
||||
0x05, 0x07, // Usage Page (Key Codes),
|
||||
0x19, 0x00, // Usage Minimum (0),
|
||||
0x29, 0xFF, // Usage Maximum (255),
|
||||
|
|
@ -307,7 +307,7 @@ static const uint8_t PROGMEM extra_hid_report_desc[] = {
|
|||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (0x1)
|
||||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7)
|
||||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7)
|
||||
0x19, 0x01, // USAGE_MINIMUM (0x1)
|
||||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <stdbool.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "pbuff.h"
|
||||
#include "ps2.h"
|
||||
#include "ps2_io.h"
|
||||
#include "print.h"
|
||||
|
|
@ -57,13 +58,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
uint8_t ps2_error = PS2_ERR_NONE;
|
||||
|
||||
|
||||
static inline uint8_t pbuf_dequeue(void);
|
||||
static inline void pbuf_enqueue(uint8_t data);
|
||||
static inline bool pbuf_has_data(void);
|
||||
static inline void pbuf_clear(void);
|
||||
|
||||
|
||||
void ps2_host_init(void)
|
||||
{
|
||||
idle();
|
||||
|
|
@ -225,55 +219,3 @@ void ps2_host_set_led(uint8_t led)
|
|||
ps2_host_send(0xED);
|
||||
ps2_host_send(led);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Ring buffer to store scan codes from keyboard
|
||||
*------------------------------------------------------------------*/
|
||||
#define PBUF_SIZE 32
|
||||
static uint8_t pbuf[PBUF_SIZE];
|
||||
static uint8_t pbuf_head = 0;
|
||||
static uint8_t pbuf_tail = 0;
|
||||
static inline void pbuf_enqueue(uint8_t data)
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
|
||||
if (next != pbuf_tail) {
|
||||
pbuf[pbuf_head] = data;
|
||||
pbuf_head = next;
|
||||
} else {
|
||||
print("pbuf: full\n");
|
||||
}
|
||||
SREG = sreg;
|
||||
}
|
||||
static inline uint8_t pbuf_dequeue(void)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
if (pbuf_head != pbuf_tail) {
|
||||
val = pbuf[pbuf_tail];
|
||||
pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
|
||||
}
|
||||
SREG = sreg;
|
||||
|
||||
return val;
|
||||
}
|
||||
static inline bool pbuf_has_data(void)
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
bool has_data = (pbuf_head != pbuf_tail);
|
||||
SREG = sreg;
|
||||
return has_data;
|
||||
}
|
||||
static inline void pbuf_clear(void)
|
||||
{
|
||||
uint8_t sreg = SREG;
|
||||
cli();
|
||||
pbuf_head = pbuf_tail = 0;
|
||||
SREG = sreg;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,30 +4,14 @@
|
|||
#include "debug.h"
|
||||
|
||||
|
||||
report_keyboard_t usb_hid_keyboard_report;
|
||||
uint16_t usb_hid_time_stamp;
|
||||
|
||||
|
||||
void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
|
||||
{
|
||||
bool is_error = false;
|
||||
report_keyboard_t *report = (report_keyboard_t *)buf;
|
||||
::memcpy(&report, buf, sizeof(report_keyboard_t));
|
||||
time_stamp = millis();
|
||||
|
||||
dprintf("keyboard input: %02X %02X", report->mods, report->reserved);
|
||||
dprintf("input %d: %02X %02X", hid->GetAddress(), report.mods, report.reserved);
|
||||
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
|
||||
if (IS_ERROR(report->keys[i])) {
|
||||
is_error = true;
|
||||
}
|
||||
dprintf(" %02X", report->keys[i]);
|
||||
dprintf(" %02X", report.keys[i]);
|
||||
}
|
||||
dprint("\r\n");
|
||||
|
||||
// ignore error and not send report to computer
|
||||
if (is_error) {
|
||||
dprint("Error usage! \r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
::memcpy(&usb_hid_keyboard_report, buf, sizeof(report_keyboard_t));
|
||||
usb_hid_time_stamp = millis();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@
|
|||
#define PARSER_H
|
||||
|
||||
#include "hid.h"
|
||||
#include "report.h"
|
||||
|
||||
class KBDReportParser : public HIDReportParser
|
||||
{
|
||||
public:
|
||||
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
|
||||
report_keyboard_t report;
|
||||
uint16_t time_stamp;
|
||||
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "debug.h"
|
||||
#include "suspend.h"
|
||||
|
||||
|
||||
#define UART_BAUD_RATE 115200
|
||||
|
|
@ -41,6 +42,23 @@ static void initForUsbConnectivity(void)
|
|||
sei();
|
||||
}
|
||||
|
||||
void usb_remote_wakeup(void) {
|
||||
cli();
|
||||
|
||||
int8_t ddr_orig = USBDDR;
|
||||
USBOUT |= (1 << USBMINUS);
|
||||
USBDDR = ddr_orig | USBMASK;
|
||||
USBOUT ^= USBMASK;
|
||||
|
||||
_delay_ms(25);
|
||||
|
||||
USBOUT ^= USBMASK;
|
||||
USBDDR = ddr_orig;
|
||||
USBOUT &= ~(1 << USBMINUS);
|
||||
|
||||
sei();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bool suspended = false;
|
||||
|
|
@ -70,19 +88,6 @@ int main(void)
|
|||
// Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
|
||||
if (timer_elapsed(last_timer) > 5) {
|
||||
suspended = true;
|
||||
/*
|
||||
uart_putchar('S');
|
||||
_delay_ms(1);
|
||||
cli();
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
sleep_enable();
|
||||
sleep_bod_disable();
|
||||
sei();
|
||||
sleep_cpu();
|
||||
sleep_disable();
|
||||
_delay_ms(10);
|
||||
uart_putchar('W');
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -95,6 +100,8 @@ int main(void)
|
|||
keyboard_task();
|
||||
}
|
||||
vusb_transfer_keyboard();
|
||||
} else if (suspend_wakeup_condition()) {
|
||||
usb_remote_wakeup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ const PROGMEM uchar keyboard_hid_report[] = {
|
|||
0x95, 0x06, // Report Count (6),
|
||||
0x75, 0x08, // Report Size (8),
|
||||
0x15, 0x00, // Logical Minimum (0),
|
||||
0x25, 0xFF, // Logical Maximum(255),
|
||||
0x26, 0xFF, 0x00, // Logical Maximum(255),
|
||||
0x05, 0x07, // Usage Page (Key Codes),
|
||||
0x19, 0x00, // Usage Minimum (0),
|
||||
0x29, 0xFF, // Usage Maximum (255),
|
||||
|
|
@ -336,7 +336,7 @@ const PROGMEM uchar mouse_hid_report[] = {
|
|||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, REPORT_ID_SYSTEM, // REPORT_ID (2)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (0x1)
|
||||
0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7)
|
||||
0x26, 0xb7, 0x00, // LOGICAL_MAXIMUM (0xb7)
|
||||
0x19, 0x01, // USAGE_MINIMUM (0x1)
|
||||
0x29, 0xb7, // USAGE_MAXIMUM (0xb7)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
|
|
|
|||
75
protocol/xt.h
Normal file
75
protocol/xt.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2016 Ethan Apodaca <papodaca@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 XT_H
|
||||
#define XT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "wait.h"
|
||||
#include "xt_io.h"
|
||||
#include "print.h"
|
||||
|
||||
void xt_host_init(void);
|
||||
uint8_t xt_host_recv(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* static functions
|
||||
*------------------------------------------------------------------*/
|
||||
static inline uint16_t wait_clock_lo(uint16_t us)
|
||||
{
|
||||
while (clock_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_clock_hi(uint16_t us)
|
||||
{
|
||||
while (!clock_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_data_lo(uint16_t us)
|
||||
{
|
||||
while (data_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_data_hi(uint16_t us)
|
||||
{
|
||||
while (!data_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
|
||||
#endif
|
||||
94
protocol/xt_interrupt.c
Normal file
94
protocol/xt_interrupt.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Copyright 2010,2011,2012,2013 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PS/2 protocol Pin interrupt version
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "pbuff.h"
|
||||
#include "xt.h"
|
||||
#include "xt_io.h"
|
||||
#include "wait.h"
|
||||
#include "print.h"
|
||||
|
||||
void xt_host_init(void)
|
||||
{
|
||||
XT_INT_INIT();
|
||||
XT_INT_ON();
|
||||
}
|
||||
|
||||
/* get data received by interrupt */
|
||||
uint8_t xt_host_recv(void)
|
||||
{
|
||||
if (pbuf_has_data()) {
|
||||
return pbuf_dequeue();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ISR(XT_INT_VECT)
|
||||
{
|
||||
static uint8_t state = 0;
|
||||
static uint8_t data = 0;
|
||||
|
||||
if (state == 0) {
|
||||
if (data_in())
|
||||
state++;
|
||||
} else if (state >= 1 && state <= 8) {
|
||||
wait_clock_lo(20);
|
||||
data >>= 1;
|
||||
if (data_in())
|
||||
data |= 0x80;
|
||||
if (state == 8)
|
||||
goto END;
|
||||
state++;
|
||||
} else {
|
||||
goto DONE;
|
||||
}
|
||||
goto RETURN;
|
||||
END:
|
||||
pbuf_enqueue(data);
|
||||
DONE:
|
||||
state = 0;
|
||||
data = 0;
|
||||
RETURN:
|
||||
return;
|
||||
}
|
||||
7
protocol/xt_io.h
Normal file
7
protocol/xt_io.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef XT_IO_H
|
||||
#define XT_IO_H
|
||||
|
||||
bool clock_in(void);
|
||||
bool data_in(void);
|
||||
|
||||
#endif
|
||||
34
protocol/xt_io_avr.c
Normal file
34
protocol/xt_io_avr.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
/* Check port settings for clock and data line */
|
||||
#if !(defined(XT_CLOCK_PORT) && \
|
||||
defined(XT_CLOCK_PIN) && \
|
||||
defined(XT_CLOCK_DDR) && \
|
||||
defined(XT_CLOCK_BIT))
|
||||
# error "XT clock port setting is required in config.h"
|
||||
#endif
|
||||
|
||||
#if !(defined(XT_DATA_PORT) && \
|
||||
defined(XT_DATA_PIN) && \
|
||||
defined(XT_DATA_DDR) && \
|
||||
defined(XT_DATA_BIT))
|
||||
# error "XT data port setting is required in config.h"
|
||||
#endif
|
||||
|
||||
bool clock_in(void)
|
||||
{
|
||||
XT_CLOCK_DDR &= ~(1<<XT_CLOCK_BIT);
|
||||
XT_CLOCK_PORT |= (1<<XT_CLOCK_BIT);
|
||||
_delay_us(1);
|
||||
return XT_CLOCK_PIN&(1<<XT_CLOCK_BIT);
|
||||
}
|
||||
|
||||
bool data_in(void)
|
||||
{
|
||||
XT_DATA_DDR &= ~(1<<XT_DATA_BIT);
|
||||
XT_DATA_PORT |= (1<<XT_DATA_BIT);
|
||||
_delay_us(1);
|
||||
return XT_DATA_PIN&(1<<XT_DATA_BIT);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue