source: avrstuff/libs/amiga_keyboard/amiga_keyboard.c@ cbc34d1

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

Some fixes and improvements to akusb and lib amiga_keyboard to try not losing that much keypresses.
It's not perfect yet, but it's better.

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

  • Property mode set to 100644
File size: 2.7 KB
Line 
1/* Amiga Keyboard reading on Atmel AVR
2 * Copyright 2010, Adrien Destugues <pulkomandy@pulkomandy.ath.cx>
3 * Distributed under the terms of the MIT Licence */
4
5#include <avr/io.h>
6#include <avr/interrupt.h>
7#include <avr/pgmspace.h>
8#include <util/delay.h>
9
10#include "amiga_keyboard.h"
11// #include "keymap.h"
12
13
14//PIN configuration
15#define AK_CLK PD3 /* Also INT1 */
16#define AK_PORT PIND
17#define AK_DATA PD4
18
19volatile uint8_t kbd_data;
20volatile uint8_t char_waiting;
21uint8_t started;
22uint8_t bit_count;
23uint8_t shift;
24
25
26// Notify the keyboard we got the last char right
27static inline void acknowledge_char()
28{
29 // We have to pull down the "DATA" line
30
31 // Set it as an input
32 DDRD |= (1<<AK_DATA);
33
34 // Down for 85 us
35 PORTD &= ~(1<<AK_DATA);
36 _delay_us(85);
37
38 // Up again to let the keybord talk
39 PORTD |= (1<<AK_DATA);
40
41 // And it's now an input again
42 DDRD &= ~(1<<AK_DATA);
43}
44
45
46// Interrupt vector - Triggered when there is activity on the clock line
47ISR(INT1_vect)
48{
49 static char tmp_kdata;
50 //make sure clock line is low, if not ignore this transition
51 if(AK_PORT & (1<<AK_CLK)){
52 return;
53 }
54
55 // First bit, reset everything then continue below
56 if(!started){
57 started = 1;
58 bit_count = 0;
59 tmp_kdata = 0;
60 }
61
62 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(!(AK_PORT & (1<<AK_DATA))) tmp_kdata |= (128>>bit_count);
66 bit_count++;
67 }
68
69 if(bit_count >= 8)
70 { // enough bits
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 if (kbd_data == 0x12) { //hanlde shift key
80 if(release == 0){
81 shift = 1;
82 } else {
83 shift = 0;
84 release = 0;
85 }
86 return;
87 } else { //not a special character
88 if(release){ //we were in release mode - exit release mode
89 release = 0;
90 //ignore that character
91 } else {
92 char_waiting = 1;
93 }
94 }*/
95 kbd_data = tmp_kdata;
96 char_waiting=1;
97 }
98}
99
100
101/*
102char ak_scancode_to_ascii(uint8_t data){
103 char to_ret = pgm_read_byte(&(keymap[data])); //grab character from array
104 if(shift) to_ret -= 0x20;
105 return to_ret;
106}
107*/
108
109uint8_t ak_wait_scancode(){
110 while(!char_waiting);
111 return ak_read_scancode();
112}
113
114
115uint8_t ak_read_scancode() {
116 while ((AK_PORT & (1<<AK_CLK)) == 0);
117 _delay_us(30);
118 acknowledge_char();
119
120 char_waiting = 0;
121 return kbd_data;
122}
123
124
125void ak_init_keyboard(){
126 started = 0;
127 kbd_data = 0;
128 bit_count = 0;
129
130 //make AK_CLK input pin
131 DDRD &= ~(1<<AK_CLK);
132 //turn on pullup resistor
133 AK_PORT |= (1<<AK_CLK);
134
135 // Interrupt configuration
136 // We use INT1 falling edge
137 MCUCR |= (1<<ISC11);
138 MCUCR &= ~(1<<ISC10);
139
140 // Enable INT1
141 GIMSK |= (1<<INT1);
142
143 // Enable interrupts
144 sei();
145
146 acknowledge_char();
147}
148
149
Note: See TracBrowser for help on using the repository browser.