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

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

kbd: working XTK on ATtiny2313

  • Move more stuff to common.mk and handle multicpu support
  • Fix some pins mixups to get things working

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

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