Drashna's split updates (#13350)

Co-authored-by: Ryan <fauxpark@gmail.com>
This commit is contained in:
Drashna Jaelre 2021-07-01 00:42:32 -07:00 committed by GitHub
parent bbe45185e3
commit b7cf9a888a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 1889 additions and 1819 deletions

View file

@ -1,17 +0,0 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// placeholder

View file

@ -1,4 +0,0 @@
USER_NAME := drashna
SRC += ../drashna/keymap.c
include $(KEYBOARD_PATH_1)/keymaps/drashna/rules.mk

View file

@ -1,616 +0,0 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stddef.h>
#include "matrix.h"
#include QMK_KEYBOARD_H
#define ROWS_PER_HAND (MATRIX_ROWS / 2)
#define SYNC_TIMER_OFFSET 2
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
#ifdef ENCODER_ENABLE
# include "encoder.h"
static pin_t encoders_pad[] = ENCODERS_PAD_A;
# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
#endif
#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
# include "led_matrix.h"
#endif
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
# include "rgb_matrix.h"
#endif
#ifdef POINTING_DEVICE_ENABLE
static uint16_t device_cpi = 0;
static int8_t split_mouse_x = 0, split_mouse_y = 0;
#endif
#ifdef OLED_DRIVER_ENABLE
# include "oled_driver.h"
#endif
#if defined(USE_I2C)
# include "i2c_master.h"
# include "i2c_slave.h"
typedef struct _I2C_slave_buffer_t {
# ifndef DISABLE_SYNC_TIMER
uint32_t sync_timer;
# endif
# ifdef SPLIT_TRANSPORT_MIRROR
matrix_row_t mmatrix[ROWS_PER_HAND];
# endif
matrix_row_t smatrix[ROWS_PER_HAND];
# ifdef SPLIT_MODS_ENABLE
uint8_t real_mods;
uint8_t weak_mods;
# ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods;
# endif
# endif
# ifdef BACKLIGHT_ENABLE
uint8_t backlight_level;
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
rgblight_syncinfo_t rgblight_sync;
# endif
# ifdef ENCODER_ENABLE
uint8_t encoder_state[NUMBER_OF_ENCODERS];
# endif
# ifdef WPM_ENABLE
uint8_t current_wpm;
# endif
int8_t mouse_x;
int8_t mouse_y;
uint16_t device_cpi;
bool oled_on;
layer_state_t t_layer_state;
layer_state_t t_default_layer_state;
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
led_eeconfig_t led_matrix;
bool led_suspend_state;
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
rgb_config_t rgb_matrix;
bool rgb_suspend_state;
# endif
} __attribute__((packed)) I2C_slave_buffer_t;
static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
# define I2C_KEYMAP_MASTER_START offsetof(I2C_slave_buffer_t, mmatrix)
# define I2C_KEYMAP_SLAVE_START offsetof(I2C_slave_buffer_t, smatrix)
# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer)
# define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods)
# define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods)
# define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)
# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm)
# define I2C_MOUSE_X_START offsetof(I2C_slave_buffer_t, mouse_x)
# define I2C_MOUSE_Y_START offsetof(I2C_slave_buffer_t, mouse_y)
# define I2C_MOUSE_DPI_START offsetof(I2C_slave_buffer_t, device_cpi)
# define I2C_OLED_ON_START offsetof(I2C_slave_buffer_t, oled_on)
# define I2C_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_layer_state)
# define I2C_DEFAULT_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_default_layer_state)
# define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix)
# define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state)
# define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix)
# define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state)
# define TIMEOUT 100
# ifndef SLAVE_I2C_ADDRESS
# define SLAVE_I2C_ADDRESS 0x32
# endif
// Get rows from other half over i2c
bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_SLAVE_START, (void *)slave_matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
# ifdef SPLIT_TRANSPORT_MIRROR
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_MASTER_START, (void *)master_matrix, sizeof(i2c_buffer->mmatrix), TIMEOUT);
# endif
// write backlight info
# ifdef BACKLIGHT_ENABLE
uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
if (level != i2c_buffer->backlight_level) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
i2c_buffer->backlight_level = level;
}
}
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
if (rgblight_get_change_flags()) {
rgblight_syncinfo_t rgblight_sync;
rgblight_get_syncinfo(&rgblight_sync);
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
rgblight_clear_change_flags();
}
}
# endif
# ifdef ENCODER_ENABLE
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT);
encoder_update_raw(i2c_buffer->encoder_state);
# endif
# ifdef WPM_ENABLE
uint8_t current_wpm = get_current_wpm();
if (current_wpm != i2c_buffer->current_wpm) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WPM_START, (void *)&current_wpm, sizeof(current_wpm), TIMEOUT) >= 0) {
i2c_buffer->current_wpm = current_wpm;
}
}
# endif
# ifdef POINTING_DEVICE_ENABLE
if (is_keyboard_left()) {
report_mouse_t temp_report = pointing_device_get_report();
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT);
temp_report.x = i2c_buffer->mouse_x;
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT);
temp_report.y = i2c_buffer->mouse_y;
pointing_device_set_report(temp_report);
if (device_cpi != i2c_buffer->device_cpi) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_DPI_START, (void *)&device_cpi, sizeof(device_cpi), TIMEOUT) >= 0) {
i2c_buffer->device_cpi = device_cpi
}
}
}
# endif
# ifdef SPLIT_MODS_ENABLE
uint8_t real_mods = get_mods();
if (real_mods != i2c_buffer->real_mods) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) {
i2c_buffer->real_mods = real_mods;
}
}
uint8_t weak_mods = get_weak_mods();
if (weak_mods != i2c_buffer->weak_mods) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) {
i2c_buffer->weak_mods = weak_mods;
}
}
# ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods = get_oneshot_mods();
if (oneshot_mods != i2c_buffer->oneshot_mods) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) {
i2c_buffer->oneshot_mods = oneshot_mods;
}
}
# endif
# endif
if (layer_state != i2c_buffer->t_layer_state) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&layer_state, sizeof(layer_state), TIMEOUT) >= 0) {
i2c_buffer->t_layer_state = layer_state;
}
}
if (default_layer_state != i2c_buffer->t_default_layer_state) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_DEFAULT_LAYER_STATE_START, (void *)&default_layer_state, sizeof(default_layer_state), TIMEOUT) >= 0) {
i2c_buffer->t_default_layer_state = default_layer_state;
}
}
# ifdef OLED_DRIVER_ENABLE
bool is_oled_on = is_oled_on();
if (is_oled_on != i2c_buffer->oled_on) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&is_oled_on, sizeof(is_oled_on), TIMEOUT) >= 0) {
i2c_buffer->oled_on = is_oled_on;
}
}
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT);
bool suspend_state = led_matrix_get_suspend_state();
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT);
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT);
bool suspend_state = rgb_matrix_get_suspend_state();
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT);
# endif
# ifndef DISABLE_SYNC_TIMER
i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
# endif
return true;
}
void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
# ifndef DISABLE_SYNC_TIMER
sync_timer_update(i2c_buffer->sync_timer);
# endif
// Copy matrix to I2C buffer
memcpy((void *)i2c_buffer->smatrix, (void *)slave_matrix, sizeof(i2c_buffer->smatrix));
# ifdef SPLIT_TRANSPORT_MIRROR
memcpy((void *)master_matrix, (void *)i2c_buffer->mmatrix, sizeof(i2c_buffer->mmatrix));
# endif
// Read Backlight Info
# ifdef BACKLIGHT_ENABLE
backlight_set(i2c_buffer->backlight_level);
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// Update the RGB with the new data
if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
i2c_buffer->rgblight_sync.status.change_flags = 0;
}
# endif
# ifdef ENCODER_ENABLE
encoder_state_raw(i2c_buffer->encoder_state);
# endif
# ifdef WPM_ENABLE
set_current_wpm(i2c_buffer->current_wpm);
# endif
# ifdef POINTING_DEVICE_ENABLE
if (!is_keyboard_left()) {
static uint16_t cpi;
if (cpi != i2c_buffer->device_cpi) {
cpi = i2c_buffer->device_cpi;
pmw_set_cpi(cpi);
}
i2c_buffer->mouse_x = split_mouse_x;
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT);
i2c_buffer->mouse_y = split_mouse_y;
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT);
}
# endif
# ifdef SPLIT_MODS_ENABLE
set_mods(i2c_buffer->real_mods);
set_weak_mods(i2c_buffer->weak_mods);
# ifndef NO_ACTION_ONESHOT
set_oneshot_mods(i2c_buffer->oneshot_mods);
# endif
# endif
if (layer_state != i2c_buffer->t_layer_state) {
layer_state = i2c_buffer->t_layer_state;
}
if (default_layer_state != i2c_buffer->t_default_layer_state) {
default_layer_state = i2c_buffer->t_default_layer_state;
}
# ifdef OLED_DRIVER_ENABLE
if (i2c_buffer->oled_on) {
oled_on();
} else {
oled_off();
}
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix));
led_matrix_set_suspend_state(i2c_buffer->led_suspend_state);
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix));
rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state);
# endif
}
void transport_master_init(void) { i2c_init(); }
void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
#else // USE_SERIAL
# include "serial.h"
typedef struct _Serial_s2m_buffer_t {
// TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
matrix_row_t smatrix[ROWS_PER_HAND];
# ifdef ENCODER_ENABLE
uint8_t encoder_state[NUMBER_OF_ENCODERS];
# endif
int8_t mouse_x;
int8_t mouse_y;
} __attribute__((packed)) Serial_s2m_buffer_t;
typedef struct _Serial_m2s_buffer_t {
# ifdef SPLIT_MODS_ENABLE
uint8_t real_mods;
uint8_t weak_mods;
# ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods;
# endif
# endif
# ifndef DISABLE_SYNC_TIMER
uint32_t sync_timer;
# endif
# ifdef SPLIT_TRANSPORT_MIRROR
matrix_row_t mmatrix[ROWS_PER_HAND];
# endif
# ifdef BACKLIGHT_ENABLE
uint8_t backlight_level;
# endif
# ifdef WPM_ENABLE
uint8_t current_wpm;
# endif
uint16_t device_cpi;
bool oled_on;
layer_state_t t_layer_state;
layer_state_t t_default_layer_state;
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
led_eeconfig_t led_matrix;
bool led_suspend_state;
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
rgb_config_t rgb_matrix;
bool rgb_suspend_state;
# endif
} __attribute__((packed)) Serial_m2s_buffer_t;
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// When MCUs on both sides drive their respective RGB LED chains,
// it is necessary to synchronize, so it is necessary to communicate RGB
// information. In that case, define RGBLIGHT_SPLIT with info on the number
// of LEDs on each half.
//
// Otherwise, if the master side MCU drives both sides RGB LED chains,
// there is no need to communicate.
typedef struct _Serial_rgblight_t {
rgblight_syncinfo_t rgblight_sync;
} Serial_rgblight_t;
volatile Serial_rgblight_t serial_rgblight = {};
uint8_t volatile status_rgblight = 0;
# endif
volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
uint8_t volatile status0 = 0;
enum serial_transaction_id {
GET_SLAVE_MATRIX = 0,
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
PUT_RGBLIGHT,
# endif
};
SSTD_t transactions[] = {
[GET_SLAVE_MATRIX] =
{
(uint8_t *)&status0,
sizeof(serial_m2s_buffer),
(uint8_t *)&serial_m2s_buffer,
sizeof(serial_s2m_buffer),
(uint8_t *)&serial_s2m_buffer,
},
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
[PUT_RGBLIGHT] =
{
(uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer
},
# endif
};
void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// rgblight synchronization information communication.
void transport_rgblight_master(void) {
if (rgblight_get_change_flags()) {
rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
rgblight_clear_change_flags();
}
}
}
void transport_rgblight_slave(void) {
if (status_rgblight == TRANSACTION_ACCEPTED) {
rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false);
status_rgblight = TRANSACTION_END;
}
}
# else
# define transport_rgblight_master()
# define transport_rgblight_slave()
# endif
bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
# ifndef SERIAL_USE_MULTI_TRANSACTION
if (soft_serial_transaction() != TRANSACTION_END) {
return false;
}
# else
transport_rgblight_master();
if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
return false;
}
# endif
// TODO: if MATRIX_COLS > 8 change to unpack()
for (int i = 0; i < ROWS_PER_HAND; ++i) {
slave_matrix[i] = serial_s2m_buffer.smatrix[i];
# ifdef SPLIT_TRANSPORT_MIRROR
serial_m2s_buffer.mmatrix[i] = master_matrix[i];
# endif
}
# ifdef BACKLIGHT_ENABLE
// Write backlight level for slave to read
serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
# endif
# ifdef ENCODER_ENABLE
encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
# endif
# ifdef WPM_ENABLE
// Write wpm to slave
serial_m2s_buffer.current_wpm = get_current_wpm();
# endif
# ifdef SPLIT_MODS_ENABLE
serial_m2s_buffer.real_mods = get_mods();
serial_m2s_buffer.weak_mods = get_weak_mods();
# ifndef NO_ACTION_ONESHOT
serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
# endif
# endif
# ifdef POINTING_DEVICE_ENABLE
if (is_keyboard_left()) {
report_mouse_t temp_report = pointing_device_get_report();
temp_report.x = serial_s2m_buffer.mouse_x;
temp_report.y = serial_s2m_buffer.mouse_y;
pointing_device_set_report(temp_report);
serial_m2s_buffer.device_cpi = device_cpi;
}
# endif
serial_m2s_buffer.t_layer_state = layer_state;
serial_m2s_buffer.t_default_layer_state = default_layer_state;
# ifdef OLED_DRIVER_ENABLE
serial_m2s_buffer.oled_on = is_oled_on();
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
serial_m2s_buffer.led_matrix = led_matrix_eeconfig;
serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state();
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
serial_m2s_buffer.rgb_matrix = rgb_matrix_config;
serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state();
# endif
# ifndef DISABLE_SYNC_TIMER
serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
# endif
return true;
}
void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
transport_rgblight_slave();
# ifndef DISABLE_SYNC_TIMER
sync_timer_update(serial_m2s_buffer.sync_timer);
# endif
// TODO: if MATRIX_COLS > 8 change to pack()
for (int i = 0; i < ROWS_PER_HAND; ++i) {
serial_s2m_buffer.smatrix[i] = slave_matrix[i];
# ifdef SPLIT_TRANSPORT_MIRROR
master_matrix[i] = serial_m2s_buffer.mmatrix[i];
# endif
}
# ifdef BACKLIGHT_ENABLE
backlight_set(serial_m2s_buffer.backlight_level);
# endif
# ifdef ENCODER_ENABLE
encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
# endif
# ifdef WPM_ENABLE
set_current_wpm(serial_m2s_buffer.current_wpm);
# endif
# ifdef SPLIT_MODS_ENABLE
set_mods(serial_m2s_buffer.real_mods);
set_weak_mods(serial_m2s_buffer.weak_mods);
# ifndef NO_ACTION_ONESHOT
set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
# endif
# endif
# ifdef POINTING_DEVICE_ENABLE
if (!is_keyboard_left()) {
static uint16_t cpi;
if (cpi != serial_m2s_buffer.device_cpi) {
cpi = serial_m2s_buffer.device_cpi;
pmw_set_cpi(cpi);
}
serial_s2m_buffer.mouse_x = split_mouse_x;
serial_s2m_buffer.mouse_y = split_mouse_y;
}
# endif
if (layer_state != serial_m2s_buffer.t_layer_state) {
layer_state = serial_m2s_buffer.t_layer_state;
}
if (default_layer_state != serial_m2s_buffer.t_default_layer_state) {
default_layer_state = serial_m2s_buffer.t_default_layer_state;
}
# ifdef OLED_DRIVER_ENABLE
if (serial_m2s_buffer.oled_on) {
oled_on();
} else {
oled_off();
}
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
led_matrix_eeconfig = serial_m2s_buffer.led_matrix;
led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state);
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
rgb_matrix_config = serial_m2s_buffer.rgb_matrix;
rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state);
# endif
}
#endif
#ifdef POINTING_DEVICE_ENABLE
void master_mouse_send(int8_t x, int8_t y) {
split_mouse_x = x;
split_mouse_y = y;
}
void trackball_set_cpi(uint16_t cpi) {
if (!is_keyboard_left()) {
pmw_set_cpi(cpi);
} else {
device_cpi = cpi;
}
}
#endif

View file

@ -16,8 +16,6 @@
#include "6x6.h"
#elif KEYBOARD_handwired_dactyl_manuform_dmote_62key
#include "62key.h"
#elif KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball
# include "5x6_right_trackball.h"
#endif
#include "quantum.h"

View file

@ -0,0 +1,67 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "4x6_right.h"
#ifdef RGB_MATRIX_ENABLE
led_config_t g_led_config = { {
{ 24, 23, 18, 17, 10, 9 },
{ 25, 22, 19, 16, 11, 8 },
{ 26, 21, 20, 15, 12, 7 },
{ NO_LED, NO_LED, NO_LED, 14, 13, 6 },
{ NO_LED, NO_LED, NO_LED, 14, 13, 6 },
{ 51, 50, 45, 44, 37, 36 },
{ 52, 49, 46, 43, 38, 35 },
{ 53, 48, 47, 42, 39, 34 },
{ NO_LED, NO_LED, NO_LED, 41, 40, 33 },
{ NO_LED, NO_LED, NO_LED, 41, 40, 33 }
}, {
{ 85, 16 }, { 50, 13 }, { 16, 20 }, { 16, 38 }, { 50, 48 }, { 85, 52 }, { 95, 63 },
{ 85, 39 }, { 85, 21 }, { 85, 4 }, { 68, 2 }, { 68, 19 }, { 68, 37 }, { 80, 58 },
{ 60, 55 }, { 50, 35 }, { 50, 13 }, { 50, 0 }, { 33, 3 }, { 33, 20 }, { 33, 37 },
{ 16, 42 }, { 16, 24 }, { 16, 7 }, { 0, 7 }, { 0, 24 }, { 0, 41 }, { 139, 16 },
{ 174, 13 }, { 208, 20 }, { 208, 38 }, { 174, 48 }, { 139, 52 }, { 129, 63 }, { 139, 39 },
{ 139, 21 }, { 139, 4 }, { 156, 2 }, { 156, 19 }, { 156, 37 }, { 144, 58 }, { 164, 55 },
{ 174, 35 }, { 174, 13 }, { 174, 0 }, { 191, 3 }, { 191, 20 }, { 191, 37 }, { 208, 42 },
{ 208, 24 }, { 208, 7 }, { 224, 7 }, { 224, 24 }, { 224, 41 }
}, {
2, 2, 2, 2, 2, 2, 1,
4, 4, 4, 4, 4, 4, 1,
1, 4, 4, 4, 4, 4, 4,
4, 4, 4, 1, 1, 1, 2,
2, 2, 2, 2, 2, 1, 4,
4, 4, 4, 4, 4, 1, 1,
4, 4, 4, 4, 4, 4, 4,
4, 4, 1, 1, 1
} };
#endif
#ifdef SWAP_HANDS_ENABLE
const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
/* Left hand, matrix positions */
{{5, 5}, {4, 5}, {3, 5}, {2, 5}, {1, 5}, {0, 5}},
{{5, 6}, {4, 6}, {3, 6}, {2, 6}, {1, 6}, {0, 6}},
{{5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7}, {0, 7}},
{{5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8}},
{{5, 9}, {4, 9}, {3, 9}, {2, 9}, {1, 9}, {0, 9}},
/* Right hand, matrix positions */
{{5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}},
{{5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}},
{{5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}},
{{5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}},
{{5, 4}, {4, 4}, {3, 4}, {2, 4}, {1, 4}, {0, 4}}
};
#endif

View file

@ -0,0 +1,47 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "tractyl_manuform.h"
#include "quantum.h"
#define ___ KC_NO
// clang-format off
#define LAYOUT_4x6_right(\
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
L32, L33, R32, R33, \
L34, L35, R31, \
L44, L45, R41, \
L42, L43, R42, R43 \
) \
{ \
{ L00, L01, L02, L03, L04, L05 }, \
{ L10, L11, L12, L13, L14, L15 }, \
{ L20, L21, L22, L23, L24, L25 }, \
{ ___, ___, L32, L33, L34, L35 }, \
{ ___, ___, L42, L43, L44, L45 }, \
\
{ R00, R01, R02, R03, R04, R05 }, \
{ R10, R11, R12, R13, R14, R15 }, \
{ R20, R21, R22, R23, R24, R25 }, \
{ ___, R31, R32, R33, ___, ___ }, \
{ ___, R41, R42, R43, ___, ___ } \
}
// clang-format on

View file

@ -0,0 +1,91 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2015 Jack Humbert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "config_common.h"
#define PRODUCT_ID 0x3537
#define DEVICE_VER 0x0001
#define PRODUCT Tractyl Manuform(4x6)
/* key matrix size */
// Rows are doubled-up
#define MATRIX_ROWS 10
#define MATRIX_COLS 6
// wiring of each half
#define MATRIX_COL_PINS { C0, C1, C2, C3, C4, C5 }
#define MATRIX_ROW_PINS { A0, A1, A2, A3, A4 }
#define DIODE_DIRECTION COL2ROW
// WS2812 RGB LED strip input and number of LEDs
#define RGB_DI_PIN E7
#define DRIVER_LED_TOTAL 62
#define RGB_MATRIX_SPLIT { 32, 30 }
#define RGB_DISABLE_WHEN_USB_SUSPENDED true
#define RGB_MATRIX_KEYPRESSES
// #define RGB_MATRIX_KEYRELEASES
#define RGB_MATRIX_FRAMEBUFFER_EFFECTS
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 80
#define SPLIT_TRANSPORT_MIRROR
#define SPLIT_HAND_PIN A6
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
// #define BACKLIGHT_LEVELS 3
// #define DEBUG_LED_PIN D6
#define ROTATIONAL_TRANSFORM_ANGLE -25
/* Bootmagic Lite key configuration */
#define BOOTMAGIC_LITE_ROW 0
#define BOOTMAGIC_LITE_COLUMN 0
#define BOOTMAGIC_LITE_ROW_RIGHT 4
#define BOOTMAGIC_LITE_COLUMN_RIGHT 5
#define AUDIO_PIN C6
#define AUDIO_PIN_ALT B7
#define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 4095
#define DYNAMIC_KEYMAP_LAYER_COUNT 16
#define LAYER_STATE_16BIT
/* serial.c configuration for split keyboard */
#define SOFT_SERIAL_PIN D3
#define EE_HANDS
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
#define SERIAL_USE_MULTI_TRANSACTION
#define SPLIT_TRANSACTION_IDS_KB RPC_ID_STATE_SYNC, RPC_ID_SLAVE_STATE

View file

@ -1,11 +1,11 @@
{
"keyboard_name": "Dactyl Manuform 5x6",
"keyboard_name": "Tractyl Manuform 4x6",
"url": "",
"maintainer": "qmk",
"maintainer": "drashna",
"width": 17,
"height": 8,
"layouts": {
"LAYOUT_5x6_right_trackball": {
"LAYOUT_5x6_right": {
"layout": [
{"label":"L00", "x":0, "y":0},
{"label":"L01", "x":1, "y":0},

View file

@ -0,0 +1,62 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
enum custom_layers {
_QWERTY,
_LOWER,
_RAISE,
};
#define RAISE MO(_RAISE)
#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
#define LOWER MO(_LOWER)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT_4x6_right(
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS,
KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH,KC_BSLASH,
KC_LBRC,KC_RBRC, KC_PLUS, KC_EQL,
RAISE, KC_SPC, LOWER,
KC_TAB, KC_HOME, KC_ENT,
KC_BSPC,KC_GRV, KC_LGUI,KC_DEL
),
[_LOWER] = LAYOUT_4x6_right(
_______,_______,_______,_______,_______,KC_LBRC, KC_RBRC, KC_P7, KC_P8, KC_P9, RESET, KC_PLUS,
_______,KC_HOME,KC_PGUP,KC_PGDN,KC_END ,KC_LPRN, KC_RPRN, KC_P4, KC_P5, KC_P6, KC_MINS,KC_PIPE,
_______,_______,_______,_______,_______,_______, _______, KC_P1, KC_P2, KC_P3, KC_EQL, KC_UNDS,
_______,KC_PSCR, _______, KC_P0,
_______,_______, _______,
_______,_______, _______,
_______,_______, _______,_______
),
[_RAISE] = LAYOUT_4x6_right(
_______,RESET, _______,_______,_______,KC_LBRC, KC_RBRC,_______,KC_NLCK,KC_INS, KC_SLCK,KC_MUTE,
_______,KC_LEFT,KC_UP ,KC_DOWN,KC_RGHT,KC_LPRN, KC_RPRN,KC_MPRV,KC_MPLY,KC_MNXT,_______,KC_VOLU,
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,KC_VOLD,
_______,_______, KC_EQL ,_______,
_______,_______, _______,
_______,_______, _______,
_______,_______, _______,_______
),
};

View file

@ -17,13 +17,12 @@
#pragma once
// #define USE_I2C
#define SELECT_SOFT_SERIAL_SPEED 0
// #define SELECT_SOFT_SERIAL_SPEED 1
// #define SERIAL_USE_MULTI_TRANSACTION
#define SPLIT_MODS_ENABLE
#define EE_HANDS
#define TRACKBALL_DPI_OPTIONS \
{ 1200, 1800, 2600, 3400 }
#define TRACKBALL_DPI_OPTIONS { 1200, 1800, 2600, 3400 }
#define RGBLIGHT_MAX_BRIGHTNESS 60
@ -35,5 +34,3 @@
#define OLED_DISPLAY_128X64
#define OLED_BRIGHTNESS 50
#define MK_KINETIC_SPEED

View file

@ -0,0 +1,243 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "drashna.h"
// clang-format off
#define LAYOUT_4x6_right_wrapper(...) LAYOUT_4x6_right(__VA_ARGS__)
#define LAYOUT_4x6_right_base( \
K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \
K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A \
) \
LAYOUT_4x6_right_wrapper( \
SH_TT, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, SH_TT, \
LALT_T(KC_TAB), K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, RALT_T(K1B), \
OS_LSFT, CTL_T(K21), K22, K23, K24, K25, K26, K27, K28, K29, RCTL_T(K2A), OS_RSFT, \
OS_LGUI, OS_LALT, OS_RGUI, OS_RALT, \
KC_PSCR, KC_GRV, MEH_T(KC_BTN3), \
KC_SPC, OS_LGUI, KC_ENT, \
BK_LWER, TT(_MOUSE), TT(_MOUSE), DL_RAIS \
)
#define LAYOUT_4x6_right_base_wrapper(...) LAYOUT_4x6_right_base(__VA_ARGS__)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT_4x6_right_base_wrapper(
_________________QWERTY_L1_________________, _________________QWERTY_R1_________________,
_________________QWERTY_L2_________________, _________________QWERTY_R2_________________,
_________________QWERTY_L3_________________, _________________QWERTY_R3_________________
),
[_COLEMAK] = LAYOUT_4x6_right_base_wrapper(
_________________COLEMAK_L1________________, _________________COLEMAK_R1________________,
_________________COLEMAK_L2________________, _________________COLEMAK_R2________________,
_________________COLEMAK_L3________________, _________________COLEMAK_R3________________
),
[_DVORAK] = LAYOUT_4x6_right_base_wrapper(
_________________DVORAK_L1_________________, _________________DVORAK_R1_________________,
_________________DVORAK_L2_________________, _________________DVORAK_R2_________________,
_________________DVORAK_L3_________________, _________________DVORAK_R3_________________
),
[_WORKMAN] = LAYOUT_4x6_right_base_wrapper(
_________________WORKMAN_L1________________, _________________WORKMAN_R1________________,
_________________WORKMAN_L2________________, _________________WORKMAN_R2________________,
_________________WORKMAN_L3________________, _________________WORKMAN_R3________________
),
[_NORMAN] = LAYOUT_4x6_right_base_wrapper(
_________________NORMAN_L1_________________, _________________NORMAN_L1_________________,
_________________NORMAN_L2_________________, _________________NORMAN_R2_________________,
_________________NORMAN_L3_________________, _________________NORMAN_R3_________________
),
[_MALTRON] = LAYOUT_4x6_right_base_wrapper(
_________________MALTRON_L1________________, _________________MALTRON_R1________________,
_________________MALTRON_L2________________, _________________MALTRON_R2________________,
_________________MALTRON_L3________________, _________________MALTRON_R3________________
),
[_EUCALYN] = LAYOUT_4x6_right_base_wrapper(
_________________EUCALYN_L1________________, _________________EUCALYN_R1________________,
_________________EUCALYN_L2________________, _________________EUCALYN_R2________________,
_________________EUCALYN_L3________________, _________________EUCALYN_R3________________
),
[_CARPLAX] = LAYOUT_4x6_right_base_wrapper(
_____________CARPLAX_QFMLWY_L1_____________, _____________CARPLAX_QFMLWY_R1_____________,
_____________CARPLAX_QFMLWY_L2_____________, _____________CARPLAX_QFMLWY_R2_____________,
_____________CARPLAX_QFMLWY_L3_____________, _____________CARPLAX_QFMLWY_R3_____________
),
[_MOUSE] = LAYOUT_4x6_right(
_______, _______, _______, _______, _______, _______, KC_WH_U, _______, _______, _______, DPI_CONFIG, _______,
_______, _______, _______, _______, _______, _______, KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, KC_BTN6, _______,
_______, _______, _______, _______, _______, _______, KC_BTN7, KC_BTN4, KC_BTN5, KC_BTN8, _______, _______,
_______, _______, _______, _______,
_______, _______, _______,
_______, _______, _______,
_______, _______, _______, _______
),
[_GAMEPAD] = LAYOUT_4x6_right(
KC_F1, KC_K, KC_Q, KC_W, KC_E, KC_R, _______, _______, _______, _______, _______, _______,
KC_TAB, KC_G, KC_A, KC_S, KC_D, KC_F, _______, _______, _______, _______, _______, _______,
KC_LCTL, KC_LSFT, KC_Z, KC_X, KC_C, KC_H, _______, _______, _______, _______, _______, _______,
KC_I, KC_T, TG_GAME, KC_NO,
KC_V, KC_O, _______,
KC_SPC, KC_P, _______,
KC_H, KC_LGUI, _______, _______
),
[_DIABLO] = LAYOUT_4x6_right(
KC_TAB, KC_S, KC_I, KC_F, KC_M, KC_T, _______, _______, _______, _______, _______, _______,
KC_Q, KC_1, KC_2, KC_3, KC_4, KC_G, _______, _______, _______, _______, _______, _______,
KC_LCTL, KC_D3_1, KC_D3_2, KC_D3_3, KC_D3_4, KC_Z, _______, _______, _______, _______, _______, _______,
KC_F, KC_L, KC_NO, TG_DBLO,
KC_DIABLO_CLEAR, KC_F, _______,
SFT_T(KC_SPC), KC_J, _______,
ALT_T(KC_Q), KC_LGUI, _______, _______
),
[_LOWER] = LAYOUT_4x6_right_wrapper(
KC_F12, _________________LOWER_L1__________________, _________________LOWER_R1__________________, KC_F11,
_______, _________________LOWER_L2__________________, _________________LOWER_R2__________________, KC_PIPE,
_______, _________________LOWER_L3__________________, _________________LOWER_R3__________________, _______,
_______, _______, _______, _______,
_______, _______, _______,
_______, _______, _______,
_______, _______, _______, _______
),
[_RAISE] = LAYOUT_4x6_right_wrapper(
KC_F12, _________________RAISE_L1__________________, _________________RAISE_R1__________________, KC_F11,
_______, _________________RAISE_L2__________________, _________________RAISE_R2__________________, KC_BSLS,
_______, _________________RAISE_L3__________________, _________________RAISE_R3__________________, _______,
_______, _______, _______, _______,
_______, _______, _______,
_______, _______, _______,
_______, _______, _______, _______
),
[_ADJUST] = LAYOUT_4x6_right_wrapper(
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RST,
VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST,
UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS,
HPT_DWLI, HPT_DWLD, TG_GAME, TG_DBLO,
HPT_TOG, HPT_BUZ, KC_NUKE,
_______, _______, _______,
_______, _______, KC_NUKE, _______
),
};
// clang-format on
#ifdef POINTING_DEVICE_ENABLE
static uint16_t mouse_timer = 0;
static uint16_t mouse_debounce_timer = 0;
static uint8_t mouse_keycode_tracker = 0;
bool tap_toggling = false;
void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y) {
if ((x || y) && timer_elapsed(mouse_timer) > 125) {
mouse_timer = timer_read();
if (!layer_state_is(_MOUSE) && !(layer_state_is(_GAMEPAD) || layer_state_is(_DIABLO)) && timer_elapsed(mouse_debounce_timer) > 125) {
layer_on(_MOUSE);
}
}
# ifdef TAPPING_TERM_PER_KEY
if (timer_elapsed(mouse_debounce_timer) > get_tapping_term(KC_BTN1, NULL)
# else
if (timer_elapsed(mouse_debounce_timer) > TAPPING_TERM
# endif
|| (layer_state_is(_GAMEPAD) || layer_state_is(_DIABLO))) {
mouse_report->x = x;
mouse_report->y = y;
}
# ifdef OLED_DRIVER_ENABLE
if (x || y) oled_timer = timer_read32();
# endif
}
void matrix_scan_keymap(void) {
if (timer_elapsed(mouse_timer) > 650 && layer_state_is(_MOUSE) && !mouse_keycode_tracker && !tap_toggling) {
layer_off(_MOUSE);
}
if (tap_toggling) {
if (!layer_state_is(_MOUSE)) {
layer_on(_MOUSE);
}
}
}
bool process_record_keymap(uint16_t keycode, keyrecord_t* record) {
switch (keycode) {
case TT(_MOUSE): {
if (record->event.pressed) {
mouse_keycode_tracker++;
} else {
# if TAPPING_TOGGLE != 0
if (record->tap.count == TAPPING_TOGGLE) {
tap_toggling ^= 1;
# if TAPPING_TOGGLE == 1
if (!tap_toggling) mouse_keycode_tracker -= record->tap.count + 1;
# else
if (!tap_toggling) mouse_keycode_tracker -= record->tap.count;
# endif
} else {
mouse_keycode_tracker--;
}
# endif
}
mouse_timer = timer_read();
break;
}
case MO(_MOUSE):
case DPI_CONFIG:
case KC_MS_UP ... KC_MS_WH_RIGHT:
record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--;
mouse_timer = timer_read();
break;
default:
if (layer_state_is(_MOUSE) && !mouse_keycode_tracker) {
layer_off(_MOUSE);
}
mouse_keycode_tracker = 0;
mouse_debounce_timer = timer_read();
break;
}
return true;
}
layer_state_t layer_state_set_keymap(layer_state_t state) {
if (layer_state_cmp(state, _GAMEPAD) || layer_state_cmp(state, _DIABLO)) {
state |= (1UL << _MOUSE);
}
return state;
}
#endif
void matrix_init_keymap(void) {
#ifdef AUDIO_ENABLE
extern audio_config_t audio_config;
if (!is_keyboard_master()) {
audio_stop_all();
audio_config.enable = false;
}
#endif
}
void keyboard_post_init_keymap(void) {
matrix_init_keymap();
}

View file

@ -1,6 +1,7 @@
RGBLIGHT_STARTUP_ANIMATION = yes
COMMAND_ENABLE = no
AUDIO_ENABLE = yes
HAPTIC_ENABLE = no
COMMAND_ENABLE = no
TAP_DANCE_ENABLE = yes
UNICODE_ENABLE = yes
OLED_DRIVER_ENABLE = yes

View file

@ -0,0 +1,33 @@
# MCU name
MCU = at90usb1286
# Bootloader selection
BOOTLOADER = atmel-dfu
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output
RGB_MATRIX_ENABLE = no
RGB_MATRIX_DRIVER = WS2812
POINTING_DEVICE_ENABLE = yes
MOUSE_SHARED_EP = no
SPLIT_KEYBOARD = yes
SRC += drivers/sensors/pmw3360.c
QUANTUM_LIB_SRC += spi_master.c tm_sync.c

View file

@ -0,0 +1,35 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "5x6_right.h"
#ifdef SWAP_HANDS_ENABLE
const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
/* Left hand, matrix positions */
{{5, 6}, {4, 6}, {3, 6}, {2, 6}, {1, 6}, {0, 6}},
{{5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7}, {0, 7}},
{{5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8}},
{{5, 9}, {4, 9}, {3, 9}, {2, 9}, {1, 9}, {0, 9}},
{{5, 10}, {4, 10}, {3, 10}, {2, 10}, {1, 10}, {0, 10}},
{{5, 11}, {4, 11}, {3, 11}, {2, 11}, {1, 11}, {0, 11}},
/* Right hand, matrix positions */
{{5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}},
{{5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}},
{{5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}},
{{5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}},
{{5, 4}, {4, 4}, {3, 4}, {2, 4}, {1, 4}, {0, 4}},
{{5, 5}, {4, 5}, {3, 5}, {2, 5}, {1, 5}, {0, 5}}};
#endif

View file

@ -16,16 +16,13 @@
#pragma once
#include "dactyl_manuform.h"
#include "tractyl_manuform.h"
#include "quantum.h"
#include "spi_master.h"
#include "drivers/sensors/pmw3360.h"
#include "pointing_device.h"
#define ___ KC_NO
#define LAYOUT_5x6_right_trackball(\
// clang-format off
#define LAYOUT_5x6_right(\
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
@ -50,24 +47,4 @@
{ ___, R41, R42, R43, ___, ___ }, \
{ ___, R51, R52, R53, ___, ___ } \
}
void process_wheel(report_mouse_t* mouse_report);
void process_wheel_user(report_mouse_t* mouse_report, int16_t h, int16_t v);
typedef union {
uint32_t raw;
struct {
uint8_t dpi_config;
};
} keyboard_config_t;
extern keyboard_config_t keyboard_config;
enum ploopy_keycodes {
DPI_CONFIG = SAFE_RANGE,
KEYMAP_SAFE_RANGE,
};
void master_mouse_send(int8_t x, int8_t y);
void trackball_set_cpi(uint16_t cpi);
// clang-format on

View file

@ -20,9 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
#define PRODUCT_ID 0x3536
#define DEVICE_VER 0x0001
#define PRODUCT Tractyl-Manuform (5x6 with right side Trackball)
#define PRODUCT_ID 0x3536
#define DEVICE_VER 0x0001
#define PRODUCT Tractyl Manuform(5x6)
/* key matrix size */
// Rows are doubled-up
@ -36,37 +36,53 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DIODE_DIRECTION COL2ROW
// WS2812 RGB LED strip input and number of LEDs
#define RGB_DI_PIN E7
#define RGBLED_NUM 58
#define RGB_DI_PIN E7
#define RGBLED_NUM 58
#define RGBLIGHT_SPLIT
#define RGBLED_SPLIT { 30 , 28 }
#define RGBLED_SPLIT { 30, 28 }
#define RGBLIGHT_SLEEP
// #define RGBW
#define RGBLIGHT_LIMIT_VAL 100
#define RGBLIGHT_LIMIT_VAL 50
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
// #define BACKLIGHT_LEVELS 3
#define DEBUG_LED_PIN D6
#define DEBUG_LED_PIN D6
#define USB_POLLING_INTERVAL_MS 1
#define ROTATIONAL_TRANSFORM_ANGLE -25
#define ROTATIONAL_TRANSFORM_ANGLE -25
/* Bootmagic Lite key configuration */
#define BOOTMAGIC_LITE_ROW 0
#define BOOTMAGIC_LITE_COLUMN 0
#define BOOTMAGIC_LITE_ROW_RIGHT 6
#define BOOTMAGIC_LITE_COLUMN_RIGHT 5
#define BOOTMAGIC_LITE_ROW 0
#define BOOTMAGIC_LITE_COLUMN 0
#define BOOTMAGIC_LITE_ROW_RIGHT 6
#define BOOTMAGIC_LITE_COLUMN_RIGHT 5
#define AUDIO_PIN C6
#define AUDIO_PIN_ALT B7
#define AUDIO_PIN C6
#define AUDIO_PIN_ALT B7
#define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 4095
#define DYNAMIC_KEYMAP_LAYER_COUNT 16
#define DYNAMIC_KEYMAP_LAYER_COUNT 16
#define LAYER_STATE_16BIT
/* serial.c configuration for split keyboard */
#undef SOFT_SERIAL_PIN
#define SOFT_SERIAL_PIN D2
#define EE_HANDS
#define ENCODERS_PAD_A { D5 }
#define ENCODERS_PAD_B { D6 }
#define ENCODER_RESOLUTION 1
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
#define SERIAL_USE_MULTI_TRANSACTION
#define SPLIT_TRANSACTION_IDS_KB RPC_ID_STATE_SYNC, RPC_ID_SLAVE_STATE

View file

@ -0,0 +1,75 @@
{
"keyboard_name": "Tractyl Manuform 5x6",
"url": "",
"maintainer": "drashna",
"width": 17,
"height": 8,
"layouts": {
"LAYOUT_5x6_right": {
"layout": [
{"label":"L00", "x":0, "y":0},
{"label":"L01", "x":1, "y":0},
{"label":"L02", "x":2, "y":0},
{"label":"L03", "x":3, "y":0},
{"label":"L04", "x":4, "y":0},
{"label":"L05", "x":5, "y":0},
{"label":"R00", "x":11, "y":0},
{"label":"R01", "x":12, "y":0},
{"label":"R02", "x":13, "y":0},
{"label":"R03", "x":14, "y":0},
{"label":"R04", "x":15, "y":0},
{"label":"R05", "x":16, "y":0},
{"label":"L10", "x":0, "y":1},
{"label":"L11", "x":1, "y":1},
{"label":"L12", "x":2, "y":1},
{"label":"L13", "x":3, "y":1},
{"label":"L14", "x":4, "y":1},
{"label":"L15", "x":5, "y":1},
{"label":"R10", "x":11, "y":1},
{"label":"R11", "x":12, "y":1},
{"label":"R12", "x":13, "y":1},
{"label":"R13", "x":14, "y":1},
{"label":"R14", "x":15, "y":1},
{"label":"R15", "x":16, "y":1},
{"label":"L20", "x":0, "y":2},
{"label":"L21", "x":1, "y":2},
{"label":"L22", "x":2, "y":2},
{"label":"L23", "x":3, "y":2},
{"label":"L24", "x":4, "y":2},
{"label":"L25", "x":5, "y":2},
{"label":"R20", "x":11, "y":2},
{"label":"R21", "x":12, "y":2},
{"label":"R22", "x":13, "y":2},
{"label":"R23", "x":14, "y":2},
{"label":"R24", "x":15, "y":2},
{"label":"R25", "x":16, "y":2},
{"label":"L30", "x":0, "y":3},
{"label":"L31", "x":1, "y":3},
{"label":"L32", "x":2, "y":3},
{"label":"L33", "x":3, "y":3},
{"label":"L34", "x":4, "y":3},
{"label":"L35", "x":5, "y":3},
{"label":"R30", "x":11, "y":3},
{"label":"R31", "x":12, "y":3},
{"label":"R32", "x":13, "y":3},
{"label":"R33", "x":14, "y":3},
{"label":"R34", "x":15, "y":3},
{"label":"R35", "x":16, "y":3},
{"label":"L42", "x":2, "y":4},
{"label":"L43", "x":3, "y":4},
{"label":"R42", "x":13, "y":4},
{"label":"R43", "x":14, "y":4},
{"label":"L44", "x":4, "y":5},
{"label":"L45", "x":5, "y":5},
{"label":"R41", "x":12, "y":5},
{"label":"L54", "x":6, "y":6},
{"label":"L55", "x":7, "y":6},
{"label":"R51", "x":10, "y":6},
{"label":"L52", "x":6, "y":7},
{"label":"L53", "x":7, "y":7},
{"label":"R52", "x":9, "y":7},
{"label":"R53", "x":10, "y":7}
]
}
}
}

View file

@ -0,0 +1,63 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
enum custom_layers {
_QWERTY,
_LOWER,
_RAISE,
};
#define RAISE MO(_RAISE)
#define LOWER MO(_LOWER)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT_5x6_right(
KC_ESC , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 ,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_MINS,
KC_LSFT, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L ,KC_SCLN,KC_QUOT,
KC_LCTL, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M ,KC_COMM,KC_DOT ,KC_SLSH,KC_BSLASH,
KC_LBRC,KC_RBRC, KC_PLUS, KC_EQL,
RAISE,KC_SPC, LOWER,
KC_TAB,KC_HOME, KC_DEL,
KC_BSPC, KC_GRV, KC_LGUI, KC_ENT
),
[_LOWER] = LAYOUT_5x6_right(
KC_TILD,KC_EXLM, KC_AT ,KC_HASH,KC_DLR ,KC_PERC, KC_CIRC,KC_AMPR,KC_ASTR,KC_LPRN,KC_RPRN,KC_DEL,
_______,_______,_______,_______,_______,KC_LBRC, KC_RBRC, KC_P7 , KC_P8 , KC_P9 ,_______,KC_PLUS,
_______,KC_HOME,KC_PGUP,KC_PGDN,KC_END ,KC_LPRN, KC_RPRN, KC_P4 , KC_P5 , KC_P6 ,KC_MINS,KC_PIPE,
_______,_______,_______,_______,_______,_______, _______, KC_P1 , KC_P2 , KC_P3 ,KC_EQL ,KC_UNDS,
_______,KC_PSCR, _______, KC_P0,
_______,_______, _______,
_______,_______, _______,
_______,_______, _______,_______
),
[_RAISE] = LAYOUT_5x6_right(
KC_F12 , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 ,KC_F10 ,KC_F11 ,
_______,_______,_______,_______,_______,KC_LBRC, KC_RBRC,_______,KC_NLCK,KC_INS ,KC_SLCK,KC_MUTE,
_______,KC_LEFT,KC_UP ,KC_DOWN,KC_RGHT,KC_LPRN, KC_RPRN,KC_MPRV,KC_MPLY,KC_MNXT,_______,KC_VOLU,
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,KC_VOLD,
_______,_______, KC_EQL ,_______,
_______,_______, _______,
_______,_______, _______,
_______,_______, _______,_______
),
};

View file

@ -16,18 +16,21 @@
#pragma once
#ifndef MOUSEKEY_WHEEL_DELTA
# define MOUSEKEY_WHEEL_DELTA 1
#endif
#ifndef MOUSEKEY_WHEEL_DELAY
# define MOUSEKEY_WHEEL_DELAY 200
#endif
#ifndef MOUSEKEY_WHEEL_INTERVAL
# define MOUSEKEY_WHEEL_INTERVAL 50
#endif
#ifndef MOUSEKEY_WHEEL_MAX_SPEED
# define MOUSEKEY_WHEEL_MAX_SPEED 8
#endif
#ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
# define MOUSEKEY_WHEEL_TIME_TO_MAX 80
#endif
// #define USE_I2C
// #define SELECT_SOFT_SERIAL_SPEED 1
// #define SERIAL_USE_MULTI_TRANSACTION
#define SPLIT_MODS_ENABLE
#define EE_HANDS
#define TRACKBALL_DPI_OPTIONS { 1200, 1800, 2600, 3400 }
#define RGBLIGHT_MAX_BRIGHTNESS 60
#undef DEBOUNCE
#define DEBOUNCE 10
#define SOLENOID_PIN F1
#define SOLENOID_DEFAULT_DWELL 8
#define OLED_DISPLAY_128X64
#define OLED_BRIGHTNESS 50

View file

@ -17,75 +17,75 @@
#include "drashna.h"
// clang-format off
#define LAYOUT_5x6_right_trackball_wrapper(...) LAYOUT_5x6_right_trackball(__VA_ARGS__)
#define LAYOUT_5x6_right_trackball_base( \
#define LAYOUT_5x6_right_wrapper(...) LAYOUT_5x6_right(__VA_ARGS__)
#define LAYOUT_5x6_right_base( \
K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \
K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A \
) \
LAYOUT_5x6_right_trackball_wrapper( \
KC_ESC, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, KC_MINS, \
LAYOUT_5x6_right_wrapper( \
KC_ESC, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, UC_IRNY, \
SH_TT, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, SH_TT, \
LALT_T(KC_TAB), K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, RALT_T(K1B), \
OS_LSFT, CTL_T(K21), K22, K23, K24, K25, K26, K27, K28, K29, RCTL_T(K2A), OS_RSFT, \
OS_LALT, OS_LGUI, TG_GAME, TG_DBLO, \
OS_LGUI, KC_GRV, OS_RGUI, \
OS_LGUI, OS_LALT, OS_RGUI, OS_RALT, \
KC_PSCR, KC_GRV, MEH_T(KC_BTN3), \
KC_SPC, OS_LGUI, KC_ENT, \
BK_LWER, TT(_MOUSE), TT(_MOUSE), DL_RAIS \
)
#define LAYOUT_5x6_right_trackball_base_wrapper(...) LAYOUT_5x6_right_trackball_base(__VA_ARGS__)
#define LAYOUT_5x6_right_base_wrapper(...) LAYOUT_5x6_right_base(__VA_ARGS__)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT_5x6_right_trackball_base_wrapper(
[_QWERTY] = LAYOUT_5x6_right_base_wrapper(
_________________QWERTY_L1_________________, _________________QWERTY_R1_________________,
_________________QWERTY_L2_________________, _________________QWERTY_R2_________________,
_________________QWERTY_L3_________________, _________________QWERTY_R3_________________
),
[_COLEMAK] = LAYOUT_5x6_right_trackball_base_wrapper(
[_COLEMAK] = LAYOUT_5x6_right_base_wrapper(
_________________COLEMAK_L1________________, _________________COLEMAK_R1________________,
_________________COLEMAK_L2________________, _________________COLEMAK_R2________________,
_________________COLEMAK_L3________________, _________________COLEMAK_R3________________
),
[_DVORAK] = LAYOUT_5x6_right_trackball_base_wrapper(
[_DVORAK] = LAYOUT_5x6_right_base_wrapper(
_________________DVORAK_L1_________________, _________________DVORAK_R1_________________,
_________________DVORAK_L2_________________, _________________DVORAK_R2_________________,
_________________DVORAK_L3_________________, _________________DVORAK_R3_________________
),
[_WORKMAN] = LAYOUT_5x6_right_trackball_base_wrapper(
[_WORKMAN] = LAYOUT_5x6_right_base_wrapper(
_________________WORKMAN_L1________________, _________________WORKMAN_R1________________,
_________________WORKMAN_L2________________, _________________WORKMAN_R2________________,
_________________WORKMAN_L3________________, _________________WORKMAN_R3________________
),
[_NORMAN] = LAYOUT_5x6_right_trackball_base_wrapper(
[_NORMAN] = LAYOUT_5x6_right_base_wrapper(
_________________NORMAN_L1_________________, _________________NORMAN_L1_________________,
_________________NORMAN_L2_________________, _________________NORMAN_R2_________________,
_________________NORMAN_L3_________________, _________________NORMAN_R3_________________
),
[_MALTRON] = LAYOUT_5x6_right_trackball_base_wrapper(
[_MALTRON] = LAYOUT_5x6_right_base_wrapper(
_________________MALTRON_L1________________, _________________MALTRON_R1________________,
_________________MALTRON_L2________________, _________________MALTRON_R2________________,
_________________MALTRON_L3________________, _________________MALTRON_R3________________
),
[_EUCALYN] = LAYOUT_5x6_right_trackball_base_wrapper(
[_EUCALYN] = LAYOUT_5x6_right_base_wrapper(
_________________EUCALYN_L1________________, _________________EUCALYN_R1________________,
_________________EUCALYN_L2________________, _________________EUCALYN_R2________________,
_________________EUCALYN_L3________________, _________________EUCALYN_R3________________
),
[_CARPLAX] = LAYOUT_5x6_right_trackball_base_wrapper(
[_CARPLAX] = LAYOUT_5x6_right_base_wrapper(
_____________CARPLAX_QFMLWY_L1_____________, _____________CARPLAX_QFMLWY_R1_____________,
_____________CARPLAX_QFMLWY_L2_____________, _____________CARPLAX_QFMLWY_R2_____________,
_____________CARPLAX_QFMLWY_L3_____________, _____________CARPLAX_QFMLWY_R3_____________
),
[_MOUSE] = LAYOUT_5x6_right_trackball(
[_MOUSE] = LAYOUT_5x6_right(
_______, _______, _______, _______, _______, _______, DPI_CONFIG, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, KC_WH_U, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, KC_BTN6, _______,
@ -95,7 +95,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______,
_______, _______, _______, _______
),
[_GAMEPAD] = LAYOUT_5x6_right_trackball(
[_GAMEPAD] = LAYOUT_5x6_right(
KC_ESC, KC_NO, KC_1, KC_2, KC_3, KC_4, DPI_CONFIG, _______, _______, _______, _______, _______,
KC_F1, KC_K, KC_Q, KC_W, KC_E, KC_R, _______, _______, _______, _______, _______, _______,
KC_TAB, KC_G, KC_A, KC_S, KC_D, KC_F, _______, _______, _______, _______, _______, _______,
@ -105,7 +105,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_SPC, KC_P, _______,
KC_H, KC_LGUI, _______, _______
),
[_DIABLO] = LAYOUT_5x6_right_trackball(
[_DIABLO] = LAYOUT_5x6_right(
KC_ESC, KC_V, KC_D, KC_LALT, KC_NO, KC_NO, KC_F9, KC_F10, KC_F11, KC_F12, KC_NO, KC_NO,
KC_TAB, KC_S, KC_I, KC_F, KC_M, KC_T, _______, _______, _______, _______, _______, _______,
KC_Q, KC_1, KC_2, KC_3, KC_4, KC_G, _______, _______, _______, _______, _______, _______,
@ -115,7 +115,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
SFT_T(KC_SPC), KC_J, _______,
ALT_T(KC_Q), KC_LGUI, _______, _______
),
[_LOWER] = LAYOUT_5x6_right_trackball_wrapper(
[_LOWER] = LAYOUT_5x6_right_wrapper(
KC_F12, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, KC_F11,
_______, _________________LOWER_L1__________________, _________________LOWER_R1__________________, _______,
_______, _________________LOWER_L2__________________, _________________LOWER_R2__________________, KC_PIPE,
@ -125,7 +125,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______,
_______, _______, _______, _______
),
[_RAISE] = LAYOUT_5x6_right_trackball_wrapper(
[_RAISE] = LAYOUT_5x6_right_wrapper(
KC_F12, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, KC_F11,
KC_GRV, _________________RAISE_L1__________________, _________________RAISE_R1__________________, _______,
_______, _________________RAISE_L2__________________, _________________RAISE_R2__________________, KC_BSLS,
@ -135,12 +135,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______,
_______, _______, _______, _______
),
[_ADJUST] = LAYOUT_5x6_right_trackball_wrapper(
[_ADJUST] = LAYOUT_5x6_right_wrapper(
KC_MAKE, ___________________BLANK___________________, _________________ADJUST_R1_________________, KC_RST,
VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EEP_RST,
_______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS,
UC_MOD, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS,
_______, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, KC_MPLY,
HPT_DWLI, HPT_DWLD, _______, _______,
HPT_DWLI, HPT_DWLD, TG_GAME, TG_DBLO,
HPT_TOG, HPT_BUZ, KC_NUKE,
_______, _______, _______,
_______, _______, KC_NUKE, _______

View file

@ -0,0 +1,11 @@
RGBLIGHT_ENABLE = yes
RGBLIGHT_STARTUP_ANIMATION = yes
AUDIO_ENABLE = yes
HAPTIC_ENABLE = no
COMMAND_ENABLE = no
TAP_DANCE_ENABLE = yes
UNICODE_ENABLE = yes
OLED_DRIVER_ENABLE = yes
WPM_ENABLE = yes
ENCODER_ENABLE = yes
# DEBOUNCE_TYPE = sym_eager_pk

View file

@ -0,0 +1,21 @@
# Drashna's Dactyl Manuform (5x6) with a right side trackball
![](https://preview.redd.it/zwt91036m3y51.jpg?width=960&crop=smart&auto=webp&s=e030deb7d8285c95a1a30c69a7e7a71f750e87bb)
It's a Dactyl Manuform with an integrated thumb based trackball, using the pmw3360 optical sensor.
It's powered by 2x Teensy++ 2.0's, using Drashna's [Teensy VBUS Hack](https://docs.qmk.fm/#/feature_split_keyboard?id=hardware-considerations-and-mods) for better detection.
* Keyboard Maintainer: [Drashna Jael're](https://github.com/drashna)
* Hardware Supported: [Design files](https://gitlab.com/keyboards1/dm_r_track/-/tree/master/boolean), [Teensy++ 2.0 (2x)](https://www.pjrc.com/store/teensypp.html), [PMW3360 Optical Sensor](https://www.tindie.com/products/jkicklighter/pmw3360-motion-sensor/)
Make example for this keyboard (after setting up your build environment):
make handwired/dactyl_manuform/5x6_right_trackball:default
Flashing example for this keyboard:
make handwired/dactyl_manuform/5x6_right_trackball:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).

View file

@ -11,21 +11,21 @@ BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
COMMAND_ENABLE = no # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = yes # USB Nkey Rollover
NKRO_ENABLE = yes # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output
SWAP_HANDS_ENABLE = yes
POINTING_DEVICE_ENABLE = yes
MOUSE_SHARED_EP = no
SPLIT_KEYBOARD = yes
SPLIT_TRANSPORT = custom
SRC += drivers/sensors/pmw3360.c
QUANTUM_LIB_SRC += pointer_transport.c serial.c i2c_master.c i2c_slave.c spi_master.c
QUANTUM_LIB_SRC += spi_master.c tm_sync.c

View file

@ -0,0 +1,43 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2015 Jack Humbert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0x44DD
#define MANUFACTURER Drashna
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
#define USB_POLLING_INTERVAL_MS 1
/* disable debug print */
// #define NO_DEBUG
/* disable print */
// #define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION

View file

@ -0,0 +1,96 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2015 Jack Humbert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// mouse config
# ifndef MOUSEKEY_MOVE_DELTA
# ifndef MK_KINETIC_SPEED
# define MOUSEKEY_MOVE_DELTA 5
# else
# define MOUSEKEY_MOVE_DELTA 25
# endif
# endif
# ifndef MOUSEKEY_DELAY
# ifndef MK_KINETIC_SPEED
# define MOUSEKEY_DELAY 300
# else
# define MOUSEKEY_DELAY 8
# endif
# endif
# ifndef MOUSEKEY_INTERVAL
# ifndef MK_KINETIC_SPEED
# define MOUSEKEY_INTERVAL 50
# else
# define MOUSEKEY_INTERVAL 20
# endif
# endif
# ifndef MOUSEKEY_MAX_SPEED
# define MOUSEKEY_MAX_SPEED 7
# endif
# ifndef MOUSEKEY_TIME_TO_MAX
# define MOUSEKEY_TIME_TO_MAX 60
# endif
# ifndef MOUSEKEY_INITIAL_SPEED
# define MOUSEKEY_INITIAL_SPEED 100
# endif
# ifndef MOUSEKEY_BASE_SPEED
# define MOUSEKEY_BASE_SPEED 1000
# endif
# ifndef MOUSEKEY_DECELERATED_SPEED
# define MOUSEKEY_DECELERATED_SPEED 400
# endif
# ifndef MOUSEKEY_ACCELERATED_SPEED
# define MOUSEKEY_ACCELERATED_SPEED 3000
# endif
// mouse scroll config
# ifndef MOUSEKEY_WHEEL_DELAY
# define MOUSEKEY_WHEEL_DELAY 15
# endif
# ifndef MOUSEKEY_WHEEL_DELTA
# define MOUSEKEY_WHEEL_DELTA 1
# endif
# ifndef MOUSEKEY_WHEEL_INTERVAL
# define MOUSEKEY_WHEEL_INTERVAL 50
# endif
# ifndef MOUSEKEY_WHEEL_MAX_SPEED
# define MOUSEKEY_WHEEL_MAX_SPEED 8
# endif
# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
# define MOUSEKEY_WHEEL_TIME_TO_MAX 80
# endif
# ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS
# define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 8
# endif
# ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS
# define MOUSEKEY_WHEEL_BASE_MOVEMENTS 48
# endif
# ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS
# define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48
# endif
# ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
# define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
# endif
#ifndef DEBOUNCE
# define DEBOUNCE 5
#endif

View file

@ -0,0 +1,159 @@
Dactyl Manuform (4x5, 5x6, 5x7, 6x6)
======
the [Dactyl-Manuform](https://github.com/tshort/dactyl-keyboard) is a split curved keyboard based on the design of [adereth dactyl](https://github.com/adereth/dactyl-keyboard) and thumb cluster design of the [manuform](https://geekhack.org/index.php?topic=46015.0) keyboard, the hardware is similar to the let's split keyboard. all information needed for making one is in the first link.
![Imgur](https://i.imgur.com/7y0Vbyd.jpg)
## First Time Setup
Download or clone the `qmk_firmware` repo and navigate to its top level directory. Once your build environment is setup, you'll be able to generate the default .hex using:
Depending on your Layout chose one of the follwing commands:
```
$ make handwired/dactyl_manuform/YOUR_LAYOUT:YOUR_KEYMAP_NAME
```
example:
```
$ make handwired/dactyl_manuform/4x5:default
```
If everything worked correctly you will see a file:
```
dactyl_manuform_YOUR_LAYOUT_YOUR_KEYMAP_NAME.hex
```
For more information on customizing keymaps, take a look at the primary documentation for [Customizing Your Keymap](/docs/faq_keymap.md) in the main readme.md.
## Keymaps
### [Keymaps 4x5](/keyboards/handwired/dactyl_manuform/4x5/keymaps/)
#### Default
Simple QWERTY layout with 3 Layers.
#### Dvorak
### [Keymaps 5x6](/keyboards/handwired/dactyl_manuform/5x6/keymaps/)
#### Default
Just a copy of the Impstyle keymap. Feel free to adjust it.
#### Impstyle
A simple QWERTY keymap with 3 Layers. Both sides are connected via serial and the Left ist the master.
### [Keymaps 5x7 aka almost Ergodox](/keyboards/handwired/dactyl_manuform/5x7/keymaps/)
#### Default
Keymap of Loligagger from geekhack.
### [Keymaps 6x6](/keyboards/handwired/dactyl_manuform/6x6/keymaps/)
#### Default
Simple QWERTY layout with 3 Layers.
## Required Hardware
Apart from diodes and key switches for the keyboard matrix in each half, you
will need:
* 2 Arduino Pro Micros. You can find these on AliExpress for ≈3.50USD each.
* 2 TRRS sockets and 1 TRRS cable, or 2 TRS sockets and 1 TRS cable
Alternatively, you can use any sort of cable and socket that has at least 3
wires. If you want to use I2C to communicate between halves, you will need a
cable with at least 4 wires and 2x 4.7kΩ pull-up resistors
## Optional Hardware
A speaker can be hooked-up to either side to the `5` (`C6`) pin and `GND`, and turned on via `AUDIO_ENABLE`.
## Wiring
The 3 wires of the TRS/TRRS cable need to connect GND, VCC, and digital pin 3 (i.e.
PD0 on the ATmega32u4) between the two Pro Micros.
Next, wire your key matrix to any of the remaining 17 IO pins of the pro micro
and modify the `matrix.c` accordingly.
The wiring for serial:
![serial wiring](https://i.imgur.com/C3D1GAQ.png)
The wiring for i2c:
![i2c wiring](https://i.imgur.com/Hbzhc6E.png)
The pull-up resistors may be placed on either half. It is also possible
to use 4 resistors and have the pull-ups in both halves, but this is
unnecessary in simple use cases.
You can change your configuration between serial and i2c by modifying your `config.h` file.
## Notes on Software Configuration
the keymaps in here are for the 4x5 layout of the keyboard only.
## Flashing
To flash your firmware take a look at: [Flashing Instructions and Bootloader Information](https://docs.qmk.fm/#/flashing)
## Choosing which board to plug the USB cable into (choosing Master)
Because the two boards are identical, the firmware has logic to differentiate the left and right board.
It uses two strategies to figure things out: looking at the EEPROM (memory on the chip) or looking if the current board has the usb cable.
The EEPROM approach requires additional setup (flashing the eeprom) but allows you to swap the usb cable to either side.
The USB cable approach is easier to setup and if you just want the usb cable on the left board, you do not need to do anything extra.
### Setting the left hand as master
If you always plug the usb cable into the left board, nothing extra is needed as this is the default. Comment out `EE_HANDS` and comment out `I2C_MASTER_RIGHT` or `MASTER_RIGHT` if for some reason it was set.
### Setting the right hand as master
If you always plug the usb cable into the right board, add an extra flag to your `config.h`
```
#define MASTER_RIGHT
```
### Setting EE_hands to use either hands as master
If you define `EE_HANDS` in your `config.h`, you will need to set the
EEPROM for the left and right halves.
The EEPROM is used to store whether the
half is left handed or right handed. This makes it so that the same firmware
file will run on both hands instead of having to flash left and right handed
versions of the firmware to each half. To flash the EEPROM file for the left
half run:
```
make handwired/dactyl_promicro:default:dfu-split-left
make handwired/dactyl_promicro:default:dfu-split-right
```
After you have flashed the EEPROM, you then need to set `EE_HANDS` in your config.h, rebuild the hex files and reflash.
Note that you need to program both halves, but you have the option of using
different keymaps for each half. You could program the left half with a QWERTY
layout and the right half with a Colemak layout using bootmagic's default layout option.
Then if you connect the left half to a computer by USB the keyboard will use QWERTY and Colemak when the
right half is connected.
Notes on Using Pro Micro 3.3V
-----------------------------
Do update the `F_CPU` parameter in `rules.mk` to `8000000` which reflects
the frequency on the 3.3V board.
Also, if the slave board is producing weird characters in certain columns,
update the following line in `matrix.c` to the following:
```
// wait_us(30); // without this wait read unstable value.
wait_us(300); // without this wait read unstable value.
```

View file

@ -0,0 +1,132 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef SPLIT_TRANSACTION_IDS_KB
# include "tractyl_manuform.h"
# include "transactions.h"
# include <string.h>
# include "drivers/sensors/pmw3360.h"
kb_runtime_config_t kb_state;
kb_slave_data_t kb_slave;
void slave_state_sync(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
if (target2initiator_buffer_size == sizeof(kb_slave)) {
memcpy(target2initiator_buffer, &kb_slave, sizeof(kb_slave));
if (kb_slave.mouse_x > 127) {
kb_slave.mouse_x -= 127;
} else if (kb_slave.mouse_x < -127) {
kb_slave.mouse_x += 127;
} else {
kb_slave.mouse_x = 0;
}
if (kb_slave.mouse_y > 127) {
kb_slave.mouse_y -= 127;
} else if (kb_slave.mouse_y < -127) {
kb_slave.mouse_y += 127;
} else {
kb_slave.mouse_y = 0;
}
}
}
void pointer_state_sync(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
if (initiator2target_buffer_size == sizeof(kb_state)) {
memcpy(&kb_state, initiator2target_buffer, sizeof(kb_state));
}
}
void keyboard_post_init_kb(void) {
// Register keyboard state sync split transaction
transaction_register_rpc(RPC_ID_STATE_SYNC, pointer_state_sync);
transaction_register_rpc(RPC_ID_SLAVE_STATE, slave_state_sync);
keyboard_post_init_user();
}
void kb_state_update(void) {
# ifdef POINTING_DEVICE_ENABLE
if (is_keyboard_master() && !is_keyboard_left()) {
static uint16_t cpi = 0;
if (cpi != kb_state.device_cpi) {
cpi = kb_state.device_cpi;
pmw_set_cpi(cpi);
}
}
# endif
}
void kb_post_state_update(void) {
# ifdef POINTING_DEVICE_ENABLE
if (is_keyboard_master() && is_keyboard_left()) {
report_mouse_t temp_report = pointing_device_get_report();
temp_report.x = kb_slave.mouse_x;
temp_report.y = kb_slave.mouse_y;
pointing_device_set_report(temp_report);
}
# endif
}
void kb_state_sync(void) {
if (is_keyboard_master()) {
// Keep track of the last state, so that we can tell if we need to propagate to slave
static kb_runtime_config_t last_kb_state;
static uint32_t last_sync = 0;
static uint32_t mouse_sync = 0;
bool needs_sync = false;
// Check if the state values are different
if (memcmp(&kb_state, &last_kb_state, sizeof(kb_runtime_config_t))) {
needs_sync = true;
memcpy(&last_kb_state, &kb_state, sizeof(kb_runtime_config_t));
}
// Send to slave every 500ms regardless of state change
if (timer_elapsed32(last_sync) > 500) {
needs_sync = true;
}
// Perform the sync if requested
if (needs_sync) {
if (transaction_rpc_send(RPC_ID_STATE_SYNC, sizeof(kb_runtime_config_t), &kb_state)) {
last_sync = timer_read32();
}
}
if (is_keyboard_left()) {
if (timer_elapsed32(mouse_sync) >= 5) {
// always sync slave data, since it may contain device reports.
if (transaction_rpc_recv(RPC_ID_SLAVE_STATE, sizeof(kb_slave_data_t), &kb_slave)) {
if (kb_slave.mouse_x >= -127 && kb_slave.mouse_x <= 127 && kb_slave.mouse_y >= -127 && kb_slave.mouse_y <= 127) {
mouse_sync = timer_read32();
}
}
}
}
}
}
void housekeeping_task_kb(void) {
// Update kb_state so we can send to slave
kb_state_update();
// Data sync from master to slave
kb_state_sync();
kb_post_state_update();
}
#endif

View file

@ -1,4 +1,4 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
/* Copyright 2020 Christopher Courtney <drashna@live.com> (@drashna)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,10 +14,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "5x6_right_trackball.h"
#include "tractyl_manuform.h"
#include "transactions.h"
#include <string.h>
#include "drivers/sensors/pmw3360.h"
#ifndef TRACKBALL_DPI_OPTIONS
# define TRACKBALL_DPI_OPTIONS { 1200, 1600, 2400 }
# define TRACKBALL_DPI_OPTIONS \
{ 1200, 1600, 2400 }
# ifndef TRACKBALL_DPI_DEFAULT
# define TRACKBALL_DPI_DEFAULT 1
# endif
@ -26,12 +30,15 @@
# define TRACKBALL_DPI_DEFAULT 0
#endif
extern kb_runtime_config_t kb_state;
extern kb_slave_data_t kb_slave;
keyboard_config_t keyboard_config;
uint16_t dpi_array[] = TRACKBALL_DPI_OPTIONS;
uint16_t dpi_array[] = TRACKBALL_DPI_OPTIONS;
#define DPI_OPTION_SIZE (sizeof(dpi_array) / sizeof(uint16_t))
bool BurstState = false; // init burst state for Trackball module
uint16_t MotionStart = 0; // Timer for accel, 0 is resting state
bool BurstState = false; // init burst state for Trackball module
uint16_t MotionStart = 0; // Timer for accel, 0 is resting state
__attribute__((weak)) void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y) {
mouse_report->x = x;
@ -53,12 +60,8 @@ __attribute__((weak)) void process_mouse(report_mouse_t* mouse_report) {
MotionStart = timer_read();
}
if (debug_mouse) {
dprintf("Delt] d: %d t: %u\n", abs(data.dx) + abs(data.dy), MotionStart);
}
if (debug_mouse) {
dprintf("Pre ] X: %d, Y: %d\n", data.dx, data.dy);
}
if (debug_mouse) { dprintf("Delt] d: %d t: %u\n", abs(data.dx) + abs(data.dy), MotionStart); }
if (debug_mouse) { dprintf("Pre ] X: %d, Y: %d\n", data.dx, data.dy); }
#if defined(PROFILE_LINEAR)
float scale = float(timer_elaspsed(MotionStart)) / 1000.0;
data.dx *= scale;
@ -85,7 +88,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
#ifdef POINTING_DEVICE_ENABLE
if (keycode == DPI_CONFIG && record->event.pressed) {
if ((get_mods()|get_oneshot_mods()) & MOD_MASK_SHIFT) {
if ((get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT) {
keyboard_config.dpi_config = (keyboard_config.dpi_config - 1) % DPI_OPTION_SIZE;
} else {
keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE;
@ -146,19 +149,11 @@ void pointing_device_init(void) {
trackball_set_cpi(dpi_array[keyboard_config.dpi_config]);
}
static bool has_report_changed(report_mouse_t new, report_mouse_t old) {
return (new.buttons != old.buttons) ||
(new.x && new.x != old.x) ||
(new.y && new.y != old.y) ||
(new.h && new.h != old.h) ||
(new.v && new.v != old.v);
}
static bool has_report_changed(report_mouse_t new, report_mouse_t old) { return (new.buttons != old.buttons) || (new.x&& new.x != old.x) || (new.y&& new.y != old.y) || (new.h&& new.h != old.h) || (new.v&& new.v != old.v); }
void pointing_device_task(void) {
report_mouse_t mouse_report = pointing_device_get_report();
if (!is_keyboard_left()) {
process_mouse(&mouse_report);
}
if (!is_keyboard_left()) { process_mouse(&mouse_report); }
pointing_device_set_report(mouse_report);
pointing_device_send();
@ -178,24 +173,20 @@ void matrix_init_kb(void) {
// is safe to just read DPI setting since matrix init
// comes before pointing device init.
keyboard_config.raw = eeconfig_read_kb();
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) {
eeconfig_init_kb();
}
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) { eeconfig_init_kb(); }
matrix_init_user();
}
#ifdef POINTING_DEVICE_ENABLE
void pointing_device_send(void) {
static report_mouse_t old_report = {};
report_mouse_t mouseReport = pointing_device_get_report();
static report_mouse_t old_report = {};
report_mouse_t mouseReport = pointing_device_get_report();
if (is_keyboard_master()) {
int8_t x = mouseReport.x, y = mouseReport.y;
mouseReport.x = 0;
mouseReport.y = 0;
process_mouse_user(&mouseReport, x, y);
if (has_report_changed(mouseReport, old_report)) {
host_mouse_send(&mouseReport);
}
if (has_report_changed(mouseReport, old_report)) { host_mouse_send(&mouseReport); }
} else {
master_mouse_send(mouseReport.x, mouseReport.y);
}
@ -203,26 +194,25 @@ void pointing_device_send(void) {
mouseReport.y = 0;
mouseReport.v = 0;
mouseReport.h = 0;
old_report = mouseReport;
old_report = mouseReport;
pointing_device_set_report(mouseReport);
}
#endif
#ifdef SWAP_HANDS_ENABLE
const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
/* Left hand, matrix positions */
{{5, 6}, {4, 6}, {3, 6}, {2, 6}, {1, 6}, {0, 6}},
{{5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7}, {0, 7}},
{{5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8}},
{{5, 9}, {4, 9}, {3, 9}, {2, 9}, {1, 9}, {0, 9}},
{{5, 10}, {4, 10}, {3, 10}, {2, 10}, {1, 10}, {0, 10}},
{{5, 11}, {4, 11}, {3, 11}, {2, 11}, {1, 11}, {0, 11}},
/* Right hand, matrix positions */
{{5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}},
{{5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}},
{{5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}},
{{5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}},
{{5, 4}, {4, 4}, {3, 4}, {2, 4}, {1, 4}, {0, 4}},
{{5, 5}, {4, 5}, {3, 5}, {2, 5}, {1, 5}, {0, 5}}
};
#ifdef POINTING_DEVICE_ENABLE
void master_mouse_send(int8_t x, int8_t y) {
#ifdef SPLIT_TRANSACTION_IDS_KB
kb_slave.mouse_x += x;
kb_slave.mouse_y += y;
#endif
}
void trackball_set_cpi(uint16_t cpi) {
if (!is_keyboard_left()) {
pmw_set_cpi(cpi);
} else {
#ifdef SPLIT_TRANSACTION_IDS_KB
kb_state.device_cpi = cpi;
#endif
}
}
#endif

View file

@ -0,0 +1,55 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
#include "pointing_device.h"
#if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right)
# include "5x6_right.h"
#elif defined(KEYBOARD_handwired_tractyl_manuform_4x6_right)
# include "4x6_right.h"
#endif
void process_mouse(report_mouse_t* mouse_report);
void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y);
typedef union {
uint32_t raw;
struct {
uint8_t dpi_config;
};
} keyboard_config_t;
extern keyboard_config_t keyboard_config;
enum ploopy_keycodes {
DPI_CONFIG = SAFE_RANGE,
KEYMAP_SAFE_RANGE,
};
void master_mouse_send(int8_t x, int8_t y);
void trackball_set_cpi(uint16_t cpi);
typedef struct {
uint16_t device_cpi;
} kb_runtime_config_t;
typedef struct {
int16_t mouse_x;
int16_t mouse_y;
} kb_slave_data_t;

View file

@ -131,7 +131,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format on
#ifdef OLED_DRIVER_ENABLE
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; }
oled_rotation_t oled_init_keymap(oled_rotation_t rotation) { return OLED_ROTATION_180; }
#endif
#ifdef ENCODER_ENABLE

View file

@ -3,19 +3,13 @@ ENCODER_ENABLE = yes # ENables the use of one or more encoders
RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
RGBLIGHT_STARTUP_ANIMATION = no
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = no # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE = no # MIDI support
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no # Audio output on port C6
NKRO_ENABLE = yes # USB Nkey Rollover
UNICODE_ENABLE = yes # Unicode
BOOTLOADER = atmel-dfu
# SPLIT_TRANSPORT = mirror
# TAP_DANCE_ENABLE = yes

View file

@ -19,7 +19,7 @@
#ifdef UNICODEMAP_ENABLE
# include "drashna_unicode.h"
#endif // UNICODEMAP_ENABLE
#include "drivers/sensors/pimoroni_trackball.h"
enum more_custom_keycodes {
KC_SWAP_NUM = NEW_SAFE_RANGE,
PM_SCROLL,
@ -317,13 +317,14 @@ void shutdown_keymap(void) {
static bool mouse_button_one, trackball_button_one;
void trackball_check_click(bool pressed, report_mouse_t* mouse) {
if (mouse_button_one | pressed) {
mouse->buttons |= MOUSE_BTN1;
void trackball_register_button(bool pressed, enum mouse_buttons button) {
report_mouse_t currentReport = pointing_device_get_report();
if (pressed) {
currentReport.buttons |= button;
} else {
mouse->buttons &= ~MOUSE_BTN1;
currentReport.buttons &= ~button;
}
trackball_button_one = pressed;
pointing_device_set_report(currentReport);
}
#endif

View file

@ -31,11 +31,11 @@
#ifdef RGBLIGHT_ENABLE
# undef RGBLED_NUM
# define RGBLED_NUM 27
# define RGBLED_NUM 27
# define RGBLIGHT_HUE_STEP 8
# define RGBLIGHT_SAT_STEP 8
# define RGBLIGHT_VAL_STEP 5
# define RGBLIGHT_HUE_STEP 8
# define RGBLIGHT_SAT_STEP 8
# define RGBLIGHT_VAL_STEP 5
# define RGBLIGHT_LIMIT_VAL 120
#endif
@ -44,37 +44,36 @@
# undef RGB_DI_PIN
# define RGB_DI_PIN A3
# endif
# define RGB_MATRIX_KEYPRESSES // reacts to keypresses
# define RGB_MATRIX_KEYPRESSES // reacts to keypresses
// # define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses)
// # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
# define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
// # define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness)
// # define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness)
# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 120 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
# define RGB_MATRIX_HUE_STEP 8
# define RGB_MATRIX_SAT_STEP 8
# define RGB_MATRIX_VAL_STEP 5
# define RGB_MATRIX_SPD_STEP 10
# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 120 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
# define RGB_MATRIX_HUE_STEP 8
# define RGB_MATRIX_SAT_STEP 8
# define RGB_MATRIX_VAL_STEP 5
# define RGB_MATRIX_SPD_STEP 10
#endif
#ifdef CONVERT_TO_PROTON_C
# define WS2812_PWM_DRIVER PWMD2 // default: PWMD2
# define WS2812_PWM_CHANNEL 4 // default: 2
# define WS2812_PWM_PAL_MODE 1 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2
# define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
# define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
# define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM2_UP // DMAMUX configuration for TIMx_UP -- only required if your MCU has a DMAMUX peripheral, see the respective reference manual for the appropriate values for your MCU.
# define WS2812_PWM_DRIVER PWMD2 // default: PWMD2
# define WS2812_PWM_CHANNEL 4 // default: 2
# define WS2812_PWM_PAL_MODE 1 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2
# define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
# define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
# define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM2_UP // DMAMUX configuration for TIMx_UP -- only required if your MCU has a DMAMUX peripheral, see the respective reference manual for the appropriate values for your MCU.
# undef SOFT_SERIAL_PIN
# define SOFT_SERIAL_PIN D3
# define SERIAL_USART_DRIVER SD1 // USART driver of TX pin. default: SD1
# define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
# define SOFT_SERIAL_PIN D3
# define SERIAL_USART_DRIVER SD1 // USART driver of TX pin. default: SD1
# define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
// #define INIT_EE_HANDS_LEFT
// #define INIT_EE_HANDS_RIGHT
#endif
#if defined(AUDIO_ENABLE) && !defined(CONVERT_TO_PROTON_C)
# define AUDIO_PIN B6
# define NO_MUSIC_MODE

View file

@ -114,7 +114,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format on
#ifdef OLED_DRIVER_ENABLE
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
return OLED_ROTATION_270;
}
#endif

View file

@ -17,34 +17,49 @@
#pragma once
// Use custom magic number so that when switching branches, EEPROM always gets reset
#define EECONFIG_MAGIC_NUMBER (uint16_t)0x1339
#define EECONFIG_MAGIC_NUMBER (uint16_t)0x1339
/* Set Polling rate to 1000Hz */
#define USB_POLLING_INTERVAL_MS 1
#if defined(SPLIT_KEYBOARD)
# define SPLIT_MODS_ENABLE
# define SPLIT_TRANSPORT_MIRROR
# define SPLIT_LAYER_STATE_ENABLE
# define SPLIT_LED_STATE_ENABLE
// # define SPLIT_TRANSPORT_MIRROR
# define SERIAL_USE_MULTI_TRANSACTION
// # define SPLIT_NUM_TRANSACTIONS_KB 2
# define SPLIT_TRANSACTION_IDS_USER RPC_ID_USER_STATE_SYNC
#endif
#ifdef AUDIO_ENABLE
# define AUDIO_CLICKY
# define STARTUP_SONG SONG(RICK_ROLL)
# define GOODBYE_SONG SONG(SONIC_RING)
# define DEFAULT_LAYER_SONGS \
{ SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(OVERWATCH_THEME) }
# define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f
# define UNICODE_SONG_MAC SONG(RICK_ROLL)
# define UNICODE_SONG_LNX SONG(RICK_ROLL)
# define UNICODE_SONG_WIN SONG(RICK_ROLL)
# define UNICODE_SONG_BSD SONG(RICK_ROLL)
# define UNICODE_SONG_WINC SONG(RICK_ROLL)
#endif // !AUDIO_ENABLE
# ifdef USER_SONG_LIST
# define STARTUP_SONG SONG(RICK_ROLL)
# define GOODBYE_SONG SONG(SONIC_RING)
# define DEFAULT_LAYER_SONGS \
{ SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(OVERWATCH_THEME) }
# define UNICODE_SONG_MAC SONG(MARIO_THEME)
# define UNICODE_SONG_LNX SONG(MARIO_POWERUP)
# define UNICODE_SONG_WIN SONG(MARIO_ONEUP)
# define UNICODE_SONG_BSD SONG(RICK_ROLL)
# define UNICODE_SONG_WINC SONG(RICK_ROLL)
# else
# define STARTUP_SONG SONG(STARTUP_SOUND)
# define GOODBYE_SONG SONG(GOODBYE_SOUND)
# define DEFAULT_LAYER_SONGS \
{ SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(WORKMAN_SOUND) }
# define UNICODE_SONG_MAC SONG(QWERTY_SOUND)
# define UNICODE_SONG_LNX SONG(COLEMAK_SOUND)
# define UNICODE_SONG_WIN SONG(DVORAK_SOUND)
# define UNICODE_SONG_BSD SONG(WORKMAN_SOUND)
# define UNICODE_SONG_WINC SONG(PLOVER_GOODBYE_SOUND)
# endif
#endif // !AUDIO_ENABLE
#define UNICODE_SELECTED_MODES UC_WIN, UC_MAC
#ifdef RGBLIGHT_ENABLE
# define RGBLIGHT_SLEEP
@ -56,18 +71,16 @@
# else
# define RGBLIGHT_ANIMATIONS
# endif
# define RGBLIGHT_EFFECT_TWINKLE_LIFE 250
# define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1/24
#endif // RGBLIGHT_ENABLE
# define RGBLIGHT_EFFECT_TWINKLE_LIFE 250
# define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1 / 24
#endif // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
# define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
# define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
// # define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
// # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
# define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
// # define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
// # define EECONFIG_RGB_MATRIX (uint32_t *)16
// # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
// # define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
# if defined(__AVR__) && !defined(__AVR_AT90USB1286__) && !defined(KEYBOARD_launchpad)
# define DISABLE_RGB_MATRIX_ALPHAS_MODS
@ -107,8 +120,8 @@
# define DISABLE_RGB_MATRIX_MULTISPLASH
# define DISABLE_RGB_MATRIX_SOLID_SPLASH
# define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
# endif // AVR
#endif // RGB_MATRIX_ENABLE
# endif // AVR
#endif // RGB_MATRIX_ENABLE
#ifdef OLED_DRIVER_ENABLE
# ifdef SPLIT_KEYBOARD
@ -120,7 +133,7 @@
# ifdef OLED_FONT_H
# undef OLED_FONT_H
# endif
# define OLED_FONT_H "drashna_font.h"
# define OLED_FONT_H "drashna_font.h"
# define OLED_FONT_END 255
// # define OLED_FONT_5X5
// # define OLED_FONT_AZTECH
@ -135,16 +148,16 @@
#ifndef ONESHOT_TAP_TOGGLE
# define ONESHOT_TAP_TOGGLE 2
#endif // !ONESHOT_TAP_TOGGLE
#endif // !ONESHOT_TAP_TOGGLE
#ifndef ONESHOT_TIMEOUT
# define ONESHOT_TIMEOUT 3000
#endif // !ONESHOT_TIMEOUT
#endif // !ONESHOT_TIMEOUT
#ifdef QMK_KEYS_PER_SCAN
# undef QMK_KEYS_PER_SCAN
# define QMK_KEYS_PER_SCAN 2
#endif // !QMK_KEYS_PER_SCAN
#endif // !QMK_KEYS_PER_SCAN
// this makes it possible to do rolling combos (zx) with keys that
// convert to other keys on hold (z becomes ctrl when you hold it,
@ -152,8 +165,8 @@
// actually sends Ctrl-x. That's bad.)
#define IGNORE_MOD_TAP_INTERRUPT
#undef PERMISSIVE_HOLD
//#define TAPPING_FORCE_HOLD
//#define RETRO_TAPPING
//#define TAPPING_FORCE_HOLD_PER_KEY
//#define RETRO_TAPPING_PER_KEY
#ifndef KEYBOARD_kyria_rev1
# define TAPPING_TERM_PER_KEY
#endif
@ -166,7 +179,7 @@
#ifdef TAPPING_TERM
# undef TAPPING_TERM
#endif // TAPPING_TERM
#endif // TAPPING_TERM
#if defined(KEYBOARD_ergodox_ez)
# define TAPPING_TERM 185
#elif defined(KEYBOARD_crkbd)
@ -185,14 +198,16 @@
# undef LOCKING_RESYNC_ENABLE
#endif
#define LAYER_STATE_16BIT
#ifdef CONVERT_TO_PROTON_C
// pins that are available but not present on Pro Micro
# define A3 PAL_LINE(GPIOA, 3)
# define A4 PAL_LINE(GPIOA, 4)
# define A5 PAL_LINE(GPIOA, 5)
# define A6 PAL_LINE(GPIOA, 6)
# define A7 PAL_LINE(GPIOA, 7)
# define A8 PAL_LINE(GPIOA, 8)
# define A3 PAL_LINE(GPIOA, 3)
# define A4 PAL_LINE(GPIOA, 4)
# define A5 PAL_LINE(GPIOA, 5)
# define A6 PAL_LINE(GPIOA, 6)
# define A7 PAL_LINE(GPIOA, 7)
# define A8 PAL_LINE(GPIOA, 8)
# define A13 PAL_LINE(GPIOA, 13)
# define A14 PAL_LINE(GPIOA, 14)
# define A15 PAL_LINE(GPIOA, 15)
@ -203,3 +218,79 @@
# define C14 PAL_LINE(GPIOC, 14)
# define C15 PAL_LINE(GPIOC, 15)
#endif
#ifdef MOUSEKEY_ENABLE
// mouse movement config
# ifdef MK_3_SPEED
# undef MK_3_SPEED
# endif
# define MK_KINETIC_SPEED
# ifdef MK_KINETIC_SPEED
# ifndef MOUSEKEY_DELAY
# define MOUSEKEY_DELAY 8
# endif
# ifndef MOUSEKEY_INTERVAL
# define MOUSEKEY_INTERVAL 20
# endif
# ifdef MOUSEKEY_MOVE_DELTA
# define MOUSEKEY_MOVE_DELTA 25
# endif
# else
# ifndef MOUSEKEY_DELAY
# define MOUSEKEY_DELAY 300
# endif
# ifndef MOUSEKEY_INTERVAL
# define MOUSEKEY_INTERVAL 50
# endif
# ifndef MOUSEKEY_MOVE_DELTA
# define MOUSEKEY_MOVE_DELTA 5
# endif
# endif
# ifndef MOUSEKEY_MAX_SPEED
# define MOUSEKEY_MAX_SPEED 7
# endif
# ifndef MOUSEKEY_TIME_TO_MAX
# define MOUSEKEY_TIME_TO_MAX 60
# endif
# ifndef MOUSEKEY_INITIAL_SPEED
# define MOUSEKEY_INITIAL_SPEED 100
# endif
# ifndef MOUSEKEY_BASE_SPEED
# define MOUSEKEY_BASE_SPEED 1000
# endif
# ifndef MOUSEKEY_DECELERATED_SPEED
# define MOUSEKEY_DECELERATED_SPEED 400
# endif
# ifndef MOUSEKEY_ACCELERATED_SPEED
# define MOUSEKEY_ACCELERATED_SPEED 3000
# endif
// mouse scroll config
# ifndef MOUSEKEY_WHEEL_DELAY
# define MOUSEKEY_WHEEL_DELAY 15
# endif
# ifndef MOUSEKEY_WHEEL_DELTA
# define MOUSEKEY_WHEEL_DELTA 1
# endif
# ifndef MOUSEKEY_WHEEL_INTERVAL
# define MOUSEKEY_WHEEL_INTERVAL 50
# endif
# ifndef MOUSEKEY_WHEEL_MAX_SPEED
# define MOUSEKEY_WHEEL_MAX_SPEED 8
# endif
# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
# define MOUSEKEY_WHEEL_TIME_TO_MAX 80
# endif
// mouse scroll kinetic config
# ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS
# define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 8
# endif
# ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS
# define MOUSEKEY_WHEEL_BASE_MOVEMENTS 48
# endif
# ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS
# define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48
# endif
# ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
# define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
# endif
#endif // MOUSEKEY_ENABLE

View file

@ -85,6 +85,9 @@ void keyboard_post_init_user(void) {
#endif
#if defined(RGB_MATRIX_ENABLE)
keyboard_post_init_rgb_matrix();
#endif
#if defined(SPLIT_KEYBOARD) && defined(SPLIT_TRANSACTION_IDS_USER)
keyboard_post_init_transport_sync();
#endif
keyboard_post_init_keymap();
}
@ -100,12 +103,12 @@ void shutdown_user(void) {
rgblight_enable_noeeprom();
rgblight_mode_noeeprom(1);
rgblight_setrgb_red();
#endif // RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
#ifdef RGB_MATRIX_ENABLE
rgb_matrix_set_color_all(0xFF, 0x00, 0x00);
rgb_matrix_update_pwm_buffers();
#endif // RGB_MATRIX_ENABLE
#endif // RGB_MATRIX_ENABLE
shutdown_keymap();
}
@ -120,7 +123,11 @@ void suspend_power_down_user(void) {
__attribute__((weak)) void suspend_wakeup_init_keymap(void) {}
void suspend_wakeup_init_user(void) { suspend_wakeup_init_keymap(); }
void suspend_wakeup_init_user(void) {
if (layer_state_is(_GAMEPAD)) { layer_off(_GAMEPAD); }
if (layer_state_is(_DIABLO)) { layer_off(_DIABLO); }
suspend_wakeup_init_keymap();
}
__attribute__((weak)) void matrix_scan_keymap(void) {}
@ -135,13 +142,13 @@ void matrix_scan_user(void) {
startup_user();
}
#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code.
#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code.
run_diablo_macro_check();
#endif // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE
#if defined(RGBLIGHT_ENABLE)
matrix_scan_rgb_light();
#endif // RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
#if defined(RGB_MATRIX_ENABLE)
matrix_scan_rgb_matrix();
#endif
@ -160,15 +167,13 @@ __attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state)
// on layer change, no matter where the change was initiated
// Then runs keymap's layer change check
layer_state_t layer_state_set_user(layer_state_t state) {
if (!is_keyboard_master()) {
return state;
}
if (!is_keyboard_master()) { return state; }
state = layer_state_set_keymap(state);
state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
#if defined(RGBLIGHT_ENABLE)
state = layer_state_set_rgb_light(state);
#endif // RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
#if defined(AUDIO_ENABLE) && !defined(__arm__)
static bool is_gamepad_on = false;
if (layer_state_cmp(state, _GAMEPAD) != is_gamepad_on) {
@ -187,15 +192,13 @@ __attribute__((weak)) layer_state_t default_layer_state_set_keymap(layer_state_t
// Runs state check and changes underglow color and animation
layer_state_t default_layer_state_set_user(layer_state_t state) {
if (!is_keyboard_master()) {
return state;
}
if (!is_keyboard_master()) { return state; }
state = default_layer_state_set_keymap(state);
#if 0
# if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
state = default_layer_state_set_rgb(state);
# endif // RGBLIGHT_ENABLE
# endif // RGBLIGHT_ENABLE
#endif
return state;
}

View file

@ -22,7 +22,7 @@
#include "process_records.h"
#ifdef TAP_DANCE_ENABLE
# include "tap_dances.h"
#endif // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE
#if defined(RGBLIGHT_ENABLE)
# include "rgb_stuff.h"
#endif
@ -35,6 +35,9 @@
#if defined(PIMORONI_TRACKBALL_ENABLE)
# include "drivers/sensors/pimoroni_trackball.h"
#endif
#ifdef SPLIT_KEYBOARD
# include "transport_sync.h"
#endif
/* Define layer names */
enum userspace_layers {
@ -98,12 +101,12 @@ We use custom codes here, so we can substitute the right stuff
# define KC_D3_2 TD(TD_D3_2)
# define KC_D3_3 TD(TD_D3_3)
# define KC_D3_4 TD(TD_D3_4)
#else // TAP_DANCE_ENABLE
#else // TAP_DANCE_ENABLE
# define KC_D3_1 KC_1
# define KC_D3_2 KC_2
# define KC_D3_3 KC_3
# define KC_D3_4 KC_4
#endif // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE
#if defined(DRASHNA_CUSTOM_TRANSPORT) && defined(POINTING_DEVICE_ENABLE)
void master_mouse_send(int8_t x, int8_t y);

View file

@ -5,8 +5,9 @@
#include "progmem.h"
// clang-format off
static const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 0
0x07, 0x08, 0x7F, 0x08, 0x07, 0x00, // 0x00 0
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, // 0x01 1
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, // 0x02 2
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, // 0x03 3 ♥
@ -1304,3 +1305,5 @@ static const unsigned char font[] PROGMEM = {
#endif
};
// clang-format on

View file

@ -1,603 +0,0 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stddef.h>
#include "matrix.h"
#include QMK_KEYBOARD_H
#define ROWS_PER_HAND (MATRIX_ROWS / 2)
#define SYNC_TIMER_OFFSET 2
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
#ifdef ENCODER_ENABLE
# include "encoder.h"
static pin_t encoders_pad[] = ENCODERS_PAD_A;
# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
#endif
#ifdef POINTING_DEVICE_ENABLE
static uint16_t device_cpi = 0;
static int8_t split_mouse_x = 0, split_mouse_y = 0;
#endif
#ifdef OLED_DRIVER_ENABLE
# include "oled_driver.h"
#endif
#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
# include "led_matrix.h"
#endif
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
# include "rgb_matrix.h"
#endif
#if defined(USE_I2C)
# include "i2c_master.h"
# include "i2c_slave.h"
typedef struct _I2C_slave_buffer_t {
# ifndef DISABLE_SYNC_TIMER
uint32_t sync_timer;
# endif
# ifdef SPLIT_TRANSPORT_MIRROR
matrix_row_t mmatrix[ROWS_PER_HAND];
# endif
matrix_row_t smatrix[ROWS_PER_HAND];
# ifdef SPLIT_MODS_ENABLE
uint8_t real_mods;
uint8_t weak_mods;
# ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods;
# endif
# endif
# ifdef BACKLIGHT_ENABLE
uint8_t backlight_level;
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
rgblight_syncinfo_t rgblight_sync;
# endif
# ifdef ENCODER_ENABLE
uint8_t encoder_state[NUMBER_OF_ENCODERS];
# endif
# ifdef WPM_ENABLE
uint8_t current_wpm;
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
led_eeconfig_t led_matrix;
bool led_suspend_state;
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
rgb_config_t rgb_matrix;
bool rgb_suspend_state;
# endif
int8_t mouse_x;
int8_t mouse_y;
uint16_t device_cpi;
bool oled_on;
layer_state_t t_layer_state;
layer_state_t t_default_layer_state;
} __attribute__((packed)) I2C_slave_buffer_t;
static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
# define I2C_KEYMAP_MASTER_START offsetof(I2C_slave_buffer_t, mmatrix)
# define I2C_KEYMAP_SLAVE_START offsetof(I2C_slave_buffer_t, smatrix)
# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer)
# define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods)
# define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods)
# define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)
# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm)
# define I2C_MOUSE_X_START offsetof(I2C_slave_buffer_t, mouse_x)
# define I2C_MOUSE_Y_START offsetof(I2C_slave_buffer_t, mouse_y)
# define I2C_MOUSE_DPI_START offsetof(I2C_slave_buffer_t, device_cpi)
# define I2C_OLED_ON_START offsetof(I2C_slave_buffer_t, oled_on)
# define I2C_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_layer_state)
# define I2C_DEFAULT_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_default_layer_state)
# define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix)
# define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state)
# define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix)
# define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state)
# define TIMEOUT 100
# ifndef SLAVE_I2C_ADDRESS
# define SLAVE_I2C_ADDRESS 0x32
# endif
// Get rows from other half over i2c
bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_SLAVE_START, (void *)slave_matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
# ifdef SPLIT_TRANSPORT_MIRROR
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_MASTER_START, (void *)master_matrix, sizeof(i2c_buffer->mmatrix), TIMEOUT);
# endif
// write backlight info
# ifdef BACKLIGHT_ENABLE
uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
if (level != i2c_buffer->backlight_level) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
i2c_buffer->backlight_level = level;
}
}
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
if (rgblight_get_change_flags()) {
rgblight_syncinfo_t rgblight_sync;
rgblight_get_syncinfo(&rgblight_sync);
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
rgblight_clear_change_flags();
}
}
# endif
# ifdef ENCODER_ENABLE
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT);
encoder_update_raw(i2c_buffer->encoder_state);
# endif
# ifdef WPM_ENABLE
uint8_t current_wpm = get_current_wpm();
if (current_wpm != i2c_buffer->current_wpm) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WPM_START, (void *)&current_wpm, sizeof(current_wpm), TIMEOUT) >= 0) {
i2c_buffer->current_wpm = current_wpm;
}
}
# endif
# ifdef POINTING_DEVICE_ENABLE
if (is_keyboard_left()) {
report_mouse_t temp_report = pointing_device_get_report();
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT);
temp_report.x = i2c_buffer->mouse_x;
i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT);
temp_report.y = i2c_buffer->mouse_y;
pointing_device_set_report(temp_report);
if (device_cpi != i2c_buffer->device_cpi) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_DPI_START, (void *)&device_cpi, sizeof(device_cpi), TIMEOUT) >= 0) {
i2c_buffer->device_cpi = device_cpi
}
}
}
# endif
# ifdef SPLIT_MODS_ENABLE
uint8_t real_mods = get_mods();
if (real_mods != i2c_buffer->real_mods) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) {
i2c_buffer->real_mods = real_mods;
}
}
uint8_t weak_mods = get_weak_mods();
if (weak_mods != i2c_buffer->weak_mods) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) {
i2c_buffer->weak_mods = weak_mods;
}
}
# ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods = get_oneshot_mods();
if (oneshot_mods != i2c_buffer->oneshot_mods) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) {
i2c_buffer->oneshot_mods = oneshot_mods;
}
}
# endif
# endif
if (layer_state != i2c_buffer->t_layer_state) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&layer_state, sizeof(layer_state), TIMEOUT) >= 0) {
i2c_buffer->t_layer_state = layer_state;
}
}
if (default_layer_state != i2c_buffer->t_default_layer_state) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_DEFAULT_LAYER_STATE_START, (void *)&default_layer_state, sizeof(default_layer_state), TIMEOUT) >= 0) {
i2c_buffer->t_default_layer_state = default_layer_state;
}
}
# ifdef OLED_DRIVER_ENABLE
bool is_oled_on = is_oled_on();
if (is_oled_on != i2c_buffer->oled_on) {
if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&is_oled_on, sizeof(is_oled_on), TIMEOUT) >= 0) {
i2c_buffer->oled_on = is_oled_on;
}
}
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT);
bool suspend_state = led_matrix_get_suspend_state();
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT);
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT);
bool suspend_state = rgb_matrix_get_suspend_state();
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT);
# endif
# ifndef DISABLE_SYNC_TIMER
i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
# endif
return true;
}
void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
# ifndef DISABLE_SYNC_TIMER
sync_timer_update(i2c_buffer->sync_timer);
# endif
// Copy matrix to I2C buffer
memcpy((void *)i2c_buffer->smatrix, (void *)slave_matrix, sizeof(i2c_buffer->smatrix));
# ifdef SPLIT_TRANSPORT_MIRROR
memcpy((void *)master_matrix, (void *)i2c_buffer->mmatrix, sizeof(i2c_buffer->mmatrix));
# endif
// Read Backlight Info
# ifdef BACKLIGHT_ENABLE
backlight_set(i2c_buffer->backlight_level);
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// Update the RGB with the new data
if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
i2c_buffer->rgblight_sync.status.change_flags = 0;
}
# endif
# ifdef ENCODER_ENABLE
encoder_state_raw(i2c_buffer->encoder_state);
# endif
# ifdef WPM_ENABLE
set_current_wpm(i2c_buffer->current_wpm);
# endif
# ifdef POINTING_DEVICE_ENABLE
if (!is_keyboard_left()) {
static uint16_t cpi;
if (cpi != i2c_buffer->device_cpi) {
cpi = i2c_buffer->device_cpi;
pmw_set_cpi(cpi);
}
i2c_buffer->mouse_x = split_mouse_x;
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT);
i2c_buffer->mouse_y = split_mouse_y;
i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT);
}
# endif
# ifdef SPLIT_MODS_ENABLE
set_mods(i2c_buffer->real_mods);
set_weak_mods(i2c_buffer->weak_mods);
# ifndef NO_ACTION_ONESHOT
set_oneshot_mods(i2c_buffer->oneshot_mods);
# endif
# endif
if (layer_state != i2c_buffer->t_layer_state) {
layer_state = i2c_buffer->t_layer_state;
}
if (default_layer_state != i2c_buffer->t_default_layer_state) {
default_layer_state = i2c_buffer->t_default_layer_state;
}
# ifdef OLED_DRIVER_ENABLE
if (i2c_buffer->oled_on) {
oled_on();
} else {
oled_off();
}
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix));
led_matrix_set_suspend_state(i2c_buffer->led_suspend_state);
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix));
rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state);
# endif
}
void transport_master_init(void) { i2c_init(); }
void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
#else // USE_SERIAL
# include "serial.h"
typedef struct _Serial_s2m_buffer_t {
// TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
matrix_row_t smatrix[ROWS_PER_HAND];
# ifdef ENCODER_ENABLE
uint8_t encoder_state[NUMBER_OF_ENCODERS];
# endif
int8_t mouse_x;
int8_t mouse_y;
} __attribute__((packed)) Serial_s2m_buffer_t;
typedef struct _Serial_m2s_buffer_t {
# ifdef SPLIT_MODS_ENABLE
uint8_t real_mods;
uint8_t weak_mods;
# ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods;
# endif
# endif
# ifndef DISABLE_SYNC_TIMER
uint32_t sync_timer;
# endif
# ifdef SPLIT_TRANSPORT_MIRROR
matrix_row_t mmatrix[ROWS_PER_HAND];
# endif
# ifdef BACKLIGHT_ENABLE
uint8_t backlight_level;
# endif
# ifdef WPM_ENABLE
uint8_t current_wpm;
# endif
uint16_t device_cpi;
bool oled_on;
layer_state_t t_layer_state;
layer_state_t t_default_layer_state;
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
led_eeconfig_t led_matrix;
bool led_suspend_state;
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
rgb_config_t rgb_matrix;
bool rgb_suspend_state;
# endif
} __attribute__((packed)) Serial_m2s_buffer_t;
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// When MCUs on both sides drive their respective RGB LED chains,
// it is necessary to synchronize, so it is necessary to communicate RGB
// information. In that case, define RGBLIGHT_SPLIT with info on the number
// of LEDs on each half.
//
// Otherwise, if the master side MCU drives both sides RGB LED chains,
// there is no need to communicate.
typedef struct _Serial_rgblight_t {
rgblight_syncinfo_t rgblight_sync;
} Serial_rgblight_t;
volatile Serial_rgblight_t serial_rgblight = {};
uint8_t volatile status_rgblight = 0;
# endif
volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
uint8_t volatile status0 = 0;
enum serial_transaction_id {
GET_SLAVE_MATRIX = 0,
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
PUT_RGBLIGHT,
# endif
};
SSTD_t transactions[] = {
[GET_SLAVE_MATRIX] =
{
(uint8_t *)&status0,
sizeof(serial_m2s_buffer),
(uint8_t *)&serial_m2s_buffer,
sizeof(serial_s2m_buffer),
(uint8_t *)&serial_s2m_buffer,
},
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
[PUT_RGBLIGHT] =
{
(uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer
},
# endif
};
void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// rgblight synchronization information communication.
void transport_rgblight_master(void) {
if (rgblight_get_change_flags()) {
rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
rgblight_clear_change_flags();
}
}
}
void transport_rgblight_slave(void) {
if (status_rgblight == TRANSACTION_ACCEPTED) {
rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false);
status_rgblight = TRANSACTION_END;
}
}
# else
# define transport_rgblight_master()
# define transport_rgblight_slave()
# endif
bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
# ifndef SERIAL_USE_MULTI_TRANSACTION
if (soft_serial_transaction() != TRANSACTION_END) {
return false;
}
# else
transport_rgblight_master();
if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
return false;
}
# endif
// TODO: if MATRIX_COLS > 8 change to unpack()
for (int i = 0; i < ROWS_PER_HAND; ++i) {
slave_matrix[i] = serial_s2m_buffer.smatrix[i];
# ifdef SPLIT_TRANSPORT_MIRROR
serial_m2s_buffer.mmatrix[i] = master_matrix[i];
# endif
}
# ifdef BACKLIGHT_ENABLE
// Write backlight level for slave to read
serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
# endif
# ifdef ENCODER_ENABLE
encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
# endif
# ifdef WPM_ENABLE
// Write wpm to slave
serial_m2s_buffer.current_wpm = get_current_wpm();
# endif
# ifdef SPLIT_MODS_ENABLE
serial_m2s_buffer.real_mods = get_mods();
serial_m2s_buffer.weak_mods = get_weak_mods();
# ifndef NO_ACTION_ONESHOT
serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
# endif
# endif
# ifdef POINTING_DEVICE_ENABLE
if (is_keyboard_left()) {
report_mouse_t temp_report = pointing_device_get_report();
temp_report.x = serial_s2m_buffer.mouse_x;
temp_report.y = serial_s2m_buffer.mouse_y;
pointing_device_set_report(temp_report);
serial_m2s_buffer.device_cpi = device_cpi;
}
# endif
serial_m2s_buffer.t_layer_state = layer_state;
serial_m2s_buffer.t_default_layer_state = default_layer_state;
# ifdef OLED_DRIVER_ENABLE
serial_m2s_buffer.oled_on = is_oled_on();
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
serial_m2s_buffer.led_matrix = led_matrix_eeconfig;
serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state();
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
serial_m2s_buffer.rgb_matrix = rgb_matrix_config;
serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state();
# endif
# ifndef DISABLE_SYNC_TIMER
serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
# endif
return true;
}
void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
transport_rgblight_slave();
# ifndef DISABLE_SYNC_TIMER
sync_timer_update(serial_m2s_buffer.sync_timer);
# endif
// TODO: if MATRIX_COLS > 8 change to pack()
for (int i = 0; i < ROWS_PER_HAND; ++i) {
serial_s2m_buffer.smatrix[i] = slave_matrix[i];
# ifdef SPLIT_TRANSPORT_MIRROR
master_matrix[i] = serial_m2s_buffer.mmatrix[i];
# endif
}
# ifdef BACKLIGHT_ENABLE
backlight_set(serial_m2s_buffer.backlight_level);
# endif
# ifdef ENCODER_ENABLE
encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
# endif
# ifdef WPM_ENABLE
set_current_wpm(serial_m2s_buffer.current_wpm);
# endif
# ifdef SPLIT_MODS_ENABLE
set_mods(serial_m2s_buffer.real_mods);
set_weak_mods(serial_m2s_buffer.weak_mods);
# ifndef NO_ACTION_ONESHOT
set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
# endif
# endif
# ifdef POINTING_DEVICE_ENABLE
if (!is_keyboard_left()) {
static uint16_t cpi;
if (cpi != serial_m2s_buffer.device_cpi) {
cpi = serial_m2s_buffer.device_cpi;
pmw_set_cpi(cpi);
}
serial_s2m_buffer.mouse_x = split_mouse_x;
serial_s2m_buffer.mouse_y = split_mouse_y;
}
# endif
if (layer_state != serial_m2s_buffer.t_layer_state) {
layer_state = serial_m2s_buffer.t_layer_state;
}
if (default_layer_state != serial_m2s_buffer.t_default_layer_state) {
default_layer_state = serial_m2s_buffer.t_default_layer_state;
}
# ifdef OLED_DRIVER_ENABLE
if (serial_m2s_buffer.oled_on) {
oled_on();
} else {
oled_off();
}
# endif
# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
led_matrix_eeconfig = serial_m2s_buffer.led_matrix;
led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state);
# endif
# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
rgb_matrix_config = serial_m2s_buffer.rgb_matrix;
rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state);
# endif
}
#endif

View file

@ -25,7 +25,7 @@
#endif
uint32_t oled_timer = 0;
static char keylog_str[KEYLOGGER_LENGTH + 1] = {"\n"};
static char keylog_str[KEYLOGGER_LENGTH + 1] = { 0 };
static uint16_t log_timer = 0;
// clang-format off
@ -57,12 +57,12 @@ void add_keylog(uint16_t keycode) {
keycode = 0;
}
for (uint8_t i = (KEYLOGGER_LENGTH - 1); i > 0; --i) {
keylog_str[i] = keylog_str[i - 1];
for (uint8_t i = 1; i < KEYLOGGER_LENGTH; i++) {
keylog_str[i-1] = keylog_str[i];
}
if (keycode < (sizeof(code_to_name) / sizeof(char))) {
keylog_str[0] = pgm_read_byte(&code_to_name[keycode]);
keylog_str[(KEYLOGGER_LENGTH - 1)] = pgm_read_byte(&code_to_name[keycode]);
}
log_timer = timer_read();
@ -92,30 +92,14 @@ void render_keylogger_status(void) {
void render_default_layer_state(void) {
oled_write_P(PSTR(OLED_RENDER_LAYOUT_NAME), false);
switch (get_highest_layer(default_layer_state)) {
case _QWERTY:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_QWERTY), false);
break;
case _COLEMAK:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_COLEMAK), false);
break;
case _DVORAK:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_DVORAK), false);
break;
case _WORKMAN:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_WORKMAN), false);
break;
case _NORMAN:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_NORMAN), false);
break;
case _MALTRON:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_MALTRON), false);
break;
case _EUCALYN:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_EUCALYN), false);
break;
case _CARPLAX:
oled_write_P(PSTR(OLED_RENDER_LAYOUT_CARPLAX), false);
break;
case _QWERTY: oled_write_P(PSTR(OLED_RENDER_LAYOUT_QWERTY), false); break;
case _COLEMAK: oled_write_P(PSTR(OLED_RENDER_LAYOUT_COLEMAK), false); break;
case _DVORAK: oled_write_P(PSTR(OLED_RENDER_LAYOUT_DVORAK), false); break;
case _WORKMAN: oled_write_P(PSTR(OLED_RENDER_LAYOUT_WORKMAN), false); break;
case _NORMAN: oled_write_P(PSTR(OLED_RENDER_LAYOUT_NORMAN), false); break;
case _MALTRON: oled_write_P(PSTR(OLED_RENDER_LAYOUT_MALTRON), false); break;
case _EUCALYN: oled_write_P(PSTR(OLED_RENDER_LAYOUT_EUCALYN), false); break;
case _CARPLAX: oled_write_P(PSTR(OLED_RENDER_LAYOUT_CARPLAX), false); break;
}
#ifdef OLED_DISPLAY_128X64
oled_advance_page(true);
@ -159,12 +143,12 @@ void render_keylock_status(uint8_t led_usb_state) {
}
void render_matrix_scan_rate(void) {
#ifdef DEBUG_MATRIX_SCAN_RATE
char matrix_rate[5];
uint16_t n = get_matrix_scan_rate();
char matrix_rate[5];
uint16_t n = get_matrix_scan_rate();
matrix_rate[4] = '\0';
matrix_rate[3] = '0' + n % 10;
matrix_rate[2] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
matrix_rate[1] = n / 10 ? '0' + n / 10 : ' ';
matrix_rate[2] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
matrix_rate[1] = n / 10 ? '0' + n / 10 : ' ';
matrix_rate[0] = ' ';
oled_write_P(PSTR("MS:"), false);
oled_write(matrix_rate, false);
@ -284,6 +268,10 @@ void render_user_status(void) {
oled_write_P(rgb_layer_status[userspace_config.rgb_layer_change], false);
static const char PROGMEM nukem_good[2][3] = {{0xF8, 0xF9, 0}, {0xF6, 0xF7, 0}};
oled_write_P(nukem_good[0], userspace_config.nuke_switch);
#if defined(UNICODE_ENABLE)
static const char PROGMEM uc_mod_status[5][3] = {{0xEA, 0xEB, 0}, {0xEC, 0xED, 0}};
oled_write_P(uc_mod_status[get_unicode_input_mode() == UC_MAC], false);
#endif
#if defined(OLED_DISPLAY_128X64)
oled_advance_page(true);
#endif
@ -306,34 +294,34 @@ void render_wpm(void) {
char wpm_counter[4];
wpm_counter[3] = '\0';
wpm_counter[2] = '0' + n % 10;
wpm_counter[1] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
wpm_counter[1] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
wpm_counter[0] = n / 10 ? '0' + n / 10 : ' ';
# else
char wpm_counter[6];
wpm_counter[5] = '\0';
wpm_counter[4] = '0' + n % 10;
wpm_counter[3] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
wpm_counter[3] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
wpm_counter[2] = n / 10 ? '0' + n / 10 : ' ';
wpm_counter[1] = ' ';
wpm_counter[0] = ' ';
# endif
# endif
oled_write_P(PSTR(OLED_RENDER_WPM_COUNTER), false);
oled_write(wpm_counter, false);
#endif
}
#ifdef KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball
#if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right)
extern keyboard_config_t keyboard_config;
extern uint16_t dpi_array[];
void render_pointing_dpi_status(void) {
char dpi_status[6];
uint16_t n = dpi_array[keyboard_config.dpi_config];
char dpi_status[6];
uint16_t n = dpi_array[keyboard_config.dpi_config];
dpi_status[5] = '\0';
dpi_status[4] = '0' + n % 10;
dpi_status[3] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
dpi_status[2] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
dpi_status[1] = n / 10 ? '0' + n / 10 : ' ';
dpi_status[3] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
dpi_status[2] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
dpi_status[1] = n / 10 ? '0' + n / 10 : ' ';
dpi_status[0] = ' ';
oled_write_P(PSTR(" DPI: "), false);
oled_write(dpi_status, false);
@ -360,7 +348,7 @@ void render_status_main(void) {
# else
render_wpm();
# endif
# ifdef KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball
# if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right)
render_pointing_dpi_status();
# endif
oled_write_P(PSTR("\n"), false);
@ -375,6 +363,15 @@ void render_status_main(void) {
render_keylogger_status();
}
__attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation) { return rotation; }
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
for (uint8_t i = 0; i < (KEYLOGGER_LENGTH - 1); i++) {
add_keylog(0);
}
return oled_init_keymap(rotation);
}
void oled_task_user(void) {
update_log();
@ -385,7 +382,7 @@ void oled_task_user(void) {
} else {
oled_on();
}
render_status_main(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
render_status_main(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
} else {
render_status_secondary();
}

View file

@ -19,97 +19,98 @@
#include "quantum.h"
#include "oled_driver.h"
void oled_driver_render_logo(void);
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record);
void oled_driver_render_logo(void);
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record);
oled_rotation_t oled_init_keymap(oled_rotation_t rotation);
extern uint32_t oled_timer;
#ifdef OLED_DISPLAY_128X64
# define OLED_RENDER_KEYLOGGER "Keylogger: "
# define OLED_RENDER_KEYLOGGER "Keylogger: "
# define OLED_RENDER_LAYOUT_NAME "Layout: "
# define OLED_RENDER_LAYOUT_QWERTY "Qwerty"
# define OLED_RENDER_LAYOUT_COLEMAK "Colemak"
# define OLED_RENDER_LAYOUT_DVORAK "Dvorak"
# define OLED_RENDER_LAYOUT_WORKMAN "Workman"
# define OLED_RENDER_LAYOUT_NORMAN "Norman"
# define OLED_RENDER_LAYOUT_MALTRON "Matron"
# define OLED_RENDER_LAYOUT_EUCALYN "Eucalyn"
# define OLED_RENDER_LAYOUT_CARPLAX "Carplax"
# define OLED_RENDER_LAYOUT_NAME "Layout: "
# define OLED_RENDER_LAYOUT_QWERTY "Qwerty"
# define OLED_RENDER_LAYOUT_COLEMAK "Colemak"
# define OLED_RENDER_LAYOUT_DVORAK "Dvorak"
# define OLED_RENDER_LAYOUT_WORKMAN "Workman"
# define OLED_RENDER_LAYOUT_NORMAN "Norman"
# define OLED_RENDER_LAYOUT_MALTRON "Matron"
# define OLED_RENDER_LAYOUT_EUCALYN "Eucalyn"
# define OLED_RENDER_LAYOUT_CARPLAX "Carplax"
# define OLED_RENDER_LAYER_NAME "Layer:"
# define OLED_RENDER_LAYER_LOWER "Lower"
# define OLED_RENDER_LAYER_RAISE "Raise"
# define OLED_RENDER_LAYER_ADJUST "Adjust"
# define OLED_RENDER_LAYER_MODS "Mods"
# define OLED_RENDER_LAYER_NAME "Layer:"
# define OLED_RENDER_LAYER_LOWER "Lower"
# define OLED_RENDER_LAYER_RAISE "Raise"
# define OLED_RENDER_LAYER_ADJUST "Adjust"
# define OLED_RENDER_LAYER_MODS "Mods"
# define OLED_RENDER_LOCK_NAME "Lock: "
# define OLED_RENDER_LOCK_NUML "NUML"
# define OLED_RENDER_LOCK_CAPS "CAPS"
# define OLED_RENDER_LOCK_SCLK "SCLK"
# define OLED_RENDER_LOCK_NAME "Lock: "
# define OLED_RENDER_LOCK_NUML "NUML"
# define OLED_RENDER_LOCK_CAPS "CAPS"
# define OLED_RENDER_LOCK_SCLK "SCLK"
# define OLED_RENDER_MODS_NAME "Mods:"
# define OLED_RENDER_MODS_SFT "Sft"
# define OLED_RENDER_MODS_CTL "Ctl"
# define OLED_RENDER_MODS_ALT "Alt"
# define OLED_RENDER_MODS_GUI "GUI"
# define OLED_RENDER_MODS_NAME "Mods:"
# define OLED_RENDER_MODS_SFT "Sft"
# define OLED_RENDER_MODS_CTL "Ctl"
# define OLED_RENDER_MODS_ALT "Alt"
# define OLED_RENDER_MODS_GUI "GUI"
# define OLED_RENDER_BOOTMAGIC_NAME "Boot "
# define OLED_RENDER_BOOTMAGIC_NKRO "NKRO"
# define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
# define OLED_RENDER_BOOTMAGIC_GRV "GRV"
# define OLED_RENDER_BOOTMAGIC_NAME "Boot "
# define OLED_RENDER_BOOTMAGIC_NKRO "NKRO"
# define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
# define OLED_RENDER_BOOTMAGIC_GRV "GRV"
# define OLED_RENDER_BOOTMAGIC_ONESHOT "1SHT"
# define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
# define OLED_RENDER_BOOTMAGIC_CAPS "CAPS"
# define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
# define OLED_RENDER_BOOTMAGIC_CAPS "CAPS"
# define OLED_RENDER_USER_NAME "USER:"
# define OLED_RENDER_USER_ANIM "Anim"
# define OLED_RENDER_USER_LAYR "Layr"
# define OLED_RENDER_USER_NUKE "Nuke"
# define OLED_RENDER_USER_NAME "USER:"
# define OLED_RENDER_USER_ANIM "Anim"
# define OLED_RENDER_USER_LAYR "Layr"
# define OLED_RENDER_USER_NUKE "Nuke"
# define OLED_RENDER_WPM_COUNTER "WPM: "
# define OLED_RENDER_WPM_COUNTER "WPM: "
#else
# define OLED_RENDER_KEYLOGGER "KLogr"
# define OLED_RENDER_KEYLOGGER "KLogr"
# define OLED_RENDER_LAYOUT_NAME "Lyout"
# define OLED_RENDER_LAYOUT_QWERTY " QRTY"
# define OLED_RENDER_LAYOUT_COLEMAK " COLE"
# define OLED_RENDER_LAYOUT_DVORAK " DVRK"
# define OLED_RENDER_LAYOUT_WORKMAN " WKMN"
# define OLED_RENDER_LAYOUT_NORMAN " NORM"
# define OLED_RENDER_LAYOUT_MALTRON " MLTN"
# define OLED_RENDER_LAYOUT_EUCALYN " ECLN"
# define OLED_RENDER_LAYOUT_CARPLAX " CRPX"
# define OLED_RENDER_LAYOUT_NAME "Lyout"
# define OLED_RENDER_LAYOUT_QWERTY " QRTY"
# define OLED_RENDER_LAYOUT_COLEMAK " COLE"
# define OLED_RENDER_LAYOUT_DVORAK " DVRK"
# define OLED_RENDER_LAYOUT_WORKMAN " WKMN"
# define OLED_RENDER_LAYOUT_NORMAN " NORM"
# define OLED_RENDER_LAYOUT_MALTRON " MLTN"
# define OLED_RENDER_LAYOUT_EUCALYN " ECLN"
# define OLED_RENDER_LAYOUT_CARPLAX " CRPX"
# define OLED_RENDER_LAYER_NAME "LAYER"
# define OLED_RENDER_LAYER_LOWER "Lower"
# define OLED_RENDER_LAYER_RAISE "Raise"
# define OLED_RENDER_LAYER_ADJUST "Adjst"
# define OLED_RENDER_LAYER_MODS " Mods"
# define OLED_RENDER_LAYER_NAME "LAYER"
# define OLED_RENDER_LAYER_LOWER "Lower"
# define OLED_RENDER_LAYER_RAISE "Raise"
# define OLED_RENDER_LAYER_ADJUST "Adjst"
# define OLED_RENDER_LAYER_MODS " Mods"
# define OLED_RENDER_LOCK_NAME "Lock:"
# define OLED_RENDER_LOCK_NUML "NumL"
# define OLED_RENDER_LOCK_CAPS "CapL"
# define OLED_RENDER_LOCK_SCLK "ScrL"
# define OLED_RENDER_LOCK_NAME "Lock:"
# define OLED_RENDER_LOCK_NUML "NumL"
# define OLED_RENDER_LOCK_CAPS "CapL"
# define OLED_RENDER_LOCK_SCLK "ScrL"
# define OLED_RENDER_MODS_NAME "Mods: "
# define OLED_RENDER_MODS_SFT "Shft"
# define OLED_RENDER_MODS_CTL "Ctrl"
# define OLED_RENDER_MODS_ALT "Alt\n"
# define OLED_RENDER_MODS_GUI "GUI\n"
# define OLED_RENDER_MODS_NAME "Mods: "
# define OLED_RENDER_MODS_SFT "Shft"
# define OLED_RENDER_MODS_CTL "Ctrl"
# define OLED_RENDER_MODS_ALT "Alt\n"
# define OLED_RENDER_MODS_GUI "GUI\n"
# define OLED_RENDER_BOOTMAGIC_NAME "BTMGK"
# define OLED_RENDER_BOOTMAGIC_NKRO "NKRO"
# define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
# define OLED_RENDER_BOOTMAGIC_GRV "GRV"
# define OLED_RENDER_BOOTMAGIC_NAME "BTMGK"
# define OLED_RENDER_BOOTMAGIC_NKRO "NKRO"
# define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
# define OLED_RENDER_BOOTMAGIC_GRV "GRV"
# define OLED_RENDER_BOOTMAGIC_ONESHOT "1SHT"
# define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
# define OLED_RENDER_BOOTMAGIC_CAPS "CAPS"
# define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
# define OLED_RENDER_BOOTMAGIC_CAPS "CAPS"
# define OLED_RENDER_USER_NAME "USER:"
# define OLED_RENDER_USER_ANIM "Anim"
# define OLED_RENDER_USER_LAYR "Layr"
# define OLED_RENDER_USER_NUKE "Nuke"
# define OLED_RENDER_USER_NAME "USER:"
# define OLED_RENDER_USER_ANIM "Anim"
# define OLED_RENDER_USER_LAYR "Layr"
# define OLED_RENDER_USER_NUKE "Nuke"
# define OLED_RENDER_WPM_COUNTER "WPM: "
# define OLED_RENDER_WPM_COUNTER "WPM: "
#endif

View file

@ -29,10 +29,10 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// If console is enabled, it will print the matrix position and status of each key pressed
#ifdef KEYLOGGER_ENABLE
uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %b, time: %5u, int: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
#endif // KEYLOGGER_ENABLE
#endif // KEYLOGGER_ENABLE
#ifdef OLED_DRIVER_ENABLE
process_record_user_oled(keycode, record);
#endif // OLED
#endif // OLED
if (!(process_record_keymap(keycode, record) && process_record_secrets(keycode, record)
#ifdef RGB_MATRIX_ENABLE
@ -59,7 +59,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
break;
case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
if (!record->event.pressed) {
#ifndef MAKE_BOOTLOADER
uint8_t temp_mod = mod_config(get_mods());
@ -90,56 +90,44 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
break;
case VRSN: // Prints firmware version
if (record->event.pressed) {
send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
}
case VRSN: // Prints firmware version
if (record->event.pressed) { send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY); }
break;
case KC_DIABLO_CLEAR: // reset all Diablo timers, disabling them
case KC_DIABLO_CLEAR: // reset all Diablo timers, disabling them
#ifdef TAP_DANCE_ENABLE
if (record->event.pressed) {
for (uint8_t index = 0; index < 4; index++) {
diablo_timer[index].key_interval = 0;
}
for (uint8_t index = 0; index < 4; index++) { diablo_timer[index].key_interval = 0; }
}
#endif // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE
break;
case KC_CCCV: // One key copy/paste
case KC_CCCV: // One key copy/paste
if (record->event.pressed) {
copy_paste_timer = timer_read();
} else {
if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy
if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy
tap_code16(LCTL(KC_C));
} else { // Tap, paste
} else { // Tap, paste
tap_code16(LCTL(KC_V));
}
}
break;
#ifdef UNICODE_ENABLE
case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻
if (record->event.pressed) {
send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻");
}
case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻
if (record->event.pressed) { send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻"); }
break;
case UC_TABL: // ┬─┬ノ( º _ ºノ)
if (record->event.pressed) {
send_unicode_string("┬─┬ノ( º _ ºノ)");
}
case UC_TABL: // ┬─┬ノ( º _ ºノ)
if (record->event.pressed) { send_unicode_string("┬─┬ノ( º _ ºノ)"); }
break;
case UC_SHRG: // ¯\_(ツ)_/¯
if (record->event.pressed) {
send_unicode_string("¯\\_(ツ)_/¯");
}
case UC_SHRG: // ¯\_(ツ)_/¯
if (record->event.pressed) { send_unicode_string("¯\\_(ツ)_/¯"); }
break;
case UC_DISA: // ಠ_ಠ
if (record->event.pressed) {
send_unicode_string("ಠ_ಠ");
}
case UC_DISA: // ಠ_ಠ
if (record->event.pressed) { send_unicode_string("ಠ_ಠ"); }
break;
#endif
case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal
case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
if (record->event.pressed) {
userspace_config.rgb_layer_change ^= 1;
@ -149,14 +137,14 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
# if defined(RGBLIGHT_ENABLE) && defined(RGB_MATRIX_ENABLE)
rgblight_enable_noeeprom();
# endif
layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
# if defined(RGBLIGHT_ENABLE) && defined(RGB_MATRIX_ENABLE)
} else {
rgblight_disable_noeeprom();
# endif
}
}
#endif // RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
break;
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
@ -176,7 +164,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
return false;
break;
case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
if (record->event.pressed) {
bool is_eeprom_updated;
# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
@ -194,9 +182,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
is_eeprom_updated = true;
}
# endif
if (is_eeprom_updated) {
eeconfig_update_user(userspace_config.raw);
}
if (is_eeprom_updated) { eeconfig_update_user(userspace_config.raw); }
}
#endif
}

View file

@ -17,58 +17,58 @@
#pragma once
#include "drashna.h"
#if defined(KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball)
#if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right)
# define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE
#else
# define PLACEHOLDER_SAFE_RANGE SAFE_RANGE
#endif
enum userspace_custom_keycodes {
VRSN = PLACEHOLDER_SAFE_RANGE, // Prints QMK Firmware and board info
KC_QWERTY, // Sets default layer to QWERTY
KC_COLEMAK, // Sets default layer to COLEMAK
KC_DVORAK, // Sets default layer to DVORAK
KC_WORKMAN, // Sets default layer to WORKMAN
KC_DIABLO_CLEAR, // Clears all Diablo Timers
KC_MAKE, // Run keyboard's customized make command
KC_RGB_T, // Toggles RGB Layer Indication mode
RGB_IDL, // RGB Idling animations
KC_SECRET_1, // test1
KC_SECRET_2, // test2
KC_SECRET_3, // test3
KC_SECRET_4, // test4
KC_SECRET_5, // test5
KC_CCCV, // Hold to copy, tap to paste
KC_NUKE, // NUCLEAR LAUNCH DETECTED!!!
UC_FLIP, // (ಠ痊ಠ)┻━┻
UC_TABL, // ┬─┬ノ( º _ ºノ)
UC_SHRG, // ¯\_(ツ)_/¯
UC_DISA, // ಠ_ಠ
NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes
VRSN = PLACEHOLDER_SAFE_RANGE, // Prints QMK Firmware and board info
KC_QWERTY, // Sets default layer to QWERTY
KC_COLEMAK, // Sets default layer to COLEMAK
KC_DVORAK, // Sets default layer to DVORAK
KC_WORKMAN, // Sets default layer to WORKMAN
KC_DIABLO_CLEAR, // Clears all Diablo Timers
KC_MAKE, // Run keyboard's customized make command
KC_RGB_T, // Toggles RGB Layer Indication mode
RGB_IDL, // RGB Idling animations
KC_SECRET_1, // test1
KC_SECRET_2, // test2
KC_SECRET_3, // test3
KC_SECRET_4, // test4
KC_SECRET_5, // test5
KC_CCCV, // Hold to copy, tap to paste
KC_NUKE, // NUCLEAR LAUNCH DETECTED!!!
UC_FLIP, // (ಠ痊ಠ)┻━┻
UC_TABL, // ┬─┬ノ( º _ ºノ)
UC_SHRG, // ¯\_(ツ)_/¯
UC_DISA, // ಠ_ಠ
NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes
};
bool process_record_secrets(uint16_t keycode, keyrecord_t *record);
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
#define ADJUST MO(_ADJUST)
#define TG_MODS OS_TOGG
#define TG_GAME TG(_GAMEPAD)
#define TG_DBLO TG(_DIABLO)
#define OS_LWR OSL(_LOWER)
#define OS_RSE OSL(_RAISE)
#define LOWER MO(_LOWER)
#define RAISE MO(_RAISE)
#define ADJUST MO(_ADJUST)
#define TG_MODS OS_TOGG
#define TG_GAME TG(_GAMEPAD)
#define TG_DBLO TG(_DIABLO)
#define OS_LWR OSL(_LOWER)
#define OS_RSE OSL(_RAISE)
#define KC_SEC1 KC_SECRET_1
#define KC_SEC2 KC_SECRET_2
#define KC_SEC3 KC_SECRET_3
#define KC_SEC4 KC_SECRET_4
#define KC_SEC5 KC_SECRET_5
#define KC_SEC1 KC_SECRET_1
#define KC_SEC2 KC_SECRET_2
#define KC_SEC3 KC_SECRET_3
#define KC_SEC4 KC_SECRET_4
#define KC_SEC5 KC_SECRET_5
#define QWERTY KC_QWERTY
#define DVORAK KC_DVORAK
#define COLEMAK KC_COLEMAK
#define WORKMAN KC_WORKMAN
#define QWERTY KC_QWERTY
#define DVORAK KC_DVORAK
#define COLEMAK KC_COLEMAK
#define WORKMAN KC_WORKMAN
#define KC_RESET RESET
#define KC_RST KC_RESET
@ -77,9 +77,9 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
# define KC_C1R3 SH_T(KC_TAB)
#elif defined(DRASHNA_LP)
# define KC_C1R3 TG(_GAMEPAD)
#else // SWAP_HANDS_ENABLE
#else // SWAP_HANDS_ENABLE
# define KC_C1R3 KC_TAB
#endif // SWAP_HANDS_ENABLE
#endif // SWAP_HANDS_ENABLE
#define BK_LWER LT(_LOWER, KC_BSPC)
#define SP_LWER LT(_LOWER, KC_SPC)

View file

@ -28,33 +28,27 @@ static uint32_t hypno_timer;
void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode, uint8_t speed, uint8_t led_type, uint8_t led_min, uint8_t led_max) {
HSV hsv = {hue, sat, val};
if (hsv.v > rgb_matrix_get_val()) {
hsv.v = rgb_matrix_get_val();
}
if (hsv.v > rgb_matrix_get_val()) { hsv.v = rgb_matrix_get_val(); }
switch (mode) {
case 1: // breathing
{
uint16_t time = scale16by8(g_rgb_timer, speed / 8);
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
RGB rgb = hsv_to_rgb(hsv);
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b);
case 1: // breathing
{
uint16_t time = scale16by8(g_rgb_timer, speed / 8);
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
RGB rgb = hsv_to_rgb(hsv);
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
if (HAS_FLAGS(g_led_config.flags[i], led_type)) { RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b); }
}
break;
}
break;
}
default: // Solid Color
{
RGB rgb = hsv_to_rgb(hsv);
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b);
default: // Solid Color
{
RGB rgb = hsv_to_rgb(hsv);
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
if (HAS_FLAGS(g_led_config.flags[i], led_type)) { RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b); }
}
break;
}
break;
}
}
}
@ -62,38 +56,30 @@ __attribute__((weak)) void rgb_matrix_indicator_keymap(void) {}
void matrix_scan_rgb_matrix(void) {
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_TYPING_HEATMAP && sync_timer_elapsed32(hypno_timer) > 15000) {
rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
}
if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_TYPING_HEATMAP && sync_timer_elapsed32(hypno_timer) > 15000) { rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE); }
#endif
rgb_matrix_indicator_keymap();
}
void keyboard_post_init_rgb_matrix(void) {
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
if (userspace_config.rgb_matrix_idle_anim) {
rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
}
if (userspace_config.rgb_matrix_idle_anim) { rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE); }
#endif
}
bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
hypno_timer = sync_timer_read32();
if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_REST_MODE) {
rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP);
}
if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_REST_MODE) { rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP); }
#endif
switch (keycode) {
case RGB_IDL: // This allows me to use underglow as layer indication, or as normal
case RGB_IDL: // This allows me to use underglow as layer indication, or as normal
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
if (record->event.pressed) {
userspace_config.rgb_matrix_idle_anim ^= 1;
dprintf("RGB Matrix Idle Animation [EEPROM]: %u\n", userspace_config.rgb_matrix_idle_anim);
eeconfig_update_user(userspace_config.raw);
if (userspace_config.rgb_matrix_idle_anim) {
rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP);
}
if (userspace_config.rgb_matrix_idle_anim) { rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP); }
}
#endif
break;

View file

@ -28,7 +28,7 @@ void rgblight_sethsv_default_helper(uint8_t index) { rgblight_sethsv_at(rgblight
static rgblight_fadeout lights[RGBLED_NUM];
/* Handler for fading/twinkling effect */
void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgblight_sethsv is supppppper intensive
void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgblight_sethsv is supppppper intensive
bool litup = false;
for (uint8_t light_index = 0; light_index < RGBLED_NUM; ++light_index) {
@ -38,21 +38,15 @@ void scan_rgblight_fadeout(void) { // Don't effing change this function .... rg
if (light->life) {
light->life -= 1;
if (get_highest_layer(layer_state) == 0) {
sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]);
}
if (get_highest_layer(layer_state) == 0) { sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]); }
light->timer = sync_timer_read();
} else {
if (light->enabled && get_highest_layer(layer_state) == 0) {
rgblight_sethsv_default_helper(light_index);
}
if (light->enabled && get_highest_layer(layer_state) == 0) { rgblight_sethsv_default_helper(light_index); }
litup = light->enabled = false;
}
}
}
if (litup && get_highest_layer(layer_state) == 0) {
rgblight_set();
}
if (litup && get_highest_layer(layer_state) == 0) { rgblight_set(); }
}
/* Triggers a LED to fade/twinkle.
@ -98,9 +92,7 @@ void start_rgb_light(void) {
bool process_record_user_rgb_light(uint16_t keycode, keyrecord_t *record) {
uint16_t temp_keycode = keycode;
// Filter out the actual keycode from MT and LT keys.
if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
temp_keycode &= 0xFF;
}
if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { temp_keycode &= 0xFF; }
switch (temp_keycode) {
# ifdef RGBLIGHT_TWINKLE
@ -110,11 +102,9 @@ bool process_record_user_rgb_light(uint16_t keycode, keyrecord_t *record) {
case KC_KP_SLASH ... KC_KP_DOT:
case KC_F13 ... KC_F24:
case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
if (record->event.pressed) {
start_rgb_light();
}
if (record->event.pressed) { start_rgb_light(); }
break;
# endif // RGBLIGHT_TWINKLE
# endif // RGBLIGHT_TWINKLE
}
return true;
}
@ -129,9 +119,7 @@ static uint16_t rgblight_startup_loop_timer;
void keyboard_post_init_rgb_light(void) {
# if defined(RGBLIGHT_STARTUP_ANIMATION)
is_enabled = rgblight_is_enabled();
if (userspace_config.rgb_layer_change) {
rgblight_enable_noeeprom();
}
if (userspace_config.rgb_layer_change) { rgblight_enable_noeeprom(); }
if (rgblight_is_enabled()) {
layer_state_set_rgb_light(layer_state);
old_hue = rgblight_get_hue();
@ -145,7 +133,7 @@ void keyboard_post_init_rgb_light(void) {
void matrix_scan_rgb_light(void) {
# ifdef RGBLIGHT_TWINKLE
scan_rgblight_fadeout();
# endif // RGBLIGHT_ENABLE
# endif // RGBLIGHT_ENABLE
# if defined(RGBLIGHT_STARTUP_ANIMATION)
if (is_rgblight_startup && is_keyboard_master()) {
@ -156,12 +144,8 @@ void matrix_scan_rgb_light(void) {
rgblight_startup_loop_timer = sync_timer_read();
if (counter == 255) {
is_rgblight_startup = false;
if (!is_enabled) {
rgblight_disable_noeeprom();
}
if (userspace_config.rgb_layer_change) {
layer_state_set_rgb_light(layer_state);
}
if (!is_enabled) { rgblight_disable_noeeprom(); }
if (userspace_config.rgb_layer_change) { layer_state_set_rgb_light(layer_state); }
}
}
}
@ -179,55 +163,25 @@ layer_state_t layer_state_set_rgb_light(layer_state_t state) {
if (userspace_config.rgb_layer_change) {
switch (get_highest_layer(state | default_layer_state)) {
case _MACROS: // mouse
if (!layer_state_cmp(state, _GAMEPAD) && !layer_state_cmp(state, _DIABLO)) {
rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_BREATHING + 3);
}
break;
case _MEDIA:
rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_KNIGHT + 1);
break;
case _GAMEPAD:
rgblight_set_hsv_and_mode(HSV_ORANGE, RGBLIGHT_MODE_SNAKE + 2);
break;
case _DIABLO:
rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_BREATHING + 3);
break;
case _RAISE:
rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_BREATHING + 3);
break;
case _LOWER:
rgblight_set_hsv_and_mode(HSV_GREEN, RGBLIGHT_MODE_BREATHING + 3);
break;
case _ADJUST:
rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_KNIGHT + 2);
break;
case _COLEMAK:
rgblight_set_hsv_and_mode(HSV_MAGENTA, RGBLIGHT_MODE_STATIC_LIGHT);
break;
case _DVORAK:
rgblight_set_hsv_and_mode(HSV_SPRINGGREEN, RGBLIGHT_MODE_STATIC_LIGHT);
break;
case _WORKMAN:
rgblight_set_hsv_and_mode(HSV_GOLDENROD, RGBLIGHT_MODE_STATIC_LIGHT);
break;
case _NORMAN:
rgblight_set_hsv_and_mode(HSV_CORAL, RGBLIGHT_MODE_STATIC_LIGHT);
break;
case _MALTRON:
rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_STATIC_LIGHT);
break;
case _EUCALYN:
rgblight_set_hsv_and_mode(HSV_PINK, RGBLIGHT_MODE_STATIC_LIGHT);
break;
case _CARPLAX:
rgblight_set_hsv_and_mode(HSV_BLUE, RGBLIGHT_MODE_STATIC_LIGHT);
break;
default:
rgblight_set_hsv_and_mode(HSV_CYAN, RGBLIGHT_MODE_STATIC_LIGHT);
if (!layer_state_cmp(state, _GAMEPAD) && !layer_state_cmp(state, _DIABLO)) { rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_BREATHING + 3); }
break;
case _MEDIA: rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_KNIGHT + 1); break;
case _GAMEPAD: rgblight_set_hsv_and_mode(HSV_ORANGE, RGBLIGHT_MODE_SNAKE + 2); break;
case _DIABLO: rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_BREATHING + 3); break;
case _RAISE: rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_BREATHING + 3); break;
case _LOWER: rgblight_set_hsv_and_mode(HSV_GREEN, RGBLIGHT_MODE_BREATHING + 3); break;
case _ADJUST: rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_KNIGHT + 2); break;
case _COLEMAK: rgblight_set_hsv_and_mode(HSV_MAGENTA, RGBLIGHT_MODE_STATIC_LIGHT); break;
case _DVORAK: rgblight_set_hsv_and_mode(HSV_SPRINGGREEN, RGBLIGHT_MODE_STATIC_LIGHT); break;
case _WORKMAN: rgblight_set_hsv_and_mode(HSV_GOLDENROD, RGBLIGHT_MODE_STATIC_LIGHT); break;
case _NORMAN: rgblight_set_hsv_and_mode(HSV_CORAL, RGBLIGHT_MODE_STATIC_LIGHT); break;
case _MALTRON: rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_STATIC_LIGHT); break;
case _EUCALYN: rgblight_set_hsv_and_mode(HSV_PINK, RGBLIGHT_MODE_STATIC_LIGHT); break;
case _CARPLAX: rgblight_set_hsv_and_mode(HSV_BLUE, RGBLIGHT_MODE_STATIC_LIGHT); break;
default: rgblight_set_hsv_and_mode(HSV_CYAN, RGBLIGHT_MODE_STATIC_LIGHT); break;
}
}
# endif // RGBLIGHT_ENABLE
# endif // RGBLIGHT_ENABLE
return state;
}

View file

@ -80,28 +80,29 @@ endif
CUSTOM_SPLIT_TRANSPORT ?= yes
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
ifneq ($(strip $(SPLIT_TRANSPORT)), custom)
ifeq ($(strip $(CUSTOM_SPLIT_TRANSPORT)), yes)
SPLIT_TRANSPORT = custom
QUANTUM_LIB_SRC += drashna_transport.c
OPT_DEFS += -DDRASHNA_CUSTOM_TRANSPORT
# Unused functions are pruned away, which is why we can add multiple drivers here without bloat.
ifeq ($(PLATFORM),AVR)
ifneq ($(NO_I2C),yes)
QUANTUM_LIB_SRC += i2c_master.c \
i2c_slave.c
endif
endif
QUANTUM_LIB_SRC += transport_sync.c
# ifneq ($(strip $(SPLIT_TRANSPORT)), custom)
# ifeq ($(strip $(CUSTOM_SPLIT_TRANSPORT)), yes)
# SPLIT_TRANSPORT = custom
# QUANTUM_LIB_SRC += drashna_transport.c
# OPT_DEFS += -DDRASHNA_CUSTOM_TRANSPORT
# # Unused functions are pruned away, which is why we can add multiple drivers here without bloat.
# ifeq ($(PLATFORM),AVR)
# ifneq ($(NO_I2C),yes)
# QUANTUM_LIB_SRC += i2c_master.c \
# i2c_slave.c
# endif
# endif
SERIAL_DRIVER ?= bitbang
OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
QUANTUM_LIB_SRC += serial.c
else
QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
endif
endif
endif
# SERIAL_DRIVER ?= bitbang
# OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
# ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
# QUANTUM_LIB_SRC += serial.c
# else
# QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
# endif
# endif
# endif
endif
# DEBUG_MATRIX_SCAN_RATE_ENABLE = api

View file

@ -26,7 +26,7 @@ uint8_t diablo_times[] = {0, 1, 3, 5, 10, 30};
// Cycle through the times for the macro, starting at 0, for disabled.
void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) {
diable_keys_t *diablo_keys = (diable_keys_t *)user_data;
diable_keys_t *diablo_keys = (diable_keys_t *)user_data;
// Sets the keycode based on the index
diablo_timer[diablo_keys->index].keycode = diablo_keys->keycode;
@ -34,7 +34,7 @@ void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) {
if (state->count >= (sizeof(diablo_times) / sizeof(uint8_t))) {
diablo_timer[diablo_keys->index].key_interval = 0;
reset_tap_dance(state);
} else { // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
} else { // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
diablo_timer[diablo_keys->index].key_interval = diablo_times[state->count - 1];
}
}
@ -64,9 +64,7 @@ void run_diablo_macro_check(void) {
// reset the timer, since enough time has passed
diablo_timer[index].timer = timer_read();
// send keycode ONLY if we're on the diablo layer.
if (IS_LAYER_ON(_DIABLO)) {
tap_code(diablo_timer[index].keycode);
}
if (IS_LAYER_ON(_DIABLO)) { tap_code(diablo_timer[index].keycode); }
}
}
}

View file

@ -43,4 +43,4 @@ enum {
TD_D3_4
};
// clang-format on
#endif // TAP_DANCE_ENABLE
#endif // TAP_DANCE_ENABLE

View file

@ -54,9 +54,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
break;
case VRSN:
if (record->event.pressed) {
SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
if (record->event.pressed) { SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); }
return false;
break;
}
@ -89,7 +87,7 @@ __attribute__((weak)) void startup_keymap(void) {}
void startup_user(void) {
#ifdef RGBLIGHT_ENABLE
matrix_init_rgb();
#endif // RGBLIGHT_ENABLE
#endif // RGBLIGHT_ENABLE
startup_keymap();
}

View file

@ -24,8 +24,8 @@
#define BASE 0
enum custom_keycodes {
VRSN = SAFE_RANGE, // can always be here
VRSN = SAFE_RANGE, // can always be here
KC_MAKE,
KC_RESET,
NEWPLACEHOLDER // use "NEWPLACEHOLDER for keymap specific codes
NEWPLACEHOLDER // use "NEWPLACEHOLDER for keymap specific codes
};

View file

@ -0,0 +1,80 @@
#ifdef SPLIT_TRANSACTION_IDS_USER
#include "transport_sync.h"
#include "transactions.h"
#include <string.h>
typedef struct {
bool oled_on;
uint16_t keymap_config;
} user_runtime_config_t;
user_runtime_config_t user_state;
void user_sync(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
if (initiator2target_buffer_size == sizeof(user_state)) {
memcpy(&user_state, initiator2target_buffer, initiator2target_buffer_size);
}
}
void keyboard_post_init_transport_sync(void) {
// Register keyboard state sync split transaction
transaction_register_rpc(RPC_ID_USER_STATE_SYNC, user_sync);
}
void user_state_update(void) {
if (is_keyboard_master()) {
#ifdef OLED_DRIVER_ENABLE
user_state.oled_on = is_oled_on();
#endif
user_state.keymap_config = keymap_config.raw;
} else {
#ifdef OLED_DRIVER_ENABLE
if (user_state.oled_on) {
oled_on();
} else {
oled_off();
}
#endif
if (keymap_config.raw != user_state.keymap_config) {
keymap_config.raw = user_state.keymap_config;
}
}
}
void user_state_sync(void) {
if (is_keyboard_master()) {
// Keep track of the last state, so that we can tell if we need to propagate to slave
static user_runtime_config_t last_user_state;
static uint32_t last_sync;
bool needs_sync = false;
// Check if the state values are different
if (memcmp(&user_state, &last_user_state, sizeof(user_state))) {
needs_sync = true;
memcpy(&last_user_state, &user_state, sizeof(user_state));
}
// Send to slave every 500ms regardless of state change
if (timer_elapsed32(last_sync) > 250) {
needs_sync = true;
}
// Perform the sync if requested
if (needs_sync) {
if (transaction_rpc_send(RPC_ID_USER_STATE_SYNC, sizeof(user_state), &user_state)) {
last_sync = timer_read32();
}
}
}
}
void housekeeping_task_user(void) {
// Update kb_state so we can send to slave
user_state_update();
// Data sync from master to slave
user_state_sync();
}
#endif

View file

@ -1,3 +1,4 @@
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
*
* This program is free software: you can redistribute it and/or modify
@ -14,9 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "drashna.h"
#include "../drashna/config.h"
void keyboard_post_init_transport_sync(void);