forked from mirrors/qmk_userspace
		
	Fix key stack and PS/2 Overrun
This commit is contained in:
		
					parent
					
						
							
								8b4fa599cf
							
						
					
				
			
			
				commit
				
					
						10b2b1ae43
					
				
			
		
					 2 changed files with 73 additions and 46 deletions
				
			
		| 
						 | 
					@ -40,6 +40,52 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#define NO_SUSPEND_POWER_DOWN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * PS/2 Busywait
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifdef PS2_USE_BUSYWAIT
 | 
				
			||||||
 | 
					#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
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * PS/2 Pin interrupt
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#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    2
 | 
				
			||||||
 | 
					#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 USART
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
#ifdef PS2_USE_USART
 | 
					#ifdef PS2_USE_USART
 | 
				
			||||||
#if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)
 | 
					#if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)
 | 
				
			||||||
/* XCK for clock line and RXD for data line */
 | 
					/* XCK for clock line and RXD for data line */
 | 
				
			||||||
| 
						 | 
					@ -51,7 +97,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#define PS2_DATA_PIN    PIND
 | 
					#define PS2_DATA_PIN    PIND
 | 
				
			||||||
#define PS2_DATA_DDR    DDRD
 | 
					#define PS2_DATA_DDR    DDRD
 | 
				
			||||||
#define PS2_DATA_BIT    2
 | 
					#define PS2_DATA_BIT    2
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
 | 
					/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
 | 
				
			||||||
/* set DDR of CLOCK as input to be slave */
 | 
					/* set DDR of CLOCK as input to be slave */
 | 
				
			||||||
#define PS2_USART_INIT() do {   \
 | 
					#define PS2_USART_INIT() do {   \
 | 
				
			||||||
| 
						 | 
					@ -82,7 +127,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#define PS2_USART_RX_DATA       UDR1
 | 
					#define PS2_USART_RX_DATA       UDR1
 | 
				
			||||||
#define PS2_USART_ERROR         (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
 | 
					#define PS2_USART_ERROR         (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
 | 
				
			||||||
#define PS2_USART_RX_VECT       USART1_RX_vect
 | 
					#define PS2_USART_RX_VECT       USART1_RX_vect
 | 
				
			||||||
 | 
					 | 
				
			||||||
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
 | 
					#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
 | 
				
			||||||
/* XCK for clock line and RXD for data line */
 | 
					/* XCK for clock line and RXD for data line */
 | 
				
			||||||
#define PS2_CLOCK_PORT  PORTD
 | 
					#define PS2_CLOCK_PORT  PORTD
 | 
				
			||||||
| 
						 | 
					@ -93,7 +137,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#define PS2_DATA_PIN    PIND
 | 
					#define PS2_DATA_PIN    PIND
 | 
				
			||||||
#define PS2_DATA_DDR    DDRD
 | 
					#define PS2_DATA_DDR    DDRD
 | 
				
			||||||
#define PS2_DATA_BIT    0
 | 
					#define PS2_DATA_BIT    0
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
 | 
					/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
 | 
				
			||||||
/* set DDR of CLOCK as input to be slave */
 | 
					/* set DDR of CLOCK as input to be slave */
 | 
				
			||||||
#define PS2_USART_INIT() do {   \
 | 
					#define PS2_USART_INIT() do {   \
 | 
				
			||||||
| 
						 | 
					@ -127,41 +170,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#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   5
 | 
					 | 
				
			||||||
#define PS2_DATA_PORT   PORTD
 | 
					 | 
				
			||||||
#define PS2_DATA_PIN    PIND
 | 
					 | 
				
			||||||
#define PS2_DATA_DDR    DDRD
 | 
					 | 
				
			||||||
#define PS2_DATA_BIT    2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef PS2_USE_BUSYWAIT
 | 
					 | 
				
			||||||
#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
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void matrix_make(uint8_t code);
 | 
					static void matrix_make(uint8_t code);
 | 
				
			||||||
static void matrix_break(uint8_t code);
 | 
					static void matrix_break(uint8_t code);
 | 
				
			||||||
 | 
					static void matrix_clear(void);
 | 
				
			||||||
#ifdef MATRIX_HAS_GHOST
 | 
					#ifdef MATRIX_HAS_GHOST
 | 
				
			||||||
static bool matrix_has_ghost_in_row(uint8_t row);
 | 
					static bool matrix_has_ghost_in_row(uint8_t row);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -84,6 +85,7 @@ uint8_t matrix_cols(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void matrix_init(void)
 | 
					void matrix_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    debug_enable = true;
 | 
				
			||||||
    ps2_host_init();
 | 
					    ps2_host_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // initialize matrix state: all keys off
 | 
					    // initialize matrix state: all keys off
 | 
				
			||||||
| 
						 | 
					@ -209,16 +211,18 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
                        state = INIT;
 | 
					                        state = INIT;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    case 0x00:  // Overrun [3]p.25
 | 
					                    case 0x00:  // Overrun [3]p.25
 | 
				
			||||||
                        print("Overrun\n");
 | 
					                        matrix_clear();
 | 
				
			||||||
                        clear_keyboard();
 | 
					                        clear_keyboard();
 | 
				
			||||||
 | 
					                        print("Overrun\n");
 | 
				
			||||||
                        state = INIT;
 | 
					                        state = INIT;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    default:    // normal key make
 | 
					                    default:    // normal key make
 | 
				
			||||||
                        if (code < 0x80) {
 | 
					                        if (code < 0x80) {
 | 
				
			||||||
                            matrix_make(code);
 | 
					                            matrix_make(code);
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            xprintf("unexpected scan code at INIT: %02X\n", code);
 | 
					                            matrix_clear();
 | 
				
			||||||
                            clear_keyboard();
 | 
					                            clear_keyboard();
 | 
				
			||||||
 | 
					                            xprintf("unexpected scan code at INIT: %02X\n", code);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        state = INIT;
 | 
					                        state = INIT;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -239,8 +243,9 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
                        if (code < 0x80) {
 | 
					                        if (code < 0x80) {
 | 
				
			||||||
                            matrix_make(code|0x80);
 | 
					                            matrix_make(code|0x80);
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            xprintf("unexpected scan code at E0: %02X\n", code);
 | 
					                            matrix_clear();
 | 
				
			||||||
                            clear_keyboard();
 | 
					                            clear_keyboard();
 | 
				
			||||||
 | 
					                            xprintf("unexpected scan code at E0: %02X\n", code);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        state = INIT;
 | 
					                        state = INIT;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -255,12 +260,18 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
                        matrix_break(PRINT_SCREEN);
 | 
					                        matrix_break(PRINT_SCREEN);
 | 
				
			||||||
                        state = INIT;
 | 
					                        state = INIT;
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
 | 
					                    case 0xF0:
 | 
				
			||||||
 | 
					                        matrix_clear();
 | 
				
			||||||
 | 
					                        clear_keyboard();
 | 
				
			||||||
 | 
					                        xprintf("unexpected scan code at F0: F0(clear and cont.)\n");
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
                    default:
 | 
					                    default:
 | 
				
			||||||
                    if (code < 0x80) {
 | 
					                    if (code < 0x80) {
 | 
				
			||||||
                        matrix_break(code);
 | 
					                        matrix_break(code);
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        xprintf("unexpected scan code at F0: %02X\n", code);
 | 
					                        matrix_clear();
 | 
				
			||||||
                        clear_keyboard();
 | 
					                        clear_keyboard();
 | 
				
			||||||
 | 
					                        xprintf("unexpected scan code at F0: %02X\n", code);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    state = INIT;
 | 
					                    state = INIT;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -275,8 +286,9 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
                        if (code < 0x80) {
 | 
					                        if (code < 0x80) {
 | 
				
			||||||
                            matrix_break(code|0x80);
 | 
					                            matrix_break(code|0x80);
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            xprintf("unexpected scan code at E0_F0: %02X\n", code);
 | 
					                            matrix_clear();
 | 
				
			||||||
                            clear_keyboard();
 | 
					                            clear_keyboard();
 | 
				
			||||||
 | 
					                            xprintf("unexpected scan code at E0_F0: %02X\n", code);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        state = INIT;
 | 
					                        state = INIT;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -369,10 +381,13 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ps2_error > PS2_ERR_STARTBIT3) {
 | 
					    // TODO: request RESEND when error occurs?
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    if (PS2_IS_FAILED(ps2_error)) {
 | 
				
			||||||
        uint8_t ret = ps2_host_send(PS2_RESEND);
 | 
					        uint8_t ret = ps2_host_send(PS2_RESEND);
 | 
				
			||||||
        xprintf("Resend: %02X\n", ret);
 | 
					        xprintf("Resend: %02X\n", ret);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -464,3 +479,9 @@ static void matrix_break(uint8_t code)
 | 
				
			||||||
        is_modified = true;
 | 
					        is_modified = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					static void matrix_clear(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue