diff options
-rw-r--r-- | CMakeLists.txt | 9 | ||||
-rw-r--r-- | ardkbd.c | 106 |
2 files changed, 103 insertions, 12 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e6d2fc..3f11ae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8.3) -SET(BOARD "atmega328" CACHE STRING "AVR CPU to build for") +SET(BOARD "atmega328p" CACHE STRING "AVR CPU to build for") SET(CLOCK "16000000" CACHE STRING "CPU clock") SET(FLASH_FLAGS "-patmega328p" "-carduino" "-P/dev/ttyUSB0" "-b57600" CACHE STRING "avrdude flags") @@ -13,12 +13,6 @@ find_program(AVRDUDE avrdude) SET(CMAKE_SYSTEM_NAME Generic) -#SET(CWARN "-Wall") -#SET(CTUNING "-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums") -#SET(COPT "-Os") -#SET(CMCU "-mmcu=${BOARD}") -#SET(CDEFS "-DF_CPU=${CLOCK}") - SET(CMAKE_C_COMPILER ${AVR_GCC}) project(ARDKBD C) @@ -31,6 +25,7 @@ add_executable(ardkbd.elf ) set_target_properties(ardkbd.elf PROPERTIES COMPILE_FLAGS "-Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Os -mmcu=${BOARD}" + LINK_FLAGS "-Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Os -mmcu=${BOARD}" COMPILE_DEFINITIONS "F_CPU=${CLOCK}" ) @@ -1,18 +1,114 @@ #include <avr/io.h> +#include <avr/interrupt.h> #include <util/delay.h> - #include <stdbool.h> +#include <stdint.h> + + +static volatile uint8_t kbd_state = 0; +static volatile uint8_t kbd_input = 0; +static volatile uint8_t kbd_flags = 0; + + +#define KBD_FLAG_ERROR (_BV(0)) +#define KBD_FLAG_BREAK (_BV(1)) +#define KBD_FLAG_EXT (_BV(2)) + +#define KBD_CODE_UP 0xe075 +#define KBD_CODE_LEFT 0xe06b +#define KBD_CODE_DOWN 0xe072 +#define KBD_CODE_RIGHT 0xe074 + + + +static inline bool kbd_data() { + return (PINC & (1 << 0)); +} +static inline bool kbd_clock() { + return (PINC & (1 << 1)); +} + + +ISR(PCINT1_vect) { + if (kbd_clock()) + return; + + bool data = kbd_data(); + + if (kbd_state == 0) { + if (!data) { /* start bit */ + kbd_input = 0; + kbd_state++; + } + + return; + } + + if (kbd_state <= 8) { + kbd_input |= (data << (kbd_state-1)); + kbd_state++; + return; + } + if (kbd_state == 9) { + if ((__builtin_popcount(kbd_input) & 1) == data) + kbd_flags |= KBD_FLAG_ERROR; -int main() { - DDRB = 0xFF; + kbd_state++; + return; + } + + kbd_state = 0; + + if (kbd_flags & KBD_FLAG_ERROR) { + /* Retry */ + return; + } + + if (kbd_input == 0xe0) { + kbd_flags |= KBD_FLAG_EXT; + return; + } + + if (kbd_input == 0xf0) { + kbd_flags |= KBD_FLAG_BREAK; + return; + } + + uint16_t code = kbd_input; + if (kbd_flags & KBD_FLAG_EXT) + code |= 0xe000; + + if (!(kbd_flags & KBD_FLAG_BREAK)) { + switch (code) { + case KBD_CODE_UP: + PORTB = 0x20; + break; + + case KBD_CODE_DOWN: + PORTB = 0; + break; + } + } + + kbd_flags = 0; +} + +int main(void) { + DDRB = 0xff; PORTB = 0; + DDRC = 0x00; + PORTC = 0x03; + + PCMSK1 = (1 << PCINT9); + PCICR = (1 << PCIE1); + + sei(); + while(true) { - _delay_ms(1000); - PORTB ^= 0x20; } return 0; |