diff options
author | Drashna Jaelre <drashna@live.com> | 2019-09-03 08:34:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-03 08:34:31 -0700 |
commit | dab4967f1bebc9a70374ed3e1fe7906828b280c2 (patch) | |
tree | 3008882538fe229273fe9b8d5be662a951460f33 | |
parent | 9f46606dff2f52f31c6c36a63035cfb75824276a (diff) | |
download | qmk_firmware-dab4967f1bebc9a70374ed3e1fe7906828b280c2.tar.gz |
Add Dip Switch as a core feature (#6140)
* Add Dip Switches as a core feature
* Add documentation for Dip Switch feature
* Update Preonic Rev3 to use new feature and remove custom matrix
* Apply suggestions from code review
Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com>
* Remove custom matrix line completely
Rather than just disabling it
Co-Authored-By: fauxpark <fauxpark@gmail.com>
* DIP changes
Co-Authored-By: fauxpark <fauxpark@gmail.com>
* Use better check for DIP Switch configuration
* Add to show features
* Add bitmask callback for dip switch
* Fix OLKB Boards dip switch config
* Update docs to include bitmask example
* Fix comments/documentation
Co-Authored-By: fauxpark <fauxpark@gmail.com>
* Fix issues with docs and use example from @tuzonghua
* Fix wording
Co-Authored-By: fauxpark <fauxpark@gmail.com>
* Fix example to use proper formatting
Bad, BAAAAAAD drashna!!!
* Handle dip switch initialization better
-rw-r--r-- | common_features.mk | 6 | ||||
-rw-r--r-- | docs/_summary.md | 1 | ||||
-rw-r--r-- | docs/feature_dip_switch.md | 90 | ||||
-rw-r--r-- | docs/features.md | 1 | ||||
-rw-r--r-- | docs/zh-cn/_summary.md | 1 | ||||
-rw-r--r-- | keyboards/planck/keymaps/default/keymap.c | 2 | ||||
-rw-r--r-- | keyboards/planck/rev6/config.h | 15 | ||||
-rw-r--r-- | keyboards/planck/rev6/matrix.c | 176 | ||||
-rw-r--r-- | keyboards/planck/rev6/rev6.c | 10 | ||||
-rw-r--r-- | keyboards/planck/rev6/rules.mk | 3 | ||||
-rw-r--r-- | keyboards/preonic/keymaps/default/keymap.c | 2 | ||||
-rw-r--r-- | keyboards/preonic/rev3/config.h | 22 | ||||
-rw-r--r-- | keyboards/preonic/rev3/matrix.c | 187 | ||||
-rw-r--r-- | keyboards/preonic/rev3/rev3.c | 10 | ||||
-rw-r--r-- | keyboards/preonic/rev3/rules.mk | 7 | ||||
-rw-r--r-- | quantum/dip_switch.c | 71 | ||||
-rw-r--r-- | quantum/dip_switch.h | 29 | ||||
-rw-r--r-- | quantum/quantum.c | 8 | ||||
-rw-r--r-- | quantum/quantum.h | 5 | ||||
-rw-r--r-- | show_options.mk | 3 |
20 files changed, 256 insertions, 393 deletions
diff --git a/common_features.mk b/common_features.mk index 3296424a1..3bc6f1c73 100644 --- a/common_features.mk +++ b/common_features.mk @@ -358,3 +358,9 @@ ifeq ($(strip $(SPACE_CADET_ENABLE)), yes) SRC += $(QUANTUM_DIR)/process_keycode/process_space_cadet.c OPT_DEFS += -DSPACE_CADET_ENABLE endif + + +ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes) + SRC += $(QUANTUM_DIR)/dip_switch.c + OPT_DEFS += -DDIP_SWITCH_ENABLE +endif diff --git a/docs/_summary.md b/docs/_summary.md index d7a49a968..4e87d8f1f 100644 --- a/docs/_summary.md +++ b/docs/_summary.md @@ -63,6 +63,7 @@ * [Combos](feature_combo.md) * [Command](feature_command.md) * [Debounce API](feature_debounce_type.md) + * [DIP Switch](feature_dip_switch.md) * [Dynamic Macros](feature_dynamic_macros.md) * [Encoders](feature_encoders.md) * [Grave Escape](feature_grave_esc.md) diff --git a/docs/feature_dip_switch.md b/docs/feature_dip_switch.md new file mode 100644 index 000000000..bce47fed8 --- /dev/null +++ b/docs/feature_dip_switch.md @@ -0,0 +1,90 @@ +# DIP Switches + +DIP switches are supported by adding this to your `rules.mk`: + + DIP_SWITCH_ENABLE = yes + +and this to your `config.h`: + +```c +#define DIP_SWITCH_PINS { B14, A15, A10, B9 } +``` + +## Callbacks + +The callback functions can be inserted into your `<keyboard>.c`: + +```c +void dip_switch_update_kb(uint8_t index, bool active) { + dip_switch_update_user(index, active); +} +``` + + +or `keymap.c`: + +```c +void dip_switch_update_user(uint8_t index, bool active) { + switch (index) { + case 0: + if(active) { audio_on(); } else { audio_off(); } + break; + case 1: + if(active) { clicky_on(); } else { clicky_off(); } + break; + case 2: + if(active) { music_on(); } else { music_off(); } + break; + case 3: + if (active) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_song); + #endif + layer_on(_PLOVER); + } else { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + break; + } +} +``` + +Additionally, we support bit mask functions which allow for more complex handling. + + +```c +void dip_switch_update_mask_kb(uint32_t state) { + dip_switch_update_mask_user(state); +} +``` + + +or `keymap.c`: + +```c +void dip_switch_update_mask_user(uint32_t state) { + if (state & (1UL<<0) && state & (1UL<<1)) { + layer_on(_ADJUST); // C on esc + } else { + layer_off(_ADJUST); + } + if (state & (1UL<<0)) { + layer_on(_TEST_A); // A on ESC + } else { + layer_off(_TEST_A); + } + if (state & (1UL<<1)) { + layer_on(_TEST_B); // B on esc + } else { + layer_off(_TEST_B); + } +} +``` + + +## Hardware + +One side of the DIP switch should be wired directly to the pin on the MCU, and the other side to ground. It should not matter which side is connected to which, as it should be functionally the same. diff --git a/docs/features.md b/docs/features.md index f230c7c23..44299bf10 100644 --- a/docs/features.md +++ b/docs/features.md @@ -12,6 +12,7 @@ QMK has a staggering number of features for building your keyboard. It can take * [Combos](feature_combo.md) - Custom actions for multiple key holds. * [Command](feature_command.md) - Runtime version of bootmagic (Formerly known as "Magic"). * [Debounce API](feature_debounce_type.md) - Customization of debouncing algorithms, and the ability to add more/custom debouncing. +* [DIP Switch](feature_dip_switch.md) - Toggle switches for customizing board function. * [Dynamic Macros](feature_dynamic_macros.md) - Record and playback macros from the keyboard itself. * [Encoders](feature_encoders.md) - Rotary encoders! * [Grave Escape](feature_grave_esc.md) - Lets you use a single key for Esc and Grave. diff --git a/docs/zh-cn/_summary.md b/docs/zh-cn/_summary.md index b0d9f1c06..98b1440d9 100644 --- a/docs/zh-cn/_summary.md +++ b/docs/zh-cn/_summary.md @@ -54,6 +54,7 @@ * [热改键](feature_bootmagic.md) * [组合](feature_combo) * [命令](feature_command.md) + * [拨动开关](feature_dip_switch.md) * [动态宏指令](feature_dynamic_macros.md) * [编码器](feature_encoders.md) * [重音号Esc复合键](feature_grave_esc.md) diff --git a/keyboards/planck/keymaps/default/keymap.c b/keyboards/planck/keymaps/default/keymap.c index 901977198..44bc7db7f 100644 --- a/keyboards/planck/keymaps/default/keymap.c +++ b/keyboards/planck/keymaps/default/keymap.c @@ -289,7 +289,7 @@ void encoder_update(bool clockwise) { } } -void dip_update(uint8_t index, bool active) { +void dip_switch_update_user(uint8_t index, bool active) { switch (index) { case 0: if (active) { diff --git a/keyboards/planck/rev6/config.h b/keyboards/planck/rev6/config.h index 3354c3f80..d8c9d86ae 100644 --- a/keyboards/planck/rev6/config.h +++ b/keyboards/planck/rev6/config.h @@ -37,15 +37,20 @@ * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * */ -/* Note: These are not used for arm boards. They're here purely as documentation. - * #define MATRIX_ROW_PINS { PB0, PB1, PB2, PA15, PA10 } - * #define MATRIX_COL_PINS { PA2, PA3, PA6, PB14, PB15, PA8, PA9, PA7, PB3, PB4, PC14, PC15, PC13, PB5, PB6 } - * #define UNUSED_PINS - */ +/* Note: These are not used for arm boards. They're here purely as documentation. */ +#undef MATRIX_ROW_PINS +#undef MATRIX_COL_PINS + +#define MATRIX_ROW_PINS { A10, A9, A8, B15, C13, C14, C15, A2 } +#define MATRIX_COL_PINS { B11, B10, B2, B1, A7, B0 } + +#define UNUSED_PINS #define ENCODERS_PAD_A { B12 } #define ENCODERS_PAD_B { B13 } +#define DIP_SWITCH_PINS { B14, A15, A0, B9 } + #define MUSIC_MAP #undef AUDIO_VOICES #undef C6_AUDIO diff --git a/keyboards/planck/rev6/matrix.c b/keyboards/planck/rev6/matrix.c deleted file mode 100644 index 2df588cef..000000000 --- a/keyboards/planck/rev6/matrix.c +++ /dev/null @@ -1,176 +0,0 @@ -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include "hal.h" -#include "timer.h" -#include "wait.h" -#include "printf.h" -#include "backlight.h" -#include "matrix.h" -#include "action.h" -#include "keycode.h" -#include <string.h> - -/* - * col: { B11, B10, B2, B1, A7, B0 } - * row: { A10, A9, A8, B15, C13, C14, C15, A2 } - */ -/* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_COLS]; -static bool debouncing = false; -static uint16_t debouncing_time = 0; - -static bool dip_switch[4] = {0, 0, 0, 0}; - -__attribute__ ((weak)) -void matrix_init_user(void) {} - -__attribute__ ((weak)) -void matrix_scan_user(void) {} - -__attribute__ ((weak)) -void matrix_init_kb(void) { - matrix_init_user(); -} - -__attribute__ ((weak)) -void matrix_scan_kb(void) { - matrix_scan_user(); -} - -void matrix_init(void) { - printf("matrix init\n"); - //debug_matrix = true; - - // dip switch setup - palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP); - palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP); - palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP); - palSetPadMode(GPIOB, 9, PAL_MODE_INPUT_PULLUP); - - // actual matrix setup - palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL); - - palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOC, 13, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_PULLDOWN); - - - memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t)); - memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_row_t)); - - - matrix_init_quantum(); -} - -__attribute__ ((weak)) -void dip_update(uint8_t index, bool active) { } - -bool last_dip_switch[4] = {0}; - -uint8_t matrix_scan(void) { - // dip switch - dip_switch[0] = !palReadPad(GPIOB, 14); - dip_switch[1] = !palReadPad(GPIOA, 15); - dip_switch[2] = !palReadPad(GPIOA, 10); - dip_switch[3] = !palReadPad(GPIOB, 9); - for (uint8_t i = 0; i < 4; i++) { - if (last_dip_switch[i] ^ dip_switch[i]) - dip_update(i, dip_switch[i]); - } - memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch)); - - // actual matrix - for (int col = 0; col < MATRIX_COLS; col++) { - matrix_row_t data = 0; - - // strobe col { B11, B10, B2, B1, A7, B0 } - switch (col) { - case 0: palSetPad(GPIOB, 11); break; - case 1: palSetPad(GPIOB, 10); break; - case 2: palSetPad(GPIOB, 2); break; - case 3: palSetPad(GPIOB, 1); break; - case 4: palSetPad(GPIOA, 7); break; - case 5: palSetPad(GPIOB, 0); break; - } - - // need wait to settle pin state - wait_us(20); - - // read row data { A10, A9, A8, B15, C13, C14, C15, A2 } - data = ( - (palReadPad(GPIOA, 10) << 0 ) | - (palReadPad(GPIOA, 9) << 1 ) | - (palReadPad(GPIOA, 8) << 2 ) | - (palReadPad(GPIOB, 15) << 3 ) | - (palReadPad(GPIOC, 13) << 4 ) | - (palReadPad(GPIOC, 14) << 5 ) | - (palReadPad(GPIOC, 15) << 6 ) | - (palReadPad(GPIOA, 2) << 7 ) - ); - - // unstrobe col { B11, B10, B2, B1, A7, B0 } - switch (col) { - case 0: palClearPad(GPIOB, 11); break; - case 1: palClearPad(GPIOB, 10); break; - case 2: palClearPad(GPIOB, 2); break; - case 3: palClearPad(GPIOB, 1); break; - case 4: palClearPad(GPIOA, 7); break; - case 5: palClearPad(GPIOB, 0); break; - } - - if (matrix_debouncing[col] != data) { - matrix_debouncing[col] = data; - debouncing = true; - debouncing_time = timer_read(); - } - } - - if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { - for (int row = 0; row < MATRIX_ROWS; row++) { - matrix[row] = 0; - for (int col = 0; col < MATRIX_COLS; col++) { - matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col); - } - } - debouncing = false; - } - - matrix_scan_quantum(); - - return 1; -} - -bool matrix_is_on(uint8_t row, uint8_t col) { - return (matrix[row] & (1<<col)); -} - -matrix_row_t matrix_get_row(uint8_t row) { - return matrix[row]; -} - -void matrix_print(void) { - printf("\nr/c 01234567\n"); - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - printf("%X0: ", row); - matrix_row_t data = matrix_get_row(row); - for (int col = 0; col < MATRIX_COLS; col++) { - if (data & (1<<col)) - printf("1"); - else - printf("0"); - } - printf("\n"); - } -} diff --git a/keyboards/planck/rev6/rev6.c b/keyboards/planck/rev6/rev6.c index 650e1a194..8f4d168bf 100644 --- a/keyboards/planck/rev6/rev6.c +++ b/keyboards/planck/rev6/rev6.c @@ -22,3 +22,13 @@ void matrix_init_kb(void) { void matrix_scan_kb(void) { matrix_scan_user(); } + +#ifdef DIP_SWITCH_ENABLE +__attribute__((weak)) +void dip_update(uint8_t index, bool active) {} + +__attribute__((weak)) +void dip_switch_update_user(uint8_t index, bool active) { + dip_update(index, active); +} +#endif diff --git a/keyboards/planck/rev6/rules.mk b/keyboards/planck/rev6/rules.mk index c58275002..ea53c8f91 100644 --- a/keyboards/planck/rev6/rules.mk +++ b/keyboards/planck/rev6/rules.mk @@ -1,5 +1,4 @@ # project specific files -SRC = matrix.c LAYOUTS += ortho_4x12 # Cortex version @@ -31,9 +30,9 @@ API_SYSEX_ENABLE = no SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend #SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend -CUSTOM_MATRIX = yes # Custom matrix file # SERIAL_LINK_ENABLE = yes ENCODER_ENABLE = yes +DIP_SWITCH_ENABLE = yes LAYOUTS = ortho_4x12 planck_mit LAYOUTS_HAS_RGB = no diff --git a/keyboards/preonic/keymaps/default/keymap.c b/keyboards/preonic/keymaps/default/keymap.c index d37882eab..b45ed0835 100644 --- a/keyboards/preonic/keymaps/default/keymap.c +++ b/keyboards/preonic/keymaps/default/keymap.c @@ -259,7 +259,7 @@ void encoder_update_user(uint8_t index, bool clockwise) { } } -void dip_update(uint8_t index, bool active) { +void dip_switch_update_user(uint8_t index, bool active) { switch (index) { case 0: if (active) { diff --git a/keyboards/preonic/rev3/config.h b/keyboards/preonic/rev3/config.h index 2d2993455..5eac2169e 100644 --- a/keyboards/preonic/rev3/config.h +++ b/keyboards/preonic/rev3/config.h @@ -27,25 +27,17 @@ #define MATRIX_ROWS 10 #define MATRIX_COLS 6 -/* - * Keyboard Matrix Assignments - * - * Change this to how you wired your keyboard - * COLS: AVR pins used for columns, left to right - * ROWS: AVR pins used for rows, top to bottom - * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) - * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) - * -*/ -/* Note: These are not used for arm boards. They're here purely as documentation. - * #define MATRIX_ROW_PINS { PB0, PB1, PB2, PA15, PA10 } - * #define MATRIX_COL_PINS { PA2, PA3, PA6, PB14, PB15, PA8, PA9, PA7, PB3, PB4, PC14, PC15, PC13, PB5, PB6 } - * #define UNUSED_PINS - */ +#undef MATRIX_ROW_PINS +#undef MATRIX_COL_PINS +#define MATRIX_ROW_PINS { A10, A9, A8, B15, C13, C14, C15, A2, A3, A6 } +#define MATRIX_COL_PINS { B11, B10, B2, B1, A7, B0 } +#define UNUSED_PINS #define ENCODERS_PAD_A { B12 } #define ENCODERS_PAD_B { B13 } +#define DIP_SWITCH_PINS { B14, A15, A0, B9 } + #define MUSIC_MAP #undef AUDIO_VOICES #undef C6_AUDIO diff --git a/keyboards/preonic/rev3/matrix.c b/keyboards/preonic/rev3/matrix.c deleted file mode 100644 index db7a4f2a3..000000000 --- a/keyboards/preonic/rev3/matrix.c +++ /dev/null @@ -1,187 +0,0 @@ -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include "hal.h" -#include "timer.h" -#include "wait.h" -#include "printf.h" -#include "backlight.h" -#include "matrix.h" -#include "action.h" -#include "keycode.h" -#include <string.h> - -/* - * col: { B11, B10, B2, B1, A7, B0 } - * row: { A10, A9, A8, B15, C13, C14, C15, A2 } - */ -/* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_col_t matrix_debouncing[MATRIX_COLS]; -static bool debouncing = false; -static uint16_t debouncing_time = 0; - -static bool dip_switch[4] = {0, 0, 0, 0}; - -__attribute__ ((weak)) -void matrix_init_user(void) {} - -__attribute__ ((weak)) -void matrix_scan_user(void) {} - -__attribute__ ((weak)) -void matrix_init_kb(void) { - matrix_init_user(); -} - -__attribute__ ((weak)) -void matrix_scan_kb(void) { - matrix_scan_user(); -} - -void matrix_init(void) { - printf("matrix init\n"); - //debug_matrix = true; - - // dip switch setup - palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP); - palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP); - palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP); - palSetPadMode(GPIOB, 9, PAL_MODE_INPUT_PULLUP); - - // actual matrix setup - palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL); - palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL); - - palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOC, 13, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 3, PAL_MODE_INPUT_PULLDOWN); - palSetPadMode(GPIOA, 6, PAL_MODE_INPUT_PULLDOWN); - - - memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t)); - memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_col_t)); - - - matrix_init_quantum(); -} - -__attribute__ ((weak)) -void dip_update(uint8_t index, bool active) { } - -__attribute__ ((weak)) -void encoder_update(bool clockwise) { } - -bool last_dip_switch[4] = {0}; - -#ifndef ENCODER_RESOLUTION - #define ENCODER_RESOLUTION 4 -#endif - -uint8_t matrix_scan(void) { - // dip switch - dip_switch[0] = !palReadPad(GPIOB, 14); - dip_switch[1] = !palReadPad(GPIOA, 15); - dip_switch[2] = !palReadPad(GPIOA, 10); - dip_switch[3] = !palReadPad(GPIOB, 9); - for (uint8_t i = 0; i < 4; i++) { - if (last_dip_switch[i] ^ dip_switch[i]) - dip_update(i, dip_switch[i]); - } - memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch)); - - // actual matrix - for (int col = 0; col < MATRIX_COLS; col++) { - matrix_col_t data = 0; - - // strobe col { B11, B10, B2, B1, A7, B0 } - switch (col) { - case 0: palSetPad(GPIOB, 11); break; - case 1: palSetPad(GPIOB, 10); break; - case 2: palSetPad(GPIOB, 2); break; - case 3: palSetPad(GPIOB, 1); break; - case 4: palSetPad(GPIOA, 7); break; - case 5: palSetPad(GPIOB, 0); break; - } - - // need wait to settle pin state - wait_us(20); - - // read row data { A10, A9, A8, B15, C13, C14, C15, A2 } - data = ( - (palReadPad(GPIOA, 10) << 0 ) | - (palReadPad(GPIOA, 9) << 1 ) | - (palReadPad(GPIOA, 8) << 2 ) | - (palReadPad(GPIOB, 15) << 3 ) | - (palReadPad(GPIOC, 13) << 4 ) | - (palReadPad(GPIOC, 14) << 5 ) | - (palReadPad(GPIOC, 15) << 6 ) | - (palReadPad(GPIOA, 2) << 7 ) | - (palReadPad(GPIOA, 3) << 8 ) | - (palReadPad(GPIOA, 6) << 9 ) - ); - - // unstrobe col { B11, B10, B2, B1, A7, B0 } - switch (col) { - case 0: palClearPad(GPIOB, 11); break; - case 1: palClearPad(GPIOB, 10); break; - case 2: palClearPad(GPIOB, 2); break; - case 3: palClearPad(GPIOB, 1); break; - case 4: palClearPad(GPIOA, 7); break; - case 5: palClearPad(GPIOB, 0); break; - } - - if (matrix_debouncing[col] != data) { - matrix_debouncing[col] = data; - debouncing = true; - debouncing_time = timer_read(); - } - } - - if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { - for (int row = 0; row < MATRIX_ROWS; row++) { - matrix[row] = 0; - for (int col = 0; col < MATRIX_COLS; col++) { - matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col); - } - } - debouncing = false; - } - - matrix_scan_quantum(); - - return 1; -} - -bool matrix_is_on(uint8_t row, uint8_t col) { - return (matrix[row] & (1<<col)); -} - -matrix_row_t matrix_get_row(uint8_t row) { - return matrix[row]; -} - -void matrix_print(void) { - printf("\nr/c 01234567\n"); - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - printf("%X0: ", row); - matrix_row_t data = matrix_get_row(row); - for (int col = 0; col < MATRIX_COLS; col++) { - if (data & (1<<col)) - printf("1"); - else - printf("0"); - } - printf("\n"); - } -} diff --git a/keyboards/preonic/rev3/rev3.c b/keyboards/preonic/rev3/rev3.c index b61beec5d..dc4ff66fc 100644 --- a/keyboards/preonic/rev3/rev3.c +++ b/keyboards/preonic/rev3/rev3.c @@ -22,3 +22,13 @@ void matrix_init_kb(void) { void matrix_scan_kb(void) { matrix_scan_user(); } + +#ifdef DIP_SWITCH_ENABLE + __attribute__((weak)) +void dip_update(uint8_t index, bool active) {} + + __attribute__((weak)) +void dip_switch_update_user(uint8_t index, bool active) { + dip_update(index, active); +} +#endif diff --git a/keyboards/preonic/rev3/rules.mk b/keyboards/preonic/rev3/rules.mk index 39e69872c..4aaa775e7 100644 --- a/keyboards/preonic/rev3/rules.mk +++ b/keyboards/preonic/rev3/rules.mk @@ -1,11 +1,8 @@ -# project specific files -SRC = matrix.c - # Cortex version MCU = STM32F303 # Build Options -# change to "no" to disable the options, or define them in the Makefile in +# change to "no" to disable the options, or define them in the Makefile in # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) @@ -27,8 +24,8 @@ API_SYSEX_ENABLE = no SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend #SLEEP_LED_ENABLE = yes -CUSTOM_MATRIX = yes # Custom matrix file # SERIAL_LINK_ENABLE = yes ENCODER_ENABLE = yes +DIP_SWITCH_ENABLE = yes LAYOUTS = ortho_5x12 diff --git a/quantum/dip_switch.c b/quantum/dip_switch.c new file mode 100644 index 000000000..3b5a8dadc --- /dev/null +++ b/quantum/dip_switch.c @@ -0,0 +1,71 @@ +/* + * Copyright 2018 Jack Humbert <jack.humb@gmail.com> + * Copyright 2019 Drashna Jaelre (Christopher Courtney) <drashna@live.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "dip_switch.h" + +// for memcpy +#include <string.h> + + +#if !defined(DIP_SWITCH_PINS) +# error "No DIP switch pads defined by DIP_SWITCH_PINS" +#endif + +#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad)/sizeof(pin_t)) +static pin_t dip_switch_pad[] = DIP_SWITCH_PINS; +static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; +static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; + + +__attribute__((weak)) +void dip_switch_update_user(uint8_t index, bool active) {} + +__attribute__((weak)) +void dip_switch_update_kb(uint8_t index, bool active) { dip_switch_update_user(index, active); } + +__attribute__((weak)) +void dip_switch_update_mask_user(uint32_t state) {} + +__attribute__((weak)) +void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); } + +void dip_switch_init(void) { + for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { + setPinInputHigh(dip_switch_pad[i]); + } + dip_switch_read(true); +} + + +void dip_switch_read(bool forced) { + bool has_dip_state_changed = false; + uint32_t dip_switch_mask = 0; + + for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { + dip_switch_state[i] = !readPin(dip_switch_pad[i]); + dip_switch_mask |= dip_switch_state[i] << i; + if (last_dip_switch_state[i] ^ dip_switch_state[i] || forced) { + has_dip_state_changed = true; + dip_switch_update_kb(i, dip_switch_state[i]); + } + } + if (has_dip_state_changed) { + dip_switch_update_mask_kb(dip_switch_mask); + } + memcpy(last_dip_switch_state, dip_switch_state, sizeof(&dip_switch_state)); +} diff --git a/quantum/dip_switch.h b/quantum/dip_switch.h new file mode 100644 index 000000000..61ef1cc19 --- /dev/null +++ b/quantum/dip_switch.h @@ -0,0 +1,29 @@ +/* + * Copyright 2018 Jack Humbert <jack.humb@gmail.com> + * Copyright 2018 Drashna Jaelre (Christopher Courtney) <drashna@live.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "quantum.h" + +void dip_switch_update_kb(uint8_t index, bool active); +void dip_switch_update_user(uint8_t index, bool active); +void dip_switch_update_mask_user(uint32_t state); +void dip_switch_update_mask_kb(uint32_t state); + +void dip_switch_init(void); +void dip_switch_read(bool forced); diff --git a/quantum/quantum.c b/quantum/quantum.c index 61e9003b7..85a03377f 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -967,6 +967,10 @@ void matrix_init_quantum() { #ifdef OUTPUT_AUTO_ENABLE set_output(OUTPUT_AUTO); #endif +#ifdef DIP_SWITCH_ENABLE + dip_switch_init(); +#endif + matrix_init_kb(); } @@ -1003,6 +1007,10 @@ void matrix_scan_quantum() { haptic_task(); #endif +#ifdef DIP_SWITCH_ENABLE + dip_switch_read(false); +#endif + matrix_scan_kb(); } #if defined(BACKLIGHT_ENABLE) && (defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)) diff --git a/quantum/quantum.h b/quantum/quantum.h index 066113590..f5ac97379 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -145,6 +145,11 @@ extern layer_state_t layer_state; # include "oled_driver.h" #endif +#ifdef DIP_SWITCH_ENABLE + #include "dip_switch.h" +#endif + + // Function substitutions to ease GPIO manipulation #if defined(__AVR__) typedef uint8_t pin_t; diff --git a/show_options.mk b/show_options.mk index 02e062a8d..63ab3b0d7 100644 --- a/show_options.mk +++ b/show_options.mk @@ -31,7 +31,8 @@ HARDWARE_OPTION_NAMES = \ LED_BREATHING_TABLE \ LED_TABLES \ POINTING_DEVICE_ENABLE \ - VISUALIZER_ENABLE + VISUALIZER_ENABLE \ + DIP_SWITCH_ENABLE OTHER_OPTION_NAMES = \ UNICODE_ENABLE \ |