aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common_features.mk6
-rw-r--r--docs/_summary.md1
-rw-r--r--docs/feature_dip_switch.md90
-rw-r--r--docs/features.md1
-rw-r--r--docs/zh-cn/_summary.md1
-rw-r--r--keyboards/planck/keymaps/default/keymap.c2
-rw-r--r--keyboards/planck/rev6/config.h15
-rw-r--r--keyboards/planck/rev6/matrix.c176
-rw-r--r--keyboards/planck/rev6/rev6.c10
-rw-r--r--keyboards/planck/rev6/rules.mk3
-rw-r--r--keyboards/preonic/keymaps/default/keymap.c2
-rw-r--r--keyboards/preonic/rev3/config.h22
-rw-r--r--keyboards/preonic/rev3/matrix.c187
-rw-r--r--keyboards/preonic/rev3/rev3.c10
-rw-r--r--keyboards/preonic/rev3/rules.mk7
-rw-r--r--quantum/dip_switch.c71
-rw-r--r--quantum/dip_switch.h29
-rw-r--r--quantum/quantum.c8
-rw-r--r--quantum/quantum.h5
-rw-r--r--show_options.mk3
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)
358 SRC += $(QUANTUM_DIR)/process_keycode/process_space_cadet.c 358 SRC += $(QUANTUM_DIR)/process_keycode/process_space_cadet.c
359 OPT_DEFS += -DSPACE_CADET_ENABLE 359 OPT_DEFS += -DSPACE_CADET_ENABLE
360endif 360endif
361
362
363ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes)
364 SRC += $(QUANTUM_DIR)/dip_switch.c
365 OPT_DEFS += -DDIP_SWITCH_ENABLE
366endif
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 @@
63 * [Combos](feature_combo.md) 63 * [Combos](feature_combo.md)
64 * [Command](feature_command.md) 64 * [Command](feature_command.md)
65 * [Debounce API](feature_debounce_type.md) 65 * [Debounce API](feature_debounce_type.md)
66 * [DIP Switch](feature_dip_switch.md)
66 * [Dynamic Macros](feature_dynamic_macros.md) 67 * [Dynamic Macros](feature_dynamic_macros.md)
67 * [Encoders](feature_encoders.md) 68 * [Encoders](feature_encoders.md)
68 * [Grave Escape](feature_grave_esc.md) 69 * [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 @@
1# DIP Switches
2
3DIP switches are supported by adding this to your `rules.mk`:
4
5 DIP_SWITCH_ENABLE = yes
6
7and this to your `config.h`:
8
9```c
10#define DIP_SWITCH_PINS { B14, A15, A10, B9 }
11```
12
13## Callbacks
14
15The callback functions can be inserted into your `<keyboard>.c`:
16
17```c
18void dip_switch_update_kb(uint8_t index, bool active) {
19 dip_switch_update_user(index, active);
20}
21```
22
23
24or `keymap.c`:
25
26```c
27void dip_switch_update_user(uint8_t index, bool active) {
28 switch (index) {
29 case 0:
30 if(active) { audio_on(); } else { audio_off(); }
31 break;
32 case 1:
33 if(active) { clicky_on(); } else { clicky_off(); }
34 break;
35 case 2:
36 if(active) { music_on(); } else { music_off(); }
37 break;
38 case 3:
39 if (active) {
40 #ifdef AUDIO_ENABLE
41 PLAY_SONG(plover_song);
42 #endif
43 layer_on(_PLOVER);
44 } else {
45 #ifdef AUDIO_ENABLE
46 PLAY_SONG(plover_gb_song);
47 #endif
48 layer_off(_PLOVER);
49 }
50 break;
51 }
52}
53```
54
55Additionally, we support bit mask functions which allow for more complex handling.
56
57
58```c
59void dip_switch_update_mask_kb(uint32_t state) {
60 dip_switch_update_mask_user(state);
61}
62```
63
64
65or `keymap.c`:
66
67```c
68void dip_switch_update_mask_user(uint32_t state) {
69 if (state & (1UL<<0) && state & (1UL<<1)) {
70 layer_on(_ADJUST); // C on esc
71 } else {
72 layer_off(_ADJUST);
73 }
74 if (state & (1UL<<0)) {
75 layer_on(_TEST_A); // A on ESC
76 } else {
77 layer_off(_TEST_A);
78 }
79 if (state & (1UL<<1)) {
80 layer_on(_TEST_B); // B on esc
81 } else {
82 layer_off(_TEST_B);
83 }
84}
85```
86
87
88## Hardware
89
90One 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
12* [Combos](feature_combo.md) - Custom actions for multiple key holds. 12* [Combos](feature_combo.md) - Custom actions for multiple key holds.
13* [Command](feature_command.md) - Runtime version of bootmagic (Formerly known as "Magic"). 13* [Command](feature_command.md) - Runtime version of bootmagic (Formerly known as "Magic").
14* [Debounce API](feature_debounce_type.md) - Customization of debouncing algorithms, and the ability to add more/custom debouncing. 14* [Debounce API](feature_debounce_type.md) - Customization of debouncing algorithms, and the ability to add more/custom debouncing.
15* [DIP Switch](feature_dip_switch.md) - Toggle switches for customizing board function.
15* [Dynamic Macros](feature_dynamic_macros.md) - Record and playback macros from the keyboard itself. 16* [Dynamic Macros](feature_dynamic_macros.md) - Record and playback macros from the keyboard itself.
16* [Encoders](feature_encoders.md) - Rotary encoders! 17* [Encoders](feature_encoders.md) - Rotary encoders!
17* [Grave Escape](feature_grave_esc.md) - Lets you use a single key for Esc and Grave. 18* [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 @@
54 * [热改键](feature_bootmagic.md) 54 * [热改键](feature_bootmagic.md)
55 * [组合](feature_combo) 55 * [组合](feature_combo)
56 * [命令](feature_command.md) 56 * [命令](feature_command.md)
57 * [拨动开关](feature_dip_switch.md)
57 * [动态宏指令](feature_dynamic_macros.md) 58 * [动态宏指令](feature_dynamic_macros.md)
58 * [编码器](feature_encoders.md) 59 * [编码器](feature_encoders.md)
59 * [重音号Esc复合键](feature_grave_esc.md) 60 * [重音号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) {
289 } 289 }
290} 290}
291 291
292void dip_update(uint8_t index, bool active) { 292void dip_switch_update_user(uint8_t index, bool active) {
293 switch (index) { 293 switch (index) {
294 case 0: 294 case 0:
295 if (active) { 295 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 @@
37 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) 37 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
38 * 38 *
39*/ 39*/
40/* Note: These are not used for arm boards. They're here purely as documentation. 40/* Note: These are not used for arm boards. They're here purely as documentation. */
41 * #define MATRIX_ROW_PINS { PB0, PB1, PB2, PA15, PA10 } 41#undef MATRIX_ROW_PINS
42 * #define MATRIX_COL_PINS { PA2, PA3, PA6, PB14, PB15, PA8, PA9, PA7, PB3, PB4, PC14, PC15, PC13, PB5, PB6 } 42#undef MATRIX_COL_PINS
43 * #define UNUSED_PINS 43
44 */ 44#define MATRIX_ROW_PINS { A10, A9, A8, B15, C13, C14, C15, A2 }
45#define MATRIX_COL_PINS { B11, B10, B2, B1, A7, B0 }
46
47#define UNUSED_PINS
45 48
46#define ENCODERS_PAD_A { B12 } 49#define ENCODERS_PAD_A { B12 }
47#define ENCODERS_PAD_B { B13 } 50#define ENCODERS_PAD_B { B13 }
48 51
52#define DIP_SWITCH_PINS { B14, A15, A0, B9 }
53
49#define MUSIC_MAP 54#define MUSIC_MAP
50#undef AUDIO_VOICES 55#undef AUDIO_VOICES
51#undef C6_AUDIO 56#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 @@
1#include <stdint.h>
2#include <stdbool.h>
3#include <string.h>
4#include "hal.h"
5#include "timer.h"
6#include "wait.h"
7#include "printf.h"
8#include "backlight.h"
9#include "matrix.h"
10#include "action.h"
11#include "keycode.h"
12#include <string.h>
13
14/*
15 * col: { B11, B10, B2, B1, A7, B0 }
16 * row: { A10, A9, A8, B15, C13, C14, C15, A2 }
17 */
18/* matrix state(1:on, 0:off) */
19static matrix_row_t matrix[MATRIX_ROWS];
20static matrix_row_t matrix_debouncing[MATRIX_COLS];
21static bool debouncing = false;
22static uint16_t debouncing_time = 0;
23
24static bool dip_switch[4] = {0, 0, 0, 0};
25
26__attribute__ ((weak))
27void matrix_init_user(void) {}
28
29__attribute__ ((weak))
30void matrix_scan_user(void) {}
31
32__attribute__ ((weak))
33void matrix_init_kb(void) {
34 matrix_init_user();
35}
36
37__attribute__ ((weak))
38void matrix_scan_kb(void) {
39 matrix_scan_user();
40}
41
42void matrix_init(void) {
43 printf("matrix init\n");
44 //debug_matrix = true;
45
46 // dip switch setup
47 palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP);
48 palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP);
49 palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP);
50 palSetPadMode(GPIOB, 9, PAL_MODE_INPUT_PULLUP);
51
52 // actual matrix setup
53 palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL);
54 palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL);
55 palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL);
56 palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL);
57 palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL);
58 palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL);
59
60 palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN);
61 palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN);
62 palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN);
63 palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLDOWN);
64 palSetPadMode(GPIOC, 13, PAL_MODE_INPUT_PULLDOWN);
65 palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN);
66 palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN);
67 palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_PULLDOWN);
68
69
70 memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
71 memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_row_t));
72
73
74 matrix_init_quantum();
75}
76
77__attribute__ ((weak))
78void dip_update(uint8_t index, bool active) { }
79
80bool last_dip_switch[4] = {0};
81
82uint8_t matrix_scan(void) {
83 // dip switch
84 dip_switch[0] = !palReadPad(GPIOB, 14);
85 dip_switch[1] = !palReadPad(GPIOA, 15);
86 dip_switch[2] = !palReadPad(GPIOA, 10);
87 dip_switch[3] = !palReadPad(GPIOB, 9);
88 for (uint8_t i = 0; i < 4; i++) {
89 if (last_dip_switch[i] ^ dip_switch[i])
90 dip_update(i, dip_switch[i]);
91 }
92 memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch));
93
94 // actual matrix
95 for (int col = 0; col < MATRIX_COLS; col++) {
96 matrix_row_t data = 0;
97
98 // strobe col { B11, B10, B2, B1, A7, B0 }
99 switch (col) {
100 case 0: palSetPad(GPIOB, 11); break;
101 case 1: palSetPad(GPIOB, 10); break;
102 case 2: palSetPad(GPIOB, 2); break;
103 case 3: palSetPad(GPIOB, 1); break;
104 case 4: palSetPad(GPIOA, 7); break;
105 case 5: palSetPad(GPIOB, 0); break;
106 }
107
108 // need wait to settle pin state
109 wait_us(20);
110
111 // read row data { A10, A9, A8, B15, C13, C14, C15, A2 }
112 data = (
113 (palReadPad(GPIOA, 10) << 0 ) |
114 (palReadPad(GPIOA, 9) << 1 ) |
115 (palReadPad(GPIOA, 8) << 2 ) |
116 (palReadPad(GPIOB, 15) << 3 ) |
117 (palReadPad(GPIOC, 13) << 4 ) |
118 (palReadPad(GPIOC, 14) << 5 ) |
119 (palReadPad(GPIOC, 15) << 6 ) |
120 (palReadPad(GPIOA, 2) << 7 )
121 );
122
123 // unstrobe col { B11, B10, B2, B1, A7, B0 }
124 switch (col) {
125 case 0: palClearPad(GPIOB, 11); break;
126 case 1: palClearPad(GPIOB, 10); break;
127 case 2: palClearPad(GPIOB, 2); break;
128 case 3: palClearPad(GPIOB, 1); break;
129 case 4: palClearPad(GPIOA, 7); break;
130 case 5: palClearPad(GPIOB, 0); break;
131 }
132
133 if (matrix_debouncing[col] != data) {
134 matrix_debouncing[col] = data;
135 debouncing = true;
136 debouncing_time = timer_read();
137 }
138 }
139
140 if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
141 for (int row = 0; row < MATRIX_ROWS; row++) {
142 matrix[row] = 0;
143 for (int col = 0; col < MATRIX_COLS; col++) {
144 matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col);
145 }
146 }
147 debouncing = false;
148 }
149
150 matrix_scan_quantum();
151
152 return 1;
153}
154
155bool matrix_is_on(uint8_t row, uint8_t col) {
156 return (matrix[row] & (1<<col));
157}
158
159matrix_row_t matrix_get_row(uint8_t row) {
160 return matrix[row];
161}
162
163void matrix_print(void) {
164 printf("\nr/c 01234567\n");
165 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
166 printf("%X0: ", row);
167 matrix_row_t data = matrix_get_row(row);
168 for (int col = 0; col < MATRIX_COLS; col++) {
169 if (data & (1<<col))
170 printf("1");
171 else
172 printf("0");
173 }
174 printf("\n");
175 }
176}
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) {
22void matrix_scan_kb(void) { 22void matrix_scan_kb(void) {
23 matrix_scan_user(); 23 matrix_scan_user();
24} 24}
25
26#ifdef DIP_SWITCH_ENABLE
27__attribute__((weak))
28void dip_update(uint8_t index, bool active) {}
29
30__attribute__((weak))
31void dip_switch_update_user(uint8_t index, bool active) {
32 dip_update(index, active);
33}
34#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 @@
1# project specific files 1# project specific files
2SRC = matrix.c
3LAYOUTS += ortho_4x12 2LAYOUTS += ortho_4x12
4 3
5# Cortex version 4# Cortex version
@@ -31,9 +30,9 @@ API_SYSEX_ENABLE = no
31SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend 30SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
32#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend 31#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
33 32
34CUSTOM_MATRIX = yes # Custom matrix file
35# SERIAL_LINK_ENABLE = yes 33# SERIAL_LINK_ENABLE = yes
36ENCODER_ENABLE = yes 34ENCODER_ENABLE = yes
35DIP_SWITCH_ENABLE = yes
37 36
38LAYOUTS = ortho_4x12 planck_mit 37LAYOUTS = ortho_4x12 planck_mit
39LAYOUTS_HAS_RGB = no 38LAYOUTS_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) {
259 } 259 }
260} 260}
261 261
262void dip_update(uint8_t index, bool active) { 262void dip_switch_update_user(uint8_t index, bool active) {
263 switch (index) { 263 switch (index) {
264 case 0: 264 case 0:
265 if (active) { 265 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 @@
27#define MATRIX_ROWS 10 27#define MATRIX_ROWS 10
28#define MATRIX_COLS 6 28#define MATRIX_COLS 6
29 29
30/* 30#undef MATRIX_ROW_PINS
31 * Keyboard Matrix Assignments 31#undef MATRIX_COL_PINS
32 * 32#define MATRIX_ROW_PINS { A10, A9, A8, B15, C13, C14, C15, A2, A3, A6 }
33 * Change this to how you wired your keyboard 33#define MATRIX_COL_PINS { B11, B10, B2, B1, A7, B0 }
34 * COLS: AVR pins used for columns, left to right 34#define UNUSED_PINS
35 * ROWS: AVR pins used for rows, top to bottom
36 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
37 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
38 *
39*/
40/* Note: These are not used for arm boards. They're here purely as documentation.
41 * #define MATRIX_ROW_PINS { PB0, PB1, PB2, PA15, PA10 }
42 * #define MATRIX_COL_PINS { PA2, PA3, PA6, PB14, PB15, PA8, PA9, PA7, PB3, PB4, PC14, PC15, PC13, PB5, PB6 }
43 * #define UNUSED_PINS
44 */
45 35
46#define ENCODERS_PAD_A { B12 } 36#define ENCODERS_PAD_A { B12 }
47#define ENCODERS_PAD_B { B13 } 37#define ENCODERS_PAD_B { B13 }
48 38
39#define DIP_SWITCH_PINS { B14, A15, A0, B9 }
40
49#define MUSIC_MAP 41#define MUSIC_MAP
50#undef AUDIO_VOICES 42#undef AUDIO_VOICES
51#undef C6_AUDIO 43#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 @@
1#include <stdint.h>
2#include <stdbool.h>
3#include <string.h>
4#include "hal.h"
5#include "timer.h"
6#include "wait.h"
7#include "printf.h"
8#include "backlight.h"
9#include "matrix.h"
10#include "action.h"
11#include "keycode.h"
12#include <string.h>
13
14/*
15 * col: { B11, B10, B2, B1, A7, B0 }
16 * row: { A10, A9, A8, B15, C13, C14, C15, A2 }
17 */
18/* matrix state(1:on, 0:off) */
19static matrix_row_t matrix[MATRIX_ROWS];
20static matrix_col_t matrix_debouncing[MATRIX_COLS];
21static bool debouncing = false;
22static uint16_t debouncing_time = 0;
23
24static bool dip_switch[4] = {0, 0, 0, 0};
25
26__attribute__ ((weak))
27void matrix_init_user(void) {}
28
29__attribute__ ((weak))
30void matrix_scan_user(void) {}
31
32__attribute__ ((weak))
33void matrix_init_kb(void) {
34 matrix_init_user();
35}
36
37__attribute__ ((weak))
38void matrix_scan_kb(void) {
39 matrix_scan_user();
40}
41
42void matrix_init(void) {
43 printf("matrix init\n");
44 //debug_matrix = true;
45
46 // dip switch setup
47 palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP);
48 palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP);
49 palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP);
50 palSetPadMode(GPIOB, 9, PAL_MODE_INPUT_PULLUP);
51
52 // actual matrix setup
53 palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL);
54 palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL);
55 palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL);
56 palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL);
57 palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL);
58 palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL);
59
60 palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN);
61 palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN);
62 palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN);
63 palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLDOWN);
64 palSetPadMode(GPIOC, 13, PAL_MODE_INPUT_PULLDOWN);
65 palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN);
66 palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN);
67 palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_PULLDOWN);
68 palSetPadMode(GPIOA, 3, PAL_MODE_INPUT_PULLDOWN);
69 palSetPadMode(GPIOA, 6, PAL_MODE_INPUT_PULLDOWN);
70
71
72 memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
73 memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_col_t));
74
75
76 matrix_init_quantum();
77}
78
79__attribute__ ((weak))
80void dip_update(uint8_t index, bool active) { }
81
82__attribute__ ((weak))
83void encoder_update(bool clockwise) { }
84
85bool last_dip_switch[4] = {0};
86
87#ifndef ENCODER_RESOLUTION
88 #define ENCODER_RESOLUTION 4
89#endif
90
91uint8_t matrix_scan(void) {
92 // dip switch
93 dip_switch[0] = !palReadPad(GPIOB, 14);
94 dip_switch[1] = !palReadPad(GPIOA, 15);
95 dip_switch[2] = !palReadPad(GPIOA, 10);
96 dip_switch[3] = !palReadPad(GPIOB, 9);
97 for (uint8_t i = 0; i < 4; i++) {
98 if (last_dip_switch[i] ^ dip_switch[i])
99 dip_update(i, dip_switch[i]);
100 }
101 memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch));
102
103 // actual matrix
104 for (int col = 0; col < MATRIX_COLS; col++) {
105 matrix_col_t data = 0;
106
107 // strobe col { B11, B10, B2, B1, A7, B0 }
108 switch (col) {
109 case 0: palSetPad(GPIOB, 11); break;
110 case 1: palSetPad(GPIOB, 10); break;
111 case 2: palSetPad(GPIOB, 2); break;
112 case 3: palSetPad(GPIOB, 1); break;
113 case 4: palSetPad(GPIOA, 7); break;
114 case 5: palSetPad(GPIOB, 0); break;
115 }
116
117 // need wait to settle pin state
118 wait_us(20);
119
120 // read row data { A10, A9, A8, B15, C13, C14, C15, A2 }
121 data = (
122 (palReadPad(GPIOA, 10) << 0 ) |
123 (palReadPad(GPIOA, 9) << 1 ) |
124 (palReadPad(GPIOA, 8) << 2 ) |
125 (palReadPad(GPIOB, 15) << 3 ) |
126 (palReadPad(GPIOC, 13) << 4 ) |
127 (palReadPad(GPIOC, 14) << 5 ) |
128 (palReadPad(GPIOC, 15) << 6 ) |
129 (palReadPad(GPIOA, 2) << 7 ) |
130 (palReadPad(GPIOA, 3) << 8 ) |
131 (palReadPad(GPIOA, 6) << 9 )
132 );
133
134 // unstrobe col { B11, B10, B2, B1, A7, B0 }
135 switch (col) {
136 case 0: palClearPad(GPIOB, 11); break;
137 case 1: palClearPad(GPIOB, 10); break;
138 case 2: palClearPad(GPIOB, 2); break;
139 case 3: palClearPad(GPIOB, 1); break;
140 case 4: palClearPad(GPIOA, 7); break;
141 case 5: palClearPad(GPIOB, 0); break;
142 }
143
144 if (matrix_debouncing[col] != data) {
145 matrix_debouncing[col] = data;
146 debouncing = true;
147 debouncing_time = timer_read();
148 }
149 }
150
151 if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
152 for (int row = 0; row < MATRIX_ROWS; row++) {
153 matrix[row] = 0;
154 for (int col = 0; col < MATRIX_COLS; col++) {
155 matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col);
156 }
157 }
158 debouncing = false;
159 }
160
161 matrix_scan_quantum();
162
163 return 1;
164}
165
166bool matrix_is_on(uint8_t row, uint8_t col) {
167 return (matrix[row] & (1<<col));
168}
169
170matrix_row_t matrix_get_row(uint8_t row) {
171 return matrix[row];
172}
173
174void matrix_print(void) {
175 printf("\nr/c 01234567\n");
176 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
177 printf("%X0: ", row);
178 matrix_row_t data = matrix_get_row(row);
179 for (int col = 0; col < MATRIX_COLS; col++) {
180 if (data & (1<<col))
181 printf("1");
182 else
183 printf("0");
184 }
185 printf("\n");
186 }
187}
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) {
22void matrix_scan_kb(void) { 22void matrix_scan_kb(void) {
23 matrix_scan_user(); 23 matrix_scan_user();
24} 24}
25
26#ifdef DIP_SWITCH_ENABLE
27 __attribute__((weak))
28void dip_update(uint8_t index, bool active) {}
29
30 __attribute__((weak))
31void dip_switch_update_user(uint8_t index, bool active) {
32 dip_update(index, active);
33}
34#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 @@
1# project specific files
2SRC = matrix.c
3
4# Cortex version 1# Cortex version
5MCU = STM32F303 2MCU = STM32F303
6 3
7# Build Options 4# Build Options
8# change to "no" to disable the options, or define them in the Makefile in 5# change to "no" to disable the options, or define them in the Makefile in
9# the appropriate keymap folder that will get included automatically 6# the appropriate keymap folder that will get included automatically
10# 7#
11BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) 8BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
@@ -27,8 +24,8 @@ API_SYSEX_ENABLE = no
27SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend 24SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
28#SLEEP_LED_ENABLE = yes 25#SLEEP_LED_ENABLE = yes
29 26
30CUSTOM_MATRIX = yes # Custom matrix file
31# SERIAL_LINK_ENABLE = yes 27# SERIAL_LINK_ENABLE = yes
32ENCODER_ENABLE = yes 28ENCODER_ENABLE = yes
29DIP_SWITCH_ENABLE = yes
33 30
34LAYOUTS = ortho_5x12 31LAYOUTS = 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 @@
1/*
2 * Copyright 2018 Jack Humbert <jack.humb@gmail.com>
3 * Copyright 2019 Drashna Jaelre (Christopher Courtney) <drashna@live.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "dip_switch.h"
20
21// for memcpy
22#include <string.h>
23
24
25#if !defined(DIP_SWITCH_PINS)
26# error "No DIP switch pads defined by DIP_SWITCH_PINS"
27#endif
28
29#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad)/sizeof(pin_t))
30static pin_t dip_switch_pad[] = DIP_SWITCH_PINS;
31static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 };
32static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 };
33
34
35__attribute__((weak))
36void dip_switch_update_user(uint8_t index, bool active) {}
37
38__attribute__((weak))
39void dip_switch_update_kb(uint8_t index, bool active) { dip_switch_update_user(index, active); }
40
41__attribute__((weak))
42void dip_switch_update_mask_user(uint32_t state) {}
43
44__attribute__((weak))
45void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); }
46
47void dip_switch_init(void) {
48 for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
49 setPinInputHigh(dip_switch_pad[i]);
50 }
51 dip_switch_read(true);
52}
53
54
55void dip_switch_read(bool forced) {
56 bool has_dip_state_changed = false;
57 uint32_t dip_switch_mask = 0;
58
59 for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
60 dip_switch_state[i] = !readPin(dip_switch_pad[i]);
61 dip_switch_mask |= dip_switch_state[i] << i;
62 if (last_dip_switch_state[i] ^ dip_switch_state[i] || forced) {
63 has_dip_state_changed = true;
64 dip_switch_update_kb(i, dip_switch_state[i]);
65 }
66 }
67 if (has_dip_state_changed) {
68 dip_switch_update_mask_kb(dip_switch_mask);
69 }
70 memcpy(last_dip_switch_state, dip_switch_state, sizeof(&dip_switch_state));
71}
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 @@
1/*
2 * Copyright 2018 Jack Humbert <jack.humb@gmail.com>
3 * Copyright 2018 Drashna Jaelre (Christopher Courtney) <drashna@live.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include "quantum.h"
22
23void dip_switch_update_kb(uint8_t index, bool active);
24void dip_switch_update_user(uint8_t index, bool active);
25void dip_switch_update_mask_user(uint32_t state);
26void dip_switch_update_mask_kb(uint32_t state);
27
28void dip_switch_init(void);
29void 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() {
967#ifdef OUTPUT_AUTO_ENABLE 967#ifdef OUTPUT_AUTO_ENABLE
968 set_output(OUTPUT_AUTO); 968 set_output(OUTPUT_AUTO);
969#endif 969#endif
970#ifdef DIP_SWITCH_ENABLE
971 dip_switch_init();
972#endif
973
970 matrix_init_kb(); 974 matrix_init_kb();
971} 975}
972 976
@@ -1003,6 +1007,10 @@ void matrix_scan_quantum() {
1003 haptic_task(); 1007 haptic_task();
1004#endif 1008#endif
1005 1009
1010#ifdef DIP_SWITCH_ENABLE
1011 dip_switch_read(false);
1012#endif
1013
1006 matrix_scan_kb(); 1014 matrix_scan_kb();
1007} 1015}
1008#if defined(BACKLIGHT_ENABLE) && (defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)) 1016#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;
145# include "oled_driver.h" 145# include "oled_driver.h"
146#endif 146#endif
147 147
148#ifdef DIP_SWITCH_ENABLE
149 #include "dip_switch.h"
150#endif
151
152
148// Function substitutions to ease GPIO manipulation 153// Function substitutions to ease GPIO manipulation
149#if defined(__AVR__) 154#if defined(__AVR__)
150typedef uint8_t pin_t; 155typedef 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 = \
31 LED_BREATHING_TABLE \ 31 LED_BREATHING_TABLE \
32 LED_TABLES \ 32 LED_TABLES \
33 POINTING_DEVICE_ENABLE \ 33 POINTING_DEVICE_ENABLE \
34 VISUALIZER_ENABLE 34 VISUALIZER_ENABLE \
35 DIP_SWITCH_ENABLE
35 36
36OTHER_OPTION_NAMES = \ 37OTHER_OPTION_NAMES = \
37 UNICODE_ENABLE \ 38 UNICODE_ENABLE \