2 #include <avr/interrupt.h>
3 #include <util/delay.h>
11 #define BUF_IDX_MASK (BUF_SZ - 1)
12 #define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK)
13 static volatile unsigned char keybuf[BUF_SZ];
14 static volatile unsigned char key_rd, key_wr;
16 static volatile int send_nbits, wait_ack;
17 static volatile unsigned char send_val, send_par;
19 static void abort_send(void);
21 int ps2write(unsigned char c)
26 send_par = 0; /* init to 0, will be calculated while sending */
28 /* inhibit transmission, hold at least 100us */
31 EIFR |= (1 << INTF0); /* clear pending interrupt due to clock transition */
35 /* RTS by data low & release clock (this counts as start bit?) */
41 while(send_nbits > 0) {
42 if(get_msec() > TIMEOUT) {
49 /* release data line and wait for ack */
56 if(get_msec() > TIMEOUT) {
64 static void abort_send(void)
69 /* hold clock low for 100us */
73 DDRD &= ~(PCLK_BIT | PDATA_BIT);
74 EIFR |= (1 << INTF0); /* clear pending interrupt */
78 unsigned char ps2read(void)
82 while(key_rd == key_wr) {
87 key_rd = NEXT_IDX(key_rd);
95 return key_rd != key_wr;
98 int ps2wait(unsigned int timeout)
101 while(key_rd == key_wr) {
102 if(get_msec() >= timeout) return -1;
108 #define PS2_RESEND 0xfe
109 #define PS2_ECHO 0xee
111 int ps2setled(unsigned char state)
117 while(!ps2pending()) {
118 if(get_msec() >= TIMEOUT) return -1;
121 /*printf("ps2setled 1st response: %x\r\n", (unsigned int)c);*/
122 if(c != PS2_ACK) return -1;
126 while(!ps2pending()) {
127 if(get_msec() >= TIMEOUT) return -1;
130 /*printf("ps2setled 2nd response: %x\r\n", (unsigned int)c);*/
131 if(c != PS2_ACK) return -1;
136 void ps2clearbuf(void)
143 static unsigned char value, parity;
144 /*static unsigned char valp;*/
148 if(!(PIND & PDATA_BIT)) {
157 case 1: /* parity bit */
158 if(send_par & 1) { /* odd number of ones: parity 0 */
160 } else { /* even number of ones: parity 1 */
164 case 0: /* stop bit: 1 */
178 if(nbits > 0 && nbits < 9) {
180 if(PIND & PDATA_BIT) {
184 }/* else if(nbits == 9) {
185 valp = (PIND >> PDATA) & 1;
191 /*if((parity & 1) == (valp & 1)) {}*/
192 keybuf[key_wr] = (unsigned char)value;
193 key_wr = NEXT_IDX(key_wr);