[ion] better ion_getchar

This commit is contained in:
Romain Goyet
2015-09-19 09:54:24 +02:00
parent c6bde2f92c
commit e45e5a0049
3 changed files with 51 additions and 69 deletions

View File

@@ -44,14 +44,13 @@ typedef enum {
ION_KEY_G_2,
ION_KEY_G_3,
ION_KEY_G_4,
ION_KEY_G_5,
ION_KEY_LAST
ION_KEY_G_5
} ion_key_t;
#define ION_NUMBER_OF_KEYS 35
bool ion_key_state(ion_key_t key);
// FIXME: Which state is "true"?
bool ion_key_down(ion_key_t key);
// This is our keymap
char ion_getchar();

View File

@@ -50,22 +50,27 @@ static inline uint8_t column_for_key(ion_key_t key) {
return key%5;
}
bool ion_key_state(ion_key_t key) {
bool ion_key_down(ion_key_t key) {
/* Drive the corresponding row low, and let all the others float.
* Note: In open-drain mode, a 0 in the register drives low, and a 1 let the
* Note: In open-drain mode, a 0 in the register drives low, and a 1 lets the
* pin in Hi-Z (floating). */
GPIO_ODR(GPIOA) = ~(1 << (column_for_key(key)+ROW_PIN_START));
uint32_t output_mask = (((uint32_t)1 << (ROW_PIN_END-ROW_PIN_START+1)) - 1) << ROW_PIN_START;
uint32_t previous_odr = GPIO_ODR(GPIOA);
uint32_t new_odr = ~((uint32_t)1 << (row_for_key(key)+ROW_PIN_START)) & output_mask;
// Wait a little...
for (int i=0;i<10000;i++) {
if (new_odr != previous_odr) {
GPIO_ODR(GPIOA) = new_odr;
// We changed the outputs, give the hardware some time to react to this change
// FIXME: Real delay!
for (int i=0;i<1000; i++) {
}
}
// Read the input of the proper column
uint32_t input = (GPIO_IDR(GPIOA) & (1 << (row_for_key(key)+COLUMN_PIN_START)));
uint32_t input = (GPIO_IDR(GPIOA) & (1 << (column_for_key(key)+COLUMN_PIN_START)));
// The key is pressed if the input is brought low by the output. In other
// words, we want to return "true" (1) if the input is low (0).
// Return the logical opposite of what we've just read
/* The key is down if the input is brought low by the output. In other words,
* we want to return "true" (1) if the input is low (0). */
return (input == 0);
}

View File

@@ -2,67 +2,45 @@
#include <string.h>
char charForKey[ION_NUMBER_OF_KEYS] = {
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8'
'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y',
'Z', '0', '1', '2', '3',
'4', '5', '6', '7', '8'
};
char ion_getchar() {
// Let's start by saving which keys we've seen up
bool key_seen_up[ION_NUMBER_OF_KEYS];
for (ion_key_t k=0; k<ION_NUMBER_OF_KEYS; k++) {
key_seen_up[k] = !ion_key_down(k);
}
// Wait a little to debounce the button.
// FIXME: REAL SLEEP
for (int i=0;i<10000;i++) {
}
/* Let's discard the keys we previously saw up but which aren't anymore: those
* were probably bouncing! */
for (ion_key_t k=0; k<ION_NUMBER_OF_KEYS; k++) {
key_seen_up[k] &= !ion_key_down(k);
}
while (1) {
ion_sleep();
for (ion_key_t k=0;k<ION_NUMBER_OF_KEYS; k++) {
if (ion_key_state(k)) {
return charForKey[k];
for (ion_key_t k=0; k<ION_NUMBER_OF_KEYS; k++) {
if (ion_key_down(k)) {
if (key_seen_up[k]) {
return charForKey[k];
}
} else {
key_seen_up[k] = 1;
}
}
ion_sleep();
// FIXME: REAL SLEEP
for (int i=0;i<10000;i++) {
}
}
/*
bool key_states[ION_NUMBER_OF_KEYS];
memcpy(key_states, ion_key_states, ION_NUMBER_OF_KEYS);
while (1) {
for (int k=0; k<ION_NUMBER_OF_KEYS; k++) {
if (ion_key_states[k]) {
if (!key_states[k]) {
return charForKey[k];
}
} else {
// Key k is down. So if we ever see it up, we'll want to return a char.
key_states[k] = 0;
}
}
ion_sleep();
}
*/
}