aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/chibios.mk3
-rw-r--r--tmk_core/common.mk1
-rw-r--r--tmk_core/common/avr/bootloader.c2
-rw-r--r--tmk_core/common/keyboard.c2
-rw-r--r--tmk_core/common/mousekey.c82
-rw-r--r--tmk_core/common/mousekey.h37
-rw-r--r--tmk_core/common/sync_timer.c58
-rw-r--r--tmk_core/common/sync_timer.h54
-rw-r--r--tmk_core/protocol/adb.c256
-rw-r--r--tmk_core/protocol/adb.h58
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c3
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h4
12 files changed, 470 insertions, 90 deletions
diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk
index 733f2d60f..5a3facf8e 100644
--- a/tmk_core/chibios.mk
+++ b/tmk_core/chibios.mk
@@ -71,6 +71,9 @@ else ifneq ("$(wildcard $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk)","
71 BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD) 71 BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD)
72 BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk 72 BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk
73 KEYBOARD_PATHS += $(BOARD_PATH)/configs 73 KEYBOARD_PATHS += $(BOARD_PATH)/configs
74 ifneq ("$(wildcard $(BOARD_PATH)/rules.mk)","")
75 include $(BOARD_PATH)/rules.mk
76 endif
74endif 77endif
75 78
76ifeq ("$(wildcard $(BOARD_MK))","") 79ifeq ("$(wildcard $(BOARD_MK))","")
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index fdf2aa097..05839824c 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -18,6 +18,7 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
18 $(COMMON_DIR)/report.c \ 18 $(COMMON_DIR)/report.c \
19 $(PLATFORM_COMMON_DIR)/suspend.c \ 19 $(PLATFORM_COMMON_DIR)/suspend.c \
20 $(PLATFORM_COMMON_DIR)/timer.c \ 20 $(PLATFORM_COMMON_DIR)/timer.c \
21 $(COMMON_DIR)/sync_timer.c \
21 $(PLATFORM_COMMON_DIR)/bootloader.c \ 22 $(PLATFORM_COMMON_DIR)/bootloader.c \
22 23
23ifeq ($(PLATFORM),AVR) 24ifeq ($(PLATFORM),AVR)
diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c
index a1db55da9..c0272903b 100644
--- a/tmk_core/common/avr/bootloader.c
+++ b/tmk_core/common/avr/bootloader.c
@@ -77,7 +77,7 @@ uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;")));
77 * 77 *
78 * FIXME: needs doc 78 * FIXME: needs doc
79 */ 79 */
80void bootloader_jump(void) { 80__attribute__((weak)) void bootloader_jump(void) {
81#if !defined(BOOTLOADER_SIZE) 81#if !defined(BOOTLOADER_SIZE)
82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); 82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
83 83
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 8c7bdc8b5..a1fbc01da 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23#include "led.h" 23#include "led.h"
24#include "keycode.h" 24#include "keycode.h"
25#include "timer.h" 25#include "timer.h"
26#include "sync_timer.h"
26#include "print.h" 27#include "print.h"
27#include "debug.h" 28#include "debug.h"
28#include "command.h" 29#include "command.h"
@@ -255,6 +256,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
255 */ 256 */
256void keyboard_init(void) { 257void keyboard_init(void) {
257 timer_init(); 258 timer_init();
259 sync_timer_init();
258 matrix_init(); 260 matrix_init();
259#ifdef VIA_ENABLE 261#ifdef VIA_ENABLE
260 via_init(); 262 via_init();
diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c
index ef18bcf1a..697e0692c 100644
--- a/tmk_core/common/mousekey.c
+++ b/tmk_core/common/mousekey.c
@@ -36,6 +36,9 @@ static void mousekey_debug(void);
36static uint8_t mousekey_accel = 0; 36static uint8_t mousekey_accel = 0;
37static uint8_t mousekey_repeat = 0; 37static uint8_t mousekey_repeat = 0;
38static uint8_t mousekey_wheel_repeat = 0; 38static uint8_t mousekey_wheel_repeat = 0;
39#ifdef MK_KINETIC_SPEED
40static uint16_t mouse_timer = 0;
41#endif
39 42
40#ifndef MK_3_SPEED 43#ifndef MK_3_SPEED
41 44
@@ -43,7 +46,7 @@ static uint16_t last_timer_c = 0;
43static uint16_t last_timer_w = 0; 46static uint16_t last_timer_w = 0;
44 47
45/* 48/*
46 * Mouse keys acceleration algorithm 49 * Mouse keys acceleration algorithm
47 * http://en.wikipedia.org/wiki/Mouse_keys 50 * http://en.wikipedia.org/wiki/Mouse_keys
48 * 51 *
49 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) 52 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
@@ -105,6 +108,69 @@ static uint8_t wheel_unit(void) {
105} 108}
106 109
107# else /* #ifndef MK_COMBINED */ 110# else /* #ifndef MK_COMBINED */
111# ifndef MK_KINETIC_SPEED
112
113/*
114 * Kinetic movement acceleration algorithm
115 *
116 * current speed = I + A * T/50 + A * 0.5 * T^2 | maximum B
117 *
118 * T: time since the mouse movement started
119 * E: mouse events per second (set through MOUSEKEY_INTERVAL, UHK sends 250, the
120 * pro micro on my Signum 3.0 sends only 125!)
121 * I: initial speed at time 0
122 * A: acceleration
123 * B: base mouse travel speed
124 */
125const uint16_t mk_accelerated_speed = MOUSEKEY_ACCELERATED_SPEED;
126const uint16_t mk_base_speed = MOUSEKEY_BASE_SPEED;
127const uint16_t mk_decelerated_speed = MOUSEKEY_DECELERATED_SPEED;
128const uint16_t mk_initial_speed = MOUSEKEY_INITIAL_SPEED;
129
130static uint8_t move_unit(void) {
131 float speed = mk_initial_speed;
132
133 if (mousekey_accel & ((1<<0) | (1<<2))) {
134 speed = mousekey_accel & (1<<2) ? mk_accelerated_speed : mk_decelerated_speed;
135 } else if (mousekey_repeat && mouse_timer) {
136 const float time_elapsed = timer_elapsed(mouse_timer) / 50;
137 speed = mk_initial_speed +
138 MOUSEKEY_MOVE_DELTA * time_elapsed +
139 MOUSEKEY_MOVE_DELTA * 0.5 * time_elapsed * time_elapsed;
140
141 speed = speed > mk_base_speed ? mk_base_speed : speed;
142 }
143
144 /* convert speed to USB mouse speed 1 to 127 */
145 speed = (uint8_t)(speed / (1000.0f / mk_interval));
146 speed = speed < 1 ? 1 : speed;
147
148 return speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed;
149}
150
151float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
152
153static uint8_t wheel_unit(void) {
154 float speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
155
156 if (mousekey_accel & ((1<<0) | (1<<2))) {
157 speed = mousekey_accel & (1<<2) ? MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS : MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS;
158 } else if (mousekey_repeat && mouse_timer) {
159 if (mk_wheel_interval != MOUSEKEY_WHEEL_BASE_MOVEMENTS) {
160 const float time_elapsed = timer_elapsed(mouse_timer) / 50;
161 speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS +
162 1 * time_elapsed +
163 1 * 0.5 * time_elapsed * time_elapsed;
164 }
165 speed = speed > MOUSEKEY_WHEEL_BASE_MOVEMENTS ? MOUSEKEY_WHEEL_BASE_MOVEMENTS : speed;
166 }
167
168 mk_wheel_interval = 1000.0f / speed;
169
170 return 1;
171}
172
173# else /* #ifndef MK_KINETIC_SPEED */
108 174
109static uint8_t move_unit(void) { 175static uint8_t move_unit(void) {
110 uint16_t unit; 176 uint16_t unit;
@@ -142,6 +208,7 @@ static uint8_t wheel_unit(void) {
142 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); 208 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
143} 209}
144 210
211# endif /* #ifndef MK_KINETIC_SPEED */
145# endif /* #ifndef MK_COMBINED */ 212# endif /* #ifndef MK_COMBINED */
146 213
147void mousekey_task(void) { 214void mousekey_task(void) {
@@ -193,6 +260,12 @@ void mousekey_task(void) {
193} 260}
194 261
195void mousekey_on(uint8_t code) { 262void mousekey_on(uint8_t code) {
263#ifdef MK_KINETIC_SPEED
264 if (mouse_timer == 0) {
265 mouse_timer = timer_read();
266 }
267#endif /* #ifdef MK_KINETIC_SPEED */
268
196 if (code == KC_MS_UP) 269 if (code == KC_MS_UP)
197 mouse_report.y = move_unit() * -1; 270 mouse_report.y = move_unit() * -1;
198 else if (code == KC_MS_DOWN) 271 else if (code == KC_MS_DOWN)
@@ -260,7 +333,12 @@ void mousekey_off(uint8_t code) {
260 mousekey_accel &= ~(1 << 1); 333 mousekey_accel &= ~(1 << 1);
261 else if (code == KC_MS_ACCEL2) 334 else if (code == KC_MS_ACCEL2)
262 mousekey_accel &= ~(1 << 2); 335 mousekey_accel &= ~(1 << 2);
263 if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0; 336 if (mouse_report.x == 0 && mouse_report.y == 0) {
337 mousekey_repeat = 0;
338#ifdef MK_KINETIC_SPEED
339 mouse_timer = 0;
340#endif /* #ifdef MK_KINETIC_SPEED */
341 }
264 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0; 342 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
265} 343}
266 344
diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h
index 300d262f5..911d11eeb 100644
--- a/tmk_core/common/mousekey.h
+++ b/tmk_core/common/mousekey.h
@@ -36,16 +36,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
36# endif 36# endif
37 37
38# ifndef MOUSEKEY_MOVE_DELTA 38# ifndef MOUSEKEY_MOVE_DELTA
39#ifndef MK_KINETIC_SPEED
39# define MOUSEKEY_MOVE_DELTA 5 40# define MOUSEKEY_MOVE_DELTA 5
41#else
42# define MOUSEKEY_MOVE_DELTA 25
43#endif
40# endif 44# endif
41# ifndef MOUSEKEY_WHEEL_DELTA 45# ifndef MOUSEKEY_WHEEL_DELTA
42# define MOUSEKEY_WHEEL_DELTA 1 46# define MOUSEKEY_WHEEL_DELTA 1
43# endif 47# endif
44# ifndef MOUSEKEY_DELAY 48# ifndef MOUSEKEY_DELAY
49#ifndef MK_KINETIC_SPEED
45# define MOUSEKEY_DELAY 300 50# define MOUSEKEY_DELAY 300
51#else
52# define MOUSEKEY_DELAY 8
53#endif
46# endif 54# endif
47# ifndef MOUSEKEY_INTERVAL 55# ifndef MOUSEKEY_INTERVAL
56#ifndef MK_KINETIC_SPEED
48# define MOUSEKEY_INTERVAL 50 57# define MOUSEKEY_INTERVAL 50
58#else
59# define MOUSEKEY_INTERVAL 8
60#endif
49# endif 61# endif
50# ifndef MOUSEKEY_MAX_SPEED 62# ifndef MOUSEKEY_MAX_SPEED
51# define MOUSEKEY_MAX_SPEED 10 63# define MOUSEKEY_MAX_SPEED 10
@@ -66,6 +78,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
66# define MOUSEKEY_WHEEL_TIME_TO_MAX 40 78# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
67# endif 79# endif
68 80
81#ifndef MOUSEKEY_INITIAL_SPEED
82#define MOUSEKEY_INITIAL_SPEED 100
83#endif
84#ifndef MOUSEKEY_BASE_SPEED
85#define MOUSEKEY_BASE_SPEED 1000
86#endif
87#ifndef MOUSEKEY_DECELERATED_SPEED
88#define MOUSEKEY_DECELERATED_SPEED 400
89#endif
90#ifndef MOUSEKEY_ACCELERATED_SPEED
91#define MOUSEKEY_ACCELERATED_SPEED 3000
92#endif
93#ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS
94#define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 16
95#endif
96#ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS
97#define MOUSEKEY_WHEEL_BASE_MOVEMENTS 32
98#endif
99#ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS
100#define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48
101#endif
102#ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
103#define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
104#endif
105
69#else /* #ifndef MK_3_SPEED */ 106#else /* #ifndef MK_3_SPEED */
70 107
71# ifndef MK_C_OFFSET_UNMOD 108# ifndef MK_C_OFFSET_UNMOD
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c
new file mode 100644
index 000000000..de24b463b
--- /dev/null
+++ b/tmk_core/common/sync_timer.c
@@ -0,0 +1,58 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#include "sync_timer.h"
27#include "keyboard.h"
28
29#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
30volatile int32_t sync_timer_ms;
31
32void sync_timer_init(void) { sync_timer_ms = 0; }
33
34void sync_timer_update(uint32_t time) {
35 if (is_keyboard_master()) return;
36 sync_timer_ms = time - timer_read32();
37}
38
39uint16_t sync_timer_read(void) {
40 if (is_keyboard_master()) return timer_read();
41 return sync_timer_read32();
42}
43
44uint32_t sync_timer_read32(void) {
45 if (is_keyboard_master()) return timer_read32();
46 return sync_timer_ms + timer_read32();
47}
48
49uint16_t sync_timer_elapsed(uint16_t last) {
50 if (is_keyboard_master()) return timer_elapsed(last);
51 return TIMER_DIFF_16(sync_timer_read(), last);
52}
53
54uint32_t sync_timer_elapsed32(uint32_t last) {
55 if (is_keyboard_master()) return timer_elapsed32(last);
56 return TIMER_DIFF_32(sync_timer_read32(), last);
57}
58#endif
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
new file mode 100644
index 000000000..9ddef45bb
--- /dev/null
+++ b/tmk_core/common/sync_timer.h
@@ -0,0 +1,54 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#pragma once
27
28#include <stdint.h>
29#include "timer.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
36void sync_timer_init(void);
37void sync_timer_update(uint32_t time);
38uint16_t sync_timer_read(void);
39uint32_t sync_timer_read32(void);
40uint16_t sync_timer_elapsed(uint16_t last);
41uint32_t sync_timer_elapsed32(uint32_t last);
42#else
43# define sync_timer_init()
44# define sync_timer_clear()
45# define sync_timer_update(t)
46# define sync_timer_read() timer_read()
47# define sync_timer_read32() timer_read32()
48# define sync_timer_elapsed(t) timer_elapsed(t)
49# define sync_timer_elapsed32(t) timer_elapsed32(t)
50#endif
51
52#ifdef __cplusplus
53}
54#endif
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c
index a23c91961..367f1b09f 100644
--- a/tmk_core/protocol/adb.c
+++ b/tmk_core/protocol/adb.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3Copyright 2013 Shay Green <gblargg@gmail.com> 3Copyright 2013 Shay Green <gblargg@gmail.com>
4 4
5This software is licensed with a Modified BSD License. 5This software is licensed with a Modified BSD License.
@@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
41#include <avr/io.h> 41#include <avr/io.h>
42#include <avr/interrupt.h> 42#include <avr/interrupt.h>
43#include "adb.h" 43#include "adb.h"
44#include "print.h"
44 45
45// GCC doesn't inline functions normally 46// GCC doesn't inline functions normally
46#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) 47#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
@@ -59,7 +60,6 @@ static inline void place_bit1(void);
59static inline void send_byte(uint8_t data); 60static inline void send_byte(uint8_t data);
60static inline uint16_t wait_data_lo(uint16_t us); 61static inline uint16_t wait_data_lo(uint16_t us);
61static inline uint16_t wait_data_hi(uint16_t us); 62static inline uint16_t wait_data_hi(uint16_t us);
62static inline uint16_t adb_host_dev_recv(uint8_t device);
63 63
64void adb_host_init(void) { 64void adb_host_init(void) {
65 ADB_PORT &= ~(1 << ADB_DATA_BIT); 65 ADB_PORT &= ~(1 << ADB_DATA_BIT);
@@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); }
81 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> 81 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
82 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> 82 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
83 */ 83 */
84 84uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }
85// ADB Bit Cells
86//
87// bit cell time: 70-130us
88// low part of bit0: 60-70% of bit cell
89// low part of bit1: 30-40% of bit cell
90//
91// bit cell time 70us 130us
92// --------------------------------------------
93// low part of bit0 42-49 78-91
94// high part of bit0 21-28 39-52
95// low part of bit1 21-28 39-52
96// high part of bit1 42-49 78-91
97//
98//
99// bit0:
100// 70us bit cell:
101// ____________~~~~~~
102// 42-49 21-28
103//
104// 130us bit cell:
105// ____________~~~~~~
106// 78-91 39-52
107//
108// bit1:
109// 70us bit cell:
110// ______~~~~~~~~~~~~
111// 21-28 42-49
112//
113// 130us bit cell:
114// ______~~~~~~~~~~~~
115// 39-52 78-91
116//
117// [from Apple IIgs Hardware Reference Second Edition]
118
119enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
120
121uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); }
122 85
123#ifdef ADB_MOUSE_ENABLE 86#ifdef ADB_MOUSE_ENABLE
124void adb_mouse_init(void) { return; } 87__attribute__((weak)) void adb_mouse_init(void) { return; }
88
89__attribute__((weak)) void adb_mouse_task(void) { return; }
125 90
126uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); } 91uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
127#endif 92#endif
128 93
129static inline uint16_t adb_host_dev_recv(uint8_t device) { 94// This sends Talk command to read data from register and returns length of the data.
130 uint16_t data = 0; 95uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
96 for (int8_t i = 0; i < len; i++) buf[i] = 0;
97
131 cli(); 98 cli();
132 attention(); 99 attention();
133 send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) 100 send_byte((addr << 4) | ADB_CMD_TALK | reg);
134 place_bit0(); // Stopbit(0) 101 place_bit0(); // Stopbit(0)
102 // TODO: Service Request(Srq):
103 // Device holds low part of comannd stopbit for 140-260us
104 //
105 // Command:
106 // ......._ ______________________ ___ ............_ -------
107 // | | | | | | |
108 // Command | | | | | Data bytes | |
109 // ........|___| | 140-260 |__| |_............|___|
110 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
111 //
112 // Command without data:
113 // ......._ __________________________
114 // | |
115 // Command | |
116 // ........|___| | 140-260 |
117 // |stop0 | Tlt Stop-to-Start |
118 //
119 // Service Request:
120 // ......._ ______ ___ ............_ -------
121 // | 140-260 | | | | | |
122 // Command | Service Request | | | | Data bytes | |
123 // ........|___________________| |__| |_............|___|
124 // |stop0 | |start1| |stop0 |
125 // ......._ __________
126 // | 140-260 |
127 // Command | Service Request |
128 // ........|___________________|
129 // |stop0 |
130 // This can be happened?
131 // ......._ ______________________ ___ ............_ -----
132 // | | | | | | 140-260 |
133 // Command | | | | | Data bytes | Service Request |
134 // ........|___| | 140-260 |__| |_............|_________________|
135 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
136 //
137 // "Service requests are issued by the devices during a very specific time at the
138 // end of the reception of the command packet.
139 // If a device in need of service issues a service request, it must do so within
140 // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
141 //
142 // "A device sends a Service Request signal by holding the bus low during the low
143 // portion of the stop bit of any command or data transaction. The device must lengthen
144 // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
145 // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
135 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored 146 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
147 xprintf("R");
136 sei(); 148 sei();
137 return -30; // something wrong 149 return 0;
138 } 150 }
139 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) 151 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
140 sei(); 152 sei();
141 return 0; // No data to send 153 return 0; // No data from device(not error);
154 }
155
156 // start bit(1)
157 if (!wait_data_hi(40)) {
158 xprintf("S");
159 sei();
160 return 0;
161 }
162 if (!wait_data_lo(100)) {
163 xprintf("s");
164 sei();
165 return 0;
142 } 166 }
143 167
144 uint8_t n = 17; // start bit + 16 data bits 168 uint8_t n = 0; // bit count
145 do { 169 do {
170 //
171 // |<- bit_cell_max(130) ->|
172 // | |<- lo ->|
173 // | | |<-hi->|
174 // _______
175 // | | |
176 // | 130-lo | lo-hi |
177 // |________| |
178 //
146 uint8_t lo = (uint8_t)wait_data_hi(130); 179 uint8_t lo = (uint8_t)wait_data_hi(130);
147 if (!lo) goto error; 180 if (!lo) goto error; // no more bit or after stop bit
148 181
149 uint8_t hi = (uint8_t)wait_data_lo(lo); 182 uint8_t hi = (uint8_t)wait_data_lo(lo);
150 if (!hi) goto error; 183 if (!hi) goto error; // stop bit extedned by Srq?
151 184
152 hi = lo - hi; 185 if (n / 8 >= len) continue; // can't store in buf
153 lo = 130 - lo;
154 186
155 data <<= 1; 187 buf[n / 8] <<= 1;
156 if (lo < hi) { 188 if ((130 - lo) < (lo - hi)) {
157 data |= 1; 189 buf[n / 8] |= 1;
158 } else if (n == 17) {
159 sei();
160 return -20;
161 } 190 }
162 } while (--n); 191 } while (++n);
163
164 // Stop bit can't be checked normally since it could have service request lenghtening
165 // and its high state never goes low.
166 if (!wait_data_hi(351) || wait_data_lo(91)) {
167 sei();
168 return -21;
169 }
170 sei();
171 return data;
172 192
173error: 193error:
174 sei(); 194 sei();
175 return -n; 195 return n / 8;
176} 196}
177 197
178void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) { 198uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
199 uint8_t len;
200 uint8_t buf[8];
201 len = adb_host_talk_buf(addr, reg, buf, 8);
202 if (len != 2) return 0;
203 return (buf[0] << 8 | buf[1]);
204}
205
206void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
179 cli(); 207 cli();
180 attention(); 208 attention();
181 send_byte(cmd); 209 send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
182 place_bit0(); // Stopbit(0) 210 place_bit0(); // Stopbit(0)
211 // TODO: Service Request
183 _delay_us(200); // Tlt/Stop to Start 212 _delay_us(200); // Tlt/Stop to Start
184 place_bit1(); // Startbit(1) 213 place_bit1(); // Startbit(1)
185 send_byte(data_h); 214 for (int8_t i = 0; i < len; i++) {
186 send_byte(data_l); 215 send_byte(buf[i]);
216 // xprintf("%02X ", buf[i]);
217 }
187 place_bit0(); // Stopbit(0); 218 place_bit0(); // Stopbit(0);
188 sei(); 219 sei();
189} 220}
190 221
222void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
223 uint8_t buf[2] = {data_h, data_l};
224 adb_host_listen_buf(addr, reg, buf, 2);
225}
226
227void adb_host_flush(uint8_t addr) {
228 cli();
229 attention();
230 send_byte((addr << 4) | ADB_CMD_FLUSH);
231 place_bit0(); // Stopbit(0)
232 _delay_us(200); // Tlt/Stop to Start
233 sei();
234}
235
191// send state of LEDs 236// send state of LEDs
192void adb_host_kbd_led(uint8_t led) { 237void adb_host_kbd_led(uint8_t led) {
193 // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) 238 // Listen Register2
194 // send upper byte (not used) 239 // upper byte: not used
195 // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: 240 // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
196 adb_host_listen(0x2A, 0, led & 0x07); 241 adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
197} 242}
198 243
199#ifdef ADB_PSW_BIT 244#ifdef ADB_PSW_BIT
@@ -327,7 +372,7 @@ Commands
327 372
328 bits commands 373 bits commands
329 ------------------------------------------------------ 374 ------------------------------------------------------
330 - - - - 0 0 0 0 Send Request(reset all devices) 375 - - - - 0 0 0 0 Send Reset(reset all devices)
331 A A A A 0 0 0 1 Flush(reset a device) 376 A A A A 0 0 0 1 Flush(reset a device)
332 - - - - 0 0 1 0 Reserved 377 - - - - 0 0 1 0 Reserved
333 - - - - 0 0 1 1 Reserved 378 - - - - 0 0 1 1 Reserved
@@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2)
435 | +----------------------------- Delete 480 | +----------------------------- Delete
436 +------------------------------- Reserved 481 +------------------------------- Reserved
437 482
483Address, Handler ID and bits(Register3)
484 1514131211 . . 8 7 . . . . . . 0
485 | | | | | | | | | | | | | | | |
486 | | | | | | | | +-+-+-+-+-+-+-+- Handler ID
487 | | | | +-+-+-+----------------- Address
488 | | | +------------------------- 0
489 | | +--------------------------- Service request enable(1 = enabled)
490 | +----------------------------- Exceptional event(alwyas 1 if not used)
491 +------------------------------- 0
492
493ADB Bit Cells
494 bit cell time: 70-130us
495 low part of bit0: 60-70% of bit cell
496 low part of bit1: 30-40% of bit cell
497
498 bit cell time 70us 130us
499 --------------------------------------------
500 low part of bit0 42-49 78-91
501 high part of bit0 21-28 39-52
502 low part of bit1 21-28 39-52
503 high part of bit1 42-49 78-91
504
505
506 bit0:
507 70us bit cell:
508 ____________~~~~~~
509 42-49 21-28
510
511 130us bit cell:
512 ____________~~~~~~
513 78-91 39-52
514
515 bit1:
516 70us bit cell:
517 ______~~~~~~~~~~~~
518 21-28 42-49
519
520 130us bit cell:
521 ______~~~~~~~~~~~~
522 39-52 78-91
523
524 [from Apple IIgs Hardware Reference Second Edition]
525
526Keyboard Handle ID
527 Apple Standard Keyboard M0116: 0x01
528 Apple Extended Keyboard M0115: 0x02
529 Apple Extended Keyboard II M3501: 0x02
530 Apple Adjustable Keybaord: 0x10
531
532 http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
533
438END_OF_ADB 534END_OF_ADB
439*/ 535*/
diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h
index 34cbcf769..fe8becc2d 100644
--- a/tmk_core/protocol/adb.h
+++ b/tmk_core/protocol/adb.h
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3 3
4This software is licensed with a Modified BSD License. 4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free, 5All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE.
47#define ADB_POWER 0x7F 47#define ADB_POWER 0x7F
48#define ADB_CAPS 0x39 48#define ADB_CAPS 0x39
49 49
50/* ADB commands */
51// Default Address
52#define ADB_ADDR_0 0
53#define ADB_ADDR_DONGLE 1
54#define ADB_ADDR_KEYBOARD 2
55#define ADB_ADDR_MOUSE 3
56#define ADB_ADDR_TABLET 4
57#define ADB_ADDR_APPLIANCE 7
58#define ADB_ADDR_8 8
59#define ADB_ADDR_9 9
60#define ADB_ADDR_10 10
61#define ADB_ADDR_11 11
62#define ADB_ADDR_12 12
63#define ADB_ADDR_13 13
64#define ADB_ADDR_14 14
65#define ADB_ADDR_15 15
66// for temporary purpose, do not use for polling
67#define ADB_ADDR_TMP 15
68#define ADB_ADDR_MOUSE_POLL 10
69// Command Type
70#define ADB_CMD_RESET 0
71#define ADB_CMD_FLUSH 1
72#define ADB_CMD_LISTEN 8
73#define ADB_CMD_TALK 12
74// Register
75#define ADB_REG_0 0
76#define ADB_REG_1 1
77#define ADB_REG_2 2
78#define ADB_REG_3 3
79
80/* ADB keyboard handler id */
81#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */
82#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */
83#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */
84#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */
85#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */
86#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */
87#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
88#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
89#define ADB_HANDLER_EXTENDED_MOUSE 0x04
90#define ADB_HANDLER_TURBO_MOUSE 0x32
91
50// ADB host 92// ADB host
51void adb_host_init(void); 93void adb_host_init(void);
52bool adb_host_psw(void); 94bool adb_host_psw(void);
95uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
96uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
97void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
98void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
99void adb_host_flush(uint8_t addr);
100void adb_host_kbd_led(uint8_t led);
53uint16_t adb_host_kbd_recv(void); 101uint16_t adb_host_kbd_recv(void);
54uint16_t adb_host_mouse_recv(void); 102uint16_t adb_host_mouse_recv(void);
55void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); 103
56void adb_host_kbd_led(uint8_t led); 104// ADB Mouse
57void adb_mouse_task(void); 105void adb_mouse_task(void);
58void adb_mouse_init(void); 106void adb_mouse_init(void);
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index d3319ab44..dda2f85b0 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
28 28
29# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers 29# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
30 30
31DmacDescriptor dmac_desc;
32DmacDescriptor dmac_desc_wb;
33
31static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer 34static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
32static uint8_t i2c_led_q_s; // Start of circular buffer 35static uint8_t i2c_led_q_s; // Start of circular buffer
33static uint8_t i2c_led_q_e; // End of circular buffer 36static uint8_t i2c_led_q_e; // End of circular buffer
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h
index 44dbdfbff..68773f213 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.h
+++ b/tmk_core/protocol/arm_atsam/i2c_master.h
@@ -24,8 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
24# include "issi3733_driver.h" 24# include "issi3733_driver.h"
25# include "config.h" 25# include "config.h"
26 26
27__attribute__((__aligned__(16))) DmacDescriptor dmac_desc; 27extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
28__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; 28extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
29 29
30uint8_t I2C3733_Init_Control(void); 30uint8_t I2C3733_Init_Control(void);
31uint8_t I2C3733_Init_Drivers(void); 31uint8_t I2C3733_Init_Drivers(void);