mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[ion] Rewrite the keyboard routine
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
88
ion/platform/device/keyboard.c
Normal file
88
ion/platform/device/keyboard.c
Normal 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);
|
||||
}
|
||||
}
|
||||
1
ion/platform/device/keyboard.h
Normal file
1
ion/platform/device/keyboard.h
Normal file
@@ -0,0 +1 @@
|
||||
void init_keyboard();
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user