diff options
author | Christian Pointner <equinox@helsinki.at> | 2014-06-01 01:17:44 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2014-06-01 01:17:44 (GMT) |
commit | f8b160eafcdee78ed9b39af432227a978c3f476c (patch) | |
tree | a96e5d4afa945e7a4a5ec1b2ef5b440af12466a7 /software/rhmixxx | |
parent | 07491040c60fe1c1a1876ce6d1c2c66484e6aa02 (diff) |
added first working support for keypad keys
Diffstat (limited to 'software/rhmixxx')
-rw-r--r-- | software/rhmixxx/keypad.c | 125 | ||||
-rw-r--r-- | software/rhmixxx/keypad.h | 5 |
2 files changed, 115 insertions, 15 deletions
diff --git a/software/rhmixxx/keypad.c b/software/rhmixxx/keypad.c index 7362ab4..6e39cc1 100644 --- a/software/rhmixxx/keypad.c +++ b/software/rhmixxx/keypad.c @@ -20,36 +20,133 @@ */ #include <avr/io.h> +#include <util/delay.h> #include "keypad.h" #define KEYPAD_PIN PINA #define KEYPAD_PORT PORTA #define KEYPAD_DDR DDRA -#define LEDS_LOW_PORT PORTC -#define LEDS_LOW_DDR DDRC -#define LEDS_HIGH_PORT PORTD -#define LEDS_HIGH_DDR DDRD +#define KEYPAD_LP_CNT_MAX 200 +static struct key_state_struct { + uint8_t last_sent; + int16_t lp_cnt; +} keypad_state[16]; + void keypad_init(void) { KEYPAD_DDR = 0x00; - KEYPAD_PORT = 0xFF; + KEYPAD_PORT = 0x0F; + uint8_t i; + for(i = 0; i < 16; ++i) { + keypad_state[i].last_sent = 0; + keypad_state[i].lp_cnt = 0; + } + + DDRC = 0xFF; + DDRB |= 0xF0; + DDRD |= 0xF0; - LEDS_LOW_DDR = 0xFF; - LEDS_LOW_PORT = 0xFF; - LEDS_HIGH_DDR = 0xFF; - LEDS_HIGH_PORT = 0xFF; + PORTC = 0x00; + PORTB &= 0x0F; + PORTD &= 0x0F; } -void keypad_start_led_test(int cnt) +void keypad_led_on(uint8_t led) { - LEDS_LOW_PORT = 0x00; - LEDS_HIGH_PORT = 0x00; + switch(led) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: PORTC |= (1 << led); break; + case 8: + case 9: + case 10: + case 11: PORTB |= (1 << (led - 8 + 4)); break; + case 12: + case 13: + case 14: + case 15: PORTD |= (1 << (led - 12 + 4)); break; + } +} + +void keypad_led_off(uint8_t led) +{ + switch(led) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: PORTC &= ~(1 << led); break; + case 8: + case 9: + case 10: + case 11: PORTB &= ~(1 << (led - 8 + 4)); break; + case 12: + case 13: + case 14: + case 15: PORTD &= ~(1 << (led - 12 + 4)); break; + } +} + +void keypad_led_toggle(uint8_t led) +{ + switch(led) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: PORTC ^= (1 << led); break; + case 8: + case 9: + case 10: + case 11: PORTB ^= (1 << (led - 8 + 4)); break; + case 12: + case 13: + case 14: + case 15: PORTD ^= (1 << (led - 12 + 4)); break; + } } void keypad_task(void) { - // TODO: poll keypad matrix for changes (with low pass) - // control led test (if running) + uint8_t col, row; + for(col = 0; col < 4; ++col) { + KEYPAD_DDR = 1 << (col + 4); + KEYPAD_PORT = 0x0F; + _delay_us(10); + + for(row = 0; row < 4; ++row) { + uint8_t key_idx = col*4 + row; + uint8_t current_state = KEYPAD_PIN & (1 << row); + keypad_state[key_idx].lp_cnt += current_state ? -1 : +1; + if(keypad_state[key_idx].lp_cnt <= 0 || + keypad_state[key_idx].lp_cnt >= KEYPAD_LP_CNT_MAX) { + + keypad_state[key_idx].lp_cnt = keypad_state[key_idx].lp_cnt <= 0 ? 0 : KEYPAD_LP_CNT_MAX; + + if(current_state != keypad_state[key_idx].last_sent) { + keypad_state[key_idx].last_sent = current_state; + + if(current_state) { + keypad_led_off(key_idx); + } else { + keypad_led_on(key_idx); + } + } + } + } + } + KEYPAD_DDR = 0x00; } diff --git a/software/rhmixxx/keypad.h b/software/rhmixxx/keypad.h index 6f28b24..14a0a08 100644 --- a/software/rhmixxx/keypad.h +++ b/software/rhmixxx/keypad.h @@ -23,7 +23,10 @@ #define RHMIXXX_keypad_h_INCLUDED void keypad_init(void); -void keypad_start_led_test(int cnt); + +void keypad_leds_on(uint16_t leds); +void keypad_leds_off(uint16_t leds); +void keypad_leds_toggle(uint16_t leds); void keypad_task(void); |