1 | // keyboard.c
|
---|
2 | // ps/2 keyboard decoder on ATMega8
|
---|
3 | // copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
|
---|
4 | // MIT Licence
|
---|
5 |
|
---|
6 | // Parts borrowed from :
|
---|
7 | // keyboard.c
|
---|
8 | // for NerdKits with ATmega168
|
---|
9 | // hevans@nerdkits.com
|
---|
10 | //
|
---|
11 | // Designed for use with the USB NerdKit running with ATMega168. Datasheet page
|
---|
12 | // numbers refer to ATMega168 datasheet.
|
---|
13 |
|
---|
14 | #define F_CPU 16000000UL
|
---|
15 |
|
---|
16 | #include <avr/io.h>
|
---|
17 | #include <avr/interrupt.h>
|
---|
18 | #include <avr/pgmspace.h>
|
---|
19 | #include <util/delay.h>
|
---|
20 |
|
---|
21 | #include "keymap.h"
|
---|
22 |
|
---|
23 |
|
---|
24 | //ps/2 Keyboard pin out
|
---|
25 | //pin 5 - clock
|
---|
26 | //pin 3 - GND
|
---|
27 | //pin 1 - data
|
---|
28 | //pin 4 - VCC
|
---|
29 |
|
---|
30 | //PIN configuration
|
---|
31 | #define PS2_CLK PD3 /* Also INT1 */
|
---|
32 | #define PS2_PORT PIND
|
---|
33 | #define PS2_DATA PD4
|
---|
34 |
|
---|
35 | volatile uint8_t kbd_data;
|
---|
36 | volatile uint8_t char_waiting;
|
---|
37 | uint8_t started;
|
---|
38 | uint8_t bit_count;
|
---|
39 | uint8_t shift;
|
---|
40 | uint8_t caps_lock;
|
---|
41 | uint8_t extended;
|
---|
42 | uint8_t release;
|
---|
43 |
|
---|
44 | // Interrupt vector - Triggered when there is activity on the clock line
|
---|
45 | ISR(INT1_vect)
|
---|
46 | {
|
---|
47 | PORTD ^= (1<<PD6);
|
---|
48 | //make sure clock line is low, if not ignore this transition
|
---|
49 | if(PS2_PORT & (1<<PS2_CLK)){
|
---|
50 | return;
|
---|
51 | }
|
---|
52 |
|
---|
53 | //if we have not started, check for start bit on DATA line
|
---|
54 | if(!started){
|
---|
55 | if ( (PS2_PORT & (1<<PS2_DATA)) == 0 ) {
|
---|
56 | started = 1;
|
---|
57 | bit_count = 0;
|
---|
58 | kbd_data = 0;
|
---|
59 | //printf_P(PSTR("%d"),started);
|
---|
60 | return;
|
---|
61 | }
|
---|
62 | } else if(bit_count < 8) { //we started, read in the new bit
|
---|
63 | //put a 1 in the right place of kdb_data if PC2 is high, leave
|
---|
64 | //a 0 otherwise
|
---|
65 | if(PS2_PORT & (1<<PS2_DATA)){
|
---|
66 | kbd_data |= (1<<bit_count);
|
---|
67 | }
|
---|
68 | bit_count++;
|
---|
69 | return;
|
---|
70 | } else if(bit_count == 8){ //pairty bit
|
---|
71 | //not implemented
|
---|
72 | bit_count++;
|
---|
73 | return;
|
---|
74 | } else { //stop bit
|
---|
75 | //should check to make sure DATA line is high, what to do if not?
|
---|
76 | started = 0;
|
---|
77 | bit_count = 0;
|
---|
78 | }
|
---|
79 |
|
---|
80 | if(kbd_data == 0xF0){ //release code
|
---|
81 | release = 1;
|
---|
82 | kbd_data = 0;
|
---|
83 | return;
|
---|
84 | } else if (kbd_data == 0x12) { //hanlde shift key
|
---|
85 | if(release == 0){
|
---|
86 | shift = 1;
|
---|
87 | } else {
|
---|
88 | shift = 0;
|
---|
89 | release = 0;
|
---|
90 | }
|
---|
91 | return;
|
---|
92 | } else { //not a special character
|
---|
93 | if(release){ //we were in release mode - exit release mode
|
---|
94 | release = 0;
|
---|
95 | //ignore that character
|
---|
96 | } else {
|
---|
97 | char_waiting = 1;
|
---|
98 | }
|
---|
99 | }
|
---|
100 | }
|
---|
101 |
|
---|
102 |
|
---|
103 | char render_scan_code(uint8_t data){
|
---|
104 | char to_ret = pgm_read_byte(&(keymap[data])); //grab character from array
|
---|
105 | if(shift) to_ret -= 0x20;
|
---|
106 | return to_ret;
|
---|
107 | }
|
---|
108 |
|
---|
109 |
|
---|
110 | uint8_t read_char(){
|
---|
111 | while(!char_waiting);
|
---|
112 | char_waiting = 0;
|
---|
113 | return kbd_data;
|
---|
114 | }
|
---|
115 |
|
---|
116 |
|
---|
117 | void init_keyboard(){
|
---|
118 | started = 0;
|
---|
119 | kbd_data = 0;
|
---|
120 | bit_count = 0;
|
---|
121 |
|
---|
122 | //make PS2_CLK input pin
|
---|
123 | DDRD &= ~(1<<PS2_CLK);
|
---|
124 | //turn on pullup resistor
|
---|
125 | PS2_PORT |= (1<<PS2_CLK);
|
---|
126 |
|
---|
127 | // PCMSK |= (1<<PIND3);
|
---|
128 | MCUCR |= (1<<ISC11); // Falling edge
|
---|
129 | MCUCR &= ~(1<<ISC10);
|
---|
130 | GIMSK |= (1<<INT1);
|
---|
131 |
|
---|
132 | sei();
|
---|
133 | }
|
---|
134 |
|
---|
135 |
|
---|