diff options
author | Priyadi Iman Nurcahyo <priyadi@priyadi.net> | 2016-11-26 14:23:55 +0700 |
---|---|---|
committer | Priyadi Iman Nurcahyo <priyadi@priyadi.net> | 2016-11-26 14:23:55 +0700 |
commit | f837406ace5a3072e98f0bd0e3f4c84704762195 (patch) | |
tree | 61d4390b50c9aea3a8dd0f6dc2e0f8a1279a697b | |
parent | bf23ac96f62be1cb36d414e76599523af3caf00f (diff) | |
download | qmk_firmware-f837406ace5a3072e98f0bd0e3f4c84704762195.tar.gz |
A few addition to PS2 documentation.
-rw-r--r-- | readme.md | 160 |
1 files changed, 125 insertions, 35 deletions
@@ -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 |