summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--quantum/config_common.h46
-rw-r--r--readme.md160
-rw-r--r--tmk_core/protocol/ps2_mouse.c5
3 files changed, 130 insertions, 81 deletions
diff --git a/quantum/config_common.h b/quantum/config_common.h
index 6b525fe1c..4d3939dae 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -79,48 +79,4 @@
# endif
#endif
-/*
- * PS/2 Interrupt configuration
- */
-#ifdef PS2_USE_INT
-/* uses INT1 for clock line(ATMega32U4) */
-#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
-
-#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
-#endif
-
-/*
- * PS/2 Busywait configuration
- */
-#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 0
-#endif
-
-#endif
-
+#endif \ No newline at end of file
diff --git a/readme.md b/readme.md
index 0157b9072..3eb67882a 100644
--- 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
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c
index c3e8b3c1c..82f6966e8 100644
--- a/tmk_core/protocol/ps2_mouse.c
+++ b/tmk_core/protocol/ps2_mouse.c
@@ -26,6 +26,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "print.h"
#include "debug.h"
+#ifndef PS2_INIT_DELAY
+#define PS2_INIT_DELAY 1000
+#endif
static report_mouse_t mouse_report = {};
@@ -39,7 +42,7 @@ uint8_t ps2_mouse_init(void) {
ps2_host_init();
- _delay_ms(1000); // wait for powering up
+ _delay_ms(PS2_INIT_DELAY); // wait for powering up
// send Reset
rcv = ps2_host_send(0xFF);