diff options
| -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 | 
