Skip to content

Commit

Permalink
Quick and dirty keymap behaving like the QMK experiment
Browse files Browse the repository at this point in the history
  • Loading branch information
cyril-L committed Jul 14, 2020
1 parent 3ceb08b commit eaea4c6
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 38 deletions.
6 changes: 4 additions & 2 deletions src/keybi/drivers/matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static void delayMicroseconds(uint32_t delay_us)

void Keybi_Matrix_Scan(int (*callback)(keybi_keyboard_matrix_event_t)) {
for (uint8_t c = 0; c < KEYBI_MATRIX_COLS; ++c) {
GPIO_SetBits(cols[c].port, cols[c].pin);
GPIO_SetBits(cols[c].port, cols[c].pin);
for (uint8_t r = 0; r < KEYBI_MATRIX_ROWS; ++r) {
uint8_t state = GPIO_ReadInputDataBit(rows[r].port, rows[r].pin);
if (state != key_states[c][r]) {
Expand All @@ -95,7 +95,9 @@ void Keybi_Matrix_Scan(int (*callback)(keybi_keyboard_matrix_event_t)) {
}
}
}
GPIO_ResetBits(cols[c].port, cols[c].pin);
GPIO_ResetBits(cols[c].port, cols[c].pin);
// Adjacent columns of the first rows registered on a single key press
// TODO investigate why and find the appropriate delay
delayMicroseconds(100);
}
}
16 changes: 11 additions & 5 deletions src/keybi/hid_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,22 @@ uint8_t* Keybi_Keyboard_GetHIDDescriptor(uint16_t Length)
return Standard_GetDescriptorData(Length, &Keybi_Keyboard_Hid_Descriptor);
}

int Keybi_Keyboard_QueueEvent(keybi_keyboard_event_queue_t * queue, keybi_keyboard_event_t event) {
if (queue->size >= queue->capacity) {
int Keybi_Keyboard_QueueEvents(keybi_keyboard_event_queue_t * queue, keybi_keyboard_event_t * events, uint8_t count) {
if (queue->size + count > queue->capacity) {
return -1;
}
unsigned tail = (queue->head + queue->size) % queue->capacity;
queue->events[tail] = event;
queue->size++;
for (int i = 0; i < count; ++i) {
unsigned tail = (queue->head + queue->size) % queue->capacity;
queue->events[tail] = events[i];
queue->size++;
}
return 0;
}

int Keybi_Keyboard_QueueEvent(keybi_keyboard_event_queue_t * queue, keybi_keyboard_event_t event) {
return Keybi_Keyboard_QueueEvents(queue, &event, 1);
}

int Keybi_Keyboard_QueueToReport(keybi_keyboard_event_queue_t * queue, uint8_t * report) {
if (queue->size == 0) {
return 0;
Expand Down
1 change: 1 addition & 0 deletions src/keybi/hid_keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct {
uint32_t capacity;
} keybi_keyboard_event_queue_t;

int Keybi_Keyboard_QueueEvents(keybi_keyboard_event_queue_t * queue, keybi_keyboard_event_t * event, uint8_t count);
int Keybi_Keyboard_QueueEvent(keybi_keyboard_event_queue_t * queue, keybi_keyboard_event_t event);

int Keybi_Keyboard_QueueToReport(keybi_keyboard_event_queue_t * queue, uint8_t * report);
45 changes: 39 additions & 6 deletions src/keybi/keybi.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#include "keybi/drivers/matrix.h"
#include "keybi/keymap.h"

static uint8_t keyboard_hid_report[8] = {0};

void Keybi_Init(void) {

Keybi_Pmw3360_Init();
Expand All @@ -16,11 +14,22 @@ void Keybi_Init(void) {
#pragma GCC push_options
#pragma GCC optimize ("O0")

static int8_t SignedByteClamp(int value) {
if (value < -128) {
return -128;
}
if (value > 127) {
return 127;
}
return value;
}

void Keybi_MainLoop(void)
{
static keybi_pmw3360_motion_t trackball_motion;

static uint8_t mouse_report[5] = {0};
static uint8_t keyboard_hid_report[8] = {0};
static uint8_t mouse_hid_report[5] = {0};

Keybi_Matrix_Scan(&Keybi_Keymap_EventHandler);
while (Keybi_Keyboard_QueueToReport(&keybi_keymap_events, keyboard_hid_report)) {
Expand All @@ -29,9 +38,33 @@ void Keybi_MainLoop(void)

Keybi_Pmw3360_Read(&trackball_motion);
if (trackball_motion.dx != 0 || trackball_motion.dy != 0) {
mouse_report[1] = 3 * ((int)trackball_motion.dy) / 4;
mouse_report[2] = trackball_motion.dx / 2;
Keybi_Mouse_SendReport(mouse_report);
if (keybi_keyboard_layer != L_MOUSE) {
keybi_keyboard_layer = L_MOUSE;
keybi_mouse_is_scrolling = 0;
}
int dx = SignedByteClamp(3 * ((int)trackball_motion.dy) / 4);
int dy = SignedByteClamp(trackball_motion.dx / 2);

if (!keybi_mouse_is_scrolling) {
mouse_hid_report[1] = dx;
mouse_hid_report[2] = dy;
mouse_hid_report[3] = 0;
mouse_hid_report[4] = 0;
} else {
mouse_hid_report[1] = 0;
mouse_hid_report[2] = 0;
mouse_hid_report[3] = -dy/3;
mouse_hid_report[4] = dx/3;
}
Keybi_Mouse_SendReport(mouse_hid_report);
}
if (mouse_hid_report[0] != keybi_mouse_buttons) {
mouse_hid_report[0] = keybi_mouse_buttons;
mouse_hid_report[1] = 0;
mouse_hid_report[2] = 0;
mouse_hid_report[3] = 0;
mouse_hid_report[4] = 0;
Keybi_Mouse_SendReport(mouse_hid_report);
}
}

Expand Down
197 changes: 172 additions & 25 deletions src/keybi/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
#include "keybi/qmk/keycode.h"
#include "keybi/drivers/matrix.h"

// Quick and dirty way to get a keymap behaving like a previous experiment
// using QMK. Needs to be cleaned up.

// TODO progmem?

#define SAFE_RANGE (0x100)
#define ____ KC_TRNS
#define XXXX KC_NO

enum custom_keycodes {
CL_FN_SWITCH = SAFE_RANGE,
Expand All @@ -17,26 +22,19 @@ enum custom_keycodes {
CL_BRACES,
CL_CMD_CTRL,
CL_TOGGLE_CMD_CTRL,
CL_MOUSE_OUT,
CL_MOUSE_TOGGLE_SCROLL,
CL_SAFE_RANGE
};

typedef enum {
L_BASE = 0,
L_NF_G1_L1,
L_NF_G1_L2,
L_NF_G2_L1,
L_FN,
L_CODE,
L_RCMD,
L_MOUSE
} layer_id_t;
#define OOOO CL_MOUSE_OUT

#define LAYOUT( \
e00, e01, e02, e03, e04, e05, e99, e06, e07, e08, e09, e10, e11, e12, e13, \
d00, d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, \
c00, c01, c02, c03, c04, c05, c07, c08, c09, c10, c11, c12, c13, \
b00, b01, b02, b03, b04, b05, b06, b07, b08, b09, b10, b11, b12, b13, \
a00, a02, a03, a04, a05, a06, a07, a08, a09, a10, a13 \
e00, e01, e02, e03, e04, e05, e99, e06, e07, e08, e09, e10, e11, e12, e13, \
d00, d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11, d12, d13, \
c00, c01, c02, c03, c04, c05, c07, c08, c09, c10, c11, c12, c13, \
b00, b01, b02, b03, b04, b05, b06, b07, b08, b09, b10, b11, b12, b13, \
a00, a02, a03, a04, a05, a06, a07, a08, a09, a10, a13 \
) \
{ \
{ e00, e01, e02, e03, e04, e05, e99, e07, e08, e09, e10, e11, e12, e13}, \
Expand All @@ -62,27 +60,176 @@ const uint16_t keymaps[][KEYBI_MATRIX_ROWS][KEYBI_MATRIX_COLS] = {
* `-----' `-----------------------------------------' `-----'
*/
[L_BASE] = LAYOUT( /* Base */
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_NO, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_NUHS, \
CL_CODE_SWITCH, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSHIFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_UP, KC_NUBS, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSHIFT, \
KC_LCTL, KC_LALT, CL_CMD_CTRL, KC_SPC, KC_LEFT, KC_DOWN, KC_RIGHT, CL_FN_SWITCH, KC_RALT, KC_RGUI, KC_RCTL \
)
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, XXXX, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_NUHS, \
CL_CODE_SWITCH, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSHIFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_UP, KC_NUBS, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSHIFT, \
KC_LCTL, KC_LALT, CL_CMD_CTRL, KC_SPC, KC_LEFT, KC_DOWN, KC_RIGHT, CL_FN_SWITCH, KC_RALT, KC_RGUI, KC_RCTL \
),
[L_FN] = LAYOUT( /* Fn, mostly used for navigation and window management */
KC_PWR, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_NO, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DELETE, \
____, ____, ____, ____, ____, ____, KC_HOME, KC_PGDN, KC_PGUP, KC_END, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, ____, ____, ____, \
XXXX, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, XXXX, \
XXXX, XXXX, CL_TOGGLE_CMD_CTRL, XXXX, ____, ____, ____, ____, XXXX, XXXX, XXXX \
),
[L_CODE] = LAYOUT( /* Mostly used for code */
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, CL_SQUOTS, CL_DQUOTS, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, CL_PARENS, CL_BRCKTS, CL_BRACES, ____, ____, ____, \
XXXX, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, XXXX, \
XXXX, XXXX, XXXX, ____, ____, ____, ____, ____, XXXX, XXXX, XXXX \
),
[L_MOUSE] = LAYOUT( /* Mouse mode */
OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, \
OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, \
OOOO, OOOO, KC_BTN2, KC_BTN3, KC_BTN1, CL_MOUSE_TOGGLE_SCROLL, CL_MOUSE_TOGGLE_SCROLL, KC_BTN1, KC_BTN3, KC_BTN2, OOOO, OOOO, OOOO, \
OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, \
OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO, OOOO \
),
};

static keybi_keyboard_event_t events[8];
static keybi_keyboard_event_t events_data[16];

keybi_keyboard_event_queue_t keybi_keymap_events = {
.events = events,
.events = events_data,
.head = 0,
.size = 0,
.capacity = 8
.capacity = 16
};

int keybi_keyboard_layer = L_BASE;
static bool is_cmd_ctrl = 1;
static int key_pressed_on_code_layer = 0;

int keybi_mouse_is_scrolling = 0;
uint8_t keybi_mouse_buttons = 0;

int Keybi_Keymap_EventHandler(keybi_keyboard_matrix_event_t matrix_event) {

// Here keycode is 16 bit to hold special values
uint16_t keycode = keymaps[keybi_keyboard_layer][matrix_event.row][matrix_event.col];

if (keybi_keyboard_layer == L_CODE && matrix_event.pressed) {
key_pressed_on_code_layer++;
}

while (1) {
if (keycode == CL_FN_SWITCH) {
if (matrix_event.pressed) {
keybi_keyboard_layer = L_FN;
} else {
keybi_keyboard_layer = L_BASE;
}
return 0;
}
if (keycode == CL_CODE_SWITCH) {
if (matrix_event.pressed) {
keybi_keyboard_layer = L_CODE;
key_pressed_on_code_layer = 0;
} else {
keybi_keyboard_layer = L_BASE;
// if no event other than layer
if (!key_pressed_on_code_layer) {
keybi_keyboard_event_t events[2] = {{KC_ESC, 1}, {KC_ESC, 0}};
return Keybi_Keyboard_QueueEvents(&keybi_keymap_events, events, 2);
}
}
return 0;
} else if (keycode == OOOO) {
if (matrix_event.pressed) {
keybi_keyboard_layer = L_BASE;
}
return 0;
}
else if (keycode == CL_CMD_CTRL) {
if (is_cmd_ctrl) {
keycode = KC_LCTL;
} else {
keycode = KC_LGUI;
}
} else if (keycode == CL_TOGGLE_CMD_CTRL) {
if (matrix_event.pressed) {
is_cmd_ctrl = !is_cmd_ctrl;
}
return 0;
} else if (keycode == ____) {
keycode = keymaps[L_BASE][matrix_event.row][matrix_event.col];
continue; // handle this keycode if special
} else if (keycode == CL_PARENS && matrix_event.pressed) {
keybi_keyboard_event_t events[6] = {
{KC_5, 1}, {KC_5, 0},
{KC_6, 1}, {KC_6, 0},
{KC_LEFT, 1}, {KC_LEFT, 0},
};
return Keybi_Keyboard_QueueEvents(&keybi_keymap_events, events, 6);
} else if (keycode == CL_BRCKTS && matrix_event.pressed) {
keybi_keyboard_event_t events[8] = {
{KC_RALT, 1},
{KC_5, 1}, {KC_5, 0},
{KC_6, 1}, {KC_6, 0},
{KC_RALT, 0},
{KC_LEFT, 1}, {KC_LEFT, 0},
};
return Keybi_Keyboard_QueueEvents(&keybi_keymap_events, events, 8);
} else if (keycode == CL_BRACES && matrix_event.pressed) {
keybi_keyboard_event_t events[8] = {
{KC_RALT, 1},
{KC_T, 1}, {KC_T, 0},
{KC_Y, 1}, {KC_Y, 0},
{KC_RALT, 0},
{KC_LEFT, 1}, {KC_LEFT, 0},
};
return Keybi_Keyboard_QueueEvents(&keybi_keymap_events, events, 8);
} else if (keycode == CL_SQUOTS && matrix_event.pressed) {
keybi_keyboard_event_t events[6] = {
{KC_MINS, 1}, {KC_MINS, 0},
{KC_MINS, 1}, {KC_MINS, 0},
{KC_LEFT, 1}, {KC_LEFT, 0},
};
return Keybi_Keyboard_QueueEvents(&keybi_keymap_events, events, 6);
} else if (keycode == CL_DQUOTS && matrix_event.pressed) {
keybi_keyboard_event_t events[8] = {
{KC_LSHIFT, 1},
{KC_MINS, 1}, {KC_MINS, 0},
{KC_MINS, 1}, {KC_MINS, 0},
{KC_LSHIFT, 0},
{KC_LEFT, 1}, {KC_LEFT, 0}
};
return Keybi_Keyboard_QueueEvents(&keybi_keymap_events, events, 8);
} else if (keycode == CL_MOUSE_TOGGLE_SCROLL) {
if (matrix_event.pressed) {
keybi_mouse_is_scrolling = !keybi_mouse_is_scrolling;
}
return 0;
} else if (keycode == KC_BTN1) {
if (matrix_event.pressed) {
keybi_mouse_buttons |= (1 << 0);
} else {
keybi_mouse_buttons &= ~(1 << 0);
}
return 0;
} else if (keycode == KC_BTN2) {
if (matrix_event.pressed) {
keybi_mouse_buttons |= (1 << 1);
} else {
keybi_mouse_buttons &= ~(1 << 1);
}
return 0;
} else if (keycode == KC_BTN3) {
if (matrix_event.pressed) {
keybi_mouse_buttons |= (1 << 2);
} else {
keybi_mouse_buttons &= ~(1 << 2);
}
return 0;
}
// no need to handle this keycode further
break;
};
// TODO check if keycode is not special here
keybi_keyboard_event_t key_event = {
.keycode = keymaps[0][matrix_event.row][matrix_event.col],
.keycode = keycode,
.pressed = matrix_event.pressed
};
return Keybi_Keyboard_QueueEvent(&keybi_keymap_events, key_event);
Expand Down
11 changes: 11 additions & 0 deletions src/keybi/keymap.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
#include "keybi/drivers/matrix.h"
#include "keybi/hid_keyboard.h"

typedef enum {
L_BASE = 0,
L_FN,
L_CODE,
L_MOUSE
} layer_id_t;

int Keybi_Keymap_EventHandler(keybi_keyboard_matrix_event_t event);

// TODO used from outside for experiments, to refactor
extern keybi_keyboard_event_queue_t keybi_keymap_events;
extern int keybi_keyboard_layer;
extern int keybi_mouse_is_scrolling;
extern uint8_t keybi_mouse_buttons;

0 comments on commit eaea4c6

Please sign in to comment.