From 9b7be8b88f6c14eb13dbe73179d29fdd25fe8b28 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Tue, 2 Mar 2021 18:05:27 +0100 Subject: [PATCH 01/13] rework encoder pin handling for split keyboards --- quantum/encoder.c | 115 ++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/quantum/encoder.c b/quantum/encoder.c index 2ed64c1e3074..97619518da7c 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -31,11 +31,39 @@ # error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" #endif -#define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) -static pin_t encoders_pad_a[] = ENCODERS_PAD_A; -static pin_t encoders_pad_b[] = ENCODERS_PAD_B; -#ifdef ENCODER_RESOLUTIONS -static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; +#ifdef SPLIT_KEYBOARD + #ifndef ENCODERS_PAD_A_RIGHT + # define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A + #endif + + #ifndef ENCODERS_PAD_B_RIGHT + # define ENCODERS_PAD_B_RIGHT ENCODERS_PAD_B + #endif + + #if defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTIONS_RIGHT) + # define ENCODER_RESOLUTIONS_RIGHT ENCODER_RESOLUTIONS + #endif + +# define NUMBER_OF_ENCODERS ((sizeof(encoders_pad_a) + sizeof(encoders_pad_a_right)) / sizeof(pin_t)) +# define NUMBER_OF_ENCODERS_LEFT (sizeof(encoders_pad_a) / sizeof(pin_t)) +# define NUMBER_OF_ENCODERS_RIGHT (sizeof(encoders_pad_a_right) / sizeof(pin_t)) + static pin_t encoders_pad_a[] = ENCODERS_PAD_A; + static pin_t encoders_pad_b[] = ENCODERS_PAD_B; + #ifdef ENCODER_RESOLUTIONS + static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; + #endif + static pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; + static pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; + #ifdef ENCODER_RESOLUTIONS_RIGHT + static uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT; + #endif +#else +# define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) + static pin_t encoders_pad_a[] = ENCODERS_PAD_A; + static pin_t encoders_pad_b[] = ENCODERS_PAD_B; + #ifdef ENCODER_RESOLUTIONS + static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; + #endif #endif #ifndef ENCODER_DIRECTION_FLIP @@ -50,96 +78,95 @@ static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0}; -#ifdef SPLIT_KEYBOARD -// right half encoders come over as second set of encoders -static uint8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0}; -// row offsets for each hand -static uint8_t thisHand, thatHand; -#else static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; -#endif __attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} __attribute__((weak)) void encoder_update_kb(int8_t index, bool clockwise) { encoder_update_user(index, clockwise); } -void encoder_init(void) { -#if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) - if (!isLeftHand) { - const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; - const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; -# if defined(ENCODER_RESOLUTIONS_RIGHT) - const uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT; -# endif - for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { - encoders_pad_a[i] = encoders_pad_a_right[i]; - encoders_pad_b[i] = encoders_pad_b_right[i]; -# if defined(ENCODER_RESOLUTIONS_RIGHT) - encoder_resolutions[i] = encoder_resolutions_right[i]; -# endif - } - } +#ifdef SPLIT_KEYBOARD + // row offsets for each hand + static uint8_t thisHand, thatHand; #endif +void encoder_init(void) { +#ifndef SPLIT_KEYBOARD for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { setPinInputHigh(encoders_pad_a[i]); setPinInputHigh(encoders_pad_b[i]); encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); } - -#ifdef SPLIT_KEYBOARD - thisHand = isLeftHand ? 0 : NUMBER_OF_ENCODERS; +#else + thisHand = is_keyboard_left() ? 0 : NUMBER_OF_ENCODERS_LEFT; + thisHandNum = is_keyboard_left() ? NUMBER_OF_ENCODERS_LEFT : NUMBER_OF_ENCODERS_RIGHT; thatHand = NUMBER_OF_ENCODERS - thisHand; + + pin_t pad_a[] = is_keyboard_left() ? encoders_pad_a : encoders_pad_a_right; + pin_t pad_b[] = is_keyboard_left() ? encoders_pad_b : encoders_pad_b_right; + + for (int i = 0; i < thisHandNum; i++) { + setPinInputHigh(pad_a[i]); + setPinInputHigh(pad_b[i]); + + encoder_state[thisHand + i] = (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1); + } #endif + } static bool encoder_update(int8_t index, uint8_t state) { bool changed = false; - uint8_t i = index; - + #ifdef ENCODER_RESOLUTIONS - int8_t resolution = encoder_resolutions[i]; + int8_t resolution = is_keyboard_left() ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT]; #else int8_t resolution = ENCODER_RESOLUTION; #endif - -#ifdef SPLIT_KEYBOARD - index += thisHand; -#endif - encoder_pulses[i] += encoder_LUT[state & 0xF]; - if (encoder_pulses[i] >= resolution) { + encoder_pulses[index] += encoder_LUT[state & 0xF]; + if (encoder_pulses[index] >= resolution) { encoder_value[index]++; changed = true; encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); } - if (encoder_pulses[i] <= -resolution) { // direction is arbitrary here, but this clockwise + if (encoder_pulses[index] <= -resolution) { // direction is arbitrary here, but this clockwise encoder_value[index]--; changed = true; encoder_update_kb(index, ENCODER_CLOCKWISE); } - encoder_pulses[i] %= resolution; + encoder_pulses[index] %= resolution; return changed; } bool encoder_read(void) { bool changed = false; +#ifndef SPLIT_KEYBOARD for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { encoder_state[i] <<= 2; encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); changed |= encoder_update(i, encoder_state[i]); } +#else + pin_t pad_a[] = is_keyboard_left() ? encoders_pad_a : encoders_pad_a_right; + pin_t pad_b[] = is_keyboard_left() ? encoders_pad_b : encoders_pad_b_right; + + for (uint8_t i = 0; i < thisHandNum; i++) { + encoder_state[thisHand + i] <<= 2; + encoder_state[thisHand + i] |= (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1); + changed |= encoder_update(thisHand + i, encoder_state[thisHand + i]); + } +#endif return changed; } #ifdef SPLIT_KEYBOARD void last_encoder_activity_trigger(void); -void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); } +void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * thisHandNum); } void encoder_update_raw(uint8_t* slave_state) { bool changed = false; - for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { + for (uint8_t i = 0; i < NUMBER_OF_ENCODERS - thisHandNum; i++) { uint8_t index = i + thatHand; int8_t delta = slave_state[i] - encoder_value[index]; while (delta > 0) { From c31e643f3c53b5171f46596d2c8e5911905e3089 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Tue, 2 Mar 2021 20:05:43 +0100 Subject: [PATCH 02/13] simplify encoder code --- quantum/encoder.c | 73 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/quantum/encoder.c b/quantum/encoder.c index 97619518da7c..05113ca9eae7 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -27,11 +27,12 @@ # define ENCODER_RESOLUTION 4 #endif -#if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B) -# error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" +#if (!defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B)) && (!defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B)) +# error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B or ENCODERS_PAD_A_RIGHT and ENCODERS_PAD_B_RIGHT" #endif #ifdef SPLIT_KEYBOARD + // if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads) #ifndef ENCODERS_PAD_A_RIGHT # define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A #endif @@ -84,34 +85,43 @@ __attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} __attribute__((weak)) void encoder_update_kb(int8_t index, bool clockwise) { encoder_update_user(index, clockwise); } +// number of encoders connected to this controller +static uint8_t numEncodersHere; +// index of the first encoder connected to this controller (only for right halves, this will be nonzero) +static uint8_t firstEncoderHere; #ifdef SPLIT_KEYBOARD - // row offsets for each hand - static uint8_t thisHand, thatHand; + // index of the first encoder connected to the other half + static uint8_t firstEncoderThere; #endif void encoder_init(void) { #ifndef SPLIT_KEYBOARD - for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { - setPinInputHigh(encoders_pad_a[i]); - setPinInputHigh(encoders_pad_b[i]); - - encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); - } + numEncodersHere = NUMBER_OF_ENCODERS; + pin_t pad_a[] = encoders_pad_a; + pin_t pad_b[] = encoders_pad_b; + firstEncoderHere = 0; #else - thisHand = is_keyboard_left() ? 0 : NUMBER_OF_ENCODERS_LEFT; - thisHandNum = is_keyboard_left() ? NUMBER_OF_ENCODERS_LEFT : NUMBER_OF_ENCODERS_RIGHT; - thatHand = NUMBER_OF_ENCODERS - thisHand; - - pin_t pad_a[] = is_keyboard_left() ? encoders_pad_a : encoders_pad_a_right; - pin_t pad_b[] = is_keyboard_left() ? encoders_pad_b : encoders_pad_b_right; + if (is_keyboard_left()) { + numEncodersHere = NUMBER_OF_ENCODERS_LEFT; + pin_t pad_a[] = encoders_pad_a; + pin_t pad_b[] = encoders_pad_b; + firstEncoderHere = 0; + firstEncoderThere = NUMBER_OF_ENCODERS_LEFT; + } else { + numEncodersHere = NUMBER_OF_ENCODERS_RIGHT; + pin_t pad_a[] = encoders_pad_a_right; + pin_t pad_b[] = encoders_pad_b_right; + firstEncoderHere = NUMBER_OF_ENCODERS_LEFT; + firstEncoderThere = 0; + } +#endif - for (int i = 0; i < thisHandNum; i++) { + for (int i = 0; i < numEncodersHere; i++) { setPinInputHigh(pad_a[i]); setPinInputHigh(pad_b[i]); - encoder_state[thisHand + i] = (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1); + encoder_state[firstEncoderHere + i] = (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1); } -#endif } @@ -140,34 +150,23 @@ static bool encoder_update(int8_t index, uint8_t state) { bool encoder_read(void) { bool changed = false; -#ifndef SPLIT_KEYBOARD - for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { - encoder_state[i] <<= 2; - encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); - changed |= encoder_update(i, encoder_state[i]); + for (uint8_t i = 0; i < numEncodersHere; i++) { + encoder_state[firstEncoderHere + i] <<= 2; + encoder_state[firstEncoderHere + i] |= (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1); + changed |= encoder_update(firstEncoderHere + i, encoder_state[firstEncoderHere + i]); } -#else - pin_t pad_a[] = is_keyboard_left() ? encoders_pad_a : encoders_pad_a_right; - pin_t pad_b[] = is_keyboard_left() ? encoders_pad_b : encoders_pad_b_right; - - for (uint8_t i = 0; i < thisHandNum; i++) { - encoder_state[thisHand + i] <<= 2; - encoder_state[thisHand + i] |= (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1); - changed |= encoder_update(thisHand + i, encoder_state[thisHand + i]); - } -#endif return changed; } #ifdef SPLIT_KEYBOARD void last_encoder_activity_trigger(void); -void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * thisHandNum); } +void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[firstEncoderHere], sizeof(uint8_t) * numEncodersHere); } void encoder_update_raw(uint8_t* slave_state) { bool changed = false; - for (uint8_t i = 0; i < NUMBER_OF_ENCODERS - thisHandNum; i++) { - uint8_t index = i + thatHand; + for (uint8_t i = 0; i < NUMBER_OF_ENCODERS - numEncodersHere; i++) { + uint8_t index = firstEncoderThere + i; int8_t delta = slave_state[i] - encoder_value[index]; while (delta > 0) { delta--; From 20f003f750667509cb3e7dbb3aa0f8acc03ae473 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Tue, 2 Mar 2021 21:13:34 +0100 Subject: [PATCH 03/13] fixes and align resolutions --- quantum/encoder.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/quantum/encoder.c b/quantum/encoder.c index 05113ca9eae7..a93c217a6cce 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -31,16 +31,23 @@ # error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B or ENCODERS_PAD_A_RIGHT and ENCODERS_PAD_B_RIGHT" #endif -#ifdef SPLIT_KEYBOARD +// on split keyboards, these are the pads and resolutions for the left half +static pin_t encoders_pad_a[] = ENCODERS_PAD_A; +static pin_t encoders_pad_b[] = ENCODERS_PAD_B; +#ifdef ENCODER_RESOLUTIONS + static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; +#endif + +#ifndef SPLIT_KEYBOARD +# define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) +#else // if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads) #ifndef ENCODERS_PAD_A_RIGHT # define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A #endif - #ifndef ENCODERS_PAD_B_RIGHT # define ENCODERS_PAD_B_RIGHT ENCODERS_PAD_B #endif - #if defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTIONS_RIGHT) # define ENCODER_RESOLUTIONS_RIGHT ENCODER_RESOLUTIONS #endif @@ -48,23 +55,11 @@ # define NUMBER_OF_ENCODERS ((sizeof(encoders_pad_a) + sizeof(encoders_pad_a_right)) / sizeof(pin_t)) # define NUMBER_OF_ENCODERS_LEFT (sizeof(encoders_pad_a) / sizeof(pin_t)) # define NUMBER_OF_ENCODERS_RIGHT (sizeof(encoders_pad_a_right) / sizeof(pin_t)) - static pin_t encoders_pad_a[] = ENCODERS_PAD_A; - static pin_t encoders_pad_b[] = ENCODERS_PAD_B; - #ifdef ENCODER_RESOLUTIONS - static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; - #endif static pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; static pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; #ifdef ENCODER_RESOLUTIONS_RIGHT static uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT; #endif -#else -# define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) - static pin_t encoders_pad_a[] = ENCODERS_PAD_A; - static pin_t encoders_pad_b[] = ENCODERS_PAD_B; - #ifdef ENCODER_RESOLUTIONS - static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; - #endif #endif #ifndef ENCODER_DIRECTION_FLIP @@ -93,24 +88,27 @@ static uint8_t firstEncoderHere; // index of the first encoder connected to the other half static uint8_t firstEncoderThere; #endif +// the pads for this controller +static pin_t *pad_a; +static pin_t *pad_b; void encoder_init(void) { #ifndef SPLIT_KEYBOARD numEncodersHere = NUMBER_OF_ENCODERS; - pin_t pad_a[] = encoders_pad_a; - pin_t pad_b[] = encoders_pad_b; + pad_a = encoders_pad_a; + pad_b = encoders_pad_b; firstEncoderHere = 0; #else if (is_keyboard_left()) { numEncodersHere = NUMBER_OF_ENCODERS_LEFT; - pin_t pad_a[] = encoders_pad_a; - pin_t pad_b[] = encoders_pad_b; + pad_a = encoders_pad_a; + pad_b = encoders_pad_b; firstEncoderHere = 0; firstEncoderThere = NUMBER_OF_ENCODERS_LEFT; } else { numEncodersHere = NUMBER_OF_ENCODERS_RIGHT; - pin_t pad_a[] = encoders_pad_a_right; - pin_t pad_b[] = encoders_pad_b_right; + pad_a = encoders_pad_a_right; + pad_b = encoders_pad_b_right; firstEncoderHere = NUMBER_OF_ENCODERS_LEFT; firstEncoderThere = 0; } @@ -129,7 +127,11 @@ static bool encoder_update(int8_t index, uint8_t state) { bool changed = false; #ifdef ENCODER_RESOLUTIONS - int8_t resolution = is_keyboard_left() ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT]; + #ifndef SPLIT_KEYBOARD + int8_t resolution = encoder_resolutions[index]; + #else + int8_t resolution = is_keyboard_left() ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT]; + #endif #else int8_t resolution = ENCODER_RESOLUTION; #endif From 629009203972b17f98affd4ca20f7dc271293333 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Tue, 2 Mar 2021 22:13:25 +0100 Subject: [PATCH 04/13] update docs --- docs/feature_encoders.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/feature_encoders.md b/docs/feature_encoders.md index e2cafdac48e8..23e3695f6686 100644 --- a/docs/feature_encoders.md +++ b/docs/feature_encoders.md @@ -40,7 +40,9 @@ It can also be defined per-encoder, by instead defining: ## Split Keyboards -If you are using different pinouts for the encoders on each half of a split keyboard, you can define the pinout (and optionally, resolutions) for the right half like this: +The above is enough for split keyboards that are symmetrical, i.e. the halves have the same number of encoders and they are on the same pins. +If the halves are not symmetrical, you can define the pinout (and optionally, resolutions) of the right half separately. +The left half will use the definitions above. ```c #define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } @@ -48,6 +50,17 @@ If you are using different pinouts for the encoders on each half of a split keyb #define ENCODER_RESOLUTIONS_RIGHT { 2, 4 } ``` +If only the right half has encoders, you must still define an empty array for the left pads (and resolutions, if you define `ENCODER_RESOLUTIONS_RIGHT`). + +```c +#define ENCODERS_PAD_A { } +#define ENCODERS_PAD_B { } +#define ENCODER_RESOLUTIONS { } +#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } +#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +#define ENCODER_RESOLUTIONS_RIGHT { 2, 4 } +``` + ## Callbacks The callback functions can be inserted into your `.c`: From 91ae2741adc930a7756e24d1ef4f07b9b6eb26f5 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Wed, 3 Mar 2021 17:03:28 -0800 Subject: [PATCH 05/13] fix formating of encoder.c with clang-format --- quantum/encoder.c | 89 +++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/quantum/encoder.c b/quantum/encoder.c index a93c217a6cce..eb21710a2a65 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -35,31 +35,31 @@ static pin_t encoders_pad_a[] = ENCODERS_PAD_A; static pin_t encoders_pad_b[] = ENCODERS_PAD_B; #ifdef ENCODER_RESOLUTIONS - static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; +static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; #endif #ifndef SPLIT_KEYBOARD -# define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) +# define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) #else - // if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads) - #ifndef ENCODERS_PAD_A_RIGHT - # define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A - #endif - #ifndef ENCODERS_PAD_B_RIGHT - # define ENCODERS_PAD_B_RIGHT ENCODERS_PAD_B - #endif - #if defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTIONS_RIGHT) - # define ENCODER_RESOLUTIONS_RIGHT ENCODER_RESOLUTIONS - #endif - -# define NUMBER_OF_ENCODERS ((sizeof(encoders_pad_a) + sizeof(encoders_pad_a_right)) / sizeof(pin_t)) -# define NUMBER_OF_ENCODERS_LEFT (sizeof(encoders_pad_a) / sizeof(pin_t)) -# define NUMBER_OF_ENCODERS_RIGHT (sizeof(encoders_pad_a_right) / sizeof(pin_t)) - static pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; - static pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; - #ifdef ENCODER_RESOLUTIONS_RIGHT - static uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT; - #endif +// if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads) +# ifndef ENCODERS_PAD_A_RIGHT +# define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A +# endif +# ifndef ENCODERS_PAD_B_RIGHT +# define ENCODERS_PAD_B_RIGHT ENCODERS_PAD_B +# endif +# if defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTIONS_RIGHT) +# define ENCODER_RESOLUTIONS_RIGHT ENCODER_RESOLUTIONS +# endif + +# define NUMBER_OF_ENCODERS ((sizeof(encoders_pad_a) + sizeof(encoders_pad_a_right)) / sizeof(pin_t)) +# define NUMBER_OF_ENCODERS_LEFT (sizeof(encoders_pad_a) / sizeof(pin_t)) +# define NUMBER_OF_ENCODERS_RIGHT (sizeof(encoders_pad_a_right) / sizeof(pin_t)) +static pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; +static pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; +# ifdef ENCODER_RESOLUTIONS_RIGHT +static uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT; +# endif #endif #ifndef ENCODER_DIRECTION_FLIP @@ -85,53 +85,52 @@ static uint8_t numEncodersHere; // index of the first encoder connected to this controller (only for right halves, this will be nonzero) static uint8_t firstEncoderHere; #ifdef SPLIT_KEYBOARD - // index of the first encoder connected to the other half - static uint8_t firstEncoderThere; +// index of the first encoder connected to the other half +static uint8_t firstEncoderThere; #endif // the pads for this controller -static pin_t *pad_a; -static pin_t *pad_b; +static pin_t* pad_a; +static pin_t* pad_b; void encoder_init(void) { #ifndef SPLIT_KEYBOARD - numEncodersHere = NUMBER_OF_ENCODERS; - pad_a = encoders_pad_a; - pad_b = encoders_pad_b; + numEncodersHere = NUMBER_OF_ENCODERS; + pad_a = encoders_pad_a; + pad_b = encoders_pad_b; firstEncoderHere = 0; #else if (is_keyboard_left()) { - numEncodersHere = NUMBER_OF_ENCODERS_LEFT; - pad_a = encoders_pad_a; - pad_b = encoders_pad_b; - firstEncoderHere = 0; + numEncodersHere = NUMBER_OF_ENCODERS_LEFT; + pad_a = encoders_pad_a; + pad_b = encoders_pad_b; + firstEncoderHere = 0; firstEncoderThere = NUMBER_OF_ENCODERS_LEFT; } else { - numEncodersHere = NUMBER_OF_ENCODERS_RIGHT; - pad_a = encoders_pad_a_right; - pad_b = encoders_pad_b_right; - firstEncoderHere = NUMBER_OF_ENCODERS_LEFT; + numEncodersHere = NUMBER_OF_ENCODERS_RIGHT; + pad_a = encoders_pad_a_right; + pad_b = encoders_pad_b_right; + firstEncoderHere = NUMBER_OF_ENCODERS_LEFT; firstEncoderThere = 0; } #endif - + for (int i = 0; i < numEncodersHere; i++) { setPinInputHigh(pad_a[i]); setPinInputHigh(pad_b[i]); encoder_state[firstEncoderHere + i] = (readPin(pad_a[i]) << 0) | (readPin(pad_b[i]) << 1); } - } static bool encoder_update(int8_t index, uint8_t state) { - bool changed = false; - + bool changed = false; + #ifdef ENCODER_RESOLUTIONS - #ifndef SPLIT_KEYBOARD - int8_t resolution = encoder_resolutions[index]; - #else - int8_t resolution = is_keyboard_left() ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT]; - #endif +# ifndef SPLIT_KEYBOARD + int8_t resolution = encoder_resolutions[index]; +# else + int8_t resolution = is_keyboard_left() ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT]; +# endif #else int8_t resolution = ENCODER_RESOLUTION; #endif From 8f2f14fdec1be4ec3a404a89f0f3819350fb6386 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Thu, 4 Mar 2021 12:46:54 -0800 Subject: [PATCH 06/13] replace include of quantum.h in encoder.h --- quantum/encoder.c | 4 ++-- quantum/encoder.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/quantum/encoder.c b/quantum/encoder.c index eb21710a2a65..cee2c8f78c3a 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -99,7 +99,7 @@ void encoder_init(void) { pad_b = encoders_pad_b; firstEncoderHere = 0; #else - if (is_keyboard_left()) { + if (isLeftHand) { numEncodersHere = NUMBER_OF_ENCODERS_LEFT; pad_a = encoders_pad_a; pad_b = encoders_pad_b; @@ -129,7 +129,7 @@ static bool encoder_update(int8_t index, uint8_t state) { # ifndef SPLIT_KEYBOARD int8_t resolution = encoder_resolutions[index]; # else - int8_t resolution = is_keyboard_left() ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT]; + int8_t resolution = isLeftHand ? encoder_resolutions[index] : encoder_resolutions_right[index - NUMBER_OF_ENCODERS_LEFT]; # endif #else int8_t resolution = ENCODER_RESOLUTION; diff --git a/quantum/encoder.h b/quantum/encoder.h index db6f220da4a4..71089625e03e 100644 --- a/quantum/encoder.h +++ b/quantum/encoder.h @@ -17,7 +17,9 @@ #pragma once -#include "quantum.h" +#include +#include +#include void encoder_init(void); bool encoder_read(void); From f283d0f0a41eb139d393fd3614a148e1ac829243 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Thu, 4 Mar 2021 15:07:30 -0800 Subject: [PATCH 07/13] fix transport buffer size for encoders --- quantum/split_common/transport.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 27a1c0d3a426..646f2f1b2424 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -18,8 +18,17 @@ #ifdef ENCODER_ENABLE # include "encoder.h" -static pin_t encoders_pad[] = ENCODERS_PAD_A; -# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) +// if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads) +# ifndef ENCODERS_PAD_A_RIGHT +# define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A +# endif +# ifndef ENCODERS_PAD_B_RIGHT +# define ENCODERS_PAD_B_RIGHT ENCODERS_PAD_B +# endif +# define NUMBER_OF_ENCODERS ((sizeof(encoders_pad_a) + sizeof(encoders_pad_a_right)) / sizeof(pin_t)) +// only needed to calculate number of encoders / size of buffer +static pin_t encoders_pad_a[] = ENCODERS_PAD_A; +static pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; #endif #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) From b8f157b857a4d8edfedf48851095d678b199d2c0 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Fri, 5 Mar 2021 13:05:55 -0800 Subject: [PATCH 08/13] add unit tests for encoders --- build_test.mk | 1 + quantum/encoder.c | 13 +- quantum/encoder.h | 1 - quantum/encoder/tests/encoder_tests.cpp | 130 ++++++++++++++++++ quantum/encoder/tests/encoder_tests_split.cpp | 129 +++++++++++++++++ quantum/encoder/tests/mock.c | 21 +++ quantum/encoder/tests/mock.h | 22 +++ quantum/encoder/tests/mock_split.c | 23 ++++ quantum/encoder/tests/mock_split.h | 28 ++++ quantum/encoder/tests/rules.mk | 13 ++ quantum/encoder/tests/testlist.mk | 3 + testlist.mk | 1 + 12 files changed, 382 insertions(+), 3 deletions(-) create mode 100644 quantum/encoder/tests/encoder_tests.cpp create mode 100644 quantum/encoder/tests/encoder_tests_split.cpp create mode 100644 quantum/encoder/tests/mock.c create mode 100644 quantum/encoder/tests/mock.h create mode 100644 quantum/encoder/tests/mock_split.c create mode 100644 quantum/encoder/tests/mock_split.h create mode 100644 quantum/encoder/tests/rules.mk create mode 100644 quantum/encoder/tests/testlist.mk diff --git a/build_test.mk b/build_test.mk index 77c4265f9371..e857be26e164 100644 --- a/build_test.mk +++ b/build_test.mk @@ -51,6 +51,7 @@ include common_features.mk include $(TMK_PATH)/common.mk include $(QUANTUM_PATH)/sequencer/tests/rules.mk include $(QUANTUM_PATH)/serial_link/tests/rules.mk +include $(QUANTUM_PATH)/encoder/tests/rules.mk ifneq ($(filter $(FULL_TESTS),$(TEST)),) include build_full_test.mk endif diff --git a/quantum/encoder.c b/quantum/encoder.c index cee2c8f78c3a..92153a65c057 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -16,8 +16,17 @@ */ #include "encoder.h" -#ifdef SPLIT_KEYBOARD -# include "split_util.h" + +// this is for unit testing +#if defined(ENCODER_MOCK_SINGLE) +# include "encoder/tests/mock.h" +#elif defined(ENCODER_MOCK_SPLIT) +# include "encoder/tests/mock_split.h" +#else +# include +# ifdef SPLIT_KEYBOARD +# include "split_util.h" +# endif #endif // for memcpy diff --git a/quantum/encoder.h b/quantum/encoder.h index 71089625e03e..d5cfa4d26f8f 100644 --- a/quantum/encoder.h +++ b/quantum/encoder.h @@ -19,7 +19,6 @@ #include #include -#include void encoder_init(void); bool encoder_read(void); diff --git a/quantum/encoder/tests/encoder_tests.cpp b/quantum/encoder/tests/encoder_tests.cpp new file mode 100644 index 000000000000..b118352c30a5 --- /dev/null +++ b/quantum/encoder/tests/encoder_tests.cpp @@ -0,0 +1,130 @@ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include +#include +#include + +extern "C" { + #include "encoder.h" + #include "encoder/tests/mock.h" +} + +struct update { + int8_t index; + bool clockwise; +}; + +uint8_t uidx = 0; +update updates[32]; + +void encoder_update_kb(int8_t index, bool clockwise) { + updates[uidx % 32] = {index, clockwise}; + uidx++; +} + +bool setAndRead(pin_t pin, bool val) { + setPin(pin, val); + return encoder_read(); +} + +class EncoderTest : public ::testing::Test { + +}; + +TEST_F(EncoderTest, TestInit) { + uidx = 0; + encoder_init(); + EXPECT_EQ(pinIsInputHigh[0], true); + EXPECT_EQ(pinIsInputHigh[1], true); + EXPECT_EQ(uidx, 0); +} + +TEST_F(EncoderTest, TestOneClockwise) { + uidx = 0; + encoder_init(); + // send 4 pulses. with resolution 4, that's one step and we should get 1 update. + setAndRead(0, false); + setAndRead(1, false); + setAndRead(0, true); + setAndRead(1, true); + + EXPECT_EQ(uidx, 1); + EXPECT_EQ(updates[0].index, 0); + EXPECT_EQ(updates[0].clockwise, true); +} + +TEST_F(EncoderTest, TestOneCounterClockwise) { + uidx = 0; + encoder_init(); + setAndRead(1, false); + setAndRead(0, false); + setAndRead(1, true); + setAndRead(0, true); + + EXPECT_EQ(uidx, 1); + EXPECT_EQ(updates[0].index, 0); + EXPECT_EQ(updates[0].clockwise, false); +} + +TEST_F(EncoderTest, TestTwoClockwiseOneCC) { + uidx = 0; + encoder_init(); + setAndRead(0, false); + setAndRead(1, false); + setAndRead(0, true); + setAndRead(1, true); + setAndRead(0, false); + setAndRead(1, false); + setAndRead(0, true); + setAndRead(1, true); + setAndRead(1, false); + setAndRead(0, false); + setAndRead(1, true); + setAndRead(0, true); + + EXPECT_EQ(uidx, 3); + EXPECT_EQ(updates[0].index, 0); + EXPECT_EQ(updates[0].clockwise, true); + EXPECT_EQ(updates[1].index, 0); + EXPECT_EQ(updates[1].clockwise, true); + EXPECT_EQ(updates[2].index, 0); + EXPECT_EQ(updates[2].clockwise, false); +} + +TEST_F(EncoderTest, TestNoEarly) { + uidx = 0; + encoder_init(); + // send 3 pulses. with resolution 4, that's not enough for a step. + setAndRead(0, false); + setAndRead(1, false); + setAndRead(0, true); + EXPECT_EQ(uidx, 0); + // now send last pulse + setAndRead(1, true); + EXPECT_EQ(uidx, 1); + EXPECT_EQ(updates[0].index, 0); + EXPECT_EQ(updates[0].clockwise, true); +} + +TEST_F(EncoderTest, TestHalfway) { + uidx = 0; + encoder_init(); + // go halfway + setAndRead(0, false); + setAndRead(1, false); + EXPECT_EQ(uidx, 0); + // back off + setAndRead(1, true); + setAndRead(0, true); + EXPECT_EQ(uidx, 0); + // go all the way + setAndRead(0, false); + setAndRead(1, false); + setAndRead(0, true); + setAndRead(1, true); + // should result in 1 update + EXPECT_EQ(uidx, 1); + EXPECT_EQ(updates[0].index, 0); + EXPECT_EQ(updates[0].clockwise, true); +} diff --git a/quantum/encoder/tests/encoder_tests_split.cpp b/quantum/encoder/tests/encoder_tests_split.cpp new file mode 100644 index 000000000000..1680387d3c59 --- /dev/null +++ b/quantum/encoder/tests/encoder_tests_split.cpp @@ -0,0 +1,129 @@ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include +#include +#include + +extern "C" { + #include "encoder.h" + #include "encoder/tests/mock_split.h" +} + +struct update { + int8_t index; + bool clockwise; +}; + +uint8_t uidx = 0; +update updates[32]; + +bool isLeftHand; + +void encoder_update_kb(int8_t index, bool clockwise) { + if (!isLeftHand) { + // this method has no effect on slave half + printf("ignoring update on right hand (%d,%s)\n", index, clockwise ? "CW" : "CC"); + return; + } + updates[uidx % 32] = {index, clockwise}; + uidx++; +} + +bool setAndRead(pin_t pin, bool val) { + setPin(pin, val); + return encoder_read(); +} + +class EncoderTest : public ::testing::Test { + protected: + void SetUp() override { + uidx = 0; + for (int i = 0; i < 32; i++) { + pinIsInputHigh[i] = 0; + pins[i] = 0; + } + } +}; + +TEST_F(EncoderTest, TestInitLeft) { + isLeftHand = true; + encoder_init(); + EXPECT_EQ(pinIsInputHigh[0], true); + EXPECT_EQ(pinIsInputHigh[1], true); + EXPECT_EQ(pinIsInputHigh[2], false); + EXPECT_EQ(pinIsInputHigh[3], false); + EXPECT_EQ(uidx, 0); +} + +TEST_F(EncoderTest, TestInitRight) { + isLeftHand = false; + encoder_init(); + EXPECT_EQ(pinIsInputHigh[0], false); + EXPECT_EQ(pinIsInputHigh[1], false); + EXPECT_EQ(pinIsInputHigh[2], true); + EXPECT_EQ(pinIsInputHigh[3], true); + EXPECT_EQ(uidx, 0); +} + +TEST_F(EncoderTest, TestOneClockwiseLeft) { + isLeftHand = true; + encoder_init(); + // send 4 pulses. with resolution 4, that's one step and we should get 1 update. + setAndRead(0, false); + setAndRead(1, false); + setAndRead(0, true); + setAndRead(1, true); + + EXPECT_EQ(uidx, 1); + EXPECT_EQ(updates[0].index, 0); + EXPECT_EQ(updates[0].clockwise, true); +} + +TEST_F(EncoderTest, TestOneClockwiseRightSent) { + isLeftHand = false; + encoder_init(); + // send 4 pulses. with resolution 4, that's one step and we should get 1 update. + setAndRead(2, false); + setAndRead(3, false); + setAndRead(2, true); + setAndRead(3, true); + + uint8_t slave_state[2] = {0}; + encoder_state_raw(slave_state); + + EXPECT_EQ((int8_t) slave_state[0], -1); +} + +/* this test will not work after the previous test. + * this is due to encoder_value[1] already being set to -1 when simulating the right half. + * When we now receive this update acting as the left half, there is no change. + * This is hard to mock, as the static values inside encoder.c normally exist twice, once on each half, + * but here, they only exist once. + */ + +// TEST_F(EncoderTest, TestOneClockwiseRightReceived) { +// isLeftHand = true; +// encoder_init(); + + +// uint8_t slave_state[2] = {255, 0}; +// encoder_update_raw(slave_state); + +// EXPECT_EQ(uidx, 1); +// EXPECT_EQ(updates[0].index, 1); +// EXPECT_EQ(updates[0].clockwise, true); +// } + +TEST_F(EncoderTest, TestOneCounterClockwiseRightReceived) { + isLeftHand = true; + encoder_init(); + + + uint8_t slave_state[2] = {0, 0}; + encoder_update_raw(slave_state); + + EXPECT_EQ(uidx, 1); + EXPECT_EQ(updates[0].index, 1); + EXPECT_EQ(updates[0].clockwise, false); +} diff --git a/quantum/encoder/tests/mock.c b/quantum/encoder/tests/mock.c new file mode 100644 index 000000000000..4c3c11e6f87e --- /dev/null +++ b/quantum/encoder/tests/mock.c @@ -0,0 +1,21 @@ + +#include "mock.h" + +bool pins[32] = {0}; +bool pinIsInputHigh[32] = {0}; + +uint8_t mockSetPinInputHigh(pin_t pin) { + // dprintf("Setting pin %d input high.", pin); + pins[pin] = true; + pinIsInputHigh[pin] = true; + return 0; +} + +bool mockReadPin(pin_t pin) { + return pins[pin]; +} + +bool setPin(pin_t pin, bool val) { + pins[pin] = val; + return val; +} diff --git a/quantum/encoder/tests/mock.h b/quantum/encoder/tests/mock.h new file mode 100644 index 000000000000..311ab3745913 --- /dev/null +++ b/quantum/encoder/tests/mock.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +/* Here, "pins" from 0 to 31 are allowed. */ +#define ENCODERS_PAD_A { 0 } +#define ENCODERS_PAD_B { 1 } + +typedef uint8_t pin_t; + +extern bool pins[]; +extern bool pinIsInputHigh[]; + +#define setPinInputHigh(pin) (mockSetPinInputHigh(pin)) +#define readPin(pin) (mockReadPin(pin)) + +uint8_t mockSetPinInputHigh(pin_t pin); + +bool mockReadPin(pin_t pin); + +bool setPin(pin_t pin, bool val); diff --git a/quantum/encoder/tests/mock_split.c b/quantum/encoder/tests/mock_split.c new file mode 100644 index 000000000000..42e0cc209fab --- /dev/null +++ b/quantum/encoder/tests/mock_split.c @@ -0,0 +1,23 @@ + +#include "mock_split.h" + +bool pins[32] = {0}; +bool pinIsInputHigh[32] = {0}; + +uint8_t mockSetPinInputHigh(pin_t pin) { + // dprintf("Setting pin %d input high.", pin); + pins[pin] = true; + pinIsInputHigh[pin] = true; + return 0; +} + +bool mockReadPin(pin_t pin) { + return pins[pin]; +} + +bool setPin(pin_t pin, bool val) { + pins[pin] = val; + return val; +} + +void last_encoder_activity_trigger(void) {} diff --git a/quantum/encoder/tests/mock_split.h b/quantum/encoder/tests/mock_split.h new file mode 100644 index 000000000000..845103836482 --- /dev/null +++ b/quantum/encoder/tests/mock_split.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +#define SPLIT_KEYBOARD +/* Here, "pins" from 0 to 31 are allowed. */ +#define ENCODERS_PAD_A { 0 } +#define ENCODERS_PAD_B { 1 } +#define ENCODERS_PAD_A_RIGHT { 2 } +#define ENCODERS_PAD_B_RIGHT { 3 } + +typedef uint8_t pin_t; +extern bool isLeftHand; +void encoder_state_raw(uint8_t* slave_state); +void encoder_update_raw(uint8_t* slave_state); + +extern bool pins[]; +extern bool pinIsInputHigh[]; + +#define setPinInputHigh(pin) (mockSetPinInputHigh(pin)) +#define readPin(pin) (mockReadPin(pin)) + +uint8_t mockSetPinInputHigh(pin_t pin); + +bool mockReadPin(pin_t pin); + +bool setPin(pin_t pin, bool val); diff --git a/quantum/encoder/tests/rules.mk b/quantum/encoder/tests/rules.mk new file mode 100644 index 000000000000..b826ce3aedec --- /dev/null +++ b/quantum/encoder/tests/rules.mk @@ -0,0 +1,13 @@ +encoder_DEFS := -DENCODER_MOCK_SINGLE + +encoder_SRC := \ + $(QUANTUM_PATH)/encoder/tests/mock.c \ + $(QUANTUM_PATH)/encoder/tests/encoder_tests.cpp \ + $(QUANTUM_PATH)/encoder.c + +encoder_split_DEFS := -DENCODER_MOCK_SPLIT + +encoder_split_SRC := \ + $(QUANTUM_PATH)/encoder/tests/mock_split.c \ + $(QUANTUM_PATH)/encoder/tests/encoder_tests_split.cpp \ + $(QUANTUM_PATH)/encoder.c diff --git a/quantum/encoder/tests/testlist.mk b/quantum/encoder/tests/testlist.mk new file mode 100644 index 000000000000..1be9f4a0548e --- /dev/null +++ b/quantum/encoder/tests/testlist.mk @@ -0,0 +1,3 @@ +TEST_LIST += \ + encoder \ + encoder_split diff --git a/testlist.mk b/testlist.mk index 0d7609b9f071..80d76bd9af28 100644 --- a/testlist.mk +++ b/testlist.mk @@ -3,6 +3,7 @@ FULL_TESTS := $(TEST_LIST) include $(ROOT_DIR)/quantum/sequencer/tests/testlist.mk include $(ROOT_DIR)/quantum/serial_link/tests/testlist.mk +include $(ROOT_DIR)/quantum/encoder/tests/testlist.mk define VALIDATE_TEST_LIST ifneq ($1,) From 32599a45f9982daf6982e0d350d4265ca25fe118 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Thu, 30 Sep 2021 23:50:40 +0200 Subject: [PATCH 09/13] format encoder tests --- quantum/encoder/tests/encoder_tests.cpp | 12 +++++------- quantum/encoder/tests/encoder_tests_split.cpp | 16 +++++++--------- quantum/encoder/tests/mock.c | 8 +++----- quantum/encoder/tests/mock.h | 6 ++++-- quantum/encoder/tests/mock_split.c | 8 +++----- quantum/encoder/tests/mock_split.h | 18 +++++++++++------- 6 files changed, 33 insertions(+), 35 deletions(-) diff --git a/quantum/encoder/tests/encoder_tests.cpp b/quantum/encoder/tests/encoder_tests.cpp index b118352c30a5..ac4037929796 100644 --- a/quantum/encoder/tests/encoder_tests.cpp +++ b/quantum/encoder/tests/encoder_tests.cpp @@ -6,17 +6,17 @@ #include extern "C" { - #include "encoder.h" - #include "encoder/tests/mock.h" +#include "encoder.h" +#include "encoder/tests/mock.h" } struct update { int8_t index; - bool clockwise; + bool clockwise; }; uint8_t uidx = 0; -update updates[32]; +update updates[32]; void encoder_update_kb(int8_t index, bool clockwise) { updates[uidx % 32] = {index, clockwise}; @@ -28,9 +28,7 @@ bool setAndRead(pin_t pin, bool val) { return encoder_read(); } -class EncoderTest : public ::testing::Test { - -}; +class EncoderTest : public ::testing::Test {}; TEST_F(EncoderTest, TestInit) { uidx = 0; diff --git a/quantum/encoder/tests/encoder_tests_split.cpp b/quantum/encoder/tests/encoder_tests_split.cpp index 1680387d3c59..a8aa5520a05d 100644 --- a/quantum/encoder/tests/encoder_tests_split.cpp +++ b/quantum/encoder/tests/encoder_tests_split.cpp @@ -6,17 +6,17 @@ #include extern "C" { - #include "encoder.h" - #include "encoder/tests/mock_split.h" +#include "encoder.h" +#include "encoder/tests/mock_split.h" } struct update { int8_t index; - bool clockwise; + bool clockwise; }; uint8_t uidx = 0; -update updates[32]; +update updates[32]; bool isLeftHand; @@ -36,12 +36,12 @@ bool setAndRead(pin_t pin, bool val) { } class EncoderTest : public ::testing::Test { - protected: + protected: void SetUp() override { uidx = 0; for (int i = 0; i < 32; i++) { pinIsInputHigh[i] = 0; - pins[i] = 0; + pins[i] = 0; } } }; @@ -92,7 +92,7 @@ TEST_F(EncoderTest, TestOneClockwiseRightSent) { uint8_t slave_state[2] = {0}; encoder_state_raw(slave_state); - EXPECT_EQ((int8_t) slave_state[0], -1); + EXPECT_EQ((int8_t)slave_state[0], -1); } /* this test will not work after the previous test. @@ -106,7 +106,6 @@ TEST_F(EncoderTest, TestOneClockwiseRightSent) { // isLeftHand = true; // encoder_init(); - // uint8_t slave_state[2] = {255, 0}; // encoder_update_raw(slave_state); @@ -119,7 +118,6 @@ TEST_F(EncoderTest, TestOneCounterClockwiseRightReceived) { isLeftHand = true; encoder_init(); - uint8_t slave_state[2] = {0, 0}; encoder_update_raw(slave_state); diff --git a/quantum/encoder/tests/mock.c b/quantum/encoder/tests/mock.c index 4c3c11e6f87e..10a2fce7fbc4 100644 --- a/quantum/encoder/tests/mock.c +++ b/quantum/encoder/tests/mock.c @@ -1,19 +1,17 @@ #include "mock.h" -bool pins[32] = {0}; +bool pins[32] = {0}; bool pinIsInputHigh[32] = {0}; uint8_t mockSetPinInputHigh(pin_t pin) { // dprintf("Setting pin %d input high.", pin); - pins[pin] = true; + pins[pin] = true; pinIsInputHigh[pin] = true; return 0; } -bool mockReadPin(pin_t pin) { - return pins[pin]; -} +bool mockReadPin(pin_t pin) { return pins[pin]; } bool setPin(pin_t pin, bool val) { pins[pin] = val; diff --git a/quantum/encoder/tests/mock.h b/quantum/encoder/tests/mock.h index 311ab3745913..9877aca02cc7 100644 --- a/quantum/encoder/tests/mock.h +++ b/quantum/encoder/tests/mock.h @@ -4,8 +4,10 @@ #include /* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A { 0 } -#define ENCODERS_PAD_B { 1 } +#define ENCODERS_PAD_A \ + { 0 } +#define ENCODERS_PAD_B \ + { 1 } typedef uint8_t pin_t; diff --git a/quantum/encoder/tests/mock_split.c b/quantum/encoder/tests/mock_split.c index 42e0cc209fab..f4650a01fb00 100644 --- a/quantum/encoder/tests/mock_split.c +++ b/quantum/encoder/tests/mock_split.c @@ -1,19 +1,17 @@ #include "mock_split.h" -bool pins[32] = {0}; +bool pins[32] = {0}; bool pinIsInputHigh[32] = {0}; uint8_t mockSetPinInputHigh(pin_t pin) { // dprintf("Setting pin %d input high.", pin); - pins[pin] = true; + pins[pin] = true; pinIsInputHigh[pin] = true; return 0; } -bool mockReadPin(pin_t pin) { - return pins[pin]; -} +bool mockReadPin(pin_t pin) { return pins[pin]; } bool setPin(pin_t pin, bool val) { pins[pin] = val; diff --git a/quantum/encoder/tests/mock_split.h b/quantum/encoder/tests/mock_split.h index 845103836482..53f144ce5e7d 100644 --- a/quantum/encoder/tests/mock_split.h +++ b/quantum/encoder/tests/mock_split.h @@ -5,15 +5,19 @@ #define SPLIT_KEYBOARD /* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A { 0 } -#define ENCODERS_PAD_B { 1 } -#define ENCODERS_PAD_A_RIGHT { 2 } -#define ENCODERS_PAD_B_RIGHT { 3 } +#define ENCODERS_PAD_A \ + { 0 } +#define ENCODERS_PAD_B \ + { 1 } +#define ENCODERS_PAD_A_RIGHT \ + { 2 } +#define ENCODERS_PAD_B_RIGHT \ + { 3 } typedef uint8_t pin_t; -extern bool isLeftHand; -void encoder_state_raw(uint8_t* slave_state); -void encoder_update_raw(uint8_t* slave_state); +extern bool isLeftHand; +void encoder_state_raw(uint8_t* slave_state); +void encoder_update_raw(uint8_t* slave_state); extern bool pins[]; extern bool pinIsInputHigh[]; From 8213db23d4ad0afabc75b95c90ba2307a8dfe1e6 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Fri, 1 Oct 2021 00:25:44 +0200 Subject: [PATCH 10/13] reapply transport buffer size fix after transport was refactored --- quantum/split_common/transport.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h index 1d4f6ed0cd86..ab65ff56db6c 100644 --- a/quantum/split_common/transport.h +++ b/quantum/split_common/transport.h @@ -42,7 +42,11 @@ bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, #ifdef ENCODER_ENABLE # include "encoder.h" -# define NUMBER_OF_ENCODERS (sizeof((pin_t[])ENCODERS_PAD_A) / sizeof(pin_t)) +// if no pads for right half are defined, we assume the keyboard is symmetric (i.e. same pads) +# ifndef ENCODERS_PAD_A_RIGHT +# define ENCODERS_PAD_A_RIGHT ENCODERS_PAD_A +# endif +# define NUMBER_OF_ENCODERS ((sizeof((pin_t[])ENCODERS_PAD_A) + (sizeof((pin_t[])ENCODERS_PAD_A_RIGHT)) / sizeof(pin_t)) #endif // ENCODER_ENABLE #ifdef BACKLIGHT_ENABLE From 15b1c51a0d628080dcc7333e1ad7896d2ea4ddf8 Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Wed, 3 Nov 2021 17:29:54 +0100 Subject: [PATCH 11/13] add license header to encoder test files --- quantum/encoder/tests/encoder_tests.cpp | 15 +++++++++++++++ quantum/encoder/tests/encoder_tests_split.cpp | 15 +++++++++++++++ quantum/encoder/tests/mock.c | 15 +++++++++++++++ quantum/encoder/tests/mock.h | 16 ++++++++++++++++ quantum/encoder/tests/mock_split.c | 15 +++++++++++++++ quantum/encoder/tests/mock_split.h | 16 ++++++++++++++++ 6 files changed, 92 insertions(+) diff --git a/quantum/encoder/tests/encoder_tests.cpp b/quantum/encoder/tests/encoder_tests.cpp index ac4037929796..1b2ac1a231ed 100644 --- a/quantum/encoder/tests/encoder_tests.cpp +++ b/quantum/encoder/tests/encoder_tests.cpp @@ -1,3 +1,18 @@ +/* Copyright 2021 Balz Guenat + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "gtest/gtest.h" #include "gmock/gmock.h" diff --git a/quantum/encoder/tests/encoder_tests_split.cpp b/quantum/encoder/tests/encoder_tests_split.cpp index a8aa5520a05d..320d2655e574 100644 --- a/quantum/encoder/tests/encoder_tests_split.cpp +++ b/quantum/encoder/tests/encoder_tests_split.cpp @@ -1,3 +1,18 @@ +/* Copyright 2021 Balz Guenat + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "gtest/gtest.h" #include "gmock/gmock.h" diff --git a/quantum/encoder/tests/mock.c b/quantum/encoder/tests/mock.c index 10a2fce7fbc4..d0506a938f7b 100644 --- a/quantum/encoder/tests/mock.c +++ b/quantum/encoder/tests/mock.c @@ -1,3 +1,18 @@ +/* Copyright 2021 Balz Guenat + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "mock.h" diff --git a/quantum/encoder/tests/mock.h b/quantum/encoder/tests/mock.h index 9877aca02cc7..dbc25a084618 100644 --- a/quantum/encoder/tests/mock.h +++ b/quantum/encoder/tests/mock.h @@ -1,3 +1,19 @@ +/* Copyright 2021 Balz Guenat + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #pragma once #include diff --git a/quantum/encoder/tests/mock_split.c b/quantum/encoder/tests/mock_split.c index f4650a01fb00..68bf3af59929 100644 --- a/quantum/encoder/tests/mock_split.c +++ b/quantum/encoder/tests/mock_split.c @@ -1,3 +1,18 @@ +/* Copyright 2021 Balz Guenat + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "mock_split.h" diff --git a/quantum/encoder/tests/mock_split.h b/quantum/encoder/tests/mock_split.h index 53f144ce5e7d..0ae62652f97f 100644 --- a/quantum/encoder/tests/mock_split.h +++ b/quantum/encoder/tests/mock_split.h @@ -1,3 +1,19 @@ +/* Copyright 2021 Balz Guenat + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #pragma once #include From d545e986eb02239cf5a32f07d9510eaee3f48842 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Sat, 20 Nov 2021 08:36:01 +1100 Subject: [PATCH 12/13] Fix overall test execution, tests are failing. --- build_test.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/build_test.mk b/build_test.mk index 44fade25294d..36cb7936edd6 100644 --- a/build_test.mk +++ b/build_test.mk @@ -25,7 +25,6 @@ GTEST_INTERNAL_INC :=\ $(GTEST_OUTPUT)_SRC :=\ googletest/src/gtest-all.cc\ - googletest/src/gtest_main.cc\ googlemock/src/gmock-all.cc $(GTEST_OUTPUT)_DEFS := From 1d9e349beb1c28c84c39b183b29ad5b9760504ff Mon Sep 17 00:00:00 2001 From: Balz Guenat Date: Sat, 20 Nov 2021 13:05:34 +0100 Subject: [PATCH 13/13] fix encoder tests --- quantum/encoder/tests/encoder_tests.cpp | 3 ++- quantum/encoder/tests/encoder_tests_split.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/quantum/encoder/tests/encoder_tests.cpp b/quantum/encoder/tests/encoder_tests.cpp index 1b2ac1a231ed..1888fdab8d08 100644 --- a/quantum/encoder/tests/encoder_tests.cpp +++ b/quantum/encoder/tests/encoder_tests.cpp @@ -33,9 +33,10 @@ struct update { uint8_t uidx = 0; update updates[32]; -void encoder_update_kb(int8_t index, bool clockwise) { +bool encoder_update_kb(uint8_t index, bool clockwise) { updates[uidx % 32] = {index, clockwise}; uidx++; + return true; } bool setAndRead(pin_t pin, bool val) { diff --git a/quantum/encoder/tests/encoder_tests_split.cpp b/quantum/encoder/tests/encoder_tests_split.cpp index 320d2655e574..25e52c83f9d6 100644 --- a/quantum/encoder/tests/encoder_tests_split.cpp +++ b/quantum/encoder/tests/encoder_tests_split.cpp @@ -35,14 +35,15 @@ update updates[32]; bool isLeftHand; -void encoder_update_kb(int8_t index, bool clockwise) { +bool encoder_update_kb(uint8_t index, bool clockwise) { if (!isLeftHand) { // this method has no effect on slave half printf("ignoring update on right hand (%d,%s)\n", index, clockwise ? "CW" : "CC"); - return; + return true; } updates[uidx % 32] = {index, clockwise}; uidx++; + return true; } bool setAndRead(pin_t pin, bool val) {