mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[ion] better ion_getchar
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user