]> git.friedersdorff.com Git - max/tmk_keyboard.git/commitdiff
xt_usb: read data on falling edge soft/hard reset
authortmk <hasu@tmk-kbd.com>
Wed, 28 Feb 2018 06:48:06 +0000 (15:48 +0900)
committertmk <hasu@tmk-kbd.com>
Wed, 14 Mar 2018 12:32:22 +0000 (21:32 +0900)
See https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol
- read data on falling edge of clock
- add soft reset and hard reset

converter/xt_usb/Makefile
converter/xt_usb/config.h
tmk_core/protocol.mk
tmk_core/protocol/xt_interrupt.c
tmk_core/protocol/xt_io.h
tmk_core/protocol/xt_io_avr.c

index 395115e3990502f7b01a83ccbf8d2b73d113f3db..e7fb6c8adc2e62db48eb78115302b35337902293 100644 (file)
@@ -11,7 +11,9 @@ TMK_DIR = ../../tmk_core
 TARGET_DIR = .
 
 # project specific files
-SRC =  matrix.c \
+SRC =  protocol/xt_interrupt.c \
+       protocol/xt_io_avr.c \
+       matrix.c \
        led.c
 
 ifdef KEYMAP
@@ -61,7 +63,7 @@ ARCH = AVR8
 F_USB = $(F_CPU)
 
 # Interrupt driven control endpoint task(+60)
-#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
 
 
 # Boot Section Size in *bytes*
@@ -71,6 +73,7 @@ F_USB = $(F_CPU)
 #   LUFA bootloader  4096
 #   USBaspLoader     2048
 OPT_DEFS += -DBOOTLOADER_SIZE=512
+#OPT_DEFS += -DBOOTLOADER_SIZE=4096
 
 
 # Build Options
@@ -84,11 +87,6 @@ COMMAND_ENABLE = yes    # Commands for debug and configuration
 NKRO_ENABLE = yes      # USB Nkey Rollover
 
 
-# XT/2 Options
-#
-XT_USE_INT = yes       # uses external interrupt for falling edge of PS/2 clock pin
-
-
 # Optimize size but this may cause error "relocation truncated to fit"
 #EXTRALDFLAGS = -Wl,--relax
 
index a9f44ca8cdbb9f9f9255a6eef761e0e231b307e4..24bf3c330718d0155096452a7efa70edc0fcdc5b 100644 (file)
@@ -45,8 +45,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /*
  * XT Pin interrupt
  */
-#ifdef XT_USE_INT
-/* uses INT1 for clock line(ATMega32U4) */
 #define XT_CLOCK_PORT  PORTD
 #define XT_CLOCK_PIN   PIND
 #define XT_CLOCK_DDR   DDRD
@@ -55,9 +53,23 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define XT_DATA_PIN    PIND
 #define XT_DATA_DDR    DDRD
 #define XT_DATA_BIT    0
+#define XT_RST_PORT    PORTB
+#define XT_RST_PIN     PINB
+#define XT_RST_DDR     DDRB
+#define XT_RST_BIT     7
+
+/* hard reset: low pulse for 500ms and after that HiZ for safety */
+#define XT_RESET() do { \
+    XT_RST_PORT &= ~(1<<XT_RST_BIT);  \
+    XT_RST_DDR  |=  (1<<XT_RST_BIT);  \
+    _delay_ms(500);                   \
+    XT_RST_DDR  &= ~(1<<XT_RST_BIT);  \
+} while (0)
+
+/* INT1 for falling edge of clock line */
 #define XT_INT_INIT()  do {    \
     EICRA |= ((1<<ISC11) |      \
-              (1<<ISC10));      \
+              (0<<ISC10));      \
 } while (0)
 #define XT_INT_ON()  do {      \
     EIMSK |= (1<<INT1);         \
@@ -66,6 +78,5 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
     EIMSK &= ~(1<<INT1);        \
 } while (0)
 #define XT_INT_VECT    INT1_vect
-#endif
 
 #endif
index 2bf05742f8782f57d4dbccb537cbd1ee768b49f2..47265d80489e846d33cde61ea1fe6bca1f256642 100644 (file)
@@ -26,13 +26,6 @@ ifeq (yes,$(strip $(PS2_USE_USART)))
 endif
 
 
-ifeq (yes,$(strip $(XT_USE_INT)))
-    SRC += protocol/xt_interrupt.c
-    SRC += protocol/xt_io_avr.c
-    OPT_DEFS += -DXT_USE_INT
-endif
-
-
 ifeq (yes,$(strip $(SERIAL_MOUSE_MICROSOFT_ENABLE)))
     SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c
     OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \
index 94b47db466a1a69e1c4558bc887b392b78fd2926..8c8408bac6335e1754626a06ce84b9db9921da0a 100644 (file)
@@ -51,6 +51,17 @@ POSSIBILITY OF SUCH DAMAGE.
 void xt_host_init(void)
 {
     XT_INT_INIT();
+
+    /* hard reset */
+#ifdef XT_RESET
+    XT_RESET();
+#endif
+
+    /* soft reset: pull clock line down for 20ms */
+    XT_INT_OFF();
+    data_lo(); clock_lo();
+    _delay_ms(20);
+    data_in(); clock_in();
     XT_INT_ON();
 }
 
@@ -66,29 +77,40 @@ uint8_t xt_host_recv(void)
 
 ISR(XT_INT_VECT)
 {
-    static uint8_t state = 0;
+    /*
+     * XT signal format consits of 10 or 9 clocks and sends start bits and 8-bit data,
+     * which should be read on falling edge of clock.
+     *
+     *  start(0), start(1), bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7
+     *
+     * Original IBM XT keyboard sends start(0) bit while some of clones don't.
+     * Start(0) bit is read as low on data line while start(1) as high.
+     *
+     * https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol
+     */
+    static enum {
+        START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, END
+    } state = START;
     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;
+    // This is needed if using PCINT which can be called on both falling and rising edge
+    if (clock_in()) return;
+
+    switch (state) {
+        case START:
+            // ignore start(0) bit
+            if (!data_in()) return;
+            break;
+        case BIT0 ... BIT7:
+            data >>= 1;
+            if (data_in())
+                data |= 0x80;
+            break;
+    }
+    if (++state == END) {
+        pbuf_enqueue(data);
+        state = START;
+        data = 0;
     }
-    goto RETURN;
-END:
-    pbuf_enqueue(data);
-DONE:
-    state = 0;
-    data = 0;
-RETURN:
     return;
 }
index 2e5f31b20270ec5e1b222e241b56cddd82efed9e..4198e6557f7b9c4f0d63805d1705bd1c1157783d 100644 (file)
@@ -4,4 +4,7 @@
 bool clock_in(void);
 bool data_in(void);
 
+void clock_lo(void);
+void data_lo(void);
+
 #endif
index 6cd153a139d71dd5bc59c315defed78d5f33d5c8..7775be7f3b18c29ac63823a307b790d68da8a6fe 100644 (file)
@@ -32,3 +32,15 @@ bool data_in(void)
     _delay_us(1);
     return XT_DATA_PIN&(1<<XT_DATA_BIT);
 }
+
+void clock_lo(void)
+{
+    XT_CLOCK_PORT &= ~(1<<XT_CLOCK_BIT);
+    XT_CLOCK_DDR  |=  (1<<XT_CLOCK_BIT);
+}
+
+void data_lo(void)
+{
+    XT_DATA_PORT &= ~(1<<XT_DATA_BIT);
+    XT_DATA_DDR  |=  (1<<XT_DATA_BIT);
+}