summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2014-06-01 01:17:44 (GMT)
committerChristian Pointner <equinox@helsinki.at>2014-06-01 01:17:44 (GMT)
commitf8b160eafcdee78ed9b39af432227a978c3f476c (patch)
treea96e5d4afa945e7a4a5ec1b2ef5b440af12466a7
parent07491040c60fe1c1a1876ce6d1c2c66484e6aa02 (diff)
added first working support for keypad keys
-rw-r--r--software/rhmixxx/keypad.c125
-rw-r--r--software/rhmixxx/keypad.h5
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);