]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
A few addition to PS2 documentation.
authorPriyadi Iman Nurcahyo <priyadi@priyadi.net>
Sat, 26 Nov 2016 07:23:55 +0000 (14:23 +0700)
committerPriyadi Iman Nurcahyo <priyadi@priyadi.net>
Sat, 26 Nov 2016 07:23:55 +0000 (14:23 +0700)
readme.md

index 0157b907248af00b7d021a6b9f1a075c9ac37b76..3eb67882ab534d0cc9180fdad085e9ae7554d6e7 100644 (file)
--- a/readme.md
+++ b/readme.md
@@ -1160,41 +1160,131 @@ Please note the USB port can only supply a limited amount of power to the keyboa
 ## PS/2 Mouse Support
 
 Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device.
-In order to do this you must first enable the option in your Makefile.
-
-    PS2_MOUSE_ENABLE = yes
-
-Then, decide whether to use interrupts (better if your microcontroller supports them) or busywait, and enable the relevant option.
-
-    PS2_USE_INT = yes
-    // PS2_USE_BUSYWAIT = yes
-
-If you're using a teensy and have hooked up the clock on your PS/2 device to D1 and the data to D0, you're all set.
-Otherwise, you will need to update the following defines in your `config.h`:
-    
-    #define PS2_CLOCK_PORT  PORTD
-    #define PS2_CLOCK_PIN   PIND
-    #define PS2_CLOCK_DDR   DDRD
-    #define PS2_CLOCK_BIT   1
-
-    #define PS2_DATA_PORT   PORTD
-    #define PS2_DATA_PIN    PIND
-    #define PS2_DATA_DDR    DDRD
-    #define PS2_DATA_BIT    0
-
-And with `PS2_USE_INT` also define these macros:
-
-    #define PS2_INT_INIT()  do {    \
-        EICRA |= ((1<<ISC11) |      \
-                  (0<<ISC10));      \
-    } while (0)
-    #define PS2_INT_ON()  do {      \
-        EIMSK |= (1<<INT1);         \
-    } while (0)
-    #define PS2_INT_OFF() do {      \
-        EIMSK &= ~(1<<INT1);        \
-    } while (0)
-    #define PS2_INT_VECT    INT1_vect
+
+Then, decide whether to use USART (best), interrupts (better) or busywait (not recommended), and enable the relevant option.
+
+### Busywait version
+
+Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
+
+In rules.mk:
+
+```
+PS2_MOUSE_ENABLE = yes
+PS2_USE_BUSYWAIT = yes
+```
+
+In your keyboard config.h:
+
+```
+#ifdef PS2_USE_BUSYWAIT
+#   define PS2_CLOCK_PORT  PORTD
+#   define PS2_CLOCK_PIN   PIND
+#   define PS2_CLOCK_DDR   DDRD
+#   define PS2_CLOCK_BIT   1
+#   define PS2_DATA_PORT   PORTD
+#   define PS2_DATA_PIN    PIND
+#   define PS2_DATA_DDR    DDRD
+#   define PS2_DATA_BIT    2
+#endif
+```
+
+### Interrupt version
+
+The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data.
+
+In rules.mk:
+
+```
+PS2_MOUSE_ENABLE = yes
+PS2_USE_INT = yes
+```
+
+In your keyboard config.h:
+
+```
+#ifdef PS2_USE_INT
+#define PS2_CLOCK_PORT  PORTD
+#define PS2_CLOCK_PIN   PIND
+#define PS2_CLOCK_DDR   DDRD
+#define PS2_CLOCK_BIT   2
+#define PS2_DATA_PORT   PORTD
+#define PS2_DATA_PIN    PIND
+#define PS2_DATA_DDR    DDRD
+#define PS2_DATA_BIT    5
+
+#define PS2_INT_INIT()  do {    \
+    EICRA |= ((1<<ISC21) |      \
+              (0<<ISC20));      \
+} while (0)
+#define PS2_INT_ON()  do {      \
+    EIMSK |= (1<<INT2);         \
+} while (0)
+#define PS2_INT_OFF() do {      \
+    EIMSK &= ~(1<<INT2);        \
+} while (0)
+#define PS2_INT_VECT   INT2_vect
+#endif
+```
+
+### USART version
+
+To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
+
+In rules.mk:
+
+```
+PS2_MOUSE_ENABLE = yes
+PS2_USE_USART = yes
+```
+
+In your keyboard config.h:
+
+```
+#ifdef PS2_USE_USART
+#define PS2_CLOCK_PORT  PORTD
+#define PS2_CLOCK_PIN   PIND
+#define PS2_CLOCK_DDR   DDRD
+#define PS2_CLOCK_BIT   5
+#define PS2_DATA_PORT   PORTD
+#define PS2_DATA_PIN    PIND
+#define PS2_DATA_DDR    DDRD
+#define PS2_DATA_BIT    2
+
+/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
+/* set DDR of CLOCK as input to be slave */
+#define PS2_USART_INIT() do {   \
+    PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);   \
+    PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);     \
+    UCSR1C = ((1 << UMSEL10) |  \
+              (3 << UPM10)   |  \
+              (0 << USBS1)   |  \
+              (3 << UCSZ10)  |  \
+              (0 << UCPOL1));   \
+    UCSR1A = 0;                 \
+    UBRR1H = 0;                 \
+    UBRR1L = 0;                 \
+} while (0)
+#define PS2_USART_RX_INT_ON() do {  \
+    UCSR1B = ((1 << RXCIE1) |       \
+              (1 << RXEN1));        \
+} while (0)
+#define PS2_USART_RX_POLL_ON() do { \
+    UCSR1B = (1 << RXEN1);          \
+} while (0)
+#define PS2_USART_OFF() do {    \
+    UCSR1C = 0;                 \
+    UCSR1B &= ~((1 << RXEN1) |  \
+                (1 << TXEN1));  \
+} while (0)
+#define PS2_USART_RX_READY      (UCSR1A & (1<<RXC1))
+#define PS2_USART_RX_DATA       UDR1
+#define PS2_USART_ERROR         (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
+#define PS2_USART_RX_VECT       USART1_RX_vect
+#endif
+#endif
+#endif
+```
 
 ## Safety Considerations