a500kbd
diff src/main.c @ 1:3228a731d4db
translate scancodes
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 14 Oct 2017 07:23:47 +0300 |
parents | 8e8e17a0f88e |
children | a4fd9c5a6655 |
line diff
1.1 --- a/src/main.c Thu Oct 12 04:08:48 2017 +0300 1.2 +++ b/src/main.c Sat Oct 14 07:23:47 2017 +0300 1.3 @@ -1,16 +1,18 @@ 1.4 #define F_CPU XTAL 1.5 #include <stdio.h> 1.6 +#include <ctype.h> 1.7 #include <avr/io.h> 1.8 #include <avr/interrupt.h> 1.9 #include <util/delay.h> 1.10 #include <util/parity.h> 1.11 #include "serial.h" 1.12 +#include "scantbl.h" 1.13 1.14 /* pin assignments: 1.15 * B0 PS/2 data 1.16 - * B1 PS/2 clock 1.17 - * C0 KBD data 1.18 - * C1 KBD clock 1.19 + * D2 PS/2 clock (INT0) 1.20 + * B1 KBD data 1.21 + * D3 KBD clock (INT1) 1.22 */ 1.23 1.24 #define BIT_DATA 1 1.25 @@ -19,50 +21,86 @@ 1.26 #define PS2LOW(bit) do { DDRB |= (bit); PORTB &= ~(bit); } while(0) 1.27 #define PS2HIGH(bit) do { DDRB |= (bit); PORTB |= (bit); } while(0) 1.28 #define PS2REL(bit) do { DDRB &= ~(bit); PORTB &= ~(bit); } while(0) 1.29 -#define PS2INTR_UNMASK do { PCICR |= (1 << PCIE0); } while(0) 1.30 -#define PS2INTR_MASK do { PCICR &= ~(1 << PCIE0); } while(0) 1.31 1.32 void ps2write(unsigned char c); 1.33 -int ps2read(unsigned char *c); 1.34 +unsigned char ps2read(void); 1.35 +int ps2pending(void); 1.36 1.37 +#define BUF_SZ 16 1.38 +#define BUF_IDX_MASK (BUF_SZ - 1) 1.39 +#define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK) 1.40 +static volatile unsigned char keybuf[BUF_SZ]; 1.41 +static volatile unsigned char key_rd, key_wr; 1.42 + 1.43 +static volatile int sending; 1.44 + 1.45 +enum { 1.46 + KF_BRK = 1, 1.47 + KF_EXT = 2, 1.48 + KF_EXT1 = 4, 1.49 +}; 1.50 1.51 int main(void) 1.52 { 1.53 - int led = 1, dir = 1; 1.54 + unsigned int keyflags = 0; 1.55 + int keycode; 1.56 1.57 DDRB = 0; 1.58 - DDRC = 0; 1.59 + DDRD = 0; 1.60 PORTB = 0; 1.61 - PORTC = 0; 1.62 + PORTD = 0; 1.63 + EIMSK = 0; /* mask external interrupts */ 1.64 + EICRA = (1 << ISC11) | (1 << ISC01); /* falling edge interrupts */ 1.65 1.66 /* initialize the UART and enable interrupts */ 1.67 init_serial(9600); 1.68 sei(); 1.69 1.70 printf("PS/2 keyboard controller - John Tsiombikas <nuclear@member.fsf.org>\r\n"); 1.71 - fflush(stdout); 1.72 + 1.73 + EIMSK = (1 << INT0); /* enable ps/2 clock interrupt */ 1.74 1.75 for(;;) { 1.76 - printf("hello!\r\n"); 1.77 - fflush(stdout); 1.78 - unsigned char c; 1.79 + unsigned char c = ps2read(); 1.80 + switch(c) { 1.81 + case 0xe0: /* extended */ 1.82 + keyflags |= KF_EXT; 1.83 + break; 1.84 1.85 - ps2write(0xed); 1.86 - ps2read(&c); 1.87 - if(c != 0xfa) { 1.88 - printf("expected ack, got: %xh\r\n", (unsigned int)c); 1.89 - } else { 1.90 - ps2write(led); 1.91 - if(led == 1) dir = 1; 1.92 - if(led == 7) dir = -1; 1.93 + case 0xe1: /* extended */ 1.94 + keyflags |= KF_EXT1; 1.95 + break; 1.96 1.97 - if(dir > 0) { 1.98 - led <<= 1; 1.99 + case 0xf0: /* break code */ 1.100 + keyflags |= KF_BRK; 1.101 + break; 1.102 + 1.103 + default: 1.104 + keycode = 0; 1.105 + if(keyflags & KF_EXT) { 1.106 + printf("ext "); 1.107 + if(c < KEYMAP_EXT_SIZE) { 1.108 + keycode = keymap_ext[(int)c]; 1.109 + } 1.110 + } else if(keyflags & KF_EXT1) { 1.111 + printf("ext1 "); 1.112 } else { 1.113 - led >>= 1; 1.114 + if(c < KEYMAP_NORMAL_SIZE) { 1.115 + keycode = keymap_normal[(int)c]; 1.116 + } 1.117 } 1.118 1.119 - _delay_ms(1000); 1.120 + if(keycode >= 256) { 1.121 + /*printf("%s: %s (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", skeystr[keycode - 256], (unsigned int)c);*/ 1.122 + printf("%s: key %xh (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", keycode, (unsigned int)c); 1.123 + } else if(isprint(keycode)) { 1.124 + printf("%s: %c (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", (char)keycode, (unsigned int)c); 1.125 + } else if(keycode > 0) { 1.126 + printf("%s: key %xh (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", keycode, (unsigned int)c); 1.127 + } else { 1.128 + printf("%s: %x\r\n", keyflags & KF_BRK ? "release" : "press", (unsigned int)c); 1.129 + } 1.130 + keyflags = 0; 1.131 } 1.132 } 1.133 return 0; 1.134 @@ -71,7 +109,7 @@ 1.135 void ps2write(unsigned char c) 1.136 { 1.137 int i; 1.138 - unsigned short out = (unsigned short)c | ((unsigned short)(~parity_even_bit(c) & 1) << 8); 1.139 + unsigned short out = (unsigned short)c | ((unsigned short)(parity_even_bit(c) & 1) << 8); 1.140 1.141 /* pull clock low for >60us */ 1.142 PS2LOW(BIT_CLK); 1.143 @@ -82,39 +120,64 @@ 1.144 PS2REL(BIT_CLK); 1.145 1.146 for(i=0; i<9; i++) { 1.147 - printf("bit %d: wait for clk-low\r\n", i); 1.148 while(PINB & BIT_CLK); /* wait for kbd to drive the clock low */ 1.149 PORTB |= out & 1; 1.150 out >>= 1; 1.151 - printf("bit %d: wait for clk-high\r\n", i); 1.152 while(!(PINB & BIT_CLK)); /* wait for kbd to drive the clock high */ 1.153 } 1.154 1.155 PS2REL(BIT_DATA); 1.156 /* wait for ack */ 1.157 - printf("wait for ack (low)\r\n"); 1.158 while(PINB & BIT_DATA); 1.159 - printf("wait for ack (high)\r\n"); 1.160 while(!(PINB & BIT_DATA)); 1.161 } 1.162 1.163 -int ps2read(unsigned char *c) 1.164 +unsigned char ps2read(void) 1.165 { 1.166 - int i, p; 1.167 - unsigned short in = 0; 1.168 + unsigned char key; 1.169 1.170 - /* wait for kbd to drive the clock low for the start bit (blocks here) */ 1.171 - while(PINB & BIT_CLK); 1.172 - while(!(PINB & BIT_CLK)); 1.173 - 1.174 - for(i=0; i<9; i++) { 1.175 - while(PINB & BIT_CLK); /* wait for clock to go low */ 1.176 - in |= (PINB & 1) << i; 1.177 - while(!(PINB & BIT_CLK)); 1.178 + while(key_rd == key_wr) { 1.179 } 1.180 1.181 - p = ~parity_even_bit((unsigned char)in); 1.182 - *c = in; 1.183 + cli(); 1.184 + key = keybuf[key_rd]; 1.185 + key_rd = NEXT_IDX(key_rd); 1.186 + sei(); 1.187 1.188 - return (p == ((in >> 8) & 1)) ? 0 : -1; 1.189 + return key; 1.190 } 1.191 + 1.192 +int ps2pending(void) 1.193 +{ 1.194 + return key_rd != key_wr; 1.195 +} 1.196 + 1.197 +ISR(INT0_vect) 1.198 +{ 1.199 + static unsigned char value, valp, parity; 1.200 + static int nbits; 1.201 + 1.202 + if(sending) { 1.203 + } else { 1.204 + if(nbits > 0 && nbits < 9) { 1.205 + value >>= 1; 1.206 + if(PINB & 1) { 1.207 + value |= 0x80; 1.208 + parity ^= 1; 1.209 + } 1.210 + }/* else if(nbits == 9) { 1.211 + valp = PINB & 1; 1.212 + }*/ 1.213 + if(++nbits >= 11) { 1.214 + nbits = 0; 1.215 + 1.216 + /* check parity */ 1.217 + /*if((parity & 1) == (valp & 1)) {}*/ 1.218 + keybuf[key_wr] = (unsigned char)value; 1.219 + key_wr = NEXT_IDX(key_wr); 1.220 + 1.221 + value = 0; 1.222 + parity = 0; 1.223 + } 1.224 + } 1.225 +}