a500kbd
annotate src/ps2kbd.c @ 2:a4fd9c5a6655
first working version
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 17 Oct 2017 15:25:33 +0300 |
parents | |
children | 31a1f0b53d98 |
rev | line source |
---|---|
nuclear@2 | 1 #include <avr/io.h> |
nuclear@2 | 2 #include <avr/interrupt.h> |
nuclear@2 | 3 #include <util/delay.h> |
nuclear@2 | 4 #include "ps2kbd.h" |
nuclear@2 | 5 #include "defs.h" |
nuclear@2 | 6 |
nuclear@2 | 7 #define BUF_SZ 16 |
nuclear@2 | 8 #define BUF_IDX_MASK (BUF_SZ - 1) |
nuclear@2 | 9 #define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK) |
nuclear@2 | 10 static volatile unsigned char keybuf[BUF_SZ]; |
nuclear@2 | 11 static volatile unsigned char key_rd, key_wr; |
nuclear@2 | 12 |
nuclear@2 | 13 static volatile int sending; |
nuclear@2 | 14 |
nuclear@2 | 15 void ps2write(unsigned char c) |
nuclear@2 | 16 { |
nuclear@2 | 17 #if 0 |
nuclear@2 | 18 int i; |
nuclear@2 | 19 unsigned short out = (unsigned short)c | ((unsigned short)(parity_even_bit(c) & 1) << 8); |
nuclear@2 | 20 |
nuclear@2 | 21 /* pull clock low for >60us */ |
nuclear@2 | 22 PS2LOW(BIT_CLK); |
nuclear@2 | 23 _delay_us(60); |
nuclear@2 | 24 |
nuclear@2 | 25 /* then pull data low and release clock */ |
nuclear@2 | 26 PS2LOW(BIT_DATA); |
nuclear@2 | 27 PS2REL(BIT_CLK); |
nuclear@2 | 28 |
nuclear@2 | 29 for(i=0; i<9; i++) { |
nuclear@2 | 30 while(PINB & BIT_CLK); /* wait for kbd to drive the clock low */ |
nuclear@2 | 31 PORTB |= out & 1; |
nuclear@2 | 32 out >>= 1; |
nuclear@2 | 33 while(!(PINB & BIT_CLK)); /* wait for kbd to drive the clock high */ |
nuclear@2 | 34 } |
nuclear@2 | 35 |
nuclear@2 | 36 PS2REL(BIT_DATA); |
nuclear@2 | 37 /* wait for ack */ |
nuclear@2 | 38 while(PINB & BIT_DATA); |
nuclear@2 | 39 while(!(PINB & BIT_DATA)); |
nuclear@2 | 40 #endif |
nuclear@2 | 41 } |
nuclear@2 | 42 |
nuclear@2 | 43 unsigned char ps2read(void) |
nuclear@2 | 44 { |
nuclear@2 | 45 unsigned char key; |
nuclear@2 | 46 |
nuclear@2 | 47 while(key_rd == key_wr) { |
nuclear@2 | 48 } |
nuclear@2 | 49 |
nuclear@2 | 50 cli(); |
nuclear@2 | 51 key = keybuf[key_rd]; |
nuclear@2 | 52 key_rd = NEXT_IDX(key_rd); |
nuclear@2 | 53 sei(); |
nuclear@2 | 54 |
nuclear@2 | 55 return key; |
nuclear@2 | 56 } |
nuclear@2 | 57 |
nuclear@2 | 58 int ps2pending(void) |
nuclear@2 | 59 { |
nuclear@2 | 60 return key_rd != key_wr; |
nuclear@2 | 61 } |
nuclear@2 | 62 |
nuclear@2 | 63 ISR(INT0_vect) |
nuclear@2 | 64 { |
nuclear@2 | 65 static unsigned char value, parity; |
nuclear@2 | 66 /*static unsigned char valp;*/ |
nuclear@2 | 67 static int nbits; |
nuclear@2 | 68 |
nuclear@2 | 69 if(sending) { |
nuclear@2 | 70 } else { |
nuclear@2 | 71 if(nbits > 0 && nbits < 9) { |
nuclear@2 | 72 value >>= 1; |
nuclear@2 | 73 if(PIND & PDATA_BIT) { |
nuclear@2 | 74 value |= 0x80; |
nuclear@2 | 75 parity ^= 1; |
nuclear@2 | 76 } |
nuclear@2 | 77 }/* else if(nbits == 9) { |
nuclear@2 | 78 valp = (PIND >> PDATA) & 1; |
nuclear@2 | 79 }*/ |
nuclear@2 | 80 if(++nbits >= 11) { |
nuclear@2 | 81 nbits = 0; |
nuclear@2 | 82 |
nuclear@2 | 83 /* check parity */ |
nuclear@2 | 84 /*if((parity & 1) == (valp & 1)) {}*/ |
nuclear@2 | 85 keybuf[key_wr] = (unsigned char)value; |
nuclear@2 | 86 key_wr = NEXT_IDX(key_wr); |
nuclear@2 | 87 |
nuclear@2 | 88 value = 0; |
nuclear@2 | 89 parity = 0; |
nuclear@2 | 90 } |
nuclear@2 | 91 } |
nuclear@2 | 92 } |