mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-06-04 23:42:46 +00:00
Merge remote-tracking branch 'upstream/develop' into xap
This commit is contained in:
commit
55baed3380
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@ -45,7 +45,7 @@ jobs:
|
||||
stale-pr-label: stale
|
||||
days-before-pr-stale: 45
|
||||
days-before-pr-close: 30
|
||||
exempt-pr-labels: bug,awaiting review,breaking_change,in progress,on hold
|
||||
exempt-pr-labels: bug,awaiting review,breaking_change,in progress,on hold,needs-core-wireless,crippled-firmware
|
||||
|
||||
stale-pr-message: >
|
||||
Thank you for your contribution!
|
||||
|
@ -1626,9 +1626,15 @@
|
||||
"buzzard": {
|
||||
"target": "buzzard/rev1"
|
||||
},
|
||||
"cannonkeys/db60": {
|
||||
"target": "cannonkeys/db60/rev2"
|
||||
},
|
||||
"clickety_split/leeloo": {
|
||||
"target": "clickety_split/leeloo/rev3"
|
||||
},
|
||||
"converter/palm_usb": {
|
||||
"target": "converter/palm_usb/stowaway"
|
||||
},
|
||||
"crkbd": {
|
||||
"target": "crkbd/rev1"
|
||||
},
|
||||
@ -1713,6 +1719,9 @@
|
||||
"handwired/dactyl_manuform/6x6": {
|
||||
"target": "handwired/dactyl_manuform/6x6/promicro"
|
||||
},
|
||||
"handwired/meck_tkl": {
|
||||
"target": "handwired/meck_tkl/blackpill_f401"
|
||||
},
|
||||
"handwired/ms_sculpt_mobile": {
|
||||
"target": "handwired/ms_sculpt_mobile/teensy2pp"
|
||||
},
|
||||
@ -1752,6 +1761,9 @@
|
||||
"hillside/46": {
|
||||
"target": "hillside/46/0_1"
|
||||
},
|
||||
"hhkb/ansi": {
|
||||
"target": "hhkb/ansi/32u4"
|
||||
},
|
||||
"hillside/48": {
|
||||
"target": "hillside/48/0_1"
|
||||
},
|
||||
@ -1797,6 +1809,9 @@
|
||||
"kakunpc/angel17": {
|
||||
"target": "kakunpc/angel17/rev1"
|
||||
},
|
||||
"kakunpc/angel64": {
|
||||
"target": "kakunpc/angel64/rev1"
|
||||
},
|
||||
"kakunpc/business_card": {
|
||||
"target": "kakunpc/business_card/beta"
|
||||
},
|
||||
@ -2148,6 +2163,9 @@
|
||||
"takashiski/namecard2x4": {
|
||||
"target": "takashiski/namecard2x4/rev2"
|
||||
},
|
||||
"teleport/native": {
|
||||
"target": "teleport/native/iso"
|
||||
},
|
||||
"themadnoodle/noodlepad": {
|
||||
"target": "themadnoodle/noodlepad/v1"
|
||||
},
|
||||
@ -2181,6 +2199,21 @@
|
||||
"vitamins_included": {
|
||||
"target": "vitamins_included/rev2"
|
||||
},
|
||||
"westm/westm68": {
|
||||
"target": "westm/westm68/rev2"
|
||||
},
|
||||
"westm/westm9": {
|
||||
"target": "westm/westm9/rev2"
|
||||
},
|
||||
"woodkeys/meira": {
|
||||
"target": "woodkeys/meira/promicro"
|
||||
},
|
||||
"work_louder/loop": {
|
||||
"target": "work_louder/loop/rev3"
|
||||
},
|
||||
"work_louder/work_board": {
|
||||
"target": "work_louder/work_board/rev3"
|
||||
},
|
||||
"yanghu/unicorne": {
|
||||
"target": "yanghu/unicorne/f411"
|
||||
},
|
||||
@ -2195,5 +2228,8 @@
|
||||
},
|
||||
"yynmt/acperience12": {
|
||||
"target": "yynmt/acperience12/rev1"
|
||||
},
|
||||
"zsa/planck_ez": {
|
||||
"target": "zsa/planck_ez/base"
|
||||
}
|
||||
}
|
||||
|
218
drivers/painter/sh1107/qp_sh1107.c
Normal file
218
drivers/painter/sh1107/qp_sh1107.c
Normal file
@ -0,0 +1,218 @@
|
||||
#include "qp_internal.h"
|
||||
#include "qp_comms.h"
|
||||
#include "qp_surface_internal.h"
|
||||
#include "qp_oled_panel.h"
|
||||
#include "qp_sh1107.h"
|
||||
#include "qp_sh1107_opcodes.h"
|
||||
#include "qp_surface.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Driver storage
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct sh1107_device_t {
|
||||
oled_panel_painter_device_t oled;
|
||||
|
||||
uint8_t framebuffer[SURFACE_REQUIRED_BUFFER_BYTE_SIZE(128, 128, 1)];
|
||||
} sh1107_device_t;
|
||||
|
||||
static sh1107_device_t sh1107_drivers[SH1107_NUM_DEVICES] = {0};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Quantum Painter API implementations
|
||||
|
||||
// Initialisation
|
||||
__attribute__((weak)) bool qp_sh1107_init(painter_device_t device, painter_rotation_t rotation) {
|
||||
sh1107_device_t *driver = (sh1107_device_t *)device;
|
||||
|
||||
// Change the surface geometry based on the panel rotation
|
||||
if (rotation == QP_ROTATION_90 || rotation == QP_ROTATION_270) {
|
||||
driver->oled.surface.base.panel_width = driver->oled.base.panel_height;
|
||||
driver->oled.surface.base.panel_height = driver->oled.base.panel_width;
|
||||
} else {
|
||||
driver->oled.surface.base.panel_width = driver->oled.base.panel_width;
|
||||
driver->oled.surface.base.panel_height = driver->oled.base.panel_height;
|
||||
}
|
||||
|
||||
// Init the internal surface
|
||||
if (!qp_init(&driver->oled.surface.base, QP_ROTATION_0)) {
|
||||
qp_dprintf("Failed to init internal surface in qp_sh1107_init\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
uint8_t sh1107_init_sequence[] = {
|
||||
// Command, Delay, N, Data[N]
|
||||
SH1107_SET_MUX_RATIO, 0, 1, 0x7F, // 1/128 duty
|
||||
SH1107_DISPLAY_OFFSET, 0, 1, 0x00,
|
||||
SH1107_SET_START_LINE, 0, 1, 0x00, // Different from SH1106
|
||||
SH1107_SET_SEGMENT_REMAP_INV, 0, 0,
|
||||
SH1107_COM_SCAN_DIR_DEC, 0, 0,
|
||||
SH1107_COM_PADS_HW_CFG, 0, 1, 0x12,
|
||||
SH1107_SET_CONTRAST, 0, 1, 0x7F,
|
||||
SH1107_ALL_ON_RESUME, 0, 0,
|
||||
SH1107_NON_INVERTING_DISPLAY, 0, 0,
|
||||
SH1107_SET_OSC_DIVFREQ, 0, 1, 0x80,
|
||||
SH1107_SET_CHARGE_PUMP, 0, 1, 0x14,
|
||||
SH1107_DISPLAY_ON, 0, 0,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// If the display width is anything other than the default 128 pixels, change SH1107_SET_MUX_RATIO data byte to the correct value.
|
||||
if (driver->oled.base.panel_width != 128) {
|
||||
sh1107_init_sequence[3] = driver->oled.base.panel_width - 1;
|
||||
}
|
||||
|
||||
// If the display width is less than the default 128 pixels, change SH1107_DISPLAY_OFFSET to use the center columns.
|
||||
if (driver->oled.base.panel_width < 128) {
|
||||
sh1107_init_sequence[7] = (128U - driver->oled.base.panel_width) / 2;
|
||||
}
|
||||
|
||||
// For smaller displays, change SH1107_COM_PADS_HW_CFG data byte from alternative (0x12) to sequential (0x02) configuration
|
||||
if (driver->oled.base.panel_height <= 64) {
|
||||
sh1107_init_sequence[20] = 0x02;
|
||||
}
|
||||
|
||||
qp_comms_bulk_command_sequence(device, sh1107_init_sequence, sizeof(sh1107_init_sequence));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Screen flush
|
||||
bool qp_sh1107_flush(painter_device_t device) {
|
||||
sh1107_device_t *driver = (sh1107_device_t *)device;
|
||||
|
||||
if (!driver->oled.surface.dirty.is_dirty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (driver->oled.base.rotation) {
|
||||
default:
|
||||
case QP_ROTATION_0:
|
||||
qp_oled_panel_page_column_flush_rot0(device, &driver->oled.surface.dirty, driver->framebuffer);
|
||||
break;
|
||||
case QP_ROTATION_90:
|
||||
qp_oled_panel_page_column_flush_rot90(device, &driver->oled.surface.dirty, driver->framebuffer);
|
||||
break;
|
||||
case QP_ROTATION_180:
|
||||
qp_oled_panel_page_column_flush_rot180(device, &driver->oled.surface.dirty, driver->framebuffer);
|
||||
break;
|
||||
case QP_ROTATION_270:
|
||||
qp_oled_panel_page_column_flush_rot270(device, &driver->oled.surface.dirty, driver->framebuffer);
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear the dirty area
|
||||
qp_flush(&driver->oled.surface);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Driver vtable
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const oled_panel_painter_driver_vtable_t sh1107_driver_vtable = {
|
||||
.base =
|
||||
{
|
||||
.init = qp_sh1107_init,
|
||||
.power = qp_oled_panel_power,
|
||||
.clear = qp_oled_panel_clear,
|
||||
.flush = qp_sh1107_flush,
|
||||
.pixdata = qp_oled_panel_passthru_pixdata,
|
||||
.viewport = qp_oled_panel_passthru_viewport,
|
||||
.palette_convert = qp_oled_panel_passthru_palette_convert,
|
||||
.append_pixels = qp_oled_panel_passthru_append_pixels,
|
||||
.append_pixdata = qp_oled_panel_passthru_append_pixdata,
|
||||
},
|
||||
.opcodes =
|
||||
{
|
||||
.display_on = SH1107_DISPLAY_ON,
|
||||
.display_off = SH1107_DISPLAY_OFF,
|
||||
.set_page = SH1107_PAGE_ADDR,
|
||||
.set_column_lsb = SH1107_SETCOLUMN_LSB,
|
||||
.set_column_msb = SH1107_SETCOLUMN_MSB,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef QUANTUM_PAINTER_SH1107_SPI_ENABLE
|
||||
// Factory function for creating a handle to the SH1107 device
|
||||
painter_device_t qp_sh1107_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode) {
|
||||
for (uint32_t i = 0; i < SH1107_NUM_DEVICES; ++i) {
|
||||
sh1107_device_t *driver = &sh1107_drivers[i];
|
||||
if (!driver->oled.base.driver_vtable) {
|
||||
painter_device_t surface = qp_make_mono1bpp_surface_advanced(&driver->oled.surface, 1, panel_width, panel_height, driver->framebuffer);
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Setup the OLED device
|
||||
driver->oled.base.driver_vtable = (const painter_driver_vtable_t *)&sh1107_driver_vtable;
|
||||
driver->oled.base.comms_vtable = (const painter_comms_vtable_t *)&spi_comms_with_dc_vtable;
|
||||
driver->oled.base.native_bits_per_pixel = 1; // 1bpp mono
|
||||
driver->oled.base.panel_width = panel_width;
|
||||
driver->oled.base.panel_height = panel_height;
|
||||
driver->oled.base.rotation = QP_ROTATION_0;
|
||||
driver->oled.base.offset_x = 0;
|
||||
driver->oled.base.offset_y = 0;
|
||||
|
||||
// SPI and other pin configuration
|
||||
driver->oled.base.comms_config = &driver->oled.spi_dc_reset_config;
|
||||
driver->oled.spi_dc_reset_config.spi_config.chip_select_pin = chip_select_pin;
|
||||
driver->oled.spi_dc_reset_config.spi_config.divisor = spi_divisor;
|
||||
driver->oled.spi_dc_reset_config.spi_config.lsb_first = false;
|
||||
driver->oled.spi_dc_reset_config.spi_config.mode = spi_mode;
|
||||
driver->oled.spi_dc_reset_config.dc_pin = dc_pin;
|
||||
driver->oled.spi_dc_reset_config.reset_pin = reset_pin;
|
||||
driver->oled.spi_dc_reset_config.command_params_uses_command_pin = true;
|
||||
|
||||
if (!qp_internal_register_device((painter_device_t)driver)) {
|
||||
memset(driver, 0, sizeof(sh1107_device_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (painter_device_t)driver;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // QUANTUM_PAINTER_SH1107_SPI_ENABLE
|
||||
|
||||
#ifdef QUANTUM_PAINTER_SH1107_I2C_ENABLE
|
||||
// Factory function for creating a handle to the SH1107 device
|
||||
painter_device_t qp_sh1107_make_i2c_device(uint16_t panel_width, uint16_t panel_height, uint8_t i2c_address) {
|
||||
for (uint32_t i = 0; i < SH1107_NUM_DEVICES; ++i) {
|
||||
sh1107_device_t *driver = &sh1107_drivers[i];
|
||||
if (!driver->oled.base.driver_vtable) {
|
||||
// Instantiate the surface
|
||||
painter_device_t surface = qp_make_mono1bpp_surface_advanced(&driver->oled.surface, 1, panel_width, panel_height, driver->framebuffer);
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Setup the OLED device
|
||||
driver->oled.base.driver_vtable = (const painter_driver_vtable_t *)&sh1107_driver_vtable;
|
||||
driver->oled.base.comms_vtable = (const painter_comms_vtable_t *)&i2c_comms_cmddata_vtable;
|
||||
driver->oled.base.native_bits_per_pixel = 1; // 1bpp mono
|
||||
driver->oled.base.panel_width = panel_width;
|
||||
driver->oled.base.panel_height = panel_height;
|
||||
driver->oled.base.rotation = QP_ROTATION_0;
|
||||
driver->oled.base.offset_x = 0;
|
||||
driver->oled.base.offset_y = 0;
|
||||
|
||||
// I2C configuration
|
||||
driver->oled.base.comms_config = &driver->oled.i2c_config;
|
||||
driver->oled.i2c_config.chip_address = i2c_address;
|
||||
|
||||
if (!qp_internal_register_device((painter_device_t)driver)) {
|
||||
memset(driver, 0, sizeof(sh1107_device_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (painter_device_t)driver;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // QUANTUM_PAINTER_SH1107_I2C_ENABLE
|
64
drivers/painter/sh1107/qp_sh1107.h
Normal file
64
drivers/painter/sh1107/qp_sh1107.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include "gpio.h"
|
||||
#include "qp_internal.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Quantum Painter SH1107 configurables (add to your keyboard's config.h)
|
||||
|
||||
#if defined(QUANTUM_PAINTER_SH1107_SPI_ENABLE) && !defined(SH1107_NUM_SPI_DEVICES)
|
||||
/**
|
||||
* @def This controls the maximum number of SPI SH1107 devices that Quantum Painter can communicate with at any one time.
|
||||
* Increasing this number allows for multiple displays to be used.
|
||||
*/
|
||||
# define SH1107_NUM_SPI_DEVICES 1
|
||||
#else
|
||||
# define SH1107_NUM_SPI_DEVICES 0
|
||||
#endif
|
||||
|
||||
#if defined(QUANTUM_PAINTER_SH1107_I2C_ENABLE) && !defined(SH1107_NUM_I2C_DEVICES)
|
||||
/**
|
||||
* @def This controls the maximum number of I2C SH1107 devices that Quantum Painter can communicate with at any one time.
|
||||
* Increasing this number allows for multiple displays to be used.
|
||||
*/
|
||||
# define SH1107_NUM_I2C_DEVICES 1
|
||||
#else
|
||||
# define SH1107_NUM_I2C_DEVICES 0
|
||||
#endif
|
||||
|
||||
#define SH1107_NUM_DEVICES ((SH1107_NUM_SPI_DEVICES) + (SH1107_NUM_I2C_DEVICES))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Quantum Painter SH1107 device factories
|
||||
|
||||
#ifdef QUANTUM_PAINTER_SH1107_SPI_ENABLE
|
||||
|
||||
/**
|
||||
* Factory method for an SH1107 SPI LCD device.
|
||||
*
|
||||
* @param panel_width[in] the width of the display in pixels (usually 64)
|
||||
* @param panel_height[in] the height of the display in pixels (usually 128)
|
||||
* @param chip_select_pin[in] the GPIO pin used for SPI chip select
|
||||
* @param dc_pin[in] the GPIO pin used for D/C control
|
||||
* @param reset_pin[in] the GPIO pin used for RST
|
||||
* @param spi_divisor[in] the SPI divisor to use when communicating with the display
|
||||
* @param spi_mode[in] the SPI mode to use when communicating with the display
|
||||
* @return the device handle used with all drawing routines in Quantum Painter
|
||||
*/
|
||||
painter_device_t qp_sh1107_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode);
|
||||
|
||||
#endif // QUANTUM_PAINTER_SH1107_SPI_ENABLE
|
||||
|
||||
#ifdef QUANTUM_PAINTER_SH1107_I2C_ENABLE
|
||||
|
||||
/**
|
||||
* Factory method for an SH1107 I2C LCD device.
|
||||
*
|
||||
* @param panel_width[in] the width of the display in pixels (usually 64)
|
||||
* @param panel_height[in] the height of the display in pixels (usually 128)
|
||||
* @param i2c_address[in] the I2C address to use
|
||||
* @return the device handle used with all drawing routines in Quantum Painter
|
||||
*/
|
||||
painter_device_t qp_sh1107_make_i2c_device(uint16_t panel_width, uint16_t panel_height, uint8_t i2c_address);
|
||||
|
||||
#endif // QUANTUM_PAINTER_SH1107_I2C_ENABLE
|
25
drivers/painter/sh1107/qp_sh1107_opcodes.h
Normal file
25
drivers/painter/sh1107/qp_sh1107_opcodes.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2024 Steve Branam (@smbranam)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#define SH1107_DISPLAY_ON 0xAF
|
||||
#define SH1107_DISPLAY_OFF 0xAE
|
||||
#define SH1107_SET_OSC_DIVFREQ 0xD5
|
||||
#define SH1107_SET_MUX_RATIO 0xA8
|
||||
#define SH1107_DISPLAY_OFFSET 0xD3
|
||||
#define SH1107_SET_START_LINE 0xDC // Key/sole difference from SH1106 (which uses 0x40)
|
||||
#define SH1107_SET_CHARGE_PUMP 0x8D
|
||||
#define SH1107_SET_SEGMENT_REMAP_NORMAL 0xA0
|
||||
#define SH1107_SET_SEGMENT_REMAP_INV 0xA1
|
||||
#define SH1107_COM_SCAN_DIR_INC 0xC0
|
||||
#define SH1107_COM_SCAN_DIR_DEC 0xC8
|
||||
#define SH1107_COM_PADS_HW_CFG 0xDA
|
||||
#define SH1107_SET_CONTRAST 0x81
|
||||
#define SH1107_SET_PRECHARGE_PERIOD 0xD9
|
||||
#define SH1107_VCOM_DESELECT_LEVEL 0xDB
|
||||
#define SH1107_ALL_ON_RESUME 0xA4
|
||||
#define SH1107_NON_INVERTING_DISPLAY 0xA6
|
||||
#define SH1107_DEACTIVATE_SCROLL 0x2E
|
||||
#define SH1107_SETCOLUMN_LSB 0x00
|
||||
#define SH1107_SETCOLUMN_MSB 0x10
|
||||
#define SH1107_PAGE_ADDR 0xB0
|
@ -20,7 +20,7 @@
|
||||
},
|
||||
"indicators": {
|
||||
"caps_lock": "A9",
|
||||
"num_lock": "A10"
|
||||
"scroll_lock": "A10"
|
||||
},
|
||||
"matrix_pins": {
|
||||
"cols": ["B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", "B11", "B12", "B13"],
|
||||
|
@ -25,19 +25,19 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT(
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SCRL, KC_PAUS, KC_MUTE,
|
||||
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_PAUS, KC_DEL, KC_MUTE,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP,
|
||||
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END,
|
||||
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
|
||||
),
|
||||
[1] = LAYOUT(
|
||||
_______, KC_MSEL, KC_VOLD, KC_VOLU, KC_MUTE, KC_MSTP, KC_MPRV, KC_MPLY, KC_MNXT, KC_MAIL, KC_WHOM, KC_MYCM, KC_CALC, _______, _______, _______, _______,
|
||||
_______, KC_MSEL, KC_VOLD, KC_VOLU, KC_MUTE, KC_MSTP, KC_MPRV, KC_MPLY, KC_MNXT, KC_MAIL, KC_WHOM, KC_MYCM, KC_CALC, _______, _______, KC_SCRL, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_END,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PSCR,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_SCRL,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, GU_TOGG, _______, _______, _______, _______, _______, _______, _______, _______
|
||||
)
|
||||
};
|
@ -1,8 +1,8 @@
|
||||
# A-JAZZ AKC084
|
||||
# A-JAZZ AKC084 (AKP846)
|
||||
|
||||
A customizable 84keys keyboard
|
||||
|
||||

|
||||

|
||||
* Keyboard Maintainer: [Feng](https://github.com/fenggx-a-jazz)
|
||||
* Hardware Supported: [a-jazz](https://www.a-jazz.com)
|
||||
* Hardware Availability: [a-jazz](https://ajazzstore.com/collections/all/products/ajazz-akp846)
|
||||
@ -18,6 +18,6 @@ Flashing example for this keyboard:
|
||||
See the build environment setup and the make instructions for more information. Brand new to QMK? Start with our Complete Newbs Guide.
|
||||
|
||||
## Bootloader ESC the bootloader in 3 ways:
|
||||
* **Bootmagic reset: Hold down Enter in the keyboard then replug
|
||||
* **Bootmagic reset: Hold down Esc in the keyboard then replug
|
||||
* **Physical reset button: Briefly press the button on the back of the PCB
|
||||
* **Keycode in layout: Press the key mapped to QK_BOOT
|
||||
|
@ -1,7 +1,5 @@
|
||||
# TriangleLabs AL1
|
||||
|
||||

|
||||
|
||||
* Keyboard Maintainer: [MechMerlin](https://github.com/mechmerlin), [Olivia](https://github.com/olivia)
|
||||
* Hardware Supported: AL1 PCB
|
||||
* Hardware Availability: [GroupBuy](https://geekhack.org/index.php?topic=93258.0)
|
||||
|
@ -1,7 +1,5 @@
|
||||
# dc60
|
||||
|
||||

|
||||
|
||||
A 60% PCB sold with the Alf DC60.
|
||||
|
||||
Keyboard Maintainer: [MechMerlin](https://github.com/mechmerlin)
|
||||
|
@ -5,8 +5,7 @@
|
||||
meishi2 - The better micro macro keyboard
|
||||
|
||||
Keyboard Maintainer: [Biacco42](https://github.com/Biacco42)
|
||||
Hardware Supported: The PCBs, controllers supported
|
||||
Hardware Availability: [links to where you can find this hardware](https://github.com/Biacco42/meishi2)
|
||||
Hardware Availability: https://github.com/Biacco42/meishi2
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
# unloved_bastard
|
||||
|
||||

|
||||
|
||||
A short description of the keyboard/project
|
||||
|
||||
Keyboard Maintainer: [Alexander Fougner](https://github.com/fougner)
|
||||
Hardware Supported: CoolerMaster Masterkeys S PBT (Not the Pro versions with backlighting etc)
|
||||
Hardware Availability: Pretty much anywhere
|
||||
|
@ -1,4 +1,2 @@
|
||||
# Wildcard to allow APM32 MCU
|
||||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF
|
||||
|
||||
DEFAULT_FOLDER = westm/westm9/rev2
|
@ -1,4 +1,2 @@
|
||||
# Wildcard to allow APM32 MCU
|
||||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF
|
||||
|
||||
DEFAULT_FOLDER = westm/westm68/rev2
|
@ -1,4 +1,2 @@
|
||||
# Wildcard to allow APM32 MCU
|
||||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF
|
||||
|
||||
DEFAULT_FOLDER = cannonkeys/db60/rev2
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"keyboard_name": "Stowaway Converter",
|
||||
"manufacturer": "QMK",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"usb": {
|
||||
"vid": "0xFEED",
|
||||
"pid": "0x0001",
|
||||
"device_version": "1.0.0"
|
||||
},
|
||||
"processor": "atmega32u4",
|
||||
"bootloader": "caterina",
|
||||
"features": {
|
||||
"bootmagic": false,
|
||||
"mousekey": false,
|
||||
"extrakey": false,
|
||||
"console": true,
|
||||
"command": true
|
||||
}
|
||||
}
|
@ -1,4 +1,22 @@
|
||||
{
|
||||
"keyboard_name": "Stowaway Converter",
|
||||
"manufacturer": "QMK",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"usb": {
|
||||
"vid": "0xFEED",
|
||||
"pid": "0x0001",
|
||||
"device_version": "1.0.0"
|
||||
},
|
||||
"processor": "atmega32u4",
|
||||
"bootloader": "caterina",
|
||||
"features": {
|
||||
"bootmagic": false,
|
||||
"mousekey": false,
|
||||
"extrakey": false,
|
||||
"console": true,
|
||||
"command": true
|
||||
},
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"layout": [
|
||||
|
@ -3,5 +3,3 @@ CUSTOM_MATRIX = yes
|
||||
|
||||
SRC += matrix.c
|
||||
UART_DRIVER_REQUIRED = yes
|
||||
|
||||
DEFAULT_FOLDER = converter/palm_usb/stowaway
|
@ -28,7 +28,7 @@ git clone のあと、
|
||||
|
||||
-----------------
|
||||
## English
|
||||
- [Here](https://github.com/telzo2000/cool836A) are a full description of this project and build guide by the great Designer: [m.ki](imgur.com image replace me!)
|
||||
- [Here](https://github.com/telzo2000/cool836A) are a full description of this project and build guide by the great Designer: m.ki
|
||||
|
||||
- Each virsions(A, B+, C+) of cool836A has the same circuit and that means you can install this firmware on any of them.
|
||||
- However, this repository is currently(Jan 7, 2021) tested on ver.B+ (RED version) only. Feel free to contact [ME](https://github.com/ketcha-k) for any problems.
|
||||
|
@ -1,15 +1,10 @@
|
||||
# deltapad
|
||||
|
||||
|
||||
|
||||
*A short description of the keyboard/project*
|
||||
|
||||
A 4x4 keypad
|
||||
|
||||
* Keyboard Maintainer: [Richard Snijder](https://github.com/rich239)
|
||||
* Hardware Supported: Atmel 32u4 based keypads
|
||||
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make deltapad:default
|
||||
|
@ -1,7 +1,5 @@
|
||||
# Jetfire
|
||||
|
||||

|
||||
|
||||
The Duck Jetfire is a hybrid full size and 1800 layout keyboard that went on
|
||||
Group Buy in November 2017.
|
||||
|
||||
|
@ -13,7 +13,6 @@ A modified version of the through hole 65% Discipline keyboard by cftkb.
|
||||
Other Information:
|
||||
|
||||
* Keyboard Maintainer: [ELau](https://github.com/ericrlau)
|
||||
* Hardware Supported: The PCBs, controllers supported
|
||||
* Hardware Availability: https://github.com/ericrlau/NumDiscipline
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
@ -25,7 +25,6 @@ Choose any key from the corrosponding row and column and solder it to the pin on
|
||||
_NOTE: Some of the keys had mislabled columns and rows, so make sure the columns are all connected without diodes to one another, and that the rows are soldered after the diode_
|
||||
|
||||
* Keyboard Maintainer: [NaCly](https://github.com/Na-Cly)
|
||||
* Hardware Supported: The PCBs, controllers supported
|
||||
* Hardware Availability: Leopold FC200RT + Teensy 2.0
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
2
keyboards/handwired/meck_tkl/blackpill_f401/rules.mk
Normal file
2
keyboards/handwired/meck_tkl/blackpill_f401/rules.mk
Normal file
@ -0,0 +1,2 @@
|
||||
AUDIO_SUPPORTED = no
|
||||
BACKLIGHT_SUPPORTED = no
|
@ -1,4 +0,0 @@
|
||||
AUDIO_SUPPORTED = no
|
||||
BACKLIGHT_SUPPORTED = no
|
||||
|
||||
DEFAULT_FOLDER = handwired/meck_tkl/blackpill_f401
|
@ -2,8 +2,6 @@
|
||||
|
||||

|
||||
|
||||
A short description of the keyboard/project
|
||||
|
||||
* Keyboard Maintainer: [Jose I. Martinez](https://github.com/mechanicalguy21)
|
||||
* Hardware Supported: This is a handwired keyboard created over a 3d printed case.
|
||||
STL will be shared soon.
|
||||
|
@ -2,5 +2,3 @@ CUSTOM_MATRIX = yes
|
||||
|
||||
# project specific files
|
||||
SRC = matrix.c
|
||||
|
||||
DEFAULT_FOLDER = hhkb/ansi/32u4
|
4
keyboards/hhkb/ansi/32u4/rules.mk
Normal file
4
keyboards/hhkb/ansi/32u4/rules.mk
Normal file
@ -0,0 +1,4 @@
|
||||
CUSTOM_MATRIX = yes
|
||||
|
||||
# project specific files
|
||||
SRC = matrix.c
|
@ -1,7 +1,5 @@
|
||||
# h75_singa
|
||||
|
||||
 - TBD
|
||||
|
||||
New 75% PCB for Singa Keyboards
|
||||
|
||||
* Keyboard Maintainer: [hineybush](https://github.com/hineybush)
|
||||
|
3
keyboards/kakunpc/angel64/alpha/rules.mk
Normal file
3
keyboards/kakunpc/angel64/alpha/rules.mk
Normal file
@ -0,0 +1,3 @@
|
||||
CUSTOM_MATRIX = yes
|
||||
|
||||
SRC += matrix.c
|
3
keyboards/kakunpc/angel64/rev1/rules.mk
Normal file
3
keyboards/kakunpc/angel64/rev1/rules.mk
Normal file
@ -0,0 +1,3 @@
|
||||
CUSTOM_MATRIX = yes
|
||||
|
||||
SRC += matrix.c
|
@ -1,5 +0,0 @@
|
||||
CUSTOM_MATRIX = yes
|
||||
|
||||
SRC += matrix.c
|
||||
|
||||
DEFAULT_FOLDER = kakunpc/angel64/rev1
|
@ -1,12 +1,6 @@
|
||||
# business_card
|
||||
|
||||

|
||||
|
||||
A short description of the keyboard/project
|
||||
|
||||
Keyboard Maintainer: [kakunpc](https://github.com/kakunpc)
|
||||
Hardware Supported: The PCBs, controllers supported
|
||||
Hardware Availability: links to where you can find this hardware
|
||||
* Keyboard Maintainer: [kakunpc](https://github.com/kakunpc)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
# Ergodicity
|
||||
|
||||

|
||||
|
||||
A short description of the keyboard/project
|
||||
|
||||
Keyboard Maintainer: [nooges/bakingpy](https://github.com/nooges)
|
||||
Hardware Supported: Ergodicity PCB w/ATmega32u4
|
||||
Hardware Availability: [Keebio](https://keeb.io)
|
||||
|
@ -1,7 +1,5 @@
|
||||
# Kira 75
|
||||
|
||||

|
||||
|
||||
75% keyboard designed by thesiscamper
|
||||
|
||||
Keyboard Maintainer: [MechMerlin](https://github.com/mechmerlin)
|
||||
|
@ -5,7 +5,6 @@
|
||||
A 16 key macropad, with USB C, RGB underglow and backlight.
|
||||
|
||||
* Keyboard Maintainer: QMK Community
|
||||
* Hardware Supported: The PCBs, controllers supported
|
||||
* Hardware Availability: [KPrepublic](https://kprepublic.com/products/bm16a-16-keys-custom-mechanical-keyboard-pcb-plate-programmed-numpad-layouts-qmk-firmware-with-rgb-bottom-underglow-alps-mx); [AliExpress](https://www.aliexpress.com/store/product/bm16a-16-keys-Custom-Mechanical-Keyboard-PCB-plate-programmed-numpad-layouts-qmk-firmware-with-rgb-bottom/3034003_32970629907.html)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
@ -3,7 +3,6 @@
|
||||
A 16-key macropad, with USB C and per-key RGB backlighting. This is a variant of the BM16A, but with low profile Choc switches.
|
||||
|
||||
* Keyboard Maintainer: QMK Community
|
||||
* Hardware Supported: The PCBs, controllers supported
|
||||
* Hardware Availability: [KPrepublic](https://kprepublic.com/collections/pcb/products/bm16s-16-keys-custom-mechanical-keyboard-pcb-plate-programmed-numpad-layouts-qmk-firmware-with-rgb-switch-leds-choc-switch); [AliExpress](https://www.aliexpress.com/item/bm16s-16-keys-Custom-Mechanical-Keyboard-PCB-plate-programmed-numpad-layouts-qmk-firmware-with-rgb-switch/32999247908.html); [Massdrop](https://www.massdrop.com/buy/78169)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
@ -4,9 +4,7 @@
|
||||
|
||||
A 32-key Symmetric staggered keyboard.
|
||||
|
||||
Keyboard Maintainer: [marksard](https://github.com/marksard)
|
||||
Hardware Supported: The PCBs, controllers supported
|
||||
Hardware Availability: links to where you can find this hardware
|
||||
* Keyboard Maintainer: [marksard](https://github.com/marksard)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
|
@ -4,9 +4,7 @@
|
||||
|
||||
A 47 (or 48) keys Symmetric Staggered keyboard.
|
||||
|
||||
Keyboard Maintainer: [marksard](https://github.com/marksard)
|
||||
Hardware Supported: The PCBs, controllers supported
|
||||
Hardware Availability: links to where you can find this hardware
|
||||
* Keyboard Maintainer: [marksard](https://github.com/marksard)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||

|
||||
|
||||
A short description of the keyboard/project
|
||||
|
||||
* Keyboard Maintainer: [Mathias Andersson](https://github.com/wraul)
|
||||
* Hardware Supported: [Classy TKL PCB](https://github.com/4pplet/classyTKL)
|
||||
* Hardware Availability: https://geekhack.org/index.php?topic=105933
|
||||
|
@ -5,8 +5,6 @@
|
||||
To reset and put into bootloader mode, please use the hardware reset button on the botton of the PCB. If the PCB is on the default firmware, software reset is available by holding the bottom left corner key and pressing `B` in the standard qwerty layout.
|
||||
|
||||
* Keyboard Maintainer: [melonbred](https://github.com/melonbred)
|
||||
* Hardware Supported: The PCBs, controllers supported
|
||||
* Hardware Availability: Links to where you can find this hardware
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
# delphine
|
||||
|
||||

|
||||
|
||||
A Number-Pad PCB, Mono backlight and RGB backlight version, Dolpad compatible.
|
||||
|
||||
* Keyboard Maintainer: [Mechlovin'](https://github.com/mechlovin)
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||

|
||||
|
||||
*A short description of the keyboard/project*
|
||||
|
||||
* Keyboard Maintainer: [Kyle McCreery](https://github.com/kylemccreery)
|
||||
* Hardware Supported: Mokulua v1.3
|
||||
* Hardware Availability: https://mechwild.com/product/mokulua/
|
||||
|
@ -1,7 +1,5 @@
|
||||
# Meme
|
||||
|
||||

|
||||
|
||||
65% gasket mount keyboard.
|
||||
|
||||
Keyboard Maintainer: [MechMerlin](https://github.com/mechmerlin)
|
||||
|
@ -2,11 +2,8 @@
|
||||
|
||||

|
||||
|
||||
A short description of the keyboard/project
|
||||
|
||||
Keyboard Maintainer: [Eucalyn](https://github.com/eucalyn) [@eucalyn_](https://twitter.com/eucalyn_)
|
||||
Hardware Supported: The Mint60 PCBs, ProMicro supported
|
||||
Hardware Availability: links to where you can find this hardware
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
|
@ -1,3 +1 @@
|
||||
POINTING_DEVICE_DRIVER = adns9800
|
||||
|
||||
DEFAULT_FOLDER = oddball/v1
|
1
keyboards/oddball/v2/rules.mk
Normal file
1
keyboards/oddball/v2/rules.mk
Normal file
@ -0,0 +1 @@
|
||||
POINTING_DEVICE_DRIVER = adns9800
|
1
keyboards/oddball/v2_1/rules.mk
Normal file
1
keyboards/oddball/v2_1/rules.mk
Normal file
@ -0,0 +1 @@
|
||||
POINTING_DEVICE_DRIVER = adns9800
|
@ -5,8 +5,6 @@
|
||||
Pegasus is a 40% keyboard with a 12.75u "WKL" layout with 0.75u blockers.
|
||||
|
||||
* Keyboard Maintainer: [melonbred](https://github.com/melonbred)
|
||||
* Hardware Supported: The PCBs, controllers supported
|
||||
* Hardware Availability: Links to where you can find this hardware
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
|
1
keyboards/teleport/native/ansi/rules.mk
Normal file
1
keyboards/teleport/native/ansi/rules.mk
Normal file
@ -0,0 +1 @@
|
||||
RGB_MATRIX_CUSTOM_KB = yes
|
1
keyboards/teleport/native/iso/rules.mk
Normal file
1
keyboards/teleport/native/iso/rules.mk
Normal file
@ -0,0 +1 @@
|
||||
RGB_MATRIX_CUSTOM_KB = yes
|
@ -1,3 +0,0 @@
|
||||
RGB_MATRIX_CUSTOM_KB = yes
|
||||
|
||||
DEFAULT_FOLDER = teleport/native/iso
|
@ -1,7 +1,5 @@
|
||||
# TGR Tris/Tris CE
|
||||
|
||||
A short description of the keyboard/project
|
||||
|
||||
* Keyboard Maintainer: [poisonking](https://github.com/halfenergized)
|
||||
* Hardware Supported: Tris PCB
|
||||
* Hardware Availability: https://geekhack.org/index.php?topic=86221.0
|
||||
|
2
keyboards/westm/westm68/rev1/rules.mk
Normal file
2
keyboards/westm/westm68/rev1/rules.mk
Normal file
@ -0,0 +1,2 @@
|
||||
# Wildcard to allow APM32 MCU
|
||||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF
|
2
keyboards/westm/westm68/rev2/rules.mk
Normal file
2
keyboards/westm/westm68/rev2/rules.mk
Normal file
@ -0,0 +1,2 @@
|
||||
# Wildcard to allow APM32 MCU
|
||||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF
|
2
keyboards/westm/westm9/rev1/rules.mk
Normal file
2
keyboards/westm/westm9/rev1/rules.mk
Normal file
@ -0,0 +1,2 @@
|
||||
# Wildcard to allow APM32 MCU
|
||||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF
|
2
keyboards/westm/westm9/rev2/rules.mk
Normal file
2
keyboards/westm/westm9/rev2/rules.mk
Normal file
@ -0,0 +1,2 @@
|
||||
# Wildcard to allow APM32 MCU
|
||||
DFU_SUFFIX_ARGS = -v FFFF -p FFFF
|
@ -1,2 +1,5 @@
|
||||
# Processor frequency
|
||||
F_CPU = 8000000
|
||||
|
||||
CUSTOM_MATRIX = yes
|
||||
SRC += matrix.c
|
||||
|
@ -1,3 +1,6 @@
|
||||
CUSTOM_MATRIX = yes
|
||||
SRC += matrix.c
|
||||
|
||||
# Disable unsupported hardware
|
||||
RGBLIGHT_SUPPORTED = no
|
||||
AUDIO_SUPPORTED = no
|
||||
|
@ -1,4 +0,0 @@
|
||||
CUSTOM_MATRIX = yes
|
||||
SRC += matrix.c
|
||||
|
||||
DEFAULT_FOLDER = woodkeys/meira/promicro
|
1
keyboards/work_louder/loop/post_rules.mk
Normal file
1
keyboards/work_louder/loop/post_rules.mk
Normal file
@ -0,0 +1 @@
|
||||
SRC += rgb_functions.c
|
@ -1,3 +0,0 @@
|
||||
SRC += rgb_functions.c
|
||||
|
||||
DEFAULT_FOLDER = work_louder/loop/rev3
|
1
keyboards/work_louder/work_board/post_rules.mk
Normal file
1
keyboards/work_louder/work_board/post_rules.mk
Normal file
@ -0,0 +1 @@
|
||||
SRC += rgb_functions.c
|
@ -1,3 +0,0 @@
|
||||
SRC += rgb_functions.c
|
||||
|
||||
DEFAULT_FOLDER = work_louder/work_board/rev3
|
@ -3,7 +3,6 @@
|
||||
A 16 key macropad, with USB C
|
||||
|
||||
* Keyboard Maintainer: QMK Community
|
||||
* Hardware Supported: The PCBs, controllers supported
|
||||
* Hardware Availability: The x16 was discontinued by [x16](https://yinxianwei.github.io/x16/)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
2
keyboards/zsa/planck_ez/base/rules.mk
Normal file
2
keyboards/zsa/planck_ez/base/rules.mk
Normal file
@ -0,0 +1,2 @@
|
||||
RGBLIGHT_SUPPORTED = no
|
||||
BACKLIGHT_SUPPORTED = no
|
2
keyboards/zsa/planck_ez/glow/rules.mk
Normal file
2
keyboards/zsa/planck_ez/glow/rules.mk
Normal file
@ -0,0 +1,2 @@
|
||||
RGBLIGHT_SUPPORTED = no
|
||||
BACKLIGHT_SUPPORTED = no
|
@ -1,4 +0,0 @@
|
||||
RGBLIGHT_SUPPORTED = no
|
||||
BAKCLIGHT_SUPPORTED = no
|
||||
|
||||
DEFAULT_FOLDER = zsa/planck_ez/base
|
@ -24,7 +24,7 @@ def _get_chunks(it, size):
|
||||
return iter(lambda: tuple(islice(it, size)), ())
|
||||
|
||||
|
||||
def _preprocess_c_file(file):
|
||||
def preprocess_c_file(file):
|
||||
"""Load file and strip comments
|
||||
"""
|
||||
file_contents = file.read_text(encoding='utf-8')
|
||||
@ -66,7 +66,7 @@ def find_layouts(file):
|
||||
parsed_layouts = {}
|
||||
|
||||
# Search the file for LAYOUT macros and aliases
|
||||
file_contents = _preprocess_c_file(file)
|
||||
file_contents = preprocess_c_file(file)
|
||||
|
||||
for line in file_contents.split('\n'):
|
||||
if layout_macro_define_regex.match(line.lstrip()) and '(' in line and 'LAYOUT' in line:
|
||||
@ -248,7 +248,7 @@ def _parse_led_config(file, matrix_cols, matrix_rows):
|
||||
current_row_index = 0
|
||||
current_row = []
|
||||
|
||||
for _type, value in lex(_preprocess_c_file(file), CLexer()):
|
||||
for _type, value in lex(preprocess_c_file(file), CLexer()):
|
||||
if not found_g_led_config:
|
||||
# Check for type
|
||||
if value == 'led_config_t':
|
||||
|
@ -11,7 +11,7 @@ from qmk.commands import get_chunks
|
||||
def dos2unix_run(files):
|
||||
"""Spawn multiple dos2unix subprocess avoiding too long commands on formatting everything
|
||||
"""
|
||||
for chunk in get_chunks(files, 10):
|
||||
for chunk in get_chunks([normpath(file).as_posix() for file in files], 10):
|
||||
dos2unix = cli.run(['dos2unix', *chunk])
|
||||
|
||||
if dos2unix.returncode:
|
||||
|
@ -10,7 +10,7 @@ from qmk.keyboard import keyboard_completer, keyboard_folder_or_all, is_all_keyb
|
||||
from qmk.keymap import locate_keymap, list_keymaps
|
||||
from qmk.path import keyboard
|
||||
from qmk.git import git_get_ignored_files
|
||||
from qmk.c_parse import c_source_files
|
||||
from qmk.c_parse import c_source_files, preprocess_c_file
|
||||
|
||||
CHIBIOS_CONF_CHECKS = ['chconf.h', 'halconf.h', 'mcuconf.h', 'board.h']
|
||||
INVALID_KB_FEATURES = set(['encoder_map', 'dip_switch_map', 'combo', 'tap_dance', 'via'])
|
||||
@ -33,12 +33,64 @@ def _list_defaultish_keymaps(kb):
|
||||
return keymaps
|
||||
|
||||
|
||||
def _get_readme_files(kb, km=None):
|
||||
"""Return potential keyboard/keymap readme files
|
||||
"""
|
||||
search_path = locate_keymap(kb, km).parent if km else keyboard(kb)
|
||||
|
||||
readme_files = []
|
||||
|
||||
if not km:
|
||||
current_path = Path(search_path.parts[0])
|
||||
for path_part in search_path.parts[1:]:
|
||||
current_path = current_path / path_part
|
||||
readme_files.extend(current_path.glob('*readme.md'))
|
||||
|
||||
for file in search_path.glob("**/*readme.md"):
|
||||
# Ignore keymaps when only globing keyboard files
|
||||
if not km and 'keymaps' in file.parts:
|
||||
continue
|
||||
readme_files.append(file)
|
||||
|
||||
return set(readme_files)
|
||||
|
||||
|
||||
def _get_build_files(kb, km=None):
|
||||
"""Return potential keyboard/keymap build files
|
||||
"""
|
||||
search_path = locate_keymap(kb, km).parent if km else keyboard(kb)
|
||||
|
||||
build_files = []
|
||||
|
||||
if not km:
|
||||
current_path = Path()
|
||||
for path_part in search_path.parts:
|
||||
current_path = current_path / path_part
|
||||
build_files.extend(current_path.glob('*rules.mk'))
|
||||
|
||||
for file in search_path.glob("**/*rules.mk"):
|
||||
# Ignore keymaps when only globing keyboard files
|
||||
if not km and 'keymaps' in file.parts:
|
||||
continue
|
||||
build_files.append(file)
|
||||
|
||||
return set(build_files)
|
||||
|
||||
|
||||
def _get_code_files(kb, km=None):
|
||||
"""Return potential keyboard/keymap code files
|
||||
"""
|
||||
search_path = locate_keymap(kb, km).parent if km else keyboard(kb)
|
||||
|
||||
code_files = []
|
||||
|
||||
if not km:
|
||||
current_path = Path()
|
||||
for path_part in search_path.parts:
|
||||
current_path = current_path / path_part
|
||||
code_files.extend(current_path.glob('*.h'))
|
||||
code_files.extend(current_path.glob('*.c'))
|
||||
|
||||
for file in c_source_files([search_path]):
|
||||
# Ignore keymaps when only globing keyboard files
|
||||
if not km and 'keymaps' in file.parts:
|
||||
@ -48,6 +100,43 @@ def _get_code_files(kb, km=None):
|
||||
return code_files
|
||||
|
||||
|
||||
def _is_invalid_readme(file):
|
||||
"""Check if file contains any unfilled content
|
||||
"""
|
||||
tokens = [
|
||||
'%KEYBOARD%',
|
||||
'%REAL_NAME%',
|
||||
'%USER_NAME%',
|
||||
'image replace me!',
|
||||
'A short description of the keyboard/project',
|
||||
'The PCBs, controllers supported',
|
||||
'Links to where you can find this hardware',
|
||||
]
|
||||
|
||||
for line in file.read_text(encoding='utf-8').split("\n"):
|
||||
if any(token in line for token in tokens):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _is_empty_rules(file):
|
||||
"""Check if file contains any useful content
|
||||
"""
|
||||
for line in file.read_text(encoding='utf-8').split("\n"):
|
||||
if len(line) > 0 and not line.isspace() and not line.startswith('#'):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _is_empty_include(file):
|
||||
"""Check if file contains any useful content
|
||||
"""
|
||||
for line in preprocess_c_file(file).split("\n"):
|
||||
if len(line) > 0 and not line.isspace() and not line.startswith('#pragma once'):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _has_license(file):
|
||||
"""Check file has a license header
|
||||
"""
|
||||
@ -91,37 +180,28 @@ def _chibios_conf_includenext_check(target):
|
||||
return None
|
||||
|
||||
|
||||
def _rules_mk_assignment_only(kb):
|
||||
def _rules_mk_assignment_only(rules_mk):
|
||||
"""Check the keyboard-level rules.mk to ensure it only has assignments.
|
||||
"""
|
||||
keyboard_path = keyboard(kb)
|
||||
current_path = Path()
|
||||
errors = []
|
||||
continuation = None
|
||||
for i, line in enumerate(rules_mk.open()):
|
||||
line = line.strip()
|
||||
|
||||
for path_part in keyboard_path.parts:
|
||||
current_path = current_path / path_part
|
||||
rules_mk = current_path / 'rules.mk'
|
||||
if '#' in line:
|
||||
line = line[:line.index('#')]
|
||||
|
||||
if rules_mk.exists():
|
||||
if continuation:
|
||||
line = continuation + line
|
||||
continuation = None
|
||||
|
||||
for i, line in enumerate(rules_mk.open()):
|
||||
line = line.strip()
|
||||
if line:
|
||||
if line[-1] == '\\':
|
||||
continuation = line[:-1]
|
||||
continue
|
||||
|
||||
if '#' in line:
|
||||
line = line[:line.index('#')]
|
||||
|
||||
if continuation:
|
||||
line = continuation + line
|
||||
continuation = None
|
||||
|
||||
if line:
|
||||
if line[-1] == '\\':
|
||||
continuation = line[:-1]
|
||||
continue
|
||||
|
||||
if line and '=' not in line:
|
||||
errors.append(f'Non-assignment code on line +{i} {rules_mk}: {line}')
|
||||
if line and '=' not in line:
|
||||
errors.append(f'Non-assignment code on line +{i} {rules_mk}: {line}')
|
||||
|
||||
return errors
|
||||
|
||||
@ -162,7 +242,7 @@ def keymap_check(kb, km):
|
||||
return ok
|
||||
|
||||
|
||||
def keyboard_check(kb):
|
||||
def keyboard_check(kb): # noqa C901
|
||||
"""Perform the keyboard level checks.
|
||||
"""
|
||||
ok = True
|
||||
@ -175,13 +255,6 @@ def keyboard_check(kb):
|
||||
if not _handle_invalid_features(kb, kb_info):
|
||||
ok = False
|
||||
|
||||
rules_mk_assignment_errors = _rules_mk_assignment_only(kb)
|
||||
if rules_mk_assignment_errors:
|
||||
ok = False
|
||||
cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb)
|
||||
for assignment_error in rules_mk_assignment_errors:
|
||||
cli.log.error(assignment_error)
|
||||
|
||||
invalid_files = git_get_ignored_files(f'keyboards/{kb}/')
|
||||
for file in invalid_files:
|
||||
if 'keymap' in file:
|
||||
@ -189,11 +262,34 @@ def keyboard_check(kb):
|
||||
cli.log.error(f'{kb}: The file "{file}" should not exist!')
|
||||
ok = False
|
||||
|
||||
for file in _get_readme_files(kb):
|
||||
if _is_invalid_readme(file):
|
||||
cli.log.error(f'{kb}: The file "{file}" still contains template tokens!')
|
||||
ok = False
|
||||
|
||||
for file in _get_build_files(kb):
|
||||
if _is_empty_rules(file):
|
||||
cli.log.error(f'{kb}: The file "{file}" is effectively empty and should be removed!')
|
||||
ok = False
|
||||
|
||||
if file.suffix in ['rules.mk']:
|
||||
rules_mk_assignment_errors = _rules_mk_assignment_only(file)
|
||||
if rules_mk_assignment_errors:
|
||||
ok = False
|
||||
cli.log.error('%s: Non-assignment code found in rules.mk. Move it to post_rules.mk instead.', kb)
|
||||
for assignment_error in rules_mk_assignment_errors:
|
||||
cli.log.error(assignment_error)
|
||||
|
||||
for file in _get_code_files(kb):
|
||||
if not _has_license(file):
|
||||
cli.log.error(f'{kb}: The file "{file}" does not have a license header!')
|
||||
ok = False
|
||||
|
||||
if file.name in ['config.h']:
|
||||
if _is_empty_include(file):
|
||||
cli.log.error(f'{kb}: The file "{file}" is effectively empty and should be removed!')
|
||||
ok = False
|
||||
|
||||
if file.name in CHIBIOS_CONF_CHECKS:
|
||||
check_error = _chibios_conf_includenext_check(file)
|
||||
if check_error is not None:
|
||||
|
@ -28,9 +28,9 @@
|
||||
// Support for pins which are on TIM1_CH1N
|
||||
#ifdef BACKLIGHT_PWM_COMPLEMENTARY_OUTPUT
|
||||
# if BACKLIGHT_ON_STATE == 1
|
||||
# define PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW;
|
||||
# else
|
||||
# define PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH;
|
||||
# else
|
||||
# define PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW;
|
||||
# endif
|
||||
#else
|
||||
# if BACKLIGHT_ON_STATE == 1
|
||||
|
@ -47,7 +47,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
int tp_buttons;
|
||||
|
||||
#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||
int retro_tapping_counter = 0;
|
||||
bool retro_tap_primed = false;
|
||||
uint16_t retro_tap_curr_key = 0;
|
||||
# if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||
uint8_t retro_tap_curr_mods = 0;
|
||||
uint8_t retro_tap_next_mods = 0;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
|
||||
@ -77,7 +82,13 @@ void action_exec(keyevent_t event) {
|
||||
debug_event(event);
|
||||
ac_dprintf("\n");
|
||||
#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||
retro_tapping_counter++;
|
||||
uint16_t event_keycode = get_event_keycode(event, false);
|
||||
if (event.pressed) {
|
||||
retro_tap_primed = false;
|
||||
retro_tap_curr_key = event_keycode;
|
||||
} else if (retro_tap_curr_key == event_keycode) {
|
||||
retro_tap_primed = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -531,7 +542,8 @@ void process_action(keyrecord_t *record, action_t action) {
|
||||
# if defined(RETRO_TAPPING) && defined(DUMMY_MOD_NEUTRALIZER_KEYCODE)
|
||||
// Send a dummy keycode to neutralize flashing modifiers
|
||||
// if the key was held and then released with no interruptions.
|
||||
if (retro_tapping_counter == 2) {
|
||||
uint16_t ev_kc = get_event_keycode(event, false);
|
||||
if (retro_tap_primed && retro_tap_curr_key == ev_kc) {
|
||||
neutralize_flashing_modifiers(get_mods());
|
||||
}
|
||||
# endif
|
||||
@ -817,6 +829,10 @@ void process_action(keyrecord_t *record, action_t action) {
|
||||
case ACT_LAYER_TAP_EXT:
|
||||
# endif
|
||||
led_set(host_keyboard_leds());
|
||||
# ifndef NO_ACTION_ONESHOT
|
||||
// don't release the key
|
||||
do_release_oneshot = false;
|
||||
# endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -825,30 +841,44 @@ void process_action(keyrecord_t *record, action_t action) {
|
||||
|
||||
#ifndef NO_ACTION_TAPPING
|
||||
# if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||
if (!is_tap_action(action)) {
|
||||
retro_tapping_counter = 0;
|
||||
} else {
|
||||
if (is_tap_action(action)) {
|
||||
if (event.pressed) {
|
||||
if (tap_count > 0) {
|
||||
retro_tapping_counter = 0;
|
||||
retro_tap_primed = false;
|
||||
} else {
|
||||
# if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||
retro_tap_curr_mods = retro_tap_next_mods;
|
||||
retro_tap_next_mods = get_mods();
|
||||
# endif
|
||||
}
|
||||
} else {
|
||||
uint16_t event_keycode = get_event_keycode(event, false);
|
||||
# if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||
uint8_t curr_mods = get_mods();
|
||||
# endif
|
||||
if (tap_count > 0) {
|
||||
retro_tapping_counter = 0;
|
||||
} else {
|
||||
retro_tap_primed = false;
|
||||
} else if (retro_tap_curr_key == event_keycode) {
|
||||
if (
|
||||
# ifdef RETRO_TAPPING_PER_KEY
|
||||
get_retro_tapping(get_event_keycode(record->event, false), record) &&
|
||||
get_retro_tapping(event_keycode, record) &&
|
||||
# endif
|
||||
retro_tapping_counter == 2) {
|
||||
retro_tap_primed) {
|
||||
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
|
||||
process_auto_shift(action.layer_tap.code, record);
|
||||
# else
|
||||
register_mods(retro_tap_curr_mods);
|
||||
wait_ms(TAP_CODE_DELAY);
|
||||
tap_code(action.layer_tap.code);
|
||||
wait_ms(TAP_CODE_DELAY);
|
||||
unregister_mods(retro_tap_curr_mods);
|
||||
# endif
|
||||
}
|
||||
retro_tapping_counter = 0;
|
||||
retro_tap_primed = false;
|
||||
}
|
||||
# if !(defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||
retro_tap_next_mods = curr_mods;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
@ -557,6 +557,12 @@ int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, pai
|
||||
# define SH1106_NUM_DEVICES 0
|
||||
#endif // QUANTUM_PAINTER_SH1106_ENABLE
|
||||
|
||||
#ifdef QUANTUM_PAINTER_SH1107_ENABLE
|
||||
# include "qp_sh1107.h"
|
||||
#else // QUANTUM_PAINTER_SH1107_ENABLE
|
||||
# define SH1107_NUM_DEVICES 0
|
||||
#endif // QUANTUM_PAINTER_SH1107_ENABLE
|
||||
|
||||
#ifdef QUANTUM_PAINTER_LD7032_ENABLE
|
||||
# include "qp_ld7032.h"
|
||||
#else // QUANTUM_PAINTER_LD7032_ENABLE
|
||||
|
@ -19,6 +19,7 @@ enum {
|
||||
+ (GC9107_NUM_DEVICES) // GC9107
|
||||
+ (SSD1351_NUM_DEVICES) // SSD1351
|
||||
+ (SH1106_NUM_DEVICES) // SH1106
|
||||
+ (SH1107_NUM_DEVICES) // SH1107
|
||||
+ (LD7032_NUM_DEVICES) // LD7032
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,8 @@ VALID_QUANTUM_PAINTER_DRIVERS := \
|
||||
ssd1351_spi \
|
||||
sh1106_i2c \
|
||||
sh1106_spi \
|
||||
sh1107_i2c \
|
||||
sh1107_spi \
|
||||
ld7032_i2c \
|
||||
ld7032_spi
|
||||
|
||||
@ -184,6 +186,29 @@ define handle_quantum_painter_driver
|
||||
$(DRIVER_PATH)/painter/oled_panel/qp_oled_panel.c \
|
||||
$(DRIVER_PATH)/painter/sh1106/qp_sh1106.c
|
||||
|
||||
else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),sh1107_spi)
|
||||
QUANTUM_PAINTER_NEEDS_SURFACE := yes
|
||||
QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes
|
||||
QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes
|
||||
OPT_DEFS += -DQUANTUM_PAINTER_SH1107_ENABLE -DQUANTUM_PAINTER_SH1107_SPI_ENABLE
|
||||
COMMON_VPATH += \
|
||||
$(DRIVER_PATH)/painter/oled_panel \
|
||||
$(DRIVER_PATH)/painter/sh1107
|
||||
SRC += \
|
||||
$(DRIVER_PATH)/painter/oled_panel/qp_oled_panel.c \
|
||||
$(DRIVER_PATH)/painter/sh1107/qp_sh1107.c
|
||||
|
||||
else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),sh1107_i2c)
|
||||
QUANTUM_PAINTER_NEEDS_SURFACE := yes
|
||||
QUANTUM_PAINTER_NEEDS_COMMS_I2C := yes
|
||||
OPT_DEFS += -DQUANTUM_PAINTER_SH1107_ENABLE -DQUANTUM_PAINTER_SH1107_I2C_ENABLE
|
||||
COMMON_VPATH += \
|
||||
$(DRIVER_PATH)/painter/oled_panel \
|
||||
$(DRIVER_PATH)/painter/sh1107
|
||||
SRC += \
|
||||
$(DRIVER_PATH)/painter/oled_panel/qp_oled_panel.c \
|
||||
$(DRIVER_PATH)/painter/sh1107/qp_sh1107.c
|
||||
|
||||
else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ld7032_spi)
|
||||
QUANTUM_PAINTER_NEEDS_SURFACE := yes
|
||||
QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes
|
||||
|
@ -168,7 +168,7 @@ TEST_F(OneShot, OSMChainingTwoOSMs) {
|
||||
tap_key(osm_key1);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press and relesea OSM2 */
|
||||
/* Press and release OSM2 */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osm_key2);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
@ -353,3 +353,337 @@ TEST_F(OneShot, OSLWithOsmAndAdditionalKeypress) {
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSLWithMoAndAdditionalKeypress) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey mo_key = KeymapKey{1, 1, 0, MO(2)};
|
||||
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
|
||||
|
||||
set_keymap({osl_key, mo_key, regular_key});
|
||||
|
||||
/* Press OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
osl_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
osl_key.release();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(1));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press MO */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mo_key.press();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(2));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press regular key */
|
||||
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(2));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular key */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release MO */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mo_key.release();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(0));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
class OneShotLayerParametrizedTestFixture : public ::testing::WithParamInterface<uint16_t>, public OneShot {};
|
||||
|
||||
TEST_P(OneShotLayerParametrizedTestFixture, OSLWithActionAndAdditionalKeypress) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey action_key = KeymapKey{1, 1, 0, GetParam()};
|
||||
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
|
||||
|
||||
set_keymap({osl_key, action_key, regular_key});
|
||||
|
||||
/* Tap OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osl_key);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Tag Action key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(action_key);
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(2));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press regular key */
|
||||
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(2));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular key */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(OneShotLayerTests, OneShotLayerParametrizedTestFixture, ::testing::Values(TG(2), TO(2)));
|
||||
|
||||
TEST_F(OneShot, OSLWithDFAndAdditionalKeypress) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey df_key = KeymapKey{1, 1, 0, DF(2)};
|
||||
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
|
||||
|
||||
set_keymap({osl_key, df_key, regular_key});
|
||||
|
||||
layer_state_t default_layer_state_bak = default_layer_state;
|
||||
|
||||
/* Tap OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osl_key);
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(1));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press DF key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
df_key.press();
|
||||
run_one_scan_loop();
|
||||
EXPECT_EQ(default_layer_state, 0b001);
|
||||
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release DF key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
df_key.release();
|
||||
run_one_scan_loop();
|
||||
EXPECT_EQ(default_layer_state, 0b100);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press regular key */
|
||||
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular key */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
default_layer_state = default_layer_state_bak;
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSLChainingTwoOSLsAndAdditionalKeypress) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl1_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey osl2_key = KeymapKey{1, 1, 0, OSL(2)};
|
||||
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
|
||||
|
||||
set_keymap({osl1_key, osl2_key, regular_key});
|
||||
|
||||
/* Press and release first OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
osl1_key.press();
|
||||
run_one_scan_loop();
|
||||
osl1_key.release();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(1));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press and release second OSL */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
osl2_key.press();
|
||||
run_one_scan_loop();
|
||||
osl2_key.release();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(2));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press regular key */
|
||||
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(0));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSLWithShortLT) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey lt_key = KeymapKey(1, 1, 0, LT(2, KC_A));
|
||||
|
||||
set_keymap({osl_key, lt_key});
|
||||
|
||||
/* Tap OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osl_key);
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(1));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Tap LT key. */
|
||||
EXPECT_REPORT(driver, (lt_key.report_code)).Times(1);
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
tap_key(lt_key);
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(0));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSLWithLongLTAndRegularKey) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey lt_key = KeymapKey(1, 1, 0, LT(2, KC_A));
|
||||
KeymapKey regular_key = KeymapKey(2, 1, 1, KC_B);
|
||||
|
||||
set_keymap({osl_key, lt_key, regular_key});
|
||||
|
||||
/* Tap OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osl_key);
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(1));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press LT key. */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
lt_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Idle for tapping term of mod tap hold key. */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
idle_for(TAPPING_TERM + 1);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
EXPECT_TRUE(layer_state_is(2));
|
||||
|
||||
/* Press regular key. */
|
||||
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular key. */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSLWithShortModTapKeyAndRegularKey) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey mod_tap_hold_key = KeymapKey(1, 1, 0, SFT_T(KC_P));
|
||||
KeymapKey regular_key = KeymapKey(0, 2, 0, KC_A);
|
||||
|
||||
set_keymap({osl_key, mod_tap_hold_key, regular_key});
|
||||
|
||||
/* Tap OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osl_key);
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(1));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press mod-tap-hold key. */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release mod-tap-hold key. */
|
||||
EXPECT_REPORT(driver, (KC_P));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press regular key. */
|
||||
EXPECT_REPORT(driver, (regular_key.report_code));
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular key. */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSLWithLongModTapKeyAndRegularKey) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
|
||||
KeymapKey mod_tap_hold_key = KeymapKey(1, 1, 0, SFT_T(KC_P));
|
||||
KeymapKey regular_key = KeymapKey(1, 2, 0, KC_A);
|
||||
|
||||
set_keymap({osl_key, mod_tap_hold_key, regular_key});
|
||||
|
||||
/* Tap OSL key */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osl_key);
|
||||
run_one_scan_loop();
|
||||
EXPECT_TRUE(layer_state_is(1));
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press mod-tap-hold key. */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Idle for tapping term of mod tap hold key. */
|
||||
EXPECT_REPORT(driver, (KC_LSFT));
|
||||
idle_for(TAPPING_TERM + 1);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release mod-tap-hold key. */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press regular key. */
|
||||
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular key. */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
408
tests/tap_hold_configurations/retro_tapping/test_key_roll.cpp
Normal file
408
tests/tap_hold_configurations/retro_tapping/test_key_roll.cpp
Normal file
@ -0,0 +1,408 @@
|
||||
/* Copyright 2024 John Rigoni
|
||||
*
|
||||
* 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 3 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 "keyboard_report_util.hpp"
|
||||
#include "keycode.h"
|
||||
#include "keycodes.h"
|
||||
#include "test_common.hpp"
|
||||
#include "action_tapping.h"
|
||||
#include "test_keymap_key.hpp"
|
||||
|
||||
using testing::_;
|
||||
using testing::InSequence;
|
||||
|
||||
class RetroTapKeyRoll : public TestFixture {};
|
||||
|
||||
TEST_F(RetroTapKeyRoll, regular_to_left_gui_mod_over_tap_term) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_key = KeymapKey(0, 1, 0, LGUI_T(KC_P));
|
||||
auto regular_key = KeymapKey(0, 2, 0, KC_B);
|
||||
|
||||
set_keymap({mod_tap_hold_key, regular_key});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_B));
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_key.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_B, KC_LEFT_GUI));
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI, DUMMY_MOD_NEUTRALIZER_KEYCODE));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
EXPECT_REPORT(driver, (KC_P));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, regular_to_mod_over_tap_term) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_A));
|
||||
auto regular_key = KeymapKey(0, 2, 0, KC_B);
|
||||
|
||||
set_keymap({mod_tap_hold_key, regular_key});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_B));
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_B, KC_LEFT_SHIFT));
|
||||
mod_tap_hold_key.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
EXPECT_REPORT(driver, (KC_A));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, regular_to_mod_under_tap_term) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_A));
|
||||
auto regular_key = KeymapKey(0, 2, 0, KC_B);
|
||||
|
||||
set_keymap({mod_tap_hold_key, regular_key});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_B));
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_A));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_under_tap_term_to_regular) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_key = KeymapKey(0, 1, 0, LGUI_T(KC_P));
|
||||
auto regular_key = KeymapKey(0, 2, 0, KC_B);
|
||||
|
||||
set_keymap({mod_tap_hold_key, regular_key});
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_P));
|
||||
EXPECT_REPORT(driver, (KC_B, KC_P));
|
||||
EXPECT_REPORT(driver, (KC_B));
|
||||
mod_tap_hold_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_over_tap_term_to_regular) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_A));
|
||||
auto regular_key = KeymapKey(0, 2, 0, KC_B);
|
||||
|
||||
set_keymap({mod_tap_hold_key, regular_key});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
mod_tap_hold_key.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_B));
|
||||
regular_key.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_B));
|
||||
mod_tap_hold_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_under_tap_term_to_mod_under_tap_term) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_gui = KeymapKey(0, 1, 0, LGUI_T(KC_P));
|
||||
auto mod_tap_hold_lshft = KeymapKey(0, 2, 0, SFT_T(KC_A));
|
||||
|
||||
set_keymap({mod_tap_hold_gui, mod_tap_hold_lshft});
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_lshft.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_gui.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_A));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_lshft.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_P));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_gui.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_over_tap_term_to_mod_under_tap_term) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_gui = KeymapKey(0, 1, 0, LGUI_T(KC_P));
|
||||
auto mod_tap_hold_lshft = KeymapKey(0, 2, 0, SFT_T(KC_A));
|
||||
|
||||
set_keymap({mod_tap_hold_gui, mod_tap_hold_lshft});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
mod_tap_hold_lshft.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_gui.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_lshft.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_P));
|
||||
EXPECT_REPORT(driver, (KC_P));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_gui.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_under_tap_term_to_mod_over_tap_term) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_gui = KeymapKey(0, 1, 0, LGUI_T(KC_P));
|
||||
auto mod_tap_hold_lshft = KeymapKey(0, 2, 0, SFT_T(KC_A));
|
||||
|
||||
set_keymap({mod_tap_hold_gui, mod_tap_hold_lshft});
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_lshft.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_LEFT_GUI));
|
||||
mod_tap_hold_gui.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
mod_tap_hold_lshft.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI, DUMMY_MOD_NEUTRALIZER_KEYCODE));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
EXPECT_REPORT(driver, (KC_P, KC_LEFT_SHIFT));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_gui.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_under_tap_term_to_mod_over_tap_term_offset) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_gui = KeymapKey(0, 1, 0, LGUI_T(KC_P));
|
||||
auto mod_tap_hold_lshft = KeymapKey(0, 2, 0, SFT_T(KC_A));
|
||||
|
||||
set_keymap({mod_tap_hold_gui, mod_tap_hold_lshft});
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_lshft.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_gui.press();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_A));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_lshft.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI, DUMMY_MOD_NEUTRALIZER_KEYCODE));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
EXPECT_REPORT(driver, (KC_P));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
idle_for(TAPPING_TERM);
|
||||
mod_tap_hold_gui.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_over_tap_term_to_mod_over_tap_term) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_gui = KeymapKey(0, 1, 0, LGUI_T(KC_P));
|
||||
auto mod_tap_hold_lshft = KeymapKey(0, 2, 0, SFT_T(KC_A));
|
||||
|
||||
set_keymap({mod_tap_hold_gui, mod_tap_hold_lshft});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
mod_tap_hold_lshft.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_LEFT_GUI));
|
||||
mod_tap_hold_gui.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
mod_tap_hold_lshft.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI, DUMMY_MOD_NEUTRALIZER_KEYCODE));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_GUI));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
EXPECT_REPORT(driver, (KC_P, KC_LEFT_SHIFT));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_gui.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(RetroTapKeyRoll, mod_to_mod_to_mod) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
auto mod_tap_hold_lalt = KeymapKey(0, 1, 0, LALT_T(KC_R));
|
||||
auto mod_tap_hold_lshft = KeymapKey(0, 2, 0, SFT_T(KC_A));
|
||||
auto mod_tap_hold_lctrl = KeymapKey(0, 3, 0, LCTL_T(KC_C));
|
||||
|
||||
set_keymap({mod_tap_hold_lalt, mod_tap_hold_lshft, mod_tap_hold_lctrl});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_ALT));
|
||||
mod_tap_hold_lalt.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_LEFT_ALT));
|
||||
mod_tap_hold_lshft.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
mod_tap_hold_lalt.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_CTRL, KC_LEFT_SHIFT));
|
||||
EXPECT_NO_REPORT(driver);
|
||||
mod_tap_hold_lctrl.press();
|
||||
idle_for(TAPPING_TERM);
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_REPORT(driver, (KC_LEFT_CTRL));
|
||||
mod_tap_hold_lshft.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
EXPECT_REPORT(driver, (KC_C, KC_LEFT_SHIFT));
|
||||
EXPECT_REPORT(driver, (KC_LEFT_SHIFT));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
mod_tap_hold_lctrl.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
@ -22,7 +22,7 @@ _qmk_install() {
|
||||
echo "sys-devel/gcc multilib\ncross-arm-none-eabi/newlib nano" | sudo tee --append /etc/portage/package.use/qmkfirmware >/dev/null
|
||||
sudo emerge -auN sys-devel/gcc
|
||||
sudo emerge -au --noreplace \
|
||||
app-arch/unzip app-arch/zip net-misc/wget sys-devel/clang \
|
||||
app-arch/unzip app-arch/zip net-misc/wget llvm-core/clang \
|
||||
sys-devel/crossdev \>=dev-lang/python-3.7 dev-embedded/avrdude \
|
||||
dev-embedded/dfu-programmer app-mobilephone/dfu-util sys-apps/hwloc \
|
||||
dev-libs/hidapi
|
||||
|
Loading…
Reference in New Issue
Block a user