aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/_summary.md1
-rw-r--r--docs/breaking_changes.md4
-rw-r--r--docs/chibios_upgrade_instructions.md56
-rw-r--r--docs/cli_commands.md2
-rw-r--r--docs/compatible_microcontrollers.md2
-rw-r--r--docs/config_options.md29
-rw-r--r--docs/custom_quantum_functions.md8
-rw-r--r--docs/eeprom_driver.md3
-rw-r--r--docs/feature_debounce_type.md4
-rw-r--r--docs/feature_dip_switch.md16
-rw-r--r--docs/feature_haptic_feedback.md26
-rw-r--r--docs/feature_oled_driver.md4
-rw-r--r--docs/feature_rgb_matrix.md114
-rw-r--r--docs/feature_rgblight.md47
-rw-r--r--docs/feature_split_keyboard.md114
-rw-r--r--docs/feature_st7565.md274
-rw-r--r--docs/ja/compatible_microcontrollers.md2
-rw-r--r--docs/ja/feature_dip_switch.md16
-rw-r--r--docs/serial_driver.md15
19 files changed, 657 insertions, 80 deletions
diff --git a/docs/_summary.md b/docs/_summary.md
index 9798ef512..4141e01e7 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -93,6 +93,7 @@
93 * Hardware Features 93 * Hardware Features
94 * Displays 94 * Displays
95 * [HD44780 LCD Controller](feature_hd44780.md) 95 * [HD44780 LCD Controller](feature_hd44780.md)
96 * [ST7565 LCD Driver](feature_st7565.md)
96 * [OLED Driver](feature_oled_driver.md) 97 * [OLED Driver](feature_oled_driver.md)
97 * Lighting 98 * Lighting
98 * [Backlight](feature_backlight.md) 99 * [Backlight](feature_backlight.md)
diff --git a/docs/breaking_changes.md b/docs/breaking_changes.md
index b0d56a81b..a1a56bd45 100644
--- a/docs/breaking_changes.md
+++ b/docs/breaking_changes.md
@@ -100,3 +100,7 @@ This happens immediately after the previous `develop` branch is merged.
100 * [ ] `git pull --ff-only` 100 * [ ] `git pull --ff-only`
101 * [ ] `git merge --no-ff develop` 101 * [ ] `git merge --no-ff develop`
102 * [ ] `git push upstream master` 102 * [ ] `git push upstream master`
103
104## Post-merge operations
105
106* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)
diff --git a/docs/chibios_upgrade_instructions.md b/docs/chibios_upgrade_instructions.md
new file mode 100644
index 000000000..40c2faafc
--- /dev/null
+++ b/docs/chibios_upgrade_instructions.md
@@ -0,0 +1,56 @@
1# ChibiOS Upgrade Procedure
2
3ChibiOS and ChibiOS-Contrib need to be updated in tandem -- the latter has a branch tied to the ChibiOS version in use and should not be mixed with different versions.
4
5## Getting ChibiOS
6
7* `svn` Initialisation:
8 * Only needed to be done once
9 * You might need to separately install `git-svn` package in your OS's package manager
10 * `git svn init --stdlayout --prefix='svn/' http://svn.osdn.net/svnroot/chibios/`
11 * `git remote add qmk git@github.com:qmk/ChibiOS.git`
12* Updating:
13 * `git svn fetch`
14 * First time around this will take several hours
15 * Subsequent updates will be incremental only
16* Tagging example (work out which version first!):
17 * `git tag -a ver20.3.3 -m ver20.3.3 svn/tags/ver20.3.3`
18 * `git push qmk ver20.3.3`
19 * `git tag -a breaking_YYYY_qN -m breaking_YYYY_qN svn/tags/ver20.3.3`
20 * `git push qmk breaking_YYYY_qN`
21
22## Getting ChibiOS-Contrib
23
24* `git` Initialisation:
25 * `git clone git@github.com:qmk/ChibiOS-Contrib`
26 * `git remote add upstream https://github.com/ChibiOS/ChibiOS-Contrib`
27 * `git checkout -b chibios-20.3.x upstream/chibios-20.3.x`
28* Updating:
29 * `git fetch --all --tags --prune`
30 * `git checkout chibios-20.3.x`
31 * `git pull --ff-only`
32 * `git push origin chibios-20.3.x`
33 * `git tag -a breaking_YYYY_qN -m breaking_YYYY_qN chibios-20.3.x`
34 * `git push origin breaking_YYYY_qN`
35
36## Updating submodules
37
38* Update the submodules
39 * `cd $QMK_FIRMWARE`
40 * `git checkout develop`
41 * `git pull --ff-only`
42 * `git checkout -b chibios-version-bump`
43 * `cd lib/chibios`
44 * `git fetch --all --tags --prune`
45 * `git checkout breaking_YYYY_qN`
46 * `cd ../chibios-contrib`
47 * `git fetch --all --tags --prune`
48 * `git checkout breaking_YYYY_qN`
49* Build everything
50 * `cd $QMK_FIRMWARE`
51 * `qmk multibuild -j4`
52 * Make sure there are no errors
53* Push to the repo
54 * `git commit -am 'Update ChibiOS to XXXXXXXXX'`
55 * `git push --set-upstream origin chibios-version-bump`
56* Make a PR to qmk_firmware with the new branch \ No newline at end of file
diff --git a/docs/cli_commands.md b/docs/cli_commands.md
index 581342093..e30593daa 100644
--- a/docs/cli_commands.md
+++ b/docs/cli_commands.md
@@ -368,7 +368,7 @@ qmk generate-docs
368 368
369## `qmk generate-rgb-breathe-table` 369## `qmk generate-rgb-breathe-table`
370 370
371This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight.md) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/`. 371This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight.md) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/rgblight/`.
372 372
373**Usage**: 373**Usage**:
374 374
diff --git a/docs/compatible_microcontrollers.md b/docs/compatible_microcontrollers.md
index 0f5b140de..865b29fee 100644
--- a/docs/compatible_microcontrollers.md
+++ b/docs/compatible_microcontrollers.md
@@ -31,6 +31,8 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
31 * [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html) 31 * [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html)
32 * [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html) 32 * [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html)
33 * [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html) 33 * [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html)
34 * [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
35 * [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
34 * [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) 36 * [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
35 * [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) 37 * [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
36 38
diff --git a/docs/config_options.md b/docs/config_options.md
index d0f0b316e..980195ac6 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -51,8 +51,10 @@ This is a C header file that is one of the first things included, and will persi
51 * the number of columns in your keyboard's matrix 51 * the number of columns in your keyboard's matrix
52* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }` 52* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }`
53 * pins of the rows, from top to bottom 53 * pins of the rows, from top to bottom
54 * may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
54* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }` 55* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }`
55 * pins of the columns, from left to right 56 * pins of the columns, from left to right
57 * may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
56* `#define MATRIX_IO_DELAY 30` 58* `#define MATRIX_IO_DELAY 30`
57 * the delay in microseconds when between changing matrix pin state and reading values 59 * the delay in microseconds when between changing matrix pin state and reading values
58* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }` 60* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }`
@@ -272,7 +274,7 @@ There are a few different ways to set handedness for split keyboards (listed in
272### Other Options 274### Other Options
273 275
274* `#define USE_I2C` 276* `#define USE_I2C`
275 * For using I2C instead of Serial (defaults to serial) 277 * For using I2C instead of Serial (default is serial; serial transport is supported on ARM -- I2C is AVR-only)
276 278
277* `#define SOFT_SERIAL_PIN D0` 279* `#define SOFT_SERIAL_PIN D0`
278 * When using serial, define this. `D0` or `D1`,`D2`,`D3`,`E6`. 280 * When using serial, define this. `D0` or `D1`,`D2`,`D3`,`E6`.
@@ -280,6 +282,7 @@ There are a few different ways to set handedness for split keyboards (listed in
280* `#define MATRIX_ROW_PINS_RIGHT { <row pins> }` 282* `#define MATRIX_ROW_PINS_RIGHT { <row pins> }`
281* `#define MATRIX_COL_PINS_RIGHT { <col pins> }` 283* `#define MATRIX_COL_PINS_RIGHT { <col pins> }`
282 * If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns. 284 * If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns.
285 * may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
283 286
284* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` 287* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
285 * If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`. 288 * If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`.
@@ -300,7 +303,7 @@ There are a few different ways to set handedness for split keyboards (listed in
300* `#define SPLIT_USB_DETECT` 303* `#define SPLIT_USB_DETECT`
301 * Detect (with timeout) USB connection when delegating master/slave 304 * Detect (with timeout) USB connection when delegating master/slave
302 * Default behavior for ARM 305 * Default behavior for ARM
303 * Required for AVR Teensy 306 * Required for AVR Teensy (without hardware mods)
304 307
305* `#define SPLIT_USB_TIMEOUT 2000` 308* `#define SPLIT_USB_TIMEOUT 2000`
306 * Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT` 309 * Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`
@@ -308,6 +311,28 @@ There are a few different ways to set handedness for split keyboards (listed in
308* `#define SPLIT_USB_TIMEOUT_POLL 10` 311* `#define SPLIT_USB_TIMEOUT_POLL 10`
309 * Poll frequency when detecting master/slave when using `SPLIT_USB_DETECT` 312 * Poll frequency when detecting master/slave when using `SPLIT_USB_DETECT`
310 313
314* `#define FORCED_SYNC_THROTTLE_MS 100`
315 * Deadline for synchronizing data from master to slave when using the QMK-provided split transport.
316
317* `#define SPLIT_TRANSPORT_MIRROR`
318 * Mirrors the master-side matrix on the slave when using the QMK-provided split transport.
319
320* `#define SPLIT_LAYER_STATE_ENABLE`
321 * Ensures the current layer state is available on the slave when using the QMK-provided split transport.
322
323* `#define SPLIT_LED_STATE_ENABLE`
324 * Ensures the current host indicator state (caps/num/scroll) is available on the slave when using the QMK-provided split transport.
325
326* `#define SPLIT_MODS_ENABLE`
327 * Ensures the current modifier state (normal, weak, and oneshot) is available on the slave when using the QMK-provided split transport.
328
329* `#define SPLIT_WPM_ENABLE`
330 * Ensures the current WPM is available on the slave when using the QMK-provided split transport.
331
332* `#define SPLIT_TRANSACTION_IDS_KB .....`
333* `#define SPLIT_TRANSACTION_IDS_USER .....`
334 * Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard.md#custom-data-sync) for more information.
335
311# The `rules.mk` File 336# The `rules.mk` File
312 337
313This is a [make](https://www.gnu.org/software/make/manual/make.html) file that is included by the top-level `Makefile`. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features. 338This is a [make](https://www.gnu.org/software/make/manual/make.html) file that is included by the top-level `Makefile`. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features.
diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md
index 694b421e7..30c637bb4 100644
--- a/docs/custom_quantum_functions.md
+++ b/docs/custom_quantum_functions.md
@@ -144,6 +144,14 @@ This is useful for setting up stuff that you may need elsewhere, but isn't hardw
144* Keyboard/Revision: `void matrix_init_kb(void)` 144* Keyboard/Revision: `void matrix_init_kb(void)`
145* Keymap: `void matrix_init_user(void)` 145* Keymap: `void matrix_init_user(void)`
146 146
147### Low-level Matrix Overrides Function Documentation :id=low-level-matrix-overrides
148
149* GPIO pin initialisation: `void matrix_init_pins(void)`
150 * This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override.
151* `COL2ROW`-based row reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)`
152* `ROW2COL`-based column reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
153* `DIRECT_PINS`-based reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
154 * These three functions need to perform the low-level retrieval of matrix state of relevant input pins, based on the matrix type. Only one of the functions should be implemented, if needed. By default this will iterate through `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, configuring the inputs and outputs based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no manipulation of matrix GPIO pin state will occur within QMK itself, instead deferring to the keyboard's override.
147 155
148## Keyboard Post Initialization code 156## Keyboard Post Initialization code
149 157
diff --git a/docs/eeprom_driver.md b/docs/eeprom_driver.md
index e2c262546..6dcf10c04 100644
--- a/docs/eeprom_driver.md
+++ b/docs/eeprom_driver.md
@@ -31,6 +31,9 @@ Currently QMK supports 24xx-series chips over I2C. As such, requires a working i
31`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32 31`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
32`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2 32`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
33`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5 33`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5
34`#define EXTERNAL_EEPROM_WP_PIN` | If defined the WP pin will be toggled appropriately when writing to the EEPROM. | _none_
35
36Some I2C EEPROM manufacturers explicitly recommend against hardcoding the WP pin to ground. This is in order to protect the eeprom memory content during power-up/power-down/brown-out conditions at low voltage where the eeprom is still operational, but the i2c master output might be unpredictable. If a WP pin is configured, then having an external pull-up on the WP pin is recommended.
34 37
35Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`. 38Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
36 39
diff --git a/docs/feature_debounce_type.md b/docs/feature_debounce_type.md
index 3ad74224c..306185fe8 100644
--- a/docs/feature_debounce_type.md
+++ b/docs/feature_debounce_type.md
@@ -121,16 +121,16 @@ DEBOUNCE_TYPE = <name of algorithm>
121Where name of algorithm is one of: 121Where name of algorithm is one of:
122* ```sym_defer_g``` - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occurred, all input changes are pushed. 122* ```sym_defer_g``` - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occurred, all input changes are pushed.
123 * This is the current default algorithm. This is the highest performance algorithm with lowest memory usage, and it's also noise-resistant. 123 * This is the current default algorithm. This is the highest performance algorithm with lowest memory usage, and it's also noise-resistant.
124* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row. 124* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row.
125For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be 125For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be
126appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use. 126appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
127* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key 127* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
128* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed. 128* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed.
129* ```asym_eager_defer_pk``` - debouncing per key. On a key-down state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key-up status change is pushed.
129 130
130### A couple algorithms that could be implemented in the future: 131### A couple algorithms that could be implemented in the future:
131* ```sym_defer_pr``` 132* ```sym_defer_pr```
132* ```sym_eager_g``` 133* ```sym_eager_g```
133* ```asym_eager_defer_pk```
134 134
135### Use your own debouncing code 135### Use your own debouncing code
136You have the option to implement you own debouncing algorithm. To do this: 136You have the option to implement you own debouncing algorithm. To do this:
diff --git a/docs/feature_dip_switch.md b/docs/feature_dip_switch.md
index 15e449c4c..5e8c19bfa 100644
--- a/docs/feature_dip_switch.md
+++ b/docs/feature_dip_switch.md
@@ -23,8 +23,9 @@ or
23The callback functions can be inserted into your `<keyboard>.c`: 23The callback functions can be inserted into your `<keyboard>.c`:
24 24
25```c 25```c
26void dip_switch_update_kb(uint8_t index, bool active) { 26bool dip_switch_update_kb(uint8_t index, bool active) {
27 dip_switch_update_user(index, active); 27 if !(dip_switch_update_user(index, active)) { return false; }
28 return true;
28} 29}
29``` 30```
30 31
@@ -32,7 +33,7 @@ void dip_switch_update_kb(uint8_t index, bool active) {
32or `keymap.c`: 33or `keymap.c`:
33 34
34```c 35```c
35void dip_switch_update_user(uint8_t index, bool active) { 36bool dip_switch_update_user(uint8_t index, bool active) {
36 switch (index) { 37 switch (index) {
37 case 0: 38 case 0:
38 if(active) { audio_on(); } else { audio_off(); } 39 if(active) { audio_on(); } else { audio_off(); }
@@ -57,6 +58,7 @@ void dip_switch_update_user(uint8_t index, bool active) {
57 } 58 }
58 break; 59 break;
59 } 60 }
61 return true;
60} 62}
61``` 63```
62 64
@@ -64,8 +66,9 @@ Additionally, we support bit mask functions which allow for more complex handlin
64 66
65 67
66```c 68```c
67void dip_switch_update_mask_kb(uint32_t state) { 69bool dip_switch_update_mask_kb(uint32_t state) {
68 dip_switch_update_mask_user(state); 70 if (!dip_switch_update_mask_user(state)) { return false; }
71 return true;
69} 72}
70``` 73```
71 74
@@ -73,7 +76,7 @@ void dip_switch_update_mask_kb(uint32_t state) {
73or `keymap.c`: 76or `keymap.c`:
74 77
75```c 78```c
76void dip_switch_update_mask_user(uint32_t state) { 79bool dip_switch_update_mask_user(uint32_t state) {
77 if (state & (1UL<<0) && state & (1UL<<1)) { 80 if (state & (1UL<<0) && state & (1UL<<1)) {
78 layer_on(_ADJUST); // C on esc 81 layer_on(_ADJUST); // C on esc
79 } else { 82 } else {
@@ -89,6 +92,7 @@ void dip_switch_update_mask_user(uint32_t state) {
89 } else { 92 } else {
90 layer_off(_TEST_B); 93 layer_off(_TEST_B);
91 } 94 }
95 return true;
92} 96}
93``` 97```
94 98
diff --git a/docs/feature_haptic_feedback.md b/docs/feature_haptic_feedback.md
index a092e784c..469c9c798 100644
--- a/docs/feature_haptic_feedback.md
+++ b/docs/feature_haptic_feedback.md
@@ -162,4 +162,28 @@ This will set what sequence HPT_RST will set as the active mode. If not defined,
162 162
163### DRV2605L Continuous Haptic Mode 163### DRV2605L Continuous Haptic Mode
164 164
165This mode sets continuous haptic feedback with the option to increase or decrease strength. 165This mode sets continuous haptic feedback with the option to increase or decrease strength.
166
167## Haptic Key Exclusion
168The Haptic Exclusion is implemented as `__attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t *record)` in haptic.c. This allows a re-definition at the required level with the specific requirement / exclusion.
169
170### NO_HAPTIC_MOD
171With the entry of `#define NO_HAPTIC_MOD` in config.h, modifiers from Left Control to Right GUI will not trigger a feedback. This also includes modifiers in a Mod Tap configuration.
172
173### NO_HAPTIC_FN
174With the entry of `#define NO_HAPTIC_FN` in config.h, layer keys will not rigger a feedback.
175
176### NO_HAPTIC_ALPHA
177With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback.
178
179### NO_HAPTIC_PUNCTUATION
180With the entry of `#define NO_HAPTIC_PUNCTUATION` in config.h, none of the following keys will trigger a feedback: Enter, ESC, Backspace, Space, Minus, Equal, Left Bracket, Right Bracket, Backslash, Non-US Hash, Semicolon, Quote, Grave, Comma, Slash, Dot, Non-US Backslash.
181
182### NO_HAPTIC_LOCKKEYS
183With the entry of `#define NO_HAPTIC_LOCKKEYS` in config.h, none of the following keys will trigger a feedback: Caps Lock, Scroll Lock, Num Lock.
184
185### NO_HAPTIC_NAV
186With the entry of `#define NO_HAPTIC_NAV` in config.h, none of the following keys will trigger a feedback: Print Screen, Pause, Insert, Delete, Page Down, Page Up, Left Arrow, Up Arrow, Right Arrow, Down Arrow, End, Home.
187
188### NO_HAPTIC_NUMERIC
189With the entry of `#define NO_HAPTIC_NUMERIC` in config.h, none of the following keys between 0 and 9 (KC_1 ... KC_0) will trigger a feedback. \ No newline at end of file
diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md
index f3b659b1b..c90aabb9c 100644
--- a/docs/feature_oled_driver.md
+++ b/docs/feature_oled_driver.md
@@ -346,6 +346,10 @@ bool oled_scroll_left(void);
346// Returns true if the screen was not scrolling or stops scrolling 346// Returns true if the screen was not scrolling or stops scrolling
347bool oled_scroll_off(void); 347bool oled_scroll_off(void);
348 348
349// Inverts the display
350// Returns true if the screen was or is inverted
351bool oled_invert(bool invert);
352
349// Returns the maximum number of characters that will fit on a line 353// Returns the maximum number of characters that will fit on a line
350uint8_t oled_max_chars(void); 354uint8_t oled_max_chars(void);
351 355
diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md
index 08d5c9c4c..675b7a1be 100644
--- a/docs/feature_rgb_matrix.md
+++ b/docs/feature_rgb_matrix.md
@@ -228,6 +228,75 @@ Configure the hardware via your `config.h`:
228``` 228```
229 229
230--- 230---
231### AW20216 :id=aw20216
232There is basic support for addressable RGB matrix lighting with the SPI AW20216 RGB controller. To enable it, add this to your `rules.mk`:
233
234```makefile
235RGB_MATRIX_ENABLE = yes
236RGB_MATRIX_DRIVER = AW20216
237```
238
239You can use up to 2 AW20216 IC's. Do not specify `DRIVER_<N>_xxx` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
240
241| Variable | Description | Default |
242|----------|-------------|---------|
243| `DRIVER_1_CS` | (Required) MCU pin connected to first RGB driver chip select line | B13 |
244| `DRIVER_2_CS` | (Optional) MCU pin connected to second RGB driver chip select line | |
245| `DRIVER_1_EN` | (Required) MCU pin connected to first RGB driver hardware enable line | C13 |
246| `DRIVER_2_EN` | (Optional) MCU pin connected to second RGB driver hardware enable line | |
247| `DRIVER_1_LED_TOTAL` | (Required) How many RGB lights are connected to first RGB driver | |
248| `DRIVER_2_LED_TOTAL` | (Optional) How many RGB lights are connected to second RGB driver | |
249| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
250| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
251| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
252| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
253| `AW_SPI_DIVISOR` | (Optional) Clock divisor for SPI communication (powers of 2, smaller numbers means faster communication, should not be less than 4) | 4 |
254
255Here is an example using 2 drivers.
256
257```c
258#define DRIVER_1_CS B13
259#define DRIVER_2_CS B14
260// Hardware enable lines may be connected to the same pin
261#define DRIVER_1_EN C13
262#define DRIVER_2_EN C13
263
264#define DRIVER_COUNT 2
265#define DRIVER_1_LED_TOTAL 66
266#define DRIVER_2_LED_TOTAL 32
267#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
268```
269
270!> Note the parentheses, this is so when `DRIVER_LED_TOTAL` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
271
272Define these arrays listing all the LEDs in your `<keyboard>.c`:
273
274```c
275const aw_led g_aw_leds[DRIVER_LED_TOTAL] = {
276/* Each AW20216 channel is controlled by a register at some offset between 0x00
277 * and 0xD7 inclusive.
278 * See drivers/awinic/aw20216.h for the mapping between register offsets and
279 * driver pin locations.
280 * driver
281 * | R location
282 * | | G location
283 * | | | B location
284 * | | | | */
285 { 0, CS1_SW1, CS2_SW1, CS3_SW1 },
286 { 0, CS4_SW1, CS5_SW1, CS6_SW1 },
287 { 0, CS7_SW1, CS8_SW1, CS9_SW1 },
288 { 0, CS10_SW1, CS11_SW1, CS12_SW1 },
289 { 0, CS13_SW1, CS14_SW1, CS15_SW1 },
290 ...
291 { 1, CS1_SW1, CS2_SW1, CS3_SW1 },
292 { 1, CS13_SW1, CS14_SW1, CS15_SW1 },
293 { 1, CS16_SW1, CS17_SW1, CS18_SW1 },
294 { 1, CS4_SW2, CS5_SW2, CS6_SW2 },
295 ...
296};
297```
298
299---
231 300
232## Common Configuration :id=common-configuration 301## Common Configuration :id=common-configuration
233 302
@@ -485,28 +554,29 @@ For inspiration and examples, check out the built-in effects under `quantum/rgb_
485 554
486These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions. 555These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions.
487 556
488|RGB |HSV | 557|RGB |HSV |
489|-------------------|-------------------| 558|---------------------|---------------------|
490|`RGB_WHITE` |`HSV_WHITE` | 559|`RGB_AZURE` |`HSV_AZURE` |
491|`RGB_RED` |`HSV_RED` | 560|`RGB_BLACK`/`RGB_OFF`|`HSV_BLACK`/`HSV_OFF`|
492|`RGB_CORAL` |`HSV_CORAL` | 561|`RGB_BLUE` |`HSV_BLUE` |
493|`RGB_ORANGE` |`HSV_ORANGE` | 562|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` |
494|`RGB_GOLDENROD` |`HSV_GOLDENROD` | 563|`RGB_CORAL` |`HSV_CORAL` |
495|`RGB_GOLD` |`HSV_GOLD` | 564|`RGB_CYAN` |`HSV_CYAN` |
496|`RGB_YELLOW` |`HSV_YELLOW` | 565|`RGB_GOLD` |`HSV_GOLD` |
497|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` | 566|`RGB_GOLDENROD` |`HSV_GOLDENROD` |
498|`RGB_GREEN` |`HSV_GREEN` | 567|`RGB_GREEN` |`HSV_GREEN` |
499|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` | 568|`RGB_MAGENTA` |`HSV_MAGENTA` |
500|`RGB_TURQUOISE` |`HSV_TURQUOISE` | 569|`RGB_ORANGE` |`HSV_ORANGE` |
501|`RGB_TEAL` |`HSV_TEAL` | 570|`RGB_PINK` |`HSV_PINK` |
502|`RGB_CYAN` |`HSV_CYAN` | 571|`RGB_PURPLE` |`HSV_PURPLE` |
503|`RGB_AZURE` |`HSV_AZURE` | 572|`RGB_RED` |`HSV_RED` |
504|`RGB_BLUE` |`HSV_BLUE` | 573|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` |
505|`RGB_PURPLE` |`HSV_PURPLE` | 574|`RGB_TEAL` |`HSV_TEAL` |
506|`RGB_MAGENTA` |`HSV_MAGENTA` | 575|`RGB_TURQUOISE` |`HSV_TURQUOISE` |
507|`RGB_PINK` |`HSV_PINK` | 576|`RGB_WHITE` |`HSV_WHITE` |
508 577|`RGB_YELLOW` |`HSV_YELLOW` |
509These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list! 578
579These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/color.h). Feel free to add to this list!
510 580
511 581
512## Additional `config.h` Options :id=additional-configh-options 582## Additional `config.h` Options :id=additional-configh-options
diff --git a/docs/feature_rgblight.md b/docs/feature_rgblight.md
index 994a014a2..d323dee4f 100644
--- a/docs/feature_rgblight.md
+++ b/docs/feature_rgblight.md
@@ -119,7 +119,7 @@ if `RGBLIGHT_EFFECT_xxxx` or `RGBLIGHT_ANIMATIONS` is defined, you also have a n
119 119
120Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstration. 120Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstration.
121 121
122Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight.h` there is a contrast table between the old mode number and the current symbol. 122Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight/rgblight.h` there is a contrast table between the old mode number and the current symbol.
123 123
124### Effect and Animation Toggles 124### Effect and Animation Toggles
125 125
@@ -328,7 +328,7 @@ Normally lighting layers are not shown when RGB Lighting is disabled (e.g. with
328 328
329## Functions 329## Functions
330 330
331If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight.h) for the full list, but the most commonly used functions include: 331If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight/rgblight.h) for the full list, but the most commonly used functions include:
332 332
333### Utility Functions 333### Utility Functions
334|Function |Description | 334|Function |Description |
@@ -449,26 +449,27 @@ rgblight_sethsv_at(HSV_GREEN, 2); // led 2
449 449
450These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions. 450These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions.
451 451
452|RGB |HSV | 452|RGB |HSV |
453|-------------------|-------------------| 453|---------------------|---------------------|
454|`RGB_WHITE` |`HSV_WHITE` | 454|`RGB_AZURE` |`HSV_AZURE` |
455|`RGB_RED` |`HSV_RED` | 455|`RGB_BLACK`/`RGB_OFF`|`HSV_BLACK`/`HSV_OFF`|
456|`RGB_CORAL` |`HSV_CORAL` | 456|`RGB_BLUE` |`HSV_BLUE` |
457|`RGB_ORANGE` |`HSV_ORANGE` | 457|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` |
458|`RGB_GOLDENROD` |`HSV_GOLDENROD` | 458|`RGB_CORAL` |`HSV_CORAL` |
459|`RGB_GOLD` |`HSV_GOLD` | 459|`RGB_CYAN` |`HSV_CYAN` |
460|`RGB_YELLOW` |`HSV_YELLOW` | 460|`RGB_GOLD` |`HSV_GOLD` |
461|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` | 461|`RGB_GOLDENROD` |`HSV_GOLDENROD` |
462|`RGB_GREEN` |`HSV_GREEN` | 462|`RGB_GREEN` |`HSV_GREEN` |
463|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` | 463|`RGB_MAGENTA` |`HSV_MAGENTA` |
464|`RGB_TURQUOISE` |`HSV_TURQUOISE` | 464|`RGB_ORANGE` |`HSV_ORANGE` |
465|`RGB_TEAL` |`HSV_TEAL` | 465|`RGB_PINK` |`HSV_PINK` |
466|`RGB_CYAN` |`HSV_CYAN` | 466|`RGB_PURPLE` |`HSV_PURPLE` |
467|`RGB_AZURE` |`HSV_AZURE` | 467|`RGB_RED` |`HSV_RED` |
468|`RGB_BLUE` |`HSV_BLUE` | 468|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` |
469|`RGB_PURPLE` |`HSV_PURPLE` | 469|`RGB_TEAL` |`HSV_TEAL` |
470|`RGB_MAGENTA` |`HSV_MAGENTA` | 470|`RGB_TURQUOISE` |`HSV_TURQUOISE` |
471|`RGB_PINK` |`HSV_PINK` | 471|`RGB_WHITE` |`HSV_WHITE` |
472|`RGB_YELLOW` |`HSV_YELLOW` |
472 473
473```c 474```c
474rgblight_setrgb(RGB_ORANGE); 475rgblight_setrgb(RGB_ORANGE);
@@ -477,7 +478,7 @@ rgblight_setrgb_at(RGB_GOLD, 3);
477rgblight_sethsv_range(HSV_WHITE, 0, 6); 478rgblight_sethsv_range(HSV_WHITE, 0, 6);
478``` 479```
479 480
480These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list! 481These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/color.h). Feel free to add to this list!
481 482
482 483
483## Changing the order of the LEDs 484## Changing the order of the LEDs
diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md
index 4ebf585f5..603c387c2 100644
--- a/docs/feature_split_keyboard.md
+++ b/docs/feature_split_keyboard.md
@@ -8,8 +8,7 @@ QMK Firmware has a generic implementation that is usable by any board, as well a
8 8
9For this, we will mostly be talking about the generic implementation used by the Let's Split and other keyboards. 9For this, we will mostly be talking about the generic implementation used by the Let's Split and other keyboards.
10 10
11!> ARM is not yet fully supported for Split Keyboards and has many limitations. Progress is being made, but we have not yet reached 100% feature parity. 11!> ARM split supports most QMK subsystems when using the 'serial' and 'serial_usart' drivers. I2C slave is currently unsupported.
12
13 12
14## Compatibility Overview 13## Compatibility Overview
15 14
@@ -169,7 +168,7 @@ Because not every split keyboard is identical, there are a number of additional
169#define USE_I2C 168#define USE_I2C
170``` 169```
171 170
172This enables I<sup>2</sup>C support for split keyboards. This isn't strictly for communication, but can be used for OLED or other I<sup>2</sup>C-based devices. 171This configures the use of I<sup>2</sup>C support for split keyboard transport (AVR only).
173 172
174```c 173```c
175#define SOFT_SERIAL_PIN D0 174#define SOFT_SERIAL_PIN D0
@@ -193,20 +192,115 @@ If you're having issues with serial communication, you can change this value, as
193* **`5`**: about 20kbps 192* **`5`**: about 20kbps
194 193
195```c 194```c
196#define SPLIT_MODS_ENABLE 195#define FORCED_SYNC_THROTTLE_MS 100
197``` 196```
198 197
199This enables transmitting modifier state (normal, weak and oneshot) to the non 198This sets the maximum number of milliseconds before forcing a synchronization of data from master to slave. Under normal circumstances this sync occurs whenever the data _changes_, for safety a data transfer occurs after this number of milliseconds if no change has been detected since the last sync.
200primary side of the split keyboard. This adds a few bytes of data to the split
201communication protocol and may impact the matrix scan speed when enabled.
202The purpose of this feature is to support cosmetic use of modifer state (e.g.
203displaying status on an OLED screen).
204 199
205```c 200```c
206#define SPLIT_TRANSPORT_MIRROR 201#define SPLIT_TRANSPORT_MIRROR
207``` 202```
208 203
209This mirrors the master side matrix to the slave side for features that react or require knowledge of master side key presses on the slave side. This adds a few bytes of data to the split communication protocol and may impact the matrix scan speed when enabled. The purpose of this feature is to support cosmetic use of key events (e.g. RGB reacting to Keypresses). 204This mirrors the master side matrix to the slave side for features that react or require knowledge of master side key presses on the slave side. The purpose of this feature is to support cosmetic use of key events (e.g. RGB reacting to keypresses). This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
205
206```c
207#define SPLIT_LAYER_STATE_ENABLE
208```
209
210This enables syncing of the layer state between both halves of the split keyboard. The main purpose of this feature is to enable support for use of things like OLED display of the currently active layer. This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
211
212```c
213#define SPLIT_LED_STATE_ENABLE
214```
215
216This enables syncing of the Host LED status (caps lock, num lock, etc) between both halves of the split keyboard. The main purpose of this feature is to enable support for use of things like OLED display of the Host LED status. This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
217
218```c
219#define SPLIT_MODS_ENABLE
220```
221
222This enables transmitting modifier state (normal, weak and oneshot) to the non primary side of the split keyboard. The purpose of this feature is to support cosmetic use of modifer state (e.g. displaying status on an OLED screen). This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
223
224```c
225#define SPLIT_WPM_ENABLE
226```
227
228This enables transmitting the current WPM to the slave side of the split keyboard. The purpose of this feature is to support cosmetic use of WPM (e.g. displaying the current value on an OLED screen). This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
229
230### Custom data sync between sides :id=custom-data-sync
231
232QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master.
233
234To leverage this, a keyboard or user/keymap can define a comma-separated list of _transaction IDs_:
235
236```c
237// for keyboard-level data sync:
238#define SPLIT_TRANSACTION_IDS_KB KEYBOARD_SYNC_A, KEYBOARD_SYNC_B
239// or, for user:
240#define SPLIT_TRANSACTION_IDS_USER USER_SYNC_A, USER_SYNC_B, USER_SYNC_C
241```
242
243These _transaction IDs_ then need a slave-side handler function to be registered with the split transport, for example:
244
245```c
246typedef struct _master_to_slave_t {
247 int m2s_data;
248} master_to_slave_t;
249
250typedef struct _slave_to_master_t {
251 int s2m_data;
252} slave_to_master_t;
253
254void user_sync_a_slave_handler(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
255 const master_to_slave_t *m2s = (const master_to_slave_t*)in_data;
256 slave_to_master_t *s2m = (slave_to_master_t*)out_data;
257 s2m->s2m_data = m2s->m2s_data + 5; // whatever comes in, add 5 so it can be sent back
258}
259
260void keyboard_post_init_user(void) {
261 transaction_register_rpc(USER_SYNC_A, user_sync_a_slave_handler);
262}
263```
264
265The master side can then invoke the slave-side handler - for normal keyboard functionality to be minimally affected, any keyboard- or user-level code attempting to sync data should be throttled:
266
267```c
268void housekeeping_task_user(void) {
269 if (is_keyboard_master()) {
270 // Interact with slave every 500ms
271 static uint32_t last_sync = 0;
272 if (timer_elapsed32(last_sync) > 500) {
273 master_to_slave_t m2s = {6};
274 slave_to_master_t s2m = {0};
275 if(transaction_rpc_exec(USER_SYNC_A, sizeof(m2s), &m2s, sizeof(s2m), &s2m)) {
276 last_sync = timer_read32();
277 dprintf("Slave value: %d\n", s2m.s2m_data); // this will now be 11, as the slave adds 5
278 } else {
279 dprint("Slave sync failed!\n");
280 }
281 }
282 }
283}
284```
285
286!> It is recommended that any data sync between halves happens during the master side's _housekeeping task_. This ensures timely retries should failures occur.
287
288If only one-way data transfer is needed, helper methods are provided:
289
290```c
291bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer);
292bool transaction_rpc_send(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer);
293bool transaction_rpc_recv(int8_t transaction_id, uint8_t target2initiator_buffer_size, void *target2initiator_buffer);
294```
295
296By default, the inbound and outbound data is limited to a maximum of 32 bytes each. The sizes can be altered if required:
297
298```c
299// Master to slave:
300#define RPC_M2S_BUFFER_SIZE 48
301// Slave to master:
302#define RPC_S2M_BUFFER_SIZE 48
303```
210 304
211### Hardware Configuration Options 305### Hardware Configuration Options
212 306
diff --git a/docs/feature_st7565.md b/docs/feature_st7565.md
new file mode 100644
index 000000000..de3e44d8e
--- /dev/null
+++ b/docs/feature_st7565.md
@@ -0,0 +1,274 @@
1# ST7565 LCD Driver
2
3## Supported Hardware
4
5LCD modules using ST7565 driver IC, communicating over SPI.
6
7|Module |IC |Size |Notes |
8|------------------------------|-------|------|----------------------------------------------------------|
9|Newhaven Display NHD-C12832A1Z|ST7565R|128x32|Used by Ergodox Infinity; primary consumer of this feature|
10|Zolentech ZLE12864B |ST7565P|128x64|Requires contrast adjustment |
11
12## Usage
13
14To enable the feature, there are three steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`:
15
16```make
17ST7565_ENABLE = yes
18```
19
20Then in your `keymap.c` file, implement the ST7565 task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`:
21
22```c
23#ifdef ST7565_ENABLE
24void st7565_task_user(void) {
25 // Host Keyboard Layer Status
26 st7565_write_P(PSTR("Layer: "), false);
27
28 switch (get_highest_layer(layer_state)) {
29 case _QWERTY:
30 st7565_write_P(PSTR("Default\n"), false);
31 break;
32 case _FN:
33 st7565_write_P(PSTR("FN\n"), false);
34 break;
35 case _ADJ:
36 st7565_write_P(PSTR("ADJ\n"), false);
37 break;
38 default:
39 // Or use the write_ln shortcut over adding '\n' to the end of your string
40 st7565_write_ln_P(PSTR("Undefined"), false);
41 }
42
43 // Host Keyboard LED Status
44 led_t led_state = host_keyboard_led_state();
45 st7565_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false);
46 st7565_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false);
47 st7565_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false);
48}
49#endif
50```
51
52## Logo Example
53
54In the default font, certain ranges of characters are reserved for a QMK logo. To render this logo to the screen, use the following code example:
55
56```c
57static void render_logo(void) {
58 static const char PROGMEM qmk_logo[] = {
59 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94,
60 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4,
61 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00
62 };
63
64 st7565_write_P(qmk_logo, false);
65}
66```
67
68## Buffer Read Example
69For some purposes, you may need to read the current state of the display buffer. The `st7565_read_raw` function can be used to safely read bytes from the buffer.
70
71In this example, calling `fade_display` in the `st7565_task_user` function will slowly fade away whatever is on the screen by turning random pixels off over time.
72```c
73//Setup some mask which can be or'd with bytes to turn off pixels
74const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254};
75
76static void fade_display(void) {
77 //Define the reader structure
78 display_buffer_reader_t reader;
79 uint8_t buff_char;
80 if (random() % 30 == 0) {
81 srand(timer_read());
82 // Fetch a pointer for the buffer byte at index 0. The return structure
83 // will have the pointer and the number of bytes remaining from this
84 // index position if we want to perform a sequential read by
85 // incrementing the buffer pointer
86 reader = st7565_read_raw(0);
87 //Loop over the remaining buffer and erase pixels as we go
88 for (uint16_t i = 0; i < reader.remaining_element_count; i++) {
89 //Get the actual byte in the buffer by dereferencing the pointer
90 buff_char = *reader.current_element;
91 if (buff_char != 0) {
92 st7565_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i);
93 }
94 //increment the pointer to fetch a new byte during the next loop
95 reader.current_element++;
96 }
97 }
98}
99```
100
101## Other Examples
102
103In split keyboards, it is very common to have two displays that each render different content and are oriented or flipped differently. You can do this by switching which content to render by using the return value from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g:
104
105```c
106#ifdef ST7565_ENABLE
107display_rotation_t st7565_init_user(display_rotation_t rotation) {
108 if (!is_keyboard_master()) {
109 return DISPLAY_ROTATION_180; // flips the display 180 degrees if offhand
110 }
111
112 return rotation;
113}
114
115void st7565_task_user(void) {
116 if (is_keyboard_master()) {
117 render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
118 } else {
119 render_logo(); // Renders a static logo
120 }
121}
122#endif
123```
124
125## Basic Configuration
126
127|Define |Default |Description |
128|------------------------|--------------|-----------------------------------------------------------------------------------------------------|
129|`ST7565_A0_PIN` |*Not defined* |(Required) The GPIO connected to the display's A0 (data/command) pin |
130|`ST7565_RST_PIN` |*Not defined* |(Required) The GPIO connected to the display's reset pin |
131|`ST7565_SS_PIN` |*Not defined* |(Required) The GPIO connected to the display's slave select pin |
132|`ST7565_SPI_CLK_DIVISOR`|`4` |The SPI clock divisor to use |
133|`ST7565_FONT_H` |`"glcdfont.c"`|The font code file to use for custom fonts |
134|`ST7565_FONT_START` |`0` |The starting character index for custom fonts |
135|`ST7565_FONT_END` |`223` |The ending character index for custom fonts |
136|`ST7565_FONT_WIDTH` |`6` |The font width |
137|`ST7565_FONT_HEIGHT` |`8` |The font height (untested) |
138|`ST7565_TIMEOUT` |`60000` |Turns off the screen after 60000ms of keyboard inactivity. Helps reduce burn-in. Set to 0 to disable.|
139|`ST7565_COLUMN_OFFSET` |`0` |Shift output to the right this many pixels. |
140|`ST7565_CONTRAST` |`32` |The default contrast level of the display, from 0 to 255. |
141|`ST7565_UPDATE_INTERVAL`|`0` |Set the time interval for updating the display in ms. This will improve the matrix scan rate. |
142
143## Custom sized displays
144
145The default display size for this feature is 128x32 and all necessary defines are precalculated with that in mind.
146
147|Define |Default |Description |
148|-----------------------|----------|-----------------------------------------------------------------------------------------------------------|
149|`ST7565_DISPLAY_WIDTH` |`128` |The width of the display. |
150|`ST7565_DISPLAY_HEIGHT`|`32` |The height of the display. |
151|`ST7565_MATRIX_SIZE` |`512` |The local buffer size to allocate.<br>`(ST7565_DISPLAY_HEIGHT / 8 * ST7565_DISPLAY_WIDTH)`. |
152|`ST7565_BLOCK_TYPE` |`uint16_t`|The unsigned integer type to use for dirty rendering. |
153|`ST7565_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.<br>`(sizeof(ST7565_BLOCK_TYPE) * 8)`.|
154|`ST7565_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br>`(ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT)`. |
155
156## API
157
158```c
159// Rotation enum values are flags
160typedef enum {
161 DISPLAY_ROTATION_0,
162 DISPLAY_ROTATION_180
163} display_rotation_t;
164
165// Initialize the display, rotating the rendered output based on the define passed in.
166// Returns true if the was initialized successfully
167bool st7565_init(display_rotation_t rotation);
168
169// Called at the start of st7565_init, weak function overridable by the user
170// rotation - the value passed into st7565_init
171// Return new display_rotation_t if you want to override default rotation
172display_rotation_t st7565_init_user(display_rotation_t rotation);
173
174// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering
175void st7565_clear(void);
176
177// Renders the dirty chunks of the buffer to display
178void st7565_render(void);
179
180// Moves cursor to character position indicated by column and line, wraps if out of bounds
181// Max column denoted by 'st7565_max_chars()' and max lines by 'st7565_max_lines()' functions
182void st7565_set_cursor(uint8_t col, uint8_t line);
183
184// Advances the cursor to the next page, writing ' ' if true
185// Wraps to the begining when out of bounds
186void st7565_advance_page(bool clearPageRemainder);
187
188// Moves the cursor forward 1 character length
189// Advance page if there is not enough room for the next character
190// Wraps to the begining when out of bounds
191void st7565_advance_char(void);
192
193// Writes a single character to the buffer at current cursor position
194// Advances the cursor while writing, inverts the pixels if true
195// Main handler that writes character data to the display buffer
196void st7565_write_char(const char data, bool invert);
197
198// Writes a string to the buffer at current cursor position
199// Advances the cursor while writing, inverts the pixels if true
200void st7565_write(const char *data, bool invert);
201
202// Writes a string to the buffer at current cursor position
203// Advances the cursor while writing, inverts the pixels if true
204// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
205void st7565_write_ln(const char *data, bool invert);
206
207// Pans the buffer to the right (or left by passing true) by moving contents of the buffer
208// Useful for moving the screen in preparation for new drawing
209void st7565_pan(bool left);
210
211// Returns a pointer to the requested start index in the buffer plus remaining
212// buffer length as struct
213display_buffer_reader_t st7565_read_raw(uint16_t start_index);
214
215// Writes a string to the buffer at current cursor position
216void st7565_write_raw(const char *data, uint16_t size);
217
218// Writes a single byte into the buffer at the specified index
219void st7565_write_raw_byte(const char data, uint16_t index);
220
221// Sets a specific pixel on or off
222// Coordinates start at top-left and go right and down for positive x and y
223void st7565_write_pixel(uint8_t x, uint8_t y, bool on);
224
225// Writes a PROGMEM string to the buffer at current cursor position
226// Advances the cursor while writing, inverts the pixels if true
227// Remapped to call 'void st7565_write(const char *data, bool invert);' on ARM
228void st7565_write_P(const char *data, bool invert);
229
230// Writes a PROGMEM string to the buffer at current cursor position
231// Advances the cursor while writing, inverts the pixels if true
232// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
233// Remapped to call 'void st7565_write_ln(const char *data, bool invert);' on ARM
234void st7565_write_ln_P(const char *data, bool invert);
235
236// Writes a PROGMEM string to the buffer at current cursor position
237void st7565_write_raw_P(const char *data, uint16_t size);
238
239// Can be used to manually turn on the screen if it is off
240// Returns true if the screen was on or turns on
241bool st7565_on(void);
242
243// Called when st7565_on() turns on the screen, weak function overridable by the user
244// Not called if the screen is already on
245void st7565_on_user(void);
246
247// Can be used to manually turn off the screen if it is on
248// Returns true if the screen was off or turns off
249bool st7565_off(void);
250
251// Called when st7565_off() turns off the screen, weak function overridable by the user
252// Not called if the screen is already off
253void st7565_off_user(void);
254
255// Returns true if the screen is currently on, false if it is
256// not
257bool st7565_is_on(void);
258
259// Basically it's st7565_render, but with timeout management and st7565_task_user calling!
260void st7565_task(void);
261
262// Called at the start of st7565_task, weak function overridable by the user
263void st7565_task_user(void);
264
265// Inverts the display
266// Returns true if the screen was or is inverted
267bool st7565_invert(bool invert);
268
269// Returns the maximum number of characters that will fit on a line
270uint8_t st7565_max_chars(void);
271
272// Returns the maximum number of lines that will fit on the display
273uint8_t st7565_max_lines(void);
274```
diff --git a/docs/ja/compatible_microcontrollers.md b/docs/ja/compatible_microcontrollers.md
index b675b038d..761a4cda4 100644
--- a/docs/ja/compatible_microcontrollers.md
+++ b/docs/ja/compatible_microcontrollers.md
@@ -36,6 +36,8 @@ QMK は十分な容量のフラッシュメモリを備えた USB 対応 AVR ま
36* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html) 36* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html)
37* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html) 37* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html)
38* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html) 38* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html)
39* [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
40* [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
39* [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) 41* [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
40* [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) 42* [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
41 43
diff --git a/docs/ja/feature_dip_switch.md b/docs/ja/feature_dip_switch.md
index a0f6aeb00..a5436779f 100644
--- a/docs/ja/feature_dip_switch.md
+++ b/docs/ja/feature_dip_switch.md
@@ -28,8 +28,9 @@ DIP スイッチは、以下を `rules.mk` に追加することでサポート
28コールバック関数を `<keyboard>.c` に記述することができます: 28コールバック関数を `<keyboard>.c` に記述することができます:
29 29
30```c 30```c
31void dip_switch_update_kb(uint8_t index, bool active) { 31bool dip_switch_update_kb(uint8_t index, bool active) {
32 dip_switch_update_user(index, active); 32 if !(dip_switch_update_user(index, active)) { return false; }
33 return true;
33} 34}
34``` 35```
35 36
@@ -37,7 +38,7 @@ void dip_switch_update_kb(uint8_t index, bool active) {
37あるいは `keymap.c` に記述することもできます: 38あるいは `keymap.c` に記述することもできます:
38 39
39```c 40```c
40void dip_switch_update_user(uint8_t index, bool active) { 41bool dip_switch_update_user(uint8_t index, bool active) {
41 switch (index) { 42 switch (index) {
42 case 0: 43 case 0:
43 if(active) { audio_on(); } else { audio_off(); } 44 if(active) { audio_on(); } else { audio_off(); }
@@ -62,6 +63,7 @@ void dip_switch_update_user(uint8_t index, bool active) {
62 } 63 }
63 break; 64 break;
64 } 65 }
66 return true;
65} 67}
66``` 68```
67 69
@@ -69,8 +71,9 @@ void dip_switch_update_user(uint8_t index, bool active) {
69 71
70 72
71```c 73```c
72void dip_switch_update_mask_kb(uint32_t state) { 74bool dip_switch_update_mask_kb(uint32_t state) {
73 dip_switch_update_mask_user(state); 75 if (!dip_switch_update_mask_user(state)) { return false; }
76 return true;
74} 77}
75``` 78```
76 79
@@ -78,7 +81,7 @@ void dip_switch_update_mask_kb(uint32_t state) {
78あるいは `keymap.c` に記述することもできます: 81あるいは `keymap.c` に記述することもできます:
79 82
80```c 83```c
81void dip_switch_update_mask_user(uint32_t state) { 84bool dip_switch_update_mask_user(uint32_t state) {
82 if (state & (1UL<<0) && state & (1UL<<1)) { 85 if (state & (1UL<<0) && state & (1UL<<1)) {
83 layer_on(_ADJUST); // C on esc 86 layer_on(_ADJUST); // C on esc
84 } else { 87 } else {
@@ -94,6 +97,7 @@ void dip_switch_update_mask_user(uint32_t state) {
94 } else { 97 } else {
95 layer_off(_TEST_B); 98 layer_off(_TEST_B);
96 } 99 }
100 return true;
97} 101}
98``` 102```
99 103
diff --git a/docs/serial_driver.md b/docs/serial_driver.md
index 359fc5955..ed989b0a1 100644
--- a/docs/serial_driver.md
+++ b/docs/serial_driver.md
@@ -73,7 +73,7 @@ You must also enable the ChibiOS `SERIAL` feature:
73Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral. 73Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral.
74 74
75### USART Full-duplex 75### USART Full-duplex
76Targeting STM32 boards where communication is offloaded to a USART hardware device. The advantage over bitbang is that this provides fast and accurate timings. USART Full-Duplex requires two conductors **without** pull-up resistors instead of one conductor with a pull-up resistor unlike the Half-duplex driver, but it is more efficent as it uses DMA transfers, which can result in even faster transmission speeds. 76Targeting STM32 boards where communication is offloaded to a USART hardware device. The advantage over bitbang is that this provides fast and accurate timings. USART Full-Duplex requires two conductors **without** pull-up resistors instead of one conductor with a pull-up resistor unlike the Half-duplex driver. Due to its internal design it is more efficent, which can result in even faster transmission speeds.
77 77
78#### Pin configuration 78#### Pin configuration
79 79
@@ -86,12 +86,13 @@ Please note that `TX` of the master half has to be connected with the `RX` pin o
86To use the driver, add this to your rules.mk: 86To use the driver, add this to your rules.mk:
87 87
88```make 88```make
89SERIAL_DRIVER = usart_duplex 89SERIAL_DRIVER = usart
90``` 90```
91 91
92Next configure the hardware via your config.h: 92Next configure the hardware via your config.h:
93 93
94```c 94```c
95#define SERIAL_USART_FULL_DUPLEX // Enable full duplex operation mode.
95#define SERIAL_USART_TX_PIN B6 // USART TX pin 96#define SERIAL_USART_TX_PIN B6 // USART TX pin
96#define SERIAL_USART_RX_PIN B7 // USART RX pin 97#define SERIAL_USART_RX_PIN B7 // USART RX pin
97//#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below. 98//#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
@@ -104,17 +105,17 @@ Next configure the hardware via your config.h:
104 // 3: 57600 baud 105 // 3: 57600 baud
105 // 4: 38400 baud 106 // 4: 38400 baud
106 // 5: 19200 baud 107 // 5: 19200 baud
107#define SERIAL_USART_DRIVER UARTD1 // USART driver of TX and RX pin. default: UARTD1 108#define SERIAL_USART_DRIVER SD1 // USART driver of TX and RX pin. default: SD1
108#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 109#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
109#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 110#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
110#define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100 111#define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100
111``` 112```
112 113
113You must also enable the ChibiOS `UART` with blocking api feature: 114You must also enable the ChibiOS `SERIAL` feature:
114* In your board's halconf.h: `#define HAL_USE_UART TRUE` and `#define UART_USE_WAIT TRUE` 115* In your board's halconf.h: `#define HAL_USE_SERIAL TRUE`
115* In your board's mcuconf.h: `#define STM32_UART_USE_USARTn TRUE` (where 'n' matches the peripheral number of your selected USART on the MCU) 116* In your board's mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (where 'n' matches the peripheral number of your selected USART on the MCU)
116 117
117Do note that the configuration required is for the `UART` peripheral, not the `SERIAL` peripheral. 118Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral.
118 119
119#### Pins for USART Peripherals with Alternate Functions for selected STM32 MCUs 120#### Pins for USART Peripherals with Alternate Functions for selected STM32 MCUs
120 121