/** * @file keypad.c * * @date 01.02.2015 * @author Pascal Gollor * web http://www.pgollor.de * * @copyright Dieses Werk ist unter einer Creative Commons Lizenz vom Typ * Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 Deutschland zugänglich. * Um eine Kopie dieser Lizenz einzusehen, konsultieren Sie * http://creativecommons.org/licenses/by-sa/3.0/de/ oder wenden Sie sich * brieflich an Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. * * -- englisch version -- * @n This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Germany License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. * */ #include "keypad.h" #include <avr/pgmspace.h> // PROGMEM #include <util/delay.h> // delay_ms #ifdef KEYPAD_DEBUG #include "defs.h" #include "uart.h" #endif /** * @brief keypad keys * * for each key you can use everything value from 0-254 * 255 means: no valid key */ PROGMEM const uint8_t g_keypad_key[KEYPAD_ROWS][KEYPAD_COLUMNS] = { {'a', 'b', '#', '*'}, {'1', '2', '3', 'c'}, {'4', '5', '6', 'd'}, {'7', '8', '9', 'e'}, {'<', '0', '>', 'f'} }; /** * @brief init io ports for keypad */ void keypad_init(void) { // columns KEYPAD_COLUMN_REGISTER |= KEYPAD_COLUMN_BITS; // define columns as output KEYPAD_COLUMN_OUT &= ~(KEYPAD_COLUMN_BITS); // set columns to zero // rows KEYPAD_ROW_REGISTER &= ~(KEYPAD_ROW_BITS); // define rows as input KEYPAD_ROW_OUT |= KEYPAD_ROW_BITS; // enable pullup for rows } /** * @brief get key from keypad */ uint8_t keypad_getKey(void) { uint8_t col = KEYPAD_NO_VALID_KEY; uint8_t row = 0; // read row channels row = ((~KEYPAD_ROW_IN) & KEYPAD_ROW_BITS) >> KEYPAD_ROW_FIRST_CHANNEL; if (row == 0) { // no key is pressed return KEYPAD_NO_VALID_KEY; } // wait for debounce _delay_ms(10); if (row != ((~KEYPAD_ROW_IN) & KEYPAD_ROW_BITS) >> KEYPAD_ROW_FIRST_CHANNEL) { return KEYPAD_NO_VALID_KEY; } // set columns to zero KEYPAD_COLUMN_OUT &= ~(KEYPAD_COLUMN_BITS); _delay_us(1); // check for pressed column for (uint8_t i = KEYPAD_COLUMN_FIRST_CHANNEL; i < (KEYPAD_COLUMN_FIRST_CHANNEL + KEYPAD_COLUMNS); i++) { KEYPAD_COLUMN_OUT |= (1 << i); _delay_us(1); if ((KEYPAD_ROW_IN & KEYPAD_ROW_BITS) == KEYPAD_ROW_BITS) { // debounce _delay_ms(10); if ((KEYPAD_ROW_IN & KEYPAD_ROW_BITS) != KEYPAD_ROW_BITS) { col = KEYPAD_NO_VALID_KEY; break; } col = i - KEYPAD_COLUMN_FIRST_CHANNEL; break; } KEYPAD_COLUMN_OUT &= ~(1 << i); _delay_us(1); } // set columns to zero KEYPAD_COLUMN_OUT &= ~(KEYPAD_COLUMN_BITS); if (col == KEYPAD_NO_VALID_KEY) { // no column detected return KEYPAD_NO_VALID_KEY; } // detect row for (uint8_t i = 0; i < KEYPAD_ROWS; i++) { if (row >> i == 1) { row = i; break; } } if (row >= KEYPAD_ROWS) return KEYPAD_NO_VALID_KEY; #ifdef KEYPAD_DEBUG printf("row: %i" CR, row); printf("column: %i" CR, col); uart_flush(); #endif // return key from keylist return pgm_read_byte(&g_keypad_key[row][col]); } /** * @brief get key and wait to for loosing */ uint8_t keypad_getKeyAndWait(void) { uint8_t key = keypad_getKey(); uint8_t last_key = KEYPAD_NO_VALID_KEY; if (key == KEYPAD_NO_VALID_KEY) { return KEYPAD_NO_VALID_KEY; } last_key = key; while (key != KEYPAD_NO_VALID_KEY) { key = keypad_getKey(); } return last_key; }