From 30c484156257dfd9b9ed588344420846afb79978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergiusz=20=27q3k=27=20Baza=C5=84ski?= Date: Tue, 17 Sep 2013 14:34:36 +0200 Subject: [PATCH] Keypad support for the keypad. Woo! --- software/keypad/Makefile | 6 +-- software/keypad/buzzer.c | 8 ++-- software/keypad/buzzer.h | 6 +-- software/keypad/io.h | 18 ++++---- software/keypad/keypad.c | 97 ++++++++++++++++++++++++++++++++++++++++ software/keypad/keypad.h | 19 ++++++++ software/keypad/main.c | 4 +- 7 files changed, 138 insertions(+), 20 deletions(-) create mode 100644 software/keypad/keypad.c create mode 100644 software/keypad/keypad.h diff --git a/software/keypad/Makefile b/software/keypad/Makefile index 9202672..e8778b7 100644 --- a/software/keypad/Makefile +++ b/software/keypad/Makefile @@ -1,5 +1,5 @@ PRG = uart_hello -OBJ = main.o buzzer.o +OBJ = main.o buzzer.o keypad.o PROGRAMMER = buspirate PORT = /dev/ttyACM0 MCU_TARGET = atmega8 @@ -8,7 +8,7 @@ OPTIMIZE = -Os DEFS = LIBS = -HZ = 2000000 +HZ = 8000000 # You should not have to change anything below here. @@ -81,7 +81,7 @@ install: $(PRG).hex fuse: avrdude -p $(AVRDUDE_TARGET) -c $(PROGRAMMER) -P $(PORT) -v \ - -U lfuse:w:0xc6:m -U hfuse:w:0xd9:m + -U lfuse:w:0xe4:m -U hfuse:w:0xd9:m ddd: gdbinit ddd --debugger "avr-gdb -x $(GDBINITFILE)" diff --git a/software/keypad/buzzer.c b/software/keypad/buzzer.c index 094120a..458e67a 100644 --- a/software/keypad/buzzer.c +++ b/software/keypad/buzzer.c @@ -22,7 +22,7 @@ void buzzer_start(uint16_t ticks) cli(); TIMSK &= ~_BV(OCIE1A); OCR1A = ticks; - TIMSK = _BV(OCIE1A); + TIMSK |= _BV(OCIE1A); TCNT1 = 0; sei(); } @@ -42,10 +42,10 @@ ISR(TIMER1_COMPA_vect) void buzzer_signal_boot(void) { buzzer_start(TONE_LOW); - _delay_ms(100); + _delay_ms(200); buzzer_start(TONE_MID); - _delay_ms(100); + _delay_ms(200); buzzer_start(TONE_HIGH); - _delay_ms(100); + _delay_ms(200); buzzer_stop(); } diff --git a/software/keypad/buzzer.h b/software/keypad/buzzer.h index 1d6eaa9..f2e4972 100644 --- a/software/keypad/buzzer.h +++ b/software/keypad/buzzer.h @@ -3,8 +3,8 @@ void buzzer_init(void); -#define TONE_LOW 8 -#define TONE_MID 4 -#define TONE_HIGH 2 +#define TONE_LOW 128 +#define TONE_MID 64 +#define TONE_HIGH 32 #endif diff --git a/software/keypad/io.h b/software/keypad/io.h index b4f4264..06a7065 100644 --- a/software/keypad/io.h +++ b/software/keypad/io.h @@ -6,21 +6,21 @@ typedef struct volatile uint8_t *DDR; volatile uint8_t *PORT; volatile uint8_t *PIN; - uint8_t Bitmap; + uint8_t BitShift; } TIOPort; -#define DECLARE_IO(name, port, bit) TIOPort g_IO_##name = { &DDR##port, &PORT##port, &PIN##port, (1 << bit) } +#define DECLARE_IO(name, port, bit) TIOPort g_IO_##name = { &DDR##port, &PORT##port, &PIN##port, bit } #define IMPORT_IO(name) extern TIOPort g_IO_##name -#define IO_SET_OUTPUT(name) do { *g_IO_##name.DDR |= g_IO_##name.Bitmap; } while(0) -#define IO_SET_INPUT(name) do { *g_IO_##name.DDR &= ~g_IO_##name.Bitmap; } while(0) -#define IO_INPUT_PULLUP(name) do { *g_IO_##name.PORT |= g_IO_##name.Bitmap; } while(0) +#define IO_SET_OUTPUT(name) do { *g_IO_##name.DDR |= (1 << g_IO_##name.BitShift); } while(0) +#define IO_SET_INPUT(name) do { *g_IO_##name.DDR &= ~(1 << g_IO_##name.BitShift); } while(0) +#define IO_INPUT_PULLUP(name) do { *g_IO_##name.PORT |= (1<< g_IO_##name.BitShift); } while(0) #define IO_OUT(name, value) do { if (value) \ - *g_IO_##name.PORT |= g_IO_##name.Bitmap; \ + *g_IO_##name.PORT |= (1 << g_IO_##name.BitShift); \ else \ - *g_IO_##name.PORT &= ~g_IO_##name.Bitmap; } while(0) -#define IO_TOGGLE(name) do { *g_IO_##name.PORT ^= g_IO_##name.Bitmap; } while(0) -#define IO_IN(name) (*g_IO_##name.PIN & g_IO_##name.Bitmap) + *g_IO_##name.PORT &= ~(1 << g_IO_##name.BitShift); } while(0) +#define IO_TOGGLE(name) do { *g_IO_##name.PORT ^= (1 << g_IO_##name.BitShift); } while(0) +#define IO_IN(name) ((*g_IO_##name.PIN >> g_IO_##name.BitShift) & 1) #endif diff --git a/software/keypad/keypad.c b/software/keypad/keypad.c new file mode 100644 index 0000000..96a255e --- /dev/null +++ b/software/keypad/keypad.c @@ -0,0 +1,97 @@ +#include +#include + +#include "io.h" + +IMPORT_IO(KPAD_ROW1); +IMPORT_IO(KPAD_ROW2); +IMPORT_IO(KPAD_ROW3); +IMPORT_IO(KPAD_ROW4); +IMPORT_IO(KPAD_COL1); +IMPORT_IO(KPAD_COL2); +IMPORT_IO(KPAD_COL3); + +IMPORT_IO(LED_RED); +IMPORT_IO(LED_GREEN); + +void _keypad_update_column(void); + +void keypad_init(void) +{ + TCCR0 = _BV(CS02); + TCNT0 = 0; + TIMSK |= _BV(TOIE0); + + IO_OUT(KPAD_ROW1, 1); + IO_OUT(KPAD_ROW2, 1); + IO_OUT(KPAD_ROW3, 1); + IO_OUT(KPAD_ROW4, 1); +} + +uint8_t g_KeypadColumn = 0; + +void _keypad_update_column(void) +{ + g_KeypadColumn++; + if (g_KeypadColumn > 2) + g_KeypadColumn = 0; + + switch(g_KeypadColumn) + { + case 0: + IO_SET_OUTPUT(KPAD_COL1); + IO_SET_INPUT(KPAD_COL2); + IO_SET_INPUT(KPAD_COL3); + IO_OUT(KPAD_COL1, 0); + IO_OUT(KPAD_COL2, 1); + IO_OUT(KPAD_COL3, 1); + break; + case 1: + IO_SET_INPUT(KPAD_COL1); + IO_SET_OUTPUT(KPAD_COL2); + IO_SET_INPUT(KPAD_COL3); + IO_OUT(KPAD_COL1, 1); + IO_OUT(KPAD_COL2, 0); + IO_OUT(KPAD_COL3, 1); + break; + case 2: + IO_SET_INPUT(KPAD_COL1); + IO_SET_INPUT(KPAD_COL2); + IO_SET_OUTPUT(KPAD_COL3); + IO_OUT(KPAD_COL1, 1); + IO_OUT(KPAD_COL2, 1); + IO_OUT(KPAD_COL3, 0); + break; + } +} + +// all the buttons of the matrix in a bitfield +uint16_t g_KeypadState = 0; +uint16_t g_NewKeypadState = 0;; + +uint8_t _keypad_read_rows(void) +{ + uint8_t Result = 0; + Result |= (IO_IN(KPAD_ROW1) << 0); + Result |= (IO_IN(KPAD_ROW2) << 1); + Result |= (IO_IN(KPAD_ROW3) << 2); + Result |= (IO_IN(KPAD_ROW4) << 3); + Result |= 0b11110000; + return ~Result; +} + +ISR(TIMER0_OVF_vect) +{ + _keypad_update_column(); + if (g_KeypadColumn == 0) + { + g_KeypadState = g_NewKeypadState; + g_NewKeypadState = 0; + } + uint8_t State = _keypad_read_rows(); + g_NewKeypadState |= (State << (4 * g_KeypadColumn)); + + IO_OUT(LED_GREEN, (g_KeypadState >> 0) & 1); + IO_OUT(LED_RED, (g_KeypadState >> 1) & 1); +} + diff --git a/software/keypad/keypad.h b/software/keypad/keypad.h new file mode 100644 index 0000000..05bd1d4 --- /dev/null +++ b/software/keypad/keypad.h @@ -0,0 +1,19 @@ +#ifndef __KEYPAD_H__ +#define __KEYPAD_H__ + +void keypad_init(void); + +#define KEY_3 0 +#define KEY_6 1 +#define KEY_9 2 +#define KEY_P 3 +#define KEY_2 4 +#define KEY_5 5 +#define KEY_8 6 +#define KEY_0 7 +#define KEY_1 8 +#define KEY_4 9 +#define KEY_7 10 +#define KEY_S 11 + +#endif diff --git a/software/keypad/main.c b/software/keypad/main.c index 4419675..8bc84df 100644 --- a/software/keypad/main.c +++ b/software/keypad/main.c @@ -5,6 +5,7 @@ #include "io.h" #include "buzzer.h" +#include "keypad.h" ///////////////////// // I/O ports setup // @@ -19,7 +20,7 @@ DECLARE_IO(LED_GREEN, C, 0); // Keypad DECLARE_IO(KPAD_COL3, D, 0); -DECLARE_IO(KAPD_ROW3, D, 1); +DECLARE_IO(KPAD_ROW3, D, 1); DECLARE_IO(KPAD_COMMON, D, 2); DECLARE_IO(KPAD_COL2, D, 3); DECLARE_IO(KPAD_ROW1, D, 4); @@ -36,6 +37,7 @@ int main (void) IO_SET_OUTPUT(LED_GREEN); buzzer_init(); + keypad_init(); sei(); // Flash LEDs and buzz buzzer for debug