source: avrstuff/libs/ps2_keyboard/ps2_keyboard.c@ 87ab18e

main
Last change on this file since 87ab18e was 87ab18e, checked in by Adrien Destugues <pulkomandy@…>, 10 years ago

Drop hacked "shift" handling from libps2.

  • It's up to clients to do that if they wish so (useful if you're converting

to ASCII, for example, but not for a regular keyboard adapter)

Improve callback system to handle release events.

  • The callback would only be called for pressed keys, not for releases, leading

to weird results. Things work much better now in XTK.

  • Also ignore the E0 byte for extended keys in XTK. This avoids apps going

crazy as the Turbo XT BIOS doesn't handle it right.

git-svn-id: svn://pulkomandy.tk/avrstuff@114 c6672c3c-f6b6-47f9-9001-1fd6b12fecbe

  • Property mode set to 100644
File size: 2.6 KB
Line 
1// ps/2 keyboard decoder on ATMega8, ATMega48
2// Copyright 2010-2014, Adrien Destugues <pulkomandy@pulkomandy.tk>
3// This file is distributed under the terms of the MIT Licence.
4
5// Parts borrowed from :
6// keyboard.c
7// for NerdKits with ATmega168
8// hevans@nerdkits.com
9
10#include <avr/io.h>
11#include <avr/interrupt.h>
12
13
14//ps/2 Keyboard pin out
15//pin 5 - clock
16//pin 3 - GND
17//pin 1 - data
18//pin 4 - VCC
19
20//PIN configuration
21#define PS2_PORT PIND
22#define PS2_CLK PD3 /* Also INT1 */
23
24#ifdef __AVR_ATtiny2313__
25// K4KUSB modified board
26#define PS2_DATA PD5
27#else
28// ENSSAT IR modified board
29#define PS2_DATA PD4
30#endif
31
32static volatile uint8_t char_waiting;
33static uint8_t started;
34static uint8_t bit_count;
35static uint8_t extended;
36
37volatile uint8_t kbd_data;
38uint8_t release;
39
40// Interrupt vector - Triggered when there is activity on the clock line
41ISR(INT1_vect)
42{
43 //make sure clock line is low, if not ignore this transition
44 if(PS2_PORT & (1<<PS2_CLK)){
45 return;
46 }
47
48 //if we have not started, check for start bit on DATA line
49 if(!started){
50 if ( (PS2_PORT & (1<<PS2_DATA)) == 0 ) {
51 started = 1;
52 bit_count = 0;
53 kbd_data = 0;
54 //printf_P(PSTR("%d"),started);
55 return;
56 }
57 } else if(bit_count < 8) { //we started, read in the new bit
58 //put a 1 in the right place of kdb_data if PC2 is high, leave
59 //a 0 otherwise
60 if(PS2_PORT & (1<<PS2_DATA)){
61 kbd_data |= (1<<bit_count);
62 }
63 bit_count++;
64 return;
65 } else if(bit_count == 8){ //pairty bit
66 //not implemented
67 bit_count++;
68 return;
69 } else { //stop bit
70 //should check to make sure DATA line is high, what to do if not?
71 started = 0;
72 bit_count = 0;
73 }
74
75 if(kbd_data == 0xF0){ //release code
76 release = 1;
77 kbd_data = 0;
78 return;
79 } else { //not a special character
80#ifdef CALLBACK
81 CALLBACK
82#endif
83 if(release){ //we were in release mode - exit release mode
84 release = 0;
85 } else {
86 // Notify callback that there's a new char waiting
87 char_waiting = 1;
88 }
89 }
90}
91
92
93uint8_t read_char(){
94 while(!char_waiting);
95 char_waiting = 0;
96 return kbd_data;
97}
98
99
100void init_keyboard(){
101 started = 0;
102 kbd_data = 0;
103 bit_count = 0;
104
105 //make PS2_CLK input pin
106 DDRD &= ~((1<<PS2_CLK) | (1<<PS2_DATA));
107 //turn on pullup resistor
108 PS2_PORT |= (1<<PS2_CLK);
109
110 // FIXME we can use the "pin change" interrupt rather than INT0/INT1 when not
111 // on the old clumsy ATMega8. This would allow for any pin to be used.
112 // PCMSK |= (1<<PIND3);
113 MCUCR |= (1<<ISC11); // Falling edge
114 MCUCR &= ~(1<<ISC10);
115#ifdef __AVR_ATmega48P__
116 EIMSK |= (1<<INT1);
117#else // ATmega8
118 GIMSK |= (1<<INT1);
119#endif
120
121 sei();
122}
123
124
Note: See TracBrowser for help on using the repository browser.