source: avrstuff/libs/amiga_keyboard/amiga_keyboard.c@ 38f2eef

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

Amiga_keybaord : add non-blocking function to get a char when it's ready.

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