diff --git a/common/action.c b/common/action.c
index ec8eeae7bc..1f15bd0918 100644
--- a/common/action.c
+++ b/common/action.c
@@ -518,7 +518,12 @@ bool is_tap_key(keypos_t key)
case ACT_RMODS_TAP:
case ACT_LAYER_TAP:
case ACT_LAYER_TAP_EXT:
- return true;
+ switch (action.layer_tap.code) {
+ case 0x00 ... 0xdf:
+ case OP_TAP_TOGGLE:
+ return true;
+ }
+ return false;
case ACT_MACRO:
case ACT_FUNCTION:
if (action.func.opt & FUNC_TAP) { return true; }
diff --git a/common/action_code.h b/common/action_code.h
index bc40e2c6fb..32ef07216d 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -70,13 +70,13 @@ along with this program. If not, see .
* 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
*
* ACT_LAYER_TAP(101x):
- * 101E|LLLL| keycode On/Off with tap key
- * 101E|LLLL|1110 mods On/Off with modifiers(0xE0-EF)
- * 101E|LLLL|1111 0000 Invert with tap toggle(0xF0)
- * 101E|LLLL|1111 0001 On/Off
- * 101E|LLLL|1111 0010 Off/On
- * 101E|LLLL|1111 0011 Set/Clear
- * 101E|LLLL|1111 xxxx Reserved(0xF4-FF)
+ * 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP]
+ * 101E|LLLL|1110 mods On/Off with modifiers (0xE0-EF)[NOT TAP]
+ * 101E|LLLL|1111 0000 Invert with tap toggle (0xF0) [TAP]
+ * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP]
+ * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP]
+ * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP]
+ * 101E|LLLL|1111 xxxx Reserved (0xF4-FF)
* ELLLL: layer 0-31(E: extra bit for layer 16-31)
*
*
diff --git a/common/keyboard.c b/common/keyboard.c
index 1e3fb510a4..b03b124d76 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -39,6 +39,9 @@ along with this program. If not, see .
#ifdef SERIAL_MOUSE_ENABLE
#include "serial_mouse.h"
#endif
+#ifdef ADB_MOUSE_ENABLE
+#include "adb.h"
+#endif
#ifdef MATRIX_HAS_GHOST
@@ -69,6 +72,9 @@ void keyboard_init(void)
#ifdef SERIAL_MOUSE_ENABLE
serial_mouse_init();
#endif
+#ifdef ADB_MOUSE_ENABLE
+ adb_mouse_init();
+#endif
#ifdef BOOTMAGIC_ENABLE
@@ -87,6 +93,9 @@ void keyboard_init(void)
void keyboard_task(void)
{
static matrix_row_t matrix_prev[MATRIX_ROWS];
+#ifdef MATRIX_HAS_GHOST
+ static matrix_row_t matrix_ghost[MATRIX_ROWS];
+#endif
static uint8_t led_status = 0;
matrix_row_t matrix_row = 0;
matrix_row_t matrix_change = 0;
@@ -96,13 +105,21 @@ void keyboard_task(void)
matrix_row = matrix_get_row(r);
matrix_change = matrix_row ^ matrix_prev[r];
if (matrix_change) {
- if (debug_matrix) matrix_print();
#ifdef MATRIX_HAS_GHOST
if (has_ghost_in_row(r)) {
- matrix_prev[r] = matrix_row;
+ /* Keep track of whether ghosted status has changed for
+ * debugging. But don't update matrix_prev until un-ghosted, or
+ * the last key would be lost.
+ */
+ if (debug_matrix && matrix_ghost[r] != matrix_row) {
+ matrix_print();
+ }
+ matrix_ghost[r] = matrix_row;
continue;
}
+ matrix_ghost[r] = matrix_row;
#endif
+ if (debug_matrix) matrix_print();
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_change & ((matrix_row_t)1<
#include
#include
#include "debug.h"
+#include "ring_buffer.h"
#include "ibm4704.h"
@@ -20,7 +21,9 @@ uint8_t ibm4704_error = 0;
void ibm4704_init(void)
{
- inhibit();
+ IBM4704_INT_INIT();
+ IBM4704_INT_ON();
+ idle();
}
/*
@@ -47,6 +50,8 @@ uint8_t ibm4704_send(uint8_t data)
bool parity = true; // odd parity
ibm4704_error = 0;
+ IBM4704_INT_OFF();
+
/* Request to send */
idle();
clock_lo();
@@ -57,7 +62,6 @@ uint8_t ibm4704_send(uint8_t data)
/* Data bit */
for (uint8_t i = 0; i < 8; i++) {
WAIT(clock_hi, 100, 0x40+i);
- //_delay_us(5);
if (data&(1<= 0x30) {
- xprintf("x%02X ", ibm4704_error);
+ idle();
+ if (ibm4704_error > 0x30) {
+ xprintf("S:%02X ", ibm4704_error);
}
- _delay_us(200); // wait to recover clock to hi
+ IBM4704_INT_ON();
return -1;
}
-/* receive data when host want else inhibit communication */
+/* wait forever to receive data */
uint8_t ibm4704_recv_response(void)
{
- // 250 * 100us(wait start bit in ibm4704_recv)
- uint8_t data = 0;
- uint8_t try = 250;
- do {
- data = ibm4704_recv();
- } while (try-- && ibm4704_error);
- return data;
+ while (!rbuf_has_data()) {
+ _delay_ms(1);
+ }
+ return rbuf_dequeue();
}
/*
@@ -121,49 +122,69 @@ Stop bit: Keyboard pulls down Data line to lo after 9th clock.
*/
uint8_t ibm4704_recv(void)
{
- uint8_t data = 0;
- bool parity = true; // odd parity
- ibm4704_error = IBM4704_ERR_NONE;
-
- idle();
- _delay_us(5); // wait for line settles
-
- /* start bit */
- WAIT(clock_lo, 100, 0x11); // wait for keyboard to send
- WAIT(data_hi, 100, 0x12); // can be delayed that long
-
- WAIT(clock_hi, 100, 0x13); // first rising edge which can take longer
- /* data */
- for (uint8_t i = 0; i < 8; i++) {
- WAIT(clock_hi, 100, 0x20+i);
- //_delay_us(5);
- if (data_in()) {
- parity = !parity;
- data |= (1< 0x12) {
- xprintf("x%02X ", ibm4704_error);
- }
- inhibit();
- _delay_us(200); // wait to recover clock to hi
- return -1;
+}
+
+ISR(IBM4704_INT_VECT)
+{
+ static enum {
+ INIT, START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY,
+ } state = INIT;
+ // LSB first
+ static uint8_t data = 0;
+ // Odd parity
+ static uint8_t parity = false;
+
+ ibm4704_error = 0;
+ // return unless falling edge
+ if (clock_in()) { goto RETURN; } // why this occurs?
+
+ state++;
+ switch (state) {
+ case START:
+ // Data:Low
+ WAIT(data_hi, 10, state);
+ break;
+ case BIT0:
+ case BIT1:
+ case BIT2:
+ case BIT3:
+ case BIT4:
+ case BIT5:
+ case BIT6:
+ case BIT7:
+ data >>= 1;
+ if (data_in()) {
+ data |= 0x80;
+ parity = !parity;
+ }
+ break;
+ case PARITY:
+ if (data_in()) {
+ parity = !parity;
+ }
+ if (!parity)
+ goto ERROR;
+ rbuf_enqueue(data);
+ ibm4704_error = IBM4704_ERR_NONE;
+ goto DONE;
+ break;
+ default:
+ goto ERROR;
+ }
+ goto RETURN;
+ERROR:
+ ibm4704_error = state;
+ while (ibm4704_send(0xFE)) _delay_ms(1); // resend
+ xprintf("R:%02X%02X\n", state, data);
+DONE:
+ state = INIT;
+ data = 0;
+ parity = false;
+RETURN:
+ return;
}
diff --git a/protocol/pjrc.mk b/protocol/pjrc.mk
index 36585de7df..2b1ba2cbfb 100644
--- a/protocol/pjrc.mk
+++ b/protocol/pjrc.mk
@@ -11,6 +11,10 @@ ifdef MOUSEKEY_ENABLE
SRC += $(PJRC_DIR)/usb_mouse.c
endif
+ifdef ADB_MOUSE_ENABLE
+ SRC += $(PJRC_DIR)/usb_mouse.c
+endif
+
ifdef PS2_MOUSE_ENABLE
SRC += $(PJRC_DIR)/usb_mouse.c
endif
diff --git a/ring_buffer.h b/ring_buffer.h
new file mode 100644
index 0000000000..7bdebbcf34
--- /dev/null
+++ b/ring_buffer.h
@@ -0,0 +1,53 @@
+#ifndef RING_BUFFER_H
+#define RING_BUFFER_H
+/*--------------------------------------------------------------------
+ * Ring buffer to store scan codes from keyboard
+ *------------------------------------------------------------------*/
+#define RBUF_SIZE 32
+static uint8_t rbuf[RBUF_SIZE];
+static uint8_t rbuf_head = 0;
+static uint8_t rbuf_tail = 0;
+static inline void rbuf_enqueue(uint8_t data)
+{
+ uint8_t sreg = SREG;
+ cli();
+ uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
+ if (next != rbuf_tail) {
+ rbuf[rbuf_head] = data;
+ rbuf_head = next;
+ } else {
+ print("rbuf: full\n");
+ }
+ SREG = sreg;
+}
+static inline uint8_t rbuf_dequeue(void)
+{
+ uint8_t val = 0;
+
+ uint8_t sreg = SREG;
+ cli();
+ if (rbuf_head != rbuf_tail) {
+ val = rbuf[rbuf_tail];
+ rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
+ }
+ SREG = sreg;
+
+ return val;
+}
+static inline bool rbuf_has_data(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ bool has_data = (rbuf_head != rbuf_tail);
+ SREG = sreg;
+ return has_data;
+}
+static inline void rbuf_clear(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ rbuf_head = rbuf_tail = 0;
+ SREG = sreg;
+}
+
+#endif /* RING_BUFFER_H */
diff --git a/rules.mk b/rules.mk
index d06756638c..a790f874bc 100644
--- a/rules.mk
+++ b/rules.mk
@@ -440,7 +440,11 @@ flip-ee: $(TARGET).hex $(TARGET).eep
$(REMOVE) $(TARGET)eep.hex
dfu-ee: $(TARGET).hex $(TARGET).eep
- dfu-programmer $(MCU) eeprom-flash $(TARGET).eep
+ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1)))
+ dfu-programmer $(MCU) flash --eeprom $(TARGET).eep
+else
+ dfu-programmer $(MCU) flash-eeprom $(TARGET).eep
+endif
dfu-programmer $(MCU) reset