diff options
-rw-r--r-- | ardkbd.c | 78 |
1 files changed, 75 insertions, 3 deletions
@@ -6,8 +6,10 @@ #include <stdint.h> -static volatile uint8_t kbd_state = 0; +static volatile int8_t kbd_state = 0; + static volatile uint8_t kbd_input = 0; +static volatile uint8_t kbd_output = 0; static volatile uint8_t kbd_flags = 0; @@ -38,6 +40,40 @@ ISR(PCINT1_vect) { if (kbd_clock()) return; + if (kbd_state < 0) { + if (kbd_state >= -8) { + if (kbd_output & (1 << (-1-kbd_state))) + PORTC |= 0x01; + else + PORTC &= ~0x01; + + kbd_state--; + return; + } + + if (kbd_state == -9) { + if ((__builtin_popcount(kbd_output) & 1) == 0) + PORTC |= 0x01; + else + PORTC &= ~0x01; + + kbd_state--; + return; + } + + if (kbd_state == -10) { + kbd_state--; + + DDRC &= ~0x01; + PORTC |= 0x01; + return; + } + + kbd_state = 0; + + return; + } + bool data = kbd_data(); if (kbd_state == 0) { @@ -94,7 +130,6 @@ ISR(PCINT1_vect) { case KBD_CODE_DOWN: if (ts < 31) ts++; - PORTB = 0; break; } } @@ -102,6 +137,31 @@ ISR(PCINT1_vect) { kbd_flags = 0; } + +void kbd_send(uint8_t command) { + while (kbd_state) {} /* wait for idle */ + + DDRC |= 0x02; + PORTC &= ~0x02; + _delay_us(100); + + DDRC |= 0x01; + PORTC &= ~0x01; + _delay_us(10); + + DDRC &= ~0x02; + PORTC |= 0x02; + + kbd_output = command; + kbd_state = -1; + + /* wait for idle */ + while (kbd_state) {} + while (!kbd_state) {} + while (kbd_state) {} +} + + int main(void) { DDRB = 0xff; PORTB = 0; @@ -114,8 +174,20 @@ int main(void) { sei(); + kbd_send(0xff); + + uint8_t l = 0; + while(true) { - PORTB ^= 0x20; + uint8_t state = PORTB ^ 0x20; + PORTB = state; + + if (state & 0x20) { + l = (l+1)%3; + + kbd_send(0xed); + kbd_send(1 << l); + } uint32_t i; for (i = 0; i < (1 << ts); i++) |