aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/action.c7
-rw-r--r--common/action_code.h14
-rw-r--r--common/keyboard.c25
-rw-r--r--common/keymap.c2
-rw-r--r--doc/keycode.txt2
-rw-r--r--doc/keymap.md2
-rw-r--r--protocol.mk4
-rw-r--r--protocol/adb.c24
-rw-r--r--protocol/adb.h4
-rw-r--r--protocol/ibm4704.c135
-rw-r--r--protocol/pjrc.mk4
-rw-r--r--ring_buffer.h53
-rw-r--r--rules.mk6
13 files changed, 210 insertions, 72 deletions
diff --git a/common/action.c b/common/action.c
index ec8eeae7b..1f15bd091 100644
--- a/common/action.c
+++ b/common/action.c
@@ -518,7 +518,12 @@ bool is_tap_key(keypos_t key)
518 case ACT_RMODS_TAP: 518 case ACT_RMODS_TAP:
519 case ACT_LAYER_TAP: 519 case ACT_LAYER_TAP:
520 case ACT_LAYER_TAP_EXT: 520 case ACT_LAYER_TAP_EXT:
521 return true; 521 switch (action.layer_tap.code) {
522 case 0x00 ... 0xdf:
523 case OP_TAP_TOGGLE:
524 return true;
525 }
526 return false;
522 case ACT_MACRO: 527 case ACT_MACRO:
523 case ACT_FUNCTION: 528 case ACT_FUNCTION:
524 if (action.func.opt & FUNC_TAP) { return true; } 529 if (action.func.opt & FUNC_TAP) { return true; }
diff --git a/common/action_code.h b/common/action_code.h
index bc40e2c6f..32ef07216 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -70,13 +70,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
70 * 1001|oopp|BBBB BBBB 8-bit Bitwise Operation??? 70 * 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
71 * 71 *
72 * ACT_LAYER_TAP(101x): 72 * ACT_LAYER_TAP(101x):
73 * 101E|LLLL| keycode On/Off with tap key 73 * 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP]
74 * 101E|LLLL|1110 mods On/Off with modifiers(0xE0-EF) 74 * 101E|LLLL|1110 mods On/Off with modifiers (0xE0-EF)[NOT TAP]
75 * 101E|LLLL|1111 0000 Invert with tap toggle(0xF0) 75 * 101E|LLLL|1111 0000 Invert with tap toggle (0xF0) [TAP]
76 * 101E|LLLL|1111 0001 On/Off 76 * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP]
77 * 101E|LLLL|1111 0010 Off/On 77 * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP]
78 * 101E|LLLL|1111 0011 Set/Clear 78 * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP]
79 * 101E|LLLL|1111 xxxx Reserved(0xF4-FF) 79 * 101E|LLLL|1111 xxxx Reserved (0xF4-FF)
80 * ELLLL: layer 0-31(E: extra bit for layer 16-31) 80 * ELLLL: layer 0-31(E: extra bit for layer 16-31)
81 * 81 *
82 * 82 *
diff --git a/common/keyboard.c b/common/keyboard.c
index 1e3fb510a..b03b124d7 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -39,6 +39,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
39#ifdef SERIAL_MOUSE_ENABLE 39#ifdef SERIAL_MOUSE_ENABLE
40#include "serial_mouse.h" 40#include "serial_mouse.h"
41#endif 41#endif
42#ifdef ADB_MOUSE_ENABLE
43#include "adb.h"
44#endif
42 45
43 46
44#ifdef MATRIX_HAS_GHOST 47#ifdef MATRIX_HAS_GHOST
@@ -69,6 +72,9 @@ void keyboard_init(void)
69#ifdef SERIAL_MOUSE_ENABLE 72#ifdef SERIAL_MOUSE_ENABLE
70 serial_mouse_init(); 73 serial_mouse_init();
71#endif 74#endif
75#ifdef ADB_MOUSE_ENABLE
76 adb_mouse_init();
77#endif
72 78
73 79
74#ifdef BOOTMAGIC_ENABLE 80#ifdef BOOTMAGIC_ENABLE
@@ -87,6 +93,9 @@ void keyboard_init(void)
87void keyboard_task(void) 93void keyboard_task(void)
88{ 94{
89 static matrix_row_t matrix_prev[MATRIX_ROWS]; 95 static matrix_row_t matrix_prev[MATRIX_ROWS];
96#ifdef MATRIX_HAS_GHOST
97 static matrix_row_t matrix_ghost[MATRIX_ROWS];
98#endif
90 static uint8_t led_status = 0; 99 static uint8_t led_status = 0;
91 matrix_row_t matrix_row = 0; 100 matrix_row_t matrix_row = 0;
92 matrix_row_t matrix_change = 0; 101 matrix_row_t matrix_change = 0;
@@ -96,13 +105,21 @@ void keyboard_task(void)
96 matrix_row = matrix_get_row(r); 105 matrix_row = matrix_get_row(r);
97 matrix_change = matrix_row ^ matrix_prev[r]; 106 matrix_change = matrix_row ^ matrix_prev[r];
98 if (matrix_change) { 107 if (matrix_change) {
99 if (debug_matrix) matrix_print();
100#ifdef MATRIX_HAS_GHOST 108#ifdef MATRIX_HAS_GHOST
101 if (has_ghost_in_row(r)) { 109 if (has_ghost_in_row(r)) {
102 matrix_prev[r] = matrix_row; 110 /* Keep track of whether ghosted status has changed for
111 * debugging. But don't update matrix_prev until un-ghosted, or
112 * the last key would be lost.
113 */
114 if (debug_matrix && matrix_ghost[r] != matrix_row) {
115 matrix_print();
116 }
117 matrix_ghost[r] = matrix_row;
103 continue; 118 continue;
104 } 119 }
120 matrix_ghost[r] = matrix_row;
105#endif 121#endif
122 if (debug_matrix) matrix_print();
106 for (uint8_t c = 0; c < MATRIX_COLS; c++) { 123 for (uint8_t c = 0; c < MATRIX_COLS; c++) {
107 if (matrix_change & ((matrix_row_t)1<<c)) { 124 if (matrix_change & ((matrix_row_t)1<<c)) {
108 action_exec((keyevent_t){ 125 action_exec((keyevent_t){
@@ -136,6 +153,10 @@ MATRIX_LOOP_END:
136 serial_mouse_task(); 153 serial_mouse_task();
137#endif 154#endif
138 155
156#ifdef ADB_MOUSE_ENABLE
157 adb_mouse_task();
158#endif
159
139 // update LED 160 // update LED
140 if (led_status != host_keyboard_leds()) { 161 if (led_status != host_keyboard_leds()) {
141 led_status = host_keyboard_leds(); 162 led_status = host_keyboard_leds();
diff --git a/common/keymap.c b/common/keymap.c
index 4c0b61b8c..9f4fab521 100644
--- a/common/keymap.c
+++ b/common/keymap.c
@@ -131,7 +131,7 @@ static action_t keycode_to_action(uint8_t keycode)
131 case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: 131 case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
132 action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); 132 action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
133 break; 133 break;
134 case KC_AUDIO_MUTE ... KC_WWW_FAVORITES: 134 case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
135 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); 135 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
136 break; 136 break;
137 case KC_MS_UP ... KC_MS_ACCEL2: 137 case KC_MS_UP ... KC_MS_ACCEL2:
diff --git a/doc/keycode.txt b/doc/keycode.txt
index 760c726e3..44d7e27cd 100644
--- a/doc/keycode.txt
+++ b/doc/keycode.txt
@@ -174,7 +174,7 @@ KC_CLEAR_AGAIN A2 Keyboard Clear/Again
174KC_CRSEL A3 Keyboard CrSel/Props 174KC_CRSEL A3 Keyboard CrSel/Props
175KC_EXSEL A4 Keyboard ExSel 175KC_EXSEL A4 Keyboard ExSel
176/* Modifiers */ 176/* Modifiers */
177KC_LCTRL KC_LCTRL E0 Keyboard LeftControl 177KC_LCTRL KC_LCTL E0 Keyboard LeftControl
178KC_LSHIFT KC_LSFT E1 Keyboard LeftShift 178KC_LSHIFT KC_LSFT E1 Keyboard LeftShift
179KC_LALT E2 Keyboard LeftAlt 179KC_LALT E2 Keyboard LeftAlt
180KC_LGUI E3 Keyboard Left GUI(Windows/Apple/Meta key) 180KC_LGUI E3 Keyboard Left GUI(Windows/Apple/Meta key)
diff --git a/doc/keymap.md b/doc/keymap.md
index 9d986a8c5..d4a129b20 100644
--- a/doc/keymap.md
+++ b/doc/keymap.md
@@ -198,7 +198,7 @@ There are 8 modifiers which has discrimination between left and right.
198 See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes. 198 See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes.
199 199
200 In regard to implementation side most of keycodes are identical with [HID usage][HID_usage](pdf) sent to host for real and some virtual keycodes are defined to support special actions. 200 In regard to implementation side most of keycodes are identical with [HID usage][HID_usage](pdf) sent to host for real and some virtual keycodes are defined to support special actions.
201[HID_usage]: http://www.usb.org/developers/devclass_docs/Hut1_11.pdf 201[HID_usage]: http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
202 202
203 203
204 204
diff --git a/protocol.mk b/protocol.mk
index 726f658a0..54913329e 100644
--- a/protocol.mk
+++ b/protocol.mk
@@ -46,5 +46,9 @@ ifdef SERIAL_MOUSE_USE_UART
46 SRC += $(PROTOCOL_DIR)/serial_uart.c 46 SRC += $(PROTOCOL_DIR)/serial_uart.c
47endif 47endif
48 48
49ifdef ADB_MOUSE_ENABLE
50 OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE
51endif
52
49# Search Path 53# Search Path
50VPATH += $(TMK_DIR)/protocol 54VPATH += $(TMK_DIR)/protocol
diff --git a/protocol/adb.c b/protocol/adb.c
index bbff66df0..5c6c99b4f 100644
--- a/protocol/adb.c
+++ b/protocol/adb.c
@@ -60,6 +60,7 @@ static inline void place_bit1(void);
60static inline void send_byte(uint8_t data); 60static inline void send_byte(uint8_t data);
61static inline uint16_t wait_data_lo(uint16_t us); 61static inline uint16_t wait_data_lo(uint16_t us);
62static inline uint16_t wait_data_hi(uint16_t us); 62static inline uint16_t wait_data_hi(uint16_t us);
63static inline uint16_t adb_host_dev_recv(uint8_t device);
63 64
64 65
65void adb_host_init(void) 66void adb_host_init(void)
@@ -121,12 +122,33 @@ bool adb_host_psw(void)
121// 122//
122// [from Apple IIgs Hardware Reference Second Edition] 123// [from Apple IIgs Hardware Reference Second Edition]
123 124
125enum {
126 ADDR_KEYB = 0x20,
127 ADDR_MOUSE = 0x30
128};
129
124uint16_t adb_host_kbd_recv(void) 130uint16_t adb_host_kbd_recv(void)
125{ 131{
132 return adb_host_dev_recv(ADDR_KEYB);
133}
134
135#ifdef ADB_MOUSE_ENABLE
136void adb_mouse_init(void) {
137 return;
138}
139
140uint16_t adb_host_mouse_recv(void)
141{
142 return adb_host_dev_recv(ADDR_MOUSE);
143}
144#endif
145
146static inline uint16_t adb_host_dev_recv(uint8_t device)
147{
126 uint16_t data = 0; 148 uint16_t data = 0;
127 cli(); 149 cli();
128 attention(); 150 attention();
129 send_byte(0x2C); // Addr:Keyboard(0010), Cmd:Talk(11), Register0(00) 151 send_byte(device|0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
130 place_bit0(); // Stopbit(0) 152 place_bit0(); // Stopbit(0)
131 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored 153 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
132 sei(); 154 sei();
diff --git a/protocol/adb.h b/protocol/adb.h
index bfe598bbf..b4b3633cf 100644
--- a/protocol/adb.h
+++ b/protocol/adb.h
@@ -56,7 +56,11 @@ POSSIBILITY OF SUCH DAMAGE.
56void adb_host_init(void); 56void adb_host_init(void);
57bool adb_host_psw(void); 57bool adb_host_psw(void);
58uint16_t adb_host_kbd_recv(void); 58uint16_t adb_host_kbd_recv(void);
59uint16_t adb_host_mouse_recv(void);
59void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); 60void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
60void adb_host_kbd_led(uint8_t led); 61void adb_host_kbd_led(uint8_t led);
62void adb_mouse_task(void);
63void adb_mouse_init(void);
64
61 65
62#endif 66#endif
diff --git a/protocol/ibm4704.c b/protocol/ibm4704.c
index 10e229fd1..a10a5e74d 100644
--- a/protocol/ibm4704.c
+++ b/protocol/ibm4704.c
@@ -4,6 +4,7 @@ Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
4#include <stdbool.h> 4#include <stdbool.h>
5#include <util/delay.h> 5#include <util/delay.h>
6#include "debug.h" 6#include "debug.h"
7#include "ring_buffer.h"
7#include "ibm4704.h" 8#include "ibm4704.h"
8 9
9 10
@@ -20,7 +21,9 @@ uint8_t ibm4704_error = 0;
20 21
21void ibm4704_init(void) 22void ibm4704_init(void)
22{ 23{
23 inhibit(); 24 IBM4704_INT_INIT();
25 IBM4704_INT_ON();
26 idle();
24} 27}
25 28
26/* 29/*
@@ -47,6 +50,8 @@ uint8_t ibm4704_send(uint8_t data)
47 bool parity = true; // odd parity 50 bool parity = true; // odd parity
48 ibm4704_error = 0; 51 ibm4704_error = 0;
49 52
53 IBM4704_INT_OFF();
54
50 /* Request to send */ 55 /* Request to send */
51 idle(); 56 idle();
52 clock_lo(); 57 clock_lo();
@@ -57,7 +62,6 @@ uint8_t ibm4704_send(uint8_t data)
57 /* Data bit */ 62 /* Data bit */
58 for (uint8_t i = 0; i < 8; i++) { 63 for (uint8_t i = 0; i < 8; i++) {
59 WAIT(clock_hi, 100, 0x40+i); 64 WAIT(clock_hi, 100, 0x40+i);
60 //_delay_us(5);
61 if (data&(1<<i)) { 65 if (data&(1<<i)) {
62 parity = !parity; 66 parity = !parity;
63 data_hi(); 67 data_hi();
@@ -79,28 +83,25 @@ uint8_t ibm4704_send(uint8_t data)
79 /* End */ 83 /* End */
80 WAIT(data_lo, 100, 0x36); 84 WAIT(data_lo, 100, 0x36);
81 85
82 inhibit(); 86 idle();
83 _delay_us(200); // wait to recover clock to hi 87 IBM4704_INT_ON();
84 return 0; 88 return 0;
85ERROR: 89ERROR:
86 inhibit(); 90 idle();
87 if (ibm4704_error >= 0x30) { 91 if (ibm4704_error > 0x30) {
88 xprintf("x%02X ", ibm4704_error); 92 xprintf("S:%02X ", ibm4704_error);
89 } 93 }
90 _delay_us(200); // wait to recover clock to hi 94 IBM4704_INT_ON();
91 return -1; 95 return -1;
92} 96}
93 97
94/* receive data when host want else inhibit communication */ 98/* wait forever to receive data */
95uint8_t ibm4704_recv_response(void) 99uint8_t ibm4704_recv_response(void)
96{ 100{
97 // 250 * 100us(wait start bit in ibm4704_recv) 101 while (!rbuf_has_data()) {
98 uint8_t data = 0; 102 _delay_ms(1);
99 uint8_t try = 250; 103 }
100 do { 104 return rbuf_dequeue();
101 data = ibm4704_recv();
102 } while (try-- && ibm4704_error);
103 return data;
104} 105}
105 106
106/* 107/*
@@ -121,49 +122,69 @@ Stop bit: Keyboard pulls down Data line to lo after 9th clock.
121*/ 122*/
122uint8_t ibm4704_recv(void) 123uint8_t ibm4704_recv(void)
123{ 124{
124 uint8_t data = 0; 125 if (rbuf_has_data()) {
125 bool parity = true; // odd parity 126 return rbuf_dequeue();
126 ibm4704_error = IBM4704_ERR_NONE; 127 } else {
127 128 return -1;
128 idle();
129 _delay_us(5); // wait for line settles
130
131 /* start bit */
132 WAIT(clock_lo, 100, 0x11); // wait for keyboard to send
133 WAIT(data_hi, 100, 0x12); // can be delayed that long
134
135 WAIT(clock_hi, 100, 0x13); // first rising edge which can take longer
136 /* data */
137 for (uint8_t i = 0; i < 8; i++) {
138 WAIT(clock_hi, 100, 0x20+i);
139 //_delay_us(5);
140 if (data_in()) {
141 parity = !parity;
142 data |= (1<<i);
143 }
144 WAIT(clock_lo, 150, 0x28+i);
145 } 129 }
130}
146 131
147 /* parity */ 132ISR(IBM4704_INT_VECT)
148 WAIT(clock_hi, 100, 0x17); 133{
149 if (data_in() != parity) { 134 static enum {
150 ibm4704_error = IBM4704_ERR_PARITY; 135 INIT, START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY,
151 goto ERROR; 136 } state = INIT;
152 } 137 // LSB first
153 WAIT(clock_lo, 150, 0x18); 138 static uint8_t data = 0;
154 139 // Odd parity
155 /* stop bit */ 140 static uint8_t parity = false;
156 WAIT(clock_hi, 100, 0x19);
157 WAIT(data_lo, 1, 0x19);
158 141
159 inhibit(); 142 ibm4704_error = 0;
160 _delay_us(200); // wait to recover clock to hi 143 // return unless falling edge
161 return data; 144 if (clock_in()) { goto RETURN; } // why this occurs?
162ERROR: 145
163 if (ibm4704_error > 0x12) { 146 state++;
164 xprintf("x%02X ", ibm4704_error); 147 switch (state) {
148 case START:
149 // Data:Low
150 WAIT(data_hi, 10, state);
151 break;
152 case BIT0:
153 case BIT1:
154 case BIT2:
155 case BIT3:
156 case BIT4:
157 case BIT5:
158 case BIT6:
159 case BIT7:
160 data >>= 1;
161 if (data_in()) {
162 data |= 0x80;
163 parity = !parity;
164 }
165 break;
166 case PARITY:
167 if (data_in()) {
168 parity = !parity;
169 }
170 if (!parity)
171 goto ERROR;
172 rbuf_enqueue(data);
173 ibm4704_error = IBM4704_ERR_NONE;
174 goto DONE;
175 break;
176 default:
177 goto ERROR;
165 } 178 }
166 inhibit(); 179 goto RETURN;
167 _delay_us(200); // wait to recover clock to hi 180ERROR:
168 return -1; 181 ibm4704_error = state;
182 while (ibm4704_send(0xFE)) _delay_ms(1); // resend
183 xprintf("R:%02X%02X\n", state, data);
184DONE:
185 state = INIT;
186 data = 0;
187 parity = false;
188RETURN:
189 return;
169} 190}
diff --git a/protocol/pjrc.mk b/protocol/pjrc.mk
index 36585de7d..2b1ba2cbf 100644
--- a/protocol/pjrc.mk
+++ b/protocol/pjrc.mk
@@ -11,6 +11,10 @@ ifdef MOUSEKEY_ENABLE
11 SRC += $(PJRC_DIR)/usb_mouse.c 11 SRC += $(PJRC_DIR)/usb_mouse.c
12endif 12endif
13 13
14ifdef ADB_MOUSE_ENABLE
15 SRC += $(PJRC_DIR)/usb_mouse.c
16endif
17
14ifdef PS2_MOUSE_ENABLE 18ifdef PS2_MOUSE_ENABLE
15 SRC += $(PJRC_DIR)/usb_mouse.c 19 SRC += $(PJRC_DIR)/usb_mouse.c
16endif 20endif
diff --git a/ring_buffer.h b/ring_buffer.h
new file mode 100644
index 000000000..7bdebbcf3
--- /dev/null
+++ b/ring_buffer.h
@@ -0,0 +1,53 @@
1#ifndef RING_BUFFER_H
2#define RING_BUFFER_H
3/*--------------------------------------------------------------------
4 * Ring buffer to store scan codes from keyboard
5 *------------------------------------------------------------------*/
6#define RBUF_SIZE 32
7static uint8_t rbuf[RBUF_SIZE];
8static uint8_t rbuf_head = 0;
9static uint8_t rbuf_tail = 0;
10static inline void rbuf_enqueue(uint8_t data)
11{
12 uint8_t sreg = SREG;
13 cli();
14 uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
15 if (next != rbuf_tail) {
16 rbuf[rbuf_head] = data;
17 rbuf_head = next;
18 } else {
19 print("rbuf: full\n");
20 }
21 SREG = sreg;
22}
23static inline uint8_t rbuf_dequeue(void)
24{
25 uint8_t val = 0;
26
27 uint8_t sreg = SREG;
28 cli();
29 if (rbuf_head != rbuf_tail) {
30 val = rbuf[rbuf_tail];
31 rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
32 }
33 SREG = sreg;
34
35 return val;
36}
37static inline bool rbuf_has_data(void)
38{
39 uint8_t sreg = SREG;
40 cli();
41 bool has_data = (rbuf_head != rbuf_tail);
42 SREG = sreg;
43 return has_data;
44}
45static inline void rbuf_clear(void)
46{
47 uint8_t sreg = SREG;
48 cli();
49 rbuf_head = rbuf_tail = 0;
50 SREG = sreg;
51}
52
53#endif /* RING_BUFFER_H */
diff --git a/rules.mk b/rules.mk
index d06756638..a790f874b 100644
--- a/rules.mk
+++ b/rules.mk
@@ -440,7 +440,11 @@ flip-ee: $(TARGET).hex $(TARGET).eep
440 $(REMOVE) $(TARGET)eep.hex 440 $(REMOVE) $(TARGET)eep.hex
441 441
442dfu-ee: $(TARGET).hex $(TARGET).eep 442dfu-ee: $(TARGET).hex $(TARGET).eep
443 dfu-programmer $(MCU) eeprom-flash $(TARGET).eep 443ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1)))
444 dfu-programmer $(MCU) flash --eeprom $(TARGET).eep
445else
446 dfu-programmer $(MCU) flash-eeprom $(TARGET).eep
447endif
444 dfu-programmer $(MCU) reset 448 dfu-programmer $(MCU) reset
445 449
446 450