1
0
Fork 0

Manually format develop (#15003)

This commit is contained in:
Joel Challis 2021-11-01 19:18:33 +00:00 committed by GitHub
parent ee371c1295
commit 92385e30cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 595 additions and 523 deletions

View file

@ -17,7 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "adns5050.h" #include "adns5050.h"
#include "wait.h" #include "wait.h"
#include "debug.h" #include "debug.h"
@ -61,13 +60,9 @@ void adns_sync(void) {
writePinHigh(ADNS_CS_PIN); writePinHigh(ADNS_CS_PIN);
} }
void adns_cs_select(void) { void adns_cs_select(void) { writePinLow(ADNS_CS_PIN); }
writePinLow(ADNS_CS_PIN);
}
void adns_cs_deselect(void) { void adns_cs_deselect(void) { writePinHigh(ADNS_CS_PIN); }
writePinHigh(ADNS_CS_PIN);
}
uint8_t adns_serial_read(void) { uint8_t adns_serial_read(void) {
setPinInput(ADNS_SDIO_PIN); setPinInput(ADNS_SDIO_PIN);
@ -121,7 +116,7 @@ uint8_t adns_read_reg(uint8_t reg_addr) {
// We don't need a minimum tSRAD here. That's because a 4ms wait time is // We don't need a minimum tSRAD here. That's because a 4ms wait time is
// already included in adns_serial_write(), so we're good. // already included in adns_serial_write(), so we're good.
// See page 10 and 15 of the ADNS spec sheet. // See page 10 and 15 of the ADNS spec sheet.
//wait_us(4); // wait_us(4);
uint8_t byte = adns_serial_read(); uint8_t byte = adns_serial_read();
@ -138,7 +133,7 @@ uint8_t adns_read_reg(uint8_t reg_addr) {
void adns_write_reg(uint8_t reg_addr, uint8_t data) { void adns_write_reg(uint8_t reg_addr, uint8_t data) {
adns_cs_select(); adns_cs_select();
adns_serial_write( 0b10000000 | reg_addr ); adns_serial_write(0b10000000 | reg_addr);
adns_serial_write(data); adns_serial_write(data);
adns_cs_deselect(); adns_cs_deselect();
} }
@ -155,7 +150,7 @@ report_adns_t adns_read_burst(void) {
// We don't need a minimum tSRAD here. That's because a 4ms wait time is // We don't need a minimum tSRAD here. That's because a 4ms wait time is
// already included in adns_serial_write(), so we're good. // already included in adns_serial_write(), so we're good.
// See page 10 and 15 of the ADNS spec sheet. // See page 10 and 15 of the ADNS spec sheet.
//wait_us(4); // wait_us(4);
uint8_t x = adns_serial_read(); uint8_t x = adns_serial_read();
uint8_t y = adns_serial_read(); uint8_t y = adns_serial_read();
@ -180,13 +175,11 @@ int8_t convert_twoscomp(uint8_t data) {
} }
// Don't forget to use the definitions for CPI in the header file. // Don't forget to use the definitions for CPI in the header file.
void adns_set_cpi(uint8_t cpi) { void adns_set_cpi(uint8_t cpi) { adns_write_reg(REG_MOUSE_CONTROL2, cpi); }
adns_write_reg(REG_MOUSE_CONTROL2, cpi);
}
bool adns_check_signature(void) { bool adns_check_signature(void) {
uint8_t pid = adns_read_reg(REG_PRODUCT_ID); uint8_t pid = adns_read_reg(REG_PRODUCT_ID);
uint8_t rid = adns_read_reg(REG_REVISION_ID); uint8_t rid = adns_read_reg(REG_REVISION_ID);
uint8_t pid2 = adns_read_reg(REG_PRODUCT_ID2); uint8_t pid2 = adns_read_reg(REG_PRODUCT_ID2);
return (pid == 0x12 && rid == 0x01 && pid2 == 0x26); return (pid == 0x12 && rid == 0x01 && pid2 == 0x26);

View file

@ -67,13 +67,13 @@ typedef struct {
// A bunch of functions to implement the ADNS5050-specific serial protocol. // A bunch of functions to implement the ADNS5050-specific serial protocol.
// Note that the "serial.h" driver is insufficient, because it does not // Note that the "serial.h" driver is insufficient, because it does not
// manually manipulate a serial clock signal. // manually manipulate a serial clock signal.
void adns_init(void); void adns_init(void);
void adns_sync(void); void adns_sync(void);
uint8_t adns_serial_read(void); uint8_t adns_serial_read(void);
void adns_serial_write(uint8_t data); void adns_serial_write(uint8_t data);
uint8_t adns_read_reg(uint8_t reg_addr); uint8_t adns_read_reg(uint8_t reg_addr);
void adns_write_reg(uint8_t reg_addr, uint8_t data); void adns_write_reg(uint8_t reg_addr, uint8_t data);
report_adns_t adns_read_burst(void); report_adns_t adns_read_burst(void);
int8_t convert_twoscomp(uint8_t data); int8_t convert_twoscomp(uint8_t data);
void adns_set_cpi(uint8_t cpi); void adns_set_cpi(uint8_t cpi);
bool adns_check_signature(void); bool adns_check_signature(void);

View file

@ -20,57 +20,57 @@
#include "adns9800.h" #include "adns9800.h"
// registers // registers
#define REG_Product_ID 0x00 #define REG_Product_ID 0x00
#define REG_Revision_ID 0x01 #define REG_Revision_ID 0x01
#define REG_Motion 0x02 #define REG_Motion 0x02
#define REG_Delta_X_L 0x03 #define REG_Delta_X_L 0x03
#define REG_Delta_X_H 0x04 #define REG_Delta_X_H 0x04
#define REG_Delta_Y_L 0x05 #define REG_Delta_Y_L 0x05
#define REG_Delta_Y_H 0x06 #define REG_Delta_Y_H 0x06
#define REG_SQUAL 0x07 #define REG_SQUAL 0x07
#define REG_Pixel_Sum 0x08 #define REG_Pixel_Sum 0x08
#define REG_Maximum_Pixel 0x09 #define REG_Maximum_Pixel 0x09
#define REG_Minimum_Pixel 0x0a #define REG_Minimum_Pixel 0x0a
#define REG_Shutter_Lower 0x0b #define REG_Shutter_Lower 0x0b
#define REG_Shutter_Upper 0x0c #define REG_Shutter_Upper 0x0c
#define REG_Frame_Period_Lower 0x0d #define REG_Frame_Period_Lower 0x0d
#define REG_Frame_Period_Upper 0x0e #define REG_Frame_Period_Upper 0x0e
#define REG_Configuration_I 0x0f #define REG_Configuration_I 0x0f
#define REG_Configuration_II 0x10 #define REG_Configuration_II 0x10
#define REG_Frame_Capture 0x12 #define REG_Frame_Capture 0x12
#define REG_SROM_Enable 0x13 #define REG_SROM_Enable 0x13
#define REG_Run_Downshift 0x14 #define REG_Run_Downshift 0x14
#define REG_Rest1_Rate 0x15 #define REG_Rest1_Rate 0x15
#define REG_Rest1_Downshift 0x16 #define REG_Rest1_Downshift 0x16
#define REG_Rest2_Rate 0x17 #define REG_Rest2_Rate 0x17
#define REG_Rest2_Downshift 0x18 #define REG_Rest2_Downshift 0x18
#define REG_Rest3_Rate 0x19 #define REG_Rest3_Rate 0x19
#define REG_Frame_Period_Max_Bound_Lower 0x1a #define REG_Frame_Period_Max_Bound_Lower 0x1a
#define REG_Frame_Period_Max_Bound_Upper 0x1b #define REG_Frame_Period_Max_Bound_Upper 0x1b
#define REG_Frame_Period_Min_Bound_Lower 0x1c #define REG_Frame_Period_Min_Bound_Lower 0x1c
#define REG_Frame_Period_Min_Bound_Upper 0x1d #define REG_Frame_Period_Min_Bound_Upper 0x1d
#define REG_Shutter_Max_Bound_Lower 0x1e #define REG_Shutter_Max_Bound_Lower 0x1e
#define REG_Shutter_Max_Bound_Upper 0x1f #define REG_Shutter_Max_Bound_Upper 0x1f
#define REG_LASER_CTRL0 0x20 #define REG_LASER_CTRL0 0x20
#define REG_Observation 0x24 #define REG_Observation 0x24
#define REG_Data_Out_Lower 0x25 #define REG_Data_Out_Lower 0x25
#define REG_Data_Out_Upper 0x26 #define REG_Data_Out_Upper 0x26
#define REG_SROM_ID 0x2a #define REG_SROM_ID 0x2a
#define REG_Lift_Detection_Thr 0x2e #define REG_Lift_Detection_Thr 0x2e
#define REG_Configuration_V 0x2f #define REG_Configuration_V 0x2f
#define REG_Configuration_IV 0x39 #define REG_Configuration_IV 0x39
#define REG_Power_Up_Reset 0x3a #define REG_Power_Up_Reset 0x3a
#define REG_Shutdown 0x3b #define REG_Shutdown 0x3b
#define REG_Inverse_Product_ID 0x3f #define REG_Inverse_Product_ID 0x3f
#define REG_Motion_Burst 0x50 #define REG_Motion_Burst 0x50
#define REG_SROM_Load_Burst 0x62 #define REG_SROM_Load_Burst 0x62
#define REG_Pixel_Burst 0x64 #define REG_Pixel_Burst 0x64
#define ADNS_CLOCK_SPEED 2000000 #define ADNS_CLOCK_SPEED 2000000
#define MIN_CPI 200 #define MIN_CPI 200
#define MAX_CPI 8200 #define MAX_CPI 8200
#define CPI_STEP 200 #define CPI_STEP 200
#define CLAMP_CPI(value) value < MIN_CPI ? MIN_CPI : value > MAX_CPI ? MAX_CPI : value #define CLAMP_CPI(value) value<MIN_CPI ? MIN_CPI : value> MAX_CPI ? MAX_CPI : value
#define SPI_MODE 3 #define SPI_MODE 3
#define SPI_DIVISOR (F_CPU / ADNS_CLOCK_SPEED) #define SPI_DIVISOR (F_CPU / ADNS_CLOCK_SPEED)
#define US_BETWEEN_WRITES 120 #define US_BETWEEN_WRITES 120
@ -80,12 +80,9 @@
extern const uint8_t firmware_data[]; extern const uint8_t firmware_data[];
void adns_spi_start(void){ void adns_spi_start(void) { spi_start(SPI_SS_PIN, false, SPI_MODE, SPI_DIVISOR); }
spi_start(SPI_SS_PIN, false, SPI_MODE, SPI_DIVISOR);
}
void adns_write(uint8_t reg_addr, uint8_t data){
void adns_write(uint8_t reg_addr, uint8_t data) {
adns_spi_start(); adns_spi_start();
spi_write(reg_addr | MSB1); spi_write(reg_addr | MSB1);
spi_write(data); spi_write(data);
@ -93,10 +90,9 @@ void adns_write(uint8_t reg_addr, uint8_t data){
wait_us(US_BETWEEN_WRITES); wait_us(US_BETWEEN_WRITES);
} }
uint8_t adns_read(uint8_t reg_addr){ uint8_t adns_read(uint8_t reg_addr) {
adns_spi_start(); adns_spi_start();
spi_write(reg_addr & 0x7f ); spi_write(reg_addr & 0x7f);
uint8_t data = spi_read(); uint8_t data = spi_read();
spi_stop(); spi_stop();
wait_us(US_BETWEEN_READS); wait_us(US_BETWEEN_READS);
@ -105,7 +101,6 @@ uint8_t adns_read(uint8_t reg_addr){
} }
void adns_init() { void adns_init() {
setPinOutput(SPI_SS_PIN); setPinOutput(SPI_SS_PIN);
spi_init(); spi_init();
@ -144,7 +139,7 @@ void adns_init() {
// send all bytes of the firmware // send all bytes of the firmware
unsigned char c; unsigned char c;
for(int i = 0; i < FIRMWARE_LENGTH; i++){ for (int i = 0; i < FIRMWARE_LENGTH; i++) {
c = (unsigned char)pgm_read_byte(firmware_data + i); c = (unsigned char)pgm_read_byte(firmware_data + i);
spi_write(c); spi_write(c);
wait_us(15); wait_us(15);
@ -161,7 +156,7 @@ void adns_init() {
config_adns_t adns_get_config(void) { config_adns_t adns_get_config(void) {
uint8_t config_1 = adns_read(REG_Configuration_I); uint8_t config_1 = adns_read(REG_Configuration_I);
return (config_adns_t){ (config_1 & 0xFF) * CPI_STEP }; return (config_adns_t){(config_1 & 0xFF) * CPI_STEP};
} }
void adns_set_config(config_adns_t config) { void adns_set_config(config_adns_t config) {
@ -169,20 +164,17 @@ void adns_set_config(config_adns_t config) {
adns_write(REG_Configuration_I, config_1); adns_write(REG_Configuration_I, config_1);
} }
static int16_t convertDeltaToInt(uint8_t high, uint8_t low){ static int16_t convertDeltaToInt(uint8_t high, uint8_t low) {
// join bytes into twos compliment // join bytes into twos compliment
uint16_t twos_comp = (high << 8) | low; uint16_t twos_comp = (high << 8) | low;
// convert twos comp to int // convert twos comp to int
if (twos_comp & 0x8000) if (twos_comp & 0x8000) return -1 * (~twos_comp + 1);
return -1 * (~twos_comp + 1);
return twos_comp; return twos_comp;
} }
report_adns_t adns_get_report(void) { report_adns_t adns_get_report(void) {
report_adns_t report = {0, 0}; report_adns_t report = {0, 0};
adns_spi_start(); adns_spi_start();
@ -194,8 +186,7 @@ report_adns_t adns_get_report(void) {
uint8_t motion = spi_read(); uint8_t motion = spi_read();
if(motion & 0x80) { if (motion & 0x80) {
// clear observation register // clear observation register
spi_read(); spi_read();

View file

@ -28,8 +28,8 @@ typedef struct {
int16_t y; int16_t y;
} report_adns_t; } report_adns_t;
void adns_init(void); void adns_init(void);
config_adns_t adns_get_config(void); config_adns_t adns_get_config(void);
void adns_set_config(config_adns_t); void adns_set_config(config_adns_t);
/* Reads and clears the current delta values on the ADNS sensor */ /* Reads and clears the current delta values on the ADNS sensor */
report_adns_t adns_get_report(void); report_adns_t adns_get_report(void);

View file

@ -23,55 +23,55 @@
#include "pmw3360_firmware.h" #include "pmw3360_firmware.h"
// Registers // Registers
#define REG_Product_ID 0x00 #define REG_Product_ID 0x00
#define REG_Revision_ID 0x01 #define REG_Revision_ID 0x01
#define REG_Motion 0x02 #define REG_Motion 0x02
#define REG_Delta_X_L 0x03 #define REG_Delta_X_L 0x03
#define REG_Delta_X_H 0x04 #define REG_Delta_X_H 0x04
#define REG_Delta_Y_L 0x05 #define REG_Delta_Y_L 0x05
#define REG_Delta_Y_H 0x06 #define REG_Delta_Y_H 0x06
#define REG_SQUAL 0x07 #define REG_SQUAL 0x07
#define REG_Raw_Data_Sum 0x08 #define REG_Raw_Data_Sum 0x08
#define REG_Maximum_Raw_data 0x09 #define REG_Maximum_Raw_data 0x09
#define REG_Minimum_Raw_data 0x0A #define REG_Minimum_Raw_data 0x0A
#define REG_Shutter_Lower 0x0B #define REG_Shutter_Lower 0x0B
#define REG_Shutter_Upper 0x0C #define REG_Shutter_Upper 0x0C
#define REG_Control 0x0D #define REG_Control 0x0D
#define REG_Config1 0x0F #define REG_Config1 0x0F
#define REG_Config2 0x10 #define REG_Config2 0x10
#define REG_Angle_Tune 0x11 #define REG_Angle_Tune 0x11
#define REG_Frame_Capture 0x12 #define REG_Frame_Capture 0x12
#define REG_SROM_Enable 0x13 #define REG_SROM_Enable 0x13
#define REG_Run_Downshift 0x14 #define REG_Run_Downshift 0x14
#define REG_Rest1_Rate_Lower 0x15 #define REG_Rest1_Rate_Lower 0x15
#define REG_Rest1_Rate_Upper 0x16 #define REG_Rest1_Rate_Upper 0x16
#define REG_Rest1_Downshift 0x17 #define REG_Rest1_Downshift 0x17
#define REG_Rest2_Rate_Lower 0x18 #define REG_Rest2_Rate_Lower 0x18
#define REG_Rest2_Rate_Upper 0x19 #define REG_Rest2_Rate_Upper 0x19
#define REG_Rest2_Downshift 0x1A #define REG_Rest2_Downshift 0x1A
#define REG_Rest3_Rate_Lower 0x1B #define REG_Rest3_Rate_Lower 0x1B
#define REG_Rest3_Rate_Upper 0x1C #define REG_Rest3_Rate_Upper 0x1C
#define REG_Observation 0x24 #define REG_Observation 0x24
#define REG_Data_Out_Lower 0x25 #define REG_Data_Out_Lower 0x25
#define REG_Data_Out_Upper 0x26 #define REG_Data_Out_Upper 0x26
#define REG_Raw_Data_Dump 0x29 #define REG_Raw_Data_Dump 0x29
#define REG_SROM_ID 0x2A #define REG_SROM_ID 0x2A
#define REG_Min_SQ_Run 0x2B #define REG_Min_SQ_Run 0x2B
#define REG_Raw_Data_Threshold 0x2C #define REG_Raw_Data_Threshold 0x2C
#define REG_Config5 0x2F #define REG_Config5 0x2F
#define REG_Power_Up_Reset 0x3A #define REG_Power_Up_Reset 0x3A
#define REG_Shutdown 0x3B #define REG_Shutdown 0x3B
#define REG_Inverse_Product_ID 0x3F #define REG_Inverse_Product_ID 0x3F
#define REG_LiftCutoff_Tune3 0x41 #define REG_LiftCutoff_Tune3 0x41
#define REG_Angle_Snap 0x42 #define REG_Angle_Snap 0x42
#define REG_LiftCutoff_Tune1 0x4A #define REG_LiftCutoff_Tune1 0x4A
#define REG_Motion_Burst 0x50 #define REG_Motion_Burst 0x50
#define REG_LiftCutoff_Tune_Timeout 0x58 #define REG_LiftCutoff_Tune_Timeout 0x58
#define REG_LiftCutoff_Tune_Min_Length 0x5A #define REG_LiftCutoff_Tune_Min_Length 0x5A
#define REG_SROM_Load_Burst 0x62 #define REG_SROM_Load_Burst 0x62
#define REG_Lift_Config 0x63 #define REG_Lift_Config 0x63
#define REG_Raw_Data_Burst 0x64 #define REG_Raw_Data_Burst 0x64
#define REG_LiftCutoff_Tune2 0x65 #define REG_LiftCutoff_Tune2 0x65
bool _inBurst = false; bool _inBurst = false;

View file

@ -66,20 +66,17 @@ typedef struct {
int8_t mdy; int8_t mdy;
} report_pmw_t; } report_pmw_t;
bool spi_start_adv(void);
void spi_stop_adv(void);
bool spi_start_adv(void);
void spi_stop_adv(void);
spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data); spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data);
uint8_t spi_read_adv(uint8_t reg_addr); uint8_t spi_read_adv(uint8_t reg_addr);
bool pmw_spi_init(void); bool pmw_spi_init(void);
void pmw_set_cpi(uint16_t cpi); void pmw_set_cpi(uint16_t cpi);
uint16_t pmw_get_cpi(void); uint16_t pmw_get_cpi(void);
void pmw_upload_firmware(void); void pmw_upload_firmware(void);
bool pmw_check_signature(void); bool pmw_check_signature(void);
report_pmw_t pmw_read_burst(void); report_pmw_t pmw_read_burst(void);
#define degToRad(angleInDegrees) ((angleInDegrees)*M_PI / 180.0) #define degToRad(angleInDegrees) ((angleInDegrees)*M_PI / 180.0)
#define radToDeg(angleInRadians) ((angleInRadians)*180.0 / M_PI) #define radToDeg(angleInRadians) ((angleInRadians)*180.0 / M_PI)
#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) #define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))

View file

@ -22,7 +22,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void analogReference(uint8_t mode); void analogReference(uint8_t mode);
int16_t analogReadPin(pin_t pin); int16_t analogReadPin(pin_t pin);
uint8_t pinToMux(pin_t pin); uint8_t pinToMux(pin_t pin);

View file

@ -821,9 +821,10 @@ void register_code(uint8_t code) {
} }
#endif #endif
else if IS_KEY (code) { else if
// TODO: should push command_proc out of this block? IS_KEY(code) {
if (command_proc(code)) return; // TODO: should push command_proc out of this block?
if (command_proc(code)) return;
#ifndef NO_ACTION_ONESHOT #ifndef NO_ACTION_ONESHOT
/* TODO: remove /* TODO: remove
@ -840,33 +841,35 @@ void register_code(uint8_t code) {
} else } else
*/ */
#endif #endif
{ {
// Force a new key press if the key is already pressed // Force a new key press if the key is already pressed
// without this, keys with the same keycode, but different // without this, keys with the same keycode, but different
// modifiers will be reported incorrectly, see issue #1708 // modifiers will be reported incorrectly, see issue #1708
if (is_key_pressed(keyboard_report, code)) { if (is_key_pressed(keyboard_report, code)) {
del_key(code); del_key(code);
send_keyboard_report();
}
add_key(code);
send_keyboard_report(); send_keyboard_report();
} }
add_key(code); }
else if
IS_MOD(code) {
add_mods(MOD_BIT(code));
send_keyboard_report(); send_keyboard_report();
} }
} else if IS_MOD (code) {
add_mods(MOD_BIT(code));
send_keyboard_report();
}
#ifdef EXTRAKEY_ENABLE #ifdef EXTRAKEY_ENABLE
else if IS_SYSTEM (code) { else if
host_system_send(KEYCODE2SYSTEM(code)); IS_SYSTEM(code) { host_system_send(KEYCODE2SYSTEM(code)); }
} else if IS_CONSUMER (code) { else if
host_consumer_send(KEYCODE2CONSUMER(code)); IS_CONSUMER(code) { host_consumer_send(KEYCODE2CONSUMER(code)); }
}
#endif #endif
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
else if IS_MOUSEKEY (code) { else if
mousekey_on(code); IS_MOUSEKEY(code) {
mousekey_send(); mousekey_on(code);
} mousekey_send();
}
#endif #endif
} }
@ -911,22 +914,26 @@ void unregister_code(uint8_t code) {
} }
#endif #endif
else if IS_KEY (code) { else if
del_key(code); IS_KEY(code) {
send_keyboard_report(); del_key(code);
} else if IS_MOD (code) { send_keyboard_report();
del_mods(MOD_BIT(code)); }
send_keyboard_report(); else if
} else if IS_SYSTEM (code) { IS_MOD(code) {
host_system_send(0); del_mods(MOD_BIT(code));
} else if IS_CONSUMER (code) { send_keyboard_report();
host_consumer_send(0); }
} else if
IS_SYSTEM(code) { host_system_send(0); }
else if
IS_CONSUMER(code) { host_consumer_send(0); }
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
else if IS_MOUSEKEY (code) { else if
mousekey_off(code); IS_MOUSEKEY(code) {
mousekey_send(); mousekey_off(code);
} mousekey_send();
}
#endif #endif
} }

View file

@ -88,7 +88,7 @@ extern bool disable_action_cache;
/* Code for handling one-handed key modifiers. */ /* Code for handling one-handed key modifiers. */
#ifdef SWAP_HANDS_ENABLE #ifdef SWAP_HANDS_ENABLE
extern bool swap_hands; extern bool swap_hands;
extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS]; extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS];
# if (MATRIX_COLS <= 8) # if (MATRIX_COLS <= 8)
typedef uint8_t swap_state_row_t; typedef uint8_t swap_state_row_t;

View file

@ -18,11 +18,11 @@
# define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
# define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
# define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) # define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
#ifndef COMBO_ENABLE # ifndef COMBO_ENABLE
# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key))) # define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)))
#else # else
# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) # define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode)
#endif # endif
__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; } __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; }
@ -212,11 +212,15 @@ bool process_tapping(keyrecord_t *keyp) {
if (tapping_key.tap.count > 1) { if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last tap(>1).\n"); debug("Tapping: Start new tap with releasing last tap(>1).\n");
// unregister key // unregister key
process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, process_record(&(keyrecord_t){
#ifdef COMBO_ENABLE .tap = tapping_key.tap,
.keycode = tapping_key.keycode, .event.key = tapping_key.event.key,
#endif .event.time = event.time,
}); .event.pressed = false,
# ifdef COMBO_ENABLE
.keycode = tapping_key.keycode,
# endif
});
} else { } else {
debug("Tapping: Start while last tap(1).\n"); debug("Tapping: Start while last tap(1).\n");
} }
@ -254,11 +258,15 @@ bool process_tapping(keyrecord_t *keyp) {
if (tapping_key.tap.count > 1) { if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last timeout tap(>1).\n"); debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");
// unregister key // unregister key
process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, process_record(&(keyrecord_t){
#ifdef COMBO_ENABLE .tap = tapping_key.tap,
.keycode = tapping_key.keycode, .event.key = tapping_key.event.key,
#endif .event.time = event.time,
}); .event.pressed = false,
# ifdef COMBO_ENABLE
.keycode = tapping_key.keycode,
# endif
});
} else { } else {
debug("Tapping: Start while last timeout tap(1).\n"); debug("Tapping: Start while last timeout tap(1).\n");
} }

View file

@ -46,17 +46,17 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state.
#define ROW_SHIFTER ((matrix_row_t)1) #define ROW_SHIFTER ((matrix_row_t)1)
typedef struct { typedef struct {
bool pressed : 1; bool pressed : 1;
uint8_t time : 7; uint8_t time : 7;
} debounce_counter_t; } debounce_counter_t;
#if DEBOUNCE > 0 #if DEBOUNCE > 0
static debounce_counter_t *debounce_counters; static debounce_counter_t *debounce_counters;
static fast_timer_t last_time; static fast_timer_t last_time;
static bool counters_need_update; static bool counters_need_update;
static bool matrix_need_update; static bool matrix_need_update;
#define DEBOUNCE_ELAPSED 0 # define DEBOUNCE_ELAPSED 0
static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time); static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time);
static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
@ -64,7 +64,7 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui
// we use num_rows rather than MATRIX_ROWS to support split keyboards // we use num_rows rather than MATRIX_ROWS to support split keyboards
void debounce_init(uint8_t num_rows) { void debounce_init(uint8_t num_rows) {
debounce_counters = malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t)); debounce_counters = malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t));
int i = 0; int i = 0;
for (uint8_t r = 0; r < num_rows; r++) { for (uint8_t r = 0; r < num_rows; r++) {
for (uint8_t c = 0; c < MATRIX_COLS; c++) { for (uint8_t c = 0; c < MATRIX_COLS; c++) {
debounce_counters[i++].time = DEBOUNCE_ELAPSED; debounce_counters[i++].time = DEBOUNCE_ELAPSED;
@ -81,10 +81,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
bool updated_last = false; bool updated_last = false;
if (counters_need_update) { if (counters_need_update) {
fast_timer_t now = timer_read_fast(); fast_timer_t now = timer_read_fast();
fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
last_time = now; last_time = now;
updated_last = true; updated_last = true;
if (elapsed_time > UINT8_MAX) { if (elapsed_time > UINT8_MAX) {
elapsed_time = UINT8_MAX; elapsed_time = UINT8_MAX;
@ -108,7 +108,7 @@ static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[],
debounce_counter_t *debounce_pointer = debounce_counters; debounce_counter_t *debounce_pointer = debounce_counters;
counters_need_update = false; counters_need_update = false;
matrix_need_update = false; matrix_need_update = false;
for (uint8_t row = 0; row < num_rows; row++) { for (uint8_t row = 0; row < num_rows; row++) {
for (uint8_t col = 0; col < MATRIX_COLS; col++) { for (uint8_t col = 0; col < MATRIX_COLS; col++) {
@ -146,8 +146,8 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui
if (delta & col_mask) { if (delta & col_mask) {
if (debounce_pointer->time == DEBOUNCE_ELAPSED) { if (debounce_pointer->time == DEBOUNCE_ELAPSED) {
debounce_pointer->pressed = (raw[row] & col_mask); debounce_pointer->pressed = (raw[row] & col_mask);
debounce_pointer->time = DEBOUNCE; debounce_pointer->time = DEBOUNCE;
counters_need_update = true; counters_need_update = true;
if (debounce_pointer->pressed) { if (debounce_pointer->pressed) {
// key-down: eager // key-down: eager

View file

@ -25,7 +25,7 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state.
#endif #endif
#if DEBOUNCE > 0 #if DEBOUNCE > 0
static bool debouncing = false; static bool debouncing = false;
static fast_timer_t debouncing_time; static fast_timer_t debouncing_time;
void debounce_init(uint8_t num_rows) {} void debounce_init(uint8_t num_rows) {}

View file

@ -49,7 +49,7 @@ static debounce_counter_t *debounce_counters;
static fast_timer_t last_time; static fast_timer_t last_time;
static bool counters_need_update; static bool counters_need_update;
#define DEBOUNCE_ELAPSED 0 # define DEBOUNCE_ELAPSED 0
static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time); static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time);
static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
@ -74,10 +74,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
bool updated_last = false; bool updated_last = false;
if (counters_need_update) { if (counters_need_update) {
fast_timer_t now = timer_read_fast(); fast_timer_t now = timer_read_fast();
fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
last_time = now; last_time = now;
updated_last = true; updated_last = true;
if (elapsed_time > UINT8_MAX) { if (elapsed_time > UINT8_MAX) {
elapsed_time = UINT8_MAX; elapsed_time = UINT8_MAX;

View file

@ -50,7 +50,7 @@ static fast_timer_t last_time;
static bool counters_need_update; static bool counters_need_update;
static bool matrix_need_update; static bool matrix_need_update;
#define DEBOUNCE_ELAPSED 0 # define DEBOUNCE_ELAPSED 0
static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time); static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);
static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
@ -75,10 +75,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
bool updated_last = false; bool updated_last = false;
if (counters_need_update) { if (counters_need_update) {
fast_timer_t now = timer_read_fast(); fast_timer_t now = timer_read_fast();
fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
last_time = now; last_time = now;
updated_last = true; updated_last = true;
if (elapsed_time > UINT8_MAX) { if (elapsed_time > UINT8_MAX) {
elapsed_time = UINT8_MAX; elapsed_time = UINT8_MAX;
@ -107,7 +107,7 @@ static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) {
for (uint8_t col = 0; col < MATRIX_COLS; col++) { for (uint8_t col = 0; col < MATRIX_COLS; col++) {
if (*debounce_pointer != DEBOUNCE_ELAPSED) { if (*debounce_pointer != DEBOUNCE_ELAPSED) {
if (*debounce_pointer <= elapsed_time) { if (*debounce_pointer <= elapsed_time) {
*debounce_pointer = DEBOUNCE_ELAPSED; *debounce_pointer = DEBOUNCE_ELAPSED;
matrix_need_update = true; matrix_need_update = true;
} else { } else {
*debounce_pointer -= elapsed_time; *debounce_pointer -= elapsed_time;

View file

@ -49,7 +49,7 @@ static debounce_counter_t *debounce_counters;
static fast_timer_t last_time; static fast_timer_t last_time;
static bool counters_need_update; static bool counters_need_update;
#define DEBOUNCE_ELAPSED 0 # define DEBOUNCE_ELAPSED 0
static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time); static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);
static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
@ -71,10 +71,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
bool updated_last = false; bool updated_last = false;
if (counters_need_update) { if (counters_need_update) {
fast_timer_t now = timer_read_fast(); fast_timer_t now = timer_read_fast();
fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
last_time = now; last_time = now;
updated_last = true; updated_last = true;
if (elapsed_time > UINT8_MAX) { if (elapsed_time > UINT8_MAX) {
elapsed_time = UINT8_MAX; elapsed_time = UINT8_MAX;
@ -102,7 +102,7 @@ static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) {
for (uint8_t row = 0; row < num_rows; row++) { for (uint8_t row = 0; row < num_rows; row++) {
if (*debounce_pointer != DEBOUNCE_ELAPSED) { if (*debounce_pointer != DEBOUNCE_ELAPSED) {
if (*debounce_pointer <= elapsed_time) { if (*debounce_pointer <= elapsed_time) {
*debounce_pointer = DEBOUNCE_ELAPSED; *debounce_pointer = DEBOUNCE_ELAPSED;
matrix_need_update = true; matrix_need_update = true;
} else { } else {
*debounce_pointer -= elapsed_time; *debounce_pointer -= elapsed_time;

View file

@ -19,7 +19,8 @@
#include "debounce_test_common.h" #include "debounce_test_common.h"
TEST_F(DebounceTest, OneKeyShort1) { TEST_F(DebounceTest, OneKeyShort1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 1ms delay */ /* Release key after 1ms delay */
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -43,7 +44,8 @@ TEST_F(DebounceTest, OneKeyShort1) {
} }
TEST_F(DebounceTest, OneKeyShort2) { TEST_F(DebounceTest, OneKeyShort2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 2ms delay */ /* Release key after 2ms delay */
{2, {{0, 1, UP}}, {}}, {2, {{0, 1, UP}}, {}},
@ -58,7 +60,8 @@ TEST_F(DebounceTest, OneKeyShort2) {
} }
TEST_F(DebounceTest, OneKeyShort3) { TEST_F(DebounceTest, OneKeyShort3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 3ms delay */ /* Release key after 3ms delay */
{3, {{0, 1, UP}}, {}}, {3, {{0, 1, UP}}, {}},
@ -73,7 +76,8 @@ TEST_F(DebounceTest, OneKeyShort3) {
} }
TEST_F(DebounceTest, OneKeyShort4) { TEST_F(DebounceTest, OneKeyShort4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 4ms delay */ /* Release key after 4ms delay */
{4, {{0, 1, UP}}, {}}, {4, {{0, 1, UP}}, {}},
@ -88,7 +92,8 @@ TEST_F(DebounceTest, OneKeyShort4) {
} }
TEST_F(DebounceTest, OneKeyShort5) { TEST_F(DebounceTest, OneKeyShort5) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 5ms delay */ /* Release key after 5ms delay */
@ -102,7 +107,8 @@ TEST_F(DebounceTest, OneKeyShort5) {
} }
TEST_F(DebounceTest, OneKeyShort6) { TEST_F(DebounceTest, OneKeyShort6) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 6ms delay */ /* Release key after 6ms delay */
@ -116,7 +122,8 @@ TEST_F(DebounceTest, OneKeyShort6) {
} }
TEST_F(DebounceTest, OneKeyShort7) { TEST_F(DebounceTest, OneKeyShort7) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 7ms delay */ /* Release key after 7ms delay */
@ -130,7 +137,8 @@ TEST_F(DebounceTest, OneKeyShort7) {
} }
TEST_F(DebounceTest, OneKeyShort8) { TEST_F(DebounceTest, OneKeyShort8) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 1ms delay */ /* Release key after 1ms delay */
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -145,7 +153,8 @@ TEST_F(DebounceTest, OneKeyShort8) {
} }
TEST_F(DebounceTest, OneKeyShort9) { TEST_F(DebounceTest, OneKeyShort9) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Release key after 1ms delay */ /* Release key after 1ms delay */
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -159,7 +168,8 @@ TEST_F(DebounceTest, OneKeyShort9) {
} }
TEST_F(DebounceTest, OneKeyBouncing1) { TEST_F(DebounceTest, OneKeyBouncing1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
{2, {{0, 1, DOWN}}, {}}, {2, {{0, 1, DOWN}}, {}},
@ -185,7 +195,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {
} }
TEST_F(DebounceTest, OneKeyBouncing2) { TEST_F(DebounceTest, OneKeyBouncing2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Change twice in the same time period */ /* Change twice in the same time period */
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -217,7 +228,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {
} }
TEST_F(DebounceTest, OneKeyLong) { TEST_F(DebounceTest, OneKeyLong) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{25, {{0, 1, UP}}, {}}, {25, {{0, 1, UP}}, {}},
@ -236,7 +248,8 @@ TEST_F(DebounceTest, OneKeyLong) {
} }
TEST_F(DebounceTest, TwoKeysShort) { TEST_F(DebounceTest, TwoKeysShort) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, {1, {{0, 2, DOWN}}, {{0, 2, DOWN}}},
/* Release key after 2ms delay */ /* Release key after 2ms delay */
@ -249,14 +262,14 @@ TEST_F(DebounceTest, TwoKeysShort) {
{10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */ {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */
/* Press key again after 1ms delay */ /* Press key again after 1ms delay */
{11, {{0, 1, DOWN}}, {{0, 1, DOWN}, {0, 2, UP}}}, /* 5ms+5ms after DOWN at time 0 */ {11, {{0, 1, DOWN}}, {{0, 1, DOWN}, {0, 2, UP}}}, /* 5ms+5ms after DOWN at time 0 */
{12, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, /* 5ms+5ms after DOWN at time 0 */ {12, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, /* 5ms+5ms after DOWN at time 0 */
}); });
runEvents(); runEvents();
} }
TEST_F(DebounceTest, OneKeyDelayedScan1) { TEST_F(DebounceTest, OneKeyDelayedScan1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late, immediately release key */ /* Processing is very late, immediately release key */
@ -269,7 +282,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan2) { TEST_F(DebounceTest, OneKeyDelayedScan2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late, immediately release key */ /* Processing is very late, immediately release key */
@ -283,7 +297,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan3) { TEST_F(DebounceTest, OneKeyDelayedScan3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late */ /* Processing is very late */
@ -298,7 +313,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan4) { TEST_F(DebounceTest, OneKeyDelayedScan4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late */ /* Processing is very late */
@ -314,7 +330,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan4) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan5) { TEST_F(DebounceTest, OneKeyDelayedScan5) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{5, {{0, 1, UP}}, {}}, {5, {{0, 1, UP}}, {}},
@ -329,7 +346,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan5) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan6) { TEST_F(DebounceTest, OneKeyDelayedScan6) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{5, {{0, 1, UP}}, {}}, {5, {{0, 1, UP}}, {}},
@ -345,7 +363,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan6) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan7) { TEST_F(DebounceTest, OneKeyDelayedScan7) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{5, {{0, 1, UP}}, {}}, {5, {{0, 1, UP}}, {}},
@ -358,7 +377,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan7) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan8) { TEST_F(DebounceTest, OneKeyDelayedScan8) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is a bit late */ /* Processing is a bit late */

View file

@ -31,9 +31,7 @@ void set_time(uint32_t t);
void advance_time(uint32_t ms); void advance_time(uint32_t ms);
} }
void DebounceTest::addEvents(std::initializer_list<DebounceTestEvent> events) { void DebounceTest::addEvents(std::initializer_list<DebounceTestEvent> events) { events_.insert(events_.end(), events.begin(), events.end()); }
events_.insert(events_.end(), events.begin(), events.end());
}
void DebounceTest::runEvents() { void DebounceTest::runEvents() {
/* Run the test multiple times, from 1kHz to 10kHz scan rate */ /* Run the test multiple times, from 1kHz to 10kHz scan rate */
@ -54,7 +52,7 @@ void DebounceTest::runEvents() {
void DebounceTest::runEventsInternal() { void DebounceTest::runEventsInternal() {
fast_timer_t previous = 0; fast_timer_t previous = 0;
bool first = true; bool first = true;
/* Initialise keyboard with start time (offset to avoid testing at 0) and all keys UP */ /* Initialise keyboard with start time (offset to avoid testing at 0) and all keys UP */
debounce_init(MATRIX_ROWS); debounce_init(MATRIX_ROWS);
@ -80,7 +78,7 @@ void DebounceTest::runEventsInternal() {
} }
} }
first = false; first = false;
previous = event.time_; previous = event.time_;
/* Prepare input matrix */ /* Prepare input matrix */
@ -98,12 +96,7 @@ void DebounceTest::runEventsInternal() {
/* Check output matrix has expected change events */ /* Check output matrix has expected change events */
for (auto &output : event.outputs_) { for (auto &output : event.outputs_) {
EXPECT_EQ(!!(cooked_matrix_[output.row_] & (1U << output.col_)), directionValue(output.direction_)) EXPECT_EQ(!!(cooked_matrix_[output.row_] & (1U << output.col_)), directionValue(output.direction_)) << "Missing event at " << strTime() << " expected key " << output.row_ << "," << output.col_ << " " << directionLabel(output.direction_) << "\ninput_matrix: changed=" << !event.inputs_.empty() << "\n" << strMatrix(input_matrix_) << "\nexpected_matrix:\n" << strMatrix(output_matrix_) << "\nactual_matrix:\n" << strMatrix(cooked_matrix_);
<< "Missing event at " << strTime()
<< " expected key " << output.row_ << "," << output.col_ << " " << directionLabel(output.direction_)
<< "\ninput_matrix: changed=" << !event.inputs_.empty() << "\n" << strMatrix(input_matrix_)
<< "\nexpected_matrix:\n" << strMatrix(output_matrix_)
<< "\nactual_matrix:\n" << strMatrix(cooked_matrix_);
} }
/* Check output matrix has no other changes */ /* Check output matrix has no other changes */
@ -133,27 +126,20 @@ void DebounceTest::runDebounce(bool changed) {
debounce(raw_matrix_, cooked_matrix_, MATRIX_ROWS, changed); debounce(raw_matrix_, cooked_matrix_, MATRIX_ROWS, changed);
if (!std::equal(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_))) { if (!std::equal(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_))) {
FAIL() << "Fatal error: debounce() modified raw matrix at " << strTime() FAIL() << "Fatal error: debounce() modified raw matrix at " << strTime() << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) << "\nraw_matrix:\n" << strMatrix(raw_matrix_);
<< "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_)
<< "\nraw_matrix:\n" << strMatrix(raw_matrix_);
} }
} }
void DebounceTest::checkCookedMatrix(bool changed, const std::string &error_message) { void DebounceTest::checkCookedMatrix(bool changed, const std::string &error_message) {
if (!std::equal(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_))) { if (!std::equal(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_))) {
FAIL() << "Unexpected event: " << error_message << " at " << strTime() FAIL() << "Unexpected event: " << error_message << " at " << strTime() << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) << "\nexpected_matrix:\n" << strMatrix(output_matrix_) << "\nactual_matrix:\n" << strMatrix(cooked_matrix_);
<< "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_)
<< "\nexpected_matrix:\n" << strMatrix(output_matrix_)
<< "\nactual_matrix:\n" << strMatrix(cooked_matrix_);
} }
} }
std::string DebounceTest::strTime() { std::string DebounceTest::strTime() {
std::stringstream text; std::stringstream text;
text << "time " << (timer_read_fast() - time_offset_) text << "time " << (timer_read_fast() - time_offset_) << " (extra_iterations=" << extra_iterations_ << ", auto_advance_time=" << auto_advance_time_ << ")";
<< " (extra_iterations=" << extra_iterations_
<< ", auto_advance_time=" << auto_advance_time_ << ")";
return text.str(); return text.str();
} }
@ -181,49 +167,39 @@ std::string DebounceTest::strMatrix(matrix_row_t matrix[]) {
bool DebounceTest::directionValue(Direction direction) { bool DebounceTest::directionValue(Direction direction) {
switch (direction) { switch (direction) {
case DOWN: case DOWN:
return true; return true;
case UP: case UP:
return false; return false;
} }
} }
std::string DebounceTest::directionLabel(Direction direction) { std::string DebounceTest::directionLabel(Direction direction) {
switch (direction) { switch (direction) {
case DOWN: case DOWN:
return "DOWN"; return "DOWN";
case UP: case UP:
return "UP"; return "UP";
} }
} }
/* Modify a matrix and verify that events always specify a change */ /* Modify a matrix and verify that events always specify a change */
void DebounceTest::matrixUpdate(matrix_row_t matrix[], const std::string &name, const MatrixTestEvent &event) { void DebounceTest::matrixUpdate(matrix_row_t matrix[], const std::string &name, const MatrixTestEvent &event) {
ASSERT_NE(!!(matrix[event.row_] & (1U << event.col_)), directionValue(event.direction_)) ASSERT_NE(!!(matrix[event.row_] & (1U << event.col_)), directionValue(event.direction_)) << "Test " << name << " at " << strTime() << " sets key " << event.row_ << "," << event.col_ << " " << directionLabel(event.direction_) << " but it is already " << directionLabel(event.direction_) << "\n" << name << "_matrix:\n" << strMatrix(matrix);
<< "Test " << name << " at " << strTime()
<< " sets key " << event.row_ << "," << event.col_ << " " << directionLabel(event.direction_)
<< " but it is already " << directionLabel(event.direction_)
<< "\n" << name << "_matrix:\n" << strMatrix(matrix);
switch (event.direction_) { switch (event.direction_) {
case DOWN: case DOWN:
matrix[event.row_] |= (1U << event.col_); matrix[event.row_] |= (1U << event.col_);
break; break;
case UP: case UP:
matrix[event.row_] &= ~(1U << event.col_); matrix[event.row_] &= ~(1U << event.col_);
break; break;
} }
} }
DebounceTestEvent::DebounceTestEvent(fast_timer_t time, DebounceTestEvent::DebounceTestEvent(fast_timer_t time, std::initializer_list<MatrixTestEvent> inputs, std::initializer_list<MatrixTestEvent> outputs) : time_(time), inputs_(inputs), outputs_(outputs) {}
std::initializer_list<MatrixTestEvent> inputs,
std::initializer_list<MatrixTestEvent> outputs)
: time_(time), inputs_(inputs), outputs_(outputs) {
}
MatrixTestEvent::MatrixTestEvent(int row, int col, Direction direction) MatrixTestEvent::MatrixTestEvent(int row, int col, Direction direction) : row_(row), col_(col), direction_(direction) {}
: row_(row), col_(col), direction_(direction) {
}

View file

@ -31,36 +31,34 @@ enum Direction {
}; };
class MatrixTestEvent { class MatrixTestEvent {
public: public:
MatrixTestEvent(int row, int col, Direction direction); MatrixTestEvent(int row, int col, Direction direction);
const int row_; const int row_;
const int col_; const int col_;
const Direction direction_; const Direction direction_;
}; };
class DebounceTestEvent { class DebounceTestEvent {
public: public:
// 0, {{0, 1, DOWN}}, {{0, 1, DOWN}}) // 0, {{0, 1, DOWN}}, {{0, 1, DOWN}})
DebounceTestEvent(fast_timer_t time, DebounceTestEvent(fast_timer_t time, std::initializer_list<MatrixTestEvent> inputs, std::initializer_list<MatrixTestEvent> outputs);
std::initializer_list<MatrixTestEvent> inputs,
std::initializer_list<MatrixTestEvent> outputs);
const fast_timer_t time_; const fast_timer_t time_;
const std::list<MatrixTestEvent> inputs_; const std::list<MatrixTestEvent> inputs_;
const std::list<MatrixTestEvent> outputs_; const std::list<MatrixTestEvent> outputs_;
}; };
class DebounceTest : public ::testing::Test { class DebounceTest : public ::testing::Test {
protected: protected:
void addEvents(std::initializer_list<DebounceTestEvent> events); void addEvents(std::initializer_list<DebounceTestEvent> events);
void runEvents(); void runEvents();
fast_timer_t time_offset_ = 7777; fast_timer_t time_offset_ = 7777;
bool time_jumps_ = false; bool time_jumps_ = false;
private: private:
static bool directionValue(Direction direction); static bool directionValue(Direction direction);
static std::string directionLabel(Direction direction); static std::string directionLabel(Direction direction);
void runEventsInternal(); void runEventsInternal();
@ -78,6 +76,6 @@ private:
matrix_row_t cooked_matrix_[MATRIX_ROWS]; matrix_row_t cooked_matrix_[MATRIX_ROWS];
matrix_row_t output_matrix_[MATRIX_ROWS]; matrix_row_t output_matrix_[MATRIX_ROWS];
int extra_iterations_; int extra_iterations_;
bool auto_advance_time_; bool auto_advance_time_;
}; };

View file

@ -19,7 +19,8 @@
#include "debounce_test_common.h" #include "debounce_test_common.h"
TEST_F(DebounceTest, OneKeyShort1) { TEST_F(DebounceTest, OneKeyShort1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {
} }
TEST_F(DebounceTest, OneKeyShort2) { TEST_F(DebounceTest, OneKeyShort2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {
} }
TEST_F(DebounceTest, OneKeyShort3) { TEST_F(DebounceTest, OneKeyShort3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {
} }
TEST_F(DebounceTest, OneKeyTooQuick1) { TEST_F(DebounceTest, OneKeyTooQuick1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Release key exactly on the debounce time */ /* Release key exactly on the debounce time */
{5, {{0, 1, UP}}, {}}, {5, {{0, 1, UP}}, {}},
@ -67,7 +71,8 @@ TEST_F(DebounceTest, OneKeyTooQuick1) {
} }
TEST_F(DebounceTest, OneKeyTooQuick2) { TEST_F(DebounceTest, OneKeyTooQuick2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -80,7 +85,8 @@ TEST_F(DebounceTest, OneKeyTooQuick2) {
} }
TEST_F(DebounceTest, OneKeyBouncing1) { TEST_F(DebounceTest, OneKeyBouncing1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
{2, {{0, 1, DOWN}}, {}}, {2, {{0, 1, DOWN}}, {}},
@ -94,7 +100,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {
} }
TEST_F(DebounceTest, OneKeyBouncing2) { TEST_F(DebounceTest, OneKeyBouncing2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
{6, {{0, 1, UP}}, {}}, {6, {{0, 1, UP}}, {}},
@ -108,7 +115,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {
} }
TEST_F(DebounceTest, OneKeyLong) { TEST_F(DebounceTest, OneKeyLong) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -125,7 +133,8 @@ TEST_F(DebounceTest, OneKeyLong) {
} }
TEST_F(DebounceTest, TwoKeysShort) { TEST_F(DebounceTest, TwoKeysShort) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{1, {{0, 2, DOWN}}, {}}, {1, {{0, 2, DOWN}}, {}},
@ -140,7 +149,8 @@ TEST_F(DebounceTest, TwoKeysShort) {
} }
TEST_F(DebounceTest, TwoKeysSimultaneous1) { TEST_F(DebounceTest, TwoKeysSimultaneous1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}}, {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}},
@ -152,7 +162,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous1) {
} }
TEST_F(DebounceTest, TwoKeysSimultaneous2) { TEST_F(DebounceTest, TwoKeysSimultaneous2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{1, {{0, 2, DOWN}}, {}}, {1, {{0, 2, DOWN}}, {}},
@ -167,7 +178,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan1) { TEST_F(DebounceTest, OneKeyDelayedScan1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Processing is very late */ /* Processing is very late */
@ -182,7 +194,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan2) { TEST_F(DebounceTest, OneKeyDelayedScan2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Processing is very late */ /* Processing is very late */
@ -197,7 +210,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan3) { TEST_F(DebounceTest, OneKeyDelayedScan3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Release key before debounce expires */ /* Release key before debounce expires */
@ -208,7 +222,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan4) { TEST_F(DebounceTest, OneKeyDelayedScan4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Processing is a bit late */ /* Processing is a bit late */

View file

@ -19,7 +19,8 @@
#include "debounce_test_common.h" #include "debounce_test_common.h"
TEST_F(DebounceTest, OneKeyShort1) { TEST_F(DebounceTest, OneKeyShort1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {
} }
TEST_F(DebounceTest, OneKeyShort2) { TEST_F(DebounceTest, OneKeyShort2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {
} }
TEST_F(DebounceTest, OneKeyShort3) { TEST_F(DebounceTest, OneKeyShort3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {
} }
TEST_F(DebounceTest, OneKeyTooQuick1) { TEST_F(DebounceTest, OneKeyTooQuick1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Release key exactly on the debounce time */ /* Release key exactly on the debounce time */
{5, {{0, 1, UP}}, {}}, {5, {{0, 1, UP}}, {}},
@ -67,7 +71,8 @@ TEST_F(DebounceTest, OneKeyTooQuick1) {
} }
TEST_F(DebounceTest, OneKeyTooQuick2) { TEST_F(DebounceTest, OneKeyTooQuick2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -80,7 +85,8 @@ TEST_F(DebounceTest, OneKeyTooQuick2) {
} }
TEST_F(DebounceTest, OneKeyBouncing1) { TEST_F(DebounceTest, OneKeyBouncing1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
{2, {{0, 1, DOWN}}, {}}, {2, {{0, 1, DOWN}}, {}},
@ -94,7 +100,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {
} }
TEST_F(DebounceTest, OneKeyBouncing2) { TEST_F(DebounceTest, OneKeyBouncing2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
{6, {{0, 1, UP}}, {}}, {6, {{0, 1, UP}}, {}},
@ -108,7 +115,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {
} }
TEST_F(DebounceTest, OneKeyLong) { TEST_F(DebounceTest, OneKeyLong) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}}}, {5, {}, {{0, 1, DOWN}}},
@ -125,7 +133,8 @@ TEST_F(DebounceTest, OneKeyLong) {
} }
TEST_F(DebounceTest, TwoKeysShort) { TEST_F(DebounceTest, TwoKeysShort) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{1, {{0, 2, DOWN}}, {}}, {1, {{0, 2, DOWN}}, {}},
@ -142,7 +151,8 @@ TEST_F(DebounceTest, TwoKeysShort) {
} }
TEST_F(DebounceTest, TwoKeysSimultaneous1) { TEST_F(DebounceTest, TwoKeysSimultaneous1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}}, {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}},
{5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}},
@ -154,7 +164,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous1) {
} }
TEST_F(DebounceTest, TwoKeysSimultaneous2) { TEST_F(DebounceTest, TwoKeysSimultaneous2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
{1, {{0, 2, DOWN}}, {}}, {1, {{0, 2, DOWN}}, {}},
@ -169,7 +180,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan1) { TEST_F(DebounceTest, OneKeyDelayedScan1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Processing is very late */ /* Processing is very late */
@ -184,7 +196,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan2) { TEST_F(DebounceTest, OneKeyDelayedScan2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Processing is very late */ /* Processing is very late */
@ -199,7 +212,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan3) { TEST_F(DebounceTest, OneKeyDelayedScan3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Release key before debounce expires */ /* Release key before debounce expires */
@ -210,7 +224,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan4) { TEST_F(DebounceTest, OneKeyDelayedScan4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {}}, {0, {{0, 1, DOWN}}, {}},
/* Processing is a bit late */ /* Processing is a bit late */

View file

@ -19,7 +19,8 @@
#include "debounce_test_common.h" #include "debounce_test_common.h"
TEST_F(DebounceTest, OneKeyShort1) { TEST_F(DebounceTest, OneKeyShort1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {
} }
TEST_F(DebounceTest, OneKeyShort2) { TEST_F(DebounceTest, OneKeyShort2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {
} }
TEST_F(DebounceTest, OneKeyShort3) { TEST_F(DebounceTest, OneKeyShort3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {
} }
TEST_F(DebounceTest, OneKeyShort4) { TEST_F(DebounceTest, OneKeyShort4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -71,7 +75,8 @@ TEST_F(DebounceTest, OneKeyShort4) {
} }
TEST_F(DebounceTest, OneKeyShort5) { TEST_F(DebounceTest, OneKeyShort5) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -83,7 +88,8 @@ TEST_F(DebounceTest, OneKeyShort5) {
} }
TEST_F(DebounceTest, OneKeyShort6) { TEST_F(DebounceTest, OneKeyShort6) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -95,7 +101,8 @@ TEST_F(DebounceTest, OneKeyShort6) {
} }
TEST_F(DebounceTest, OneKeyBouncing1) { TEST_F(DebounceTest, OneKeyBouncing1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
{2, {{0, 1, DOWN}}, {}}, {2, {{0, 1, DOWN}}, {}},
@ -110,7 +117,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {
} }
TEST_F(DebounceTest, OneKeyBouncing2) { TEST_F(DebounceTest, OneKeyBouncing2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Change twice in the same time period */ /* Change twice in the same time period */
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -135,7 +143,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {
} }
TEST_F(DebounceTest, OneKeyLong) { TEST_F(DebounceTest, OneKeyLong) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{25, {{0, 1, UP}}, {{0, 1, UP}}}, {25, {{0, 1, UP}}, {{0, 1, UP}}},
@ -146,7 +155,8 @@ TEST_F(DebounceTest, OneKeyLong) {
} }
TEST_F(DebounceTest, TwoKeysShort) { TEST_F(DebounceTest, TwoKeysShort) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
{2, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, {2, {{0, 2, DOWN}}, {{0, 2, DOWN}}},
@ -167,7 +177,8 @@ TEST_F(DebounceTest, TwoKeysShort) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan1) { TEST_F(DebounceTest, OneKeyDelayedScan1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted */ /* Processing is very late but the change will now be accepted */
@ -178,7 +189,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan2) { TEST_F(DebounceTest, OneKeyDelayedScan2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1 scan delay */ /* Processing is very late but the change will now be accepted even with a 1 scan delay */
@ -190,7 +202,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan3) { TEST_F(DebounceTest, OneKeyDelayedScan3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1ms delay */ /* Processing is very late but the change will now be accepted even with a 1ms delay */
@ -202,7 +215,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan4) { TEST_F(DebounceTest, OneKeyDelayedScan4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is a bit late but the change will now be accepted */ /* Processing is a bit late but the change will now be accepted */
@ -213,7 +227,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan4) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan5) { TEST_F(DebounceTest, OneKeyDelayedScan5) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1 scan delay */ /* Processing is very late but the change will now be accepted even with a 1 scan delay */
@ -225,7 +240,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan5) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan6) { TEST_F(DebounceTest, OneKeyDelayedScan6) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1ms delay */ /* Processing is very late but the change will now be accepted even with a 1ms delay */

View file

@ -19,7 +19,8 @@
#include "debounce_test_common.h" #include "debounce_test_common.h"
TEST_F(DebounceTest, OneKeyShort1) { TEST_F(DebounceTest, OneKeyShort1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {
} }
TEST_F(DebounceTest, OneKeyShort2) { TEST_F(DebounceTest, OneKeyShort2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {
} }
TEST_F(DebounceTest, OneKeyShort3) { TEST_F(DebounceTest, OneKeyShort3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {
} }
TEST_F(DebounceTest, OneKeyShort4) { TEST_F(DebounceTest, OneKeyShort4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -71,7 +75,8 @@ TEST_F(DebounceTest, OneKeyShort4) {
} }
TEST_F(DebounceTest, OneKeyShort5) { TEST_F(DebounceTest, OneKeyShort5) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -83,7 +88,8 @@ TEST_F(DebounceTest, OneKeyShort5) {
} }
TEST_F(DebounceTest, OneKeyShort6) { TEST_F(DebounceTest, OneKeyShort6) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -95,7 +101,8 @@ TEST_F(DebounceTest, OneKeyShort6) {
} }
TEST_F(DebounceTest, OneKeyBouncing1) { TEST_F(DebounceTest, OneKeyBouncing1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
{2, {{0, 1, DOWN}}, {}}, {2, {{0, 1, DOWN}}, {}},
@ -110,7 +117,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {
} }
TEST_F(DebounceTest, OneKeyBouncing2) { TEST_F(DebounceTest, OneKeyBouncing2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Change twice in the same time period */ /* Change twice in the same time period */
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
@ -135,7 +143,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {
} }
TEST_F(DebounceTest, OneKeyLong) { TEST_F(DebounceTest, OneKeyLong) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{25, {{0, 1, UP}}, {{0, 1, UP}}}, {25, {{0, 1, UP}}, {{0, 1, UP}}},
@ -146,7 +155,8 @@ TEST_F(DebounceTest, OneKeyLong) {
} }
TEST_F(DebounceTest, TwoRowsShort) { TEST_F(DebounceTest, TwoRowsShort) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
{2, {{2, 0, DOWN}}, {{2, 0, DOWN}}}, {2, {{2, 0, DOWN}}, {{2, 0, DOWN}}},
@ -167,7 +177,8 @@ TEST_F(DebounceTest, TwoRowsShort) {
} }
TEST_F(DebounceTest, TwoKeysOverlap) { TEST_F(DebounceTest, TwoKeysOverlap) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
{1, {{0, 1, UP}}, {}}, {1, {{0, 1, UP}}, {}},
/* Press a second key during the first debounce */ /* Press a second key during the first debounce */
@ -190,7 +201,8 @@ TEST_F(DebounceTest, TwoKeysOverlap) {
} }
TEST_F(DebounceTest, TwoKeysSimultaneous1) { TEST_F(DebounceTest, TwoKeysSimultaneous1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}}, {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}},
{20, {{0, 1, UP}}, {{0, 1, UP}}}, {20, {{0, 1, UP}}, {{0, 1, UP}}},
{21, {{0, 2, UP}}, {}}, {21, {{0, 2, UP}}, {}},
@ -202,7 +214,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous1) {
} }
TEST_F(DebounceTest, TwoKeysSimultaneous2) { TEST_F(DebounceTest, TwoKeysSimultaneous2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}}, {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}},
{20, {{0, 1, UP}, {0, 2, UP}}, {{0, 1, UP}, {0, 2, UP}}}, {20, {{0, 1, UP}, {0, 2, UP}}, {{0, 1, UP}, {0, 2, UP}}},
}); });
@ -210,7 +223,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan1) { TEST_F(DebounceTest, OneKeyDelayedScan1) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted */ /* Processing is very late but the change will now be accepted */
@ -221,7 +235,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan2) { TEST_F(DebounceTest, OneKeyDelayedScan2) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1 scan delay */ /* Processing is very late but the change will now be accepted even with a 1 scan delay */
@ -233,7 +248,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan3) { TEST_F(DebounceTest, OneKeyDelayedScan3) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1ms delay */ /* Processing is very late but the change will now be accepted even with a 1ms delay */
@ -245,7 +261,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan4) { TEST_F(DebounceTest, OneKeyDelayedScan4) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is a bit late but the change will now be accepted */ /* Processing is a bit late but the change will now be accepted */
@ -256,7 +273,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan4) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan5) { TEST_F(DebounceTest, OneKeyDelayedScan5) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1 scan delay */ /* Processing is very late but the change will now be accepted even with a 1 scan delay */
@ -268,7 +286,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan5) {
} }
TEST_F(DebounceTest, OneKeyDelayedScan6) { TEST_F(DebounceTest, OneKeyDelayedScan6) {
addEvents({ /* Time, Inputs, Outputs */ addEvents({
/* Time, Inputs, Outputs */
{0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},
/* Processing is very late but the change will now be accepted even with a 1ms delay */ /* Processing is very late but the change will now be accepted even with a 1ms delay */

View file

@ -74,8 +74,7 @@ enum steno_keycodes {
}; };
#ifdef STENO_COMBINEDMAP #ifdef STENO_COMBINEDMAP
enum steno_combined_keycodes enum steno_combined_keycodes {
{
STN_S3 = QK_STENO_COMB, STN_S3 = QK_STENO_COMB,
STN_TKL, STN_TKL,
STN_PWL, STN_PWL,

View file

@ -18,10 +18,9 @@
#include "process_combo.h" #include "process_combo.h"
#include "action_tapping.h" #include "action_tapping.h"
#ifdef COMBO_COUNT #ifdef COMBO_COUNT
__attribute__((weak)) combo_t key_combos[COMBO_COUNT]; __attribute__((weak)) combo_t key_combos[COMBO_COUNT];
uint16_t COMBO_LEN = COMBO_COUNT; uint16_t COMBO_LEN = COMBO_COUNT;
#else #else
extern combo_t key_combos[]; extern combo_t key_combos[];
extern uint16_t COMBO_LEN; extern uint16_t COMBO_LEN;
@ -46,64 +45,86 @@ __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo
#endif #endif
#ifndef COMBO_NO_TIMER #ifndef COMBO_NO_TIMER
static uint16_t timer = 0; static uint16_t timer = 0;
#endif #endif
static bool b_combo_enable = true; // defaults to enabled static bool b_combo_enable = true; // defaults to enabled
static uint16_t longest_term = 0; static uint16_t longest_term = 0;
typedef struct { typedef struct {
keyrecord_t record; keyrecord_t record;
uint16_t combo_index; uint16_t combo_index;
uint16_t keycode; uint16_t keycode;
} queued_record_t; } queued_record_t;
static uint8_t key_buffer_size = 0; static uint8_t key_buffer_size = 0;
static queued_record_t key_buffer[COMBO_KEY_BUFFER_LENGTH]; static queued_record_t key_buffer[COMBO_KEY_BUFFER_LENGTH];
typedef struct { typedef struct {
uint16_t combo_index; uint16_t combo_index;
} queued_combo_t; } queued_combo_t;
static uint8_t combo_buffer_write= 0; static uint8_t combo_buffer_write = 0;
static uint8_t combo_buffer_read = 0; static uint8_t combo_buffer_read = 0;
static queued_combo_t combo_buffer[COMBO_BUFFER_LENGTH]; static queued_combo_t combo_buffer[COMBO_BUFFER_LENGTH];
#define INCREMENT_MOD(i) i = (i + 1) % COMBO_BUFFER_LENGTH #define INCREMENT_MOD(i) i = (i + 1) % COMBO_BUFFER_LENGTH
#define COMBO_KEY_POS ((keypos_t){.col=254, .row=254}) #define COMBO_KEY_POS ((keypos_t){.col = 254, .row = 254})
#ifndef EXTRA_SHORT_COMBOS #ifndef EXTRA_SHORT_COMBOS
/* flags are their own elements in combo_t struct. */ /* flags are their own elements in combo_t struct. */
# define COMBO_ACTIVE(combo) (combo->active) # define COMBO_ACTIVE(combo) (combo->active)
# define COMBO_DISABLED(combo) (combo->disabled) # define COMBO_DISABLED(combo) (combo->disabled)
# define COMBO_STATE(combo) (combo->state) # define COMBO_STATE(combo) (combo->state)
# define ACTIVATE_COMBO(combo) do {combo->active = true;}while(0) # define ACTIVATE_COMBO(combo) \
# define DEACTIVATE_COMBO(combo) do {combo->active = false;}while(0) do { \
# define DISABLE_COMBO(combo) do {combo->disabled = true;}while(0) combo->active = true; \
# define RESET_COMBO_STATE(combo) do { \ } while (0)
combo->disabled = false; \ # define DEACTIVATE_COMBO(combo) \
combo->state = 0; \ do { \
}while(0) combo->active = false; \
} while (0)
# define DISABLE_COMBO(combo) \
do { \
combo->disabled = true; \
} while (0)
# define RESET_COMBO_STATE(combo) \
do { \
combo->disabled = false; \
combo->state = 0; \
} while (0)
#else #else
/* flags are at the two high bits of state. */ /* flags are at the two high bits of state. */
# define COMBO_ACTIVE(combo) (combo->state & 0x80) # define COMBO_ACTIVE(combo) (combo->state & 0x80)
# define COMBO_DISABLED(combo) (combo->state & 0x40) # define COMBO_DISABLED(combo) (combo->state & 0x40)
# define COMBO_STATE(combo) (combo->state & 0x3F) # define COMBO_STATE(combo) (combo->state & 0x3F)
# define ACTIVATE_COMBO(combo) do {combo->state |= 0x80;}while(0) # define ACTIVATE_COMBO(combo) \
# define DEACTIVATE_COMBO(combo) do {combo->state &= ~0x80;}while(0) do { \
# define DISABLE_COMBO(combo) do {combo->state |= 0x40;}while(0) combo->state |= 0x80; \
# define RESET_COMBO_STATE(combo) do {combo->state &= ~0x7F;}while(0) } while (0)
# define DEACTIVATE_COMBO(combo) \
do { \
combo->state &= ~0x80; \
} while (0)
# define DISABLE_COMBO(combo) \
do { \
combo->state |= 0x40; \
} while (0)
# define RESET_COMBO_STATE(combo) \
do { \
combo->state &= ~0x7F; \
} while (0)
#endif #endif
static inline void release_combo(uint16_t combo_index, combo_t *combo) { static inline void release_combo(uint16_t combo_index, combo_t *combo) {
if (combo->keycode) { if (combo->keycode) {
keyrecord_t record = { keyrecord_t record = {
.event = { .event =
.key = COMBO_KEY_POS, {
.time = timer_read()|1, .key = COMBO_KEY_POS,
.pressed = false, .time = timer_read() | 1,
}, .pressed = false,
},
.keycode = combo->keycode, .keycode = combo->keycode,
}; };
#ifndef NO_ACTION_TAPPING #ifndef NO_ACTION_TAPPING
@ -123,18 +144,17 @@ static inline bool _get_combo_must_hold(uint16_t combo_index, combo_t *combo) {
#elif defined(COMBO_MUST_HOLD_PER_COMBO) #elif defined(COMBO_MUST_HOLD_PER_COMBO)
return get_combo_must_hold(combo_index, combo); return get_combo_must_hold(combo_index, combo);
#elif defined(COMBO_MUST_HOLD_MODS) #elif defined(COMBO_MUST_HOLD_MODS)
return (KEYCODE_IS_MOD(combo->keycode) || return (KEYCODE_IS_MOD(combo->keycode) || (combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX));
(combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX));
#endif #endif
return false; return false;
} }
static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo ) { static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo) {
if (_get_combo_must_hold(combo_index, combo) if (_get_combo_must_hold(combo_index, combo)
#ifdef COMBO_MUST_TAP_PER_COMBO #ifdef COMBO_MUST_TAP_PER_COMBO
|| get_combo_must_tap(combo_index, combo) || get_combo_must_tap(combo_index, combo)
#endif #endif
) { ) {
if (longest_term < COMBO_HOLD_TERM) { if (longest_term < COMBO_HOLD_TERM) {
return COMBO_HOLD_TERM; return COMBO_HOLD_TERM;
} }
@ -144,9 +164,8 @@ static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo ) {
} }
static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) { static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) {
#if defined(COMBO_TERM_PER_COMBO) #if defined(COMBO_TERM_PER_COMBO)
return get_combo_term(combo_index, combo); return get_combo_term(combo_index, combo);
#endif #endif
return COMBO_TERM; return COMBO_TERM;
@ -154,7 +173,7 @@ static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) {
void clear_combos(void) { void clear_combos(void) {
uint16_t index = 0; uint16_t index = 0;
longest_term = 0; longest_term = 0;
for (index = 0; index < COMBO_LEN; ++index) { for (index = 0; index < COMBO_LEN; ++index) {
combo_t *combo = &key_combos[index]; combo_t *combo = &key_combos[index];
if (!COMBO_ACTIVE(combo)) { if (!COMBO_ACTIVE(combo)) {
@ -175,7 +194,7 @@ static inline void dump_key_buffer(void) {
key_buffer_next = key_buffer_i + 1; key_buffer_next = key_buffer_i + 1;
queued_record_t *qrecord = &key_buffer[key_buffer_i]; queued_record_t *qrecord = &key_buffer[key_buffer_i];
keyrecord_t *record = &qrecord->record; keyrecord_t * record = &qrecord->record;
if (IS_NOEVENT(record->event)) { if (IS_NOEVENT(record->event)) {
continue; continue;
@ -185,9 +204,9 @@ static inline void dump_key_buffer(void) {
process_combo_event(qrecord->combo_index, true); process_combo_event(qrecord->combo_index, true);
} else { } else {
#ifndef NO_ACTION_TAPPING #ifndef NO_ACTION_TAPPING
action_tapping_process(*record); action_tapping_process(*record);
#else #else
process_record(record); process_record(record);
#endif #endif
} }
record->event.time = 0; record->event.time = 0;
@ -242,7 +261,9 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
/* Apply combo's result keycode to the last chord key of the combo and /* Apply combo's result keycode to the last chord key of the combo and
* disable the other keys. */ * disable the other keys. */
if (COMBO_DISABLED(combo)) { return; } if (COMBO_DISABLED(combo)) {
return;
}
// state to check against so we find the last key of the combo from the buffer // state to check against so we find the last key of the combo from the buffer
#if defined(EXTRA_EXTRA_LONG_COMBOS) #if defined(EXTRA_EXTRA_LONG_COMBOS)
@ -254,12 +275,11 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
#endif #endif
for (uint8_t key_buffer_i = 0; key_buffer_i < key_buffer_size; key_buffer_i++) { for (uint8_t key_buffer_i = 0; key_buffer_i < key_buffer_size; key_buffer_i++) {
queued_record_t *qrecord = &key_buffer[key_buffer_i]; queued_record_t *qrecord = &key_buffer[key_buffer_i];
keyrecord_t *record = &qrecord->record; keyrecord_t * record = &qrecord->record;
uint16_t keycode = qrecord->keycode; uint16_t keycode = qrecord->keycode;
uint8_t key_count = 0; uint8_t key_count = 0;
uint16_t key_index = -1; uint16_t key_index = -1;
_find_key_index_and_count(combo->keys, keycode, &key_index, &key_count); _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count);
@ -271,7 +291,7 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
KEY_STATE_DOWN(state, key_index); KEY_STATE_DOWN(state, key_index);
if (ALL_COMBO_KEYS_ARE_DOWN(state, key_count)) { if (ALL_COMBO_KEYS_ARE_DOWN(state, key_count)) {
// this in the end executes the combo when the key_buffer is dumped. // this in the end executes the combo when the key_buffer is dumped.
record->keycode = combo->keycode; record->keycode = combo->keycode;
record->event.key = COMBO_KEY_POS; record->event.key = COMBO_KEY_POS;
qrecord->combo_index = combo_index; qrecord->combo_index = combo_index;
@ -283,19 +303,15 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {
// by making it a TICK event. // by making it a TICK event.
record->event.time = 0; record->event.time = 0;
} }
} }
drop_combo_from_buffer(combo_index); drop_combo_from_buffer(combo_index);
} }
static inline void apply_combos(void) { static inline void apply_combos(void) {
// Apply all buffered normal combos. // Apply all buffered normal combos.
for (uint8_t i = combo_buffer_read; for (uint8_t i = combo_buffer_read; i != combo_buffer_write; INCREMENT_MOD(i)) {
i != combo_buffer_write;
INCREMENT_MOD(i)) {
queued_combo_t *buffered_combo = &combo_buffer[i]; queued_combo_t *buffered_combo = &combo_buffer[i];
combo_t *combo = &key_combos[buffered_combo->combo_index]; combo_t * combo = &key_combos[buffered_combo->combo_index];
#ifdef COMBO_MUST_TAP_PER_COMBO #ifdef COMBO_MUST_TAP_PER_COMBO
if (get_combo_must_tap(buffered_combo->combo_index, combo)) { if (get_combo_must_tap(buffered_combo->combo_index, combo)) {
@ -310,15 +326,15 @@ static inline void apply_combos(void) {
clear_combos(); clear_combos();
} }
combo_t* overlaps(combo_t *combo1, combo_t *combo2) { combo_t *overlaps(combo_t *combo1, combo_t *combo2) {
/* Checks if the combos overlap and returns the combo that should be /* Checks if the combos overlap and returns the combo that should be
* dropped from the combo buffer. * dropped from the combo buffer.
* The combo that has less keys will be dropped. If they have the same * The combo that has less keys will be dropped. If they have the same
* amount of keys, drop combo1. */ * amount of keys, drop combo1. */
uint8_t idx1 = 0, idx2 = 0; uint8_t idx1 = 0, idx2 = 0;
uint16_t key1, key2; uint16_t key1, key2;
bool overlaps = false; bool overlaps = false;
while ((key1 = pgm_read_word(&combo1->keys[idx1])) != COMBO_END) { while ((key1 = pgm_read_word(&combo1->keys[idx1])) != COMBO_END) {
idx2 = 0; idx2 = 0;
@ -335,7 +351,7 @@ combo_t* overlaps(combo_t *combo1, combo_t *combo2) {
} }
static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) { static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) {
uint8_t key_count = 0; uint8_t key_count = 0;
uint16_t key_index = -1; uint16_t key_index = -1;
_find_key_index_and_count(combo->keys, keycode, &key_index, &key_count); _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count);
@ -369,12 +385,9 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
// disable readied combos that overlap with this combo // disable readied combos that overlap with this combo
combo_t *drop = NULL; combo_t *drop = NULL;
for (uint8_t combo_buffer_i = combo_buffer_read; for (uint8_t combo_buffer_i = combo_buffer_read; combo_buffer_i != combo_buffer_write; INCREMENT_MOD(combo_buffer_i)) {
combo_buffer_i != combo_buffer_write; queued_combo_t *qcombo = &combo_buffer[combo_buffer_i];
INCREMENT_MOD(combo_buffer_i)) { combo_t * buffered_combo = &key_combos[qcombo->combo_index];
queued_combo_t *qcombo = &combo_buffer[combo_buffer_i];
combo_t *buffered_combo = &key_combos[qcombo->combo_index];
if ((drop = overlaps(buffered_combo, combo))) { if ((drop = overlaps(buffered_combo, combo))) {
DISABLE_COMBO(drop); DISABLE_COMBO(drop);
@ -387,21 +400,19 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
INCREMENT_MOD(combo_buffer_read); INCREMENT_MOD(combo_buffer_read);
} }
} }
} }
if (drop != combo) { if (drop != combo) {
// save this combo to buffer // save this combo to buffer
combo_buffer[combo_buffer_write] = (queued_combo_t){ combo_buffer[combo_buffer_write] = (queued_combo_t){
.combo_index=combo_index, .combo_index = combo_index,
}; };
INCREMENT_MOD(combo_buffer_write); INCREMENT_MOD(combo_buffer_write);
// get possible longer waiting time for tap-/hold-only combos. // get possible longer waiting time for tap-/hold-only combos.
longest_term = _get_wait_time(combo_index, combo); longest_term = _get_wait_time(combo_index, combo);
} }
} // if timer elapsed end } // if timer elapsed end
} }
} else { } else {
// chord releases // chord releases
@ -416,7 +427,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
else if (get_combo_must_tap(combo_index, combo)) { else if (get_combo_must_tap(combo_index, combo)) {
// immediately apply tap-only combo // immediately apply tap-only combo
apply_combo(combo_index, combo); apply_combo(combo_index, combo);
apply_combos(); // also apply other prepared combos and dump key buffer apply_combos(); // also apply other prepared combos and dump key buffer
# ifdef COMBO_PROCESS_KEY_RELEASE # ifdef COMBO_PROCESS_KEY_RELEASE
if (process_combo_key_release(combo_index, combo, key_index, keycode)) { if (process_combo_key_release(combo_index, combo, key_index, keycode)) {
release_combo(combo_index, combo); release_combo(combo_index, combo);
@ -424,10 +435,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
# endif # endif
} }
#endif #endif
} else if (COMBO_ACTIVE(combo) } else if (COMBO_ACTIVE(combo) && ONLY_ONE_KEY_IS_DOWN(COMBO_STATE(combo)) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) {
&& ONLY_ONE_KEY_IS_DOWN(COMBO_STATE(combo))
&& KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)
) {
/* last key released */ /* last key released */
release_combo(combo_index, combo); release_combo(combo_index, combo);
key_is_part_of_combo = true; key_is_part_of_combo = true;
@ -435,9 +443,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *
#ifdef COMBO_PROCESS_KEY_RELEASE #ifdef COMBO_PROCESS_KEY_RELEASE
process_combo_key_release(combo_index, combo, key_index, keycode); process_combo_key_release(combo_index, combo, key_index, keycode);
#endif #endif
} else if (COMBO_ACTIVE(combo) } else if (COMBO_ACTIVE(combo) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) {
&& KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)
) {
/* first or middle key released */ /* first or middle key released */
key_is_part_of_combo = true; key_is_part_of_combo = true;
@ -489,21 +495,21 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed && is_combo_key) { if (record->event.pressed && is_combo_key) {
#ifndef COMBO_NO_TIMER #ifndef COMBO_NO_TIMER
# ifdef COMBO_STRICT_TIMER # ifdef COMBO_STRICT_TIMER
if (!timer) { if (!timer) {
// timer is set only on the first key // timer is set only on the first key
timer = timer_read(); timer = timer_read();
} }
# else # else
timer = timer_read(); timer = timer_read();
# endif # endif
#endif #endif
if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) { if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) {
key_buffer[key_buffer_size++] = (queued_record_t){ key_buffer[key_buffer_size++] = (queued_record_t){
.record = *record, .record = *record,
.keycode = keycode, .keycode = keycode,
.combo_index = -1, // this will be set when applying combos .combo_index = -1, // this will be set when applying combos
}; };
} }
} else { } else {
@ -532,7 +538,7 @@ void combo_task(void) {
if (combo_buffer_read != combo_buffer_write) { if (combo_buffer_read != combo_buffer_write) {
apply_combos(); apply_combos();
longest_term = 0; longest_term = 0;
timer = 0; timer = 0;
} else { } else {
dump_key_buffer(); dump_key_buffer();
timer = 0; timer = 0;
@ -546,9 +552,9 @@ void combo_enable(void) { b_combo_enable = true; }
void combo_disable(void) { void combo_disable(void) {
#ifndef COMBO_NO_TIMER #ifndef COMBO_NO_TIMER
timer = 0; timer = 0;
#endif #endif
b_combo_enable = false; b_combo_enable = false;
combo_buffer_read = combo_buffer_write; combo_buffer_read = combo_buffer_write;
clear_combos(); clear_combos();
dump_key_buffer(); dump_key_buffer();

View file

@ -43,8 +43,8 @@ typedef struct {
#ifdef EXTRA_SHORT_COMBOS #ifdef EXTRA_SHORT_COMBOS
uint8_t state; uint8_t state;
#else #else
bool disabled; bool disabled;
bool active; bool active;
# if defined(EXTRA_EXTRA_LONG_COMBOS) # if defined(EXTRA_EXTRA_LONG_COMBOS)
uint32_t state; uint32_t state;
# elif defined(EXTRA_LONG_COMBOS) # elif defined(EXTRA_LONG_COMBOS)

View file

@ -67,7 +67,7 @@ static const uint8_t boltmap[64] PROGMEM = {TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM,
#ifdef STENO_COMBINEDMAP #ifdef STENO_COMBINEDMAP
/* Used to look up when pressing the middle row key to combine two consonant or vowel keys */ /* Used to look up when pressing the middle row key to combine two consonant or vowel keys */
static const uint16_t combinedmap_first[] PROGMEM = {STN_S1, STN_TL, STN_PL, STN_HL, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR, STN_A, STN_E}; static const uint16_t combinedmap_first[] PROGMEM = {STN_S1, STN_TL, STN_PL, STN_HL, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR, STN_A, STN_E};
static const uint16_t combinedmap_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, STN_RL, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR, STN_O, STN_U}; static const uint16_t combinedmap_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, STN_RL, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR, STN_O, STN_U};
#endif #endif
@ -174,11 +174,10 @@ bool process_steno(uint16_t keycode, keyrecord_t *record) {
return false; return false;
#ifdef STENO_COMBINEDMAP #ifdef STENO_COMBINEDMAP
case QK_STENO_COMB ... QK_STENO_COMB_MAX: case QK_STENO_COMB ... QK_STENO_COMB_MAX: {
{
uint8_t result; uint8_t result;
result = process_steno(combinedmap_first[keycode-QK_STENO_COMB], record); result = process_steno(combinedmap_first[keycode - QK_STENO_COMB], record);
result &= process_steno(combinedmap_second[keycode-QK_STENO_COMB], record); result &= process_steno(combinedmap_second[keycode - QK_STENO_COMB], record);
return result; return result;
} }
#endif #endif

View file

@ -809,12 +809,12 @@ enum quantum_keycodes {
#define CMD_T(kc) LCMD_T(kc) #define CMD_T(kc) LCMD_T(kc)
#define WIN_T(kc) LWIN_T(kc) #define WIN_T(kc) LWIN_T(kc)
#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Left Control + Shift e.g. for gnome-terminal #define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Left Control + Shift e.g. for gnome-terminal
#define MEH_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc) // Meh is a less hyper version of the Hyper key -- doesn't include GUI, so just Left Control + Shift + Alt #define MEH_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc) // Meh is a less hyper version of the Hyper key -- doesn't include GUI, so just Left Control + Shift + Alt
#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left Control + Alt + GUI #define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left Control + Alt + GUI
#define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc) // Right Control + Alt + GUI #define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc) // Right Control + Alt + GUI
#define HYPR_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ #define HYPR_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
#define LSG_T(kc) MT(MOD_LSFT | MOD_LGUI, kc) // Left Shift + GUI #define LSG_T(kc) MT(MOD_LSFT | MOD_LGUI, kc) // Left Shift + GUI
#define SGUI_T(kc) LSG_T(kc) #define SGUI_T(kc) LSG_T(kc)
#define SCMD_T(kc) LSG_T(kc) #define SCMD_T(kc) LSG_T(kc)
#define SWIN_T(kc) LSG_T(kc) #define SWIN_T(kc) LSG_T(kc)
@ -845,7 +845,7 @@ enum quantum_keycodes {
#define UC_M_MA UNICODE_MODE_MAC #define UC_M_MA UNICODE_MODE_MAC
#define UNICODE_MODE_OSX UNICODE_MODE_MAC // Deprecated alias #define UNICODE_MODE_OSX UNICODE_MODE_MAC // Deprecated alias
#define UC_M_OS UNICODE_MODE_MAC // Deprecated alias #define UC_M_OS UNICODE_MODE_MAC // Deprecated alias
#define UC_M_LN UNICODE_MODE_LNX #define UC_M_LN UNICODE_MODE_LNX
#define UC_M_WI UNICODE_MODE_WIN #define UC_M_WI UNICODE_MODE_WIN
#define UC_M_BS UNICODE_MODE_BSD #define UC_M_BS UNICODE_MODE_BSD

View file

@ -18,44 +18,57 @@
#ifdef ENABLE_RGB_MATRIX_FRACTAL #ifdef ENABLE_RGB_MATRIX_FRACTAL
RGB_MATRIX_EFFECT(FRACTAL) RGB_MATRIX_EFFECT(FRACTAL)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS # ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
static bool FRACTAL(effect_params_t* params) { static bool FRACTAL(effect_params_t* params) {
#define MID_COL MATRIX_COLS / 2 # define MID_COL MATRIX_COLS / 2
static bool led[MATRIX_ROWS][MATRIX_COLS]; static bool led[MATRIX_ROWS][MATRIX_COLS];
static uint32_t wait_timer = 0; static uint32_t wait_timer = 0;
if (wait_timer > g_rgb_timer) { return false; } if (wait_timer > g_rgb_timer) {
return false;
}
inline uint32_t interval(void) { return 3000 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16); } inline uint32_t interval(void) { return 3000 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16); }
RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv); RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv);
for (uint8_t h = 0; h < MATRIX_ROWS; ++h) { for (uint8_t h = 0; h < MATRIX_ROWS; ++h) {
for (uint8_t l = 0; l < MID_COL - 1; ++l) { // Light and move left columns outwards
for (uint8_t l = 0; l < MID_COL-1; ++l) { // Light and move left columns outwards if (led[h][l]) {
if (led[h][l]) { rgb_matrix_set_color(g_led_config.matrix_co[h][l], rgb.r, rgb.g, rgb.b); } rgb_matrix_set_color(g_led_config.matrix_co[h][l], rgb.r, rgb.g, rgb.b);
else { rgb_matrix_set_color(g_led_config.matrix_co[h][l], 0, 0, 0); } } else {
led[h][l] = led[h][l+1]; rgb_matrix_set_color(g_led_config.matrix_co[h][l], 0, 0, 0);
}
led[h][l] = led[h][l + 1];
} }
for (uint8_t r = MATRIX_COLS-1; r > MID_COL; --r) { // Light and move right columns outwards for (uint8_t r = MATRIX_COLS - 1; r > MID_COL; --r) { // Light and move right columns outwards
if (led[h][r]) { rgb_matrix_set_color(g_led_config.matrix_co[h][r], rgb.r, rgb.g, rgb.b); } if (led[h][r]) {
else { rgb_matrix_set_color(g_led_config.matrix_co[h][r], 0, 0, 0); } rgb_matrix_set_color(g_led_config.matrix_co[h][r], rgb.r, rgb.g, rgb.b);
led[h][r] = led[h][r-1]; } else {
rgb_matrix_set_color(g_led_config.matrix_co[h][r], 0, 0, 0);
}
led[h][r] = led[h][r - 1];
} }
// Light both middle columns // Light both middle columns
if (led[h][MID_COL]) { rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL], rgb.r, rgb.g, rgb.b); } if (led[h][MID_COL]) {
else { rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL], 0, 0, 0); } rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL], rgb.r, rgb.g, rgb.b);
if (led[h][MID_COL-1]) { rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL-1], rgb.r, rgb.g, rgb.b); } } else {
else { rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL-1], 0, 0, 0); } rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL], 0, 0, 0);
}
if (led[h][MID_COL - 1]) {
rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL - 1], rgb.r, rgb.g, rgb.b);
} else {
rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL - 1], 0, 0, 0);
}
// Generate new random fractal columns // Generate new random fractal columns
led[h][MID_COL] = led[h][MID_COL-1] = (random8() & 3) ? false : true; led[h][MID_COL] = led[h][MID_COL - 1] = (random8() & 3) ? false : true;
} }
wait_timer = g_rgb_timer + interval(); wait_timer = g_rgb_timer + interval();
return false; return false;
} }
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS # endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
#endif // ENABLE_RGB_MATRIX_FRACTAL #endif // ENABLE_RGB_MATRIX_FRACTAL

View file

@ -42,8 +42,8 @@
{ &dummy, 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb } { &dummy, 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb }
#define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL) #define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL)
#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) #define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0)
#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) #define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length)
#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
// Forward-declare the RPC callback handlers // Forward-declare the RPC callback handlers
@ -157,8 +157,8 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro
memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix));
} }
# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix) # define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix)
# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix) # define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix)
# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix), # define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix),
#else // SPLIT_TRANSPORT_MIRROR #else // SPLIT_TRANSPORT_MIRROR
@ -235,8 +235,8 @@ static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
} }
} }
# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer) # define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer)
# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer) # define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer)
# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer), # define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer),
#else // DISABLE_SYNC_TIMER #else // DISABLE_SYNC_TIMER
@ -300,8 +300,8 @@ static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
set_split_host_keyboard_leds(split_shmem->led_state); set_split_host_keyboard_leds(split_shmem->led_state);
} }
# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state) # define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state)
# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state) # define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state)
# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state), # define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state),
#else // SPLIT_LED_STATE_ENABLE #else // SPLIT_LED_STATE_ENABLE
@ -357,8 +357,8 @@ static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave
# endif # endif
} }
# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods) # define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods)
# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods) # define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods)
# define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods), # define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods),
#else // SPLIT_MODS_ENABLE #else // SPLIT_MODS_ENABLE
@ -382,8 +382,8 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t
static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); } static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); }
# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight) # define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight)
# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight) # define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight)
# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level), # define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level),
#else // BACKLIGHT_ENABLE #else // BACKLIGHT_ENABLE
@ -419,8 +419,8 @@ static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s
} }
} }
# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight) # define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight)
# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight) # define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight)
# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync), # define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync),
#else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) #else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
@ -449,8 +449,8 @@ static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state); led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state);
} }
# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix) # define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix)
# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix) # define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix)
# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync), # define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync),
#else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) #else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
@ -479,8 +479,8 @@ static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t
rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state); rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state);
} }
# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix) # define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix)
# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix) # define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix)
# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync), # define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync),
#else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) #else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
@ -504,8 +504,8 @@ static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave
static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); } static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); }
# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm) # define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm)
# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm) # define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm)
# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm), # define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm),
#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) #else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE)
@ -535,8 +535,8 @@ static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave
} }
} }
# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled) # define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled)
# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled) # define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled)
# define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state), # define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state),
#else // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) #else // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE)
@ -566,8 +566,8 @@ static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sla
} }
} }
# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565) # define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565)
# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565) # define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565)
# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state), # define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state),
#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) #else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE)

View file

@ -65,7 +65,7 @@ void sleep_led_timer_callback(void) {
/* LPTMR clock options */ /* LPTMR clock options */
# define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */ # define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */ # define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
# define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */ # define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */
# define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */ # define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */
@ -121,7 +121,7 @@ void sleep_led_init(void) {
MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock
# if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others # if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others
MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; MCG->MC |= MCG_MC_LIRC_DIV2_DIV2;
# endif /* KL27 */ # endif /* KL27 */
MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock
// to work in stop mode, also MCG_C1_IREFSTEN // to work in stop mode, also MCG_C1_IREFSTEN
// Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec =>