a500kbd

view src/main.c @ 0:8e8e17a0f88e

initial commit: serial comms up, kbd doesn't respond
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 12 Oct 2017 04:08:48 +0300
parents
children 3228a731d4db
line source
1 #define F_CPU XTAL
2 #include <stdio.h>
3 #include <avr/io.h>
4 #include <avr/interrupt.h>
5 #include <util/delay.h>
6 #include <util/parity.h>
7 #include "serial.h"
9 /* pin assignments:
10 * B0 PS/2 data
11 * B1 PS/2 clock
12 * C0 KBD data
13 * C1 KBD clock
14 */
16 #define BIT_DATA 1
17 #define BIT_CLK 2
19 #define PS2LOW(bit) do { DDRB |= (bit); PORTB &= ~(bit); } while(0)
20 #define PS2HIGH(bit) do { DDRB |= (bit); PORTB |= (bit); } while(0)
21 #define PS2REL(bit) do { DDRB &= ~(bit); PORTB &= ~(bit); } while(0)
22 #define PS2INTR_UNMASK do { PCICR |= (1 << PCIE0); } while(0)
23 #define PS2INTR_MASK do { PCICR &= ~(1 << PCIE0); } while(0)
25 void ps2write(unsigned char c);
26 int ps2read(unsigned char *c);
29 int main(void)
30 {
31 int led = 1, dir = 1;
33 DDRB = 0;
34 DDRC = 0;
35 PORTB = 0;
36 PORTC = 0;
38 /* initialize the UART and enable interrupts */
39 init_serial(9600);
40 sei();
42 printf("PS/2 keyboard controller - John Tsiombikas <nuclear@member.fsf.org>\r\n");
43 fflush(stdout);
45 for(;;) {
46 printf("hello!\r\n");
47 fflush(stdout);
48 unsigned char c;
50 ps2write(0xed);
51 ps2read(&c);
52 if(c != 0xfa) {
53 printf("expected ack, got: %xh\r\n", (unsigned int)c);
54 } else {
55 ps2write(led);
56 if(led == 1) dir = 1;
57 if(led == 7) dir = -1;
59 if(dir > 0) {
60 led <<= 1;
61 } else {
62 led >>= 1;
63 }
65 _delay_ms(1000);
66 }
67 }
68 return 0;
69 }
71 void ps2write(unsigned char c)
72 {
73 int i;
74 unsigned short out = (unsigned short)c | ((unsigned short)(~parity_even_bit(c) & 1) << 8);
76 /* pull clock low for >60us */
77 PS2LOW(BIT_CLK);
78 _delay_us(60);
80 /* then pull data low and release clock */
81 PS2LOW(BIT_DATA);
82 PS2REL(BIT_CLK);
84 for(i=0; i<9; i++) {
85 printf("bit %d: wait for clk-low\r\n", i);
86 while(PINB & BIT_CLK); /* wait for kbd to drive the clock low */
87 PORTB |= out & 1;
88 out >>= 1;
89 printf("bit %d: wait for clk-high\r\n", i);
90 while(!(PINB & BIT_CLK)); /* wait for kbd to drive the clock high */
91 }
93 PS2REL(BIT_DATA);
94 /* wait for ack */
95 printf("wait for ack (low)\r\n");
96 while(PINB & BIT_DATA);
97 printf("wait for ack (high)\r\n");
98 while(!(PINB & BIT_DATA));
99 }
101 int ps2read(unsigned char *c)
102 {
103 int i, p;
104 unsigned short in = 0;
106 /* wait for kbd to drive the clock low for the start bit (blocks here) */
107 while(PINB & BIT_CLK);
108 while(!(PINB & BIT_CLK));
110 for(i=0; i<9; i++) {
111 while(PINB & BIT_CLK); /* wait for clock to go low */
112 in |= (PINB & 1) << i;
113 while(!(PINB & BIT_CLK));
114 }
116 p = ~parity_even_bit((unsigned char)in);
117 *c = in;
119 return (p == ((in >> 8) & 1)) ? 0 : -1;
120 }