source: avrstuff/libs/ps2_keyboard/ps2_keyboard.c@ 071dc14

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

PS/2: support ATmega48P

  • A register got renamed.

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

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