source: avrstuff/libs/ps2_keyboard/ps2_keyboard.c@ c7cc629

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

Move the ASCII keymap out of ps2_keyboard.c.

It is used only by the serial converter, so save some flashspace for other projects.

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

  • Property mode set to 100644
File size: 2.7 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#define PS2_DATA PD4
24
25static volatile uint8_t kbd_data;
26static volatile uint8_t char_waiting;
27static uint8_t started;
28static uint8_t bit_count;
29static uint8_t caps_lock;
30static uint8_t extended;
31
32uint8_t shift;
33uint8_t release;
34
35// Interrupt vector - Triggered when there is activity on the clock line
36ISR(INT1_vect)
37{
38 //make sure clock line is low, if not ignore this transition
39 if(PS2_PORT & (1<<PS2_CLK)){
40 return;
41 }
42
43 //if we have not started, check for start bit on DATA line
44 if(!started){
45 if ( (PS2_PORT & (1<<PS2_DATA)) == 0 ) {
46 started = 1;
47 bit_count = 0;
48 kbd_data = 0;
49 //printf_P(PSTR("%d"),started);
50 return;
51 }
52 } else if(bit_count < 8) { //we started, read in the new bit
53 //put a 1 in the right place of kdb_data if PC2 is high, leave
54 //a 0 otherwise
55 if(PS2_PORT & (1<<PS2_DATA)){
56 kbd_data |= (1<<bit_count);
57 }
58 bit_count++;
59 return;
60 } else if(bit_count == 8){ //pairty bit
61 //not implemented
62 bit_count++;
63 return;
64 } else { //stop bit
65 //should check to make sure DATA line is high, what to do if not?
66 started = 0;
67 bit_count = 0;
68 }
69
70 if(kbd_data == 0xF0){ //release code
71 release = 1;
72 kbd_data = 0;
73 return;
74 } else if (kbd_data == 0x12) { //hanlde shift key
75 if(release == 0){
76 shift = 1;
77 } else {
78 shift = 0;
79 release = 0;
80 }
81 return;
82 } else { //not a special character
83 if(release){ //we were in release mode - exit release mode
84 release = 0;
85 //ignore that character
86 } else {
87 char_waiting = 1;
88#ifdef CALLBACK
89 CALLBACK
90#endif
91 }
92 }
93}
94
95
96uint8_t read_char(){
97 while(!char_waiting);
98 char_waiting = 0;
99 return kbd_data;
100}
101
102
103void init_keyboard(){
104 started = 0;
105 kbd_data = 0;
106 bit_count = 0;
107
108 //make PS2_CLK input pin
109 DDRD &= ~(1<<PS2_CLK);
110 //turn on pullup resistor
111 PS2_PORT |= (1<<PS2_CLK);
112
113 // FIXME we can use the "pin change" interrupt rather than INT0/INT1 when not
114 // on the old clumsy ATMega8. This would allow for any pin to be used.
115 // PCMSK |= (1<<PIND3);
116 MCUCR |= (1<<ISC11); // Falling edge
117 MCUCR &= ~(1<<ISC10);
118#ifdef __AVR_ATmega48P__
119 EIMSK |= (1<<INT1);
120#else // ATmega8
121 GIMSK |= (1<<INT1);
122#endif
123
124 sei();
125}
126
127
Note: See TracBrowser for help on using the repository browser.