[ion] Rewrite the keyboard routine

This commit is contained in:
Romain Goyet
2015-09-17 20:15:00 +02:00
parent 98f6929b03
commit 033b091e07
8 changed files with 167 additions and 22 deletions

View File

@@ -3,24 +3,57 @@
#include <stdbool.h>
/* Platforms should simply set the ion_key_states pointer.
* Clients of Ion, (including ion_getchar) will then dereference this pointer to
* read the state of the keys: ion_key_states[ion_key] gives the last known
* state of ion_key */
typedef enum {
ION_KEY_1,
ION_KEY_2,
ION_KEY_3,
ION_KEY_DIVIDE,
ION_KEY_POW,
ION_KEY_DOT
ION_KEY_A_1,
ION_KEY_A_2,
ION_KEY_A_3,
ION_KEY_A_4,
ION_KEY_A_5,
ION_KEY_B_1,
ION_KEY_B_2,
ION_KEY_B_3,
ION_KEY_B_4,
ION_KEY_B_5,
ION_KEY_FAKE_0,
ION_KEY_FAKE_1,
ION_KEY_C_1,
ION_KEY_C_2,
ION_KEY_C_3,
ION_KEY_D_1,
ION_KEY_D_2,
ION_KEY_D_3,
ION_KEY_D_4,
ION_KEY_D_5,
ION_KEY_E_1,
ION_KEY_E_2,
ION_KEY_E_3,
ION_KEY_E_4,
ION_KEY_E_5,
ION_KEY_F_1,
ION_KEY_F_2,
ION_KEY_F_3,
ION_KEY_F_4,
ION_KEY_F_5,
ION_KEY_G_1,
ION_KEY_G_2,
ION_KEY_G_3,
ION_KEY_G_4,
ION_KEY_G_5,
ION_KEY_LAST
} ion_key_t;
#define ION_NUMBER_OF_KEYS 6
#define ION_NUMBER_OF_KEYS 35
extern bool * ion_key_states;
bool ion_key_state(ion_key_t key);
// This is our keymap
char ion_getchar();
#endif

View File

@@ -1,2 +1,2 @@
objs += $(addprefix ion/platform/device/, platform.o init.o display.o framebuffer.o init_kbd.o display/dma.o display/gpio.o display/spi.o)
objs += $(addprefix ion/drivers/, st7586/st7586.o fx92kbd/fx92kbd.o)
objs += $(addprefix ion/platform/device/, platform.o init.o display.o framebuffer.o keyboard.o display/dma.o display/gpio.o display/spi.o)
objs += $(addprefix ion/drivers/, st7586/st7586.o)

View File

@@ -1,7 +1,7 @@
#include <ion.h>
#include <assert.h>
#include "display.h"
#include "init_kbd.h"
#include "keyboard.h"
//#extern char _framebuffer_end;
@@ -13,7 +13,7 @@ void ion_init() {
#endif
*/
init_kbd();
init_keyboard();
init_display();
}

View File

@@ -0,0 +1,88 @@
/* Keyboard initialization code
*
* Our role here is to implement the "ion_key_state" function.
* The keyboard is a matrix that is as plugged as follow:
*
* | PA8 | PA9 | PA10 | PA11 | PA12 |
* ----+------+------+------+------+------+
* PA0 | K_A1 | K_A2 | K_A3 | K_A4 | K_A5 |
* ----+------+------+------+------+------+
* PA1 | K_B1 | K_B2 | K_B3 | K_B4 | K_B5 |
* ----+------+------+------+------+------+
* PA2 | | | K_C1 | K_C2 | K_C3 |
* ----+------+------+------+------+------+
* PA3 | K_D1 | K_D2 | K_D3 | K_D4 | K_D5 |
* ----+------+------+------+------+------+
* PA4 | K_E1 | K_E2 | K_E3 | K_E4 | K_E5 |
* ----+------+------+------+------+------+
* PA5 | K_F1 | K_F2 | K_F3 | K_F4 | K_F5 |
* ----+------+------+------+------+------+
* PA6 | K_G1 | K_G2 | K_G3 | K_G4 | K_G5 |
* ----+------+------+------+------+------+
*
* We decide to drive the rows (PA0-6) and read the columns (PA8-12).
*
* To avoid short-circuits, the pins A0-A6 will not be standard outputs but
* only open-drain. Open drain can either drive low or let it float. Otherwise,
* when a user presses multiple keys, a shortcut between rows could happen,
* which could trigger a short circuit between an output driving high and
* another driving low.
*
* If the outputs are open-drain, this means that the input must be pulled up.
* So if the input reads "1", this means the key is in fact *not* pressed, and
* if it reads "0" it means that there's a short to an open-drain output. Which
* means the corresponding key is pressed.
*/
#include <ion.h>
#include "registers/registers.h"
// We'll make the assertion that the row and column pins are contiguous
#define ROW_PIN_START 0
#define ROW_PIN_END 6
#define COLUMN_PIN_START 8
#define COLUMN_PIN_END 12
static inline uint8_t row_for_key(ion_key_t key) {
return key/5;
}
static inline uint8_t column_for_key(ion_key_t key) {
return key%5;
}
bool ion_key_state(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
* pin in Hi-Z (floating). */
GPIO_ODR(GPIOA) = ~(1 << (column_for_key(key)+ROW_PIN_START));
// Wait a little...
for (int i=0;i<10000;i++) {
}
// Read the input of the proper column
uint32_t input = (GPIO_IDR(GPIOA) & (1 << (row_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
return (input == 0);
}
void init_keyboard() {
/* We are using GPIO group A, which live on the AHB1 bus. Let's start by
* enabling its clock. */
RCC_AHB1ENR |= GPIOAEN;
// Configure the row pins as open-drain outputs
for (int pin=ROW_PIN_START; pin<=ROW_PIN_END; pin++) {
REGISTER_SET_VALUE(GPIO_MODER(GPIOA), MODER(pin), GPIO_MODE_OUTPUT);
REGISTER_SET_VALUE(GPIO_OTYPER(GPIOA), OTYPER(pin), GPIO_OTYPE_OPEN_DRAIN);
}
// Configure the column as are pulled-up inputs
for (int pin=COLUMN_PIN_START; pin<=COLUMN_PIN_END; pin++) {
REGISTER_SET_VALUE(GPIO_MODER(GPIOA), MODER(pin), GPIO_MODE_INPUT);
REGISTER_SET_VALUE(GPIO_PUPDR(GPIOA), PUPDR(pin), GPIO_PUPD_PULL_UP);
}
}

View File

@@ -0,0 +1 @@
void init_keyboard();

View File

@@ -53,6 +53,16 @@ typedef struct {
#define LOW_BIT_MODER(v) (2*v)
#define HIGH_BIT_MODER(v) (2*v+1)
// GPIO port output type registers
#define GPIO_OTYPER(gpio_group) GPIO_REGISTER_AT(gpio_group, 0x04)
#define GPIO_OTYPE_PUSH_PULL 0
#define GPIO_OTYPE_OPEN_DRAIN 1
#define LOW_BIT_OTYPER(v) (v)
#define HIGH_BIT_OTYPER(v) (v)
// GPIO port pull-up/pull-down registers
#define GPIO_PUPDR(gpio_group) GPIO_REGISTER_AT(gpio_group, 0x0C)

View File

@@ -1,8 +1,6 @@
#include <ion.h>
#include <string.h>
bool * ion_key_states;
char charForKey[ION_NUMBER_OF_KEYS] = {
'1',
'2',
@@ -13,6 +11,20 @@ char charForKey[ION_NUMBER_OF_KEYS] = {
};
char ion_getchar() {
while (1) {
ion_sleep();
if (ion_key_state(0)) {
return charForKey[0];
}
/*
for (ion_key_t k=0;k<ION_NUMBER_OF_KEYS; k++) {
if (ion_key_state(k)) {
return charForKey[k];
}
}
*/
}
/*
bool key_states[ION_NUMBER_OF_KEYS];
memcpy(key_states, ion_key_states, ION_NUMBER_OF_KEYS);
while (1) {
@@ -28,4 +40,5 @@ char ion_getchar() {
}
ion_sleep();
}
*/
}

View File

@@ -29,9 +29,9 @@ void hello() {
KDFillRect((KDRect){
.x = 0,
.y = 0,
.width = 320,
.height = 240},
0x7F);
.width = 160,
.height = 160},
0x00);
}
input[index++] = character;
input[index] = 0;